add multiple columns with liquibase using yml - yaml

I want to add multiple columns to my database using liquibase and a yml-file.
I know that I can do this with one step using xml like this:
<changeSet author="liquibase-docs" id="addColumn-example">
<addColumn catalogName="cat"
schemaName="public"
tableName="person">
<column name="job" type="varchar(255)"/>
<column name="designation" type="varchar(255)"/>
</addColumn>
</changeSet>
Can I do the same in a yml-file?
- changeSet:
id: myId
author: malt
changes:
- addColumn:
tableName: myTable
columns:
- column:
name: name01
type: decimal(21,2)
- column:
name: name02
type: decimal(21,2)
This does not seem to work...
I just don't want to repeat the -addColumn-Tag again and again.
Thanks for your help!
Matthias

According to addColumn liquibase documentation you can do this in yaml as such (just their example):
databaseChangeLog:
- changeSet:
id: addColumn-example
author: liquibase-docs
changes:
- addColumn:
tableName: person
columns:
name: middlename
type: varchar(50)

You almost got it right, just need an extra indent after column:
- changeSet:
id: myId
author: malt
changes:
- addColumn:
tableName: myTable
columns:
- column:
 # note the indent below here!
name: name01
type: decimal(21,2)
- column:
name: name02
type: decimal(21,2)


Related

How to specify symbol/character in os-signpost-point-schema

I have a custom Xcode 13.2.1 (13C100) Instrument to which I have recently added os-signpost-point-schema. I notice that the events are marked with a hyphen/dash rather than a ⓢ. See the comparison of my custom tool vs the standard “Points of Interest” tool:
I have been digging through the documentation and while I wager that there is some simple attribute that can be set to dictate which symbol is included within the signpost ⃝, it is not jumping out at me. How does one select the symbol used within custom event points in Instruments?
Here is the code for the instrument:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Instruments Developer Help: https://help.apple.com/instruments/developer/mac/current/ -->
<package>
<id>com.robertmryan.CustomInterval</id>
<version>0.2</version>
<title>Custom Points of Interest</title>
<owner>
<name>Robert Ryan</name>
</owner>
<import-schema>os-signpost</import-schema>
<!-- See https://help.apple.com/instruments/developer/mac/current/#/dev536412616 -->
<os-signpost-point-schema>
<id>custom-point-schema</id>
<title>Points</title>
<owner>
<name>Robert Ryan</name>
</owner>
<purpose>Provide mechanism for multicolored events posted by `os_signpost`; The string generated by `os_signpost` must be in form of "Label:%d,Concept:%{public}#", where "Label" is string that will control what text appears in the event, and "Concept" is one of the strings listed in https://help.apple.com/instruments/developer/mac/current/#/dev66257045 that dictates the color of the interval. No spaces after the commas within this string.</purpose>
<note>That message must use that printf-style format, not embedding the values in the format string literal.</note>
<!-- you can constrain this to a particular subsystem if you'd like:
<subsystem>"com.domain.MyApp"</subsystem>
-->
<category>"Interval"</category>
<name>?name</name>
<pattern>
<message>"Label:" ?label ",Concept:" ?concept</message>
</pattern>
<column>
<mnemonic>name</mnemonic>
<title>Name</title>
<type>string</type>
<expression>?name</expression>
</column>
<column>
<mnemonic>label</mnemonic>
<title>Label</title>
<type>string</type>
<expression>?label</expression>
</column>
<column>
<mnemonic>concept</mnemonic>
<title>Concept</title>
<type>event-concept</type>
<expression>?concept</expression>
</column>
</os-signpost-point-schema>
<os-signpost-interval-schema>
<id>custom-interval-schema</id>
<title>Intervals</title>
<owner>
<name>Robert Ryan</name>
</owner>
<purpose>Provide mechanism for multicolored intervals posted by `os_signpost`; The string generated by `os_signpost` must be in form of "Label:%d,Concept:%{public}#", where "Label" is string that will control what text appears in the interval, and "Concept" is one of the strings listed in https://help.apple.com/instruments/developer/mac/current/#/dev66257045 that dictates the color of the interval. No spaces after the commas within this string.</purpose>
<note>That message must use that printf-style format, not embedding the values in the format string literal.</note>
<!-- you can constrain this to a particular subsystem if you'd like:
<subsystem>"com.domain.MyApp"</subsystem>
-->
<category>"Interval"</category>
<name>?name</name>
<start-pattern>
<message>"Label:" ?label ",Concept:" ?concept</message>
</start-pattern>
<column>
<mnemonic>name</mnemonic>
<title>Name</title>
<type>string</type>
<expression>?name</expression>
</column>
<column>
<mnemonic>label</mnemonic>
<title>Label</title>
<type>string</type>
<expression>?label</expression>
</column>
<column>
<mnemonic>concept</mnemonic>
<title>Concept</title>
<type>event-concept</type>
<expression>?concept</expression>
</column>
</os-signpost-interval-schema>
<instrument>
<id>com.robertmryan.CustomInterval.instrument</id>
<title>Custom Points of Interest</title>
<category>Behavior</category>
<purpose>Provide multi-colored intervals as dictated by the "event-concept" parsed from the `start-pattern` string.</purpose>
<icon>Generic</icon>
<limitations></limitations>
<create-table>
<id>custom-interval-table</id>
<schema-ref>custom-interval-schema</schema-ref>
</create-table>
<create-table>
<id>custom-point-table</id>
<schema-ref>custom-point-schema</schema-ref>
</create-table>
<graph>
<title>Custom Interval Graph</title>
<lane>
<title>Points</title>
<table-ref>custom-point-table</table-ref>
<plot-template>
<instance-by>name</instance-by>
<label-format>%s</label-format>
<value-from>name</value-from>
<color-from>concept</color-from>
<label-from>label</label-from>
</plot-template>
</lane>
<lane>
<title>Intervals</title>
<table-ref>custom-interval-table</table-ref>
<plot-template>
<instance-by>name</instance-by>
<label-format>%s</label-format>
<value-from>name</value-from>
<color-from>concept</color-from>
<label-from>label</label-from>
<qualified-by>layout-qualifier</qualified-by>
</plot-template>
</lane>
</graph>
<list>
<title>Custom Regions of Interest</title>
<table-ref>custom-interval-table</table-ref>
<column>name</column>
<column>label</column>
<column>concept</column>
<column>start</column>
<column>duration</column>
</list>
<list>
<title>Custom Points of Interest</title>
<table-ref>custom-point-table</table-ref>
<column>name</column>
<column>label</column>
<column>concept</column>
</list>
</instrument>
</package>
I posted this on the Apple forums, too, and received this answer:
… To customize the icon that is set in the point rendering scenario, your type that is selected in your value-from field needs to have a "Special Value Treatment" defined. In your case, instead of using name, you could safely use event-concept.
The mapping between Value -> (Icon, Color) can be found in the etype documentation. For event concept, that would be: https://help.apple.com/instruments/developer/mac/current/#/dev66257045
Please let me know if that helps!
Kacper
Posted 57 minutes ago by kacperh_ 
In short, the event-concept can control both the color and the symbol for the event, too.
So, I replaced the value-from in the points lane to use the parsed event-concept string, just like the color-from was doing:
<lane>
<title>Points</title>
<table-ref>custom-point-table</table-ref>
<plot-template>
<instance-by>name</instance-by>
<label-format>%s</label-format>
<value-from>concept</value-from>
<color-from>concept</color-from>
<label-from>label</label-from>
</plot-template>
</lane>
And that yielded:

