From: Matt S Trout Date: Fri, 20 Feb 2009 07:07:46 +0000 (+0000) Subject: revert previous revision X-Git-Tag: v0.08240~89 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=6ffb5be522e752ea1ad2a99d36648535fe30a43b;hp=506558685fcff08dee7bfdf5ab55b70f82d64818 revert previous revision --- diff --git a/Changes b/Changes index 24cd9c6..9bdf1b9 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,15 @@ Revision history for DBIx::Class + - Add DBIC_MULTICREATE_DEBUG env var (undocumented, quasi-internal) + - Fix up multi-create to: + - correctly propagate columns loaded during multi-insert of rels + - not try and insert things tagged on via new_related unless required - Possible to set locale in IC::DateTime extra => {} config + - Calling the accessor of a belongs_to when the foreign_key + was NULL and the row was not stored would unexpectedly fail (groditi) + - Split sql statements for deploy only if SQLT::Producer returned a scalar + containing all statements to be executed + - Add as_query() for ResultSet and ResultSetColumn. This makes subqueries + possible. See the Cookbook for details. (robkinyon, michaelr) 0.08099_06 2009-01-23 07:30:00 (UTC) - Allow a scalarref to be supplied to the 'from' resultset attribute @@ -19,6 +29,7 @@ Revision history for DBIx::Class - PG array datatype supported with SQLA >= 1.50 - insert should use store_column, not set_column to avoid marking clean just-stored values as dirty. New test for this (groditi) + - regression test for source_name (groditi) 0.08099_05 2008-10-30 21:30:00 (UTC) - Rewritte of Storage::DBI::connect_info(), extended with an diff --git a/lib/DBIx/Class.pm b/lib/DBIx/Class.pm index 31c7f12..6ea8116 100644 --- a/lib/DBIx/Class.pm +++ b/lib/DBIx/Class.pm @@ -291,6 +291,8 @@ ribasushi: Peter Rabbitson rjbs: Ricardo Signes +robkinyon: Rob Kinyon + sc_: Just Another Perl Hacker scotty: Scotty Allen diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index f4a5a45..678e173 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -1407,12 +1407,16 @@ passing them as bind values: $resultset->search( { - numbers => \[ '= ?', [1, 2, 3] ] + numbers => \[ '= ?', [numbers => [1, 2, 3]] ] } ); See L and L for more explanation. +placeholders and bind values (subqueries)> for more explanation. Note that +L sets L to C, so you must pass +the bind values (the C<[1, 2, 3]> arrayref in the above example) wrapped in +arrayrefs together with the column name, like this: C<< [column_name => value] +>>. =head1 BOOTSTRAPPING/MIGRATING diff --git a/lib/DBIx/Class/Relationship/Accessor.pm b/lib/DBIx/Class/Relationship/Accessor.pm index dcb906e..6ec2f25 100644 --- a/lib/DBIx/Class/Relationship/Accessor.pm +++ b/lib/DBIx/Class/Relationship/Accessor.pm @@ -31,6 +31,7 @@ sub add_relationship_accessor { $rel_info->{cond}, $rel, $self ); if ($rel_info->{attrs}->{undef_on_null_fk}){ + return unless ref($cond) eq 'HASH'; return if grep { not defined } values %$cond; } my $val = $self->find_related($rel, {}, {}); diff --git a/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm b/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm index 833ffad..76ca7f2 100644 --- a/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm +++ b/lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm @@ -187,17 +187,19 @@ bringing down your entire pool of databases. sub _safely_ensure_connected { my ($self, $replicant, @args) = @_; - my $return; eval { - $return = $replicant->ensure_connected(@args); - }; if ($@) { + eval { + $replicant->ensure_connected(@args); + }; + if ($@) { $replicant - ->debugobj - ->print( - sprintf( "Exception trying to ->ensure_connected for replicant %s, error is %s", - $self->_dbi_connect_info->[0], $@) + ->debugobj + ->print( + sprintf( "Exception trying to ->ensure_connected for replicant %s, error is %s", + $replicant->_dbi_connect_info->[0], $@) ); + return; } - return $return; + return 1; } =head2 connected_replicants diff --git a/t/66relationship.t b/t/66relationship.t index 6a30aa3..0ae02e6 100644 --- a/t/66relationship.t +++ b/t/66relationship.t @@ -8,7 +8,7 @@ use DBICTest; my $schema = DBICTest->init_schema(); -plan tests => 74; +plan tests => 69; # has_a test my $cd = $schema->resultset("CD")->find(4); diff --git a/t/72pg.t b/t/72pg.t index fa67d1c..45e614f 100644 --- a/t/72pg.t +++ b/t/72pg.t @@ -153,7 +153,7 @@ SKIP: { my $count; lives_ok { $count = $schema->resultset('ArrayTest')->search({ - arrayfield => \[ '= ?' => [3, 4] ], #TODO anything less ugly than this? + arrayfield => \[ '= ?' => [arrayfield => [3, 4]] ], #TODO anything less ugly than this? })->count; } 'comparing arrayref to pg array data does not blow up'; is($count, 1, 'comparing arrayref to pg array data gives correct result'); diff --git a/t/86sqlt.t b/t/86sqlt.t index 531a8a3..24d573e 100644 --- a/t/86sqlt.t +++ b/t/86sqlt.t @@ -10,7 +10,7 @@ plan skip_all => 'SQL::Translator required' if $@; my $schema = DBICTest->init_schema; -plan tests => 132; +plan tests => 133; my $translator = SQL::Translator->new( parser_args => { @@ -29,7 +29,7 @@ my $translator = SQL::Translator->new( $schema->source('Track')->sqlt_deploy_callback(sub { my ($self, $sqlt_table) = @_; - if ($sqlt_table->schema->translator->producer_type =~ /SQLite$/ ) { + if ($schema->storage->sqlt_type eq 'SQLite' ) { $sqlt_table->add_index( name => 'track_title', fields => ['title'] ) or die $sqlt_table->error; } diff --git a/t/bindtype_columns.t b/t/bindtype_columns.t index cf0649d..1462d9b 100644 --- a/t/bindtype_columns.t +++ b/t/bindtype_columns.t @@ -21,8 +21,6 @@ my $dbh = $schema->storage->dbh; $dbh->do('DROP TABLE IF EXISTS bindtype_test'); # the blob/clob are for reference only, will be useful when we switch to SQLT and can test Oracle along the way - - # the blob/clob are for reference only, will be useful when we switch to SQLT and can test Oracle along the way $dbh->do(qq[ CREATE TABLE bindtype_test ( @@ -34,21 +32,57 @@ my $dbh = $schema->storage->dbh; ],{ RaiseError => 1, PrintError => 1 }); } +my $big_long_string = "\x00\x01\x02 abcd" x 125000; + +my $new; +# test inserting a row +{ + $new = $schema->resultset('BindType')->create({ bytea => $big_long_string }); + + ok($new->id, "Created a bytea row"); + is($new->bytea, $big_long_string, "Set the blob correctly."); +} + # test retrieval of the bytea column { my $row = $schema->resultset('BindType')->find({ id => $new->id }); is($row->get_column('bytea'), $big_long_string, "Created the blob correctly."); } -my $new = $schema->resultset('BindType')->create({ bytea => $big_long_string }); +TODO: { + local $TODO = + 'Passing bind attributes to $sth->bind_param() should be implemented (it only works in $storage->insert ATM)'; -ok($new->id, "Created a bytea row"); -is($new->bytea, $big_long_string, "Set the blob correctly."); + my $rs = $schema->resultset('BindType')->search({ bytea => $big_long_string }); -my $rs = $schema->resultset('BindType')->find({ id => $new->id }); + # search on the bytea column (select) + { + my $row = $rs->first; + is($row ? $row->id : undef, $new->id, "Found the row searching on the bytea column."); + } -is($rs->get_column('bytea'), $big_long_string, "Created the blob correctly."); + # search on the bytea column (update) + { + my $new_big_long_string = $big_long_string . "2"; + $schema->txn_do(sub { + $rs->update({ bytea => $new_big_long_string }); + my $row = $schema->resultset('BindType')->find({ id => $new->id }); + is($row ? $row->get_column('bytea') : undef, $new_big_long_string, + "Updated the row correctly (searching on the bytea column)." + ); + $schema->txn_rollback; + }); + } -$dbh->do("DROP TABLE bindtype_test"); + # search on the bytea column (delete) + { + $schema->txn_do(sub { + $rs->delete; + my $row = $schema->resultset('BindType')->find({ id => $new->id }); + is($row, undef, "Deleted the row correctly (searching on the bytea column)."); + $schema->txn_rollback; + }); + } +} $dbh->do("DROP TABLE bindtype_test"); diff --git a/t/lib/DBIC/SqlMakerTest.pm b/t/lib/DBIC/SqlMakerTest.pm index 8c2406c..cf33fd9 100644 --- a/t/lib/DBIC/SqlMakerTest.pm +++ b/t/lib/DBIC/SqlMakerTest.pm @@ -7,8 +7,11 @@ use base qw/Test::Builder::Module Exporter/; our @EXPORT = qw/ &is_same_sql_bind + &is_same_sql + &is_same_bind &eq_sql &eq_bind + &eq_sql_bind /; @@ -39,19 +42,59 @@ our @EXPORT = qw/ $tb->ok($same_sql && $same_bind, $msg); if (!$same_sql) { - $tb->diag("SQL expressions differ\n" - . " got: $sql1\n" - . "expected: $sql2\n" - ); + _sql_differ_diag($sql1, $sql2); } if (!$same_bind) { - $tb->diag("BIND values differ\n" - . " got: " . Dumper($bind_ref1) - . "expected: " . Dumper($bind_ref2) - ); + _bind_differ_diag($bind_ref1, $bind_ref2); } } + sub is_same_sql + { + my ($sql1, $sql2, $msg) = @_; + + my $same_sql = eq_sql($sql1, $sql2); + + $tb->ok($same_sql, $msg); + + if (!$same_sql) { + _sql_differ_diag($sql1, $sql2); + } + } + + sub is_same_bind + { + my ($bind_ref1, $bind_ref2, $msg) = @_; + + my $same_bind = eq_bind($bind_ref1, $bind_ref2); + + $tb->ok($same_bind, $msg); + + if (!$same_bind) { + _bind_differ_diag($bind_ref1, $bind_ref2); + } + } + + sub _sql_differ_diag + { + my ($sql1, $sql2) = @_; + + $tb->diag("SQL expressions differ\n" + . " got: $sql1\n" + . "expected: $sql2\n" + ); + } + + sub _bind_differ_diag + { + my ($bind_ref1, $bind_ref2) = @_; + + $tb->diag("BIND values differ\n" + . " got: " . Dumper($bind_ref1) + . "expected: " . Dumper($bind_ref2) + ); + } + sub eq_sql { my ($left, $right) = @_; @@ -68,6 +111,13 @@ our @EXPORT = qw/ return eq_deeply($bind_ref1, $bind_ref2); } + + sub eq_sql_bind + { + my ($sql1, $bind_ref1, $sql2, $bind_ref2) = @_; + + return eq_sql($sql1, $sql2) && eq_bind($bind_ref1, $bind_ref2); + } } eval "use SQL::Abstract::Test;"; @@ -75,14 +125,20 @@ if ($@ eq '') { # SQL::Abstract::Test available *is_same_sql_bind = \&SQL::Abstract::Test::is_same_sql_bind; + *is_same_sql = \&SQL::Abstract::Test::is_same_sql; + *is_same_bind = \&SQL::Abstract::Test::is_same_bind; *eq_sql = \&SQL::Abstract::Test::eq_sql; *eq_bind = \&SQL::Abstract::Test::eq_bind; + *eq_sql_bind = \&SQL::Abstract::Test::eq_sql_bind; } else { # old SQL::Abstract *is_same_sql_bind = \&DBIC::SqlMakerTest::SQLATest::is_same_sql_bind; + *is_same_sql = \&DBIC::SqlMakerTest::SQLATest::is_same_sql; + *is_same_bind = \&DBIC::SqlMakerTest::SQLATest::is_same_bind; *eq_sql = \&DBIC::SqlMakerTest::SQLATest::eq_sql; *eq_bind = \&DBIC::SqlMakerTest::SQLATest::eq_bind; + *eq_sql_bind = \&DBIC::SqlMakerTest::SQLATest::eq_sql_bind; } @@ -131,6 +187,28 @@ comparison of bind values. Compares given and expected pairs of C<($sql, \@bind)>, and calls L on the result, with C<$test_msg> as message. +=head2 is_same_sql + + is_same_sql( + $given_sql, + $expected_sql, + $test_msg + ); + +Compares given and expected SQL statement, and calls L on the +result, with C<$test_msg> as message. + +=head2 is_same_bind + + is_same_bind( + \@given_bind, + \@expected_bind, + $test_msg + ); + +Compares given and expected bind value lists, and calls L on +the result, with C<$test_msg> as message. + =head2 eq_sql my $is_same = eq_sql($given_sql, $expected_sql); @@ -143,6 +221,16 @@ Compares the two SQL statements. Returns true IFF they are equivalent. Compares two lists of bind values. Returns true IFF their values are the same. +=head2 eq_sql_bind + + my $is_same = eq_sql_bind( + $given_sql, \@given_bind, + $expected_sql, \@expected_bind + ); + +Compares the two SQL statements and the two lists of bind values. Returns true +IFF they are equivalent and the bind values are the same. + =head1 SEE ALSO diff --git a/t/lib/sqlite.sql b/t/lib/sqlite.sql index ebc10cd..b364cb4 100644 --- a/t/lib/sqlite.sql +++ b/t/lib/sqlite.sql @@ -1,6 +1,6 @@ -- -- Created by SQL::Translator::Producer::SQLite --- Created on Sat Jan 17 19:40:47 2009 +-- Created on Sat Jan 24 19:42:15 2009 -- BEGIN TRANSACTION; @@ -38,6 +38,18 @@ CREATE TABLE cd_artwork ( CREATE INDEX cd_artwork_idx_cd_id_cd_artwor ON cd_artwork (cd_id); -- +-- Table: artwork_to_artist +-- +CREATE TABLE artwork_to_artist ( + artwork_cd_id integer NOT NULL, + artist_id integer NOT NULL, + PRIMARY KEY (artwork_cd_id, artist_id) +); + +CREATE INDEX artwork_to_artist_idx_artist_id_artwork_to_arti ON artwork_to_artist (artist_id); +CREATE INDEX artwork_to_artist_idx_artwork_cd_id_artwork_to_ ON artwork_to_artist (artwork_cd_id); + +-- -- Table: bindtype_test -- CREATE TABLE bindtype_test (