Merge 'trunk' into 'DBIx-Class-current'
Matt S Trout [Thu, 23 Feb 2006 19:27:36 +0000 (19:27 +0000)]
r8098@obrien (orig r958):  ningu | 2006-02-23 11:09:00 +0000
attempt to fix weird overload '0+' bug, modify tests to make sure it works
r8099@obrien (orig r959):  matthewt | 2006-02-23 13:55:52 +0000
Updated Oracle test
r8157@obrien (orig r960):  jesper | 2006-02-23 19:14:42 +0000
Double char quoting implemented, now supports stuff like [] (for MSSQL)

lib/DBIx/Class/Manual/Cookbook.pod
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/Storage/DBI.pm
t/19quotes.t
t/run/13oracle.tl
t/run/16joins.tl

index f287e92..1ab0e31 100644 (file)
@@ -601,4 +601,20 @@ in SQL::Abstract::Limit -documentation.
 The JDBC-bridge is one way of getting access to a MSSQL-server from a platform
 that Microsoft doesn't deliver native client libraries for. (e.g. Linux)
 
+=head2 Setting quotes for the generated SQL. 
+
+If the database contains columnames with spaces and/or reserved words, the
+SQL-query needs to be quoted. This is done using:
+
+  __PACKAGE__->storage->sql_maker->quote_char([ qw/[ ]/] );
+  __PACKAGE__->storage->sql_maker->name_sep('.');
+
+The first sets the quotesymbols. If the quote i "symmetric" as " or '
+  
+  __PACKAGE__->storage->sql_maker->quote_char('"');
+
+is enough. If the left qoute differs form the right quote, the first 
+notation should be used. name_sep needs to be set to allow the 
+SQL generator to put the quotes the correct place. 
+
 =cut
index 09b7868..4ab3389 100644 (file)
@@ -3,7 +3,7 @@ package DBIx::Class::ResultSet;
 use strict;
 use warnings;
 use overload
-        '0+'     => 'count',
+        '0+'     => \&count,
         'bool'   => sub { 1; },
         fallback => 1;
 use Data::Page;
