X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSchema%2FVersioned.pm;h=2ff160f5c033221707716af8c911f11f0025071c;hb=da0dd7dc8c18f051d39733703d3790af65c9842e;hp=26760b54bf5699ee47d7cd39fd95170c10be992d;hpb=c13002976e32b818eabc3a8eaf6fa2e23ebed7e9;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Schema/Versioned.pm b/lib/DBIx/Class/Schema/Versioned.pm index 26760b5..2ff160f 100644 --- a/lib/DBIx/Class/Schema/Versioned.pm +++ b/lib/DBIx/Class/Schema/Versioned.pm @@ -96,10 +96,31 @@ this will attempt to upgrade the database from its current version to the curren schema version using a diff from your I. If a suitable diff is not found then no upgrade is possible. -NB: At the moment, only SQLite and MySQL are supported. This is due to -spotty behaviour in the SQL::Translator producers, please help us by -enhancing them. Ask on the mailing list or IRC channel for details (community details -in L). +=head1 SEE ALSO + +L is a much more powerful alternative to this +module. Examples of things it can do that this module cannot do include + +=over + +=item * + +Downgrades in addition to upgrades + +=item * + +Multiple sql files files per upgrade/downgrade/install + +=item * + +Perl scripts allowed for upgrade/downgrade/install + +=item * + +Just one set of files needed for upgrade, unlike this module where one might +need to generate C + +=back =head1 GETTING STARTED @@ -182,6 +203,8 @@ use base 'DBIx::Class::Schema'; use Carp::Clan qw/^DBIx::Class/; use Time::HiRes qw/gettimeofday/; +use Try::Tiny; +use namespace::clean; __PACKAGE__->mk_classdata('_filedata'); __PACKAGE__->mk_classdata('upgrade_directory'); @@ -225,7 +248,7 @@ sub install # must be called on a fresh database if ($self->get_db_version()) { - carp 'Install not possible as versions table already exists in database'; + $self->throw_exception("A versioned schema has already been deployed, try upgrade instead.\n"); } # default to current version if none passed @@ -303,7 +326,7 @@ list of schema versions (if ordered_schema_versions returns nothing then it is assumed you can do the upgrade as a single step). It then iterates through the list of versions between the current db version and the schema version applying one update at a time until -all relvant updates are applied. +all relevant updates are applied. The individual update steps are performed by using L, which will apply the update and also @@ -503,7 +526,7 @@ sub get_db_version my ($self, $rs) = @_; my $vtable = $self->{vschema}->resultset('Table'); - my $version = eval { + my $version = try { $vtable->search({}, { order_by => { -desc => 'installed' }, rows => 1 } ) ->get_column ('version') ->next; @@ -544,7 +567,7 @@ warns if they are not the same or if the DB is unversioned. It also provides compatibility between the old versions table (SchemaVersions) and the new one (dbix_class_schema_versions). -To avoid the checks on connect, set the env var DBIC_NO_VERSION_CHECK or alternatively you can set the ignore_version attr in the forth argument like so: +To avoid the checks on connect, set the environment var DBIC_NO_VERSION_CHECK or alternatively you can set the ignore_version attr in the forth argument like so: my $schema = MyApp::Schema->connect( $dsn, @@ -558,30 +581,30 @@ To avoid the checks on connect, set the env var DBIC_NO_VERSION_CHECK or alterna sub connection { my $self = shift; $self->next::method(@_); - $self->_on_connect($_[3]); + $self->_on_connect(); return $self; } sub _on_connect { - my ($self, $args) = @_; + my ($self) = @_; - $args = {} unless $args; + my $conn_info = $self->storage->connect_info; + $self->{vschema} = DBIx::Class::Version->connect(@$conn_info); + my $conn_attrs = $self->{vschema}->storage->_dbic_connect_attributes || {}; - $self->{vschema} = DBIx::Class::Version->connect(@{$self->storage->connect_info()}); my $vtable = $self->{vschema}->resultset('Table'); # useful when connecting from scripts etc - return if ($args->{ignore_version} || ($ENV{DBIC_NO_VERSION_CHECK} && !exists $args->{ignore_version})); + return if ($conn_attrs->{ignore_version} || ($ENV{DBIC_NO_VERSION_CHECK} && !exists $conn_attrs->{ignore_version})); # check for legacy versions table and move to new if exists - my $vschema_compat = DBIx::Class::VersionCompat->connect(@{$self->storage->connect_info()}); unless ($self->_source_exists($vtable)) { - my $vtable_compat = $vschema_compat->resultset('TableCompat'); + my $vtable_compat = DBIx::Class::VersionCompat->connect(@$conn_info)->resultset('TableCompat'); if ($self->_source_exists($vtable_compat)) { $self->{vschema}->deploy; map { $vtable->create({ installed => $_->Installed, version => $_->Version }) } $vtable_compat->all; - $self->storage->dbh->do("DROP TABLE " . $vtable_compat->result_source->from); + $self->storage->_get_dbh->do("DROP TABLE " . $vtable_compat->result_source->from); } } @@ -681,13 +704,13 @@ sub _set_db_version { # This is necessary since there are legitimate cases when upgrades can happen # back to back within the same second. This breaks things since we relay on the # ability to sort by the 'installed' value. The logical choice of an autoinc - # is not possible, as it will break multiple legacy installations. Also it is + # is not possible, as it will break multiple legacy installations. Also it is # not possible to format the string sanely, as the column is a varchar(20). # The 'v' character is added to the front of the string, so that any version # formatted by this new function will sort _after_ any existing 200... strings. my @tm = gettimeofday(); my @dt = gmtime ($tm[0]); - my $o = $vtable->create({ + my $o = $vtable->create({ version => $version, installed => sprintf("v%04d%02d%02d_%02d%02d%02d.%03.0f", $dt[5] + 1900, @@ -709,12 +732,12 @@ sub _read_sql_file { my @data = split /\n/, join '', <$fh>; close $fh; - @data = grep { - $_ && - !/^--/ && - !/^(BEGIN|BEGIN TRANSACTION|COMMIT)/m - } split /;/, - join '', @data; + @data = split /;/, + join '', + grep { $_ && + !/^--/ && + !/^(BEGIN|BEGIN TRANSACTION|COMMIT)/mi } + @data; return \@data; } @@ -723,12 +746,12 @@ sub _source_exists { my ($self, $rs) = @_; - my $c = eval { - $rs->search({ 1, 0 })->count; + return try { + $rs->search(\'1=0')->cursor->next; + 1; + } catch { + 0; }; - return 0 if $@ || !defined $c; - - return 1; } 1;