Quantcast
Channel: Liquibase Forums
Viewing all 2993 articles
Browse latest View live

Re : How to build statistics for an update run

$
0
0
Nice! I've never done any Scala, but it is certainly readable. Seems like it would be pretty straightforward to translate to Java or Groovy or whatever. 

I like your github username, by the way. 

Steve Donie
Principal Software Engineer
Datical, Inc. http://www.datical.com/

Looking for 4.0 code review: Action/ActionLogic and testing

$
0
0

Looking for a quick code review/feedback on how the tests for 4.0 will work. 

https://github.com/liquibase/liquibase/pull/340 is the pull request for most of the Action changes I've done with 4.0 so far, but it is getting a bit overwhelming already. Below is a more packaged few areas I'd be interested in feedback on. 

The major refactoring for 4.0 (and what I’ve started on) is a simplifying and consolidating all the database (and other external interactions) down to:

  • -         Action classes that describe a particular thing you want done (like AddPrimaryKeyAction or SnapshotDatabaseObjectsAction).
  • -         ActionLogic classes take the Action class and transform it into something that can be executed. These classes are prioritized so you can have one implementation for mysql and another for oracle and a 3rd parth-specific implementation for oracle in an extension

These classes take the place of the Change, Statement, Generator, and Snapshot classes in 3.x.

Action Examples:

AddAutoIncrementAction: https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/main/java/liquibase/action/core/AddAutoIncrementAction.java

 SnapshotDatabaseObjectsAction: https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/main/java/liquibase/action/core/SnapshotDatabaseObjectsAction.java

Notice that these are pure data holder objects, and so I purposely did not use get/set methods but instead just public fields. It does implement liquibase.ExtensibleObject which gives you a get(fieldName) and set(fieldName, value) interface as well as the ability for extensions to add additional properties without subclassing.

ActionLogic Examples:

AddAutoIncrementLogic: https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/main/java/liquibase/actionlogic/core/AddAutoIncrementLogic.java

 AddAutoIncrementLogicMysql: https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-mysql/src/main/java/liquibase/actionlogic/core/mysql/AddAutoIncrementLogicMysql.java

 SnapshotTablesLogicJdbc: https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/main/java/liquibase/actionlogic/core/SnapshotTablesLogicJdbc.java

 SnapshotTablesLogicOffline: https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/main/java/liquibase/actionlogic/core/SnapshotTablesLogicOffline.java

 Notice both AddAutoIncrementLogic and AddAutoIncrementLogicMysql handle AddAutoIncrementAction classes, but which is picked depends on the database type.

Similarly, both SnapshotTalbesLogicJdbc and SnapshotTablesLogicOffline both can handle SnapshotDatabaseObjectsAction but which is used depends on the connection on the database as well as the type of object in SnapshotDatabaseObjectsAction

You also see in AddAutoIncrementLogic*, how I am no longer just bulding raw Strings, but instead a smarter StringClauses class I created which lets me build up a standard SQL statement in the base class, and then replace, alter and/or move pieces much easier in database-specific Logic subclasses.

Unit Testing

So now that I have everything using a common Action/ActionLogic pattern, I need to test them. There is unit-test style tests that I do such as:

-        AddAutoIncrementLogicTest https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/test/groovy/liquibase/actionlogic/core/AddAutoIncrementLogicTest.groovy

-        SnapshotTablesLogicJdbcTest https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/test/groovy/liquibase/actionlogic/core/SnapshotTablesLogicJdbcTest.groovy

-        SnapshotTablesLogicOfflineTest https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/test/groovy/liquibase/actionlogic/core/SnapshotTablesLogicOfflineTest.groovy

-        SnapshotColumnsLogicJdbcTest https://github.com/liquibase/liquibase/blob/4.0_action/liquibase-core/src/test/groovy/liquibase/actionlogic/core/SnapshotColumnsLogicJdbcTest.groovy

These tests work well for easily checking my standard “checkStatus()”  method which does no database interaction (AddAutoIncrementLogicTest) or even test methods passing in example resultSets I’ve seen (SnapshotColumnsLogicJdbcTest). I’m using spock for these tests because spock is awesome.

Integration Testing

