Test -dt_$foo
Arthur Axel 'fREW' Schmidt [Thu, 3 Feb 2011 21:16:29 +0000 (15:16 -0600)]
lib/DBIx/Class/SQLMaker/DateOps.pm
t/sqlmaker/op_dt.t

index 1930b9c..40e7514 100644 (file)
@@ -93,7 +93,7 @@ sub _where_op_GET_DATETIME {
   return $self->_datetime_sql($part, $sql), @bind;
 }
 
-for my $part (qw(month day year hour minute second)) {
+for my $part (qw(month year hour minute second)) {
    no strict 'refs';
    my $name = '_where_op_GET_DATETIME_' . uc($part);
    *{$name} = subname "DBIx::Class::SQLMaker::DateOps::$name", sub {
@@ -106,6 +106,15 @@ for my $part (qw(month day year hour minute second)) {
    }
 }
 
+sub _where_op_GET_DATETIME_DAY {
+  my $self = shift;
+  my ($op, $rhs) = splice @_, -2;
+
+  my $lhs = shift;
+
+  return $self->_where_op_GET_DATETIME($op, $lhs, [day_of_month => $rhs])
+}
+
 sub _where_op_DATETIME_NOW {
   my ($self) = @_;
 
index 8ed1038..2bf4615 100644 (file)
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 
 use Test::More;
-use Test::Fatal;
+use Test::Exception;
 
 use lib qw(t/lib);
 use DBIC::SqlMakerTest;
@@ -12,7 +12,9 @@ use_ok('DBICTest');
 
 my $schema = DBICTest->init_schema();
 
-my $sql_maker = $schema->storage->sql_maker;
+my %sql_maker = (
+   sqlite => $schema->storage->sql_maker,
+);
 
 my $date = DateTime->new(
    year => 2010,
@@ -25,78 +27,209 @@ my $date = DateTime->new(
 
 my $date2 = $date->clone->set_day(16);
 
-use Devel::Dwarn;
+my @tests = (
+  {
+    func   => 'select',
+    args   => ['artist', '*', { 'artist.when_began' => { -dt => $date } }],
+    sqlite => {
+       stmt   => 'SELECT * FROM artist WHERE artist.when_began = ?',
+       bind   => [[ 'artist.when_began', '2010-12-14 12:12:12' ]],
+    },
+    msg => '-dt_now works',
+  },
+  {
+    func   => 'update',
+    args   => ['artist',
+      { 'artist.when_began' => { -dt => $date } },
+      { 'artist.when_ended' => { '<' => { -dt => $date2 } } }
+    ],
+    sqlite => {
+       stmt   => 'UPDATE artist SET artist.when_began = ?  WHERE artist.when_ended < ?  ',
+       bind   => [
+         [ 'artist.when_began', '2010-12-14 12:12:12' ],
+         [ 'artist.when_ended', '2010-12-16 12:12:12' ],
+       ],
+    },
+    msg => '-dt_now works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_year => { -ident => 'artist.when_began' } ] ]],
+    sqlite => {
+      stmt   => "SELECT STRFTIME('%Y', artist.when_began) FROM artist",
+       bind   => [],
+    },
+    msg    => '-dt_year works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_month => { -ident => 'artist.when_began' } ] ]],
+    sqlite => {
+      stmt   => "SELECT STRFTIME('%m', artist.when_began) FROM artist",
+      bind   => [],
+    },
+    msg    => '-dt_month works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_day => { -ident => 'artist.when_began' } ] ]],
+    sqlite => {
+      stmt   => "SELECT STRFTIME('%d', artist.when_began) FROM artist",
+      bind   => [],
+    },
+    msg    => '-dt_day works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_hour => { -ident => 'artist.when_began' } ] ]],
+    sqlite => {
+      stmt   => "SELECT STRFTIME('%H', artist.when_began) FROM artist",
+      bind   => [],
+    },
+    msg    => '-dt_hour works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_minute => { -ident => 'artist.when_began' } ] ]],
+    sqlite => {
+      stmt   => "SELECT STRFTIME('%M', artist.when_began) FROM artist",
+      bind   => [],
+    },
+    msg    => '-dt_minute works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_second => { -ident => 'artist.when_began' } ] ]],
+    sqlite => {
+      stmt   => "SELECT STRFTIME('%s', artist.when_began) FROM artist",
+      bind   => [],
+    },
+    msg    => '-dt_second works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_diff => [second => { -ident => 'artist.when_ended' }, \'artist.when_began' ] ] ]],
+    sqlite => {
+      stmt   => "SELECT (STRFTIME('%s', artist.when_ended) - STRFTIME('%s', artist.when_began)) FROM artist",
+      bind   => [],
+    },
+    msg    => '-dt_diff (second) works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_diff => [day => { -ident => 'artist.when_ended' }, \'artist.when_began' ] ] ]],
+    sqlite => {
+      stmt   => "SELECT (JULIANDAY(artist.when_ended) - JULIANDAY(artist.when_began)) FROM artist",
+      bind   => [],
+    },
+    msg    => '-dt_diff (day) works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_add => [year => 3, { -ident => 'artist.when_ended' } ] ] ]],
+    sqlite => {
+      stmt   => "SELECT (datetime(artist.when_ended, ? || ' years')) FROM artist",
+      bind   => [[ '', 3 ]],
+    },
+    msg    => '-dt_add (year) works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_add => [month => 3, { -ident => 'artist.when_ended' } ] ] ]],
+    sqlite => {
+      stmt   => "SELECT (datetime(artist.when_ended, ? || ' months')) FROM artist",
+      bind   => [[ '', 3 ]],
+    },
+    msg    => '-dt_add (month) works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_add => [day => 3, { -ident => 'artist.when_ended' } ] ] ]],
+    sqlite => {
+      stmt   => "SELECT (datetime(artist.when_ended, ? || ' days')) FROM artist",
+      bind   => [[ '', 3 ]],
+    },
+    msg    => '-dt_add (day) works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_add => [hour => 3, { -ident => 'artist.when_ended' } ] ] ]],
+    sqlite => {
+      stmt   => "SELECT (datetime(artist.when_ended, ? || ' hours')) FROM artist",
+      bind   => [[ '', 3 ]],
+    },
+    msg    => '-dt_add (hour) works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_add => [minute => 3, { -ident => 'artist.when_ended' } ] ] ]],
+    sqlite => {
+      stmt   => "SELECT (datetime(artist.when_ended, ? || ' minutes')) FROM artist",
+      bind   => [[ '', 3 ]],
+    },
+    msg    => '-dt_add (minute) works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_add => [second => 3, { -ident => 'artist.when_ended' } ] ] ]],
+    sqlite => {
+      stmt   => "SELECT (datetime(artist.when_ended, ? || ' seconds')) FROM artist",
+      bind   => [[ '', 3 ]],
+    },
+    msg    => '-dt_add (second) works',
+  },
+  {
+    func   => 'select',
+    args   => ['artist', [ [ -dt_diff => [year => \'artist.when_started', { -ident => 'artist.when_ended' } ] ] ]],
+    sqlite => {
+      exception_like => qr/date diff not supported for part "year" with database "SQLite"/,
+    },
+  },
+);
 
