Properties allowed in Liquibase - Constraints - postgresql

I am trying to add a new table in the DB using Liquibase.
I am putting Constraints inside the table definition and have a foreign key in it. Without having an extra addForeignKey code snippet.
So I am trying to use this. But it says onDelete is not allowed in constraints . Its also a little hard to find any documentation related to this. Other properties do get allowed though.
<createTable tableName="relationship_view_person">
<column name="view_id" type="BIGINT">
<constraints nullable="false" foreignKeyName="fk_view_person_reln" referencedTableName="configured_view" referencedColumnNames="view_id" onDelete="CASCADE" />
</column>
<column name="person_id" type="TEXT">
<constraints nullable="false" foreignKeyName="fk_person_view_reln" referencedTableName="persons" referencedColumnNames="person_id" onDelete="CASCADE" />
</column>
</createTable>
I get this error
cvc-complex-type.3.2.2: Attribute 'onDelete' is not allowed to appear in element 'constraints'.

Please checkout this documentation for add column in liquibase. And scroll till you are on Constraints tag section. You will find all the attributes allowed with liquibase constraints tag.
As per the error you are getting for onDelete is not allowed, please try using attribute deleteCascade="true" like below:
<createTable tableName="relationship_view_person">
<column name="view_id" type="BIGINT">
<constraints nullable="false" foreignKeyName="fk_view_person_reln" referencedTableName="configured_view" referencedColumnNames="view_id" deleteCascade="true" />
</column>
<column name="person_id" type="TEXT">
<constraints nullable="false" foreignKeyName="fk_person_view_reln" referencedTableName="persons" referencedColumnNames="person_id" deleteCascade="true" />
</column>
</createTable>
On running updateSQL it will generate the expected SQL query for you (which you can verify before executing it directly on DB):
CREATE TABLE public.relationship_view_person (view_id BIGINT NOT NULL, person_id TEXT NOT NULL, CONSTRAINT fk_view_person_reln FOREIGN KEY (view_id) REFERENCES public.configured_view(view_id) ON DELETE CASCADE, CONSTRAINT fk_person_view_reln FOREIGN KEY (person_id) REFERENCES public.persons(person_id) ON DELETE CASCADE);
Note: onDelete attribute works with addForeignKeyConstraint tag in liquibase. Find documentation for it here.

TL;DR
You said
I am putting Constraints inside the table definition and have a foreign key in it. Without having an extra addForeignKey code snippet.
As exception suggest you are not allow to set unknown element line onDelete with in <constraint> tag, furthermore the set of possible configuration with in <constraint> till the latest version (4.*.*) are as follow.
<!-- Attributes for constraints -->
<xsd:attributeGroup name="constraintsAttributes">
<xsd:attribute name="nullable" type="booleanExp"/>
<xsd:attribute name="primaryKey" type="booleanExp"/>
<xsd:attribute name="primaryKeyName" type="xsd:string"/>
<xsd:attribute name="primaryKeyTablespace" type="xsd:string"/>
<xsd:attribute name="unique" type="booleanExp"/>
<xsd:attribute name="uniqueConstraintName" type="xsd:string"/>
<xsd:attribute name="references" type="xsd:string"/>
<xsd:attribute name="referencedTableName" type="xsd:string"/>
<xsd:attribute name="referencedColumnNames" type="xsd:string"/>
<xsd:attribute name="foreignKeyName" type="xsd:string"/>
<xsd:attribute name="deleteCascade" type="booleanExp"/>
<xsd:attribute name="deferrable" type="booleanExp"/>
<xsd:attribute name="initiallyDeferred" type="booleanExp"/>
<xsd:attribute name="checkConstraint" type="xsd:string"/>
</xsd:attributeGroup>

Related

Citation Style Language: Modify the bibliography

