The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 016
MANIFEST 119
META.json 46
META.yml 2224
Makefile.PL 510
README 11
cpanfile 13
dist.ini 14
inc/Dist/Zilla/Plugin/DBICSgen.pm 33
lib/DBIx/Class/Helper/IgnoreWantarray.pm 52
lib/DBIx/Class/Helper/JoinTable.pm 52
lib/DBIx/Class/Helper/Random.pm 52
lib/DBIx/Class/Helper/ResultSet/AutoRemoveColumns.pm 52
lib/DBIx/Class/Helper/ResultSet/CorrelateRelationship.pm 52
lib/DBIx/Class/Helper/ResultSet/DateMethods1/Announcement.pod 0158
lib/DBIx/Class/Helper/ResultSet/DateMethods1.pm 0989
lib/DBIx/Class/Helper/ResultSet/IgnoreWantarray.pm 52
lib/DBIx/Class/Helper/ResultSet/Me.pm 52
lib/DBIx/Class/Helper/ResultSet/NoColumns.pm 52
lib/DBIx/Class/Helper/ResultSet/Random.pm 52
lib/DBIx/Class/Helper/ResultSet/RemoveColumns.pm 63
lib/DBIx/Class/Helper/ResultSet/ResultClassDWIM.pm 52
lib/DBIx/Class/Helper/ResultSet/SearchOr.pm 52
lib/DBIx/Class/Helper/ResultSet/SetOperations.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/AddColumns.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/Columns.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/Distinct.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/GroupBy.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/HRI.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/HasRows.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/Limit.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/LimitedPage.pm 056
lib/DBIx/Class/Helper/ResultSet/Shortcut/OrderBy.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/OrderByMagic.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/Page.pm 035
lib/DBIx/Class/Helper/ResultSet/Shortcut/Prefetch.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut/Rows.pm 52
lib/DBIx/Class/Helper/ResultSet/Shortcut.pm 525
lib/DBIx/Class/Helper/ResultSet/Union.pm 52
lib/DBIx/Class/Helper/ResultSet/VirtualView.pm 52
lib/DBIx/Class/Helper/ResultSet.pm 52
lib/DBIx/Class/Helper/Row/CleanResultSet.pm 52
lib/DBIx/Class/Helper/Row/JoinTable.pm 52
lib/DBIx/Class/Helper/Row/NumifyGet.pm 52
lib/DBIx/Class/Helper/Row/OnColumnChange.pm 52
lib/DBIx/Class/Helper/Row/ProxyResultSetMethod.pm 52
lib/DBIx/Class/Helper/Row/ProxyResultSetUpdate.pm 52
lib/DBIx/Class/Helper/Row/RelationshipDWIM.pm 52
lib/DBIx/Class/Helper/Row/SelfResultSet.pm 52
lib/DBIx/Class/Helper/Row/StorageValues.pm 52
lib/DBIx/Class/Helper/Row/SubClass.pm 52
lib/DBIx/Class/Helper/Row/ToJSON.pm 52
lib/DBIx/Class/Helper/Schema/DateTime.pm 52
lib/DBIx/Class/Helper/Schema/GenerateSource.pm 52
lib/DBIx/Class/Helper/Schema/LintContents.pm 54
lib/DBIx/Class/Helper/Schema/QuoteNames.pm 52
lib/DBIx/Class/Helper/SubClass.pm 52
lib/DBIx/Class/Helper/VirtualView.pm 52
lib/DBIx/Class/Helpers/Util.pm 52
lib/DBIx/Class/Helpers.pm 52
t/lib/A/ResultSet/DateMethods1.pm 0492
t/lib/ParentSchema/Result/Bar.pm 01
t/lib/ParentSchema/Result/Foo.pm 01
t/lib/TestSchema/Result/Bloaty.pm 32
t/lib/TestSchema/Result/Gnarly.pm 42
t/lib/TestSchema/Result/HasDateOps.pm 014
t/lib/TestSchema/Result/Station.pm 42
t/lib/TestSchema/ResultSet/HasDateOps.pm 011
t/lib/TestSchema-0.001-MySQL.sql 020
t/lib/TestSchema-0.001-Oracle.sql 019
t/lib/TestSchema-0.001-PostgreSQL.sql 015
t/lib/TestSchema-0.001-SQLServer.sql 015
t/lib/TestSchema-0.001-SQLite.sql 097
t/lib/TestSchema.pm 721
t/lib/ddl.sql 920
t/release-pod-syntax.t 32
t/resultset/date-methods-1/mssql.t 078
t/resultset/date-methods-1/mysql.t 077
t/resultset/date-methods-1/oracle.t 050
t/resultset/date-methods-1/pg.t 084
t/resultset/date-methods-1/sqlite.t 062
t/resultset/shortcut/limited-page.t 037
t/row/jointable.t 31
t/schema/lint-contents.t 11
84 files changed (This is a version diff) 3912548
@@ -1,5 +1,21 @@
 Revision history for DBIx-Class-Helpers
 
+2.021001  2014-04-06 11:43:36-05:00 America/Chicago
+ - Fix ::RemoveColumns to work with a specified `columns` (Anthony DeRobertis)
+   (Fixes GH#27) Also fixes RT#91977/GH#24)
+
+2.021000  2014-04-01 20:12:40-05:00 America/Chicago
+ - Create Shortcut::Page and Shortcut::LimitedPage ResultSet helpers (wreis)
+
+2.020001  2014-03-05 10:33:46CST-0600 America/Chicago
+ - Make ::DateMethods1 tests paralellizable (thanks Alexander Hartmaier!)
+ - fix ::Helper::ResultSet::DateMethods1 for Oracle (thanks Alexander Hartmaier!)
+ - fix ABSTRACT on ::Helper::ResultSet::DateMethods1
+
+2.020000  2014-03-04 08:31:39-06:00 America/Chicago
+ - Add ::Helper::ResultSet::DateMethods1
+ - Add abstract to ::Schema::LintContents
+
 2.019004  2014-02-14 07:53:19 America/Chicago
  - Make IgnoreWantarray's search die in void context
 
@@ -1,3 +1,4 @@
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.013.
 CONTRIBUTING
 Changes
 LICENSE
@@ -15,6 +16,8 @@ lib/DBIx/Class/Helper/Random.pm
 lib/DBIx/Class/Helper/ResultSet.pm
 lib/DBIx/Class/Helper/ResultSet/AutoRemoveColumns.pm
 lib/DBIx/Class/Helper/ResultSet/CorrelateRelationship.pm
+lib/DBIx/Class/Helper/ResultSet/DateMethods1.pm
+lib/DBIx/Class/Helper/ResultSet/DateMethods1/Announcement.pod
 lib/DBIx/Class/Helper/ResultSet/IgnoreWantarray.pm
 lib/DBIx/Class/Helper/ResultSet/Me.pm
 lib/DBIx/Class/Helper/ResultSet/NoColumns.pm
@@ -31,8 +34,10 @@ lib/DBIx/Class/Helper/ResultSet/Shortcut/GroupBy.pm
 lib/DBIx/Class/Helper/ResultSet/Shortcut/HRI.pm
 lib/DBIx/Class/Helper/ResultSet/Shortcut/HasRows.pm
 lib/DBIx/Class/Helper/ResultSet/Shortcut/Limit.pm
+lib/DBIx/Class/Helper/ResultSet/Shortcut/LimitedPage.pm
 lib/DBIx/Class/Helper/ResultSet/Shortcut/OrderBy.pm
 lib/DBIx/Class/Helper/ResultSet/Shortcut/OrderByMagic.pm
+lib/DBIx/Class/Helper/ResultSet/Shortcut/Page.pm
 lib/DBIx/Class/Helper/ResultSet/Shortcut/Prefetch.pm
 lib/DBIx/Class/Helper/ResultSet/Shortcut/Rows.pm
 lib/DBIx/Class/Helper/ResultSet/Union.pm
@@ -57,6 +62,7 @@ lib/DBIx/Class/Helper/VirtualView.pm
 lib/DBIx/Class/Helpers.pm
 lib/DBIx/Class/Helpers/Util.pm
 t/bug-1.t
+t/lib/A/ResultSet/DateMethods1.pm
 t/lib/Lolbot.pm
 t/lib/ParentRS.pm
 t/lib/ParentSchema.pm
@@ -64,6 +70,11 @@ t/lib/ParentSchema/Result.pm
 t/lib/ParentSchema/Result/Bar.pm
 t/lib/ParentSchema/Result/Foo.pm
 t/lib/RS.pm
+t/lib/TestSchema-0.001-MySQL.sql
+t/lib/TestSchema-0.001-Oracle.sql
+t/lib/TestSchema-0.001-PostgreSQL.sql
+t/lib/TestSchema-0.001-SQLServer.sql
+t/lib/TestSchema-0.001-SQLite.sql
 t/lib/TestSchema.pm
 t/lib/TestSchema/Result/Bar.pm
 t/lib/TestSchema/Result/Bloaty.pm
@@ -71,15 +82,21 @@ t/lib/TestSchema/Result/Foo.pm
 t/lib/TestSchema/Result/Foo_Bar.pm
 t/lib/TestSchema/Result/Gnarly.pm
 t/lib/TestSchema/Result/Gnarly_Station.pm
+t/lib/TestSchema/Result/HasDateOps.pm
 t/lib/TestSchema/Result/Station.pm
 t/lib/TestSchema/ResultSet.pm
 t/lib/TestSchema/ResultSet/Bloaty.pm
 t/lib/TestSchema/ResultSet/Foo.pm
 t/lib/TestSchema/ResultSet/Gnarly.pm
+t/lib/TestSchema/ResultSet/HasDateOps.pm
 t/lib/TestSchema/ResultSet/Station.pm
-t/lib/ddl.sql
 t/release-pod-syntax.t
 t/resultset/correlate-relationship.t
+t/resultset/date-methods-1/mssql.t
+t/resultset/date-methods-1/mysql.t
+t/resultset/date-methods-1/oracle.t
+t/resultset/date-methods-1/pg.t
+t/resultset/date-methods-1/sqlite.t
 t/resultset/ignore-wantarray.t
 t/resultset/me.t
 t/resultset/no-columns.t
@@ -95,6 +112,7 @@ t/resultset/shortcut/group-by.t
 t/resultset/shortcut/has-rows.t
 t/resultset/shortcut/hri.t
 t/resultset/shortcut/limit.t
+t/resultset/shortcut/limited-page.t
 t/resultset/shortcut/order-by-magic.t
 t/resultset/shortcut/order-by.t
 t/resultset/shortcut/prefetch.t
@@ -4,7 +4,7 @@
       "Arthur Axel \"fREW\" Schmidt <frioux+cpan@gmail.com>"
    ],
    "dynamic_config" : 0,
-   "generated_by" : "Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.120921",
+   "generated_by" : "Dist::Zilla version 5.013, CPAN::Meta::Converter version 2.133380",
    "license" : [
       "perl_5"
    ],
@@ -29,10 +29,11 @@
             "Carp::Clan" : "6.04",
             "DBIx::Class" : "0.0826",
             "DBIx::Class::Candy" : "0.001003",
-            "DBIx::Introspector" : "0",
+            "DBIx::Introspector" : "0.001002",
             "Lingua::EN::Inflect" : "0",
             "List::Util" : "0",
             "Module::Runtime" : "0",
+            "Safe::Isa" : "0",
             "String::CamelCase" : "0",
             "Sub::Exporter::Progressive" : "0.001006",
             "Try::Tiny" : "0",
@@ -46,7 +47,8 @@
             "DateTime::Format::SQLite" : "0",
             "Test::Deep" : "0",
             "Test::Exception" : "0",
-            "Test::More" : "0.94"
+            "Test::More" : "0.94",
+            "Test::Roo" : "0"
          }
       }
    },
@@ -62,6 +64,6 @@
          "web" : "https://github.com/frioux/DBIx-Class-Helpers"
       }
    },
-   "version" : "2.019004"
+   "version" : "2.021001"
 }
 
@@ -1,37 +1,39 @@
 ---
 abstract: 'Simplify the common case stuff for DBIx::Class.'
 author:
-  - "Arthur Axel \"fREW\" Schmidt <frioux+cpan@gmail.com>"
+  - 'Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>'
 build_requires:
-  DBD::SQLite: 0
-  DateTime::Format::SQLite: 0
-  Test::Deep: 0
-  Test::Exception: 0
-  Test::More: 0.94
+  DBD::SQLite: '0'
+  DateTime::Format::SQLite: '0'
+  Test::Deep: '0'
+  Test::Exception: '0'
+  Test::More: '0.94'
+  Test::Roo: '0'
 configure_requires:
-  ExtUtils::MakeMaker: 6.30
+  ExtUtils::MakeMaker: '6.30'
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.120921'
+generated_by: 'Dist::Zilla version 5.013, CPAN::Meta::Converter version 2.133380'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
-  version: 1.4
+  version: '1.4'
 name: DBIx-Class-Helpers
 requires:
-  Carp::Clan: 6.04
-  DBIx::Class: 0.0826
-  DBIx::Class::Candy: 0.001003
-  DBIx::Introspector: 0
-  Lingua::EN::Inflect: 0
-  List::Util: 0
-  Module::Runtime: 0
-  String::CamelCase: 0
-  Sub::Exporter::Progressive: 0.001006
-  Try::Tiny: 0
-  namespace::clean: 0.23
-  parent: 0
+  Carp::Clan: '6.04'
+  DBIx::Class: '0.0826'
+  DBIx::Class::Candy: '0.001003'
+  DBIx::Introspector: '0.001002'
+  Lingua::EN::Inflect: '0'
+  List::Util: '0'
+  Module::Runtime: '0'
+  Safe::Isa: '0'
+  String::CamelCase: '0'
+  Sub::Exporter::Progressive: '0.001006'
+  Try::Tiny: '0'
+  namespace::clean: '0.23'
+  parent: '0'
 resources:
   bugtracker: https://github.com/frioux/DBIx-Class-Helpers/issues
   homepage: https://github.com/frioux/DBIx-Class-Helpers
   repository: https://github.com/frioux/DBIx-Class-Helpers.git
