Merge 'trunk' into 'DBIx-Class-current'
Matt S Trout [Tue, 14 Feb 2006 15:40:54 +0000 (15:40 +0000)]
r6092@obrien (orig r892):  ningu | 2006-02-12 19:35:58 +0000
- put last change in trunk
r6094@obrien (orig r894):  matthewt | 2006-02-13 15:37:06 +0000
- fix up 14mssql.tl
r6095@obrien (orig r895):  scotty | 2006-02-13 16:28:12 +0000
added check to skip tests that break on SQLite < 3.2.6 due to SQLite not understanding COUNT(DISTINCT())
r6096@obrien (orig r896):  matthewt | 2006-02-13 17:19:01 +0000
fixes for columns_info_for stuff from zby
r6097@obrien (orig r897):  scotty | 2006-02-13 17:47:32 +0000
added myself to the contributors list
r6098@obrien (orig r898):  marcus | 2006-02-13 19:59:46 +0000
prepared for release.
r6099@obrien (orig r899):  dwc | 2006-02-13 20:31:35 +0000
For sqlite version checks
r6100@obrien (orig r900):  scotty | 2006-02-13 21:20:08 +0000
removed version.pm dependancy
r6101@obrien (orig r901):  dwc | 2006-02-13 21:28:21 +0000
Prepping for release
r6103@obrien (orig r903):  ningu | 2006-02-13 21:58:30 +0000
- fix Changes file
r6104@obrien (orig r904):  marcus | 2006-02-13 22:13:17 +0000
another fix for group_by as scalar.
r6105@obrien (orig r905):  marcus | 2006-02-13 22:14:23 +0000
and changes
r6107@obrien (orig r907):  blblack | 2006-02-14 06:01:10 +0000
storage fix for fork() and workaround for Apache::DBI

Changes
MANIFEST
lib/DBIx/Class.pm
lib/DBIx/Class/AccessorGroup.pm
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Storage/DBI.pm
t/run/01core.tl
t/run/14mssql.tl
t/run/16joins.tl

diff --git a/Changes b/Changes
index 0d5904d..e200673 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,8 +1,16 @@
 Revision history for DBIx::Class
 
+       - Another fix for count with scalar group_by.
+
+0.05005 2006-02-13 21:24:51
+        - remove build dependency on version.pm
+
+0.05004 2006-02-13 20:59:00
+        - allow specification of related columns via cols attr when primary 
+          keys of the related table are not fetched
+        - fix count for group_by as scalar
         - add horrific fix to make Oracle's retarded limit syntax work
-        - changed UUIDColumns to use new UUIDMaker classes for uuid creation
-        using whatever module may be available
+        - remove Carp require
 
 0.05003 2006-02-08 17:50:20
         - add component_class accessors and use them for *_class
index ff271fb..44bd794 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -96,6 +96,7 @@ t/19quotes.t
 t/20setuperrors.t
 t/30dbicplain.t
 t/40resultsetmanager.t
+t/41orrible.t
 t/basicrels/01core.t
 t/basicrels/04db.t
 t/basicrels/05multipk.t
index dab9d2c..855f0b4 100644 (file)
@@ -13,7 +13,7 @@ sub component_base_class { 'DBIx::Class' }
 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
 # brain damage and presumably various other packaging systems too
 