Update query in liquibase

I need to run the below update query in liquibase, but I am not sure about the syntax. Can anyone please help:
update xyz.users
set email = (select CONCAT(username, '#gmail.com ') "email"
from xyz.users )
where email like '%#yahoo.com%' ;
try this
<update tableName="xyz.users">
<column name="email" valueComputed="(select CONCAT(username, '#gmail.com ')
from xyz.users)"/>
<where>email like '%#yahoo.com%'</where>
</update>

XPath to identify a parent based on two related children

Using the following Example, I am trying to create an XPath that will identify the id of Apples where their branchID matches the ID of a branch, but the treeID doesn't match the branch's treeID.
for instance: //growth[#type="apple"][branchID=//branch/#id]/#id - results would be
Granny
Empire
Gala
And //growth[#type="apple"][treeID!=//branch/treeID]/#id - results would be
Granny
Empire
Gala
But I want a query that will only return:
Granny
<xml>
<growth type="apple" id="Granny">
<branchID>ABCD</branchID>
<treeID>456</treeID>
</growth>
<growth type="apple" id="Empire">
<branchID>ABCD</branchID>
<treeID>123</treeID>
</growth>
<growth type="apple" id="Gala">
<branchID>EFGH</branchID>
<treeID>456</treeID>
</growth>
<growth type="flower" id="white">
<branchID>EFGH</branchID>
<treeID>123</treeID>
</growth>
<growth type="flower" id="yellow">
<branchID>ABCD</branchID>
<treeID>456</treeID>
</growth>
<branch id="ABCD">
<treeID>123</treeID>
</branch>
<branch id="EFGH">
<treeID>456</treeID>
</branch>
<tree id="123" />
<tree id="456" />
<tree id="789" />
</xml>
So the required item(s) (where the branchID/treeID pair does not exist in a branch element) will have different index values for the branchID in the list of all //branch/#id values and the treeID in the list of all //branch/treeID values...
//growth[#type="apple"][index-of(//branch/#id,branchID)!=index-of(//branch/treeID,treeID)]/#id
Granny
Nice question to give the little grey cells some exercise on a Friday lunchtime :o)

