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

Re : Liquibase 3.3 : insert SYSDATE into DATE field fails with 'ora-01858'

$
0
0
Hi Nathan,

It's using liquibase tags:

        <insert tableName="DWP_VERSION">
            <column name="VER_ID_VERSION_MAJOR" value="3"/>
            <column name="VER_ID_VERSION_MINOR" value="0"/>
            <column name="VER_LIBELLE_VERSION" value="INFOCENTRE V3.00"/>
            <column name="VER_DATE" value="SYSDATE"/>
        </insert>
With VER_DATE being a DATE column.

            <column name="VER_DATE" value="SYSTIMESTAMP"/>
works fine.

Liquibase is on a french windows , database on english linux, and oracle sessions set in french with :
view NLS_SESSION_PARAMETERS says 
NLS_DATE_FORMAT : DD/MM/RR
NLS_TIMESTAMP_FORMAT : DD/MM/RR HH24:MI:SSXFF

but view NLS_DATABASE_PARAMETERS says 
NLS_DATE_FORMAT : DD/MON/RR
NLS_TIMESTAMP_FORMAT : DD-MON-RR HH.MI.SSXFF AM

Regards





Re : Calling sql scripts with some parameters

$
0
0
Ok Nathan, now I see.
We're using Ant but not with the liquibase tasks. We're calling liquibase scripts with Ant giving parameters like url, username...
I will do a refactor of this to use Liquibase Ant tasks as recommended here : http://www.liquibase.org/documentation/ant/index.html
(hoping I'll still be able to update/rollback my different targets as I do now)

Regards,
Frederic

Skip checksum verification

$
0
0
We have written an application using liquibase which is widely distributed to users outside of our control. So it is important that upgrades are solid and reliable. Liquibase has been terrific for us except that the way checksums are implemented causes more difficulty than assistance.

Is there a way to disable checksum verification in liquibase, either in total or for just one changeset?


More information:

To avoid lots of responses telling me how daft we are for disabling checksums, I'll and explain some of our use cases.

1. We sometimes go back and fix an old migration which wasn't coded quite right. We don't want it to run again for users who executed it fine. We can manually add a checksum value to the changeset, so we have a workaround which is annoying but OK.

2. We have a changeset which imports some data from CSV to set up a user's database the way we want. We never want to overwrite that data later on in an upgrade, as the user may have changed it in all sorts of ways. However we also want to improve that setup data in a future release so that new users of our application get new and improved setup data. That migration should not run again for existing users, but it also should not fail the checksum because the CSV file changed. It is quite hard to catch this checksum failure problem with unit tests since we would in theory have to upgrade every release of the application to every other release.

To my mind, the whole concept of checksums is poorly implemented for our particular needs. Checksums should warn developers committing bad changes by accident. If the checksum was committed to version control then junit or the CI could warn you of changes. If every changeset was put in a separate file, then we could create commit hooks to warn on changes to old files.

However by making a checksum a feature which blocks upgrade in an environment we don't control for a changeset which has already run, for a change we didn't want to execute anyway since it was already run. Well, that's something I'd like to be able to disable.


Thanks
Ari

Re : Liquibase 3.3 : insert SYSDATE into DATE field fails with 'ora-01858'

$
0
0
It should work if you use valueDate="SYSDATE" instead of value="SYSDATE".

Liquibase doesn't inspect the table to determine the type, so value="" normally assumes it's a string and needs to be quoted but there is a special case for the "current time" function which is set to SYSTIMESTAMP for oracle.

Using valueDate instead tells liquibase the value is a date and if it's a known date function to not quote it which should resolve your issue.

Nathan

Re : Calling sql scripts with some parameters

$
0
0
If you don't want to refactor your ant tasks, you can pass in paramemer values though the command line or set them as system properties.

Nathan

Re : Return output messages from oracle chnageset execution to Liquibase

$
0
0
Hi Nathan,

I checked the jira mentioned above, i believe you are planing to fix this in 3.4.0.

If my understanding is correct, we will now be seeing the stdout in return for each sql statement getting executed via liquibase?

Please advise.
Thanks in advance.

Re : Calling sql scripts with some parameters

$
0
0
Well I did the refactor, and it's working fine !
Thanks for all.

So now I use Ant to call directly liquibase, giving some <liquibase:changeLogParameters> that are directly used by the scripts called with <sqlFile>, used as : '${databaseCdcTarget}' for example.
It now works very well but it was quite a mess to set up as I ran throught a lot of path problems.
I will therefore open a new thread about not logged path errors.

Also,  previoulsy I was calling one target with parameters to give the command update/updateSql/rollback/rollbackSQL and to add the rollback tag for example. But now I have 4 targets. and I can't use the same target for update and updateSQL because if I set outputFile="" (if I don't want to log the sql requests but want to really update) then I have an error. So I duplicated <liquibase:updateDatabase>, one with outputFile and one without. Is there a way to avoid that?

Regards

Replacement for missing liquibase classes moving from liquibase 2.0.3 to 3.3.0

$
0
0

I have a project using liquibase-core 2.0.3. When I updated to liquibase-core 3.3.0 I'm getting a lot of compiler class not found errors for the classes below.

Any help on info on where/what they have been replaced with is much appreciated?



import liquibase.change.core.AnonymousChange;

import liquibase.database.core.MaxDBDatabase;

import liquibase.database.typeconversion.TypeConverter;
import liquibase.database.typeconversion.core.CacheTypeConverter;
import liquibase.database.typeconversion.core.DB2TypeConverter;
import liquibase.database.typeconversion.core.DefaultTypeConverter;
import liquibase.database.typeconversion.core.DerbyTypeConverter;
import liquibase.database.typeconversion.core.FirebirdTypeConverter;
import liquibase.database.typeconversion.core.H2TypeConverter;
import liquibase.database.typeconversion.core.HsqlTypeConverter;
import liquibase.database.typeconversion.core.InformixTypeConverter;
import liquibase.database.typeconversion.core.MSSQLTypeConverter;
import liquibase.database.typeconversion.core.MaxDBTypeConverter;
import liquibase.database.typeconversion.core.MySQLTypeConverter;
import liquibase.database.typeconversion.core.OracleTypeConverter;
import liquibase.database.typeconversion.core.Postgres83TypeConverter;
import liquibase.database.typeconversion.core.PostgresTypeConverter;
import liquibase.database.typeconversion.core.SQLiteTypeConverter;
import liquibase.database.typeconversion.core.SybaseASATypeConverter;
import liquibase.database.typeconversion.core.SybaseTypeConverter;

