How to identify changes inside changeset when manipulating XML?

Hello


I am developing an interface web for generate liquibase changelog, and I need to identify a change inside a changeset (something like an id attribute) tag for edit purposes.


For example:


I read changelog XML file

Parse it to java object (JAXB parsing) 

Then I manipulate these objects in a web page to save/edit 

And finally persist XML changed file again


The problem: I cannot identify a change in my page (createTable, dropColumn, etc…) for edit and override last one in changelog.xml



**** EDIT ****


For more information about what I am developing:


I create a Changelog

A Changeset that has N Changes (is it a bad practice? should I use 1 change for 1 changeset for id needs?)

Then I can edit it from a web interface, editing a changeset (N changes), save and generate new changelog


Could you help me define the best practice for this kind of manipulation?

Liquibase doesn’t uniquely identify the Change objects, only the changeSet. 


You do normally want one change per changeSet, though. You want to do that because liquibase tries to run each changeSet as a single transaction but most databases auto-commit after each DDL statement (create table, etc.). If you have a changeSet like “createTable A” + “createTable B” if A gets created successfully but B fails to create for some reason, the databse cannot roll back the creation of A and you are stuck in a bad state where liquibase will try to run the changeSet again next time but will fail with “table A already exists”. If they were separate changeSets, then liquibase would know A already exists and just try to re-create B.


In the case of insert, update, delete statemetns where you can have multiple change tags per changeSet and it all runs transactionally but that is a relatively rare case in liquibase usage.


Also, you normally don’t want to go back and edit existing changeSets because you don’t know what other systems may have ran them with the old definition. If you have a changeSet createTable and decide a column needs to be renamed, you want to create a new changeSet with a change rather than editing the original changeSet.


Finally, if you are looking to work with liquibase programatically, you should look at the existing java API liquibase provides. It already has methods for parsing an changeLog into an object model and serializing a DatabaseChangeLog object back into XML and other formats. It may save you a lot of coding and also be able to handle more cases than your JAXB parsing would.


Nathan

Ok, I got it!


But actually I didn’t find a JAXB equivalent API to work with objects. Could you give me a start point?

Start with the javadocs:


http://www.liquibase.org/javadoc/liquibase/Liquibase.html


What you probably want to do is start by creating a Liquibase Object - there are a couple of different constructors you can use. Then call the getDatabaseChangeLog() method, which gives you back a DatabaseChangeLog object. Then call the getChangeSets() method on the DatabaseChangeLog to get back a List of ChangeSet objects. 



Oh. dammit!


I was almost rewriting this facade for xml objects using ObjectFactory generated by JAXB parsing, just adding some particular mandatory fields and input patterns.


I’ll take a look, thank you!