The meat of the logic in the Action/ActionLogic classes, however, is whether the SQL executed against the database by each ActionLogic is correct and does what it is supposed to do. And, we can’t really know if it works like it is supposed to without running it against the database. This is where TestMD comes in.

 TestMD lets me write tests like this:

 Looking at AddAutoIncrementActionTest.“Can apply standard settings to column name” as an example, you can see it is still using spock as the test framework because it is still awesome, but there are a couple things I’m doing differently:

  1.   I’m using more of a generative testing pattern, where the “where” block isn’t just a static table, but instead calls a method which will build up all permutations of the items in each list passed to CollectionUtil.permutations. Within the test itself, the assertions are not hard-coded assertions but instead it looks at the permutation values and then checks what should be right based on those values.
  2. The checking of the permutation uses TestMD which lets me say “this permutation is defined by these three attributes, and what is ran against the database is this SQL plan”. When the test is ran successfully, it creates an “accepted.md” file which lists the SQL plan ran for each permutation. For future times it is ran, if the SQL has changed the test is re-ran to verify it still does what it expects. If the SQL has not changed, it is not re-validated. 

Example accepted.md files:

which are nicely formatted by github as:

 My hope for TestMD is that it gets us the “test everything against the live database” advantage from integration testing, but since without the sloooow performance of integration testing. When I run AddAutoIncrementActionTest against Mysql the first time, the 65 test iterations take 33s to run.  Once I have ran run them once, I (or any other contributer) I just have to run “all tests” like normal and they take just milliseconds to run—unless the generated SQL changed. If the generated SQL is ever changed, TestMD will re-run the verification for just the changed permutations. If I (or a committer) doesn’t have the correct environment set up to test the permutation, it will be marked as “unverified” in the accepted.md file and when I see the pull request I’ll see it is unverified, I can look at the SQL changes to make sure they look right and/or run them with the correct environment to ensure they are correct.

 My hope is that the combination of generative permutations + testmd will give much, much better test coverage than we’ve ever had before while allowing us to always run all tests and therefore catch all expected and unexpected changes in SQL.

 So far I think that plan is panning out because I am definitely finding a lot of parameter permutations I’ve never really handled before just in the couple *ActionTests I’ve done so far. The biggest problem has been now needing to actually handle all those error cases.

 Let me know what you think

 Nathan

Re : Liquibase Inheritance creation

Re : Liquibase Inheritance creation

$
0
0
Also, this forum is more for people changing liquibase itself rather than how to use Liquibase.

Steve Donie
Principal Software Engineer
Datical, Inc. http://www.datical.com/

Re : Liquibase Inheritance creation

$
0
0
Thanks for the information Steve. I did not get much answers regarding the inheritance in liquibase from the links you provided.  Would it be helpful and easier to implement inheritance using hibernate concepts.

Re : Bootstrap performance on Oracle with lots of Table

$
0
0
There were some good performance improvements with Liquibase 3.4.0. Can you try with that version?

Nathan

Re : Liquibase modify dbchangelog table

Liquibase 3.4.0 loadData fails on mariaDB.

$
0
0
Seems like loadData from csv fails after csv file contains more than 50 (default threshold in InsertSetStatement) rows on mariaDB 5.5.
Related to CORE-864.

After 50 rows, data is split into two inserts and second insert is not recognized:

[ERROR] Reason: liquibase.exception.DatabaseException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version fo
r the right syntax to use near 'INSERT INTO EMTimeZone (Name, IsSystemOwned, RecordVersion) VALUES ('America/Daw' at line 2 [Failed SQL: INSERT INTO EMTimeZone
(Name, IsSystemOwned, RecordVersion) VALUES ('Etc/GMT+12', '1', '1'),('Etc/GMT+11', '1', '1'),('MIT', '1', '1'),('Pacific/Apia', '1', '1'),('Pacific/Midway', '1
', '1'),('Pacific/Niue', '1', '1'),('Pacific/Pago_Pago', '1', '1'),('Pacific/Samoa', '1', '1'),('US/Samoa', '1', '1'),('America/Adak', '1', '1'),('America/Atka'
, '1', '1'),('Etc/GMT+10', '1', '1'),('HST', '1', '1'),('Pacific/Fakaofo', '1', '1'),('Pacific/Honolulu', '1', '1'),('Pacific/Johnston', '1', '1'),('Pacific/Rar
otonga', '1', '1'),('Pacific/Tahiti', '1', '1'),('SystemV/HST10', '1', '1'),('US/Aleutian', '1', '1'),('US/Hawaii', '1', '1'),('Pacific/Marquesas', '1', '1'),('
AST', '1', '1'),('America/Anchorage', '1', '1'),('America/Juneau', '1', '1'),('America/Nome', '1', '1'),('America/Yakutat', '1', '1'),('Etc/GMT+9', '1', '1'),('
Pacific/Gambier', '1', '1'),('SystemV/YST9', '1', '1'),('SystemV/YST9YDT', '1', '1'),('US/Alaska', '1', '1'),('America/Dawson', '1', '1'),('America/Ensenada', '
1', '1'),('America/Los_Angeles', '1', '1'),('America/Tijuana', '1', '1'),('America/Vancouver', '1', '1'),('America/Whitehorse', '1', '1'),('Canada/Pacific', '1'
, '1'),('Canada/Yukon', '1', '1'),('Etc/GMT+8', '1', '1'),('Mexico/BajaNorte', '1', '1'),('PST', '1', '1'),('PST8PDT', '1', '1'),('Pacific/Pitcairn', '1', '1'),
('SystemV/PST8', '1', '1'),('SystemV/PST8PDT', '1', '1'),('US/Pacific', '1', '1'),('US/Pacific-New', '1', '1'),('America/Boise', '1', '1');
[ERROR] INSERT INTO EMTimeZone (Name, IsSystemOwned, RecordVersion) VALUES ('America/Dawson_Creek', '1', '1');]

Preconditions column exists

$
0
0

Using liquibase 3.4.1 I want to rename my columns in Oracle to uppercase if they exist. I always get the following error no matter what I do:

Unexpected error running Liquibase: ORA-00957: duplicate column name
 [Failed SQL: ALTER TABLE "SYSTEM"."MYTABLE" RENAME COLUMN "id" TO "ID"]

My precondition looks like this:

    <changeSet author="sake" id="gfdgfd" dbms="oracle" objectQuotingStrategy="QUOTE_ALL_OBJECTS">
            <preConditions onFail="MARK_RAN" >          
                      <columnExists tableName="MYTABLE" columnName="id" />
            </preConditions>
            <renameColumn tableName="MYTABLE" oldColumnName="id" newColumnName="ID"/>
</changeSet>

I tried following: - removing objectQuotingStrategy - adding SQL check:

<sqlCheck expectedResult="1">
                SELECT COUNT(*) FROM USER_TAB_COLUMNS
                WHERE TABLE_NAME='MYTABLE'
                AND COLUMN_NAME='id'
            </sqlCheck>

Any idea why this happens? :/

Password encryption in Liquibase properties file

$
0
0
To manage migration with Liquibase, I am using a properties file that holds all the information about the database connection. The pitfall of this file is that it discloses my database password since it is a plain text file. Is there a way to avoid that ? Does Liquibase support any kind of encryption for the properties file ?

Re : Password encryption in Liquibase properties file

While executing the liquibase script, how to print the comment the one which is defined in the above changeset ?

$
0
0
<changeSet id="Aug050815" author="myApplication" >
   <comment>Test comments 1</comment>
   </changeSet>
</databaseChangeLog>


While executing the liquibase script, how to print the comment the one which is defined in the above changeset ?

Silently stopping Liquibase at mid-update

$
0
0

Is there any way I can cancel a Liquibase update after I started it?

I've a list with around 5000 changesets, and I need to prevent all changesets from a specific point forward, to not be executed if a specific condition occurs in one of those scripts.

Since putting <preConditions> in all of the existing scripts, and to all the new ones that will be created until the end of days, is not a doable approach, I was looking into an alternative and already tried the following:

  • Created a <customChange> and throw an exception
  • Created an invalid <sql> statement
  • Added <stop/> in the <changeset>