import liquibase.snapshot.jvm.DB2DatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.DerbyDatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.H2DatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.HsqlDatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.InformixDatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.MSSQLDatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.MySQLDatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.OracleDatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.PostgresDatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.SQLiteDatabaseSnapshotGenerator;
import liquibase.snapshot.jvm.StandardJdbcDatabaseSnapshotGenerator;

Looking for Feedback on Liquibase 4.0 Roadmap

$
0
0
As I am wrapping up 3.3.x changes and looking forward to what changes and features people are asking for and what I would like improved, I am thinking it is time to look at larger changes around a Liquibase 4.0 release. 

My most-likely overly-ambitious goal for Liquibase 4.0 is to do a major housecleaning of the Liquibase codebase to simplify it while increasing testability and test coverage. There have been changes in scope and requirements over the last 7 years and the codebase is getting a bit over-complex and haphazard. This makes it harder for me to maintain and a barrier to entry for contributors.

Previously I thought about trying to break this into a few smaller blocks/themes and focus on one for 3.4, one for 3.5, etc. until they are done and have 4.0 be just the final cleanup “no more changes” release. After doing some work with the testing and the snapshot logic, however, I think they all bleed into each other enough to make it much easier to do a single major release that just breaks everything.

The jump to 4.0 will signify compatibility-breaking API changes, but there should be no changes to the changelog format: 4.0 should be a drop-in replacement for anyone just using a changelog and not writing extensions etc.

The major themes/changes I’m looking to make are:

Improvement of how state is managed and high-level functions are called
Currently there is the liquibase.Liquibase façade object that wraps many common functions with method parameters, a variety of “configuration” objects (such as DiffOutputControl), and a heavy use of singletons. Ant/maven/command line etc. call out to the Liquibase façade as best they can.

The problems with this setup include:
  • Liquibase facace is getting overly large and complex
  • Difficult to add/override standard command functionality in extensions
  • There is a lot of duplicated setup/validation logic in ant/maven/command line/etc. before calling the façade objects
  • Singletons not always cleaned up between calls and/or run into each other
  • Difficult/impossible for extensions to rely on configuration that does not happen to be on the method parameters passed along
  • Method signatures get long but still don’t have all parameters we sometimes need

Planned changes:
  • Switch to using “Command” objects in favor of a monolithic Liquibase façade
    • Allows command logic to be encapsulated and more easily extended including validation and setup
    • Allows new commands to be written within extensions and exposed through command line, maven, etc.
  • Create a hierarchical “Scope” object
    • Works similar to AngularJS $scope where a root container object is created and passed along to sub-methods. 
    • Along the call chain, new attributes can be added that are only visible to methods further down the call chain
    • Root Scope object created as part of the Command execution and builds from there
    • Replace use of singletons with objects added to the Scope
    • Ideally we can access the scope object without needing to include it in every method signature, but unsure on a good implementation yet
    • Configuration objects available from Scope object

Improved Testing/Testability
Liquibase currently doesn’t have a great way to handle testing of the interaction with the database. Traditionally, I’ve had the liquibase-integration-tests module which mainly uses a set of changeSets with example changes and scenarios and preconditions to test that they ran successfully.

Problems with this setup include:
  • Slow to execute
  • Contributors need special database setup to test and so cannot normally run the tests to validate their changes
  • Preconditions are not designed to be an assertion library
  • No structure to tests to know what is tested and what is not

Beyond the database interaction tests, there is some unit test coverage but not enough

Planned changes:
  • Fully implement my new “VerifiedTest” framework. The idea is that each test creates a simple text description of the interaction (such as the SQL string to execute) and a way to validate the test passed. Previous test run text descriptions and the results are stored in a markdown-formatted file. On each test run, the text description of the code is compared to the last run and if they are the same (most of the time) they are just marked as passed. If they are different, the validation code is used to make sure the new version is still correct and then the markdown file is updated. If the validation fails, the test fails. If the validation cannot run (database is unavailable) the markdown file is updated but marked as “not validated”
    • The hope is to allow for database tests in a more standard test framework, allow most integration tests to run in unit-test speed, allow contributors to know when they have potentially broken things even if they don’t have the database to test against, and provide a way for me to see how the interactions have changed from within the pull request system
  • Finish move to Spock testing
  • TDD develop new and changed 4.0 functionality to increase general coverage
  • Use generative testing to ensure all permutations are tested, both with standard unit test and “VerifiedTest”

Use more 3rd party libraries
In the past, I’ve tried to avoid the use of 3rd party libraries in order to avoid jar-hell for people using Liquibase. I think there are few places where there have been enough convergence on a “standard” and/or isolated-enough use cases that I should introduce some 3rd party libraries in order to simplify my codebase. In particular:
  • SLF4j instead of custom logging wrapper over java.logging
  • Apache Commons-CLI: Only really needed if running command-line version where jar-hell doesn’t really matter since it’s more of a packaged application
  • Considering but not decided (need to research more, don’t want to cause issues for users with different versions or technologies)
    • Serialize/Deserialize logic? Need to research options for XML and/or YAML/JSON
    • Dependency Injection/Class finding/Classloading logic? Maybe spring? Maybe OSGi?

Improve database snapshot functionality
Database Snapshot support was never really central to Liquibase, but it has become more and more used within Liquibase. The current implementation is overly complex and the way it abstracts the logic for extension doesn’t really fit with how extension is happening in real life leading to performance issues and excessive code writing. Furthermore, testing is slow and difficult to impossible.

