Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extend Liquibase to generate change logs with stored procedures, functions and triggers?

Currently Liquibase has some limitations when you try to generate change logs on an existing database. It does not export the following types of objects:

  • Stored procedures, functions, packages
  • Triggers
  • Types

Reference: http://www.liquibase.org/documentation/generating_changelogs.html

As far as I understand I need to develop my own liquibase.snapshot.SnapshotGenerator implementation. I know how to obtain these types of objects from Oracle but I'm a bit lost on how to implement such interface from Liquibase.

Ideally I guess the liquibase.database.Database interface should be also extended to add the following extra methods:

  • public abstract boolean supportsPackages();
  • public abstract boolean supportsFunctions();
  • public abstract boolean supportsStoredProcedures();
  • public abstract boolean supportsTriggers();
  • public abstract boolean supportsTypes();
like image 967
bgillis Avatar asked Mar 04 '14 12:03

bgillis


People also ask

How do I create a changelog file using Liquibase?

To generate a newer version of the changelog file with stored logic objects based on the current database state, you need to delete, rename, or move the Objects directory that was created by running the generate-changelog command previously. Then, you can run the generate-changelog command again.

How should stored procedures be managed Liquibase?

Managing Stored Procedures: Try to maintain separate changelog for Stored Procedures and use runOnChange=”true”. This flag forces LiquiBase to check if the changeset was modified. If so, liquibase executes the change again.

What is a change set in Liquibase?

The changeset tag is a unit of change that Liquibase executes on a database and which is used to group database Liquibase Change Types together. A list of changes created by multiple changesets are tracked in a changelog.


1 Answers

You are right that the general strategy is to create a new class that implements SnapshotGenerator, but there are a couple other steps you need to do as well. The general snapshot process is:

  1. Liquibase searches for SnapshotGenerator implemetnations and calls the addsTo() for each object it finds in the database. For your types, you probably want a quick "if passed object instanceof Schema" because they are types that are part of a schema.
  2. You will need to create new Package, StoredProcedure, etc objects that implement DatabaseObject. They will be lik ehte liquibase.structure.core.Table class and capture the state of the object. They are created in your SnapshotGenerator.addsTo() method to the point of being identifiable (name, schema, etc set)
  3. All objects that are added by the addsTo() method are then ran through your SnapshotGenerator.snapshotObject() method which will pull any additional metadata that you didn't get originally, such as stored procedure text, etc.
  4. Once liquibase has a snapshot containing your objects it compares the snapshot to another (in generateChangeLog case an empty snapshot) to determine what objects are missing, unexpected, and changed in the second snapshot. It then looks for implementations of MissingObjectChangeGenerator, UnexpectedObjectChangeGenerator, and ChangedObjectChangeGenerator. For generateChangeLog there will only be "missing" objects so you would implement MissingTriggerChangeGenerator, MissingPackagedChangeGenerator etc. Their job is to create Change instances to create the missing objects
  5. The Msising*ChangeGenerator classes could return RawSqlChange instances or you could create new implementations of Change such as CreateTriggerChange.
like image 85
Nathan Voxland Avatar answered Oct 24 '22 21:10

Nathan Voxland