CSV to XML conversion using MFL

I have an CSV file like:
1234|abc|val1=12;val2=13;val3=14
1235|xyz|val1=15;val2=16;val3=18
I need to convert it into XML using mfl file.
This is my approach:
<StructFormat name='player' delimOptional='n' repeat='*'>
<FieldFormat name='FieldID' type='String' delimRef='' delim='|' dataDelim='"' delimOptional='n' optional='n' codepage='UTF-8'/>
<FieldFormat name='playerName' type='String' delimRef='' delim='|' dataDelim='"' delimOptional='n' optional='n' codepage='UTF-8'/>
<StructFormat name='extraList' delim='|' delimOptional='n' optional='y'>
<FieldFormat name='extra' type='String' delimRef='' delim='|' delimOptional='n' optional='y' codepage='UTF-8' repeat='*'/>
</StructFormat>
</StructFormat>
I don't know how to implement unlimited amount of couples: val1=12 assigned to each player.
Any help? Thank you!
Appears to be generated by tool, check used wizard for
Group Occurrence -> Repeat Delimiter -> Select this option to indicate that the group will repeat until the specified delimiter is encountered.
as per http://docs.oracle.com/cd/E13214_01/wli/docs70/diuser/fmtdef.htm - dated but still ok

Proper use of org.joda.time.contrib.hibernate.PersistentDateTime with webapp configured for different timezone than db