I am using Zotero and want to change the bibliography slightly:
<group delimiter="">
<text value=""/>
<text variable="URL"/>
<group prefix=". " suffix="">
<text term="accessed" suffix=" "/>
<date variable="accessed">
<date-part name="day" suffix=" "/>
<date-part name="month" form="" suffix=" "/>
<date-part name="year" form=""/>
</date>
</group>
</group>
In this I suspect the name for the used term in bibliography is used (see below):
accessed 1 March 2017
This I want to change to upper case:
Accessed 1 March 2017
If I change the text term to "Accessed" I get an error
Any suggestions?
You can change <text term="accessed" suffix=" "/> to <text term="accessed" text-case="capitalize-first" suffix=" "/>. See http://docs.citationstyles.org/en/stable/specification.html#text-case.
Alternatively, you can use <text value="Accessed" suffix=" "/>, but generally the use of terms is preferred, because terms allow styles to more easily localize to different languages.

Can Liquibase use DB2's multiple tablespaces?

In DB2 LUW it is recommended that tables, indexes and "long objects" (ie LOBs) should be placed in separate tablespaces. Our existing SQL scripts have lines like this:
CREATE TABLE "APPLICATIONTABLE"(
APPLICATIONID INTEGER NOT NULL,
APPLICATIONNAME VARCHAR(30) NOT NULL
)IN USERSPACE1 INDEX IN USERSPACE2 LONG IN USERSPACE3;
In a changeset we can specifiy a tablespace:
<createTable tableName="APPLICATIONTABLE" tablespace="${tablespace.data}">
<column name="APPLICATIONID" type="NUMBER(4, 0)">
<constraints nullable="false"/>
</column>
<column name="APPLICATIONNAME" type="VARCHAR(30)">
<constraints nullable="false"/>
</column>
</createTable>
But not, as far as I can see, DB2's multiple tablespaces. Is there any way to do this?
You could use a sql change which liquibase doc describes as:
The ‘sql’ tag allows you to specify whatever sql you want. It is useful for complex changes that aren’t supported through Liquibase’s automated refactoring tags and to work around bugs and limitations of Liquibase. The SQL contained in the sql tag can be multi-line.
It looks like this (copied from the liquibase doc):
<changeSet author="liquibase-docs" id="sql-example">
<sql dbms="h2, oracle"
endDelimiter="\nGO"
splitStatements="true"
stripComments="true">insert into person (name) values ('Bob')
<comment>What about Bob?</comment>
</sql>
</changeSet>
EDIT:
Just saw another option after reading this answer.
You could use the modifySql tag. Maybe leave out tablespace info and just append it like this (untested code - just a suggestion):
<createTable tableName="APPLICATIONTABLE">
<column name="APPLICATIONID" type="NUMBER(4, 0)">
<constraints nullable="false"/>
</column>
<column name="APPLICATIONNAME" type="VARCHAR(30)">
<constraints nullable="false"/>
</column>
<modifySql dbms="db2">
<append value=" IN USERSPACE1 INDEX IN USERSPACE2 LONG IN USERSPACE3"/>
</modifySql>
</createTable>
This is something that is supported by the Datical extensions to Liquibase, but not in Liquibase itself.
I know this is 6 years old, but I thought I'd post this as another possible solution. From their site they give the following as example
<changeSet id="2" author="liquibase">
<createTable catalogName="department2"
remarks="A String"
schemaName="public"
tableName="person"
tablespace="${tablespace}">
<column name="address" type="varchar(255)"/>
</createTable>
</changeSet>
Then define the tablespace name on the command line. If you had multiple you could provide multiple -D options
liquibase -Dtablespace='tablespaceQA' update

Liferay, ServiceBuilder, what's the scope for attributes userId, companyId, userId