index 492cc91..95673ce 100644 (file)
@@ -145,7 +145,16 @@ sub _join_condition {
 sub _quote {
   my ($self, $label) = @_;
   return '' unless defined $label;
+  return "*" if $label eq '*';
   return $label unless $self->{quote_char};
+  if(ref $self->{quote_char} eq "ARRAY"){
+    return $self->{quote_char}->[0] . $label . $self->{quote_char}->[1]
+      if !defined $self->{name_sep};
+    my $sep = $self->{name_sep};
+    return join($self->{name_sep},
+        map { $self->{quote_char}->[0] . $_ . $self->{quote_char}->[1]  }
+       split(/\Q$sep\E/,$label));
+  }
   return $self->SUPER::_quote($label);
 }
 
@@ -167,6 +176,21 @@ sub limit_dialect {
     return $self->{limit_dialect};
 }
 
+sub quote_char {
+    my $self = shift;
+    $self->{quote_char} = shift if @_;
+    return $self->{quote_char};
+}
+
+sub name_sep {
+    my $self = shift;
+    $self->{name_sep} = shift if @_;
+    return $self->{name_sep};
+}
+
+
+
+
 package DBIx::Class::Storage::DBI::DebugCallback;
 
 sub print {
index 69ba5b5..70c8f8e 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     eval "use DBD::SQLite";
     plan $@
         ? ( skip_all => 'needs DBD::SQLite for testing' )
-        : ( tests => 3 );
+        : ( tests => 4 );
 }
 
 use lib qw(t/lib);
@@ -15,8 +15,8 @@ use_ok('DBICTest');
 
 use_ok('DBICTest::HelperRels');
 
-DBICTest->schema->storage->sql_maker->{'quote_char'} = q!'!;
-DBICTest->schema->storage->sql_maker->{'name_sep'} = '.';
+DBICTest->schema->storage->sql_maker->quote_char("'");
+DBICTest->schema->storage->sql_maker->name_sep('.');
 
 my $rs = DBICTest::CD->search(
            { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
@@ -24,3 +24,14 @@ my $rs = DBICTest::CD->search(
 
 cmp_ok( $rs->count, '==', 1, "join with fields quoted");
 
+DBICTest->schema->storage->sql_maker->quote_char([qw/[ ]/]);
+DBICTest->schema->storage->sql_maker->name_sep('.');
+
+$rs = DBICTest::CD->search(
+           { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
+           { join => 'artist' });
+cmp_ok($rs->count,'==', 1,"join quoted with brackets.");
+
+
+
+
index 42d37d3..278e663 100644 (file)
@@ -4,10 +4,10 @@ my $schema = shift;
 my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_ORA_${_}" } qw/DSN USER PASS/};
 
 plan skip_all, 'Set $ENV{DBICTEST_ORA_DSN}, _USER and _PASS to run this test. ' .
-  'Warning: This test drops and creates a table called \'artist\''
+  'Warning: This test drops and creates tables called \'artist\', \'cd\' and \'track\''
   unless ($dsn && $user && $pass);
 
-plan tests => 4;
+plan tests => 5;
 
 DBICTest::Schema->compose_connection('OraTest' => $dsn, $user, $pass);
 
@@ -16,9 +16,14 @@ my $dbh = OraTest->schema->storage->dbh;
 eval {
   $dbh->do("DROP SEQUENCE artist_seq");
   $dbh->do("DROP TABLE artist");
+  $dbh->do("DROP TABLE cd");
+  $dbh->do("DROP TABLE track");
 };
 $dbh->do("CREATE SEQUENCE artist_seq START WITH 1 MAXVALUE 999999 MINVALUE 0");
 $dbh->do("CREATE TABLE artist (artistid NUMBER(12), name VARCHAR(255))");
+$dbh->do("CREATE TABLE cd (cdid NUMBER(12), artist NUMBER(12), title VARCHAR(255), year VARCHAR(4))");
+$dbh->do("CREATE TABLE track (trackid NUMBER(12), cd NUMBER(12), position NUMBER(12), title VARCHAR(255))");
+
 $dbh->do("ALTER TABLE artist ADD (CONSTRAINT artist_pk PRIMARY KEY (artistid))");
 $dbh->do(qq{
   CREATE OR REPLACE TRIGGER artist_insert_trg
@@ -34,11 +39,24 @@ $dbh->do(qq{
 });
 
 OraTest::Artist->load_components('PK::Auto');
+OraTest::CD->load_components('PK::Auto::Oracle');
+OraTest::Track->load_components('PK::Auto::Oracle');
 
 # test primary key handling
 my $new = OraTest::Artist->create({ name => 'foo' });
 is($new->artistid, 1, "Oracle Auto-PK worked");
 
+# test join with row count ambiguity
+my $cd = OraTest::CD->create({ cdid => 1, artist => 1, title => 'EP C', year => '2003' });
+my $track = OraTest::Track->create({ trackid => 1, cd => 1, position => 1, title => 'Track1' });
+my $tjoin = OraTest::Track->search({ 'me.title' => 'Track1'},
+        { join => 'cd',
+          rows => 2 }
+);
+
+is($tjoin->next->title, 'Track1', "ambiguous column ok");
+
+
 # test LIMIT support
 for (1..6) {
     OraTest::Artist->create({ name => 'Artist ' . $_ });
@@ -57,6 +75,8 @@ is( $it->next, undef, "next past end of resultset ok" );
 # clean up our mess
 $dbh->do("DROP SEQUENCE artist_seq");
 $dbh->do("DROP TABLE artist");
+$dbh->do("DROP TABLE cd");
+$dbh->do("DROP TABLE track");
 
 }
 
index efab7b1..091cf74 100644 (file)
@@ -73,7 +73,7 @@ my $rs = $schema->resultset("CD")->search(
                          ] ] }
          );
 
-cmp_ok( $rs->count, '==', 1, "Single record in resultset");
+cmp_ok( $rs + 0, '==', 1, "Single record in resultset");
 
 is($rs->first->title, 'Forkful of bees', 'Correct record returned');
 
@@ -81,7 +81,7 @@ $rs = $schema->resultset("CD")->search(
            { 'year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
            { join => 'artist' });
 
-cmp_ok( $rs->count, '==', 1, "Single record in resultset");
+cmp_ok( $rs + 0, '==', 1, "Single record in resultset");
 
 is($rs->first->title, 'Forkful of bees', 'Correct record returned');
 
@@ -90,7 +90,7 @@ $rs = $schema->resultset("CD")->search(
              'liner_notes.notes' => 'Kill Yourself!' },
            { join => [ qw/artist liner_notes/ ] });
 
-cmp_ok( $rs->count, '==', 1, "Single record in resultset");
+cmp_ok( $rs + 0, '==', 1, "Single record in resultset");
 
 is($rs->first->title, 'Come Be Depressed With Us', 'Correct record returned');
 
@@ -114,7 +114,7 @@ $rs = $schema->resultset("CD")->search(
            { prefetch => [ qw/artist liner_notes/ ],
              order_by => 'me.cdid' });
 
-cmp_ok($rs->count, '==', 3, 'Correct number of records returned');
+cmp_ok($rs + 0, '==', 3, 'Correct number of records returned');
 
 # start test for prefetch SELECT count
 unlink 't/var/dbic.trace' if -e 't/var/dbic.trace';