I'm sure this has been encountered many times over, and written about elsewhere. Apologies in advance for the long-winded post, but I wanted to provide as much detail as I could up front.
I have a workstation running the JVM in one timezone (in my case -07:00). I have an Oracle database configured to persist date values in UTC.
I am attempting to use jodatime extension, http://www.joda.org/joda-time-hibernate/, that has custom Hibernate types, one of which is PersistentDateTime.
Here is a sample from my .hbm.xml.
<hibernate-mapping>
<class name="com.spp.mui.domain.MktBidHourly" table="MKTBIDHOURLY">
<comment>Entity to represent the hourly participant bids</comment>
<id name="bidId" type="big_decimal">
<column name="BIDID" precision="22" scale="0" />
<generator class="foreign">
<param name="property">mktBid</param>
</generator>
</id>
<one-to-one name="mktBid" class="com.spp.mui.domain.MktAbstractBid" constrained="true"></one-to-one>
<property name="period" type="org.joda.time.contrib.hibernate.PersistentDateTime">
<column name="PERIOD" length="7">
<comment>Identifies the Period for which the bid applies.</comment>
</column>
</property>
<property name="bidCurveId" type="big_decimal">
<column name="BIDCURVEID" precision="22" scale="0">
<comment>A database-generated unique identifier for the bid curve</comment>
</column>
</property>
</class>
Note the period field in MktBidHourly.
So before executing a unit test for one of my DAOs (using Spring), I use a tool like Toad (for Oracle), to insert some data, that will be queried in the test, something like
insert into MKTBIDHOURLY values (33, (select to_timestamp('2011-08-03
13:00', 'YYYY-MM-DD HH24:MI') from dual), 298384);
The Hibernate query in my DAO looks a little like this
public static final String QRY_FIND_BIDS =
"from MktBid bid where bid.priceNodeId in (:priceNodeIdList) and bid.mktBidHourly.period in (:periodsList) and bid.mktBidType = (:bidType) and bid.participantId = (:participantId)";
Query q = getSession().createQuery(MktQueries.QRY_FIND_BIDS);
q.setParameterList("priceNodeIdList", priceNodeIds);
q.setParameterList("periodsList", periods);
q.setEntity("bidType", bidType);
q.setBigDecimal("participantId", participantId);
realBids = q.list();
Here's the test method
#Test
public void testFindVirtualBids() throws ParseException {
List<MktVirtualBid> candidateBids = new ArrayList<MktVirtualBid>();
MktBidType bidType = new MktBidType(MktBid.VIRTUAL_BID);
candidateBids.add(data.createMktVirtualBid(new BigDecimal(LOCATION_ID_1), false, timeDispatcher.getDateTimeFromXMLDateTime("2011-08-03T13:00:00-07:00"), new BigDecimal(CURVE_ID_1)));
candidateBids.add(data.createMktVirtualBid(new BigDecimal(LOCATION_ID_2), false, timeDispatcher.getDateTimeFromXMLDateTime("2011-08-04T13:00:00-07:00"), new BigDecimal(CURVE_ID_2)));
List<MktVirtualBid> foundBids = dao.findVirtualBids(bidType, new BigDecimal(PARTICIPANT_ID), candidateBids);
Assert.assertEquals(2, foundBids.size());
}
Note the timeDispatcher method is using
ISODateTimeFormat.dateTimeParser().withZone(DateTimeZone.getDefault())
as formatter, and then
parseDateTime(xmlDateTime).withZone(DateTimeZone.UTC)
to obtain a DateTime.
Here's some sample output from a test run (sorry for the poor formatting)
16:22:31,729 DEBUG [AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
16:22:31,732 DEBUG [SQL]
select
mktbid0_.BIDID as BIDID5_,
mktbid0_.BIDTYPE as BIDTYPE5_,
mktbid0_.PARTICIPANTID as PARTICIP3_5_,
mktbid0_.PNODEID as PNODEID5_,
mktbid0_.USEBIDSLOPE as USEBIDSL5_5_
from
DEVMOI2.MKTBID mktbid0_,
DEVMOI2.MKTBIDHOURLY mktbidhour1_
where
mktbid0_.BIDID=mktbidhour1_.BIDID
and (
mktbid0_.PNODEID in (
? , ?
)
)
and (
mktbidhour1_.PERIOD in (
? , ?
)
)
and mktbid0_.BIDTYPE=?
and mktbid0_.PARTICIPANTID=? Hibernate:
select
mktbid0_.BIDID as BIDID5_,
mktbid0_.BIDTYPE as BIDTYPE5_,
mktbid0_.PARTICIPANTID as PARTICIP3_5_,
mktbid0_.PNODEID as PNODEID5_,
mktbid0_.USEBIDSLOPE as USEBIDSL5_5_
from
DEVMOI2.MKTBID mktbid0_,
DEVMOI2.MKTBIDHOURLY mktbidhour1_
where
mktbid0_.BIDID=mktbidhour1_.BIDID
and (
mktbid0_.PNODEID in (
? , ?
)
)
and (
mktbidhour1_.PERIOD in (
? , ?
)
)
and mktbid0_.BIDTYPE=?
and mktbid0_.PARTICIPANTID=?
16:22:31,733 TRACE [AbstractBatcher] preparing statement
16:22:31,798 TRACE [BasicBinder] binding parameter [1] as [NUMERIC] - 262235
16:22:31,798 TRACE [BasicBinder] binding parameter [2] as [NUMERIC] - 262234
16:22:31,799 TRACE [BasicBinder] binding parameter [3] as [TIMESTAMP] - Wed Aug 03 13:00:00 PDT 2011
16:22:31,799 TRACE [BasicBinder] binding parameter [4] as [TIMESTAMP] - Thu Aug 04 13:00:00 PDT 2011
16:22:31,801 TRACE [BasicBinder] binding parameter [5] as [VARCHAR] - D
16:22:31,801 TRACE [BasicBinder] binding parameter [6] as [NUMERIC] - 260699
and then the test fails
Results :
Failed tests:
testFindVirtualBids(com.spp.mui.persistence.hibernate.MktBidDAOTest): expected:<2> but was:<0>
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0
Why won't my test's assertion pass?
I solved this myself. The tricky part in how I was inserting dates. I opted for another route, which unfortunately I cannot share the code for. Suffice it to say I developed a test base class with a routine for loading in CSV files. It leverages Spring's TestContext framework, particularly an #BeforeTransaction annotated method which delegates to helpers to deal with various String types (e.g., date, number, byte[], etc).
The formatter is fundamentally correct. For those who are curious The timeDispatcher's method impl looks like this...
public DateTime getDateTimeFromXMLDateTime(String xmlDateTime) {
if(xmlDateTime == null || "".equals(xmlDateTime)) {
return null;
} else {
return isoParser.parseDateTime(xmlDateTime).withZone(gmtTZ);
}
}
where
isoParser = ISODateTimeFormat.dateTimeParser(DateTimeZone.getDefault());
and
gmtTZ = DateTimeZone.UTC;

Resources