-version: 2.019004
+version: '2.021001'
@@ -1,4 +1,5 @@
 
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.013.
 use strict;
 use warnings;
 
@@ -23,10 +24,11 @@ my %WriteMakefileArgs = (
     "Carp::Clan" => "6.04",
     "DBIx::Class" => "0.0826",
     "DBIx::Class::Candy" => "0.001003",
-    "DBIx::Introspector" => 0,
+    "DBIx::Introspector" => "0.001002",
     "Lingua::EN::Inflect" => 0,
     "List::Util" => 0,
     "Module::Runtime" => 0,
+    "Safe::Isa" => 0,
     "String::CamelCase" => 0,
     "Sub::Exporter::Progressive" => "0.001006",
     "Try::Tiny" => 0,
@@ -38,11 +40,12 @@ my %WriteMakefileArgs = (
     "DateTime::Format::SQLite" => 0,
     "Test::Deep" => 0,
     "Test::Exception" => 0,
-    "Test::More" => "0.94"
+    "Test::More" => "0.94",
+    "Test::Roo" => 0
   },
-  "VERSION" => "2.019004",
+  "VERSION" => "2.021001",
   "test" => {
-    "TESTS" => "t/*.t t/resultset/*.t t/resultset/shortcut/*.t t/row/*.t t/schema/*.t"
+    "TESTS" => "t/*.t t/resultset/*.t t/resultset/date-methods-1/*.t t/resultset/shortcut/*.t t/row/*.t t/schema/*.t"
   }
 );
 
