From: Luke Saunders Date: Tue, 5 Feb 2008 12:18:44 +0000 (+0000) Subject: minor tidying and failing test for overlapping schema problem X-Git-Tag: v1.001002~43 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b099fee95285c1d046f9b9263c04d270863563d5;p=dbsrgits%2FDBIx-Class-Fixtures.git minor tidying and failing test for overlapping schema problem --- diff --git a/Makefile.PL b/Makefile.PL index e6c7b7a..f3b984b 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -10,11 +10,11 @@ WriteMakefile( PREREQ_PM => { 'Test::More' => 0.7, 'DBIx::Class' => 0.08, - 'Class::Accessor' => 0.31, + 'Class::Accessor::Grouped' => 0.08001, 'Path::Class' => 0.16, 'Config::Any' => 0.08, 'JSON::Syck' => 0.26, - 'Data::Dump::Streamer' => 2.08, + 'Data::Dump::Streamer' => 2.05, 'Hash::Merge' => 0.10, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, diff --git a/lib/DBIx/Class/Fixtures.pm b/lib/DBIx/Class/Fixtures.pm index 07cbb82..8766688 100644 --- a/lib/DBIx/Class/Fixtures.pm +++ b/lib/DBIx/Class/Fixtures.pm @@ -4,7 +4,7 @@ use strict; use warnings; use DBIx::Class::Exception; -use Class::Accessor; +use Class::Accessor::Grouped; use Path::Class qw(dir file); use File::Slurp; use Config::Any::JSON; @@ -16,14 +16,14 @@ use File::Copy qw/move/; use Hash::Merge qw( merge ); use Data::Dumper; -use base qw(Class::Accessor); +use base qw(Class::Accessor::Grouped); our %db_to_parser = ( 'mysql' => 'DateTime::Format::MySQL', 'pg' => 'DateTime::Format::Pg', ); -__PACKAGE__->mk_accessors(qw(config_dir _inherited_attributes debug schema_class )); +__PACKAGE__->mk_group_accessors( 'simple' => qw/config_dir _inherited_attributes debug schema_class/); =head1 VERSION @@ -59,11 +59,16 @@ DBIx::Class::Fixtures =head1 DESCRIPTION -Dump fixtures from source database to filesystem then import to another database (with same schema) at any time. Use as a constant dataset for running tests against or for populating development databases when impractical to use production clones. Describe fixture set using relations and conditions based on your DBIx::Class schema. +Dump fixtures from source database to filesystem then import to another database (with same schema) +at any time. Use as a constant dataset for running tests against or for populating development databases +when impractical to use production clones. Describe fixture set using relations and conditions based +on your DBIx::Class schema. =head1 DEFINE YOUR FIXTURE SET -Fixture sets are currently defined in .json files which must reside in your config_dir (e.g. /home/me/app/fixture_configs/a_fixture_set.json). They describe which data to pull and dump from the source database. +Fixture sets are currently defined in .json files which must reside in your config_dir +(e.g. /home/me/app/fixture_configs/a_fixture_set.json). They describe which data to pull and dump +from the source database. For example: @@ -81,17 +86,20 @@ For example: }] } -This will fetch artists with primary keys 1 and 3, the producer with primary key 5 and two of producer 5's artists where 'artists' is a has_many DBIx::Class rel from Producer to Artist. +This will fetch artists with primary keys 1 and 3, the producer with primary key 5 and two of producer 5's +artists where 'artists' is a has_many DBIx::Class rel from Producer to Artist. The top level attributes are as follows: =head2 sets -Sets must be an array of hashes, as in the example given above. Each set defines a set of objects to be included in the fixtures. For details on valid set attributes see L below. +Sets must be an array of hashes, as in the example given above. Each set defines a set of objects to be +included in the fixtures. For details on valid set attributes see L below. =head2 rules -Rules place general conditions on classes. For example if whenever an artist was dumped you also wanted all of their cds dumped too, then you could use a rule to specify this. For example: +Rules place general conditions on classes. For example if whenever an artist was dumped you also wanted all +of their cds dumped too, then you could use a rule to specify this. For example: { sets: [{ @@ -115,7 +123,8 @@ Rules place general conditions on classes. For example if whenever an artist was } } -In this case all the cds of artists 1, 3 and all producer 5's artists will be dumped as well. Note that 'cds' is a has_many DBIx::Class relation from Artist to CD. This is eqivalent to: +In this case all the cds of artists 1, 3 and all producer 5's artists will be dumped as well. Note that 'cds' is a +has_many DBIx::Class relation from Artist to CD. This is eqivalent to: { sets: [{ @@ -145,7 +154,8 @@ L =head2 datetime_relative -Only available for MySQL and PostgreSQL at the moment, must be a value that DateTime::Format::* can parse. For example: +Only available for MySQL and PostgreSQL at the moment, must be a value that DateTime::Format::* +can parse. For example: { sets: [{ @@ -155,7 +165,10 @@ Only available for MySQL and PostgreSQL at the moment, must be a value that Date datetime_relative : "2007-10-30 00:00:00" } -This will work when dumping from a MySQL database and will cause any datetime fields (where datatype => 'datetime' in the column def of the schema class) to be dumped as a DateTime::Duration object relative to the date specified in the datetime_relative value. For example if the RecentItem object had a date field set to 2007-10-25, then when the fixture is imported the field will be set to 5 days in the past relative to the current time. +This will work when dumping from a MySQL database and will cause any datetime fields (where datatype => 'datetime' +in the column def of the schema class) to be dumped as a DateTime::Duration object relative to the date specified in +the datetime_relative value. For example if the RecentItem object had a date field set to 2007-10-25, then when the +fixture is imported the field will be set to 5 days in the past relative to the current time. =head2 might_have @@ -174,7 +187,9 @@ Specifies whether to automatically dump might_have relationships. Should be a ha }] } -Note: belongs_to rels are automatically dumped whether you like it or not, this is to avoid FKs to nowhere when importing. General rules on has_many rels are not accepted at this top level, but you can turn them on for individual sets - see L. +Note: belongs_to rels are automatically dumped whether you like it or not, this is to avoid FKs to nowhere when importing. +General rules on has_many rels are not accepted at this top level, but you can turn them on for individual +sets - see L. =head1 SET ATTRIBUTES @@ -184,11 +199,14 @@ Required attribute. Specifies the DBIx::Class object class you wish to dump. =head2 ids -Array of primary key ids to fetch, basically causing an $rs->find($_) for each. If the id is not in the source db then it just won't get dumped, no warnings or death. +Array of primary key ids to fetch, basically causing an $rs->find($_) for each. If the id is not in the source db then it +just won't get dumped, no warnings or death. =head2 quantity -Must be either an integer or the string 'all'. Specifying an integer will effectively set the 'rows' attribute on the resultset clause, specifying 'all' will cause the rows attribute to be left off and for all matching rows to be dumped. There's no randomising here, it's just the first x rows. +Must be either an integer or the string 'all'. Specifying an integer will effectively set the 'rows' attribute on the resultset clause, +specifying 'all' will cause the rows attribute to be left off and for all matching rows to be dumped. There's no randomising +here, it's just the first x rows. =head2 cond @@ -253,7 +271,9 @@ Must be an array of hashes. Specifies which rels to also dump. For example: Will cause the cds of artists 1 and 3 to be dumped where the cd position is 2. -Valid attributes are: 'rel', 'quantity', 'cond', 'has_many', 'might_have' and 'join'. rel is the name of the DBIx::Class rel to follow, the rest are the same as in the set attributes. quantity is necessary for has_many relationships, but not if using for belongs_to or might_have relationships. +Valid attributes are: 'rel', 'quantity', 'cond', 'has_many', 'might_have' and 'join'. rel is the name of the DBIx::Class +rel to follow, the rest are the same as in the set attributes. quantity is necessary for has_many relationships, +but not if using for belongs_to or might_have relationships. =head2 has_many @@ -488,10 +508,7 @@ sub dump_object { $self->msg('-- dumping ' . $file->stringify, 2); my %ds = $object->get_columns; - my $driver = $object->result_source->schema->storage->dbh->{Driver}->{Name}; - my $formatter= $db_to_parser{$driver}; - eval "require $formatter" if ($formatter); - + my $formatter= $object->result_source->schema->storage->datetime_parser; # mess with dates if specified if ($set->{datetime_relative}) { unless ($@ || !$formatter) { @@ -512,7 +529,7 @@ sub dump_object { $ds{$col} = $object->get_inflated_column($col)->subtract_datetime($dt); } } else { - warn "datetime_relative not supported for $driver at the moment"; + warn "datetime_relative not supported for this db driver at the moment"; } } @@ -705,9 +722,7 @@ sub populate { eval { $schema->storage->dbh->do('SET foreign_key_checks=0') }; my $fixup_visitor; - my $driver = $schema->storage->dbh->{Driver}->{Name}; - my $formatter= $db_to_parser{$driver}; - eval "require $formatter" if ($formatter); + my $formatter= $schema->storage->datetime_parser; unless ($@ || !$formatter) { my %callbacks; if ($params->{datetime_relative_to}) { @@ -742,6 +757,8 @@ sub populate { $self->msg("- cleaning up"); $tmp_fixture_dir->rmtree; eval { $schema->storage->dbh->do('SET foreign_key_checks=1') }; + + return 1; } sub msg { diff --git a/t/lib/DBICTest.pm b/t/lib/DBICTest.pm index 2e1ddc4..502112f 100755 --- a/t/lib/DBICTest.pm +++ b/t/lib/DBICTest.pm @@ -94,8 +94,7 @@ sub deploy_schema { my $self = shift; my $schema = shift; - - my $file = $self->get_ddl_file($schema); + my $file = shift || $self->get_ddl_file($schema); open IN, $file; my $sql; { local $/ = undef; $sql = ; } diff --git a/t/lib/DBICTest/Schema2.pm b/t/lib/DBICTest/Schema2.pm new file mode 100644 index 0000000..2ab7342 --- /dev/null +++ b/t/lib/DBICTest/Schema2.pm @@ -0,0 +1,10 @@ +package # hide from PAUSE + DBICTest::Schema2; + +use base qw/DBIx::Class::Schema/; + +no warnings qw/qw/; + +__PACKAGE__->load_classes(qw/Artist CD Friend/); + +1; diff --git a/t/lib/DBICTest/Schema2/Artist.pm b/t/lib/DBICTest/Schema2/Artist.pm new file mode 100644 index 0000000..72b6e4e --- /dev/null +++ b/t/lib/DBICTest/Schema2/Artist.pm @@ -0,0 +1,25 @@ +package # hide from PAUSE + DBICTest::Schema2::Artist; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table('artist'); +__PACKAGE__->add_columns( + 'artistid' => { + data_type => 'integer', + is_auto_increment => 1, + }, + 'name' => { + data_type => 'varchar', + size => 100, + is_nullable => 1, + }, +); +__PACKAGE__->set_primary_key('artistid'); + +__PACKAGE__->has_many( + cds => 'DBICTest::Schema2::CD', undef, + { order_by => 'year' }, +); + +1; diff --git a/t/lib/DBICTest/Schema2/CD.pm b/t/lib/DBICTest/Schema2/CD.pm new file mode 100644 index 0000000..7d11ebc --- /dev/null +++ b/t/lib/DBICTest/Schema2/CD.pm @@ -0,0 +1,30 @@ +package # hide from PAUSE + DBICTest::Schema2::CD; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table('cd'); +__PACKAGE__->add_columns( + 'cdid' => { + data_type => 'integer', + is_auto_increment => 1, + }, + 'artist' => { + data_type => 'integer', + }, + 'title' => { + data_type => 'varchar', + size => 100, + }, + 'year' => { + data_type => 'varchar', + size => 100, + }, +); +__PACKAGE__->set_primary_key('cdid'); +__PACKAGE__->add_unique_constraint([ qw/artist title/ ]); + +__PACKAGE__->belongs_to( artist => 'DBICTest::Schema2::Artist' ); + + +1; diff --git a/t/lib/DBICTest/Schema2/Friend.pm b/t/lib/DBICTest/Schema2/Friend.pm new file mode 100644 index 0000000..ec9698f --- /dev/null +++ b/t/lib/DBICTest/Schema2/Friend.pm @@ -0,0 +1,20 @@ +package # hide from PAUSE + DBICTest::Schema2::Friend; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table('friend'); +__PACKAGE__->add_columns( + 'friendid' => { + data_type => 'integer', + is_auto_increment => 1 + }, + 'name' => { + data_type => 'varchar', + size => 100, + }, +); +__PACKAGE__->set_primary_key('friendid'); +__PACKAGE__->add_unique_constraint(prod_name => [ qw/name/ ]); + +1; diff --git a/t/lib/sqlite_different.sql b/t/lib/sqlite_different.sql new file mode 100644 index 0000000..77b1de4 --- /dev/null +++ b/t/lib/sqlite_different.sql @@ -0,0 +1,34 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Tue Aug 8 01:53:20 2006 +-- +BEGIN TRANSACTION; + +-- +-- Table: artist +-- +CREATE TABLE artist ( + artistid INTEGER PRIMARY KEY NOT NULL, + name varchar(100) +); + + +-- +-- Table: cd +-- +CREATE TABLE cd ( + cdid INTEGER PRIMARY KEY NOT NULL, + artist integer NOT NULL, + title varchar(100) NOT NULL, + year varchar(100) NOT NULL +); + +-- +-- Table: friend +-- +CREATE TABLE friend ( + friendid INTEGER PRIMARY KEY NOT NULL, + name varchar(100) NOT NULL +); + +COMMIT;