All cases work, but they also throw thousands of log lines (that I can't have), because I need a silent stop.

Translator from MySQL to liquibase

$
0
0
Do you guys know if there are any tools to convert SQL scripts into LB .xlm files? It would really come in handy in order to import all my previous changes and sum them up in order to be able to do a fresh install of my app.

Re : While executing the liquibase script, how to print the comment the one which is defined in the above changeset ?

$
0
0
You would need to run Liquibase programatically (i.e. from your own Java code) and write a class that implements the ChangeExecListener interface. The class implementing the interface would get notified of all changes and would be able to examine the changeset and print out the comment if there was one. 

There is currently no way to specify a ChangeExecListener from the command line, maven, ant, etc. 

Steve Donie
Principal Software Engineer
Datical, Inc. http://www.datical.com/

Re : Translator from MySQL to liquibase

$
0
0
I assume you mean .xml rather than .xlm

What you would do is:

1. Create a clean, empty database.
2. Apply the SQL scripts that you have to the database.
3. Run the Liquibase generateChangelog command on that database.

Note that this will only capture the end state of the database - i.e. if you have a SQL script that creates a table, and then another later SQL script that drops the table, the XML will not have a <createTable> and a <dropTable>.

Steve Donie
Principal Software Engineer
Datical, Inc. http://www.datical.com/

Liquibase java not applying changesets

$
0
0
Hi,

I'm using Liquibase directly from Java 8, after adding the Maven dependency for Liquibase 3.4.0.
My project includes some database interactions with an Oracle 11g database (I included ojdbc6.jar in the build path and liquibase-oracle-3.0.0.jar as a maven dependency). My changelog is composed with a single changeset of creating a table if it doesn't exist (precondition with onSQLOutput="TEST"). When I run this changelog with the command line, everything works fine, but when I launch it with my Java application, something goes wrong (my simplified java code is written down below).
With the update action, this task simply does nothing. With updateSQL or futureRollbackSQL, it generates a file creating the tables of Liquibase (databasechangelog and databasechangeloglock), but does not include my changeset.
I'm 100% sure that the table does not exist on the given database.

I'm a little lost now, I don't know what to do or what's wrong. I checked at some examples from other topics, but I can't see any error in my code in my code (well... there should be one, obviously). Even posted this question on stackoverflow and didn't get any answer.

So I would be very grateful if you could help me point out my mistake(s) on this application !

Tell me if you need more details.

Thank you for your answers.

Java Code
  1. Connection c = null;
  2. Database database = null;
  3. PrintWriter pw = null;
  4. File file = null;
  5. liquibase.Liquibase liquibase = null;
  6. contexts = db+"."+user;
  7. try {
  8.     pw = new PrintWriter(new FileWriter(file));
  9.     // Get connection
  10.     c = SQLManager.getInstance().getConnection(db, user, passwd);
  11.     // Get liquibase connection
  12.     database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(c));
  13.     liquibase = new liquibase.Liquibase(new DatabaseChangeLog(fsource), new FileSystemResourceAccessor(),
  14.             database);
  15.     // Run liquibase action
  16.     switch (realAction) {
  17.         case Constants.LIQUIBASE_ACTION_FUTUREROLLBACKSQL:
  18.             liquibase.futureRollbackSQL(pw);
  19.             break;
  20.         case Constants.LIQUIBASE_ACTION_UPDATESQL:
  21.             liquibase.update(contexts, pw);
  22.             break;
  23.         case Constants.LIQUIBASE_ACTION_UPDATE:
  24.             liquibase.update(contexts);
  25.             if (!c.getAutoCommit())
  26.                 c.commit();
  27.             break;
  28.         default:
  29.             throw new RuntimeException("Action not implemented");
  30.     }
  31.     pw.close();
  32.     database.close();
  33.     c.close();
  34. } catch (IOException | SQLException | LiquibaseException e) {
  35.     throw new Exception(e.getMessage());
  36. } finally {
  37.     if (c != null) {
  38.         try {
  39.             c.close();
  40.         } catch (SQLException e) {
  41.             throw new RuntimeException(e.getClass() + ": " + e.getMessage());
  42.         }
  43.     }
  44. }

Re : Preconditions column exists

$
0
0
Oracle doesn't consider case when checking for table names or column names.
Thus you don't even have to rename your columns !

Re : Silently stopping Liquibase at mid-update

$
0
0
If you know the number of changesets you have to apply, you could use the equivalent of command line's action "updateCount <value>" in whatever way your are using liquibase.

Or is there no way to break your changelog into much smaller pieces? If you have to stop changesets from executing starting at some point, then you should have a way to create much smaller changelogs (with eventually one big changelog composed with includes).

Re : Liquibase java not applying changesets

Viewing all 2993 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>