-$VERSION = '0.05003';
+$VERSION = '0.05005';
 
 sub MODIFY_CODE_ATTRIBUTES {
     my ($class,$code,@attrs) = @_;
@@ -160,7 +160,7 @@ Jesper Krogh
 
 Brandon Black
 
-Christopher H. Laco
+Scotty Allen <scotty@scottyallen.com>
 
 =head1 LICENSE
 
index 4e42b27..dd99da3 100644 (file)
@@ -122,7 +122,6 @@ sub make_group_wo_accessor {
 
         unless (@_) {
             my $caller = caller;
-            require Carp;
             croak("'$caller' cannot access the value of '$field' on ".
                         "objects of class '$class'");
         }
index 3ded443..e8c020a 100644 (file)
@@ -424,14 +424,14 @@ sub count {
     my $group_by;
     my $select = { 'count' => '*' };
     if( $group_by = delete $self->{attrs}{group_by} ) {
-      my @distinct = @$group_by;
+      my @distinct = (ref $group_by ?  @$group_by : ($group_by));
       # todo: try CONCAT for multi-column pk
       my @pk = $self->result_source->primary_columns;
       if( scalar(@pk) == 1 ) {
         my $pk = shift(@pk);
         my $alias = $self->{attrs}{alias};
         my $re = qr/^($alias\.)?$pk$/;
-        foreach my $column ( @$group_by ) {
+        foreach my $column ( @distinct) {
           if( $column =~ $re ) {
             @distinct = ( $column );
             last;
index c8341de..7270b5f 100644 (file)
@@ -41,6 +41,7 @@ sub new {
   $new->{_columns} = { %{$new->{_columns}||{}} };
   $new->{_relationships} = { %{$new->{_relationships}||{}} };
   $new->{name} ||= "!!NAME NOT SET!!";
+  $new->{_columns_info_loaded} ||= 0;
   return $new;
 }
 
@@ -108,8 +109,11 @@ sub column_info {
   my ($self, $column) = @_;
   $self->throw_exception("No such column $column") 
     unless exists $self->_columns->{$column};
-  if ( (! $self->_columns->{$column}->{data_type})
+  #warn $self->{_columns_info_loaded}, "\n";
+  if ( ! $self->_columns->{$column}->{data_type} 
+       && ! $self->{_columns_info_loaded} 
        && $self->schema && $self->storage() ){
+      $self->{_columns_info_loaded}++;
       my $info;
 ############ eval for the case of storage without table 
       eval{
index 14cc4ab..578735e 100644 (file)
@@ -167,7 +167,8 @@ use base qw/DBIx::Class/;
 __PACKAGE__->load_components(qw/AccessorGroup/);
 
 __PACKAGE__->mk_group_accessors('simple' =>
-  qw/connect_info _dbh _sql_maker debug debugfh cursor on_connect_do transaction_depth/);
+  qw/connect_info _dbh _sql_maker _connection_pid debug debugfh cursor
+     on_connect_do transaction_depth/);
 
 sub new {
   my $new = bless({}, ref $_[0] || $_[0]);
@@ -256,6 +257,8 @@ sub ensure_connected {
 sub dbh {
   my ($self) = @_;
 
+  $self->_dbh(undef)
+    if $self->_connection_pid && $self->_connection_pid != $$;
   $self->ensure_connected;
   return $self->_dbh;
 }
@@ -281,11 +284,22 @@ sub _populate_dbh {
   foreach my $sql_statement (@{$self->on_connect_do || []}) {
     $self->_dbh->do($sql_statement);
   }
+
+  $self->_connection_pid($$);
 }
 
 sub _connect {
   my ($self, @info) = @_;
-  return DBI->connect(@info);
+
+  if ($INC{'Apache/DBI.pm'} && $ENV{MOD_PERL}) {
+      my $old_connect_via = $DBI::connect_via;
+      $DBI::connect_via = 'connect';
+      my $dbh = DBI->connect(@info);
+      $DBI::connect_via = $old_connect_via;
+      return $dbh;
+  }
+
+  DBI->connect(@info);
 }
 
 =head2 txn_begin
@@ -340,6 +354,7 @@ sub _execute {
       $self->debugfh->print("$sql: @debug_bind\n");
   }
   my $sth = $self->sth($sql,$op);
+  croak "no sth generated via sql: $sql" unless $sth;
   @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
   my $rv;
   if ($sth) {  
index 412ac8f..34c9b9c 100644 (file)
@@ -1,7 +1,7 @@
 sub run_tests {
 my $schema = shift;
 
-plan tests => 38; 
+plan tests => 39; 
 
 my @art = $schema->resultset("Artist")->search({ }, { order_by => 'name DESC'});
 
@@ -152,6 +152,9 @@ $schema->source("Artist")->{_columns}{'artistid'} = {};
 
 my $typeinfo = $schema->source("Artist")->column_info('artistid');
 is($typeinfo->{data_type}, 'INTEGER', 'column_info ok');
+$schema->source("Artist")->column_info('artistid');
+ok($schema->source("Artist")->{_columns_info_loaded} == 1, 'Columns info flag set');
+
 }
 
 1;
index a6eb5b2..5dcc2bc 100644 (file)
@@ -1,48 +1,48 @@
 sub run_tests {
-my $schema = shift;\r
-\r
-my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MSSQL_${_}" } qw/DSN USER PASS/};\r
-\r
-#warn "$dsn $user $pass";\r
-\r
-plan skip_all, 'Set $ENV{DBICTEST_MSSQL_DSN}, _USER and _PASS to run this test'\r
-  unless ($dsn);\r
-\r
-plan tests => 4;\r
-\r
-$schema->resultset("Schema")->compose_connection( 'MSSQLTest' => $dsn, $user, $pass );\r
-\r
-my $dbh = MSSQLTest->schema->storage->dbh;\r
-\r
-$dbh->do("IF OBJECT_ID('artist', 'U') IS NOT NULL\r
-    DROP TABLE artist");\r
-\r
-$dbh->do("CREATE TABLE artist (artistid INT IDENTITY PRIMARY KEY, name VARCHAR(255));");\r
-\r
-MSSQLTest::Artist->load_components('PK::Auto');\r
-\r
-# Test PK\r
-my $new = MSSQLTest::Artist->create( { name => 'foo' } );\r
-ok($new->artistid, "Auto-PK worked");\r
-\r
-# Test LIMIT\r
-for (1..6) {\r
-    MSSQLTest::Artist->create( { name => 'Artist ' . $_ } );\r
-}\r
-\r
-my $it = MSSQLTest::Artist->search( { },\r
-    { rows     => 3,\r
-      offset   => 2,\r
-      order_by => 'artistid'\r
-    }\r
-);\r
-\r
-is( $it->count, 3, "LIMIT count ok" );\r
-is( $it->next->name, "Artist 2", "iterator->next ok" );\r
-$it->next;\r
-$it->next;\r
-is( $it->next, undef, "next past end of resultset ok" );\r
-\r
-}\r
-\r
-1;\r
+my $schema = shift;
+
+my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MSSQL_${_}" } qw/DSN USER PASS/};
+
+#warn "$dsn $user $pass";
+
+plan skip_all, 'Set $ENV{DBICTEST_MSSQL_DSN}, _USER and _PASS to run this test'
+  unless ($dsn);
+
+plan tests => 4;
+
+$schema->compose_connection( 'MSSQLTest' => $dsn, $user, $pass );
+
+my $dbh = MSSQLTest->schema->storage->dbh;
+
+$dbh->do("IF OBJECT_ID('artist', 'U') IS NOT NULL
+    DROP TABLE artist");
+
+$dbh->do("CREATE TABLE artist (artistid INT IDENTITY PRIMARY KEY, name VARCHAR(255));");
+
+MSSQLTest::Artist->load_components('PK::Auto::MSSQL');
+
+# Test PK
+my $new = MSSQLTest::Artist->create( { name => 'foo' } );
+ok($new->artistid, "Auto-PK worked");
+
+# Test LIMIT
+for (1..6) {
+    MSSQLTest::Artist->create( { name => 'Artist ' . $_ } );
+}
+
+my $it = MSSQLTest::Artist->search( { },
+    { rows     => 3,
+      offset   => 2,
+      order_by => 'artistid'
+    }
+);
+
+is( $it->count, 3, "LIMIT count ok" );
+is( $it->next->name, "Artist 2", "iterator->next ok" );
+$it->next;
+$it->next;
+is( $it->next, undef, "next past end of resultset ok" );
+
+}
+
+1;
index a3c9383..b9ebeb4 100644 (file)
@@ -10,6 +10,18 @@ BEGIN {
         : ( tests => 41 );
 }
 
+# figure out if we've got a version of sqlite that is older than 3.2.6, in
+# which case COUNT(DISTINCT()) doesn't work
+my $is_broken_sqlite = 0;
+my ($sqlite_major_ver,$sqlite_minor_ver,$sqlite_patch_ver) =
+    split /\./, $schema->storage->dbh->get_info(18);
+if( $schema->storage->dbh->get_info(17) eq 'SQLite' &&
+    ( ($sqlite_major_ver < 3) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver < 2) ||
+      ($sqlite_major_ver == 3 && $sqlite_minor_ver == 2 && $sqlite_patch_ver < 6) ) ) {
+    $is_broken_sqlite = 1;
+}
+
 # test the abstract join => SQL generator
 my $sa = new DBIC::SQL::Abstract;
 
@@ -222,7 +234,11 @@ $rs = $schema->resultset("CD")->search(
   { group_by => [qw/ title me.cdid /] }
 );
 
-cmp_ok( $rs->count, '==', 5, "count() ok after group_by on main pk" );
+SKIP: {
+    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
+        if $is_broken_sqlite;
+    cmp_ok( $rs->count, '==', 5, "count() ok after group_by on main pk" );
+}
 
 cmp_ok( scalar $rs->all, '==', 5, "all() returns same count as count() after group_by on main pk" );
 
@@ -231,7 +247,11 @@ $rs = $schema->resultset("CD")->search(
   { join => [qw/ artist /], group_by => [qw/ artist.name /] }
 );
 
-cmp_ok( $rs->count, '==', 3, "count() ok after group_by on related column" );
+SKIP: {
+    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
+        if $is_broken_sqlite;
+    cmp_ok( $rs->count, '==', 3, "count() ok after group_by on related column" );
+}
 
 cmp_ok( scalar $rs->all, '==', 3, "all() returns same count as count() after group_by on related column" );
 
@@ -240,7 +260,12 @@ $rs = $schema->resultset("Artist")->search(
           'cds_2.title' => 'Forkful of bees' },
         { join => [ 'cds', 'cds' ] });
 
-cmp_ok($rs->count, '==', 1, "single artist returned from multi-join");
+SKIP: {
+    skip "SQLite < 3.2.6 doesn't understand COUNT(DISTINCT())", 1
+        if $is_broken_sqlite;
+    cmp_ok($rs->count, '==', 1, "single artist returned from multi-join");
+}
+
 is($rs->next->name, 'Caterwauler McCrae', "Correct artist returned");
 
 my $queries;