[Bps-public-commit] dbix-searchbuilder branch, date-time-interval, created. 1.63-21-g99c09ee
Ruslan Zakirov
ruz at bestpractical.com
Fri Mar 8 17:29:36 EST 2013
The branch, date-time-interval has been created
at 99c09ee4838e3b69378c1e5db9231848ce1b4b6e (commit)
- Log -----------------------------------------------------------------
commit 99c09ee4838e3b69378c1e5db9231848ce1b4b6e
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Fri Mar 8 22:45:15 2013 +0400
Handle->DateTimeIntervalFunction method
generates function call that calcs difference between
two dates in seconds.
diff --git a/MANIFEST b/MANIFEST
index 44fbeb1..88a42c0 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -44,6 +44,7 @@ t/02distinct_values.t
t/02order_outer.t
t/02records_cachable.t
t/02records_datetime.t
+t/02records_dt_interval.t
t/02records_integers.t
t/02records_object.t
t/02searches_joins.t
diff --git a/lib/DBIx/SearchBuilder/Handle.pm b/lib/DBIx/SearchBuilder/Handle.pm
index ba0ddff..818b4a1 100755
--- a/lib/DBIx/SearchBuilder/Handle.pm
+++ b/lib/DBIx/SearchBuilder/Handle.pm
@@ -1593,6 +1593,22 @@ sub ConvertTimezoneFunction {
return $args{'Field'};
}
+=head2 DateTimeIntervalFunction
+
+Generates a function to calculate interval in seconds between two
+dates. Takes From and To arguments which can be either scalar or
+a hash. Hash is processed with L<DBIx::SearchBuilder/CombineFunctionWithField>.
+
+Arguments are not quoted or escaped in any way. It's caller's job.
+
+=cut
+
+sub DateTimeIntervalFunction {
+ my $self = shift;
+ my %args = ( From => undef, To => undef, @_ );
+ return 'NULL';
+}
+
=head2 DESTROY
diff --git a/lib/DBIx/SearchBuilder/Handle/Oracle.pm b/lib/DBIx/SearchBuilder/Handle/Oracle.pm
index ad49eee..0b96d55 100755
--- a/lib/DBIx/SearchBuilder/Handle/Oracle.pm
+++ b/lib/DBIx/SearchBuilder/Handle/Oracle.pm
@@ -435,6 +435,17 @@ sub ConvertTimezoneFunction {
return "FROM_TZ( CAST ($args{'Field'} AS TIMESTAMP), $args{'From'}) AT TIME ZONE $args{'To'}";
}
+sub DateTimeIntervalFunction {
+ my $self = shift;
+ my %args = ( From => undef, To => undef, @_ );
+
+ my ($from, $to) = @args{'From', 'To'};
+ $_ = DBIx::SearchBuilder->CombineFunctionWithField(%$_)
+ for grep ref, $from, $to;
+
+ return "ROUND(( CAST( $to AS DATE ) - CAST( $from AS DATE ) ) * 86400)";
+}
+
1;
__END__
diff --git a/lib/DBIx/SearchBuilder/Handle/Pg.pm b/lib/DBIx/SearchBuilder/Handle/Pg.pm
index df32079..49a6333 100755
--- a/lib/DBIx/SearchBuilder/Handle/Pg.pm
+++ b/lib/DBIx/SearchBuilder/Handle/Pg.pm
@@ -325,6 +325,17 @@ sub ConvertTimezoneFunction {
return $res;
}
+sub DateTimeIntervalFunction {
+ my $self = shift;
+ my %args = ( From => undef, To => undef, @_ );
+
+ my ($from, $to) = @args{'From', 'To'};
+ $_ = DBIx::SearchBuilder->CombineFunctionWithField(%$_)
+ for grep ref, $from, $to;
+
+ return "EXTRACT(EPOCH FROM AGE($to, $from))";
+}
+
1;
__END__
diff --git a/lib/DBIx/SearchBuilder/Handle/SQLite.pm b/lib/DBIx/SearchBuilder/Handle/SQLite.pm
index b7985cb..e58843a 100644
--- a/lib/DBIx/SearchBuilder/Handle/SQLite.pm
+++ b/lib/DBIx/SearchBuilder/Handle/SQLite.pm
@@ -209,6 +209,17 @@ sub ConvertTimezoneFunction {
return $res;
}
+sub DateTimeIntervalFunction {
+ my $self = shift;
+ my %args = ( From => undef, To => undef, @_ );
+
+ my ($from, $to) = @args{'From', 'To'};
+ $_ = DBIx::SearchBuilder->CombineFunctionWithField(%$_)
+ for grep ref, $from, $to;
+
+ return "strftime('%s',$to) - strftime('%s',$from)";
+}
+
1;
__END__
diff --git a/lib/DBIx/SearchBuilder/Handle/mysql.pm b/lib/DBIx/SearchBuilder/Handle/mysql.pm
index 5c56ca9..b488dde 100755
--- a/lib/DBIx/SearchBuilder/Handle/mysql.pm
+++ b/lib/DBIx/SearchBuilder/Handle/mysql.pm
@@ -282,6 +282,17 @@ sub ConvertTimezoneFunction {
return "CONVERT_TZ( $args{'Field'}, $args{'From'}, $args{'To'} )";
}
+sub DateTimeIntervalFunction {
+ my $self = shift;
+ my %args = ( From => undef, To => undef, @_ );
+
+ my ($from, $to) = @args{'From', 'To'};
+ $_ = DBIx::SearchBuilder->CombineFunctionWithField(%$_)
+ for grep ref, $from, $to;
+
+ return "TIMESTAMPDIFF(SECOND, $from, $to)";
+}
+
1;
__END__
diff --git a/t/02records_dt_interval.t b/t/02records_dt_interval.t
new file mode 100644
index 0000000..ce0e6f3
--- /dev/null
+++ b/t/02records_dt_interval.t
@@ -0,0 +1,185 @@
+#!/usr/bin/perl -w
+
+BEGIN { $ENV{'TZ'} = 'Europe/Moscow' };
+
+use strict;
+use warnings;
+use Test::More;
+BEGIN { require "t/utils.pl" }
+our (@AvailableDrivers);
+
+use constant TESTS_PER_DRIVER => 15;
+
+my $total = scalar(@AvailableDrivers) * TESTS_PER_DRIVER;
+plan tests => $total;
+
+my $handle;
+
+foreach my $d ( @AvailableDrivers ) {
+SKIP: {
+ unless( has_schema( 'TestApp', $d ) ) {
+ skip "No schema for '$d' driver", TESTS_PER_DRIVER;
+ }
+ unless( should_test( $d ) ) {
+ skip "ENV is not defined for driver '$d'", TESTS_PER_DRIVER;
+ }
+
+ $handle = get_handle( $d );
+ connect_handle( $handle );
+ isa_ok($handle->dbh, 'DBI::db');
+
+ diag "testing $d" if $ENV{'TEST_VERBOSE'};
+
+ my $ret = init_schema( 'TestApp', $handle );
+ isa_ok($ret,'DBI::st', "Inserted the schema. got a statement handle back");
+
+ my $count_all = init_data( 'TestApp::User', $handle );
+ ok( $count_all, "init users data" );
+
+ my $users = TestApp::Users->new( $handle );
+ $users->UnLimit;
+ $users->Column( FIELD => 'Result' );
+ my $column = $users->Column(
+ FUNCTION => $users->_Handle->DateTimeIntervalFunction( From => 'Created', To => 'Resolved' ),
+ );
+
+ while ( my $user = $users->Next ) {
+ is $user->__Value( $column ), $user->Result;
+ }
+
+ $users = TestApp::Users->new( $handle );
+ $users->UnLimit;
+ $users->Column( FIELD => 'Result' );
+ $column = $users->Column(
+ FUNCTION => $users->_Handle->DateTimeIntervalFunction(
+ From => { FIELD => 'Created' }, To => { FIELD => 'Resolved' },
+ ),
+ );
+
+ while ( my $user = $users->Next ) {
+ is $user->__Value( $column ), $user->Result;
+ }
+
+ cleanup_schema( 'TestApp', $handle );
+}} # SKIP, foreach blocks
+
+1;
+
+package TestApp;
+
+sub schema_mysql {
+<<EOF;
+CREATE TEMPORARY TABLE Users (
+ id integer AUTO_INCREMENT,
+ Created DATETIME NULL,
+ Resolved DATETIME NULL,
+ Result integer NULL,
+ PRIMARY KEY (id)
+)
+EOF
+
+}
+
+sub schema_pg {
+<<EOF;
+CREATE TEMPORARY TABLE Users (
+ id serial PRIMARY KEY,
+ Created TIMESTAMP NULL,
+ Resolved TIMESTAMP NULL,
+ Result integer NULL
+)
+EOF
+
+}
+
+sub schema_sqlite {
+
+<<EOF;
+CREATE TABLE Users (
+ id integer primary key,
+ Created TEXT NULL,
+ Resolved TEXT NULL,
+ Result integer NULL
+)
+EOF
+
+}
+
+sub schema_oracle { [
+ "CREATE SEQUENCE Users_seq",
+ "CREATE TABLE Users (
+ id integer CONSTRAINT Users_Key PRIMARY KEY,
+ Created DATE NULL,
+ Resolved DATE NULL,
+ Result integer NULL
+ )",
+] }
+
+sub cleanup_schema_oracle { [
+ "DROP SEQUENCE Users_seq",
+ "DROP TABLE Users",
+] }
+
+
+1;
+
+package TestApp::User;
+
+use base $ENV{SB_TEST_CACHABLE}?
+ qw/DBIx::SearchBuilder::Record::Cachable/:
+ qw/DBIx::SearchBuilder::Record/;
+
+sub _Init {
+ my $self = shift;
+ my $handle = shift;
+ $self->Table('Users');
+ $self->_Handle($handle);
+}
+
+sub _ClassAccessible {
+ {
+ id =>
+ {read => 1, type => 'int(11)' },
+ Created =>
+ {read => 1, write => 1, type => 'datetime' },
+ Resolved =>
+ {read => 1, write => 1, type => 'datetime' },
+ Result =>
+ {read => 1, type => 'int(11)' },
+ }
+}
+
+sub init_data {
+ return (
+ [ 'Created', 'Resolved', 'Result' ],
+ [ undef, undef , undef ],
+ [ undef , '2011-05-20 19:53:23', undef ],
+ [ '2011-05-20 19:53:23', undef , undef ],
+ [ '2011-05-20 19:53:23', '2011-05-20 19:53:23', 0],
+ [ '2011-05-20 19:53:23', '2011-05-21 20:54:24', 1*24*60*60+1*60*60+1*60+1],
+ [ '2011-05-20 19:53:23', '2011-05-19 18:52:22', -(1*24*60*60+1*60*60+1*60+1)],
+ );
+}
+
+1;
+
+package TestApp::Users;
+
+# use TestApp::User;
+use base qw/DBIx::SearchBuilder/;
+
+sub _Init {
+ my $self = shift;
+ $self->SUPER::_Init( Handle => shift );
+ $self->Table('Users');
+}
+
+sub NewItem
+{
+ my $self = shift;
+ return TestApp::User->new( $self->_Handle );
+}
+
+1;
+
+
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list