[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