Although I've developed some services with Liferay ServiceBuilder, I'm not quite sure I understand the point of using the attributes:
userId
companyId
groupId
Note that these attributes are available through the PortalRequest.
Following the basic tutorials, you are instructed to create these attributes for every entity, and take care to set them on 'add' functions. But thinking of it, I've not ever seen any tutorial or referenced code where these attributes are used on data retrieval (Finder methods, dynamic queries, or custom queries either)
So what's the point on keeping this information ?
Are these attributes used automatically somehow under some convention or scope ? Something like, the Liferay's default Finders using them when they are available through the PortalRequest ?
Or is it up to the developer to use them on every Select, E.g. are all the single-parameter Finders practically useless on multi-instance Portals (since the companyId attribute should be used on every Finder method) ?
Or is it just a good practice to keep this structure for database extendability, auditing, indexing or something else I'm totally missing ?
These attributes are necessary when you use your entities for example on staging environment. The groupId specifies to which environment the entity belongs to. Meaning of userId is obvious and as for companyId it is the site identifier. So IMHO these attributes are quite important when you have multiple sites on one portal, when you have staging env. enabled etc..
Suppose you have a new table and you want to set UserId in your table then it is necessary but otherwise I don't think these attributes are neccessary.
I have created service builder
<entity name="FaoEsalesCustomer" local-service="true" remote-service="false" table="fao_esalecustomer">
<!-- PK fields -->
<column name="esaleCustomerId" type="long" primary="true" />
<!-- Audit fields -->
<column name="createdBy" type="long" />
<column name="createdOn" type="Date" />
<column name="modifiedBy" type="long" />
<column name="modifiedOn" type="Date" />
<!-- Other fields -->
<column name="customerName" type="String" />
<column name="address" type="String" />
<column name="ph" type="Integer" />
<column name="categoryId" type="long" />
<column name="categoryName" type="String" />
<column name="quantity" type="Double" />
<column name="price" type="Double" />
</entity>

WSDL enumeration restriction with key/value pairs

I'm working on a SOAP webservice which features many inputfields using enumeration restrictions.
These enumerations are much like an HTML select/option setup; I expect a certain value to be returned but the label of that value should be exposed using the WSDL as well.
An example: the client wishes to add an insurance policy regarding his/her house and thus needs to specify the type of building involved.
<xsd:restriction base="xsd:string">
<xsd:enumeration value="00001" />
<xsd:enumeration value="00002" />
<xsd:enumeration value="00003" />
</xsd:restriction>
However, the client does not yet understand what these values 1, 2 and 3 are. So, something like this:
<xsd:restriction base="xsd:string">
<xsd:enumeration value="00001" label="Brick and mortar" />
<xsd:enumeration value="00002" label="Straw" />
<xsd:enumeration value="00003" label="Aircastle" />
</xsd:restriction>
would be great for the client to be used to display these labels to the consumer.
Is there any standard WSDL annotation/syntax for this construction?
Is there any standard WSDL annotation/syntax for this construction?
I'm afraid not. The XML Schema enumeration is used to constrain a value to be within a specified set of possible values. When your client sends you the request, the element with the restriction type will only be allowed to have (in your case) a value of 00001, 00002 or 00003 or it won't be valid.
The restriction only specifies the values, you can't add labels. You could at best add an <annotation> but that would be just documentation. In the client UI, it would be the responsibility of each client to say that 00001 is actually "Brick and mortar" and that 00002 is "Straw" etc.
If you don't want to do that, and instead want to also return labels, then you need a slightly more complex object, maybe something like this:
<option>
<key>00001</key>
<label>Brick and mortar</label>
</option>
You provide a label and you restrict the key with a schema like:
<xsd:simpleType name="ValuesType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="00001" />
<xsd:enumeration value="00002" />
<xsd:enumeration value="00003" />
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="OptionType">
<xsd:sequence>
<xsd:element name="key" type="ValuesType" />
<xsd:element name="label" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
You can return a list of options to the clients and they can present it in the interface with key as value and label as the text of options in <select> inputs, while on the request you will get back the selected value (i.e. the selected key).

Generate #Indexed annotation using Jaxb or HyperJaxb

I want to implement lucene based hibernate search in my assignment. For generating domain objects I am using HyperJaxb3.
I want #Indexed annotation to be added during domain object creation using HyperJaxb.
I tried googling for this, but unable to find solutions.
Any pointer in this regard will be of great help.
Annotate plugin is the right answer. See this example.
This is how it looks in schema:
....
xmlns:hs="http://annox.dev.java.net/org.hibernate.search.annotations"
...
<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<annox:annotate>
<hs:FieldBridge impl="org.jvnet.hyperjaxb3.ejb.tests.annox.Items">
<params>
<hs:Parameter name="foo" value="bar"/>
</params>
</hs:FieldBridge>
</annox:annotate>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
You can also use extra binding files (see the example).