@@ -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 },