The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

DBIx::Schema::UpToDate - Helps keep a database schema up to date

VERSION

version 1.001

SYNOPSIS

  package Local::Database;
  use parent 'DBIx::Schema::UpToDate';

  sub updates {
    shift->{updates} ||= [

      # version 1
      sub {
        my ($self) = @_;
        $self->dbh->do('-- sql');
        $self->do_something_else;
      },

      # version 2
      sub {
        my ($self) = @_;
        my $val = Local::Project::NewerClass->value;
        $self->dbh->do('INSERT INTO values (?)', {}, $val);
      },
    ];
  }

  package main;

  my $dbh = DBI->connect(@connection_args);
  Local::Database->new(dbh => $dbh);

  # do something with $dbh which now contains the schema you expect

DESCRIPTION

This module provides a base class for keeping a database schema up to date. If you need to make changes to the schema in remote databases in an automated manner you may not be able to ensure what version of the database is installed by the time it gets the update. This module will apply updates (defined as perl subs (coderefs)) sequentially to bring the database schema up to the latest version from whatever the current version is.

The aim of this module is to enable you to write incredibly simple subclasses so that all you have to do is define the updates you want to apply. This is done with subs (coderefs) so you can access the object and its database handle.

It is intentionally simple and is not intended for large scale applications. It may be a good fit for small embedded databases. It can also be useful if you need to reference other parts of your application as the subs allow you to utilize the object (and anything else you can reach).

Check "SEE ALSO" for alternative solutions and pick the one that's right for your situation.

USAGE

Subclasses should overwrite "updates" to return an arrayref of subs (coderefs) that will be executed to bring the schema up to date.

Each sub (coderef) will be called as a method (it will receive the object as its first parameter):

  sub { my ($self) = @_; $self->dbh->do('...'); }

The rest of the methods are small in the hopes that you can overwrite the ones you need to get the customization you require.

The updates can be run individually (outside of "up_to_date") for testing your subs...

  my $dbh = DBI->connect(@in_memory_database);
  my $schema = DBIx::Schema::UpToDate->new(dbh => $dbh, auto_update => 0);

  # don't forget this:
  $schema->initialize_version_table;

  $schema->update_to_version(1);
  # execute calls on $dbh to test changes
  $schema->dbh->do( @something );
  # test row output or column information or whatever
  ok( $test_something, $here );

  $schema->update_to_version(2);
  # test things

  $schema->update_to_version(3);
  # test changes

  ...

  is($schema->current_version, $schema->latest_version, 'updated to latest version');
  done_testing;

METHODS

new

Constructor; Accepts a hash or hashref of options.

Options used by the base module:

  • dbh - A database handle (as returned from DBI->connect)

    Database commands will be executed against this handle.

  • auto_update - Boolean

    By default "up_to_date" is called at initialization (just after being blessed). Set this value to false to disable this if you need to do something else before updating. You will have to call "up_to_date" yourself.

  • sql_limit - Boolean

    By default "current_version" uses a LIMIT 1 suffix. Set this value to false to disable this behavior (in case your database doesn't support the LIMIT syntax).

  • transactions - Boolean

    By default "update_to_version" does its work in a transaction. Set this value to false to disable this behavior (in case your database doesn't support transactions).

begin_work

Convenience method for calling "begin_work" in DBI on the database handle if transactions are enabled.

commit

Convenience method for calling "commit" in DBI on the database handle if transactions are enabled.

dbh

Returns the object's database handle.

current_version

Determine the current version of the database schema.

initialize_version_table

Create the version metadata table in the database and insert initial version record.

latest_version

Returns the latest [possible] version of the database schema.

quoted_table_name

Returns the table name ("version_table_name") quoted by "quote_identifier" in DBI.

quote_identifiers

  @quoted = $self->quote_identifiers(qw(field1 field2));

Convenience method for passing each argument through "quote_identifier" in DBI.

Returns a list.

set_version

  $cache->set_version($verison);

Sets the current database version to $version. Called from "update_to_version" after executing the appropriate update.

updates

Returns an arrayref of subs (coderefs) that can be used to update the database from one version to the next. This is used by "up_to_date" to replay a recorded database history on the "dbh" until the database schema is up to date.

update_to_version

  $cache->update_to_version($version);

Executes the update associated with $version in order to bring database up to that version.

up_to_date

Ensures that the database is up to date. If it is not it will apply updates after "current_version" up to "latest_version" to bring the schema up to date.

version_table_name

The name to use the for the schema version metadata.

Defaults to 'schema_version'.

TODO

  • Come up with a better name (too late).

  • Add an initial_version attribute to allow altering the history

RATIONALE

I had already written most of the logic for this module in another project when I realized I should abstract it. Then I went looking and found the modules listed in "SEE ALSO" but didn't find one that fit my needs, so I released what I had made.

SEE ALSO

Here are a number of alternative modules I have found (some older, some newer) that perform a similar task, why I didn't use them, and why you probably should.

SUPPORT

Perldoc

You can find documentation for this module with the perldoc command.

  perldoc DBIx::Schema::UpToDate

Websites

The following websites have more information about this module, and may be of help to you. As always, in addition to those websites please use your favorite search engine to discover more resources.

Bugs / Feature Requests

Please report any bugs or feature requests by email to bug-dbix-schema-uptodate at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=DBIx-Schema-UpToDate. You will be automatically notified of any progress on the request by the system.

Source Code

http://github.com/rwstauner/DBIx-Schema-UpToDate

  git clone http://github.com/rwstauner/DBIx-Schema-UpToDate

AUTHOR

Randy Stauner <rwstauner@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2011 by Randy Stauner.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.