@@ -1,3 +1,16 @@
+0.36
+ - Fix the bug that the following feature which is add to 0.35 don't work.
+ add join attribute to DBIx::Custom::Where
+ to add join infomartion to select method
+0.35
+ - remove EXPERIMENTAL status the following.
+ add select method column option syntax
+ {__MY__ => '*'}
+ - remove EXPERIMENTAL last_sql attribute
+ - add join attribute to DBIx::Custom::Where
+ to add join infomartion to select method
+0.34
+ - (EXPERIMENTAL) fix async select not getting err bug.
0.33
- (EXPERIMENTAL) fix MySQL async insert result.
0.32
@@ -1,6 +1,4 @@
Changes
-DBIx-Custom-0.31/META.json
-DBIx-Custom-0.31/META.yml
lib/DBIx/Custom.pm
lib/DBIx/Custom/Mapper.pm
lib/DBIx/Custom/Model.pm
@@ -108,7 +106,6 @@ t/common_uc/MyModel8/TABLE1.pm
t/common_uc/MyModel8/TABLE2.pm
t/create_fullqualified_module.pl
t/create_uppercase_module.pl
-t/mysql-async-opt-insert.t
t/mysql-async-opt.t
t/mysql-async.t
t/mysql.t
@@ -4,7 +4,7 @@
"Yuki Kimoto <kimoto.yuki@gmail.com>"
],
"dynamic_config" : 1,
- "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112150",
+ "generated_by" : "ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.131560",
"license" : [
"perl_5"
],
@@ -22,12 +22,12 @@
"prereqs" : {
"build" : {
"requires" : {
- "ExtUtils::MakeMaker" : 0
+ "ExtUtils::MakeMaker" : "0"
}
},
"configure" : {
"requires" : {
- "ExtUtils::MakeMaker" : 0
+ "ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
@@ -35,10 +35,10 @@
"DBD::SQLite" : "1.25",
"DBI" : "1.605",
"Object::Simple" : "3.1",
- "Test::More" : 0
+ "Test::More" : "0"
}
}
},
"release_status" : "stable",
- "version" : "0.33"
+ "version" : "0.36"
}
@@ -7,7 +7,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112150'
+generated_by: 'ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.131560'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -22,4 +22,4 @@ requires:
DBI: 1.605
Object::Simple: 3.1
Test::More: 0
-version: 0.33
+version: 0.36
@@ -4,7 +4,7 @@
"Yuki Kimoto <kimoto.yuki@gmail.com>"
],
"dynamic_config" : 0,
- "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112150",
+ "generated_by" : "ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.131560",
"license" : [
"perl_5"
],
@@ -22,12 +22,12 @@
"prereqs" : {
"build" : {
"requires" : {
- "ExtUtils::MakeMaker" : 0
+ "ExtUtils::MakeMaker" : "0"
}
},
"configure" : {
"requires" : {
- "ExtUtils::MakeMaker" : 0
+ "ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
@@ -35,10 +35,10 @@
"DBD::SQLite" : "1.25",
"DBI" : "1.605",
"Object::Simple" : "3.1",
- "Test::More" : 0
+ "Test::More" : "0"
}
}
},
"release_status" : "stable",
- "version" : "0.33"
+ "version" : "0.36"
}
@@ -7,7 +7,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 0
-generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112150'
+generated_by: 'ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.131560'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -22,4 +22,4 @@ requires:
DBI: 1.605
Object::Simple: 3.1
Test::More: 0
-version: 0.33
+version: 0.36
@@ -9,8 +9,10 @@ use overload '""' => sub { shift->to_string }, fallback => 1;
# Carp trust relationship
push @DBIx::Custom::CARP_NOT, __PACKAGE__;
-has [qw/dbi param/],
- clause => sub { [] };
+has 'dbi';
+has 'param';
+has clause => sub { [] };
+has 'join';
sub new {
my $self = shift->SUPER::new(@_);
@@ -239,6 +241,15 @@ If all parameter names is exists.
L<DBIx::Custom> object.
+=head2 join
+
+ my $join = $where->join;
+ $join = $where->join($join);
+
+join information. This values is addd to select method C<join> option values.
+
+ $where->join(['left join author on book.author = authro.id']);
+
=head1 METHODS
L<DBIx::Custom::Where> inherits all methods from L<Object::Simple>
@@ -2,7 +2,7 @@ use 5.008007;
package DBIx::Custom;
use Object::Simple -base;
-our $VERSION = '0.33';
+our $VERSION = '0.36';
use Carp 'croak';
use DBI;
@@ -19,7 +19,6 @@ use DBIx::Custom::NotExists;
use Encode qw/encode encode_utf8 decode_utf8/;
use Scalar::Util qw/weaken/;
-
has [qw/connector dsn default_schema password quote user exclude_table user_table_info
user_column_info safety_character/],
async_conf => sub { {} },
@@ -69,7 +68,6 @@ has [qw/connector dsn default_schema password quote user exclude_table user_tabl
stash => sub { {} };
has mytable_symbol => '__MY__';
-has 'last_sth';
sub available_datatype {
my $self = shift;
@@ -371,7 +369,7 @@ sub execute {
my $new_dbi = bless {%$self}, ref $self;
$new_dbi->connector(undef);
$new_dbi->{dbh} = DBI->connect($dsn, $user, $password,
- {%{$new_dbi->default_option}, %$option});
+ {%{$new_dbi->default_option}, %$option, PrintError => 0, RaiseError => 0});
$new_dbi->{_new_connection} = 1;
return $new_dbi->execute($sql, defined $params ? ($params) : (), %opt);
@@ -593,10 +591,7 @@ sub execute {
}
# Affected of insert, update, or delete
- $self->last_sth($sth);
if (!$sth->{NUM_OF_FIELDS} && $opt{statement} ne 'select') {
- my $driver = $self->_driver;
-
# Non-Blocking
if (my $cb = $opt{async}) {
require AnyEvent;
@@ -606,6 +601,7 @@ sub execute {
poll => 'w',
cb => sub {
my $affected;
+ my $driver = $self->_driver;
if ($driver eq 'mysql') {
$affected = $sth->mysql_async_result;
}
@@ -656,6 +652,12 @@ sub execute {
fh => $self->async_conf->{fh}->($self),
poll => 'r',
cb => sub {
+ my $error;
+ my $driver = $self->_driver;
+ if ($driver eq 'mysql') {
+ $sth->mysql_async_result;
+ }
+
$cb->($self, $result);
undef $watcher;
undef $result;
@@ -1154,7 +1156,22 @@ sub select {
unshift @$tables, @{$self->_search_tables($w->{clause})};
# Join statement
- $self->_push_join(\$sql, $opt{join}, $tables) if defined $opt{join};
+ my $join = [];
+ if (defined $opt{join}) {
+ my $opt_join = $opt{join};
+ if (ref $opt_join eq 'ARRAY') {
+ push @$join, @$opt_join;
+ }
+ else { push @$join, $opt_join }
+ }
+ if (defined $w->{join}) {
+ my $where_join = $w->{join};
+ if (ref $where_join eq 'ARRAY') {
+ push @$join, @$where_join;
+ }
+ else { push @$join, $where_join }
+ }
+ $self->_push_join(\$sql, $join, $tables) if @$join;
# Add where clause
$sql .= "$w->{clause} ";
@@ -1690,11 +1707,6 @@ sub _option {
sub _push_join {
my ($self, $sql, $join, $join_tables) = @_;
- $join = [$join] unless ref $join eq 'ARRAY';
-
- # No join
- return unless @$join;
-
# Push join clause
my $tree = {};
for (my $i = 0; $i < @$join; $i++) {
@@ -1853,6 +1865,7 @@ sub _where_clause_and_param {
$w->{param} = keys %$where_param
? $self->merge_param($where_param, $obj->param)
: $obj->param;
+ $w->{join} = $obj->{join};
}
elsif ($where) {
$w->{clause} = "where $where";
@@ -2423,12 +2436,6 @@ Filters, registered by C<register_filter> method.
Get last succeeded SQL executed by C<execute> method.
-=head2 (EXPERIMENTAL) last_sth
-
- my $last_sth = $dbi->last_sth;
-
-Get last executed statement handle.
-
=head2 now
my $now = $dbi->now;
@@ -3768,10 +3775,10 @@ You can use this in insert statement.
=head2 where
- my $where = $dbi->where(
- clause => ['and', 'title = :title', 'author = :author'],
- param => {title => 'Perl', author => 'Ken'}
- );
+ my $where = $dbi->where;
+ $where->clause(['and', 'title = :title', 'author = :author']);
+ $where->param({title => 'Perl', author => 'Ken'});
+ $where->join(['left join author on book.author = author.id]);
Create a new L<DBIx::Custom::Where> object.
See L<DBIx::Custom::Where> to know how to create where clause.
@@ -3523,16 +3523,6 @@ test 'DBIX_CUSTOM_TAG_PARSE environment variable';
delete$ENV{DBIX_CUSTOM_TAG_PARSE};
}
-test 'last_sql';
-$dbi = DBIx::Custom->connect;
-eval { $dbi->execute("drop table $table1") };
-$dbi->execute($create_table1);
-$dbi->execute("select * from $table1");
-is($dbi->last_sql, " select * from $table1");
-
-eval{$dbi->execute("aaa")};
-is($dbi->last_sql, ' aaa');
-
test 'DBIx::Custom header';
$dbi = DBIx::Custom->connect;
eval { $dbi->execute("drop table $table1") };
@@ -5077,4 +5067,59 @@ $result = $dbi->execute(
);
like($result->one->{$key1}, qr/^2010-01-01/);
-1;
+# DBIx::Custom::Where join
+{
+ my $dbi = DBIx::Custom->connect;
+ eval { $dbi->execute("drop table $table1") };
+ $dbi->execute($create_table1);
+ $dbi->insert({$key1 => 1, $key2 => 2}, table => $table1);
+ $dbi->insert({$key1 => 3, $key2 => 4}, table => $table1);
+ eval { $dbi->execute("drop table $table2") };
+ $dbi->execute($create_table2);
+ $dbi->insert({$key1 => 1, $key3 => 5}, table => $table2);
+ eval { $dbi->execute("drop table $table3") };
+ $dbi->execute("create table $table3 ($key3 int, $key4 int)");
+ $dbi->insert({$key3 => 5, $key4 => 4}, table => $table3);
+
+ {
+ my $where = $dbi->where;
+ $where->param({$key1 => 1});
+ $where->clause(":${key1}{=}");
+ $where->join(["left outer join $table3 on $table2.$key3 = $table3.$key3"]);
+
+ my $rows = $dbi->select(
+ table => $table1,
+ where => $where,
+ join => ["left outer join $table2 on $table1.$key1 = $table2.$key1"]
+ )->all;
+ is_deeply($rows, [{$key1 => 1, $key2 => 2}]);
+ }
+ {
+ my $where = $dbi->where;
+ $where->param({"$table1.$key1" => 1});
+ $where->clause(":$table1.${key1}{=}");
+ $where->join(["left outer join $table3 on $table2.$key3 = $table3.$key3"]);
+
+ my $rows = $dbi->select(
+ column => "$table3.$key4 as " . u2("${table3}__$key4"),
+ table => $table1,
+ where => $where,
+ join => ["left outer join $table2 on $table1.$key1 = $table2.$key1"]
+ )->all;
+ is_deeply($rows, [{u2"${table3}__$key4" => 4}]);
+ }
+ {
+ my $where = $dbi->where;
+ $where->param({"$table3.$key4" => 4});
+ $where->clause(":$table3.${key4}{=}");
+ $where->join(["left outer join $table3 on $table2.$key3 = $table3.$key3"]);
+
+ my $rows = $dbi->select(
+ column => "$table1.$key1 as " . u2("${table1}__$key1"),
+ table => $table1,
+ where => $where,
+ join => ["left outer join $table2 on $table1.$key1 = $table2.$key1"]
+ )->all;
+ is_deeply($rows, [{u2"${table1}__$key1" => 1}]);
+ }
+}
@@ -1,61 +0,0 @@
-use Test::More;
-use strict;
-use warnings;
-use utf8;
-
-use FindBin;
-use DBIx::Custom;
-
-my $dbi;
-my $dsn;
-my $args;
-my $user = 'dbix_custom';
-my $password = 'dbix_custom';
-my $database = 'dbix_custom';
-
-$dsn = "dbi:mysql:database=$database";
-$args = {dsn => $dsn, user => $user, password => $password,};
-
-plan skip_all => 'mysql private test' unless -f "$FindBin::Bin/run/mysql-async-opt-insert.run"
- && eval { $dbi = DBIx::Custom->connect($args); 1 };
-plan 'no_plan';
-
-$SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /DEPRECATED/};
-
-# Function for test name
-sub test { print "# $_[0]\n" }
-
-$dbi = DBIx::Custom->connect(
- dsn => "dbi:mysql:database=$database;",
- user => $user,
- password => $password
-);
-
-eval { $dbi->do('drop table table1') };
-$dbi->do('create table table1 (key1 varchar(255), key2 varchar(255)) engine=InnoDB');
-
-test 'async test';
-
-require AnyEvent;
-
-my $cond = AnyEvent->condvar;
-
-$dbi->async_conf({
- prepare_attr => {async => 1},
- fh => sub { shift->dbh->mysql_fd }
-});
-
-$dbi->insert(
- {key1 => 1, key2 => 2},
- table => 'table1',
- async => sub {
- my ($dbi, $affected) = @_;
- is($affected, 1);
- $cond->send;
- }
-);
-
-$cond->recv;
-
-my $rows = $dbi->select(table => 'table1')->all;
-is_deeply($rows, [{key1 => 1, key2 => 2}]);
@@ -56,46 +56,104 @@ test 'async test';
require AnyEvent;
-my $cond = AnyEvent->condvar;
-
-my $timer = AnyEvent->timer(
- interval => 1,
- cb => sub {
- 1;
- }
-);
-
-my $count = 0;
-
$dbi->async_conf({
prepare_attr => {async => 1},
fh => sub { shift->dbh->mysql_fd }
});
-$dbi->execute('SELECT SLEEP(1), 3', undef,
- select => 1,
- async => sub {
- my ($dbi, $result) = @_;
- my $row = $result->fetch_one;
- is($row->[1], 3, 'before');
- $cond->send if ++$count == 2;
- }
-);
-
-$dbi->select('key1', table => 'table1',
- async => sub {
- my ($dbi, $result) = @_;
- my $row = $result->fetch_one;
- is($row->[0], 1, 'after1');
- $dbi->select('key1', table => 'table1',
- async => sub {
- my ($dbi, $result) = @_;
- my $row = $result->fetch_one;
- is($row->[0], 1, 'after2');
- $cond->send if ++$count == 2;
- }
- )
- }
-);
-
-$cond->recv;
+# Select
+{
+ my $cond = AnyEvent->condvar;
+
+ my $timer = AnyEvent->timer(
+ interval => 1,
+ cb => sub {
+ 1;
+ }
+ );
+
+ my $count = 0;
+
+ $dbi->execute('SELECT SLEEP(1), 3', undef,
+ select => 1,
+ async => sub {
+ my ($dbi, $result) = @_;
+ my $row = $result->fetch_one;
+ is($row->[1], 3, 'before');
+ ok(!$dbi->errstr);
+ $cond->send if ++$count == 2;
+ }
+ );
+
+ $dbi->select('key1', table => 'table1',
+ async => sub {
+ my ($dbi, $result) = @_;
+ my $row = $result->fetch_one;
+ is($row->[0], 1, 'after1');
+ $dbi->select('key1', table => 'table1',
+ async => sub {
+ my ($dbi, $result) = @_;
+ my $row = $result->fetch_one;
+ is($row->[0], 1, 'after2');
+ $cond->send if ++$count == 2;
+ }
+ )
+ }
+ );
+
+ $cond->recv;
+}
+
+# Select error
+{
+ my $cond = AnyEvent->condvar;
+ $dbi->select('key1', table => 'table_not_exists',
+ async => sub {
+ my ($dbi, $result) = @_;
+ ok($dbi->errstr);
+ $cond->send;
+ }
+ );
+
+ $cond->recv;
+}
+
+# insert
+{
+ $dbi->do('delete from table1');
+ my $cond = AnyEvent->condvar;
+
+ $dbi->insert(
+ {key1 => 1, key2 => 2},
+ table => 'table1',
+ async => sub {
+ my ($dbi, $affected) = @_;
+ is($affected, 1);
+ ok(!$dbi->errstr);
+ $cond->send;
+ }
+ );
+
+ $cond->recv;
+
+ my $rows = $dbi->select(table => 'table1')->all;
+ is_deeply($rows, [{key1 => 1, key2 => 2}]);
+}
+
+# insert error
+{
+ $dbi->do('delete from table1');
+ my $cond = AnyEvent->condvar;
+
+ $dbi->insert(
+ {key1 => 1, key2 => 2},
+ table => 'table_not_exists',
+ async => sub {
+ my ($dbi, $affected) = @_;
+ ok($dbi->errstr);
+ $cond->send;
+ }
+ );
+
+ $cond->recv;
+}