Planned changes:
  • Change snapshot algorithm from starting with a single object (schema, table, etc.) and then recursively finding related objects to a process where we first just fetch all objects in the database and then connect up those objects in memory if needed. The base object to snapshot (a schema, a table, a column, etc.) is still passed to each of the fetch methods which can limit what is read from the database if it so chooses, but it will be a much less convoluted process
  • Ensure the snapshot interfaces and base classes do not make JDBC or even RDBMS assumptions. The snapshot process should be able to handle non-traditional “databases” such as hibernate mappings, changelog files, mongodb and other nosql database, etc. Ideally it would even be able to snapshot non-databases such as server configurations although that is less important.
  • Ability (or at least API hooks) to support data diff
  • Add a way to specify subsets of items to not snapshot. For example, don’t include tables that match the name “ADM_.*” 
    • Needs to be able to do something like “snapshot all objects but only diff the data in “.*_lookup” tables and only include tablespace information for “.*_lob” tables
  • Use VerifyTest framework to ensure good testing of the snapshot functionality
  • Better model the connection between primary keys, foreign keys, unique constraints, and indexes 

Improve Change and SQL Generation logic
Currently we have Change classes which represent what can be in a changeLog file. These generate one or more Statement objects which are a lower-level logical database change. The Statement objects are then fed to SqlGenerator objects which create the actual SQL based on the Statement and the Database.

Planned changes:
  • Remove Change/Statement distinction in favor of a more general purpose Action class. The current Change and Statement objects are mainly duplicates of each other and there doesn’t really need to be a distinction. 
    • The new Action classes will also include things that are currently outside the scope of the Change/Statement objects such as the metadata lookup. Bringing the metadata lookup into the same “Action” framework will allow us to have just one code path for all “I want to do X against this database” logic
  • Change most SqlGenerator logic from building up SQL strings programmatically to using simple text files with templates of the SQL that can be filled in

Improve Cross-database Logic

Both update and snapshot logic currently have issues with cross-database functionality.

Data types is the major problem:
On update, sometimes people want to be able to specify a simple type like “text” and have that mean “clob” on one database and “nvarchar(max)” on another. Other times, people want “text” to mean “clob” on one database but “text” (not nvarchar(max)) on another. Or “int” should be the database default “int” on all but oracle where it should be number(23). Then there are boolean types where some databases don’t support Boolean so you need to use “bit” but you also sometimes need to specify a actual “bit” type which isn’t used as a boolean and so should be tinyint on the db that supports Boolean but not bit.

On snapshot, if you are comparing a mssql and a mysql database should you mark the columns as different if they data types are int vs. integer? What about nvarchar(10) vs varchar(10) when one doesn’t support nvarchar? Bit vs. Boolean? Text vs. nvarchar(max)? Text. Vs. Text (when mssql’s nvarchar(max) is more like mysql text?)

On generateChangeLog, do you generate generic types or database-specific types?

Case handling is the other major problem:
How should differences in case be handled in comparisons? When should case sensitivity be preserved and when should it not matter?

There are other issues too:
  • Auto-generated names vary, how do we best handle those? 
  • If Mysql has an index on a FK column but oracle doesn’t, is that a difference to fix since mysql auto-generates the index? 
  • If you try to create a sequence on a database that doesn‘t suppport sequences, should that be an error? Or expected to fail and skipped?
    • Are sequences different than other non-supported features like non-clustered PKs, full text indexes, etc.?

General Code Improvements
  • Handle multiple active connections
    • ChangeSet/Actions can target different connections
    • Allows multiple databases to be updated in concert
  • Want to further reduce duplication of code between XML and YAML/JSON parsers and serialize/deserialize logic
  • Simple SQL Parser
    • Enough to be able to handle strings vs. keywords vs. objects
    • May be helpful with new “Action Template” functionality
    • May be helpful with <sql> <createView> etc. validation and checksum
  • More granularity on checksum versioning
  • Currently there is a “version” as part of the checksum tag for when I need to make a change to the logic that affects how they are generated, but most often there changes just in individual tags or certain scenarios of certain tags. We need a better way to handle this to make updates more seamless for everyone.
  • UTF8 / Other Charsets
    • I need to better understand charset handling and ensure we are handling files correctly.
  • There are some placeholder hooks and naming in place to support non-java uses of the code. In particular I was hoping to be able to use ikvm to re-compile most of the Liquibase logic for .Net and just plug in particular classes to make it better integrate (.net-native connections, xml parsers, etc.) There has never been any traction on this and I think it should be pulled out to simplify things
  • Improved prepared statement logic: sometimes you need to use prepared statements, not simple statements. Liquibase has tried to avoid prepared statements and so places where they are needed are badly wedged in.
  • Safer modifySql logic: currently the modifySql just does a simple string replacement of the SQL, but if/when the generated SQL logic changes that can transparently break previously working modifySql. Need a way to make this safer
  • Better OSGi support: I don’t really know OSGi well enough to know if what we have is good or not
  • Separate SQL logging: Currently most SQL goes through the DEBUG level logging but people often want SQL logged but no other debug info and/or to log SQL to a separate location. Ensure all SQL is logged and handled separately
  • The tag table structure currently doesn’t support multiple tags at the same point and doesn’t always track all the changes in a tag well. Probably need a separate DATABASECHANGELOGTAG table
  • Refactor the Database API: It is currently a mix of “Dialect logic”, connection handling, and more. Some logic should be split out, other dialect logic scattered throughout the code should be brought into the Database class
  • Refactor ResourceAccessor API: I made some changes with 3.3 but ensure the APIs cover what is needed
  • Clean up multi-schema support: There is some support for managing multiple schemas but it is not consistently used and supported.
  • Move non-core database support to extensions
    • What are core databases? I would suggest mysql, pgsql, oracle, mssql, db2 
  • Should not be using “database instanceof MysqlDatabase” etc. Should be using subclassing instead.


New Features
  • Postconditions: Like preconditions but ran before committing the changeSet
  • updateReference, rollbackReference, and other *Reference commands that perform the same logic as the normal version (update, rollback, etc) but against the “reference” database.
  • Improved DBDoc with an updated skin and new features

