Having this kind of tooling would be great. There are many users that are running, say, database version 1.4 and want to upgrade to the latest. If they were running our war file things would be fine, but they are just using our database model. Our liquibase xml file has changesets from version 1.2 all the way to version 1.5. Liquibase can export a sql file currently, but it expects to run all of the statements. This won't work because the user has run all statements between 1.2-1.4 and only needs 1.4-1.5.

In the past we would keep our database updates in a mysql script that checked their database version and only ran the "changesets" that hadn't been run yet. In mysql you have to do this with procedures to be able to do the "if" statements. See below.

Surely liquibase could export something like this just modified to look at the databasechangelog instead of our database_version. I don't know what this looks like in other databases, but it probably is similar.

update-to-latest.sql:
#----------------------------------------
# OpenMRS Datamodel version 1.1.10
# Ben Wolfe                 May 31st 2007
# Adding township_division, region, and # subregion attributes to patient_address # and location tables
#----------------------------------------

DROP PROCEDURE IF EXISTS diff_procedure;

delimiter //

CREATE PROCEDURE diff_procedure (IN new_db_version VARCHAR(10))
BEGIN
        IF (SELECT REPLACE(property_value, '.', '0') < REPLACE(new_db_version, 
'.', '0') FROM global_property WHERE property = 'database_version') THEN
        SELECT CONCAT('Updating to ', new_db_version) AS 'Datamodel Update:' 
FROM dual;
        
        ALTER TABLE `person_address` ADD COLUMN `region` varchar(50) default 
NULL;
        ALTER TABLE `person_address` ADD COLUMN `subregion` varchar(50) default 
NULL;
        ALTER TABLE `person_address` ADD COLUMN `township_division` varchar(50) 
default NULL;
        
        ALTER TABLE `location` ADD COLUMN `region` varchar(50) default NULL;
        ALTER TABLE `location` ADD COLUMN `subregion` varchar(50) default NULL;
        ALTER TABLE `location` ADD COLUMN `township_division` varchar(50) 
default NULL;
        
        UPDATE `global_property` SET property_value=new_db_version WHERE 
property = 'database_version';
        
        END IF;
END;
//

delimiter ;
call diff_procedure('1.1.10');

#----------------------------------------
# OpenMRS Datamodel version 1.1.11
# Ben Wolfe                 Dec 21st 2007
# Removing the unneeded auto increment values
# on patient_id and user_id.
#----------------------------------------

DROP PROCEDURE IF EXISTS diff_procedure;

delimiter //

CREATE PROCEDURE diff_procedure (IN new_db_version VARCHAR(10))
BEGIN
        IF (SELECT REPLACE(property_value, '.', '0') < REPLACE(new_db_version, 
'.', '0') FROM global_property WHERE property = 'database_version') THEN
        SELECT CONCAT('Updating to ', new_db_version) AS 'Datamodel Update:' 
FROM dual;
        
        ALTER TABLE `patient` MODIFY COLUMN `patient_id` int(11) NOT NULL;
        ALTER TABLE `users` MODIFY COLUMN `user_id` int(11) NOT NULL;
        
        UPDATE `global_property` SET property_value=new_db_version WHERE 
property = 'database_version';
        
        END IF;
END;
//

delimiter ;
call diff_procedure('1.1.11');

etc etc etc.....


Ben

Thomas Vial wrote:
Hi all!
I am considering introducing LiquiBase into a project I'm currently working on. After thinking about the process we usually follow wrt staging from development to Q&A and then to production, I feel that a very useful feature would be the ability to update any existing database to the most recent version, whatever changes have been performed on that particular DB before -- the same, unique script would run whatsoever and achieve the desired result. I have reviewed various threads on the mailing list, particularly this one: http://sourceforge.net/mailarchive/forum.php?thread_name=4ef551420902140711j5a434eacg7250ec84af2c7b04%40mail.gmail.com&forum_name=liquibase-user <http://sourceforge.net/mailarchive/forum.php?thread_name=4ef551420902140711j5a434eacg7250ec84af2c7b04%40mail.gmail.com&forum_name=liquibase-user> I understand that translating all of elaborated LB's functionalities into some dialect-dependant of SQL is virtually impossible (see Paul's answer in the aforementioned thread). However, in my mind it would be easy to add a test for every changeset, with SQL code like this one: -------------------------------------------- if exists (select 1 from databasechangelog where id='id1' and author='me' and filename='...') begin
   create table XXX... // SQL generated for changeset 1
end
if exists (select 1 from databasechangelog where id='id2' and author='me' and filename='...') begin
   create table XXX... // SQL generated for changeset 2
end
--------------------------------------------
The id's, author's and filename's, which I understand make up the unique key of the changeset, would be pulled from the changelog just like the contents of their corresponding changesets. The syntax for the if's would be dialect-dependant of course, hopefully not a big deal. I guess the functionality, if used correctly (i.e. with staging environments undergoing the same changes in the same order, only at different rates), could have some strong benefits, some of which were pointed by others before: * being able to generate the SQL from the changelog only -- no connection to the target DB required * packaging a unique SQL script with the artifacts of the project (e.g. maven assembly); that same script could be run confidently on all environments, with no adjustment like removing snippets that are irrelevant in some environments * thus having the package validated as a whole, enforcing consistency of all its components * having all production staff pull their stuff from the same, unique package: SQL goes to the DBA, WAR goes to the web team, and so on * making scripts idempotents: if the DBA's procedure requires to re-run the script for some reason, all parts that were not executed the first time, if any, would have no side effect * not forcing DBAs into running LB themselves against the databases. These folks usually have their own set of tools and don't like to have to adopt others (especially all that Java mumbo-jumbo, we real men only know of SQL, perl and ksh ;-) Of course, making independant changes by hand on the production DB would break it all, just as it would break the result of an updateSQL command. Using the suggested functionality would require just as much discipline. This is why I think it would make sense, as an optional feature of course. I guess some care may be necessary with transaction management and ability to rollback (like knowing if a changeset was interrupted in the middle of a previous run). Any thoughts? Sorry if you feel this topic is just another avatar of the thread I mentioned above. I wanted to point out a cheap, possible solution, and some benefits beyond all those that were already identified. Thomas
------------------------------------------------------------------------

------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
------------------------------------------------------------------------

_______________________________________________
Liquibase-user mailing list
Liquibase-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/liquibase-user
------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
Liquibase-user mailing list
Liquibase-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/liquibase-user

Reply via email to