@@ -52,16 +55,18 @@ my %FallbackPrereqs = (
   "DBD::SQLite" => 0,
   "DBIx::Class" => "0.0826",
   "DBIx::Class::Candy" => "0.001003",
-  "DBIx::Introspector" => 0,
+  "DBIx::Introspector" => "0.001002",
   "DateTime::Format::SQLite" => 0,
   "Lingua::EN::Inflect" => 0,
   "List::Util" => 0,
   "Module::Runtime" => 0,
+  "Safe::Isa" => 0,
   "String::CamelCase" => 0,
   "Sub::Exporter::Progressive" => "0.001006",
   "Test::Deep" => 0,
   "Test::Exception" => 0,
   "Test::More" => "0.94",
+  "Test::Roo" => 0,
   "Try::Tiny" => 0,
   "namespace::clean" => "0.23",
   "parent" => 0
@@ -2,7 +2,7 @@ NAME
     DBIx::Class::Helpers - Simplify the common case stuff for DBIx::Class.
 
 VERSION
-    version 2.019004
+    version 2.021001
 
 SYNOPSIS
      package MyApp::Schema::Result::Foo_Bar;
@@ -7,13 +7,15 @@ requires 'String::CamelCase' => 0;
 requires 'namespace::clean' => 0.23;
 requires 'List::Util' => 0;
 requires 'DBIx::Class::Candy' => 0.001003;
-requires 'DBIx::Introspector';
+requires 'DBIx::Introspector' => 0.001002;
 requires 'Module::Runtime';
 requires 'Try::Tiny';
+requires 'Safe::Isa';
 
 on test => sub {
    requires 'Test::More' => 0.94;
    requires 'Test::Deep' => 0;
+   requires 'Test::Roo' => 0;
    requires 'DBD::SQLite' => 0;
    requires 'Test::Exception' => 0;
    requires 'DateTime::Format::SQLite' => 0;
@@ -2,7 +2,7 @@ name             = DBIx-Class-Helpers
 author           = Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
 license          = Perl_5
 copyright_holder = Arthur Axel "fREW" Schmidt
-version          = 2.019004
+version          = 2.021001
 
 [NextRelease]
 [@Git]
@@ -16,6 +16,9 @@ issues = 1
 [ReadmeFromPod]
 [PodSyntaxTests]
 
+[PruneFiles]
+match = ^maint/
+
 [=inc::Dist::Zilla::Plugin::DBICSgen]
 schema = TestSchema
 lib = lib
@@ -25,7 +25,7 @@ has lib => (
 
 sub mvp_multivalue_args { qw(lib) }
 
-unlink 't/lib/ddl.sql';
+unlink $_ for glob 't/lib/*.sql';
 
 sub gather_files {
    my $self = shift;
@@ -37,8 +37,8 @@ sub gather_files {
 
    $schema->generate_ddl;
 
-   my $file = Dist::Zilla::File::OnDisk->new(name => $schema->ddl_filename);
-   $self->add_file($file);
+   $self->add_file( Dist::Zilla::File::OnDisk->new(name => $_))
+      for glob 't/lib/*.sql';
 }
 
 no Moose;
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::IgnoreWantarray;
-{
-  $DBIx::Class::Helper::IgnoreWantarray::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::IgnoreWantarray::VERSION = '2.021001';
 use parent 'DBIx::Class::Helper::ResultSet::IgnoreWantarray';
 
 use Carp::Clan;
@@ -25,7 +22,7 @@ DBIx::Class::Helper::IgnoreWantarray - (DEPRECATED) Get rid of search context is
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::JoinTable;
-{
-  $DBIx::Class::Helper::JoinTable::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::JoinTable::VERSION = '2.021001';
 use parent 'DBIx::Class::Helper::Row::JoinTable';
 
 use Carp::Clan;
@@ -25,7 +22,7 @@ DBIx::Class::Helper::JoinTable - (DEPRECATED) Easily set up join tables with DBI
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Random;
-{
-  $DBIx::Class::Helper::Random::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Random::VERSION = '2.021001';
 use parent 'DBIx::Class::Helper::ResultSet::Random';
 
 use Carp::Clan;
@@ -25,7 +22,7 @@ DBIx::Class::Helper::Random - (DEPRECATED) Get random rows from a ResultSet
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::AutoRemoveColumns;
-{
-  $DBIx::Class::Helper::ResultSet::AutoRemoveColumns::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::AutoRemoveColumns::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -70,7 +67,7 @@ DBIx::Class::Helper::ResultSet::AutoRemoveColumns - Automatically remove columns
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::CorrelateRelationship;
-{
-  $DBIx::Class::Helper::ResultSet::CorrelateRelationship::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::CorrelateRelationship::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -39,7 +36,7 @@ DBIx::Class::Helper::ResultSet::CorrelateRelationship - Easily correlate your Re
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -0,0 +1,158 @@
+# PODNAME: DBIx::Class::Helper::ResultSet::DateMethods1::Announce
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+DBIx::Class::Helper::ResultSet::DateMethods1::Announce
+
+=head1 VERSION
+
+version 2.021001
+
+=head1 NAME
+
+::DateMethods1 Announcement
+
+=head1 Content
+
+L<A little over three years ago|https://github.com/frioux/dbic-withdates/commit/5e6893d4cb873eca75118061c104bed9b891dee0>
+I got inspired while on vacation to Crested Butte, CO and started a branch
+in DBIC called merely, "date-ops."  The idea was to allow users to call
+various date functions, portably, directly in DBIC.  With some help from
+some people who use other databases, I got it working with SQL Server,
+SQLite, PostgreSQL, MySQL, and Oracle.
+
+Unfortunately after we finished it (
+L<about six months after I started|https://github.com/frioux/dbic-withdates/commit/fcb5b33a58426ee9d4b87fd84144d05d7a1cf9e9>
+) it merely languished.  There were some technical issues we never got
+around to ironing out, mostly because it wasn't clear to us what the
+cost of not taking care of them would be.
+
+Fast forward a few more months and I was working on a greenfield project
+at work.  I wanted to do some date math in the database, so far I did all
+of my development against SQLite but deployed to SQL Server, and it looked
+like the date ops were my solution.  I decided that given that I was the
+primary author of them, I could live with deploying them to production.
+I did exactly that and had pretty much no problems.  Well, no problems
+until I had to upgrade DBIC.  Every time I needed to upgrade DBIC I had
+to merge/rebase the branch.  It turned out to be much more work than I
+bargained for, and I ended up just never updating DBIC.
+
+At some point (
+L<just under a month ago|https://github.com/frioux/DBIx-Class-Helpers/commit/5fefda2e5dafb0b78e9ee5a687fb698899d8d2ff>
+) I decided that I
+needed to upgrade DBIC and that maintaining these date ops was no longer
+tenable.  Armed with three more years of experience than I had when I
+started I embarked on converting the date ops to date methods, that would
+work as Helpers.  In addition to not being core, so I could release at
+my own pace, I could also version the API, so if I end up making some
+critical mistakes or needing to break the API for some features in the
+future, I can merely release C<::DateMethods2>.  So without further ado:
+
+=head1 Announcing C<DBIx::Class::Helper::ResultSet::DateMethods1>
+
+Do you store dates in your database?  Do you ever want to manipulate them
+efficiently?  Well here's your solution!
+
+First, how do you search in a more comprehensible way?
+
+ $rs->dt_on_or_before(
+   { -ident => '.when_created' },
+   DateTime->now->subtract(days => 7),
+ );
+
+C<dt_on_or_before> (as well as C<dt_before>, C<dt_on_or_after>, or C<dt_after>)
+merely aliases C<< <= >>, C<< < >>, C<< >= >>, and C<< > >>, respectively.
+Instead of trying to think about the numerical meaning of a date on a timeline,
+just use these named methods.  In addition to the nicer name, they can take
+L<DateTime> object (which are automatically converted to UTC), and autoprepend
+L<DBIx::Class::ResultSet/current_source_alias> when passed an C<-ident> that
+starts with a C<.>.  You can pass any of a value, a column (via C<-ident>), a
+subquery, literal sql, or a C<DateTime> object to either parameter slots of
+these methods.
+
+Second, how do I really leverage this module to do stuff with dates in my
+database?
+
+Here's a query I originally wrote with date ops.  Basically it groups some
+columns by some "date parts" like year, month, day, etc.  You can use it to make
+nice reports of things like how many things have been done per month, or maybe
+find out if the system is more busy in the summer:
+
+ $rs->search(undef, {
+    columns => {
+       count => '*',
+       year  => $rs->dt_SQL_pluck({ -ident => '.start' }, 'year'),
+       month => $rs->dt_SQL_pluck({ -ident => '.start' }, 'month'),
+    },
+    group_by => [
+      $rs->dt_SQL_pluck({ -ident => '.start' }, 'year'),
+      $rs->dt_SQL_pluck({ -ident => '.start' }, 'month'),
+    ],
+ )->hri->all
+
+I use that exact query (though I give the user a UI for which dateparts
+to include) in my system, and it works on SQL Server and SQLite, and
+it's fast.  Awesome.
+
+Or how about a query to discover how many issues were resolved before the next
+full day after their creation?  Check it out:
+
+ # note that 'day', 1 should also work
+ $rs->dt_before(
+   { -ident => '.resolution' },
+   $rs->dt_SQL_add({ -ident => '.creation' }, 'hour', 24),
+ )->all
+
+Both of the above queries work on all of the supported datebases!
+
+Third, some little helpers to extend the above.
+
+On top of those things, I also throw in a couple other handy methods.  One,
+C<utc> converts a DateTime object to a string, in the UTC timezone.  Hopefully
+you shouldn't need it directly, but I've already ended up using it in places
+where our code forced me to return a simple hash to get merged into a search
+query, instead of letting me call methods on an RS.
+
+Another lagniappe is C<utc_now> which returns some literal sql that resolves to
+the current date and time in UTC on your database.  You can pass it in to search
+just like you would datetime.  So if your server and your database have in sync
+clocks, these would do the same thing:
+
+ $rs->dt_on_or_before(
+   { -ident => '.when_created' },
+   DateTime->now->subtract(days => 7),
+ );
+
+ $rs->dt_on_or_before(
+   { -ident => '.when_created' },
+   $rs->dt_SQL_add($rs->utc->now, 'day', -7),
+ );
+
+(NOTE: many people seem to hold suspect the idea that the clock is correct on a
+given server.  If you can't trust the clock of a server, you probably can't
+trust the server.  Use NTP.)
+
+And that's it.  I hope you can use and enjoy these helpers!
+
+=head1 SEE ALSO
+
+L<original blog post|http://blog.afoolishmanifesto.com/archives/1926>
+
+=head1 AUTHOR
+
+Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2014 by Arthur Axel "fREW" Schmidt.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -0,0 +1,989 @@
+package DBIx::Class::Helper::ResultSet::DateMethods1;
+$DBIx::Class::Helper::ResultSet::DateMethods1::VERSION = '2.021001';
+# ABSTRACT: Work with dates in your RDBMS nicely
+
+use strict;
+use warnings;
+
+use DBIx::Introspector;
+use Safe::Isa;
+
+sub _flatten_thing {
+   my ($self, $thing) = @_;
+
+   die 'you dummy' unless defined $thing;
+   my $ref = ref $thing;
+
+   return ('?', $thing) if !$ref;
+
+   if ($ref eq 'HASH' && exists $thing->{'-ident'}) {
+      my $thing = $thing->{'-ident'};
+      $thing = $self->current_source_alias . $thing if $thing =~ m/^\./;
+      return $self->result_source->storage->sql_maker->_quote($thing)
+   }
+
+   return ${$thing} if $ref eq 'SCALAR';
+
+   # FIXME: this should have the right bind type
+   return ('?', $self->utc($thing)) if $thing->$_isa('DateTime');
+   return @{${$thing}};
+}
+
+sub _introspector {
+   my $d = DBIx::Introspector->new(drivers => '2013-12.01');
+
+   $d->decorate_driver_unconnected(MSSQL => now_utc_sql => 'GETUTCDATE()');
+   $d->decorate_driver_unconnected(SQLite => now_utc_sql => q<DATETIME('now')>);
+   $d->decorate_driver_unconnected(mysql => now_utc_sql => 'UTC_TIMESTAMP()');
+   $d->decorate_driver_unconnected(Oracle => now_utc_sql => 'sys_extract_utc(SYSTIMESTAMP)');
+   $d->decorate_driver_unconnected(Pg => now_utc_sql => 'CURRENT_TIMESTAMP');
+   MSSQL: {
+      my %part_map = (
+         year         => 'year',
+         quarter      => 'quarter',
+         month        => 'month',
+         day_of_year  => 'dayofyear',
+         day_of_month => 'day',
+         week         => 'week',
+         day_of_week  => 'ISO_WEEK',
+         hour         => 'hour',
+         minute       => 'minute',
+         second       => 'second',
+         millisecond  => 'millisecond',
+         nanosecond   => 'nanosecond',
+         non_iso_day_of_week => 'weekday',
+         timezone_as_minutes => 'TZoffset',
+      );
+
+      $d->decorate_driver_unconnected(MSSQL => datepart_sql => sub {
+         sub {
+            my ($date_sql, $part) = @_;
+
+            my $sql = delete $date_sql->[0];
+
+            return [
+               "DATEPART($part_map{$part}, $sql)",
+               @$date_sql
+            ]
+         }
+      });
+
+
+      my %diff_part_map = %part_map;
+      $diff_part_map{day} = delete $diff_part_map{day_of_year};
+      delete $diff_part_map{day_of_month};
+      delete $diff_part_map{day_of_week};
+
+      $d->decorate_driver_unconnected(MSSQL => dateadd_sql => sub {
+         sub {
+            my ($date_sql, $unit, $amount_sql) = @_;
+
+            my ($d_sql, @d_args) = @{$date_sql};
+            my ($a_sql, @a_args) = @{$amount_sql};
+
+            return [
+               "DATEADD($diff_part_map{$unit}, CAST($a_sql AS int), $d_sql)",
+               @a_args, @d_args,
+            ];
+         }
+      });
+   }
+
+   SQLITE: {
+      my %part_map = (
+         month               => 'm',
+         day_of_month        => 'd',
+         year                => 'Y',
+         hour                => 'H',
+         day_of_year         => 'j',
+         minute              => 'M',
+         second              => 'S',
+         day_of_week         => 'w',
+         week                => 'W',
+         # maybe don't support these or prefix them with 'sqlite.'?
+         julian_day          => 'J',
+         seconds_since_epoch => 's',
+         fractional_seconds  => 'f',
+      );
+
+      $d->decorate_driver_unconnected(SQLite => datepart_sql => sub {
+         sub {
+            my ($date_sql, $part) = @_;
+
+            my $sql = delete $date_sql->[0];
+
+            return [
+               "STRFTIME('%$part_map{$part}', $sql)",
+               @$date_sql
+            ]
+         }
+      });
+
+
+      my %diff_part_map = (
+         day                 => 'days',
+         hour                => 'hours',
+         minute              => 'minutes',
+         second              => 'seconds',
+         month               => 'months',
+         year                => 'years',
+      );
+
+      $d->decorate_driver_unconnected(SQLite => dateadd_sql => sub {
+         sub {
+            my ($date_sql, $unit, $amount_sql) = @_;
+
+            my ($d_sql, @d_args) = @{$date_sql};
+            my ($a_sql, @a_args) = @{$amount_sql};
+
+            die "unknown part $unit" unless $diff_part_map{$unit};
+
+            return [
+               "DATETIME($d_sql, $a_sql || ?)",
+               @d_args, @a_args, " $diff_part_map{$unit}"
+            ];
+         }
+      });
+   }
+
+   PG: {
+      my %part_map = (
+         century             => 'century',
+         decade              => 'decade',
+         day_of_month        => 'day',
+         day_of_week         => 'dow',
+         day_of_year         => 'doy',
+         seconds_since_epoch => 'epoch',
+         hour                => 'hour',
+         iso_day_of_week     => 'isodow',
+         iso_year            => 'isoyear',
+         microsecond         => 'microseconds',
+         millenium           => 'millenium',
+         millisecond         => 'milliseconds',
+         minute              => 'minute',
+         month               => 'month',
+         quarter             => 'quarter',
+         second              => 'second',
+         timezone            => 'timezone',
+         timezone_hour       => 'timezone_hour',
+         timezone_minute     => 'timezone_minute',
+         week                => 'week',
+         year                => 'year',
+      );
+
+      my %diff_part_map = %part_map;
+      delete $diff_part_map{qw(
+         day_of_week day_of_year iso_day_of_week iso_year millenium quarter
+         seconds_since_epoch timezone timezone_hour timezone_minute
+      )};
+      $diff_part_map{day} = delete $diff_part_map{day_of_month};
+
+      $d->decorate_driver_unconnected(Pg => datepart_sql => sub {
+         sub {
+            my ($date_sql, $part) = @_;
+
+            my $sql = delete $date_sql->[0];
+
+            return [
+               "date_part(?, $sql)",
+               $part_map{$part}, @$date_sql
+            ]
+         }
+      });
+
+      $d->decorate_driver_unconnected(Pg => dateadd_sql => sub {
+         sub {
+            my ($date_sql, $unit, $amount_sql) = @_;
+
+            my ($d_sql, @d_args) = @{$date_sql};
+            my ($a_sql, @a_args) = @{$amount_sql};
+
+            die "unknown part $unit" unless $diff_part_map{$unit};
+
+            return [
+               "($d_sql + $a_sql * interval '1 $diff_part_map{$unit}')",
+               @d_args, @a_args,
+            ];
+         }
+      });
+   }
+
+   MYSQL: {
+      my %part_map = (
+         microsecond        => 'MICROSECOND',
+         second             => 'SECOND',
+         minute             => 'MINUTE',
+         hour               => 'HOUR',
+         day_of_month       => 'DAY',
+         week               => 'WEEK',
+         month              => 'MONTH',
+         quarter            => 'QUARTER',
+         year               => 'YEAR',
+         second_microsecond => 'SECOND_MICROSECOND',
+         minute_microsecond => 'MINUTE_MICROSECOND',
+         minute_second      => 'MINUTE_SECOND',
+         hour_microsecond   => 'HOUR_MICROSECOND',
+         hour_second        => 'HOUR_SECOND',
+         hour_minute        => 'HOUR_MINUTE',
+         day_microsecond    => 'DAY_MICROSECOND',
+         day_second         => 'DAY_SECOND',
+         day_minute         => 'DAY_MINUTE',
+         day_hour           => 'DAY_HOUR',
+         year_month         => 'YEAR_MONTH',
+      );
+
+      my %diff_part_map = %part_map;
+      $diff_part_map{day} = delete $diff_part_map{day_of_month};
+      delete $diff_part_map{qw(
+         second_microsecond minute_microsecond minute_second
+         hour_microsecond hour_second hour_minute day_microsecond
+         day_second day_minute day_hour year_month
+      )};
+
+      $d->decorate_driver_unconnected(mysql => datepart_sql => sub {
+         sub {
+            my ($date_sql, $part) = @_;
+
+            my $sql = delete $date_sql->[0];
+
+            return [
+               "EXTRACT($part_map{$part} FROM $sql)", @$date_sql
+            ]
+         }
+      });
+
+      $d->decorate_driver_unconnected(mysql => dateadd_sql => sub {
+         sub {
+            my ($date_sql, $unit, $amount_sql) = @_;
+
+            my ($d_sql, @d_args) = @{$date_sql};
+            my ($a_sql, @a_args) = @{$amount_sql};
+
+            die "unknown part $unit" unless $diff_part_map{$unit};
+
+            return [
+               "DATE_ADD($d_sql, INTERVAL $a_sql $diff_part_map{$unit})",
+               @d_args, @a_args,
+            ];
+         }
+      });
+   }
+
+   ORACLE: {
+      my %part_map = (
+         second       => 'SECOND',
+         minute       => 'MINUTE',
+         hour         => 'HOUR',
+         day_of_month => 'DAY',
+         month        => 'MONTH',
+         year         => 'YEAR',
+      );
+
+      $d->decorate_driver_unconnected(Oracle => datepart_sql => sub {
+         sub {
+            my ($date_sql, $part) = @_;
+
+            my $sql = delete $date_sql->[0];
+
+            $sql = "TO_TIMESTAMP($sql)"
+                if $part =~ /second|minute|hour/;
+            return [
+               "EXTRACT($part_map{$part} FROM $sql)", @$date_sql
+            ]
+         }
+      });
+
+      my %diff_part_map = %part_map;
+      $diff_part_map{day} = delete $diff_part_map{day_of_month};
+      delete $diff_part_map{$_} for qw(year month);
+      $d->decorate_driver_unconnected(Oracle => dateadd_sql => sub {
+         sub {
+            my ($date_sql, $unit, $amount_sql) = @_;
+
+            my ($d_sql, @d_args) = @{$date_sql};
+            my ($a_sql, @a_args) = @{$amount_sql};
+
+            die "unknown unit $unit" unless $diff_part_map{$unit};
+
+            return [
+               "($d_sql + NUMTODSINTERVAL($a_sql, ?))",
+               @d_args, @a_args, $diff_part_map{$unit}
+            ];
+         }
+      });
+   }
+   return $d;
+}
+
+use namespace::clean;
+
+sub utc {
+   my ($self, $datetime) = @_;
+
+   my $tz_name = $datetime->time_zone->name;
+
+   die "floating dates are not allowed"
+      if $tz_name eq 'floating';
+
+   $datetime = $datetime->clone->set_time_zone('UTC')
+      unless $tz_name eq 'UTC';
+
+   $_[0]->result_source->storage->datetime_parser->format_datetime($datetime)
+}
+
+sub dt_before {
+   my ($self, $l, $r) = @_;
+
+   my ($l_sql, @l_args) = _flatten_thing($self, $l);
+   my ($r_sql, @r_args) = _flatten_thing($self, $r);
+
+   return $self->search(\[
+      "$l_sql < $r_sql", @l_args, @r_args
+   ]);
+}
+
+sub dt_on_or_before {
+   my ($self, $l, $r) = @_;
+
+   my ($l_sql, @l_args) = _flatten_thing($self, $l);
+   my ($r_sql, @r_args) = _flatten_thing($self, $r);
+
+   $self->search(\[
+      "$l_sql <= $r_sql", @l_args, @r_args
+   ]);
+}
+
+sub dt_on_or_after {
+   my ($self, $l, $r) = @_;
+
+   my ($l_sql, @l_args) = _flatten_thing($self, $l);
+   my ($r_sql, @r_args) = _flatten_thing($self, $r);
+
+   return $self->search(\[
+      "$l_sql >= $r_sql", @l_args, @r_args
+   ]);
+}
+
+sub dt_after {
+   my ($self, $l, $r) = @_;
+
+   my ($l_sql, @l_args) = _flatten_thing($self, $l);
+   my ($r_sql, @r_args) = _flatten_thing($self, $r);
+
+   return $self->search(\[
+      "$l_sql > $r_sql", @l_args, @r_args
+   ]);
+}
+
+my $d;
+sub utc_now {
+   my $self = shift;
+   my $storage = $self->result_source->storage;
+   $storage->ensure_connected;
+
+   $d ||= _introspector();
+
+   return \( $d->get($storage->dbh, undef, 'now_utc_sql') );
+}
+
+sub dt_SQL_add {
+   my ($self, $thing, $unit, $amount) = @_;
+
+   my $storage = $self->result_source->storage;
+   $storage->ensure_connected;
+
+   $d ||= _introspector();
+
+   return \(
+      $d->get($storage->dbh, undef, 'dateadd_sql')->(
+         [ _flatten_thing($self, $thing) ],
+         $unit,
+         [ _flatten_thing($self, $amount) ],
+      )
+   );
+}
+
+sub dt_SQL_pluck {
+   my ($self, $thing, $part) = @_;
+
+   my $storage = $self->result_source->storage;
+   $storage->ensure_connected;
+
+   $d ||= _introspector();
+
+   return \(
+      $d->get($storage->dbh, undef, 'datepart_sql')->(
+         [ _flatten_thing($self, $thing) ],
+         $part,
+      )
+   );
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+DBIx::Class::Helper::ResultSet::DateMethods1 - Work with dates in your RDBMS nicely
+
+=head1 VERSION
+
+version 2.021001
+
+=head1 DESCRIPTION
+
+See L<DBIx::Class::Helper::ResultSet/NOTE> for a nice way to apply it
+to your entire schema.
+
+This ResultSet component gives the user tools to do B<mostly> portable date
+manipulation in the database.  Before embarking on a cross database project,
+take a look at L</IMPLEMENTATION> to see what might break on switching
+databases.
+
+This package has a few types of methods.
+
+=over
+
+=item Search Shortcuts
+
+These, like typical ResultSet methods, return another ResultSet.  See
+L</dt_before>, L</dt_on_or_before>, L</dt_on_or_after>, and L</dt_after>.
+
+=item The date helper
+
+There is only one: L</utc>.  Makes searching with dates a little easier.
+
+=item SQL generators
+
+These help generate more complex queries.  The can be used in many different
+parts of L<DBIx::Class::ResultSet/search>.  See L</utc_now>, L</dt_SQL_pluck>,
+and L</dt_SQL_add>.
+
+=back
+
+=head1 METHODS
+
+=head2 utc
+
+ $rs->search({
+   'some_date' => $rs->utc($datetime),
+ })->all
+
+Takes a L<DateTime> object, updates the C<time_zone> to C<UTC>, and formats it
+according to whatever database engine you are using.
+
+Dies if you pass it a date with a C<< floating time_zone >>.
+
+=head2 utc_now
+
+Returns a C<ScalarRef> representing the way to get the current date and time
+in C<UTC> for whatever database engine you are using.
+
+=head2 dt_before
+
+ $rs->dt_before({ -ident => '.start' }, { -ident => '.end' })->all
+
+Takes two values, each an expression of L</TYPES>.
+
+=head2 dt_on_or_before
+
+ $rs->dt_on_or_before({ -ident => '.start' }, DateTime->now)->all
+
+Takes two values, each an expression of L</TYPES>.
+
+=head2 dt_on_or_after
+
+ $rs->dt_on_or_after(DateTime->now, { ident => '.end' })->all
+
+Takes two values, each an expression of L</TYPES>.
+
+=head2 dt_after
+
+ $rs->dt_after({ ident => '.end' }, $rs->get_column('datecol')->as_query)->all
+
+Takes two values, each an expression of L</TYPES>.
+
+=head2 dt_SQL_add
+
+ # which ones start in 3 minutes?
+ $rs->dt_on_or_after(
+    { ident => '.start' },
+    $rs->dt_SQL_add($rs->utc_now, 'minute', 3)
+ )->all
+
+Takes three arguments: a date conforming to L</TYPES>, a unit, and an amount.
+The idea is to add the given unit to the datetime.  See your L</IMPLEMENTATION>
+for what units are accepted.
+
+=head2 dt_SQL_pluck
+
+ # get count per year
+ $rs->search(undef, {
+    columns => {
+       count => '*',
+       year  => $rs->dt_SQL_pluck({ -ident => '.start' }, 'year'),
+    },
+    group_by => [$rs->dt_SQL_pluck({ -ident => '.start' }, 'year')],
+ )->hri->all
+
+Takes two arguments: a date conforming to L</TYPES> and a unit.  The idea
+is to pluck a given unit from the datetime.  See your L</IMPLEMENTATION>
+for what units are accepted.
+
+=head1 TYPES
+
+Because these methods are so limited in scope they can be a bit more smart
+than typical C<SQL::Abstract> trees.
+
+There are "smart types" that this package supports.
+
+=over
+
+=item * vanilla scalars (C<1>, C<2012-12-12 12:12:12>)
+
+bound directly as untyped values
+
+=item * hashrefs with an C<-ident> (C<< { -ident => '.foo' } >>)
+
+As usual this gets flattened into a column.  The one special feature in this
+module is that columns starting with a dot will automatically be prefixed with
+L<DBIx::Class::ResultSet/current_source_alias>.
+
+=item * L<DateTime> objects
+
+C<DateTime> objects work as if they were passed to L</utc>.
+
+=item * C<ScalarRef> (C<< \'NOW()' >>)
+
+As usual in C<DBIx::Class>, C<ScalarRef>'s will be flattened into regular SQL.
+
+=item * C<ArrayRefRef> (C<< \["SELECT foo FROM bar WHERE id = ?", [{}, 1]] >>)
+
+As usual in C<DBIx::Class>, C<ArrayRefRef>'s will be flattened into SQL with
+bound values.
+
+=back
+
+Anything not mentioned in the above list will explode, one way or another.
+
+=head1 IMPLEMENTATION
+
+The exact details for the functions your database engine provides.
+
+If a piece of functionality is flagged with âš , it means that the feature in
+question is not portable at all, and only supported on that engine.
+
+=head2 C<SQL Server>
+
+=over
+
+=item * L</utc_now> - L<GETUTCDATE|http://msdn.microsoft.com/en-us/library/ms178635.aspx>
+
+=item * L</dt_SQL_pluck> - L<DATEPART|http://msdn.microsoft.com/en-us/library/ms174420.aspx>
+
+Supported units
+
+=over
+
+=item * year
+
+=item * quarter
+
+=item * month
+
+=item * day_of_year
+
+=item * day_of_month
+
+=item * week
+
+=item * day_of_week
+
+=item * hour
+
+=item * minute
+
+=item * second
+
+=item * millisecond
+
+=item * nanosecond âš 
+
+=item * non_iso_day_of_week
+
+SQL Server offers both C<ISO_WEEK> and C<weekday>.  For interop reasons
+C<weekday> uses the C<ISO_WEEK> version.
+
+=item * timezone_as_minutes âš 
+
+=back
+
+=item * L</dt_SQL_add> - L<DATEADD|http://msdn.microsoft.com/en-us/library/ms186819.aspx>
+
+Supported units
+
+=over
+
+=item * year
+
+=item * quarter
+
+=item * month
+
+=item * day
+
+=item * week
+
+=item * hour
+
+=item * minute
+
+=item * second
+
+=item * millisecond
+
+=item * nanosecond âš 
+
+=item * iso_day_of_week
+
+=item * timezone_as_minutes âš 
+
+=back
+
+=back
+
+=head2 C<SQLite>
+
+=over
+
+=item * L</utc_now> - L<DATETIME('now')|https://www.sqlite.org/lang_datefunc.html>
+
+=item * L</dt_SQL_pluck> - L<STRFTIME|https://www.sqlite.org/lang_datefunc.html>
+
+Note: C<SQLite>'s pluck implementation pads numbers with zeros, because it is
+implemented on based on a formatting function.  If you want your code to work
+on SQLite you'll need to strip off (or just numify) what you get out of the
+database first.
+
+Available units
+
+=over
+
+=item * month
+
+=item * day_of_month
+
+=item * year
+
+=item * hour
+
+=item * day_of_year
+
+=item * minute
+
+=item * second
+
+=item * day_of_week
+
+=item * week
+
+=item * julian_day âš 
+
+=item * seconds_since_epoch
+
+=item * fractional_seconds âš 
+
+=back
+
+=item * L</dt_SQL_add> - L<DATETIME|https://www.sqlite.org/lang_datefunc.html>
+
+Available units
+
+=over
+
+=item * day
+
+=item * hour
+
+=item * minute
+
+=item * second
+
+=item * month
+
+=item * year
+
+=back
+
+=back
+
+=head2 C<PostgreSQL>
+
+=over
+
+=item * L</utc_now> - L<CURRENT_TIMESTAMP|http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT>
+
+=item * L</dt_SQL_pluck> - L<date_part|http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT>
+
+Available units
+
+=over
+
+=item * century âš 
+
+=item * decade âš 
+
+=item * day_of_month
+
+=item * day_of_week
+
+=item * day_of_year
+
+=item * seconds_since_epoch
+
+=item * hour
+
+=item * iso_day_of_week
+
+=item * iso_year
+
+=item * microsecond
+
+=item * millenium âš 
+
+=item * millisecond
+
+=item * minute
+
+=item * month
+
+=item * quarter
+
+=item * second
+
+=item * timezone âš 
+
+=item * timezone_hour âš 
+
+=item * timezone_minute âš 
+
+=item * week
+
+=item * year
+
+=back
+
+=item * L</dt_SQL_add> - Addition and L<interval|http://www.postgresql.org/docs/current/static/functions-datetime.html#OPERATORS-DATETIME-TABLE>
+
+To be clear, it ends up looking like:
+C<< ("some_column" + 5 * interval '1 minute') >>
+
+Available units
+
+=over
+
+=item * century âš 
+
+=item * decade âš 
+
+=item * day
+
+=item * hour
+
+=item * microsecond âš 
+
+=item * millisecond
+
+=item * minute
+
+=item * month
+
+=item * second
+
+=item * week
+
+=item * year
+
+=back
+
+=back
+
+=head2 C<MySQL>
+
+=over
+
+=item * L</utc_now> - L<UTC_TIMESTAMP|https://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_utc-timestamp>
+
+=item * L</dt_SQL_pluck> - L<EXTRACT|https://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_extract>
+
+Available units
+
+=over
+
+=item * microsecond
+
+=item * second
+
+=item * minute
+
+=item * hour
+
+=item * day_of_month
+
+=item * week
+
+=item * month
+
+=item * quarter
+
+=item * year
+
+=item * second_microsecond âš 
+
+=item * minute_microsecond âš 
+
+=item * minute_second âš 
+
+=item * hour_microsecond âš 
+
+=item * hour_second âš 
+
+=item * hour_minute âš 
+
+=item * day_microsecond âš 
+
+=item * day_second âš 
+
+=item * day_minute âš 
+
+=item * day_hour âš 
+
+=item * year_month âš 
+
+=back
+
+=item * L</dt_SQL_add> - L<DATE_ADD|https://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date-add>
+
+Available units
+
+=over
+
+=item * microsecond
+
+=item * second
+
+=item * minute
+
+=item * hour
+
+=item * day
+
+=item * week
+
+=item * month
+
+=item * quarter
+
+=item * year
+
+=back
+
+=back
+
+=head2 C<Oracle>
+
+B<< ORACLE USERS BEWARE >>: I run all the tests on all of the databases
+B<except> C<Oracle>.  If you have time to help make
+L<dockerprove|https://github.com/frioux/DBIx-Class-Helpers/blob/master/dockerprove>
+and/or L<travisci|https://github.com/frioux/DBIx-Class-Helpers/blob/master/.travis.yml>
+test against C<Oracle> I'll gladly take those patches.  For hints look at
+L<https://index.docker.io/u/wnameless/oracle-xe-11g/> and
+L<https://github.com/dbsrgits/dbix-class/commit/003e97c53e065e7497a4946c29d5a94e7cf34389>.
+
+=over
+
+=item * L</utc_now> - L<sys_extract_utc(SYSTIMESTAMP)|http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions167.htm>
+
+=item * L</dt_SQL_pluck> - L<EXTRACT|docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm>
+
+Available units
+
+=over
+
+=item * second
+
+=item * minute
+
+=item * hour
+
+=item * day_of_month
+
+=item * month
+
+=item * year
+
+=back
+
+=item * L</dt_SQL_add> - Addition and L<NUMTODSINTERVAL|http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions103.htm>
+
+To be clear, it ends up looking like:
+C<< ("some_column" + NUMTODSINTERVAL(4, 'MINUTE') >>
+
+Available units
+
+=over
+
+=item * second
+
+=item * minute
+
+=item * hour
+
+=item * day
+
+=back
+
+=back
+
+=head1 CONTRIBUTORS
+
+These people worked on the original implementation, and thus deserve some
+credit for at least providing me a reference to implement this based off of:
+
+=over
+
+=item Alexander Hartmaier (abraxxa) for Oracle implementation details
+
+=item Devin Austin (dhoss) for Pg implementation details
+
+=item Rafael Kitover (caelum) for providing a test environment with lots of DBs
+
+=back
+
+=head1 WHENCE dt_SQL_diff?
+
+The original implementation of these date helpers (originally dubbed date
+operators) included a third operator called C<"diff">.  It existed to
+subtract one date from another and return a duration.  After using it a few
+times and getting bitten every time, I decided to stop using it and instead
+compare against actual dates always.  If someone can come up with a good use
+case I am interested in re-implementing C<dt_SQL_diff>, but I worry that it
+will be very unportable and generally not very useful.
+
+=head1 AUTHOR
+
+Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2014 by Arthur Axel "fREW" Schmidt.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::IgnoreWantarray;
-{
-  $DBIx::Class::Helper::ResultSet::IgnoreWantarray::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::IgnoreWantarray::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -29,7 +26,7 @@ DBIx::Class::Helper::ResultSet::IgnoreWantarray - Get rid of search context issu
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Me;
-{
-  $DBIx::Class::Helper::ResultSet::Me::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Me::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -24,7 +21,7 @@ DBIx::Class::Helper::ResultSet::Me - Define predefined searches more nicely
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::NoColumns;
-{
-  $DBIx::Class::Helper::ResultSet::NoColumns::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::NoColumns::VERSION = '2.021001';
 # ABSTRACT: Look ma, no columns!
 
 use strict;
@@ -24,7 +21,7 @@ DBIx::Class::Helper::ResultSet::NoColumns - Look ma, no columns!
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Random;
-{
-  $DBIx::Class::Helper::ResultSet::Random::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Random::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -63,7 +60,7 @@ DBIx::Class::Helper::ResultSet::Random - Get random rows from a ResultSet
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::RemoveColumns;
-{
-  $DBIx::Class::Helper::ResultSet::RemoveColumns::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::RemoveColumns::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -13,7 +10,7 @@ sub _resolved_attrs {
 
    my $attrs  = $self->{attrs}; # not copying on purpose...
 
-   if ( $attrs->{remove_columns} ) {
+   if ( !$attrs->{columns} && $attrs->{remove_columns} ) {
       my %rc = map { $_ => 1 } @{$attrs->{remove_columns}};
       $attrs->{columns} = [
          grep { !$rc{$_} } $self->result_source->columns
@@ -37,7 +34,7 @@ DBIx::Class::Helper::ResultSet::RemoveColumns - Remove columns from a ResultSet
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::ResultClassDWIM;
-{
-  $DBIx::Class::Helper::ResultSet::ResultClassDWIM::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::ResultClassDWIM::VERSION = '2.021001';
 # ABSTRACT: result_class => '::HRI' == WIN
 
 use strict;
@@ -38,7 +35,7 @@ DBIx::Class::Helper::ResultSet::ResultClassDWIM - result_class => '::HRI' == WIN
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::SearchOr;
-{
-  $DBIx::Class::Helper::ResultSet::SearchOr::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::SearchOr::VERSION = '2.021001';
 # ABSTRACT: Combine ResultSet searches with OR's
 
 use strict;
@@ -40,7 +37,7 @@ DBIx::Class::Helper::ResultSet::SearchOr - Combine ResultSet searches with OR's
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::SetOperations;
-{
-  $DBIx::Class::Helper::ResultSet::SetOperations::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::SetOperations::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -107,7 +104,7 @@ DBIx::Class::Helper::ResultSet::SetOperations - Do set operations with DBIx::Cla
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::AddColumns;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::AddColumns::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::AddColumns::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -22,7 +19,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::AddColumns
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::Columns;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::Columns::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::Columns::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -22,7 +19,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::Columns
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::Distinct;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::Distinct::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::Distinct::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -22,7 +19,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::Distinct
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::GroupBy;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::GroupBy::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::GroupBy::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -22,7 +19,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::GroupBy
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::HRI;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::HRI::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::HRI::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -25,7 +22,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::HRI
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::HasRows;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::HasRows::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::HasRows::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -24,7 +21,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::HasRows
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::Limit;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::Limit::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::Limit::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -24,7 +21,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::Limit
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -0,0 +1,56 @@
+package DBIx::Class::Helper::ResultSet::Shortcut::LimitedPage;
+$DBIx::Class::Helper::ResultSet::Shortcut::LimitedPage::VERSION = '2.021001';
+use strict;
+use warnings;
+
+use base qw(
+  DBIx::Class::Helper::ResultSet::Shortcut::Rows
+  DBIx::Class::Helper::ResultSet::Shortcut::Page
+);
+
+sub limited_page {
+  my $self = shift;
+  if (@_ == 1) {
+    my $arg = shift;
+    if (ref $arg) {
+      my ( $page, $rows ) = @$arg{qw(page rows)};
+      return $self->page($page)->rows($rows);
+    } else {
+      return $self->page($arg);
+    }
+  } elsif (@_ == 2) {
+    my ( $page, $rows ) = @_;
+    return $self->page($page)->rows($rows);
+  } else {
+    die 'Invalid args passed to get_page method';
+  }
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+DBIx::Class::Helper::ResultSet::Shortcut::LimitedPage
+
+=head1 VERSION
+
+version 2.021001
+
+=head1 AUTHOR
+
+Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2014 by Arthur Axel "fREW" Schmidt.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::OrderBy;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::OrderBy::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::OrderBy::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -22,7 +19,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::OrderBy
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::OrderByMagic;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::OrderByMagic::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::OrderByMagic::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -48,7 +45,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::OrderByMagic
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -0,0 +1,35 @@
+package DBIx::Class::Helper::ResultSet::Shortcut::Page;
+$DBIx::Class::Helper::ResultSet::Shortcut::Page::VERSION = '2.021001';
+use strict;
+use warnings;
+
+sub page { shift->search(undef, { page => shift }) }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+DBIx::Class::Helper::ResultSet::Shortcut::Page
+
+=head1 VERSION
+
+version 2.021001
+
+=head1 AUTHOR
+
+Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2014 by Arthur Axel "fREW" Schmidt.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::Prefetch;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::Prefetch::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::Prefetch::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -22,7 +19,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::Prefetch
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut::Rows;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::Rows::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::Rows::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -22,7 +19,7 @@ DBIx::Class::Helper::ResultSet::Shortcut::Rows
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 AUTHOR
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Shortcut;
-{
-  $DBIx::Class::Helper::ResultSet::Shortcut::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Shortcut::VERSION = '2.021001';
 # ABSTRACT: Shortcuts to common searches (->order_by, etc)
 
 use strict;
@@ -18,7 +15,9 @@ use base (qw(
    DBIx::Class::Helper::ResultSet::Shortcut::Limit
    DBIx::Class::Helper::ResultSet::Shortcut::OrderByMagic
    DBIx::Class::Helper::ResultSet::Shortcut::Prefetch
+   DBIx::Class::Helper::ResultSet::Shortcut::LimitedPage
    DBIx::Class::Helper::ResultSet::Shortcut::Rows
+   DBIx::Class::Helper::ResultSet::Shortcut::Page
 ));
 
 1;
@@ -35,7 +34,7 @@ DBIx::Class::Helper::ResultSet::Shortcut - Shortcuts to common searches (->order
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -133,6 +132,20 @@ This is an alias for C<rows>.
 A lighter way to check the resultset contains any data rather than
 calling C<< $rs->count >>.
 
+=head2 page
+
+ $foo_rs->page(2);
+
+ # equivalent to...
+ $foo_rs->search(undef, { page => 2 })
+
+=head2 limited_page
+
+ $foo_rs->limited_page(2, 3);
+
+ # equivalent to...
+ $foo_rs->search(undef, { page => 2, rows => 3 })
+
 =head2 columns
 
  $foo_rs->columns([qw/ some column names /]);
@@ -191,6 +204,13 @@ C<DBIx::Class::Helper::ResultSet::Shortcut::OrderBy>))
 
 =item * L<DBIx::Class::Helper::ResultSet::Shortcut::AddColumns>
 
+=item * L<DBIx::Class::Helper::ResultSet::Shortcut::Page>
+
+=item * L<DBIx::Class::Helper::ResultSet::Shortcut::LimitedPage>
+
+(inherits from C<DBIx::Class::Helper::ResultSet::Shortcut::Page> and
+L<DBIx::Class::Helper::ResultSet::Shortcut::Rows>)
+
 =back
 
 =head1 AUTHOR
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::Union;
-{
-  $DBIx::Class::Helper::ResultSet::Union::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::Union::VERSION = '2.021001';
 use parent 'DBIx::Class::Helper::ResultSet::SetOperations';
 
 use Carp::Clan;
@@ -25,7 +22,7 @@ DBIx::Class::Helper::ResultSet::Union - (DEPRECATED) Get rid of search context i
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet::VirtualView;
-{
-  $DBIx::Class::Helper::ResultSet::VirtualView::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::VirtualView::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -32,7 +29,7 @@ DBIx::Class::Helper::ResultSet::VirtualView - Clean up your SQL namespace (DEPRE
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::ResultSet;
-{
-  $DBIx::Class::Helper::ResultSet::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::ResultSet::VERSION = '2.021001';
 use parent qw{
    DBIx::Class::Helper::ResultSet::AutoRemoveColumns
    DBIx::Class::Helper::ResultSet::CorrelateRelationship
@@ -33,7 +30,7 @@ DBIx::Class::Helper::ResultSet - All the ResultSet Helpers in one place
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::CleanResultSet;
-{
-  $DBIx::Class::Helper::Row::CleanResultSet::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::CleanResultSet::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -24,7 +21,7 @@ DBIx::Class::Helper::Row::CleanResultSet - Shortcut for C<< ->resultset >>
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::JoinTable;
-{
-  $DBIx::Class::Helper::Row::JoinTable::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::JoinTable::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -195,7 +192,7 @@ DBIx::Class::Helper::Row::JoinTable - Easily set up join tables with DBIx::Class
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::NumifyGet;
-{
-  $DBIx::Class::Helper::Row::NumifyGet::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::NumifyGet::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -49,7 +46,7 @@ DBIx::Class::Helper::Row::NumifyGet - Force numeric "context" on numeric columns
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::OnColumnChange;
-{
-  $DBIx::Class::Helper::Row::OnColumnChange::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::OnColumnChange::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -140,7 +137,7 @@ DBIx::Class::Helper::Row::OnColumnChange - Do things when the values of a column
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::ProxyResultSetMethod;
-{
-  $DBIx::Class::Helper::Row::ProxyResultSetMethod::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::ProxyResultSetMethod::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -62,7 +59,7 @@ DBIx::Class::Helper::Row::ProxyResultSetMethod - Efficiently reuse ResultSet met
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::ProxyResultSetUpdate;
-{
-  $DBIx::Class::Helper::Row::ProxyResultSetUpdate::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::ProxyResultSetUpdate::VERSION = '2.021001';
 # ABSTRACT: Efficiently reuse ResultSet updates from results
 
 use base 'DBIx::Class::Helper::Row::SelfResultSet';
@@ -44,7 +41,7 @@ DBIx::Class::Helper::Row::ProxyResultSetUpdate - Efficiently reuse ResultSet upd
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::RelationshipDWIM;
-{
-  $DBIx::Class::Helper::Row::RelationshipDWIM::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::RelationshipDWIM::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -58,7 +55,7 @@ DBIx::Class::Helper::Row::RelationshipDWIM - Type less for your relationships!
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::SelfResultSet;
-{
-  $DBIx::Class::Helper::Row::SelfResultSet::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::SelfResultSet::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -34,7 +31,7 @@ DBIx::Class::Helper::Row::SelfResultSet - Easily use ResultSet methods for the c
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::StorageValues;
-{
-  $DBIx::Class::Helper::Row::StorageValues::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::StorageValues::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -81,7 +78,7 @@ DBIx::Class::Helper::Row::StorageValues - Keep track of stored vs in-memory row
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::SubClass;
-{
-  $DBIx::Class::Helper::Row::SubClass::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::SubClass::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -58,7 +55,7 @@ DBIx::Class::Helper::Row::SubClass - Convenient subclassing with DBIx::Class
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Row::ToJSON;
-{
-  $DBIx::Class::Helper::Row::ToJSON::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Row::ToJSON::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -70,7 +67,7 @@ DBIx::Class::Helper::Row::ToJSON - Remove the boilerplate from your TO_JSON func
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Schema::DateTime;
-{
-  $DBIx::Class::Helper::Schema::DateTime::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Schema::DateTime::VERSION = '2.021001';
 # ABSTRACT: DateTime helper
 
 use strict;
@@ -28,7 +25,7 @@ DBIx::Class::Helper::Schema::DateTime - DateTime helper
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Schema::GenerateSource;
-{
-  $DBIx::Class::Helper::Schema::GenerateSource::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Schema::GenerateSource::VERSION = '2.021001';
 # ABSTRACT: Generate sources directly from your Schema
 
 use strict;
@@ -44,7 +41,7 @@ DBIx::Class::Helper::Schema::GenerateSource - Generate sources directly from you
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,7 +1,6 @@
 package DBIx::Class::Helper::Schema::LintContents;
-{
-  $DBIx::Class::Helper::Schema::LintContents::VERSION = '2.019004';
-}
+$DBIx::Class::Helper::Schema::LintContents::VERSION = '2.021001';
+# ABSTRACT: suite of methods to find violated "constraints"
 
 use strict;
 use warnings;
@@ -114,11 +113,11 @@ __END__
 
 =head1 NAME
 
-DBIx::Class::Helper::Schema::LintContents
+DBIx::Class::Helper::Schema::LintContents - suite of methods to find violated "constraints"
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::Schema::QuoteNames;
-{
-  $DBIx::Class::Helper::Schema::QuoteNames::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::Schema::QuoteNames::VERSION = '2.021001';
 # ABSTRACT: force C<quote_names> on
 
 use strict;
@@ -33,7 +30,7 @@ DBIx::Class::Helper::Schema::QuoteNames - force C<quote_names> on
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::SubClass;
-{
-  $DBIx::Class::Helper::SubClass::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::SubClass::VERSION = '2.021001';
 use parent 'DBIx::Class::Helper::Row::SubClass';
 
 use Carp::Clan;
@@ -25,7 +22,7 @@ DBIx::Class::Helper::SubClass - (DEPRECATED) Convenient subclassing with DBIx::C
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helper::VirtualView;
-{
-  $DBIx::Class::Helper::VirtualView::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helper::VirtualView::VERSION = '2.021001';
 use parent 'DBIx::Class::Helper::ResultSet::VirtualView';
 
 use Carp::Clan;
@@ -25,7 +22,7 @@ DBIx::Class::Helper::VirtualView - (DEPRECATED) Clean up your SQL namespace
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helpers::Util;
-{
-  $DBIx::Class::Helpers::Util::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helpers::Util::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -156,7 +153,7 @@ DBIx::Class::Helpers::Util - Helper utilities for DBIx::Class components
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -1,8 +1,5 @@
 package DBIx::Class::Helpers;
-{
-  $DBIx::Class::Helpers::VERSION = '2.019004';
-}
-
+$DBIx::Class::Helpers::VERSION = '2.021001';
 use strict;
 use warnings;
 
@@ -22,7 +19,7 @@ DBIx::Class::Helpers - Simplify the common case stuff for DBIx::Class.
 
 =head1 VERSION
 
-version 2.019004
+version 2.021001
 
 =head1 SYNOPSIS
 
@@ -0,0 +1,492 @@
+package A::ResultSet::DateMethods1;
+
+use Test::Roo;
+use Test::Deep;
+use DateTime;
+use Test::Fatal;
+
+use lib 't/lib';
+use TestSchema;
+
+sub _dt {
+   DateTime->new(
+      time_zone => 'UTC',
+      year => shift(@_), month => shift(@_), day => shift(@_),
+   )
+}
+
+has on_connect_call => ( is => 'ro' );
+
+has [qw(
+   add_sql_by_part_skip add_sql_by_part_result
+   pluck_sql_by_part_skip pluck_sql_by_part_result
+)] => (
+   is => 'ro',
+   default => sub { {} },
+);
+
+has [map "${_}_sql_by_part", qw(pluck add)] => (
+   is => 'ro',
+   default => sub { {} },
+);
+
+has _skip_msg_once => ( is => 'rw' );
+sub skip_reason {
+   return '(see above)' if $_[0]->_skip_msg_once;
+   $_[0]->_skip_msg_once(1);
+   'set ' . join(q<, >, shift->env_vars) . ' to run these tests'
+}
+
+sub env_vars {
+   my $self = shift;
+
+   my $p = 'DBIITEST_' . uc($self->engine);
+   $p . '_DSN', $p . '_USER', $p . '_PASSWORD';
+}
+
+has connect_info => (
+   is => 'ro',
+   lazy => 1,
+   default => sub {
+      my $self = shift;
+      my @connect_info = grep $_, map $ENV{$_}, $self->env_vars;
+      push @connect_info, { on_connect_call => $self->on_connect_call }
+         if @connect_info && $self->on_connect_call;
+
+      return \@connect_info;
+   },
+);
+
+has [qw(
+   engine utc_now stringified_date add_sql_prefix
+   sub_sql pluck_sql_prefix storage_type
+)] => (is => 'ro');
+
+has plucked_minute => (
+   is => 'ro',
+   default => 9,
+);
+
+has plucked_second => (
+   is => 'ro',
+   default => 8,
+);
+
+sub _merged_pluck_sql_by_part_result {
+   my $self = shift;
+
+   my %base = (
+      year         => 2012,
+      month        => 1,
+      day_of_month => 2,
+      hour         => 3,
+      day_of_year  => 2,
+      minute       => 4,
+      second       => 5,
+      day_of_week  => 1,
+      week         => 1,
+      quarter      => 1,
+   );
+
+   my %results = %{$self->pluck_sql_by_part_result};
+
+   my @overrides = grep { $base{$_} } sort keys %results;
+   note join(q(, ), @overrides) . ' overridden' if @overrides;
+
+   return +{ %base, %results };
+}
+
+sub _merged_add_sql_by_part_result {
+   my $self = shift;
+
+   return +{
+      day    => '2012-12-13 00:00:00',
+      hour   => '2012-12-12 02:00:00',
+      minute => '2012-12-12 00:03:00',
+      month  => '2013-04-12 00:00:00',
+      second => '2012-12-12 00:00:05',
+      year   => '2018-12-12 00:00:00',
+      %{$self->add_sql_by_part_result},
+   }
+}
+
+sub connected { !!@{shift->connect_info} }
+
+has schema => (
+   is => 'ro',
+   lazy => 1,
+   builder => sub {
+      my $self = shift;
+
+      my $schema = 'TestSchema';
+      $schema->storage_type('DBIx::Class::Storage::DBI'); # class methods: THE WORST
+      $schema->storage_type('DBIx::Class::Storage::DBI::' . $self->storage_type)
+         if $self->storage_type && !$self->connected;
+
+      $schema = TestSchema->connect(@{$self->connect_info});
+      $schema->deploy if $self->connected;
+      $schema->storage->dbh->{private_dbii_driver} = $self->engine;
+
+      $schema
+   },
+);
+
+sub rs { shift->schema->resultset('HasDateOps') }
+
+sub pop_rs_1 {
+   my $self = shift;
+
+   $self->rs->delete;
+   $self->rs->populate([
+      [qw(id a_date)],
+      [1, $self->format_datetime(_dt(2012, 12, 12)), ],
+      [2, $self->format_datetime(_dt(2012, 12, 13)), ],
+      [3, $self->format_datetime(_dt(2012, 12, 14)), ],
+   ])
+}
+
+sub pop_rs_2 {
+   my $self = shift;
+
+   my $dt1 = $self->format_datetime(_dt(2012, 12, 12));
+   my $dt2 = $self->format_datetime(_dt(2012, 12, 13));
+   $self->rs->delete;
+   $self->rs->populate([
+      [qw(id a_date b_date)],
+      [1, $dt1, $dt2],
+      [2, $dt1, $dt1],
+      [3, $dt2, $dt1],
+   ])
+}
+
+sub format_datetime {
+   shift->schema
+      ->storage
+      ->datetime_parser
+      ->format_datetime(shift @_)
+}
+
+sub parse_datetime {
+   shift->schema
+      ->storage
+      ->datetime_parser
+      ->parse_datetime(shift @_)
+}
+
+test basic => sub {
+   my $self = shift;
+
+   is(${$self->rs->utc_now}, $self->utc_now, 'utc_now');
+
+   like(exception {
+      $self->rs->utc(DateTime->new(year => 1985, month => 1, day => 1))
+   }, qr/floating dates are not allowed/, 'no floating dates');
+
+   SKIP: {
+      skip $self->skip_reason, 1 unless $self->connected;
+
+      my $central_date = DateTime->new(
+         year   => 2014,
+         month  => 2,
+         day    => 7,
+         hour   => 22,
+         minute => 43,
+         time_zone => 'America/Chicago',
+      );
+
+      is(
+         $self->rs->utc($central_date),
+         $self->stringified_date,
+         'datetime correctly UTC and stringified'
+      );
+
+      my $local_dt = DateTime->now( time_zone => 'UTC' );
+
+      $self->rs->delete;
+      $self->rs->create({ id => 1, a_date => $self->rs->utc_now });
+
+      my $remote_dt = $self->parse_datetime($self->rs->next->a_date);
+
+      ok(
+         $local_dt->subtract_datetime_absolute($remote_dt)->seconds < 60,
+         'UTC works! (and clock is correct)',
+      );
+   }
+};
+
+sub _comparisons {
+   my ($self, $l, $r, $n) = @_;
+   subtest $n => sub {
+      cmp_deeply(
+         [$self->rs->dt_before($l => $r)->get_column('id')->all],
+         [1],
+         'before',
+      );
+
+      cmp_deeply(
+         [$self->rs->dt_on_or_before($l, $r)->get_column('id')->all],
+         bag(1, 2),
+         'on_or_before',
+      );
+
+      cmp_deeply(
+         [$self->rs->dt_on_or_after($l, $r)->get_column('id')->all],
+         bag(2, 3),
+         'on_or_after',
+      );
+
+      cmp_deeply(
+         [$self->rs->dt_after($l, $r)->get_column('id')->all],
+         [3],
+         'after',
+      );
+   };
+}
+
+sub _middle_comparisons {
+   my ($self, $r) = @_;
+
+   $self->_comparisons({ -ident => 'a_date' } => $r, 'no prefix');
+
+   $self->_comparisons({ -ident => '.a_date' } => $r, 'auto prefix');
+
+   $self->_comparisons(
+      { -ident => $self->rs->current_source_alias . '.a_date' }
+         => $r, 'manual prefix'
+   )
+}
+
+test comparisons => sub {
+   my $self = shift;
+
+   SKIP: {
+      skip $self->skip_reason, 1 unless $self->connected;
+
+      $self->pop_rs_1;
+
+      my $dt = _dt(2012, 12, 13);
+      subtest 'datetime object' =>
+         sub { $self->_middle_comparisons($dt) };
+
+      subtest 'datetime literal'=> sub {
+         $self->_middle_comparisons($self->format_datetime($dt))
+      };
+
+      subtest subquery => sub {
+         $self->_middle_comparisons(
+            $self->rs->search({ id => 2})->get_column('a_date')->as_query
+         )
+      };
+
+      subtest 'both columns' => sub {
+         $self->pop_rs_2;
+
+         $self->_middle_comparisons({ -ident => '.b_date' }, 'auto prefix');
+         $self->_middle_comparisons({ -ident => 'b_date' }, 'no prefix');
+         $self->_middle_comparisons(
+            { -ident => $self->rs->current_source_alias . '.b_date' },
+            'manual prefix',
+         );
+      };
+
+      subtest 'literal SQL' => sub {
+         cmp_deeply(
+            [$self->rs->dt_before(
+               { -ident => '.b_date' },
+               $self->rs->utc_now
+            )->get_column('id')->all],
+            [1, 2, 3],
+            'literal SQL compared (and db clock correct)',
+         );
+      };
+   }
+};
+
+test add => sub {
+   my $self = shift;
+
+   $self->pop_rs_1 if $self->connected;
+
+   SKIP: {
+      skip $self->engine  . q(doesn't set add_sql_prefix) unless $self->add_sql_prefix;
+
+      my %offset = (
+         day => 1,
+         hour => 2,
+         minute => 3,
+         month => 4,
+         second => 5,
+         year => 6,
+      );
+      my $i = 1 + scalar keys %offset;
+      for my $part (sort keys %{$self->add_sql_by_part}) {
+         my $query = $self->rs->dt_SQL_add(
+            { -ident => 'a_date' },
+            $part,
+            $offset{$part} || $i++,
+         );
+         SKIP: {
+            skip $self->skip_reason, 1 unless $self->connected;
+            skip $self->add_sql_by_part_skip->{$part}, 1
+               if $self->add_sql_by_part_skip->{$part};
+
+            my $v;
+            my $e = exception {
+               $v = $self->rs->search({ id => 1 }, {
+                  columns => { v => $query },
+               })->get_column('v')->next;
+            };
+            ok !$e, "live $part" or diag "exception: $e";
+            is($v, $self->_merged_add_sql_by_part_result->{$part}, "suspected $part");
+         }
+
+         cmp_deeply(
+            $query,
+            $self->add_sql_by_part->{$part},
+            "unit: $part",
+         );
+      }
+
+      cmp_deeply(
+         $self->rs->dt_SQL_add({ -ident => '.a_date' }, 'second', 1),
+         $self->add_sql_prefix,
+         'vanilla add',
+      );
+   }
+
+   SKIP: {
+      skip $self->skip_reason, 1 unless $self->connected;
+
+      my $dt = DateTime->new(
+         time_zone => 'UTC',
+         year => 2013,
+         month => 12,
+         day => 11,
+         hour => 10,
+         minute => 9,
+         second => 8,
+      );
+
+      $self->rs->delete;
+      $self->rs->create({ id => 1, a_date => $self->rs->utc($dt) });
+
+      my $added = $self->rs->search(undef, {
+         rows => 1,
+         columns => { foo =>
+            $self->rs->dt_SQL_add(
+               $self->rs->dt_SQL_add(
+                  $self->rs->dt_SQL_add({ -ident => '.a_date' }, 'minute', 2),
+                     second => 4,
+               ), hour => 1,
+            ),
+         },
+         result_class => 'DBIx::Class::ResultClass::HashRefInflator',
+      })->first->{foo};
+      $added = $self->parse_datetime($added);
+
+      is($added->year => 2013, 'added year');
+      is($added->month => 12, 'added month');
+      is($added->day => 11, 'added day');
+      is($added->hour => 11, 'added hour');
+      is($added->minute => 11, 'added minute');
+      is($added->second => 12, 'added second');
+   }
+};
+
+test pluck => sub {
+   my $self = shift;
+
+   if ($self->connected) {
+      $self->rs->delete;
+      $self->rs->populate([
+         [qw(id a_date)],
+         [1, $self->format_datetime(
+               DateTime->new(
+                  year => 2012,
+                  month => 1,
+                  day => 2,
+                  hour => 3,
+                  minute => 4,
+                  second => 5,
+               )
+            )
+         ],
+      ])
+   }
+
+   my $i = 1;
+   for my $part (sort keys %{$self->pluck_sql_by_part}) {
+         SKIP: {
+            skip $self->skip_reason, 1 unless $self->connected;
+            skip $self->pluck_sql_by_part_skip->{$part}, 1
+               if $self->pluck_sql_by_part_skip->{$part};
+
+            my $res;
+            my $e = exception {
+               $res = $self->rs->search({ id => 1 }, {
+                  columns => {
+                     a_date => 'a_date',
+                     v => $self->rs->dt_SQL_pluck({ -ident => 'a_date' }, $part)
+                  },
+                  result_class => 'DBIx::Class::ResultClass::HashRefInflator',
+               })->next;
+            };
+            my $v = $res->{v};
+            my $date = $res->{a_date};
+            ok !$e, "live $part" or diag "exception: $e";
+            is(
+               $v,
+               $self->_merged_pluck_sql_by_part_result->{$part},
+               "suspected $part"
+            ) or diag "for date $date";
+         }
+
+      cmp_deeply(
+         $self->rs->dt_SQL_pluck({ -ident => 'a_date' }, $part),
+         $self->pluck_sql_by_part->{$part},
+         "unit $part",
+      );
+   }
+
+   cmp_deeply(
+      $self->rs->dt_SQL_pluck({ -ident => '.a_date' }, 'second'),
+      $self->pluck_sql_prefix,
+      'vanilla pluck',
+   );
+
+   SKIP: {
+      skip $self->skip_reason, 1 unless $self->connected;
+
+      my $dt = DateTime->new(
+         time_zone => 'UTC',
+         year => 2013,
+         month => 12,
+         day => 11,
+         hour => 10,
+         minute => 9,
+         second => 8,
+      );
+
+      $self->rs->delete;
+      $self->rs->create({ id => 1, a_date => $self->rs->utc($dt) });
+
+      my @parts = qw(year month day_of_month hour minute second);
+      my $plucked = $self->rs->search(undef, {
+         rows => 1,
+         select => [map $self->rs->dt_SQL_pluck({ -ident => '.a_date' }, $_), @parts],
+         as => \@parts,
+         result_class => 'DBIx::Class::ResultClass::HashRefInflator',
+      })->first;
+
+      cmp_deeply($plucked, {
+         year => 2013,
+         month => 12,
+         day_of_month => 11,
+         hour => 10,
+         minute => $self->plucked_minute,
+         second => $self->plucked_second,
+      }, 'live pluck works');
+   }
+};
+
+1;
@@ -10,6 +10,7 @@ column id => {
 };
 
 column foo_id => {
+   data_type => 'integer',
    keep_storage_value => 1,
 };
 
@@ -5,6 +5,7 @@ use DBIx::Class::Candy;
 table 'Foo';
 
 column id => {
+   data_type => 'integer',
    is_numeric => 1,
 };
 
@@ -6,9 +6,10 @@ use DBIx::Class::Candy -components => [
 
 table 'Bloaty';
 
-column 'id';
+primary_column id => { data_type => 'int' };
 
 column name => {
+   data_type => 'varchar',
    remove_column => 1,
 };
 
@@ -23,6 +24,4 @@ column your_mom => {
    is_serializable => 1,
 };
 
-primary_key 'id';
-
 1;
@@ -8,8 +8,8 @@ use DBIx::Class::Candy
 
 table 'Gnarly';
 
-column 'id';
-column 'name';
+primary_column id => { data_type => 'int' };
+column name => { data_type => 'varchar' };
 
 column literature => {
    data_type => 'text',
@@ -21,8 +21,6 @@ column your_mom => {
    is_serializable => 1,
 };
 
-primary_key 'id';
-
 proxy_resultset_method 'id_plus_one';
 
 proxy_resultset_method id_plus_two => {
@@ -0,0 +1,14 @@
+package TestSchema::Result::HasDateOps;
+
+use DBIx::Class::Candy;
+
+table 'HasDateOps';
+
+primary_column id => { data_type => 'int' };;
+column a_date => { data_type => 'datetime' };
+column b_date => {
+   data_type => 'datetime',
+   is_nullable => 1,
+};
+
+1;
@@ -4,9 +4,7 @@ use DBIx::Class::Candy;
 
 table 'Station';
 
-column 'id';
-column 'name';
-
-primary_key 'id';
+primary_column id => { data_type => 'int' };
+column name => { data_type => 'varchar' };
 
 1;
@@ -0,0 +1,11 @@
+package TestSchema::ResultSet::HasDateOps;
+use strict;
+use warnings;
+
+use parent 'TestSchema::ResultSet';
+
+__PACKAGE__->load_components(qw{
+   Helper::ResultSet::DateMethods1
+});
+
+1;
@@ -0,0 +1,20 @@
+-- 
+-- Created by SQL::Translator::Producer::MySQL
+-- Created on Sun Apr  6 11:43:38 2014
+-- 
+SET foreign_key_checks=0;
+
+DROP TABLE IF EXISTS `HasDateOps`;
+
+--
+-- Table: `HasDateOps`
+--
+CREATE TABLE `HasDateOps` (
+  `id` integer NOT NULL,
+  `a_date` datetime NOT NULL,
+  `b_date` datetime NULL,
+  PRIMARY KEY (`id`)
+);
+
+SET foreign_key_checks=1;
+
@@ -0,0 +1,19 @@
+-- 
+-- Created by SQL::Translator::Producer::Oracle
+-- Created on Sun Apr  6 11:43:38 2014
+-- 
+--
+-- Table: HasDateOps
+--;
+
+DROP TABLE "HasDateOps" CASCADE CONSTRAINTS;
+
+CREATE TABLE "HasDateOps" (
+  "id" number NOT NULL,
+  "a_date" date NOT NULL,
+  "b_date" date,
+  PRIMARY KEY ("id")
+);
+
+/
+
@@ -0,0 +1,15 @@
+-- 
+-- Created by SQL::Translator::Producer::PostgreSQL
+-- Created on Sun Apr  6 11:43:38 2014
+-- 
+--
+-- Table: HasDateOps.
+--
+DROP TABLE "HasDateOps" CASCADE;
+CREATE TABLE "HasDateOps" (
+  "id" integer NOT NULL,
+  "a_date" timestamp NOT NULL,
+  "b_date" timestamp,
+  PRIMARY KEY ("id")
+);
+
@@ -0,0 +1,15 @@
+-- 
+-- Created by SQL::Translator::Generator::Role::DDL
+-- Created on Sun Apr  6 11:43:38 2014
+-- 
+
+
+--
+-- Table: [HasDateOps]
+--
+CREATE TABLE [HasDateOps] (
+  [id] int NOT NULL,
+  [a_date] datetime NOT NULL,
+  [b_date] datetime NULL,
+  CONSTRAINT [HasDateOps_pk] PRIMARY KEY ([id])
+);
@@ -0,0 +1,97 @@
+-- 
+-- Created by SQL::Translator::Producer::SQLite
+-- Created on Sun Apr  6 11:43:38 2014
+-- 
+
+BEGIN TRANSACTION;
+
+--
+-- Table: Bloaty
+--
+CREATE TABLE Bloaty (
+  id INTEGER PRIMARY KEY NOT NULL,
+  name varchar NOT NULL,
+  literature text,
+  your_mom blob
+);
+
+--
+-- Table: Gnarly
+--
+CREATE TABLE Gnarly (
+  id INTEGER PRIMARY KEY NOT NULL,
+  name varchar NOT NULL,
+  literature text,
+  your_mom blob
+);
+
+--
+-- Table: HasDateOps
+--
+CREATE TABLE HasDateOps (
+  id INTEGER PRIMARY KEY NOT NULL,
+  a_date datetime NOT NULL,
+  b_date datetime
+);
+
+--
+-- Table: Station
+--
+CREATE TABLE Station (
+  id INTEGER PRIMARY KEY NOT NULL,
+  name varchar NOT NULL
+);
+
+--
+-- Table: Bar
+--
+CREATE TABLE Bar (
+  id INTEGER PRIMARY KEY NOT NULL,
+  foo_id integer NOT NULL,
+  FOREIGN KEY (foo_id) REFERENCES Foo(id) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX Bar_idx_foo_id ON Bar (foo_id);
+
+--
+-- Table: Foo
+--
+CREATE TABLE Foo (
+  id INTEGER PRIMARY KEY NOT NULL,
+  bar_id integer NOT NULL,
+  FOREIGN KEY (bar_id) REFERENCES Bar(id) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX Foo_idx_bar_id ON Foo (bar_id);
+
+--
+-- Table: Foo_Bar
+--
+CREATE TABLE Foo_Bar (
+  foo_id integer NOT NULL,
+  bar_id integer(12) NOT NULL,
+  PRIMARY KEY (foo_id, bar_id),
+  FOREIGN KEY (bar_id) REFERENCES Bar(id),
+  FOREIGN KEY (foo_id) REFERENCES Foo(id)
+);
+
+CREATE INDEX Foo_Bar_idx_bar_id ON Foo_Bar (bar_id);
+
+CREATE INDEX Foo_Bar_idx_foo_id ON Foo_Bar (foo_id);
+
+--
+-- Table: Gnarly_Station
+--
+CREATE TABLE Gnarly_Station (
+  gnarly_id int NOT NULL,
+  station_id int NOT NULL,
+  PRIMARY KEY (gnarly_id, station_id),
+  FOREIGN KEY (gnarly_id) REFERENCES Gnarly(id) ON DELETE CASCADE ON UPDATE CASCADE,
+  FOREIGN KEY (station_id) REFERENCES Station(id) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX Gnarly_Station_idx_gnarly_id ON Gnarly_Station (gnarly_id);
+
+CREATE INDEX Gnarly_Station_idx_station_id ON Gnarly_Station (station_id);
+
+COMMIT;
@@ -20,33 +20,47 @@ __PACKAGE__->load_components(qw(
 sub upgrade_directory { './t/lib' }
 
 sub ddl_filename {
-   return File::Spec->catfile(shift->upgrade_directory, 'ddl.sql');
+   my $self = shift;
+
+   $_[2] = $self->upgrade_directory;
+
+   $self->next::method(@_)
 }
 
 sub deploy_or_connect {
    my $self = shift;
 
-   my $schema = $self->connect;
+   my $schema = $self->connect(@_);
    $schema->deploy();
    return $schema;
 }
 
 sub connect {
    my $self = shift;
-   return $self->next::method('dbi:SQLite::memory:');
+
+   if (@_) {
+      return $self->next::method(@_);
+   } else {
+      return $self->next::method('dbi:SQLite::memory:');
+   }
 }
 
 sub generate_ddl {
    my $self = shift;
    my $schema = $self->connect;
    $schema->create_ddl_dir(
-      'SQLite',
+      $_,
       $schema->schema_version,
-      $self->upgrade_directory,
+      undef,
       undef, {
-         add_drop_table => 0,
+          ($_ ne 'SQLite'
+            ? (
+                add_drop_table => 1,
+                parser_args => { sources => ['HasDateOps'] })
+            : ( add_drop_table => 0 )
+         )
       },
-   );
+   ) for qw(SQLite MySQL PostgreSQL SQLServer Oracle);
 }
 
 sub prepopulate {
@@ -1,92 +0,0 @@
--- 
--- Created by SQL::Translator::Producer::SQLite
--- Created on Fri Feb 14 07:53:23 2014
--- 
-
-BEGIN TRANSACTION;
-
---
--- Table: Bloaty
---
-CREATE TABLE Bloaty (
-  id  NOT NULL,
-  name  NOT NULL,
-  literature text,
-  your_mom blob,
-  PRIMARY KEY (id)
-);
-
---
--- Table: Gnarly
---
-CREATE TABLE Gnarly (
-  id  NOT NULL,
-  name  NOT NULL,
-  literature text,
-  your_mom blob,
-  PRIMARY KEY (id)
-);
-
---
--- Table: Station
---
-CREATE TABLE Station (
-  id  NOT NULL,
-  name  NOT NULL,
-  PRIMARY KEY (id)
-);
-
---
--- Table: Bar
---
-CREATE TABLE Bar (
-  id INTEGER PRIMARY KEY NOT NULL,
-  foo_id  NOT NULL,
-  FOREIGN KEY (foo_id) REFERENCES Foo(id) ON DELETE CASCADE ON UPDATE CASCADE
-);
-
-CREATE INDEX Bar_idx_foo_id ON Bar (foo_id);
-
---
--- Table: Foo
---
-CREATE TABLE Foo (
-  id  NOT NULL,
-  bar_id integer NOT NULL,
-  PRIMARY KEY (id),
-  FOREIGN KEY (bar_id) REFERENCES Bar(id) ON DELETE CASCADE ON UPDATE CASCADE
-);
-
-CREATE INDEX Foo_idx_bar_id ON Foo (bar_id);
-
---
--- Table: Foo_Bar
---
-CREATE TABLE Foo_Bar (
-  foo_id  NOT NULL,
-  bar_id integer(12) NOT NULL,
-  PRIMARY KEY (foo_id, bar_id),
-  FOREIGN KEY (bar_id) REFERENCES Bar(id),
-  FOREIGN KEY (foo_id) REFERENCES Foo(id)
-);
-
-CREATE INDEX Foo_Bar_idx_bar_id ON Foo_Bar (bar_id);
-
-CREATE INDEX Foo_Bar_idx_foo_id ON Foo_Bar (foo_id);
-
---
--- Table: Gnarly_Station
---
-CREATE TABLE Gnarly_Station (
-  gnarly_id integer NOT NULL,
-  station_id integer NOT NULL,
-  PRIMARY KEY (gnarly_id, station_id),
-  FOREIGN KEY (gnarly_id) REFERENCES Gnarly(id) ON DELETE CASCADE ON UPDATE CASCADE,
-  FOREIGN KEY (station_id) REFERENCES Station(id) ON DELETE CASCADE ON UPDATE CASCADE
-);
-
-CREATE INDEX Gnarly_Station_idx_gnarly_id ON Gnarly_Station (gnarly_id);
-
-CREATE INDEX Gnarly_Station_idx_station_id ON Gnarly_Station (station_id);
-
-COMMIT;
@@ -7,9 +7,8 @@ BEGIN {
   }
 }
 
+# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests.
 use Test::More;
-
-eval "use Test::Pod 1.41";
-plan skip_all => "Test::Pod 1.41 required for testing POD" if $@;
+use Test::Pod 1.41;
 
 all_pod_files_ok();
@@ -0,0 +1,78 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More;
+use lib 't/lib';
+use A::ResultSet::DateMethods1;
+
+A::ResultSet::DateMethods1->run_tests(MSSQL => {
+   engine => 'MSSQL',
+   utc_now => 'GETUTCDATE()',
+   stringified_date => '2014-02-08 04:43:00.000',
+
+
+   storage_type => 'MSSQL',
+
+   add_sql_prefix => \[ 'DATEADD(second, CAST(? AS int), [me].[a_date])', 1  ],
+
+   add_sql_by_part_skip => {
+      nanosecond => "doesn't work with DATETIME data type",
+   },
+
+   add_sql_by_part => {
+      day         => \[ 'DATEADD(dayofyear, CAST(? AS int), [a_date])',   1  ],
+      hour        => \[ 'DATEADD(hour, CAST(? AS int), [a_date])',        2  ],
+      millisecond => \[ 'DATEADD(millisecond, CAST(? AS int), [a_date])', 7  ],
+      minute      => \[ 'DATEADD(minute, CAST(? AS int), [a_date])',      3  ],
+      month       => \[ 'DATEADD(month, CAST(? AS int), [a_date])',       4  ],
+      nanosecond  => \[ 'DATEADD(nanosecond, CAST(? AS int), [a_date])',  8  ],
+      quarter     => \[ 'DATEADD(quarter, CAST(? AS int), [a_date])',     9  ],
+      second      => \[ 'DATEADD(second, CAST(? AS int), [a_date])',      5  ],
+      week        => \[ 'DATEADD(week, CAST(? AS int), [a_date])',        10 ],
+      year        => \[ 'DATEADD(year, CAST(? AS int), [a_date])',        6  ],
+   },
+
+   add_sql_by_part_result => {
+      day         => '2012-12-13 00:00:00.000',
+      hour        => '2012-12-12 02:00:00.000',
+      millisecond => '2012-12-12 00:00:00.007',
+      minute      => '2012-12-12 00:03:00.000',
+      month       => '2013-04-12 00:00:00.000',
+      quarter     => '2015-03-12 00:00:00.000',
+      second      => '2012-12-12 00:00:05.000',
+      week        => '2013-02-20 00:00:00.000',
+      year        => '2018-12-12 00:00:00.000',
+   },
+
+   pluck_sql_prefix => \[ q<DATEPART(second, [me].[a_date])> ],
+
+   pluck_sql_by_part => {
+      year                => \[ 'DATEPART(year, [a_date])' ],
+      quarter             => \[ 'DATEPART(quarter, [a_date])' ],
+      month               => \[ 'DATEPART(month, [a_date])' ],
+      day_of_year         => \[ 'DATEPART(dayofyear, [a_date])' ],
+      day_of_month        => \[ 'DATEPART(day, [a_date])' ],
+      week                => \[ 'DATEPART(week, [a_date])' ],
+      day_of_week         => \[ 'DATEPART(ISO_WEEK, [a_date])' ],
+      hour                => \[ 'DATEPART(hour, [a_date])' ],
+      minute              => \[ 'DATEPART(minute, [a_date])' ],
+      second              => \[ 'DATEPART(second, [a_date])' ],
+      millisecond         => \[ 'DATEPART(millisecond, [a_date])' ],
+      nanosecond          => \[ 'DATEPART(nanosecond, [a_date])' ],
+      non_iso_day_of_week => \[ 'DATEPART(weekday, [a_date])' ],
+      timezone_as_minutes => \[ 'DATEPART(TZoffset, [a_date])' ],
+   },
+
+   pluck_sql_by_part_skip => {
+      timezone_as_minutes => 'not supported by DateTime data type',
+   },
+
+   pluck_sql_by_part_result => {
+      millisecond         => 0,
+      nanosecond          => 0,
+      non_iso_day_of_week => 2,
+   },
+});
+
+done_testing;
@@ -0,0 +1,77 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More;
+use lib 't/lib';
+use A::ResultSet::DateMethods1;
+
+A::ResultSet::DateMethods1->run_tests(mysql => {
+   engine => 'mysql',
+   utc_now => 'UTC_TIMESTAMP()',
+   stringified_date => '2014-02-08 04:43:00',
+
+   storage_type => 'mysql',
+
+   pluck_sql_prefix => \[ 'EXTRACT(SECOND FROM `me`.`a_date`)' ],
+
+   pluck_sql_by_part => {
+      microsecond        => \[ 'EXTRACT(MICROSECOND FROM `a_date`)' ],
+      second             => \[ 'EXTRACT(SECOND FROM `a_date`)' ],
+      minute             => \[ 'EXTRACT(MINUTE FROM `a_date`)' ],
+      hour               => \[ 'EXTRACT(HOUR FROM `a_date`)' ],
+      day_of_month       => \[ 'EXTRACT(DAY FROM `a_date`)' ],
+      week               => \[ 'EXTRACT(WEEK FROM `a_date`)' ],
+      month              => \[ 'EXTRACT(MONTH FROM `a_date`)' ],
+      quarter            => \[ 'EXTRACT(QUARTER FROM `a_date`)' ],
+      year               => \[ 'EXTRACT(YEAR FROM `a_date`)' ],
+      second_microsecond => \[ 'EXTRACT(SECOND_MICROSECOND FROM `a_date`)' ],
+      minute_microsecond => \[ 'EXTRACT(MINUTE_MICROSECOND FROM `a_date`)' ],
+      minute_second      => \[ 'EXTRACT(MINUTE_SECOND FROM `a_date`)' ],
+      hour_microsecond   => \[ 'EXTRACT(HOUR_MICROSECOND FROM `a_date`)' ],
+      hour_second        => \[ 'EXTRACT(HOUR_SECOND FROM `a_date`)' ],
+      hour_minute        => \[ 'EXTRACT(HOUR_MINUTE FROM `a_date`)' ],
+      day_microsecond    => \[ 'EXTRACT(DAY_MICROSECOND FROM `a_date`)' ],
+      day_second         => \[ 'EXTRACT(DAY_SECOND FROM `a_date`)' ],
+      day_minute         => \[ 'EXTRACT(DAY_MINUTE FROM `a_date`)' ],
+      day_hour           => \[ 'EXTRACT(DAY_HOUR FROM `a_date`)' ],
+      year_month         => \[ 'EXTRACT(YEAR_MONTH FROM `a_date`)' ],
+   },
+
+   pluck_sql_by_part_result => {
+      microsecond        => 0,
+      second_microsecond => '5000000',
+      minute_microsecond => '405000000',
+      minute_second      => 405,
+      hour_microsecond   => '30405000000',
+      hour_second        => 30405,
+      hour_minute        => 304,
+      day_microsecond    => '2030405000000',
+      day_second         => '2030405',
+      day_minute         => 20304,
+      day_hour           => 203,
+      year_month         => '201201',
+   },
+
+   add_sql_prefix => \[ 'DATE_ADD(`me`.`a_date`, INTERVAL ? SECOND)', 1 ],
+
+   add_sql_by_part => {
+      day         => \[ 'DATE_ADD(`a_date`, INTERVAL ? DAY)',         1 ],
+      hour        => \[ 'DATE_ADD(`a_date`, INTERVAL ? HOUR)',        2 ],
+      microsecond => \[ 'DATE_ADD(`a_date`, INTERVAL ? MICROSECOND)', 7 ],
+      minute      => \[ 'DATE_ADD(`a_date`, INTERVAL ? MINUTE)',      3 ],
+      month       => \[ 'DATE_ADD(`a_date`, INTERVAL ? MONTH)',       4 ],
+      quarter     => \[ 'DATE_ADD(`a_date`, INTERVAL ? QUARTER)',     8 ],
+      second      => \[ 'DATE_ADD(`a_date`, INTERVAL ? SECOND)',      5 ],
+      week        => \[ 'DATE_ADD(`a_date`, INTERVAL ? WEEK)',        9 ],
+      year        => \[ 'DATE_ADD(`a_date`, INTERVAL ? YEAR)',        6 ],
+   },
+
+   add_sql_by_part_result => {
+      microsecond => '2012-12-12 00:00:00.000007',
+      quarter     => '2014-12-12 00:00:00',
+      week        => '2013-02-13 00:00:00',
+   },
+});
+
+done_testing;
@@ -0,0 +1,50 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More;
+use lib 't/lib';
+use A::ResultSet::DateMethods1;
+
+local $SIG{__WARN__} = sub {
+   my $warning = shift;
+
+   return if $warning =~
+      m/DBIx::Class::Storage::DBI::Oracle.*sql_(?:limit_dialect|quote_char)/;
+
+   print STDERR $warning;
+};
+
+A::ResultSet::DateMethods1->run_tests(Oracle => {
+   on_connect_call => 'datetime_setup',
+
+   engine => 'Oracle',
+   utc_now => 'sys_extract_utc(SYSTIMESTAMP)',
+   stringified_date => '2014-02-08 04:43:00',
+
+   storage_type => 'Oracle',
+
+   add_sql_prefix => \[
+      '("me"."a_date" + NUMTODSINTERVAL(?, ?))', 1, 'SECOND',
+    ],
+
+   add_sql_by_part => {
+      day    => \[ '("a_date" + NUMTODSINTERVAL(?, ?))', 1, 'DAY' ],
+      hour   => \[ '("a_date" + NUMTODSINTERVAL(?, ?))', 2, 'HOUR' ],
+      minute => \[ '("a_date" + NUMTODSINTERVAL(?, ?))', 3, 'MINUTE' ],
+      second => \[ '("a_date" + NUMTODSINTERVAL(?, ?))', 5, 'SECOND' ],
+   },
+
+   pluck_sql_prefix => \[ 'EXTRACT(SECOND FROM TO_TIMESTAMP("me"."a_date"))' ],
+
+   pluck_sql_by_part => {
+      second       => \[ 'EXTRACT(SECOND FROM TO_TIMESTAMP("a_date"))' ],
+      minute       => \[ 'EXTRACT(MINUTE FROM TO_TIMESTAMP("a_date"))' ],
+      hour         => \[ 'EXTRACT(HOUR FROM TO_TIMESTAMP("a_date"))' ],
+      day_of_month => \[ 'EXTRACT(DAY FROM "a_date")' ],
+      month        => \[ 'EXTRACT(MONTH FROM "a_date")' ],
+      year         => \[ 'EXTRACT(YEAR FROM "a_date")' ],
+   },
+});
+
+done_testing;
@@ -0,0 +1,84 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More;
+use lib 't/lib';
+use A::ResultSet::DateMethods1;
+
+A::ResultSet::DateMethods1->run_tests(Pg => {
+   engine => 'Pg',
+   utc_now => 'CURRENT_TIMESTAMP',
+   stringified_date => '2014-02-08 04:43:00+0000',
+
+   storage_type => 'Pg',
+
+   add_sql_prefix => \[ q<("me"."a_date" + ? * interval '1 second')>, 1],
+
+   add_sql_by_part => {
+      century     => \[ q<("a_date" + ? * interval '1 century')>,      7  ],
+      day         => \[ q<("a_date" + ? * interval '1 day')>,          1  ],
+      decade      => \[ q<("a_date" + ? * interval '1 decade')>,       8  ],
+      hour        => \[ q<("a_date" + ? * interval '1 hour')>,         2  ],
+      microsecond => \[ q<("a_date" + ? * interval '1 microseconds')>, 9 ],
+      millisecond => \[ q<("a_date" + ? * interval '1 milliseconds')>, 10 ],
+      minute      => \[ q<("a_date" + ? * interval '1 minute')>,       3  ],
+      month       => \[ q<("a_date" + ? * interval '1 month')>,        4  ],
+      second      => \[ q<("a_date" + ? * interval '1 second')>,       5  ],
+      week        => \[ q<("a_date" + ? * interval '1 week')>,         11 ],
+      year        => \[ q<("a_date" + ? * interval '1 year')>,         6  ],
+   },
+
+   add_sql_by_part_result => {
+      century     => '2712-12-12 00:00:00',
+      decade      => '2092-12-12 00:00:00',
+      microsecond => '2012-12-12 00:00:00.000009',
+      millisecond => '2012-12-12 00:00:00.01',
+      week        => '2013-02-27 00:00:00',
+   },
+
+   pluck_sql_prefix => \[ 'date_part(?, "me"."a_date")', 'second' ],
+
+   pluck_sql_by_part => {
+      century             => \[ 'date_part(?, "a_date")', 'century' ],
+      decade              => \[ 'date_part(?, "a_date")', 'decade' ],
+      day_of_month        => \[ 'date_part(?, "a_date")', 'day' ],
+      day_of_week         => \[ 'date_part(?, "a_date")', 'dow' ],
+      day_of_year         => \[ 'date_part(?, "a_date")', 'doy' ],
+      seconds_since_epoch => \[ 'date_part(?, "a_date")', 'epoch' ],
+      hour                => \[ 'date_part(?, "a_date")', 'hour' ],
+      iso_day_of_week     => \[ 'date_part(?, "a_date")', 'isodow' ],
+      iso_year            => \[ 'date_part(?, "a_date")', 'isoyear' ],
+      microsecond         => \[ 'date_part(?, "a_date")', 'microseconds' ],
+      millenium           => \[ 'date_part(?, "a_date")', 'millenium' ],
+      millisecond         => \[ 'date_part(?, "a_date")', 'milliseconds' ],
+      minute              => \[ 'date_part(?, "a_date")', 'minute' ],
+      month               => \[ 'date_part(?, "a_date")', 'month' ],
+      quarter             => \[ 'date_part(?, "a_date")', 'quarter' ],
+      second              => \[ 'date_part(?, "a_date")', 'second' ],
+      timezone            => \[ 'date_part(?, "a_date")', 'timezone' ],
+      timezone_hour       => \[ 'date_part(?, "a_date")', 'timezone_hour' ],
+      timezone_minute     => \[ 'date_part(?, "a_date")', 'timezone_minute' ],
+      week                => \[ 'date_part(?, "a_date")', 'week' ],
+      year                => \[ 'date_part(?, "a_date")', 'year' ],
+   },
+
+   pluck_sql_by_part_skip => {
+      millenium => 'not supported by DateTime data type',
+      timezone => 'not supported by DateTime data type',
+      timezone_hour => 'not supported by DateTime data type',
+      timezone_minute => 'not supported by DateTime data type',
+   },
+
+   pluck_sql_by_part_result => {
+      century             => 21,
+      decade              => 201,
+      seconds_since_epoch => '1325473445',
+      iso_day_of_week     => 1,
+      iso_year            => 2012,
+      microsecond         => '5000000',
+      millisecond         => 5000,
+   },
+});
+
+done_testing;
@@ -0,0 +1,62 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More;
+use lib 't/lib';
+use A::ResultSet::DateMethods1;
+
+A::ResultSet::DateMethods1->run_tests(SQLite => {
+   engine => 'SQLite',
+   utc_now => q<DATETIME('now')>,
+   stringified_date => '2014-02-08 04:43:00',
+
+   plucked_minute => '09',
+   plucked_second => '08',
+
+   connect_info => [ 'dbi:SQLite::memory:' ],
+
+
+   add_sql_prefix => \[ 'DATETIME("me"."a_date", ? || ?)', 1, ' seconds' ],
+
+   add_sql_by_part => {
+      day    => \[ 'DATETIME("a_date", ? || ?)', 1, ' days' ],
+      hour   => \[ 'DATETIME("a_date", ? || ?)', 2, ' hours' ],
+      minute => \[ 'DATETIME("a_date", ? || ?)', 3, ' minutes' ],
+      month  => \[ 'DATETIME("a_date", ? || ?)', 4, ' months' ],
+      second => \[ 'DATETIME("a_date", ? || ?)', 5, ' seconds' ],
+      year   => \[ 'DATETIME("a_date", ? || ?)', 6, ' years' ],
+   },
+
+   pluck_sql_prefix => \[ q<STRFTIME('%S', "me"."a_date")> ],
+
+   pluck_sql_by_part => {
+      year                => \[ q<STRFTIME('%Y', "a_date")> ],
+      month               => \[ q<STRFTIME('%m', "a_date")> ],
+      day_of_month        => \[ q<STRFTIME('%d', "a_date")> ],
+      hour                => \[ q<STRFTIME('%H', "a_date")> ],
+      day_of_year         => \[ q<STRFTIME('%j', "a_date")> ],
+      minute              => \[ q<STRFTIME('%M', "a_date")> ],
+      second              => \[ q<STRFTIME('%S', "a_date")> ],
+      day_of_week         => \[ q<STRFTIME('%w', "a_date")> ],
+      week                => \[ q<STRFTIME('%W', "a_date")> ],
+      julian_day          => \[ q<STRFTIME('%J', "a_date")> ],
+      seconds_since_epoch => \[ q<STRFTIME('%s', "a_date")> ],
+      fractional_seconds  => \[ q<STRFTIME('%f', "a_date")> ],
+   },
+
+   pluck_sql_by_part_result => {
+      month               => '01',
+      day_of_month        => '02',
+      hour                => '03',
+      day_of_year         => '002',
+      minute              => '04',
+      second              => '05',
+      week                => '01',
+      julian_day          => '2455928.627835648',
+      seconds_since_epoch => '1325473445',
+      fractional_seconds  => '05.000',
+   },
+});
+
+done_testing;
@@ -0,0 +1,37 @@
+#!perl
+
+use strict;
+use warnings;
+
+use lib 't/lib';
+use Test::More;
+use Test::Deep;
+
+use TestSchema;
+my $schema = TestSchema->deploy_or_connect();
+$schema->prepopulate;
+
+my $rs = $schema->resultset('Foo');
+
+cmp_deeply
+   [$rs->limited_page(2, 3)->all],
+   [$rs->search({},{ page => 2, rows => 3 })->all],
+   'limited_page works the same';
+
+cmp_deeply
+   [$rs->limited_page({ page => 2, rows => 3 })->all],
+   [$rs->search({},{ page => 2, rows => 3 })->all],
+   'limited_page works the same';
+
+cmp_deeply
+   [$rs->limited_page({ page => 2 })->all],
+   [$rs->search({},{ page => 2 })->all],
+   'limited_page works the same';
+
+cmp_deeply
+   [$rs->limited_page(2)->all],
+   [$rs->limited_page({ page => 2 })->all],
+   'limited_page works the same';
+
+done_testing;
+
@@ -43,9 +43,7 @@ $schema->prepopulate;
       my $g_s_rs = $schema->resultset('Gnarly_Station');
 
       cmp_deeply $g_s_rs->result_source->column_info('gnarly_id'), {
-         data_type => 'integer',
-         is_nullable => 0,
-         is_numeric => 1,
+         data_type => 'int',
       }, 'gnarly_id defaults column info correctly';
 
       is $s_rs->result_source->relationship_info('gnarly_stations')->{class},
@@ -16,7 +16,7 @@ subtest 'null_check_source_auto' => sub {
    local $schema->source('Gnarly')->column_info('literature')->{is_nullable} = 0;
    cmp_deeply [map +{ $_ => $schema->null_check_source_auto($_)->count }, sort $schema->sources], supersetof(
      { Bar => 0 },
-     { Bloaty => undef },
+     { Bloaty => 0 },
      { Foo => 0 },
      { Foo_Bar => 0 },
      { Gnarly => 3 },