Infrastructure Improvements:
  • Split SDK from main Liquibase code and improve SDK
  • Improve extension portal
  • Improve generation of doc for website
  • Improve Javadoc
  • Consider Grade vs Maven
  • Testing of Liquibase in Java 7 and 8
  • Not yet ready to drop Java 6 support
  • Liquibase 3 compatibility layer: Is it possible? Is it needed?
  • Move Liquibase blog to github pages
  • Vet all classes with extensions and subclassing in mind


What are your thoughts on the 4.0 feature list? Anything you think should be added or removed?

Nathan

Re : Skip checksum verification

$
0
0
Yes, there are times that it makes sense to disable the standard checksum behavior. You can disable the checks per changeSet using the <validCheckSum> tag with known good values, or with <validCheckSum>ANY</validCheckSum> to allow all checksum values.

I thought there was an extension to disable checksums globally, but it looks like on hasn't been made yet. It should be possible to extend the liquibase.changelog.ChangeLogHistoryService class to not deal with checksums, but starting with per-changeSet disabling is probably the best way to start since it is simpler and only affects changeSets you know can be problems and you will still get notifications of unexpected changes everywhere else.

Nathan

Re : Multiple inserts in sqlFile do not fail as expected

$
0
0
Thanks for the test, that helped. What I found is that it looks like an issue with the JDBC driver. Because you have endDelimiter="\nGO" in your changelog but no GO in your file, Liquibase is not splitting the two statements and just passing the entire string as a single statement to the JDBC driver in statement.execute(). With the asExpected test, the driver throws an SQLException that is caught and handled correctly. 

With the unexpected test, however, the JDBC driver does not throw an exception even though the statement is rolled back. I'm not seeing any known issues with sqlserver or the jdbc driver with a quick google search and I'm also not seeing a way with the JDBC interface to know that there really was an error even though no exception was thrown.

I created https://liquibase.jira.com/browse/CORE-2162 to track the issue but for now I think your best work-around is to make sure that the statements are being split correctly. Either adding a GO after each line or adding a semicolon to the end of the insert statements and removing the endDelimiter setting will have each ran separately and then everything works as expected.

Nathan

Re : Return output messages from oracle chnageset execution to Liquibase

$
0
0
Yes, 1802 is currently set for 3.4 although I'm still looking at 3.4 vs. 4.0 work and timelines. Currently if you run with logLevel=DEBUG it will output all the SQL but it is mixed in with other log messages.

Nathan

Re : Calling sql scripts with some parameters

$
0
0
Good that worked. I don't think there is a way to combine your targets, but I haven't used the ant tasks for a while. They were redone a bit with 3.3.0, is that the version you are using?

Nathan

Re : Return output messages from oracle chnageset execution to Liquibase

$
0
0
Thanks for the information Nathan, I can see the detailed log with logging level to as DEBUG, however I was trying to capture the actual output of statements that are being executed. Some thing along these lines, if I run select statements, capturing its actual output which is the content of the table:

select * from ascii;

1 test
2 !@#$%^&* jain
3 hello world

At present DEBUG log just shows me that the custom sql has been executed:

DEBUG 05/12/14 03:05: liquibase: db-Changelogascii.xml: ddl/ALTER_TABLE_ASCII.sql::005::ascii: Executing EXECUTE database command: select * from ascii
INFO 05/12/14 03:05: liquibase: db-Changelogascii.xml: ddl/ALTER_TABLE_ASCII.sql::005::ascii: Custom SQL executed

Re : Replacement for missing liquibase classes moving from liquibase 2.0.3 to 3.3.0

$
0
0
Thanks Nathan for you answer on stackoverflow.com;

http://stackoverflow.com/questions/27291619/replacement-for-missing-liquibase-classes-moving-from-liquibase-2-0-3-to-3-3-0

