[Bast-commits] r4133 - in DBIx-Class-Fixtures/1.000: . branches
branches/includes branches/includes/lib
branches/includes/lib/DBIx branches/includes/lib/DBIx/Class
branches/includes/lib/DBIx/Class/Fixtures branches/includes/t
branches/includes/t/lib branches/includes/t/lib/DBICTest
branches/includes/t/lib/DBICTest/Schema
branches/includes/t/lib/DBICTest/Schema2
branches/includes/t/var branches/includes/t/var/configs
captainL at dev.catalyst.perl.org
captainL at dev.catalyst.perl.org
Wed Mar 5 14:56:16 GMT 2008
Author: captainL
Date: 2008-03-05 14:56:16 +0000 (Wed, 05 Mar 2008)
New Revision: 4133
Added:
DBIx-Class-Fixtures/1.000/branches/includes/
DBIx-Class-Fixtures/1.000/branches/includes/Changes
DBIx-Class-Fixtures/1.000/branches/includes/MANIFEST
DBIx-Class-Fixtures/1.000/branches/includes/Makefile.PL
DBIx-Class-Fixtures/1.000/branches/includes/README
DBIx-Class-Fixtures/1.000/branches/includes/lib/
DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/
DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/
DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures.pm
DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/
DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/Schema.pm
DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/SchemaVersioned.pm
DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/Versioned.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/
DBIx-Class-Fixtures/1.000/branches/includes/t/00-load.t
DBIx-Class-Fixtures/1.000/branches/includes/t/01-new.t
DBIx-Class-Fixtures/1.000/branches/includes/t/02-dump-basic.t
DBIx-Class-Fixtures/1.000/branches/includes/t/03-dump-quantity.t
DBIx-Class-Fixtures/1.000/branches/includes/t/04-dump-fetch.t
DBIx-Class-Fixtures/1.000/branches/includes/t/05-dump-rules.t
DBIx-Class-Fixtures/1.000/branches/includes/t/06-dump-date.t
DBIx-Class-Fixtures/1.000/branches/includes/t/07-dump-all.t
DBIx-Class-Fixtures/1.000/branches/includes/t/08-dump-includes.t
DBIx-Class-Fixtures/1.000/branches/includes/t/12-populate-basic.t
DBIx-Class-Fixtures/1.000/branches/includes/t/13populate-two-dbs.t
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Artist.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/CD.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/CD_to_Producer.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Producer.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Tag.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Track.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/Artist.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/CD.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/Friend.pm
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/mysql.sql
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/sqlite.sql
DBIx-Class-Fixtures/1.000/branches/includes/t/lib/sqlite_different.sql
DBIx-Class-Fixtures/1.000/branches/includes/t/var/
DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/
DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/date.json
DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/fetch.json
DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/includes.json
DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/quantity.json
DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/rules.json
DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/sample.json
DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/simple.json
Modified:
DBIx-Class-Fixtures/1.000/
Log:
r33 at ubuntu (orig r4128): captainL | 2008-03-05 12:42:53 +0000
new version
r34 at ubuntu (orig r4129): captainL | 2008-03-05 12:59:16 +0000
new branch
r35 at ubuntu (orig r4130): captainL | 2008-03-05 14:42:44 +0000
test passes
r36 at ubuntu (orig r4131): captainL | 2008-03-05 14:47:38 +0000
fixed formatting
r37 at ubuntu (orig r4132): captainL | 2008-03-05 14:56:07 +0000
updated docs, changes and manifest
Property changes on: DBIx-Class-Fixtures/1.000
___________________________________________________________________
Name: svk:merge
+ bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class-Fixtures/1.001:4132
Added: DBIx-Class-Fixtures/1.000/branches/includes/Changes
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/Changes (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/Changes 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,11 @@
+Revision history for DBIx-Class-Fixtures
+
+1.001000
+- Added includes functionality
+
+1.000001
+- Added missing deps
+
+1.000000
+- Released
+
Added: DBIx-Class-Fixtures/1.000/branches/includes/MANIFEST
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/MANIFEST (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/MANIFEST 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,53 @@
+Changes
+inc/Module/AutoInstall.pm
+inc/Module/Install.pm
+inc/Module/Install/AutoInstall.pm
+inc/Module/Install/Base.pm
+inc/Module/Install/Can.pm
+inc/Module/Install/Fetch.pm
+inc/Module/Install/Include.pm
+inc/Module/Install/Makefile.pm
+inc/Module/Install/Metadata.pm
+inc/Module/Install/Win32.pm
+inc/Module/Install/WriteAll.pm
+lib/DBIx/Class/Fixtures.pm
+lib/DBIx/Class/Fixtures/Schema.pm
+lib/DBIx/Class/Fixtures/SchemaVersioned.pm
+lib/DBIx/Class/Fixtures/Versioned.pm
+Makefile.PL
+MANIFEST
+META.yml Module meta-data (added by MakeMaker)
+README
+t/00-load.t
+t/01-new.t
+t/02-dump-basic.t
+t/03-dump-quantity.t
+t/04-dump-fetch.t
+t/05-dump-rules.t
+t/06-dump-date.t
+t/07-dump-all.t
+t/07-dump-includes.t
+t/12-populate-basic.t
+t/13populate-two-dbs.t
+t/lib/DBICTest.pm
+t/lib/DBICTest/Schema.pm
+t/lib/DBICTest/Schema/Artist.pm
+t/lib/DBICTest/Schema/CD.pm
+t/lib/DBICTest/Schema/CD_to_Producer.pm
+t/lib/DBICTest/Schema/Producer.pm
+t/lib/DBICTest/Schema/Tag.pm
+t/lib/DBICTest/Schema/Track.pm
+t/lib/DBICTest/Schema2.pm
+t/lib/DBICTest/Schema2/Artist.pm
+t/lib/DBICTest/Schema2/CD.pm
+t/lib/DBICTest/Schema2/Friend.pm
+t/lib/mysql.sql
+t/lib/sqlite.sql
+t/lib/sqlite_different.sql
+t/var/configs/date.json
+t/var/configs/fetch.json
+t/var/configs/quantity.json
+t/var/configs/rules.json
+t/var/configs/sample.json
+t/var/configs/simple.json
+t/var/configs/includes.json
Added: DBIx-Class-Fixtures/1.000/branches/includes/Makefile.PL
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/Makefile.PL (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/Makefile.PL 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,29 @@
+use inc::Module::Install 0.67;
+
+name 'DBIx-Class-Fixtures';
+perl_version '5.006001';
+all_from 'lib/DBIx/Class/Fixtures.pm';
+
+requires 'DBIx::Class' => 0.08;
+requires 'Data::Visitor' => 0.15;
+requires 'File::Copy::Recursive' => 0.35;
+requires 'DateTime' => 0.41;
+requires 'DateTime::Format::MySQL' => 0.04;
+requires 'DBIx::Class::Schema::Loader' => 0.04004;
+requires 'Class::Accessor::Grouped' => 0.06;
+requires 'Path::Class' => 0.16;
+requires 'File::Slurp' => 999.13;
+requires 'Config::Any' => 0.08;
+requires 'JSON::Syck' => 0.26;
+requires 'Data::Dump::Streamer' => 2.05;
+requires 'Hash::Merge' => 0.10;
+
+build_requires 'Test::More' => 0.7;
+
+tests_recursive();
+
+auto_provides;
+
+auto_install;
+
+WriteAll;
Added: DBIx-Class-Fixtures/1.000/branches/includes/README
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/README (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/README 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,20 @@
+DBIx-Class-Fixtures
+
+INSTALLATION
+
+To install this module, run the following commands:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+COPYRIGHT AND LICENCE
+
+Development sponsored by takkle.com
+
+Copyright (C) 2008 Luke Saunders <luke at shadowcatsystems.com>, some rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
Added: DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/Schema.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/Schema.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/Schema.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,10 @@
+package DBIx::Class::Fixtures::Schema;
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Schema::Loader';
+
+__PACKAGE__->loader_options( );
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/SchemaVersioned.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/SchemaVersioned.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/SchemaVersioned.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,18 @@
+package DBIx::Class::Fixtures::SchemaVersioned;
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Schema::Loader';
+
+our $VERSION = 'set-when-loading';
+
+__PACKAGE__->load_components('Schema::Versioned');
+__PACKAGE__->loader_options(
+ # debug => 1,
+ );
+
+sub schema_version {
+ return $DBIx::Class::Fixtures::SchemaVersioned::VERSION;
+}
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/Versioned.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/Versioned.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures/Versioned.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,45 @@
+package DBIx::Class::Fixtures::Versioned;
+
+use strict;
+use warnings;
+
+use base qw/DBIx::Class::Fixtures/;
+use DBIx::Class::Fixtures::SchemaVersioned;
+use Class::C3;
+
+=head1 NAME
+
+DBIx::Class::Fixtures::Versioned
+
+=head1 DESCRIPTION
+
+Just ignore it for now, but it will vaguely tie in to DBIx::Class::Schema::Versioned's functionality eventually.
+
+=cut
+
+sub populate {
+ my $self = shift;
+ my ($params) = @_;
+
+ $self->schema_class("DBIx::Class::Fixtures::SchemaVersioned");
+ unless ($params->{version}) {
+ return DBIx::Class::Exception->throw('You must pass a version to populate');
+ }
+ return $self->next::method(@_);
+}
+
+sub _generate_schema {
+ my $self = shift;
+ my ($params) = @_;
+
+ # manually set the schema version
+ $DBIx::Class::Fixtures::SchemaVersioned::VERSION = $params->{version};
+
+ my $schema = $self->next::method(@_);
+
+ # set the db version to the schema version
+ $schema->upgrade(); # set version number
+ return $schema;
+}
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/lib/DBIx/Class/Fixtures.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,862 @@
+package DBIx::Class::Fixtures;
+
+use strict;
+use warnings;
+
+use DBIx::Class::Exception;
+use Class::Accessor::Grouped;
+use Path::Class qw(dir file);
+use File::Slurp;
+use Config::Any::JSON;
+use Data::Dump::Streamer;
+use Data::Visitor::Callback;
+use File::Path;
+use File::Copy::Recursive qw/dircopy/;
+use File::Copy qw/move/;
+use Hash::Merge qw( merge );
+use Data::Dumper;
+use Class::C3::Componentised;
+
+use base qw(Class::Accessor::Grouped);
+
+our $namespace_counter = 0;
+
+__PACKAGE__->mk_group_accessors( 'simple' => qw/config_dir _inherited_attributes debug schema_class/);
+
+=head1 VERSION
+
+Version 1.000001
+
+=cut
+
+our $VERSION = '1.000001';
+
+=head1 NAME
+
+DBIx::Class::Fixtures
+
+=head1 SYNOPSIS
+
+ use DBIx::Class::Fixtures;
+
+ ...
+
+ my $fixtures = DBIx::Class::Fixtures->new({ config_dir => '/home/me/app/fixture_configs' });
+
+ $fixtures->dump({
+ config => 'set_config.json',
+ schema => $source_dbic_schema,
+ directory => '/home/me/app/fixtures'
+ });
+
+ $fixtures->populate({
+ directory => '/home/me/app/fixtures',
+ ddl => '/home/me/app/sql/ddl.sql',
+ connection_details => ['dbi:mysql:dbname=app_dev', 'me', 'password']
+ });
+
+=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.
+
+=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.
+
+For example:
+
+ {
+ sets: [{
+ class: 'Artist',
+ ids: ['1', '3']
+ }, {
+ class: 'Producer',
+ ids: ['5'],
+ fetch: [{
+ rel: 'artists',
+ quantity: '2'
+ }]
+ }]
+ }
+
+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</SET ATTRIBUTES> 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:
+
+ {
+ sets: [{
+ class: 'Artist',
+ ids: ['1', '3']
+ }, {
+ class: 'Producer',
+ ids: ['5'],
+ fetch: [{
+ rel: 'artists',
+ quantity: '2'
+ }]
+ }],
+ rules: {
+ Artist: {
+ fetch: [{
+ rel: 'cds',
+ quantity: 'all'
+ }]
+ }
+ }
+ }
+
+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: [{
+ class: 'Artist',
+ ids: ['1', '3'],
+ fetch: [{
+ rel: 'cds',
+ quantity: 'all'
+ }]
+ }, {
+ class: 'Producer',
+ ids: ['5'],
+ fetch: [{
+ rel: 'artists',
+ quantity: '2',
+ fetch: [{
+ rel: 'cds',
+ quantity: 'all'
+ }]
+ }]
+ }]
+ }
+
+rules must be a hash keyed by class name.
+
+L</RULE ATTRIBUTES>
+
+=head2 includes
+
+To prevent repetition between configs you can include other configs. For example:
+
+ {
+ sets: [{
+ class: 'Producer',
+ ids: ['5']
+ }],
+ includes: [{
+ file: 'base.json'
+ }]
+ }
+
+Includes must be an arrayref of hashrefs where the hashrefs have key 'file' which is the name of another config
+file in the same directory. The original config is merged with its includes using Hash::Merge.
+
+=head2 datetime_relative
+
+Only available for MySQL and PostgreSQL at the moment, must be a value that DateTime::Format::*
+can parse. For example:
+
+ {
+ sets: [{
+ class: 'RecentItems',
+ ids: ['9']
+ }],
+ 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.
+
+=head2 might_have
+
+Specifies whether to automatically dump might_have relationships. Should be a hash with one attribute - fetch. Set fetch to 1 or 0.
+
+ {
+ might_have: [{
+ fetch: 1
+ },
+ sets: [{
+ class: 'Artist',
+ ids: ['1', '3']
+ }, {
+ class: 'Producer',
+ ids: ['5']
+ }]
+ }
+
+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</SET ATTRIBUTES>.
+
+=head1 SET ATTRIBUTES
+
+=head2 class
+
+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.
+
+=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.
+
+=head2 cond
+
+A hash specifying the conditions dumped objects must match. Essentially this is a JSON representation of a DBIx::Class search clause. For example:
+
+ {
+ sets: [{
+ class: 'Artist',
+ quantiy: 'all',
+ cond: { name: 'Dave' }
+ }]
+ }
+
+This will dump all artists whose name is 'dave'. Essentially $artist_rs->search({ name => 'Dave' })->all.
+
+Sometimes in a search clause it's useful to use scalar refs to do things like:
+
+$artist_rs->search({ no1_singles => \'> no1_albums' })
+
+This could be specified in the cond hash like so:
+
+ {
+ sets: [{
+ class: 'Artist',
+ quantiy: 'all',
+ cond: { no1_singles: '\> no1_albums' }
+ }]
+ }
+
+So if the value starts with a backslash the value is made a scalar ref before being passed to search.
+
+=head2 join
+
+An array of relationships to be used in the cond clause.
+
+ {
+ sets: [{
+ class: 'Artist',
+ quantiy: 'all',
+ cond: { 'cds.position': { '>': 4 } },
+ join: ['cds']
+ }]
+ }
+
+Fetch all artists who have cds with position greater than 4.
+
+=head2 fetch
+
+Must be an array of hashes. Specifies which rels to also dump. For example:
+
+ {
+ sets: [{
+ class: 'Artist',
+ ids: ['1', '3'],
+ fetch: [{
+ rel: 'cds',
+ quantity: '3',
+ cond: { position: '2' }
+ }]
+ }]
+ }
+
+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.
+
+=head2 has_many
+
+Specifies whether to fetch has_many rels for this set. Must be a hash containing keys fetch and quantity.
+
+Set fetch to 1 if you want to fetch them, and quantity to either 'all' or an integer.
+
+Be careful here, dumping has_many rels can lead to a lot of data being dumped.
+
+=head2 might_have
+
+As with has_many but for might_have relationships. Quantity doesn't do anything in this case.
+
+This value will be inherited by all fetches in this set. This is not true for the has_many attribute.
+
+=head1 RULE ATTRIBUTES
+
+=head2 cond
+
+Same as with L</SET ATTRIBUTES>
+
+=head2 fetch
+
+Same as with L</SET ATTRIBUTES>
+
+=head2 join
+
+Same as with L</SET ATTRIBUTES>
+
+=head2 has_many
+
+Same as with L</SET ATTRIBUTES>
+
+=head2 might_have
+
+Same as with L</SET ATTRIBUTES>
+
+=head1 METHODS
+
+=head2 new
+
+=over 4
+
+=item Arguments: \%$attrs
+
+=item Return Value: $fixture_object
+
+=back
+
+Returns a new DBIx::Class::Fixture object. %attrs has only two valid keys at the
+moment - 'debug' which determines whether to be verbose and 'config_dir' which is required and much contain a valid path to
+the directory in which your .json configs reside.
+
+ my $fixtures = DBIx::Class::Fixtures->new({ config_dir => '/home/me/app/fixture_configs' });
+
+=cut
+
+sub new {
+ my $class = shift;
+
+ my ($params) = @_;
+ unless (ref $params eq 'HASH') {
+ return DBIx::Class::Exception->throw('first arg to DBIx::Class::Fixtures->new() must be hash ref');
+ }
+
+ unless ($params->{config_dir}) {
+ return DBIx::Class::Exception->throw('config_dir param not specified');
+ }
+
+ my $config_dir = dir($params->{config_dir});
+ unless (-e $params->{config_dir}) {
+ return DBIx::Class::Exception->throw('config_dir directory doesn\'t exist');
+ }
+
+ my $self = {
+ config_dir => $config_dir,
+ _inherited_attributes => [qw/datetime_relative might_have rules/],
+ debug => $params->{debug}
+ };
+
+ bless $self, $class;
+
+ return $self;
+}
+
+=head2 dump
+
+=over 4
+
+=item Arguments: \%$attrs
+
+=item Return Value: 1
+
+=back
+
+ $fixtures->dump({
+ config => 'set_config.json', # config file to use. must be in the config directory specified in the constructor
+ schema => $source_dbic_schema,
+ directory => '/home/me/app/fixtures' # output directory
+ });
+
+ or
+
+ $fixtures->dump({
+ all => 1, # just dump everything that's in the schema
+ schema => $source_dbic_schema,
+ directory => '/home/me/app/fixtures' # output directory
+ });
+
+In this case objects will be dumped to subdirectories in the specified directory. For example:
+
+ /home/me/app/fixtures/artist/1.fix
+ /home/me/app/fixtures/artist/3.fix
+ /home/me/app/fixtures/producer/5.fix
+
+schema and directory are required attributes. also, one of config or all must be specified.
+
+=cut
+
+sub dump {
+ my $self = shift;
+
+ my ($params) = @_;
+ unless (ref $params eq 'HASH') {
+ return DBIx::Class::Exception->throw('first arg to dump must be hash ref');
+ }
+
+ foreach my $param (qw/schema directory/) {
+ unless ($params->{$param}) {
+ return DBIx::Class::Exception->throw($param . ' param not specified');
+ }
+ }
+
+ my $schema = $params->{schema};
+ my $config_file;
+ my $config;
+ if ($params->{config}) {
+ #read config
+ $config_file = file($self->config_dir, $params->{config});
+ unless (-e $config_file) {
+ return DBIx::Class::Exception->throw('config does not exist at ' . $config_file);
+ }
+ $config = Config::Any::JSON->load($config_file);
+
+ #process includes
+ if ($config->{includes}) {
+ $self->msg($config->{includes});
+ unless (ref $config->{includes} eq 'ARRAY') {
+ return DBIx::Class::Exception->throw('includes params of config must be an array ref of hashrefs');
+ }
+ foreach my $include_config (@{$config->{includes}}) {
+ unless ((ref $include_config eq 'HASH') && $include_config->{file}) {
+ return DBIx::Class::Exception->throw('includes params of config must be an array ref of hashrefs');
+ }
+
+ my $include_file = file($self->config_dir, $include_config->{file});
+ unless (-e $include_file) {
+ return DBIx::Class::Exception->throw('config does not exist at ' . $include_file);
+ }
+ my $include = Config::Any::JSON->load($include_file);
+ $self->msg($include);
+ $config = merge( $config, $include );
+ }
+ delete $config->{includes};
+ }
+
+ # validate config
+ unless ($config && $config->{sets} && ref $config->{sets} eq 'ARRAY' && scalar(@{$config->{sets}})) {
+ return DBIx::Class::Exception->throw('config has no sets');
+ }
+
+ $config->{might_have} = { fetch => 0 } unless (exists $config->{might_have});
+ $config->{has_many} = { fetch => 0 } unless (exists $config->{has_many});
+ $config->{belongs_to} = { fetch => 1 } unless (exists $config->{belongs_to});
+ } elsif ($params->{all}) {
+ $config = { might_have => { fetch => 0 }, has_many => { fetch => 0 }, belongs_to => { fetch => 0 }, sets => [map {{ class => $_, quantity => 'all' }} $schema->sources] };
+ print Dumper($config);
+ } else {
+ return DBIx::Class::Exception->throw('must pass config or set all');
+ }
+
+ my $output_dir = dir($params->{directory});
+ unless (-e $output_dir) {
+ $output_dir->mkpath ||
+ return DBIx::Class::Exception->throw('output directory does not exist at ' . $output_dir);
+ }
+
+ $self->msg("generating fixtures");
+ my $tmp_output_dir = dir($output_dir, '-~dump~-' . $<);
+
+ if (-e $tmp_output_dir) {
+ $self->msg("- clearing existing $tmp_output_dir");
+ $tmp_output_dir->rmtree;
+ }
+ $self->msg("- creating $tmp_output_dir");
+ $tmp_output_dir->mkpath;
+
+ # write version file (for the potential benefit of populate)
+ my $version_file = file($tmp_output_dir, '_dumper_version');
+ write_file($version_file->stringify, $VERSION);
+
+ $config->{rules} ||= {};
+ my @sources = sort { $a->{class} cmp $b->{class} } @{delete $config->{sets}};
+ my %options = ( is_root => 1 );
+ foreach my $source (@sources) {
+ # apply rule to set if specified
+ my $rule = $config->{rules}->{$source->{class}};
+ $source = merge( $source, $rule ) if ($rule);
+
+ # fetch objects
+ my $rs = $schema->resultset($source->{class});
+ $rs = $rs->search($source->{cond}, { join => $source->{join} }) if ($source->{cond});
+ $self->msg("- dumping $source->{class}");
+ my @objects;
+ my %source_options = ( set => { %{$config}, %{$source} } );
+ if ($source->{quantity}) {
+ $rs = $rs->search({}, { order_by => $source->{order_by} }) if ($source->{order_by});
+ if ($source->{quantity} eq 'all') {
+ push (@objects, $rs->all);
+ } elsif ($source->{quantity} =~ /^\d+$/) {
+ push (@objects, $rs->search({}, { rows => $source->{quantity} }));
+ } else {
+ DBIx::Class::Exception->throw('invalid value for quantity - ' . $source->{quantity});
+ }
+ }
+ if ($source->{ids}) {
+ my @ids = @{$source->{ids}};
+ my @id_objects = grep { $_ } map { $rs->find($_) } @ids;
+ push (@objects, @id_objects);
+ }
+ unless ($source->{quantity} || $source->{ids}) {
+ DBIx::Class::Exception->throw('must specify either quantity or ids');
+ }
+
+ # dump objects
+ foreach my $object (@objects) {
+ $source_options{set_dir} = $tmp_output_dir;
+ $self->dump_object($object, { %options, %source_options } );
+ next;
+ }
+ }
+
+ foreach my $dir ($output_dir->children) {
+ next if ($dir eq $tmp_output_dir);
+ $dir->remove || $dir->rmtree;
+ }
+
+ $self->msg("- moving temp dir to $output_dir");
+ move($_, dir($output_dir, $_->relative($_->parent)->stringify)) for $tmp_output_dir->children;
+ if (-e $output_dir) {
+ $self->msg("- clearing tmp dir $tmp_output_dir");
+ # delete existing fixture set
+ $tmp_output_dir->remove;
+ }
+
+ $self->msg("done");
+
+ return 1;
+}
+
+sub dump_object {
+ my ($self, $object, $params, $rr_info) = @_;
+ my $set = $params->{set};
+ die 'no dir passed to dump_object' unless $params->{set_dir};
+ die 'no object passed to dump_object' unless $object;
+
+ my @inherited_attrs = @{$self->_inherited_attributes};
+
+ # write dir and gen filename
+ my $source_dir = dir($params->{set_dir}, lc($object->result_source->from));
+ mkdir($source_dir->stringify, 0777);
+ my $file = file($source_dir, join('-', map { $object->get_column($_) } sort $object->primary_columns) . '.fix');
+
+ # write file
+ my $exists = (-e $file->stringify) ? 1 : 0;
+ unless ($exists) {
+ $self->msg('-- dumping ' . $file->stringify, 2);
+ my %ds = $object->get_columns;
+
+ my $formatter= $object->result_source->schema->storage->datetime_parser;
+ # mess with dates if specified
+ if ($set->{datetime_relative}) {
+ unless ($@ || !$formatter) {
+ my $dt;
+ if ($set->{datetime_relative} eq 'today') {
+ $dt = DateTime->today;
+ } else {
+ $dt = $formatter->parse_datetime($set->{datetime_relative}) unless ($@);
+ }
+
+ while (my ($col, $value) = each %ds) {
+ my $col_info = $object->result_source->column_info($col);
+
+ next unless $value
+ && $col_info->{_inflate_info}
+ && uc($col_info->{data_type}) eq 'DATETIME';
+
+ $ds{$col} = $object->get_inflated_column($col)->subtract_datetime($dt);
+ }
+ } else {
+ warn "datetime_relative not supported for this db driver at the moment";
+ }
+ }
+
+ # do the actual dumping
+ my $serialized = Dump(\%ds)->Out();
+ write_file($file->stringify, $serialized);
+ my $mode = 0777; chmod $mode, $file->stringify;
+ }
+
+ # don't bother looking at rels unless we are actually planning to dump at least one type
+ return unless ($set->{might_have}->{fetch} || $set->{belongs_to}->{fetch} || $set->{has_many}->{fetch} || $set->{fetch});
+
+ # dump rels of object
+ my $s = $object->result_source;
+ unless ($exists) {
+ foreach my $name (sort $s->relationships) {
+ my $info = $s->relationship_info($name);
+ my $r_source = $s->related_source($name);
+ # if belongs_to or might_have with might_have param set or has_many with has_many param set then
+ if (($info->{attrs}{accessor} eq 'single' && (!$info->{attrs}{join_type} || ($set->{might_have} && $set->{might_have}->{fetch}))) || $info->{attrs}{accessor} eq 'filter' || ($info->{attrs}{accessor} eq 'multi' && ($set->{has_many} && $set->{has_many}->{fetch}))) {
+ my $related_rs = $object->related_resultset($name);
+ my $rule = $set->{rules}->{$related_rs->result_source->source_name};
+ # these parts of the rule only apply to has_many rels
+ if ($rule && $info->{attrs}{accessor} eq 'multi') {
+ $related_rs = $related_rs->search($rule->{cond}, { join => $rule->{join} }) if ($rule->{cond});
+ $related_rs = $related_rs->search({}, { rows => $rule->{quantity} }) if ($rule->{quantity} && $rule->{quantity} ne 'all');
+ $related_rs = $related_rs->search({}, { order_by => $rule->{order_by} }) if ($rule->{order_by});
+ }
+ if ($set->{has_many}->{quantity} && $set->{has_many}->{quantity} =~ /^\d+$/) {
+ $related_rs = $related_rs->search({}, { rows => $set->{has_many}->{quantity} });
+ }
+ my %c_params = %{$params};
+ # inherit date param
+ my %mock_set = map { $_ => $set->{$_} } grep { $set->{$_} } @inherited_attrs;
+ $c_params{set} = \%mock_set;
+ # use Data::Dumper; print ' -- ' . Dumper($c_params{set}, $rule->{fetch}) if ($rule && $rule->{fetch});
+ $c_params{set} = merge( $c_params{set}, $rule) if ($rule && $rule->{fetch});
+ # use Data::Dumper; print ' -- ' . Dumper(\%c_params) if ($rule && $rule->{fetch});
+ $self->dump_object($_, \%c_params) foreach $related_rs->all;
+ }
+ }
+ }
+
+ return unless $set && $set->{fetch};
+ foreach my $fetch (@{$set->{fetch}}) {
+ # inherit date param
+ $fetch->{$_} = $set->{$_} foreach grep { !$fetch->{$_} && $set->{$_} } @inherited_attrs;
+ my $related_rs = $object->related_resultset($fetch->{rel});
+ my $rule = $set->{rules}->{$related_rs->result_source->source_name};
+ if ($rule) {
+ my $info = $object->result_source->relationship_info($fetch->{rel});
+ if ($info->{attrs}{accessor} eq 'multi') {
+ $fetch = merge( $fetch, $rule );
+ } elsif ($rule->{fetch}) {
+ $fetch = merge( $fetch, { fetch => $rule->{fetch} } );
+ }
+ }
+ die "relationship " . $fetch->{rel} . " does not exist for " . $s->source_name unless ($related_rs);
+ if ($fetch->{cond} and ref $fetch->{cond} eq 'HASH') {
+ # if value starts with / assume it's meant to be passed as a scalar ref to dbic
+ # ideally this would substitute deeply
+ $fetch->{cond} = { map { $_ => ($fetch->{cond}->{$_} =~ s/^\\//) ? \$fetch->{cond}->{$_} : $fetch->{cond}->{$_} } keys %{$fetch->{cond}} };
+ }
+ $related_rs = $related_rs->search($fetch->{cond}, { join => $fetch->{join} }) if ($fetch->{cond});
+ $related_rs = $related_rs->search({}, { rows => $fetch->{quantity} }) if ($fetch->{quantity} && $fetch->{quantity} ne 'all');
+ $related_rs = $related_rs->search({}, { order_by => $fetch->{order_by} }) if ($fetch->{order_by});
+ $self->dump_object($_, { %{$params}, set => $fetch }) foreach $related_rs->all;
+ }
+}
+
+sub _generate_schema {
+ my $self = shift;
+ my $params = shift || {};
+ require DBI;
+ $self->msg("\ncreating schema");
+ # die 'must pass version param to generate_schema_from_ddl' unless $params->{version};
+
+ my $schema_class = $self->schema_class || "DBIx::Class::Fixtures::Schema";
+ eval "require $schema_class";
+ die $@ if $@;
+
+ my $pre_schema;
+ my $connection_details = $params->{connection_details};
+ $namespace_counter++;
+ my $namespace = "DBIx::Class::Fixtures::GeneratedSchema_" . $namespace_counter;
+ Class::C3::Componentised->inject_base( $namespace => $schema_class );
+ $pre_schema = $namespace->connect(@{$connection_details});
+ unless( $pre_schema ) {
+ return DBIx::Class::Exception->throw('connection details not valid');
+ }
+ my @tables = map { $pre_schema->source($_)->from } $pre_schema->sources;
+ my $dbh = $pre_schema->storage->dbh;
+
+ # clear existing db
+ $self->msg("- clearing DB of existing tables");
+ eval { $dbh->do('SET foreign_key_checks=0') };
+ $dbh->do('drop table ' . $_) for (@tables);
+
+ # import new ddl file to db
+ my $ddl_file = $params->{ddl};
+ $self->msg("- deploying schema using $ddl_file");
+ my $fh;
+ open $fh, "<$ddl_file" or die ("Can't open DDL file, $ddl_file ($!)");
+ my @data = split(/\n/, join('', <$fh>));
+ @data = grep(!/^--/, @data);
+ @data = split(/;/, join('', @data));
+ close($fh);
+ @data = grep { $_ && $_ !~ /^-- / } @data;
+ for (@data) {
+ eval { $dbh->do($_) or warn "SQL was:\n $_"};
+ if ($@) { die "SQL was:\n $_\n$@"; }
+ }
+ $self->msg("- finished importing DDL into DB");
+
+ # load schema object from our new DB
+ $namespace_counter++;
+ my $namespace2 = "DBIx::Class::Fixtures::GeneratedSchema_" . $namespace_counter;
+ Class::C3::Componentised->inject_base( $namespace2 => $schema_class );
+ my $schema = $namespace2->connect(@{$connection_details});
+ return $schema;
+}
+
+
+=head2 populate
+
+=over 4
+
+=item Arguments: \%$attrs
+
+=item Return Value: 1
+
+=back
+
+ $fixtures->populate({
+ directory => '/home/me/app/fixtures', # directory to look for fixtures in, as specified to dump
+ ddl => '/home/me/app/sql/ddl.sql', # DDL to deploy
+ connection_details => ['dbi:mysql:dbname=app_dev', 'me', 'password'] # database to clear, deploy and then populate
+ });
+
+In this case the database app_dev will be cleared of all tables, then the specified DDL deployed to it,
+then finally all fixtures found in /home/me/app/fixtures will be added to it. populate will generate
+its own DBIx::Class schema from the DDL rather than being passed one to use. This is better as
+custom insert methods are avoided which can to get in the way. In some cases you might not
+have a DDL, and so this method will eventually allow a $schema object to be passed instead.
+
+directory, dll and connection_details are all required attributes.
+
+=cut
+
+sub populate {
+ my $self = shift;
+ my ($params) = @_;
+ unless (ref $params eq 'HASH') {
+ return DBIx::Class::Exception->throw('first arg to populate must be hash ref');
+ }
+
+ foreach my $param (qw/directory/) {
+ unless ($params->{$param}) {
+ return DBIx::Class::Exception->throw($param . ' param not specified');
+ }
+ }
+ my $fixture_dir = dir(delete $params->{directory});
+ unless (-e $fixture_dir) {
+ return DBIx::Class::Exception->throw('fixture directory does not exist at ' . $fixture_dir);
+ }
+
+ my $ddl_file;
+ my $dbh;
+ if ($params->{ddl} && $params->{connection_details}) {
+ $ddl_file = file(delete $params->{ddl});
+ unless (-e $ddl_file) {
+ return DBIx::Class::Exception->throw('DDL does not exist at ' . $ddl_file);
+ }
+ unless (ref $params->{connection_details} eq 'ARRAY') {
+ return DBIx::Class::Exception->throw('connection details must be an arrayref');
+ }
+ } elsif ($params->{schema}) {
+ return DBIx::Class::Exception->throw('passing a schema is not supported at the moment');
+ } else {
+ return DBIx::Class::Exception->throw('you must set the ddl and connection_details params');
+ }
+
+ my $schema = $self->_generate_schema({ ddl => $ddl_file, connection_details => delete $params->{connection_details}, %{$params} });
+ $self->msg("\nimporting fixtures");
+ my $tmp_fixture_dir = dir($fixture_dir, "-~populate~-" . $<);
+
+ my $version_file = file($fixture_dir, '_dumper_version');
+ unless (-e $version_file) {
+# return DBIx::Class::Exception->throw('no version file found');
+ }
+
+ if (-e $tmp_fixture_dir) {
+ $self->msg("- deleting existing temp directory $tmp_fixture_dir");
+ $tmp_fixture_dir->rmtree;
+ }
+ $self->msg("- creating temp dir");
+ dircopy(dir($fixture_dir, $schema->source($_)->from), dir($tmp_fixture_dir, $schema->source($_)->from)) for grep { -e dir($fixture_dir, $schema->source($_)->from) } $schema->sources;
+
+ eval { $schema->storage->dbh->do('SET foreign_key_checks=0') };
+
+ my $fixup_visitor;
+ my $formatter= $schema->storage->datetime_parser;
+ unless ($@ || !$formatter) {
+ my %callbacks;
+ if ($params->{datetime_relative_to}) {
+ $callbacks{'DateTime::Duration'} = sub {
+ $params->{datetime_relative_to}->clone->add_duration($_);
+ };
+ } else {
+ $callbacks{'DateTime::Duration'} = sub {
+ $formatter->format_datetime(DateTime->today->add_duration($_))
+ };
+ }
+ $callbacks{object} ||= "visit_ref";
+ $fixup_visitor = new Data::Visitor::Callback(%callbacks);
+ }
+ foreach my $source (sort $schema->sources) {
+ $self->msg("- adding " . $source);
+ my $rs = $schema->resultset($source);
+ my $source_dir = dir($tmp_fixture_dir, lc($rs->result_source->from));
+ next unless (-e $source_dir);
+ while (my $file = $source_dir->next) {
+ next unless ($file =~ /\.fix$/);
+ next if $file->is_dir;
+ my $contents = $file->slurp;
+ my $HASH1;
+ eval($contents);
+ $HASH1 = $fixup_visitor->visit($HASH1) if $fixup_visitor;
+ $rs->create($HASH1);
+ }
+ }
+
+ $self->msg("- fixtures imported");
+ $self->msg("- cleaning up");
+ $tmp_fixture_dir->rmtree;
+ eval { $schema->storage->dbh->do('SET foreign_key_checks=1') };
+
+ return 1;
+}
+
+sub msg {
+ my $self = shift;
+ my $subject = shift || return;
+ my $level = shift || 1;
+ return unless $self->debug >= $level;
+ if (ref $subject) {
+ print Dumper($subject);
+ } else {
+ print $subject . "\n";
+ }
+}
+
+=head1 AUTHOR
+
+ Luke Saunders <luke at shadowcatsystems.co.uk>
+
+ Initial development sponsored by and (c) Takkle, Inc. 2007
+
+=head1 CONTRIBUTORS
+
+ Ash Berlin <ash at shadowcatsystems.co.uk>
+ Matt S. Trout <mst at shadowcatsystems.co.uk>
+
+=head1 LICENSE
+
+ This library is free software under the same license as perl itself
+
+=cut
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/00-load.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/00-load.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/00-load.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,9 @@
+#!perl -T
+
+use Test::More tests => 1;
+
+BEGIN {
+ use_ok( 'DBIx::Class::Fixtures' );
+}
+
+diag( "Testing DBIx::Class::Fixtures $DBIx::Class::Fixtures::VERSION, Perl $], $^X" );
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/01-new.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/01-new.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/01-new.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,19 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More tests => 3;
+
+my $config_dir = 't/var/configs';
+my $imaginary_config_dir = 't/var/not_there';
+
+eval {
+ DBIx::Class::Fixtures->new({ });
+};
+ok($@, 'new errors without config dir');
+
+eval {
+ DBIx::Class::Fixtures->new({ config_dir => $imaginary_config_dir });
+};
+ok($@, 'new errors with non-existent config dir');
+
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir }), 'object created with correct config dir');
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/02-dump-basic.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/02-dump-basic.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/02-dump-basic.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,36 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More tests => 9;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $config_dir = 't/var/configs';
+
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+ok($fixtures->dump({ config => 'simple.json', schema => $schema, directory => 't/var/fixtures' }), 'simple dump executed okay');
+
+# check dump is okay
+my $dir = dir('t/var/fixtures/artist');
+ok(-e 't/var/fixtures/artist', 'artist directory created');
+
+my @children = $dir->children;
+is(scalar(@children), 1, 'right number of fixtures created');
+
+my $fix_file = $children[0];
+my $HASH1; eval($fix_file->slurp());
+is(ref $HASH1, 'HASH', 'fixture evals into hash');
+
+is_deeply([sort $schema->source('Artist')->columns], [sort keys %{$HASH1}], 'fixture has correct keys');
+
+my $artist = $schema->resultset('Artist')->find($HASH1->{artistid});
+is_deeply({$artist->get_columns}, $HASH1, 'dumped fixture is equivalent to artist row');
+
+$schema->resultset('Artist')->delete; # so we can create the row again on the next line
+ok($schema->resultset('Artist')->create($HASH1), 'new dbic row created from fixture');
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/03-dump-quantity.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/03-dump-quantity.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/03-dump-quantity.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,29 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More tests => 10;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $config_dir = 't/var/configs';
+
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+ok($fixtures->dump({ config => 'quantity.json', schema => $schema, directory => 't/var/fixtures' }), 'quantity dump executed okay');
+
+# check dump is okay
+my $dir = dir('t/var/fixtures/cd');
+my @children = $dir->children;
+is(scalar(@children), 3, 'right number of cd fixtures created');
+
+foreach my $cd_fix_file (@children) {
+ my $HASH1; eval($cd_fix_file->slurp());
+ is(ref $HASH1, 'HASH', 'fixture evals into hash');
+ my $cd = $schema->resultset('CD')->find($HASH1->{cdid});
+ is_deeply({$cd->get_columns}, $HASH1, 'dumped fixture is equivalent to cd row');
+}
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/04-dump-fetch.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/04-dump-fetch.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/04-dump-fetch.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,51 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More tests => 11;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $config_dir = 't/var/configs';
+
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+ok($fixtures->dump({ config => 'fetch.json', schema => $schema, directory => 't/var/fixtures' }), 'fetch dump executed okay');
+
+# check dump is okay
+my $dir = dir('t/var/fixtures/artist');
+my @children = $dir->children;
+is(scalar(@children), 2, 'right number of artist fixtures created');
+
+# check both artists dumped
+foreach my $id (1, 2) {
+ my $artist_fix_file = dir($dir, $id . '.fix');
+ ok(-e $artist_fix_file, "artist $id dumped okay");
+}
+
+# check all of artist1's cds were fetched
+my $artist1 = $schema->resultset('Artist')->find(1);
+my @artist1_cds = $artist1->cds->all;
+foreach my $cd (@artist1_cds) {
+ my $cd_fix_file = dir('t/var/fixtures', 'cd', $cd->id . '.fix');
+ ok(-e $cd_fix_file, "artist1's cd rel dumped okay");
+}
+
+# check only cds matching artist2's cond were fetched
+my $artist2 = $schema->resultset('Artist')->find(2);
+my @artist2_cds = $artist2->cds->search({ year => { '>' => 2002 } });
+foreach my $cd (@artist2_cds) {
+ my $cd_fix_file = dir('t/var/fixtures', 'cd', $cd->id . '.fix');
+ ok(-e $cd_fix_file, "artist2's cd rel dumped okay");
+}
+
+my $cd_dir = dir('t/var/fixtures/cd');
+ at children = $cd_dir->children;
+is(scalar(@children), scalar(@artist1_cds) + scalar(@artist2_cds), 'no extra cd fixtures dumped');
+
+
+
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/05-dump-rules.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/05-dump-rules.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/05-dump-rules.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,50 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More tests => 14;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $config_dir = 't/var/configs';
+
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+ok($fixtures->dump({ config => 'rules.json', schema => $schema, directory => 't/var/fixtures' }), 'fetch dump executed okay');
+
+# check dump is okay
+my $dir = dir('t/var/fixtures');
+my $cd_dir = dir($dir, 'cd');
+my $track_dir = dir($dir, 'track');
+
+# check only artist1's cds that matched the rule were fetched
+my $artist1 = $schema->resultset('Artist')->find(1);
+my $artist1_cds = $artist1->cds;
+while (my $a1_cd = $artist1_cds->next) {
+ my $cd_fix_file = file($cd_dir, $a1_cd->id . '.fix');
+ if ($a1_cd->tags->search({ tag => 'Cheesy' })->count) {
+ ok(-e $cd_fix_file, 'cd matching rule fetched');
+ } else {
+ isnt(-e $cd_fix_file, 1, 'cd not matching rule not fetched');
+ }
+}
+
+# check only cds' tracks that matched the rule were fetched
+foreach my $cd_fix_file ($cd_dir->children) {
+ my $HASH1; eval($cd_fix_file->slurp());
+ is(ref $HASH1, 'HASH', 'cd fixture evals into hash');
+
+ my $cd = $schema->resultset('CD')->find($HASH1->{cdid});
+ foreach my $track ($cd->tracks->all) {
+ my $track_fix_file = file($track_dir, $track->id . '.fix');
+ if ($track->get_column('position') eq 2) {
+ is(-e $track_fix_file, 1, 'track matching rule fetched');
+ } else {
+ isnt(-e $track_fix_file, 1, 'track not matching rule not fetched');
+ }
+ }
+}
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/06-dump-date.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/06-dump-date.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/06-dump-date.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,30 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+use DateTime;
+
+plan skip_all => 'Set $ENV{FIXTURETEST_DSN}, _USER and _PASS to point at MySQL DB to run this test'
+ unless ($ENV{FIXTURETEST_DSN});
+
+plan tests => 5;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema( dsn => $ENV{FIXTURETEST_DSN}, user => $ENV{FIXTURETEST_USER}, pass => $ENV{FIXTURETEST_PASS}), 'got schema');
+
+my $config_dir = 't/var/configs';
+
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+ok($fixtures->dump({ config => 'date.json', schema => $schema, directory => 't/var/fixtures' }), 'date dump executed okay');
+ok($fixtures->populate({ ddl => DBICTest->get_ddl_file($schema), connection_details => [$ENV{FIXTURETEST_DSN}, $ENV{FIXTURETEST_DBUSER} || '', $ENV{FIXTURETEST_DBPASS} || ''], directory => 't/var/fixtures' }), 'date populate okay');
+
+my $track = $schema->resultset('Track')->find(9);
+my $now = DateTime->now();
+my $dt = $track->get_inflated_column('last_updated_on');
+my $diff = $now->subtract_datetime( $dt );
+is($diff->delta_days, 10, 'date set to the correct time in the past');
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/07-dump-all.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/07-dump-all.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/07-dump-all.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,28 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+
+plan tests => 9;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema( ), 'got schema');
+
+my $config_dir = 't/var/configs';
+my $fixture_dir = 't/var/fixtures';
+
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+ok($fixtures->dump({ all => 1, schema => $schema, directory => 't/var/fixtures' }), 'fetch dump executed okay');
+
+
+foreach my $source ($schema->sources) {
+ my $rs = $schema->resultset($source);
+ my $dir = dir($fixture_dir, $rs->result_source->from);
+ my @children = $dir->children;
+ is (scalar(@children), $rs->count, 'all objects from $source dumped');
+}
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/08-dump-includes.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/08-dump-includes.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/08-dump-includes.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,31 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More tests => 7;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $config_dir = 't/var/configs';
+
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+ok($fixtures->dump({ config => 'includes.json', schema => $schema, directory => 't/var/fixtures' }), 'simple dump executed okay');
+
+# check dump is okay
+my $producer_dir = dir('t/var/fixtures/producer');
+ok(-e $producer_dir, 'producer directory created');
+
+my @producer_children = $producer_dir->children;
+is(scalar(@producer_children), 1, 'right number of fixtures created');
+
+my $artist_dir = dir('t/var/fixtures/artist');
+ok(-e $artist_dir, 'artist directory created');
+
+my @artist_children = $artist_dir->children;
+is(scalar(@artist_children), 1, 'right number of fixtures created');
+
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/12-populate-basic.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/12-populate-basic.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/12-populate-basic.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,37 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More tests => 47;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+my $config_dir = 't/var/configs';
+
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+
+foreach my $set ('simple', 'quantity', 'fetch', 'rules') {
+ no warnings 'redefine';
+ DBICTest->clear_schema($schema);
+ DBICTest->populate_schema($schema);
+ ok($fixtures->dump({ config => "$set.json", schema => $schema, directory => 't/var/fixtures' }), "$set dump executed okay");
+ $fixtures->populate({ ddl => 't/lib/sqlite.sql', connection_details => ['dbi:SQLite:t/var/DBIxClass.db', '', ''], directory => 't/var/fixtures' });
+
+ my $fixture_dir = dir('t/var/fixtures');
+ foreach my $class ($schema->sources) {
+ my $source_dir = dir($fixture_dir, lc($class));
+ is($schema->resultset($class)->count, (-e $source_dir) ? scalar($source_dir->children) : 0, "correct number of $set " . lc($class) . 's ' . $schema->resultset($class)->count);
+ next unless (-e $source_dir);
+
+ my $rs = $schema->resultset($class);
+ foreach my $row ($rs->all) {
+ my $file = file($source_dir, $row->id . '.fix');
+ my $HASH1; eval($file->slurp());
+ is_deeply($HASH1, {$row->get_columns}, "$set " . lc($class) . " row " . $row->id . " imported okay")
+ }
+ }
+}
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/13populate-two-dbs.t
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/13populate-two-dbs.t (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/13populate-two-dbs.t 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,26 @@
+#!perl
+
+use DBIx::Class::Fixtures;
+use Test::More tests => 7;
+use lib qw(t/lib);
+use DBICTest;
+use Path::Class;
+use Data::Dumper;
+use DBICTest::Schema2;
+
+# set up and populate normal schema
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+my $config_dir = 't/var/configs';
+
+my @different_connection_details = ('dbi:SQLite:t/var/DBIxClassDifferent.db', '', '');
+ok(my $schema2 = DBICTest::Schema2->compose_namespace('DBICTest2')->connect(@different_connection_details));
+unlink('t/var/DBIxClassDifferent.db') if (-e 't/var/DBIxClassDifferent.db');
+DBICTest->deploy_schema($schema2, 't/lib/sqlite_different.sql');
+# do dump
+ok(my $fixtures = DBIx::Class::Fixtures->new({ config_dir => $config_dir, debug => 0 }), 'object created with correct config dir');
+ok($fixtures->dump({ config => "simple.json", schema => $schema, directory => 't/var/fixtures' }), "simple dump executed okay");
+
+ok($fixtures->populate({ ddl => 't/lib/sqlite_different.sql', connection_details => [@different_connection_details], directory => 't/var/fixtures' }), 'mysql populate okay');
+ok($fixtures->populate({ ddl => 't/lib/sqlite.sql', connection_details => ['dbi:SQLite:t/var/DBIxClass.db', '', ''], directory => 't/var/fixtures' }), 'sqlite populate okay');
+
+is($schema->resultset('Artist')->count, 1, 'artist imported to sqlite okay');
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Artist.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Artist.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Artist.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,25 @@
+package # hide from PAUSE
+ DBICTest::Schema::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::Schema::CD', undef,
+ { order_by => 'year' },
+);
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/CD.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/CD.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/CD.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,44 @@
+package # hide from PAUSE
+ DBICTest::Schema::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::Schema::Artist' );
+
+__PACKAGE__->has_many( tracks => 'DBICTest::Schema::Track' );
+__PACKAGE__->has_many(
+ tags => 'DBICTest::Schema::Tag', undef,
+ { order_by => 'tag' },
+);
+__PACKAGE__->has_many(
+ cd_to_producer => 'DBICTest::Schema::CD_to_Producer' => 'cd'
+);
+
+__PACKAGE__->many_to_many( producers => cd_to_producer => 'producer' );
+__PACKAGE__->many_to_many(
+ producers_sorted => cd_to_producer => 'producer',
+ { order_by => 'producer.name' },
+);
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/CD_to_Producer.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/CD_to_Producer.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/CD_to_Producer.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,23 @@
+package # hide from PAUSE
+ DBICTest::Schema::CD_to_Producer;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('cd_to_producer');
+__PACKAGE__->add_columns(
+ cd => { data_type => 'integer' },
+ producer => { data_type => 'integer' },
+);
+__PACKAGE__->set_primary_key(qw/cd producer/);
+
+__PACKAGE__->belongs_to(
+ 'cd', 'DBICTest::Schema::CD',
+ { 'foreign.cdid' => 'self.cd' }
+);
+
+__PACKAGE__->belongs_to(
+ 'producer', 'DBICTest::Schema::Producer',
+ { 'foreign.producerid' => 'self.producer' }
+);
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Producer.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Producer.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Producer.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,20 @@
+package # hide from PAUSE
+ DBICTest::Schema::Producer;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('producer');
+__PACKAGE__->add_columns(
+ 'producerid' => {
+ data_type => 'integer',
+ is_auto_increment => 1
+ },
+ 'name' => {
+ data_type => 'varchar',
+ size => 100,
+ },
+);
+__PACKAGE__->set_primary_key('producerid');
+__PACKAGE__->add_unique_constraint(prod_name => [ qw/name/ ]);
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Tag.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Tag.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Tag.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,24 @@
+package # hide from PAUSE
+ DBICTest::Schema::Tag;
+
+use base qw/DBIx::Class::Core/;
+
+__PACKAGE__->table('tags');
+__PACKAGE__->add_columns(
+ 'tagid' => {
+ data_type => 'integer',
+ is_auto_increment => 1,
+ },
+ 'cd' => {
+ data_type => 'integer',
+ },
+ 'tag' => {
+ data_type => 'varchar',
+ size => 100,
+ },
+);
+__PACKAGE__->set_primary_key('tagid');
+
+__PACKAGE__->belongs_to( cd => 'DBICTest::Schema::CD' );
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Track.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Track.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema/Track.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,37 @@
+package # hide from PAUSE
+ DBICTest::Schema::Track;
+
+use base 'DBIx::Class::Core';
+__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
+
+__PACKAGE__->table('track');
+__PACKAGE__->add_columns(
+ 'trackid' => {
+ data_type => 'integer',
+ is_auto_increment => 1,
+ },
+ 'cd' => {
+ data_type => 'integer',
+ },
+ 'position' => {
+ data_type => 'integer',
+ accessor => 'pos',
+ },
+ 'title' => {
+ data_type => 'varchar',
+ size => 100,
+ },
+ last_updated_on => {
+ data_type => 'datetime',
+ accessor => 'updated_date',
+ is_nullable => 1
+ },
+);
+__PACKAGE__->set_primary_key('trackid');
+
+__PACKAGE__->add_unique_constraint([ qw/cd position/ ]);
+__PACKAGE__->add_unique_constraint([ qw/cd title/ ]);
+
+__PACKAGE__->belongs_to( cd => 'DBICTest::Schema::CD' );
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,10 @@
+package # hide from PAUSE
+ DBICTest::Schema;
+
+use base qw/DBIx::Class::Schema/;
+
+no warnings qw/qw/;
+
+__PACKAGE__->load_classes(qw/Artist CD Track Tag Producer CD_to_Producer/);
+
+1;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/Artist.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/Artist.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/Artist.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -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;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/CD.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/CD.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/CD.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -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;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/Friend.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/Friend.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2/Friend.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -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;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest/Schema2.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -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;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest.pm
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest.pm (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest.pm 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,199 @@
+package # hide from PAUSE
+ DBICTest;
+
+use strict;
+use warnings;
+use DBICTest::Schema;
+
+=head1 NAME
+
+DBICTest - Library to be used by DBIx::Class test scripts.
+
+=head1 SYNOPSIS
+
+ use lib qw(t/lib);
+ use DBICTest;
+ use Test::More;
+
+ my $schema = DBICTest->init_schema();
+
+=head1 DESCRIPTION
+
+This module provides the basic utilities to write tests against
+DBIx::Class.
+
+=head1 METHODS
+
+=head2 init_schema
+
+ my $schema = DBICTest->init_schema(
+ no_deploy=>1,
+ no_populate=>1,
+ );
+
+This method removes the test SQLite database in t/var/DBIxClass.db
+and then creates a new, empty database.
+
+This method will call deploy_schema() by default, unless the
+no_deploy flag is set.
+
+Also, by default, this method will call populate_schema() by
+default, unless the no_deploy or no_populate flags are set.
+
+=cut
+
+sub init_schema {
+ my $self = shift;
+ my %args = @_;
+
+ my $db_file = "t/var/DBIxClass.db";
+
+ unlink($db_file) if -e $db_file;
+ unlink($db_file . "-journal") if -e $db_file . "-journal";
+ mkdir("t/var") unless -d "t/var";
+
+ my $dsn = $args{"dsn"} || "dbi:SQLite:${db_file}";
+ my $dbuser = $args{"user"} || '';
+ my $dbpass = $args{"pass"} || '';
+
+ my $schema;
+
+ my @connect_info = ($dsn, $dbuser, $dbpass, { AutoCommit => 1 });
+
+ if ($args{compose_connection}) {
+ $schema = DBICTest::Schema->compose_connection(
+ 'DBICTest', @connect_info
+ );
+ } else {
+ $schema = DBICTest::Schema->compose_namespace('DBICTest')
+ ->connect(@connect_info);
+ }
+
+ if ( !$args{no_deploy} ) {
+ __PACKAGE__->deploy_schema( $schema );
+ __PACKAGE__->populate_schema( $schema ) if( !$args{no_populate} );
+ }
+ return $schema;
+}
+
+
+sub get_ddl_file {
+ my $self = shift;
+ my $schema = shift;
+
+ return 't/lib/' . lc($schema->storage->dbh->{Driver}->{Name}) . '.sql';
+}
+
+=head2 deploy_schema
+
+ DBICTest->deploy_schema( $schema );
+
+=cut
+
+sub deploy_schema {
+ my $self = shift;
+ my $schema = shift;
+
+ my $file = shift || $self->get_ddl_file($schema);
+ open IN, $file;
+ my $sql;
+ { local $/ = undef; $sql = <IN>; }
+ close IN;
+ ($schema->storage->dbh->do($_) || print "Error on SQL: $_\n") for split(/;\n/, $sql);
+}
+
+
+=head2 clear_schema
+
+ DBICTest->clear_schema( $schema );
+
+=cut
+
+sub clear_schema {
+ my $self = shift;
+ my $schema = shift;
+
+ foreach my $class ($schema->sources) {
+ $schema->resultset($class)->delete;
+ }
+}
+
+
+=head2 populate_schema
+
+ DBICTest->populate_schema( $schema );
+
+After you deploy your schema you can use this method to populate
+the tables with test data.
+
+=cut
+
+sub populate_schema {
+ my $self = shift;
+ my $schema = shift;
+
+ $schema->populate('Artist', [
+ [ qw/artistid name/ ],
+ [ 1, 'Caterwauler McCrae' ],
+ [ 2, 'Random Boy Band' ],
+ [ 3, 'We Are Goth' ],
+ ]);
+
+ $schema->populate('CD', [
+ [ qw/cdid artist title year/ ],
+ [ 1, 1, "Spoonful of bees", 1999 ],
+ [ 2, 1, "Forkful of bees", 2001 ],
+ [ 3, 1, "Caterwaulin' Blues", 1997 ],
+ [ 4, 2, "Generic Manufactured Singles", 2001 ],
+ [ 5, 2, "We like girls and stuff", 2003 ],
+ [ 6, 3, "Come Be Depressed With Us", 1998 ],
+ ]);
+
+ $schema->populate('Tag', [
+ [ qw/tagid cd tag/ ],
+ [ 1, 1, "Blue" ],
+ [ 2, 2, "Blue" ],
+ [ 3, 3, "Blue" ],
+ [ 4, 5, "Blue" ],
+ [ 5, 2, "Cheesy" ],
+ [ 6, 4, "Cheesy" ],
+ [ 7, 5, "Cheesy" ],
+ [ 8, 2, "Shiny" ],
+ [ 9, 4, "Shiny" ],
+ ]);
+
+ $schema->populate('Producer', [
+ [ qw/producerid name/ ],
+ [ 1, 'Matt S Trout' ],
+ [ 2, 'Bob The Builder' ],
+ [ 3, 'Fred The Phenotype' ],
+ ]);
+
+ $schema->populate('CD_to_Producer', [
+ [ qw/cd producer/ ],
+ [ 1, 1 ],
+ [ 1, 2 ],
+ [ 1, 3 ],
+ ]);
+
+ $schema->populate('Track', [
+ [ qw/trackid cd position title last_updated_on/ ],
+ [ 4, 2, 1, "Stung with Success"],
+ [ 5, 2, 2, "Stripy"],
+ [ 6, 2, 3, "Sticky Honey"],
+ [ 7, 3, 1, "Yowlin"],
+ [ 8, 3, 2, "Howlin"],
+ [ 9, 3, 3, "Fowlin", '2007-10-20 00:00:00'],
+ [ 10, 4, 1, "Boring Name"],
+ [ 11, 4, 2, "Boring Song"],
+ [ 12, 4, 3, "No More Ideas"],
+ [ 13, 5, 1, "Sad"],
+ [ 14, 5, 2, "Under The Weather"],
+ [ 15, 5, 3, "Suicidal"],
+ [ 16, 1, 1, "The Bees Knees"],
+ [ 17, 1, 2, "Apiary"],
+ [ 18, 1, 3, "Beehind You"],
+ ]);
+}
+
+1;
Property changes on: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/DBICTest.pm
___________________________________________________________________
Name: svn:executable
+ *
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/mysql.sql
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/mysql.sql (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/mysql.sql 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,61 @@
+--
+-- Table: cd_to_producer
+--
+DROP TABLE IF EXISTS cd_to_producer;
+CREATE TABLE cd_to_producer (
+ cd integer NOT NULL,
+ producer integer NOT NULL,
+ PRIMARY KEY (cd, producer)
+);
+
+--
+-- Table: artist
+--
+DROP TABLE IF EXISTS artist;
+CREATE TABLE artist (
+ artistid INTEGER PRIMARY KEY NOT NULL,
+ name varchar(100)
+);
+
+
+--
+-- Table: cd
+--
+DROP TABLE IF EXISTS 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: track
+--
+DROP TABLE IF EXISTS track;
+CREATE TABLE track (
+ trackid INTEGER PRIMARY KEY NOT NULL,
+ cd integer NOT NULL,
+ position integer NOT NULL,
+ title varchar(100) NOT NULL,
+ last_updated_on datetime NULL
+);
+
+--
+-- Table: tags
+--
+DROP TABLE IF EXISTS tags;
+CREATE TABLE tags (
+ tagid INTEGER PRIMARY KEY NOT NULL,
+ cd integer NOT NULL,
+ tag varchar(100) NOT NULL
+);
+
+--
+-- Table: producer
+--
+DROP TABLE IF EXISTS producer;
+CREATE TABLE producer (
+ producerid INTEGER PRIMARY KEY NOT NULL,
+ name varchar(100) NOT NULL
+);
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/sqlite.sql
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/sqlite.sql (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/sqlite.sql 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,63 @@
+--
+-- Created by SQL::Translator::Producer::SQLite
+-- Created on Tue Aug 8 01:53:20 2006
+--
+BEGIN TRANSACTION;
+
+--
+-- Table: cd_to_producer
+--
+CREATE TABLE cd_to_producer (
+ cd integer NOT NULL,
+ producer integer NOT NULL,
+ PRIMARY KEY (cd, producer)
+);
+
+--
+-- 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: track
+--
+CREATE TABLE track (
+ trackid INTEGER PRIMARY KEY NOT NULL,
+ cd integer NOT NULL,
+ position integer NOT NULL,
+ title varchar(100) NOT NULL,
+ last_updated_on datetime NULL
+);
+
+--
+-- Table: tags
+--
+CREATE TABLE tags (
+ tagid INTEGER PRIMARY KEY NOT NULL,
+ cd integer NOT NULL,
+ tag varchar(100) NOT NULL
+);
+
+--
+-- Table: producer
+--
+CREATE TABLE producer (
+ producerid INTEGER PRIMARY KEY NOT NULL,
+ name varchar(100) NOT NULL
+);
+
+COMMIT;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/lib/sqlite_different.sql
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/lib/sqlite_different.sql (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/lib/sqlite_different.sql 2008-03-05 14:56:16 UTC (rev 4133)
@@ -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;
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/date.json
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/date.json (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/date.json 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,13 @@
+{
+ might_have: {
+ fetch: 0
+ },
+ has_many: {
+ fetch: 0
+ },
+ sets: [{
+ class: 'Track',
+ ids: ['9']
+ }],
+ datetime_relative : "2007-10-30 00:00:00"
+}
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/fetch.json
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/fetch.json (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/fetch.json 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,23 @@
+{
+ might_have: {
+ fetch: 0
+ },
+ has_many: {
+ fetch: 0
+ },
+ sets: [{
+ class: 'Artist',
+ ids: ['1'],
+ fetch: [{
+ rel: cds,
+ quantity: all
+ }]
+ }, {
+ class: 'Artist',
+ ids: ['2'],
+ fetch: [{
+ rel: cds,
+ cond: { year: {'>': 2002} }
+ }]
+ }]
+}
\ No newline at end of file
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/includes.json
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/includes.json (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/includes.json 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,15 @@
+{
+ might_have: {
+ fetch: 0
+ },
+ has_many: {
+ fetch: 0
+ },
+ sets: [{
+ class: 'Producer',
+ quantity: 1
+ }],
+ includes: [{
+ file: 'simple.json'
+ }]
+}
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/quantity.json
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/quantity.json (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/quantity.json 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,12 @@
+{
+ might_have: {
+ fetch: 0
+ },
+ has_many: {
+ fetch: 0
+ },
+ sets: [{
+ class: 'CD',
+ quantity: 3
+ }]
+}
\ No newline at end of file
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/rules.json
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/rules.json (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/rules.json 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,29 @@
+{
+ might_have: {
+ fetch: 0
+ },
+ has_many: {
+ fetch: 0
+ },
+ sets: [{
+ class: 'CD',
+ ids: ['5']
+ }, {
+ class: 'Artist',
+ ids: ['1'],
+ fetch: [{
+ rel: cds,
+ quantity: all
+ }]
+ }],
+ rules: {
+ 'CD': {
+ cond: [{ 'tags.tag': 'Cheesy' }],
+ join: ['tags'],
+ fetch: [{
+ rel: tracks,
+ cond: { position: 2 }
+ }]
+ }
+ }
+}
\ No newline at end of file
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/sample.json
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/sample.json (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/sample.json 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,41 @@
+{
+ might_have: {
+ fetch: 0
+ },
+ has_many: {
+ fetch: 0
+ },
+ sets: [{
+ class: 'User',
+ cond: { photo_count: { '<': 5 } },
+ quantity: 3,
+ datetime_relative: today,
+ fetch: [{
+ rel: comments,
+ cond: { comments: { '!=': 'faks' }},
+ quantity: 2
+ }]
+ }, {
+ class: 'User',
+ cond: { photo_count: { '>=': 5 } },
+ quantity: 3
+ }, {
+ class: 'Video',
+ quantity: 3
+ }, {
+ class: 'FeaturedVideo',
+ quantity: 3
+ }],
+ rules: {
+ 'User': {
+ cond: { video_count: { '>=': 5 } }
+ },
+ 'Video': {
+ fetch: [{
+ rel: user_videos,
+ cond: { me.fk_user_id: '\= video.fk_owner_id' },
+ join: 'video'
+ }]
+ }
+ }
+}
\ No newline at end of file
Added: DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/simple.json
===================================================================
--- DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/simple.json (rev 0)
+++ DBIx-Class-Fixtures/1.000/branches/includes/t/var/configs/simple.json 2008-03-05 14:56:16 UTC (rev 4133)
@@ -0,0 +1,12 @@
+{
+ might_have: {
+ fetch: 0
+ },
+ has_many: {
+ fetch: 0
+ },
+ sets: [{
+ class: 'Artist',
+ quantity: 1
+ }]
+}
\ No newline at end of file
More information about the Bast-commits
mailing list