-Dwarn [$schema->resultset('Artist')->search(undef, {
-   select => [
-      [ -dt_diff => [second => { -dt => $date }, { -dt => $date2 }] ],
-      [ -dt_diff => [day    => { -dt => $date }, { -dt => $date2 }] ],
-      [ -dt_add => [minute => 3, { -dt => $date }] ],
-      [ -dt_add => [minute => 3, { -dt_add => [ hour => 1, { -dt => $date } ] } ] ],
-      [ -dt_now => [] ],
-      [ -dt_now => ['system'] ],
-   ],
-   as => [qw(seconds days date date2 now now_local)],
-   result_class => 'DBIx::Class::ResultClass::HashRefInflator',
-   rows => 1,
-})->all];
+for my $t (@tests) {
+  local $"=', ';
 
-is_same_sql_bind (
-  \[ $sql_maker->select ('artist', '*', { 'artist.when_began' => { -dt => $date } } ) ],
-  "SELECT *
-    FROM artist
-    WHERE artist.when_began = ?
-  ",
-  [['artist.when_began', '2010-12-14 12:12:12']],
-  '-dt works'
-);
+  DB_TEST:
+  for my $db (keys %sql_maker) {
+     my $maker = $sql_maker{$db};
 
-is_same_sql_bind (
-  \[ $sql_maker->update ('artist',
-    { 'artist.when_began' => { -dt => $date } },
-    { 'artist.when_ended' => { '<' => { -dt => $date2 } } },
-  ) ],
-  "UPDATE artist
-    SET artist.when_began = ?
-    WHERE artist.when_ended < ?
-  ",
-  [
-   ['artist.when_began', '2010-12-14 12:12:12'],
-   ['artist.when_ended', '2010-12-16 12:12:12'],
-  ],
-  '-dt works'
-);
+     my $db_test = $t->{$db};
+     next DB_TEST unless $db_test;
 
-is_same_sql_bind (
-  \[ $sql_maker->select ('artist', '*', {
-    -and => [
-       { -op => [ '=', 12, { -dt_month => { -ident => 'artist.when_began' } } ] },
-       { -op => [ '=', 2010, { -dt_get => [year => \'artist.when_began'] } ] },
-       { -op => [ '=', 14, { -dt_get => [day_of_month => \'artist.when_began'] } ] },
-       { -op => [ '=', 100, { -dt_diff => [second => { -ident => 'artist.when_began' }, \'artist.when_ended'] } ] },
-       { -op => [ '=', 10, { -dt_diff => [day => { -ident => 'artist.when_played_last' }, \'artist.when_ended'] } ] },
-    ]
-  } ) ],
-  "SELECT *
-     FROM artist
-     WHERE ( (
-       ( ? = STRFTIME('%m', artist.when_began) ) AND
-       ( ? = STRFTIME('%Y', artist.when_began) ) AND
-       ( ? = STRFTIME('%d', artist.when_began) ) AND
-       ( ? = ( STRFTIME('%s', artist.when_began) - STRFTIME('%s', artist.when_ended))) AND
-       ( ? = ( JULIANDAY(artist.when_played_last) - JULIANDAY(artist.when_ended)))
-     ) )
-  ",
-  [
-   ['', 12],
-   ['', 2010],
-   ['', 14],
-   ['', 100],
-   ['', 10],
-  ],
-  '-dt_month, -dt_get, and -dt_diff work'
-);
+     my($stmt, @bind);
+
+     my $cref = sub {
+       my $op = $t->{func};
+       ($stmt, @bind) = $maker->$op (@ { $t->{args} } );
+     };
 
-like exception { $sql_maker->select('foo', '*', { -dt_diff => [year => \'artist.lololol', \'artist.fail'] }) }, qr/date diff not supported for part "year" with database "SQLite"/, 'SQLite does not support year diff';
+     if ($db_test->{exception_like}) {
+       throws_ok(
+         sub { $cref->() },
+         $db_test->{exception_like},
+         "throws the expected exception ($db_test->{exception_like})",
+       );
+     } else {
+       if ($db_test->{warning_like}) {
+         warning_like(
+           sub { $cref->() },
+           $db_test->{warning_like},
+           "issues the expected warning ($db_test->{warning_like})"
+         );
+       }
+       else {
+         $cref->();
+       }
+       is_same_sql_bind(
+         $stmt,
+         \@bind,
+         $db_test->{stmt},
+         $db_test->{bind},
+         ($t->{msg} ? $t->{msg} : ())
+       );
+     }
+  }
+}
 
 done_testing;