To give some context, I have the following class that no longer compiles when I upgraded from liquibase-core 2.0.3 to liquibase-core 3.3.0 (due to the missing classes listed in my original post).

  1. import java.lang.reflect.Field;
  2. import java.util.Arrays;
  3. import java.util.HashMap;
  4. import java.util.HashSet;
  5. import java.util.Map;
  6. import java.util.Set;

  7. import liquibase.change.Change;
  8. import liquibase.change.core.AddAutoIncrementChange;
  9. import liquibase.change.core.AddColumnChange;
  10. import liquibase.change.core.AddDefaultValueChange;
  11. import liquibase.change.core.AddForeignKeyConstraintChange;
  12. import liquibase.change.core.AddLookupTableChange;
  13. import liquibase.change.core.AddNotNullConstraintChange;
  14. import liquibase.change.core.AddPrimaryKeyChange;
  15. import liquibase.change.core.AddUniqueConstraintChange;
  16. import liquibase.change.core.AlterSequenceChange;
  17. import liquibase.change.core.AnonymousChange;
  18. import liquibase.change.core.CreateIndexChange;
  19. import liquibase.change.core.CreateProcedureChange;
  20. import liquibase.change.core.CreateSequenceChange;
  21. import liquibase.change.core.CreateTableChange;
  22. import liquibase.change.core.CreateViewChange;
  23. import liquibase.change.core.DeleteDataChange;
  24. import liquibase.change.core.DropAllForeignKeyConstraintsChange;
  25. import liquibase.change.core.DropColumnChange;
  26. import liquibase.change.core.DropDefaultValueChange;
  27. import liquibase.change.core.DropForeignKeyConstraintChange;
  28. import liquibase.change.core.DropIndexChange;
  29. import liquibase.change.core.DropNotNullConstraintChange;
  30. import liquibase.change.core.DropPrimaryKeyChange;
  31. import liquibase.change.core.DropSequenceChange;
  32. import liquibase.change.core.DropTableChange;
  33. import liquibase.change.core.DropUniqueConstraintChange;
  34. import liquibase.change.core.DropViewChange;
  35. import liquibase.change.core.EmptyChange;
  36. import liquibase.change.core.ExecuteShellCommandChange;
  37. import liquibase.change.core.InsertDataChange;
  38. import liquibase.change.core.LoadDataChange;
  39. import liquibase.change.core.LoadUpdateDataChange;
  40. import liquibase.change.core.MergeColumnChange;
  41. import liquibase.change.core.ModifyDataTypeChange;
  42. import liquibase.change.core.RawSQLChange;
  43. import liquibase.change.core.RenameColumnChange;
  44. import liquibase.change.core.RenameTableChange;
  45. import liquibase.change.core.RenameViewChange;
  46. import liquibase.change.core.SQLFileChange;
  47. import liquibase.change.core.StopChange;
  48. import liquibase.change.core.TagDatabaseChange;
  49. import liquibase.change.core.UpdateDataChange;
  50. import liquibase.change.custom.CustomChangeWrapper;
  51. import liquibase.database.Database;
  52. import liquibase.database.core.CacheDatabase;
  53. import liquibase.database.core.DB2Database;
  54. import liquibase.database.core.DB2iDatabase;
  55. import liquibase.database.core.DerbyDatabase;
  56. import liquibase.database.core.FirebirdDatabase;
  57. import liquibase.database.core.H2Database;
  58. import liquibase.database.core.HsqlDatabase;
  59. import liquibase.database.core.InformixDatabase;
  60. import liquibase.database.core.MSSQLDatabase;
  61. import liquibase.database.core.MaxDBDatabase;
  62. import liquibase.database.core.MySQLDatabase;
  63. import liquibase.database.core.OracleDatabase;
  64. import liquibase.database.core.PostgresDatabase;
  65. import liquibase.database.core.SQLiteDatabase;
  66. import liquibase.database.core.SybaseASADatabase;
  67. import liquibase.database.core.SybaseDatabase;
  68. import liquibase.database.core.UnsupportedDatabase;
  69. import liquibase.database.typeconversion.TypeConverter;
  70. import liquibase.database.typeconversion.core.CacheTypeConverter;
  71. import liquibase.database.typeconversion.core.DB2TypeConverter;
  72. import liquibase.database.typeconversion.core.DefaultTypeConverter;
  73. import liquibase.database.typeconversion.core.DerbyTypeConverter;
  74. import liquibase.database.typeconversion.core.FirebirdTypeConverter;
  75. import liquibase.database.typeconversion.core.H2TypeConverter;
  76. import liquibase.database.typeconversion.core.HsqlTypeConverter;
  77. import liquibase.database.typeconversion.core.InformixTypeConverter;
  78. import liquibase.database.typeconversion.core.MSSQLTypeConverter;
  79. import liquibase.database.typeconversion.core.MaxDBTypeConverter;
  80. import liquibase.database.typeconversion.core.MySQLTypeConverter;
  81. import liquibase.database.typeconversion.core.OracleTypeConverter;
  82. import liquibase.database.typeconversion.core.Postgres83TypeConverter;
  83. import liquibase.database.typeconversion.core.PostgresTypeConverter;
  84. import liquibase.database.typeconversion.core.SQLiteTypeConverter;
  85. import liquibase.database.typeconversion.core.SybaseASATypeConverter;
  86. import liquibase.database.typeconversion.core.SybaseTypeConverter;
  87. import liquibase.executor.Executor;
  88. import liquibase.executor.LoggingExecutor;
  89. import liquibase.executor.jvm.JdbcExecutor;
  90. import liquibase.ext.logging.slf4j.Slf4jLogger;
  91. import liquibase.logging.Logger;
  92. import liquibase.logging.core.DefaultLogger;
  93. import liquibase.parser.ChangeLogParser;
  94. import liquibase.parser.core.formattedsql.FormattedSqlChangeLogParser;
  95. import liquibase.parser.core.sql.SqlChangeLogParser;
  96. import liquibase.parser.core.xml.XMLChangeLogSAXParser;
  97. import liquibase.precondition.CustomPreconditionWrapper;
  98. import liquibase.precondition.Precondition;
  99. import liquibase.precondition.core.AndPrecondition;
  100. import liquibase.precondition.core.ChangeLogPropertyDefinedPrecondition;
  101. import liquibase.precondition.core.ChangeSetExecutedPrecondition;
  102. import liquibase.precondition.core.ColumnExistsPrecondition;
  103. import liquibase.precondition.core.DBMSPrecondition;
  104. import liquibase.precondition.core.ForeignKeyExistsPrecondition;
  105. import liquibase.precondition.core.IndexExistsPrecondition;
  106. import liquibase.precondition.core.NotPrecondition;
  107. import liquibase.precondition.core.OrPrecondition;
  108. import liquibase.precondition.core.PreconditionContainer;
  109. import liquibase.precondition.core.PrimaryKeyExistsPrecondition;
  110. import liquibase.precondition.core.RunningAsPrecondition;
  111. import liquibase.precondition.core.SequenceExistsPrecondition;
  112. import liquibase.precondition.core.SqlPrecondition;
  113. import liquibase.precondition.core.TableExistsPrecondition;
  114. import liquibase.precondition.core.ViewExistsPrecondition;
  115. import liquibase.servicelocator.PackageScanClassResolver;
  116. import liquibase.servicelocator.PackageScanFilter;
  117. import liquibase.servicelocator.ServiceLocator;
  118. import liquibase.snapshot.DatabaseSnapshotGenerator;
  119. import liquibase.snapshot.jvm.DB2DatabaseSnapshotGenerator;
  120. import liquibase.snapshot.jvm.DerbyDatabaseSnapshotGenerator;
  121. import liquibase.snapshot.jvm.H2DatabaseSnapshotGenerator;
  122. import liquibase.snapshot.jvm.HsqlDatabaseSnapshotGenerator;
  123. import liquibase.snapshot.jvm.InformixDatabaseSnapshotGenerator;
  124. import liquibase.snapshot.jvm.MSSQLDatabaseSnapshotGenerator;
  125. import liquibase.snapshot.jvm.MySQLDatabaseSnapshotGenerator;
  126. import liquibase.snapshot.jvm.OracleDatabaseSnapshotGenerator;
  127. import liquibase.snapshot.jvm.PostgresDatabaseSnapshotGenerator;
  128. import liquibase.snapshot.jvm.SQLiteDatabaseSnapshotGenerator;
  129. import liquibase.snapshot.jvm.StandardJdbcDatabaseSnapshotGenerator;
  130. import liquibase.sqlgenerator.SqlGenerator;
  131. import liquibase.sqlgenerator.core.*;

  132. public class ServiceLocatorStaticClassResolver implements PackageScanClassResolver {

  133.     private Map<Class<?>, Set<Class<?>>> implementations = new HashMap<Class<?>, Set<Class<?>>>();

  134.     {
  135.         put(Logger.class, set(DefaultLogger.class, Slf4jLogger.class));

  136.         put(Executor.class, set(JdbcExecutor.class, LoggingExecutor.class));

  137.         put(DatabaseSnapshotGenerator.class,
  138.             set(DB2DatabaseSnapshotGenerator.class, DerbyDatabaseSnapshotGenerator.class,
  139.                 H2DatabaseSnapshotGenerator.class, HsqlDatabaseSnapshotGenerator.class,
  140.                 InformixDatabaseSnapshotGenerator.class, MSSQLDatabaseSnapshotGenerator.class,
  141.                 MySQLDatabaseSnapshotGenerator.class, OracleDatabaseSnapshotGenerator.class,
  142.                 PostgresDatabaseSnapshotGenerator.class, SQLiteDatabaseSnapshotGenerator.class,
  143.                 StandardJdbcDatabaseSnapshotGenerator.class));

  144.         put(SqlGenerator.class,
  145.             set(AddAutoIncrementGenerator.class, AddAutoIncrementGeneratorDB2.class,
  146.                 AddAutoIncrementGeneratorHsqlH2.class, AddAutoIncrementGeneratorInformix.class,
  147.                 AddAutoIncrementGeneratorSQLite.class, AddColumnGenerator.class,
  148.                 AddColumnGeneratorDefaultClauseBeforeNotNull.class, AddColumnGeneratorSQLite.class,
  149.                 AddDefaultValueGenerator.class, AddDefaultValueGeneratorDerby.class,
  150.                 AddDefaultValueGeneratorInformix.class, AddDefaultValueGeneratorMaxDB.class,
  151.                 AddDefaultValueGeneratorMSSQL.class, AddDefaultValueGeneratorMySQL.class,
  152.                 AddDefaultValueGeneratorOracle.class, AddDefaultValueGeneratorSybase.class,
  153.                 AddDefaultValueGeneratorSybaseASA.class, AddDefaultValueSQLite.class,
  154.                 AddForeignKeyConstraintGenerator.class, AddPrimaryKeyGenerator.class,
  155.                 AddPrimaryKeyGeneratorInformix.class, AddUniqueConstraintGenerator.class,
  156.                 AddUniqueConstraintGeneratorInformix.class, AddUniqueConstraintGeneratorTDS.class,
  157.                 AlterSequenceGenerator.class, ClearDatabaseChangeLogTableGenerator.class, CommentGenerator.class,
  158.                 CopyRowsGenerator.class, CreateDatabaseChangeLogLockTableGenerator.class,
  159.                 CreateDatabaseChangeLogTableGenerator.class, CreateDatabaseChangeLogTableGeneratorSybase.class,
  160.                 CreateIndexGenerator.class, CreateSequenceGenerator.class, CreateTableGenerator.class,
  161.                 CreateViewGenerator.class, DeleteGenerator.class, DropColumnGenerator.class,
  162.                 DropDefaultValueGenerator.class, DropForeignKeyConstraintGenerator.class, DropIndexGenerator.class,
  163.                 DropPrimaryKeyGenerator.class, DropSequenceGenerator.class, DropTableGenerator.class,
  164.                 DropUniqueConstraintGenerator.class, DropViewGenerator.class,
  165.                 FindForeignKeyConstraintsGeneratorDB2.class, FindForeignKeyConstraintsGeneratorMSSQL.class,
  166.                 FindForeignKeyConstraintsGeneratorMySQL.class, FindForeignKeyConstraintsGeneratorOracle.class,
  167.                 FindForeignKeyConstraintsGeneratorPostgres.class, GetNextChangeSetSequenceValueGenerator.class,
  168.                 GetViewDefinitionGenerator.class, GetViewDefinitionGeneratorDB2.class,
  169.                 GetViewDefinitionGeneratorDerby.class, GetViewDefinitionGeneratorFirebird.class,
  170.                 GetViewDefinitionGeneratorHsql.class, GetViewDefinitionGeneratorInformationSchemaViews.class,
  171.                 GetViewDefinitionGeneratorInformix.class, GetViewDefinitionGeneratorMaxDB.class,
  172.                 GetViewDefinitionGeneratorMSSQL.class, GetViewDefinitionGeneratorOracle.class,
  173.                 GetViewDefinitionGeneratorPostgres.class, GetViewDefinitionGeneratorSybase.class,
  174.                 GetViewDefinitionGeneratorSybaseASA.class, InsertGenerator.class, InsertOrUpdateGenerator.class,
  175.                 InsertOrUpdateGeneratorDB2.class, InsertOrUpdateGeneratorMSSQL.class,
  176.                 InsertOrUpdateGeneratorMySQL.class, InsertOrUpdateGeneratorOracle.class,
  177.                 InsertOrUpdateGeneratorPostgres.class, LockDatabaseChangeLogGenerator.class,
  178.                 MarkChangeSetRanGenerator.class, ModifyDataTypeGenerator.class, RawSqlGenerator.class,
  179.                 ReindexGeneratorSQLite.class, RemoveChangeSetRanStatusGenerator.class, RenameColumnGenerator.class,
  180.                 RenameTableGenerator.class, RenameViewGenerator.class, ReorganizeTableGeneratorDB2.class,
  181.                 RuntimeGenerator.class, SelectFromDatabaseChangeLogGenerator.class,
  182.                 SelectFromDatabaseChangeLogLockGenerator.class, SelectSequencesGeneratorDB2.class,
  183.                 SelectSequencesGeneratorDerby.class, SelectSequencesGeneratorFirebird.class,
  184.                 SelectSequencesGeneratorH2.class, SelectSequencesGeneratorHsql.class,
  185.                 SelectSequencesGeneratorInformix.class, SelectSequencesGeneratorMaxDB.class,
  186.                 SelectSequencesGeneratorOracle.class, SelectSequencesGeneratorPostgres.class,
  187.                 SetColumnRemarksGenerator.class, SetTableRemarksGenerator.class, StoredProcedureGenerator.class,
  188.                 TagDatabaseGenerator.class, UnlockDatabaseChangeLogGenerator.class,
  189.                 UpdateChangeSetChecksumGenerator.class, UpdateGenerator.class));
  190.         put(TypeConverter.class,
  191.             set(CacheTypeConverter.class, DB2TypeConverter.class, DefaultTypeConverter.class, DerbyTypeConverter.class,
  192.                 FirebirdTypeConverter.class, H2TypeConverter.class, HsqlTypeConverter.class,
  193.                 InformixTypeConverter.class, MaxDBTypeConverter.class, MSSQLTypeConverter.class,
  194.                 MySQLTypeConverter.class, OracleTypeConverter.class, PostgresTypeConverter.class,
  195.                 Postgres83TypeConverter.class, SQLiteTypeConverter.class, SybaseASATypeConverter.class,
  196.                 SybaseTypeConverter.class));

  197.     private Set<Class<?>> set(final Class<?>... types) {
  198.         return new HashSet<Class<?>>(Arrays.asList(types));
  199.     }

  200.     private void put(final Class<?> clazz, final Set<Class<?>> set) {
  201.         implementations.put(clazz, set);
  202.     }

  203.     public void setImplementations(final Map<Class<?>, Set<Class<?>>> implementations) {
  204.         this.implementations = implementations;
  205.     }

  206.     @Override
  207.     public Set<Class<?>> findImplementations(final Class<?> parent, final String... packageNames) {
  208.         final Set<Class<?>> classes = implementations.get(parent);
  209.         if (classes != null) {
  210.             return classes;
  211.         } else {
  212.             throw new RuntimeException("No classes defined for " + parent);
  213.         }
  214.     }

  215.     @Override
  216.     public Set<Class<?>> findByFilter(final PackageScanFilter filter, final String... packageNames) {
  217.         throw new UnsupportedOperationException();
  218.     }

  219.     @Override
  220.     public void addFilter(final PackageScanFilter filter) {
  221.     }

  222.     @Override
  223.     public void removeFilter(final PackageScanFilter filter) {
  224.     }

  225.     @Override
  226.     public void setClassLoaders(final Set<ClassLoader> classLoaders) {
  227.     }

  228.     @Override
  229.     public Set<ClassLoader> getClassLoaders() {
  230.         return null;
  231.     }

  232.     @Override
  233.     public void addClassLoader(final ClassLoader classLoader) {
  234.     }

  235.     public void init() throws Exception {
  236.         final ServiceLocator sl = ServiceLocator.getInstance();
  237.         final Field classResolver = sl.getClass().getDeclaredField("classResolver");
  238.         classResolver.setAccessible(true);
  239.         classResolver.set(sl, this);
  240.     }

  241. }
You mention some of the changes required on stackoverflow.com, but would you be able to help me in the context of the above class, e.g. what specifically should I replace the missing classes with? 

Also, I commented out some of the missing classes from this class to try and see if my application would at least start, but am now getting a NoSuchFieldException on this line of code:

  1. final ServiceLocator sl = ServiceLocator.getInstance();
  2. final Field classResolver = sl.getClass().getDeclaredField("classResolver");
It seems it can't find the 'classResolver' field in ServiceLocation, but I opened the .class file in eclipse and the field is there, any ideas whats going on?

Oracle VARCHAR2 definition

$
0
0
Hi

We are migrating from an existing Oracle database to Liquibase. We would like to support multiple databases, at least PostgreSQL. We've got couple of varchar definitions like this: VARCHAR2(255 CHAR) . We use UTF8 database so defining length in chars is crucial.
generateSQL command generated the same XML definition as in Oracle, but this is not portable, PostgreSQL is not able to understand CHAR modifier.
I managed to solve this problem with dbms attribute in every table definiton, although this makes the script very redundant, I have to create seperate definitions for Oracle and PostgreSQL.

What is the proper way to define VARCHAR2 length in CHARs?

Thanks,


Hubi

Re : Replacement for missing liquibase classes moving from liquibase 2.0.3 to 3.3.0

$
0
0
Just a quick update here..

So i changed 
  1.     public void init() throws Exception {
  2.         final ServiceLocator sl = ServiceLocator.getInstance();
  3.         final Field classResolver = sl.getClass().getDeclaredField("classResolver");
  4.         classResolver.setAccessible(true);
  5.         classResolver.set(sl, this);
  6.     }
to just
  1.     public void init() throws Exception {
  2.         ServiceLocator.setInstance(new CustomResolverServiceLocator(this));
  3.     }
and added a few interface to class mappings to the above class listing that liquibase was complaining about;:

  1. put(LockService.class, set(StandardLockService.class));

  2. put(SnapshotGenerator.class, set(JdbcSnapshotGenerator.class, ColumnSnapshotGenerator.class, H2ColumnSnapshotGenerator.class, UniqueConstraintSnapshotGenerator.class));
Just to get the class to compile, I commented out some of the classes my original post referred to:
  1.       //     set(DB2DatabaseSnapshotGenerator.class, DerbyDatabaseSnapshotGenerator.class,
  2.       //      H2DatabaseSnapshotGenerator.class, HsqlDatabaseSnapshotGenerator.class,
  3.       //          InformixDatabaseSnapshotGenerator.class, MSSQLDatabaseSnapshotGenerator.class,
  4.       //          MySQLDatabaseSnapshotGenerator.class, OracleDatabaseSnapshotGenerator.class,
  5.       //          PostgresDatabaseSnapshotGenerator.class, SQLiteDatabaseSnapshotGenerator.class,
  6.       //          StandardJdbcDatabaseSnapshotGenerator.class));*/
and

  1.     //    put(TypeConverter.class,
  2.     //        set(CacheTypeConverter.class, DB2TypeConverter.class, DefaultTypeConverter.class, DerbyTypeConverter.class,
  3.    //             FirebirdTypeConverter.class, H2TypeConverter.class, HsqlTypeConverter.class,
  4.    //             InformixTypeConverter.class, MaxDBTypeConverter.class, MSSQLTypeConverter.class,
  5.    //             MySQLTypeConverter.class, OracleTypeConverter.class, PostgresTypeConverter.class,
  6.    //             Postgres83TypeConverter.class, SQLiteTypeConverter.class,   //SybaseASATypeConverter.class,
  7.   //              SybaseTypeConverter.class));
When I run my app now though, I'm seeing the following exception;

liquibase.exception.LockException: java.lang.NullPointerException
at liquibase.lockservice.StandardLockService.acquireLock(StandardLockService.java:211)[343:org.liquibase.osgi:3.2.3]
at liquibase.lockservice.StandardLockService.waitForLock(StandardLockService.java:151)[343:org.liquibase.osgi:3.2.3]
at liquibase.Liquibase.update(Liquibase.java:182)[343:org.liquibase.osgi:3.2.3]
at liquibase.Liquibase.update(Liquibase.java:174)[343:org.liquibase.osgi:3.2.3]
at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:345)[343:org.liquibase.osgi:3.2.3]
at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:302)[343:org.liquibase.osgi:3.2.3]
at com.myapp.bootstrap.liquibase.LiquibaseFactoryImpl.upgradeDatabase(LiquibaseFactoryImpl.java:264)[319:com.myapp.bootstrap:3.0.1.SNAPSHOT]
at commyapp.bootstrap.liquibase.LiquibaseFactoryImpl.upgradeDatabase(LiquibaseFactoryImpl.java:146)[319:com.myapp.bootstrap:3.0.1.SNAPSHOT]
at com.myapp.data.source.liquibase.LiquibaseRunner.upgradeDatabase(LiquibaseRunner.java:46)[307:com.myapp.data.source:3.0.1.SNAPSHOT]
at com.myapp.data.source.DatasourceManagedServiceFactory.upgradeDatabase(DatasourceManagedServiceFactory.java:235)[307:com.myapp.data.source:3.0.1.SNAPSHOT]
at com.myapp.data.source.DatasourceManagedServiceFactory.access$300(DatasourceManagedServiceFactory.java:46)[307:com.myapp.data.source:3.0.1.SNAPSHOT]
at com.myapp.data.source.DatasourceManagedServiceFactory$1.run(DatasourceManagedServiceFactory.java:95)[307:com.myapp.data.source:3.0.1.SNAPSHOT]
Caused by: java.lang.NullPointerException
at liquibase.snapshot.DatabaseSnapshot.include(DatabaseSnapshot.java:153)[343:org.liquibase.osgi:3.2.3]
at liquibase.snapshot.DatabaseSnapshot.init(DatabaseSnapshot.java:51)[343:org.liquibase.osgi:3.2.3]
at liquibase.snapshot.DatabaseSnapshot.<init>(DatabaseSnapshot.java:33)[343:org.liquibase.osgi:3.2.3]
at liquibase.snapshot.JdbcDatabaseSnapshot.<init>(JdbcDatabaseSnapshot.java:22)[343:org.liquibase.osgi:3.2.3]
at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:126)[343:org.liquibase.osgi:3.2.3]
at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:119)[343:org.liquibase.osgi:3.2.3]
at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:107)[343:org.liquibase.osgi:3.2.3]
at liquibase.snapshot.SnapshotGeneratorFactory.has(SnapshotGeneratorFactory.java:97)[343:org.liquibase.osgi:3.2.3]
at liquibase.snapshot.SnapshotGeneratorFactory.hasDatabaseChangeLogLockTable(SnapshotGeneratorFactory.java:166)[343:org.liquibase.osgi:3.2.3]
at liquibase.lockservice.StandardLockService.hasDatabaseChangeLogLockTable(StandardLockService.java:138)[343:org.liquibase.osgi:3.2.3]
at liquibase.lockservice.StandardLockService.init(StandardLockService.java:85)[343:org.liquibase.osgi:3.2.3]
at liquibase.lockservice.StandardLockService.acquireLock(StandardLockService.java:185)[343:org.liquibase.osgi:3.2.3]
... 11 more

