added test for relative date support
Luke Saunders [Mon, 4 Feb 2008 14:48:11 +0000 (14:48 +0000)]
lib/DBIx/Class/Fixtures.pm
t/06-dump-date.t [new file with mode: 0644]
t/lib/DBICTest.pm
t/lib/mysql.sql [new file with mode: 0644]
t/var/configs/date.json [new file with mode: 0644]

index 044c537..87e13f3 100644 (file)
@@ -18,6 +18,11 @@ use Data::Dumper;
 
 use base qw(Class::Accessor);
 
+our %db_to_parser = (
+  'mysql'      => 'DateTime::Format::MySQL',
+  'pg'         => 'DateTime::Format::Pg',
+);
+
 __PACKAGE__->mk_accessors(qw(config_dir _inherited_attributes debug schema_class ));
 
 =head1 VERSION
@@ -221,24 +226,31 @@ sub dump_object {
     $self->msg('-- dumping ' . $file->stringify, 2);
     my %ds = $object->get_columns;
 
+    my $driver = $object->result_source->schema->storage->dbh->{Driver}->{Name};
+    my $formatter= $db_to_parser{$driver};
+    eval "require $formatter" if ($formatter);
+
     # mess with dates if specified
-    if ($set->{datetime_relative}) {     
-      my $dt;
-      if ($set->{datetime_relative} eq 'today') {
-        $dt = DateTime->today;
-      } else {
-        require DateTime::Format::MySQL;
-        $dt = DateTime::Format::MySQL->parse_datetime($set->{datetime_relative});
-      }
+    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);
+        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';
+          next unless $value
+            && $col_info->{_inflate_info}
+              && uc($col_info->{data_type}) eq 'DATETIME';
 
-        $ds{$col} = $object->get_inflated_column($col)->subtract_datetime($dt);
+          $ds{$col} = $object->get_inflated_column($col)->subtract_datetime($dt);
+        }
+      } else {
+        warn "datetime_relative not supported for $driver at the moment";
       }
     }
 
@@ -402,20 +414,25 @@ sub populate {
   dircopy(dir($fixture_dir, $schema->source($_)->from), dir($tmp_fixture_dir, $schema->source($_)->from)) for $schema->sources;
 
   eval { $schema->storage->dbh->do('SET foreign_key_checks=0') };
+
   my $fixup_visitor;
-  my %callbacks;
-  if ($params->{datetime_relative_to}) {
-    $callbacks{'DateTime::Duration'} = sub {
-      $params->{datetime_relative_to}->clone->add_duration($_);
-    };
-  } else {
-    $callbacks{'DateTime::Duration'} = sub {
-      DateTime->today->add_duration($_)
-    };
+  my $driver = $schema->storage->dbh->{Driver}->{Name};
+  my $formatter= $db_to_parser{$driver};  
+  eval "require $formatter" if ($formatter);
+  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);
   }
-  $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);
@@ -428,7 +445,7 @@ sub populate {
       my $HASH1;
       eval($contents);
       $HASH1 = $fixup_visitor->visit($HASH1) if $fixup_visitor;
-      $rs->find_or_create($HASH1);
+      $rs->create($HASH1);
     }
   }
 
diff --git a/t/06-dump-date.t b/t/06-dump-date.t
new file mode 100644 (file)
index 0000000..888b2e2
--- /dev/null
@@ -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 mysql db 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');
index c3059ce..2e1ddc4 100755 (executable)
@@ -45,15 +45,16 @@ default, unless the no_deploy or no_populate flags are set.
 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 = $ENV{"FIXTURETEST_DSN"} || "dbi:SQLite:${db_file}";
-    my $dbuser = $ENV{"FIXTURETEST_DBUSER"} || '';
-    my $dbpass = $ENV{"FIXTURETEST_DBPASS"} || '';
+    my $dsn = $args{"dsn"} || "dbi:SQLite:${db_file}";
+    my $dbuser = $args{"user"} || '';
+    my $dbpass = $args{"pass"} || '';
 
     my $schema;
 
@@ -67,7 +68,7 @@ sub init_schema {
       $schema = DBICTest::Schema->compose_namespace('DBICTest')
                                 ->connect(@connect_info);
     }
-    $schema->storage->on_connect_do(['PRAGMA synchronous = OFF']);
+
     if ( !$args{no_deploy} ) {
         __PACKAGE__->deploy_schema( $schema );
         __PACKAGE__->populate_schema( $schema ) if( !$args{no_populate} );
@@ -75,6 +76,14 @@ sub init_schema {
     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 );
@@ -85,7 +94,9 @@ sub deploy_schema {
     my $self = shift;
     my $schema = shift;
 
-    open IN, "t/lib/sqlite.sql";
+
+    my $file = $self->get_ddl_file($schema);
+    open IN, $file;
     my $sql;
     { local $/ = undef; $sql = <IN>; }
     close IN;
@@ -167,13 +178,13 @@ sub populate_schema {
     ]);
 
     $schema->populate('Track', [
-        [ qw/trackid cd  position title/ ],
+        [ 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"],
+        [ 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"],
diff --git a/t/lib/mysql.sql b/t/lib/mysql.sql
new file mode 100644 (file)
index 0000000..ca1b034
--- /dev/null
@@ -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
+);
diff --git a/t/var/configs/date.json b/t/var/configs/date.json
new file mode 100644 (file)
index 0000000..2fc932c
--- /dev/null
@@ -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"  
+}