diff -urb DBIx-Abstract-1.005/Abstract.pm dbix-abstract/Abstract.pm --- DBIx-Abstract-1.005/Abstract.pm 2003-02-17 22:28:48.000000000 -0500 +++ dbix-abstract/Abstract.pm 2004-04-04 19:31:31.000000000 -0400 @@ -1,16 +1,25 @@ -# $Id: dbix-abstract.patch 118 2006-04-13 01:20:06Z fil $ +# $Id: dbix-abstract.patch 118 2006-04-13 01:20:06Z fil $ package DBIx::Abstract; use DBI; -use Scalar::Util 'weaken'; use strict; use vars qw( $AUTOLOAD $VERSION $LAST_CHANGE ); +use vars qw($has_weaken); BEGIN { - $DBIx::Abstract::VERSION = '1.005'; - ($DBIx::Abstract::CVSVERSION) = q$Revision: 118 $ =~ /(\d+\.[\d.]+)/; + eval { + require Scalar::Util; + Scalar::Util->import('weaken'); + }; + $has_weaken=1 unless $@; +} + + +BEGIN { + $DBIx::Abstract::VERSION = '1.006'; + ($DBIx::Abstract::CVSVERSION) = q$Revision: 118 $ =~ /(\d+\.[\d.]+)/; ($DBIx::Abstract::LAST_CHANGE) = - q$Date: 2006-04-12 21:20:06 -0400 (Wed, 12 Apr 2006) $ =~ /(\d+\/\S+ \d+:\S+)/; + q$Date: 2006-04-12 21:20:06 -0400 (Wed, 12 Apr 2006) $ =~ /(\d+\/\S+ \d+:\S+)/; } sub ___drivers { @@ -260,10 +269,11 @@ } else { $newself->{'ORIG'} = $self->{'ORIG'}; } - weaken($newself->{'ORIG'}); + weaken($newself->{'ORIG'}) if $has_weaken; push(@{$newself->{'ORIG'}->{'CLONES'}},$newself); - weaken($newself->{'ORIG'}->{'CLONES'}[$#{$newself->{'ORIG'}->{'CLONES'}}]); + weaken($newself->{'ORIG'}->{'CLONES'}[$#{$newself->{'ORIG'}->{'CLONES'}}]) + if $has_weaken; $self->__logwrite(5,'Cloned'); return $newself; @@ -487,7 +497,11 @@ if (ref($$where{$_}) eq 'ARRAY') { $self->__logwrite(7,'Value is array',@{$$where{$_}}); $ret .= $$where{$_}[0].' '; - if (ref($$where{$_}[1]) eq 'SCALAR') { + if(uc($$where{$_}[0]) eq 'IN' and ref($$where{$_}[1]) eq 'ARRAY') { + $ret .= "(".join(',', map { $self->quote($_)} + @{$$where{$_}[1]}).")"; + } + elsif (ref($$where{$_}[1]) eq 'SCALAR') { $ret .= ${$$where{$_}[1]}; } else { $ret .= '?'; @@ -688,6 +702,16 @@ sub select { my $self = shift; + my($sql, @bind_params)=$self->select2query(@_); + + $self->__logwrite_sql(2,$sql,@bind_params); + $self->__literal_query($sql,@bind_params); + return $self; +} + +sub select2query +{ + my $self=shift; my($fields,$table,$where,$order,$extra) = @_; # $fields == A hash ref with the following values # OR @@ -697,6 +721,7 @@ # $where == One of my handy-dandy standard where's. See __where. # $order == The order to output in my $group;#== The key to group by, only available in hash mode + my $having;#= where clause for the grouped records, only available in hash mode my($sql,@keys,$i,$join); if (ref($fields) eq 'HASH') { my $field; @@ -712,6 +737,7 @@ $group = $$fields{'group'}; $extra = $$fields{'extra'}; $join = $$fields{'join'}; + $having = $$fields{'having'}; $fields = $$fields{'fields'} || $$fields{'field'}; } @@ -746,15 +772,36 @@ } else { $where = []; } - foreach (@{$join}) { - push(@$where,'and') if $#$where>-1; + my $todo=$join; + if(uc($join->[0]) eq 'LEFT') { + $todo=[]; + my($q, $type, $table, $addsql, @b); + for(my $q=0; $q <=$#$join; $q+=3) { + $type=uc $join->[$q]; + unless($type eq 'LEFT' or $type eq 'RIGHT' or + $type eq 'INNER' or $type eq 'CROSS' or + $type eq 'NATURAL') { + push @$todo, $type, $join->[$q+1]; + $q--; + next; + } + $table=$join->[$q+1]; + ($addsql,@b) = $self->__where($join->[$q+2]); + $addsql =~ s/WHERE/ON/; + $sql .= " $type JOIN $table$addsql"; + push @bind_params, @b; + } + } + foreach (@{$todo}) { + push(@$where,'AND') if $#$where>-1; push(@$where, [$_]); } } if (defined($where)) { - ($addsql,@bind_params) = $self->__where($where); + my($addsql,@b) = $self->__where($where); $sql .= $addsql; + push @bind_params, @b; } if (ref($group) eq 'ARRAY') { @@ -765,6 +812,15 @@ $sql .= " GROUP BY $group"; } + if($having) { + my($addsql,@b) = $self->__where($having); + if($addsql) { + $addsql =~ s/WHERE/HAVING/; + $sql .= $addsql; + push @bind_params, @b; + } + } + if (ref($order) eq 'ARRAY') { if ($#$order>-1) { $sql .= ' ORDER BY '.join(',',@$order); @@ -776,10 +832,7 @@ if ($extra) { $sql .= ' '.$extra; } - - $self->__logwrite_sql(2,$sql,@bind_params); - $self->__literal_query($sql,@bind_params); - return $self; + return($sql, @bind_params); } sub select_one_to_hashref { Only in dbix-abstract: Abstract.pm~ Only in dbix-abstract: CVS Only in dbix-abstract: Makefile Only in dbix-abstract: Makefile~ Only in dbix-abstract: blib Only in dbix-abstract/lib: CVS Only in dbix-abstract/lib/Test: CVS Only in dbix-abstract: pm_to_blib diff -urb DBIx-Abstract-1.005/t/2-dbix-abstract.t dbix-abstract/t/2-dbix-abstract.t --- DBIx-Abstract-1.005/t/2-dbix-abstract.t 2003-03-14 19:30:58.000000000 -0500 +++ dbix-abstract/t/2-dbix-abstract.t 2004-04-04 19:31:31.000000000 -0400 @@ -5,7 +5,7 @@ ######################### -use Test::More tests => 28; +use Test::More tests => 31; ######################### @@ -89,6 +89,9 @@ ok( $dbh, "connect w/dbhandle and destroy: Database handle exists"); ok( $dbh->connected(), "connect w/dbhandle and destroy: We are indeed connected." ); + SKIP : { + skip("No weak reference", 1) unless $DBIx::Abstract::has_weaken; + is( @{$dbh->{'CLONES'}}, 0, "no clones yet"); eval { eval { @@ -98,6 +101,7 @@ is( @{$dbh->{'CLONES'}}, 0, "clone cleaned up"); }; ok( ! $@, "clone without error"); + } eval { $dbh->query('create table foo (id int null,name char(30) not null,value char(30) null)'); @@ -158,12 +162,63 @@ }; is($@,'','select with join'); eval { + $dbh->select({ + fields=>'count(foo.id)', + tables=>'foo', + 'join'=>[ 'left', 'bar', + 'foo.id = bar.foo_id', + ], + where=>{'foo.id'=>['<',10]}, + extra=>'LIMIT 1000', + }); + if ($dbh->rows) { + while(@foo = $dbh->fetchrow_array) { $count2 ++ } + } + }; is($@,'','select with left join'); + + $dbh->query('create table bat (honk int null, zip char(30) not null,value char(30) null)'); + $dbh->insert('bat',{honk=>2,zip=>'bar',value=>'zip'}); + $dbh->insert('bat',{honk=>2,zip=>'foo',value=>'honk'}); + $dbh->insert('bat',{honk=>2,zip=>'adf',value=>'flap'}); + $dbh->insert('bat',{honk=>2,zip=>'123',value=>'eek'}); + $dbh->insert('bat',{honk=>2,zip=>'99999',value=>'zipzip'}); + + eval { + $dbh->select({ + fields=>'*', + tables=>'foo', + 'join'=>[ 'left', 'bar', 'foo.id = bar.foo_id', + 'left', 'bat', {'foo.id' => \'bat.honk'} + ], + where=>{'foo.id'=>['<',2]}, + }); + if ($dbh->rows) { + while(@foo = $dbh->fetchrow_array) { $count2 ++ } + } + # warn "count2=$count2"; + }; is($@,'','select with double left join'); + + eval { + $dbh->select({ + fields=>['count(foo.id) AS zoh'], + tables=>'foo', + 'join'=>[ 'left', 'bat', {'foo.id' => \'bat.honk'} ], + group=>['foo.id'], + having=>{'zoh'=>['>',1]} + }); + if($dbh->rows) { + while(@foo = $dbh->fetchrow_array) { $count2 ++ } + } + }; is($@,'','select with left join and having'); + + eval { $dbh->delete('foo',{id=>['like','%']}); }; is((!$@ and $count1==$dbh->rows)?1:0,1,'delete'); eval { $dbh->query('drop table foo'); $dbh->query('drop table bar'); + $dbh->query('drop table bat'); }; ok( !$@,'drop'); ok( $dbh->connected, "verified connection" ); @@ -175,7 +230,9 @@ ok( ! $dbh->connected, "verified disconnection" ); if (open(LOG,'test.log')) { - my @log = ; + # 5.004 has a different hash order, so we don't know which + # option is set first + my @log = grep {!/Option change\tlog/} ; close(LOG); my @data; my $ignore = 0; @@ -184,8 +241,11 @@ $ignore = $1; } elsif ($ignore and /^[^\t]+\t0\t$ignore\tEND\n$/) { $ignore = 0; + } elsif(/Cloned/ and not $DBIx::Abstract::has_weaken) { + # If we don't have a weaken function, cloning doesn't work + # as well, so it's not checked. } elsif (!$ignore) { - push(@data,$_); + push(@data,$_) unless /Option change\tlog/; } } foreach (\@log,\@data) { @@ -200,7 +260,6 @@ } __DATA__ -Mon Feb 17 13:36:46 2003 5 Option change logfile test.log Mon Feb 17 13:36:46 2003 5 Connect driver=>mysqlPP host=> port=> Mon Feb 17 13:36:46 2003 5 connected 0 Mon Feb 17 13:36:46 2003 5 reconnect success @@ -231,14 +290,33 @@ Mon Feb 17 13:36:46 2003 5 rows Mon Feb 17 13:36:46 2003 4 fetchrow_array Mon Feb 17 13:36:46 2003 4 fetchrow_array -Mon Feb 17 13:36:46 2003 2 SELECT count(foo.id) FROM foo,bar WHERE (foo.id < '10') and ( foo.id = bar.foo_id ) GROUP BY bar.name +Mon Feb 17 13:36:46 2003 2 SELECT count(foo.id) FROM foo,bar WHERE (foo.id < '10') AND ( foo.id = bar.foo_id ) GROUP BY bar.name Mon Feb 17 13:36:46 2003 5 rows Mon Feb 17 13:36:46 2003 4 fetchrow_array Mon Feb 17 13:36:46 2003 4 fetchrow_array Mon Feb 17 13:36:46 2003 4 fetchrow_array +Mon Feb 17 13:36:46 2003 2 SELECT count(foo.id) FROM foo LEFT JOIN bar ON foo.id = bar.foo_id WHERE (foo.id < '10') LIMIT 1000 +Mon Feb 17 13:36:46 2003 5 rows +Mon Feb 17 13:36:46 2003 4 fetchrow_array +Mon Feb 17 13:36:46 2003 4 fetchrow_array +Thu Mar 18 22:12:48 2004 3 create table bat (honk int null, zip char(30) not null,value char(30) null) +Thu Mar 18 22:12:48 2004 1 INSERT INTO bat ( zip, honk, value) VALUES ('bar', '2', 'zip') +Thu Mar 18 22:12:48 2004 1 INSERT INTO bat ( zip, honk, value) VALUES ('foo', '2', 'honk') +Thu Mar 18 22:12:48 2004 1 INSERT INTO bat ( zip, honk, value) VALUES ('adf', '2', 'flap') +Thu Mar 18 22:12:48 2004 1 INSERT INTO bat ( zip, honk, value) VALUES ('123', '2', 'eek') +Thu Mar 18 22:12:48 2004 1 INSERT INTO bat ( zip, honk, value) VALUES ('99999', '2', 'zipzip') +Thu Mar 18 22:12:48 2004 2 SELECT * FROM foo LEFT JOIN bar ON foo.id = bar.foo_id LEFT JOIN bat ON foo.id = bat.honk WHERE (foo.id < '2') +Thu Mar 18 22:12:48 2004 5 rows +Thu Mar 18 22:12:48 2004 4 fetchrow_array +Thu Mar 18 22:12:48 2004 4 fetchrow_array +Thu Mar 18 22:12:48 2004 2 SELECT count(foo.id) AS zoh FROM foo LEFT JOIN bat ON foo.id = bat.honk GROUP BY foo.id HAVING zoh > '1' +Thu Mar 18 22:12:48 2004 5 rows +Thu Mar 18 22:12:48 2004 4 fetchrow_array +Thu Mar 18 22:12:48 2004 4 fetchrow_array Mon Feb 17 13:36:46 2003 1 DELETE FROM foo WHERE id like '%' Mon Feb 17 13:36:46 2003 5 rows Mon Feb 17 13:36:46 2003 3 drop table foo Mon Feb 17 13:36:46 2003 3 drop table bar +Mon Feb 17 13:36:46 2003 3 drop table bat Mon Feb 17 13:36:46 2003 5 connected 1 Mon Feb 17 13:36:46 2003 5 connected 0 Only in dbix-abstract/t: 2-dbix-abstract.t~ Only in dbix-abstract/t: CVS diff -urb DBIx-Abstract-1.005/t/dbia.config dbix-abstract/t/dbia.config --- DBIx-Abstract-1.005/t/dbia.config 2003-03-15 01:51:21.000000000 -0500 +++ dbix-abstract/t/dbia.config 2004-04-04 19:31:32.000000000 -0400 @@ -1,11 +1,11 @@ { my $opt = { - 'testdsn' => '', - 'testport' => '', 'testpassword' => '', - 'testhost' => '', - 'testuser' => '', + 'testport' => '', + 'testdsn' => '', 'testdb' => 'test', - 'testdriver' => '' + 'testdriver' => 'mysql', + 'testhost' => '', + 'testuser' => '' }; sub load_all { return ( driver => $opt->{'testdriver'}, Only in dbix-abstract/t: dbia.config~