Any help is much appreciated!

Re : Looking for Feedback on Liquibase 4.0 Roadmap

$
0
0
While I understand the convenience of 
  • "Move non-core database support to extensions
    • What are core databases? I would suggest mysql, pgsql, oracle, mssql, db2"
I would consider pushing ALL DMBS support to extensions.  This may make it easier for installations to create their own rules around whatever dbms they use and also make it easier to support major versions of DBMS product as separateextensions. 

Re : Looking for Feedback on Liquibase 4.0 Roadmap

$
0
0
Pushing everything to an extension is an option. My concern with that is that it adds one more step/dependency for people and therefore a chance for mistake. I run into issues with the few databases that have been pushed off into extensions already where they forget they need the extension. It is also easy to get confusion with version management between the database extensions and the core library.

However, if the core library contains support for nothing, it makes for an easier and helpful error message if there are no Database implementations found. 

Also, there is probably confusion already since there is built in support for oracle, mssql and postgres but there are also extensions for them. The built-in support has support for the "standard" liquibase features and the extensions can add extra features such as a <vaccuum> command, materialized view support, etc. 

Maybe the best approach would be to split out the core databases into separate modules in the main liquibase codebase. So there would be liquibase-core, liquibase-maven, etc. like there is now but then add liquibase-oracle, liquibase-mysql, liquibase-db2, liquibase-mssql and liquibase-pgsql. The current "extension" code could go in those. Since it's the same codebase, each new liquibase version would contain new builds for the standard database extensions and versions would stay in sync. 

That will help force there to be no database-specific code in any of the rest of liquibase, for better or worse. There are time when it is nice to say "use this sql for mysql and oracle" vs. having to duplicate the different behavior in both extensions, but there are sometimes other options like flags or some duplication can be nice to not accidentally break other databases.

Nathan

Re : Skip checksum verification

$
0
0
Thank you. That's exactly what I need. I never found this feature in the documentation, so if you have commit rights there you might like to add something for others to find.

Thanks for your help.
Viewing all 2993 articles
Browse latest View live


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