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 fromDBI->connect
)Database commands will be executed against this handle.
auto_update
- BooleanBy 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
- BooleanBy default "current_version" uses a
LIMIT 1
suffix. Set this value to false to disable this behavior (in case your database doesn't support theLIMIT
syntax).transactions
- BooleanBy 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.
-
Was close to what I was looking for, but not customizable enough. Were I to subclass it I would have needed to overwrite the two main methods.
-
Much bigger scale than what I was looking for. Needed something without Moose.
-
Something new(er than this module)... haven't investigated.
ORLite::Migrate (http://use.perl.org/~Alias/journal/38087)
Much bigger scale than what I was looking for. Wasn't using ORLite, and didn't want to use separate script files.
DBIx::Class::Schema::Versioned
Not using DBIx::Class; again, significantly larger scale than I desired.
DBIx::Class::DeploymentHandler
Not using DBIx::Class; more powerful than the previous means it's even larger than what was already more than I needed.
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.
Search CPAN
The default CPAN search engine, useful to view POD in HTML format.
RT: CPAN's Bug Tracker
The RT ( Request Tracker ) website is the default bug/issue tracking system for CPAN.
http://rt.cpan.org/NoAuth/Bugs.html?Dist=DBIx-Schema-UpToDate
CPAN Ratings
The CPAN Ratings is a website that allows community ratings and reviews of Perl modules.
CPAN Testers
The CPAN Testers is a network of smokers who run automated tests on uploaded CPAN distributions.
CPAN Testers Matrix
The CPAN Testers Matrix is a website that provides a visual overview of the test results for a distribution on various Perls/platforms.
CPAN Testers Dependencies
The CPAN Testers Dependencies is a website that shows a chart of the test results of all dependencies for a distribution.
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.