NAME

Module::Build::Database - Manage database patches in the style of Module::Build.

SYNOPSIS

 perl Build.PL
 ./Build dbtest
 ./Build dbdist
 ./Build dbfakeinstall
 ./Build dbinstall

In more detail :

 # In Build.PL :

 use Module::Build::Database;

 my $builder = Module::Build::Database->new(
    database_type => "PostgreSQL",
    ...other module build options..
  );

 $builder->create_build_script();

 # Put database patches into db/patches/*.sql.
 # A schema will be autogenerated in db/dist/base.sql.
 # Any data generated by the patches will be put into db/dist/base_data.sql.
 # Documentation will be autogenerated in db/doc/.

 # That is, first do this :
 perl Build.PL

 # Then, test that patches in db/patches/ will apply successfully to
 # the schema in db/dist/ :
 ./Build dbtest

 # The, update the db information in db/dist/ by applying any
 # unapplied patches in db/patches/ to the schema in db/dist/ :
 ./Build dbdist

 # Update the docs in db/docs using the schema in db/dist :
 ./Build dbdocs

 # Install a new database or upgrade an existing one :
 ./Build dbfakeinstall
 ./Build dbinstall

Additionally, when doing

 ./Build install

The content of the db directory will be installed into your distributions share directory so that it can be retrieved using File::ShareDir. For example, assuming your MBD dist is called MyDist, to find the base.sql file from perl:

 use File::ShareDir qw( dist_dir );
 my $base = dist_dir('MyDist') . '/dist/base.sql';

DESCRIPTION

This is a subclass of Module::Build for modules which depend on a database, which adds functionality for testing and distributing changes to the database.

Changes are represented as sql files ("patches") which will be fed into a command line client for the database.

A complete schema is regenerated whenever dbdist is run.

A list of the patches which have been applied is stored in two places :

  1. the file db/dist/patches_applied.txt

  2. the table patches_applied within the target database.

When the dbinstall action is invoked, any patches in (1) but not in (2) are applied. In order to determine whether they will apply successfully, dbfakeinstall may be run, which does the following :

  1. Dumps the schema for an existing instance.

  2. Applies any patches not found in the patches_applied table.

  3. Dumps the resulting schema and compares it to the schema in db/dist/base.sql.

If the comparison in step 3 is the same, then one may conclude that applying the missing patches will produce the desired schema.

ACTIONS

dbdist

This (re-)generates the files db/dist/base.sql, db/dist/base_data.sql, and db/dist/patches_applied.txt.

It does this by reading patches from db/patches/*.sql, applying the ones that are not listed in db/dist/patches_applied.txt, and then dumping out a new db/dist/base.sql and db/dist/base_data.sql.

In other words :

  1. Start a new empty database instance.

  2. Populate the schema using db/dist/base.sql.

  3. Import any data in db/dist/base_data.sql.

  4. For every patch in db/patches/*.sql :

    Is the patch is listed in db/dist/patches_applied.txt?

    Yes?

    Skip it.

    No?

    Apply it, and add it to db/dist/patches_applied.txt.

  5. Dump the new schema out to db/dist/base.sql

  6. Dump any data out into db/dist/base_data.sql

  7. Stop the database.

dbtest

  1. Start a new empty database instance.

  2. Apply db/dist/base.sql.

  3. Apply db/dist/base_data.sql.

  4. Apply any patches in db/patches/*.sql that are not in db/dist/patches_applied.txt. For each of the above, the tests will fail if any of the patches do not apply cleanly.

  5. Shut down the database instance.

    If --leave_running=1 is passed, step 4 will not be executed. The "host" for the database can be found in

     Module::Build::Database->current->notes("dbtest_host");

dbclean

Stop any test daemons that are running and remove any test databases that have been created.

dbdocs

  1. Start a new empty database instance.

  2. Apply db/dist/base.sql.

  3. Dump the new schema docs out to db/doc.

  4. Stop the database.

dbfakeinstall

  1. Look for a running database, based on environment variables.

  2. Display the connection information obtained from the above.

  3. Dump the schema from the live database to a temporary directory.

  4. Make a temporary database using the above schema.

  5. Apply patches listed in db/dist/patches_applied.txt that are not in the patches_applied table.

  6. Dump out the resulting schema, and compare it to db/dist/base.sql.

Note that dbdist must be run to update base.sql before doing dbfakeinstall|Module::Build::Database#dbfakeinstall or dbinstall|Module::Build::Database#dbinstall.

dbinstall

  1. Look for a running database, based on environment variables

  2. Apply any patches in db/dist/patches_applied.txt that are not in the patches_applied table.

  3. Add an entry to the patches_applied table for each patch applied.

dbplant

  1. Starts a test database based on base.sql and any patches (see dbtest)

  2. Calls plant() in Rose::Planter. to generate a static object hierarchy.

  3. Stops the test database.

The default name of the object class will be formed by appending '::Objects' to the name of the module. This may be overridden by setting the build property database_object_class. The directory name will be formed by prepending lib and appending autolib, e.g. ./lib/MyModule/Objects/autolib.

NOTES

Patches will be applied in lexicographic order, so their names should start with a sequence of digits, e.g. 0010_something.sql, 0020_something_else.sql, etc.

AUTHOR

Brian Duggan

Graham Ollis <plicease@cpan.org>

Curt Tilmes

TODO

Allow dbclean to not interfere with other running mbd-test databases. Currently it errs on the side of cleaning up too much.

SEE ALSO

Test::MBD, Module::Build::Database::SQLite, Module::Build::Database::PostgreSQL