>table(\"foo") now works
Rafael Kitover [Sun, 28 Jun 2009 21:24:47 +0000 (21:24 +0000)]
lib/DBIx/Class/ResultSourceProxy/Table.pm
lib/DBIx/Class/SQLAHacks.pm
t/19quotes_newstyle.t
t/99dbic_sqlt_parser.t
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Schema/CDTableRef.pm [new file with mode: 0644]

index 5cfe4f3..11c0ea4 100644 (file)
@@ -75,7 +75,8 @@ Gets or sets the table name.
 sub table {
   my ($class, $table) = @_;
   return $class->result_source_instance->name unless $table;
-  unless (ref $table) {
+
+  unless (Scalar::Util::blessed($table) && $table->isa($class->table_class)) {
     $table = $class->table_class->new({
         $class->can('result_source_instance') ?
           %{$class->result_source_instance||{}} : (),
index a454cd5..92f36a2 100644 (file)
@@ -163,12 +163,10 @@ sub select {
 
   $self->{"${_}_bind"} = [] for (qw/having from order/);
 
-  if (ref $table eq 'SCALAR') {
-    $table = $$table;
-  }
-  elsif (not ref $table) {
+  if (not ref($table) or ref($table) eq 'SCALAR') {
     $table = $self->_quote($table);
   }
+
   local $self->{rownum_hack_count} = 1
     if (defined $rest[0] && $self->{limit_dialect} eq 'RowNum');
   @rest = (-1) unless defined $rest[0];
@@ -192,7 +190,7 @@ sub select {
 sub insert {
   my $self = shift;
   my $table = shift;
-  $table = $self->_quote($table) unless ref($table);
+  $table = $self->_quote($table);
 
   # SQLA will emit INSERT INTO $table ( ) VALUES ( )
   # which is sadly understood only by MySQL. Change default behavior here,
@@ -207,14 +205,14 @@ sub insert {
 sub update {
   my $self = shift;
   my $table = shift;
-  $table = $self->_quote($table) unless ref($table);
+  $table = $self->_quote($table);
   $self->SUPER::update($table, @_);
 }
 
 sub delete {
   my $self = shift;
   my $table = shift;
-  $table = $self->_quote($table) unless ref($table);
+  $table = $self->_quote($table);
   $self->SUPER::delete($table, @_);
 }
 
@@ -410,6 +408,7 @@ sub _join_condition {
 sub _quote {
   my ($self, $label) = @_;
   return '' unless defined $label;
+  return $$label if ref($label) eq 'SCALAR';
   return "*" if $label eq '*';
   return $label unless $self->{quote_char};
   if(ref $self->{quote_char} eq "ARRAY"){
index f0c34a9..01a8c77 100644 (file)
@@ -11,7 +11,7 @@ BEGIN {
     eval "use DBD::SQLite";
     plan $@
         ? ( skip_all => 'needs DBD::SQLite for testing' )
-        : ( tests => 7 );
+        : ( tests => 8 );
 }
 
 use_ok('DBICTest');
@@ -46,6 +46,17 @@ is_same_sql_bind(
   'got correct SQL for count query with quoting'
 );
 
+# try with ->table(\'cd') should NOT be quoted
+$rs = $schema->resultset('CDTableRef')->search(
+           { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
+           { join => 'artist' });
+eval { $rs->count };
+is_same_sql_bind(
+  $sql, \@bind,
+  "SELECT COUNT( * ) FROM cd `me`  JOIN `artist` `artist` ON ( `artist`.`artistid` = `me`.`artist` ) WHERE ( `artist`.`name` = ? AND `me`.`year` = ? )", ["'Caterwauler McCrae'", "'2001'"],
+  'got correct SQL for count query with quoting'
+);
+
 my $order = 'year DESC';
 $rs = $schema->resultset('CD')->search({},
             { 'order_by' => $order });
index 9968a82..d95f698 100644 (file)
@@ -16,6 +16,7 @@ BEGIN {
 my $schema = DBICTest->init_schema();
 # Dummy was yanked out by the sqlt hook test
 # YearXXXXCDs are views
+
 my @sources = grep { $_ ne 'Dummy' && $_ !~ /^Year\d{4}CDs$/ } 
                 $schema->sources;
 
@@ -25,7 +26,7 @@ plan tests => ( @sources * 3);
        my $sqlt_schema = create_schema({ schema => $schema, args => { parser_args => { } } });
 
        foreach my $source (@sources) {
-               my $table = $sqlt_schema->get_table($schema->source($source)->from);
+               my $table = get_table($sqlt_schema, $schema, $source);
 
                my $fk_count = scalar(grep { $_->type eq 'FOREIGN KEY' } $table->get_constraints);
                my @indices = $table->get_indices;
@@ -39,7 +40,7 @@ plan tests => ( @sources * 3);
        my $sqlt_schema = create_schema({ schema => $schema, args => { parser_args => { add_fk_index => 1 } } });
 
        foreach my $source (@sources) {
-               my $table = $sqlt_schema->get_table($schema->source($source)->from);
+               my $table = get_table($sqlt_schema, $schema, $source);
 
                my $fk_count = scalar(grep { $_->type eq 'FOREIGN KEY' } $table->get_constraints);
                my @indices = $table->get_indices;
@@ -53,7 +54,7 @@ plan tests => ( @sources * 3);
        my $sqlt_schema = create_schema({ schema => $schema, args => { parser_args => { add_fk_index => 0 } } });
 
        foreach my $source (@sources) {
-               my $table = $sqlt_schema->get_table($schema->source($source)->from);
+               my $table = get_table($sqlt_schema, $schema, $source);
 
                my @indices = $table->get_indices;
                my $index_count = scalar(@indices);
@@ -79,3 +80,12 @@ sub create_schema {
        $sqlt->parser('SQL::Translator::Parser::DBIx::Class');
        return $sqlt->translate({ data => $schema }) or die $sqlt->error;
 }
+
+sub get_table {
+    my ($sqlt_schema, $schema, $source) = @_;
+
+    my $table_name = $schema->source($source)->from;
+    $table_name    = $$table_name if ref $table_name;
+
+    return $sqlt_schema->get_table($table_name);
+}
index b03d090..b9521ef 100644 (file)
@@ -11,6 +11,7 @@ __PACKAGE__->load_classes(qw/
   BindType
   Employee
   CD
+  CDTableRef
   FileColumn
   Genre
   Link
diff --git a/t/lib/DBICTest/Schema/CDTableRef.pm b/t/lib/DBICTest/Schema/CDTableRef.pm
new file mode 100644 (file)
index 0000000..b29fb3f
--- /dev/null
@@ -0,0 +1,89 @@
+package # hide from PAUSE 
+    DBICTest::Schema::CDTableRef;
+
+use base qw/DBICTest::BaseResult/;
+
+__PACKAGE__->table(\'cd');
+
+__PACKAGE__->add_columns(
+  'cdid' => {
+    data_type => 'integer',
+    is_auto_increment => 1,
+  },
+  'artist' => {
+    data_type => 'integer',
+  },
+  'title' => {
+    data_type => 'varchar',
+    size      => 100,
+  },
+  'year' => {
+    data_type => 'varchar',
+    size      => 100,
+  },
+  'genreid' => { 
+    data_type => 'integer',
+    is_nullable => 1,
+  },
+  'single_track' => {
+    data_type => 'integer',
+    is_nullable => 1,
+    is_foreign_key => 1,
+  }
+);
+__PACKAGE__->set_primary_key('cdid');
+__PACKAGE__->add_unique_constraint([ qw/artist title/ ]);
+
+__PACKAGE__->belongs_to( artist => 'DBICTest::Schema::Artist',
+  'artist', { 
+    is_deferrable => 1, 
+});
+
+# in case this is a single-cd it promotes a track from another cd
+__PACKAGE__->belongs_to( single_track => 'DBICTest::Schema::Track', 'single_track', 
+    { join_type => 'left'} 
+);
+
+__PACKAGE__->has_many( tracks => 'DBICTest::Schema::Track', 'cd' );
+__PACKAGE__->has_many(
+    tags => 'DBICTest::Schema::Tag', 'cd',
+    { order_by => 'tag' },
+);
+__PACKAGE__->has_many(
+    cd_to_producer => 'DBICTest::Schema::CD_to_Producer' => 'cd'
+);
+
+__PACKAGE__->might_have(
+    liner_notes => 'DBICTest::Schema::LinerNotes', undef,
+    { proxy => [ qw/notes/ ] },
+);
+__PACKAGE__->might_have(artwork => 'DBICTest::Schema::Artwork', 'cd_id');
+
+__PACKAGE__->many_to_many( producers => cd_to_producer => 'producer' );
+__PACKAGE__->many_to_many(
+    producers_sorted => cd_to_producer => 'producer',
+    { order_by => 'producer.name' },
+);
+
+__PACKAGE__->belongs_to('genre', 'DBICTest::Schema::Genre',
+    { 'foreign.genreid' => 'self.genreid' },
+    {
+        join_type => 'left',
+        on_delete => 'SET NULL',
+        on_update => 'CASCADE',
+    },
+);
+
+#This second relationship was added to test the short-circuiting of pointless
+#queries provided by undef_on_null_fk. the relevant test in 66relationship.t
+__PACKAGE__->belongs_to('genre_inefficient', 'DBICTest::Schema::Genre',
+    { 'foreign.genreid' => 'self.genreid' },
+    {
+        join_type => 'left',
+        on_delete => 'SET NULL',
+        on_update => 'CASCADE',
+        undef_on_null_fk => 0,
+    },
+);
+
+1;