Fixed documentation and added test for the "Arbitrary SQL through a custom ResultSour...
Norbert Buchmuller [Tue, 21 Jul 2009 05:58:12 +0000 (07:58 +0200)]
lib/DBIx/Class/Manual/Cookbook.pod
t/bind/attribute.t
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Schema/CustomSql.pm [new file with mode: 0644]

index 2e3e984..b534435 100644 (file)
@@ -145,13 +145,12 @@ that you cannot modify the rows it contains, ie. cannot call L</update>,
 L</delete>, ...  on it).
 
 If you prefer to have the definitions of these custom ResultSources in separate
-files (instead of stuffing all of them into the same resultset class), you can
-achieve the same with subclassing the resultset class and defining the
-ResultSource there:
+files (instead of stuffing all of them into the same ResultSource class), you
+can achieve the same with subclassing the ResultSource class and defining the
+new SQL ResultSource there:
 
   package My::Schema::Result::UserFriendsComplex;
 
-  use My::Schema::Result::User;
   use base qw/My::Schema::Result::User/;
 
   __PACKAGE__->table('dummy');  # currently must be called before anything else
@@ -159,7 +158,7 @@ ResultSource there:
   # Hand in your query as a scalar reference
   # It will be added as a sub-select after FROM,
   # so pay attention to the surrounding brackets!
-  __PACKAGE__->name( \<<SQL );
+  __PACKAGE__->result_source_instance->name( \<<SQL );
   ( SELECT u.* FROM user u
   INNER JOIN user_friends f ON u.id = f.user_id
   WHERE f.friend_user_id = ?
@@ -169,6 +168,8 @@ ResultSource there:
   WHERE f.user_id = ? )
   SQL
 
+  1;
+
 TIMTOWDI.
 
 =head2 Using specific columns
index b9946a4..1a1d0c7 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
     eval "use DBD::SQLite";
     plan $@
         ? ( skip_all => 'needs DBD::SQLite for testing' )
-        : ( tests => 9 );
+        : ( tests => 13 );
 }
 
 my $where_bind = {
@@ -45,34 +45,34 @@ TODO: {
     is ( $rs->count, 1, 'where/bind last' );
 }
 
-# More complex cases, based primarily on the Cookbook
-# "Arbitrary SQL through a custom ResultSource" technique,
-# which seems to be the only place the bind attribute is
-# documented.  Breaking this technique probably breaks existing
-# application code.
-my $source = DBICTest::Artist->result_source_instance;
-my $new_source = $source->new($source);
-$new_source->source_name('Complex');
+{
+  # More complex cases, based primarily on the Cookbook
+  # "Arbitrary SQL through a custom ResultSource" technique,
+  # which seems to be the only place the bind attribute is
+  # documented.  Breaking this technique probably breaks existing
+  # application code.
+  my $source = DBICTest::Artist->result_source_instance;
+  my $new_source = $source->new($source);
+  $new_source->source_name('Complex');
 
-$new_source->name(\<<'');
-( SELECT a.*, cd.cdid AS cdid, cd.title AS title, cd.year AS year 
-  FROM artist a
-  JOIN cd ON cd.artist = a.artistid
-  WHERE cd.year = ?)
+  $new_source->name(\<<'');
+  ( SELECT a.*, cd.cdid AS cdid, cd.title AS title, cd.year AS year 
+    FROM artist a
+    JOIN cd ON cd.artist = a.artistid
+    WHERE cd.year = ?)
 
-$schema->register_extra_source('Complex' => $new_source);
+  $schema->register_extra_source('Complex' => $new_source);
 
-$rs = $schema->resultset('Complex')->search({}, { bind => [ 1999 ] });
-is ( $rs->count, 1, 'cookbook arbitrary sql example' );
+  $rs = $schema->resultset('Complex')->search({}, { bind => [ 1999 ] });
+  is ( $rs->count, 1, 'cookbook arbitrary sql example' );
 
-$rs = $schema->resultset('Complex')->search({ 'artistid' => 1 }, { bind => [ 1999 ] });
-is ( $rs->count, 1, '...coobook + search condition' );
+  $rs = $schema->resultset('Complex')->search({ 'artistid' => 1 }, { bind => [ 1999 ] });
+  is ( $rs->count, 1, '...cookbook + search condition' );
 
-$rs = $schema->resultset('Complex')->search({}, { bind => [ 1999 ] })
-    ->search({ 'artistid' => 1 });
-is ( $rs->count, 1, '...cookbook (bind first) + chained search' );
+  $rs = $schema->resultset('Complex')->search({}, { bind => [ 1999 ] })
+      ->search({ 'artistid' => 1 });
+  is ( $rs->count, 1, '...cookbook (bind first) + chained search' );
 
-{
   $rs = $schema->resultset('Complex')->search({}, { bind => [ 1999 ] })->search({}, { where => \"title LIKE ?", bind => [ 'Spoon%' ] });
   is_same_sql_bind(
     $rs->as_query,
@@ -82,8 +82,36 @@ is ( $rs->count, 1, '...cookbook (bind first) + chained search' );
       [ '!!dummy' => 'Spoon%' ]
     ],
     'got correct SQL'
-);
+  );
+}
+
+{
+  # More complex cases, based primarily on the Cookbook
+  # "Arbitrary SQL through a custom ResultSource" technique,
+  # which seems to be the only place the bind attribute is
+  # documented.  Breaking this technique probably breaks existing
+  # application code.
+
+  $rs = $schema->resultset('CustomSql')->search({}, { bind => [ 1999 ] });
+  is ( $rs->count, 1, 'cookbook arbitrary sql example (in separate file)' );
+
+  $rs = $schema->resultset('CustomSql')->search({ 'artistid' => 1 }, { bind => [ 1999 ] });
+  is ( $rs->count, 1, '...cookbook (in separate file) + search condition' );
+
+  $rs = $schema->resultset('CustomSql')->search({}, { bind => [ 1999 ] })
+      ->search({ 'artistid' => 1 });
+  is ( $rs->count, 1, '...cookbook (bind first, in separate file) + chained search' );
 
+  $rs = $schema->resultset('CustomSql')->search({}, { bind => [ 1999 ] })->search({}, { where => \"title LIKE ?", bind => [ 'Spoon%' ] });
+  is_same_sql_bind(
+    $rs->as_query,
+    "(SELECT me.artistid, me.name, me.rank, me.charfield FROM (SELECT a.*, cd.cdid AS cdid, cd.title AS title, cd.year AS year FROM artist a JOIN cd ON cd.artist = a.artistid WHERE cd.year = ?) WHERE title LIKE ?)",
+    [
+      [ '!!dummy' => '1999' ], 
+      [ '!!dummy' => 'Spoon%' ]
+    ],
+    'got correct SQL (cookbook arbitrary SQL, in separate file)'
+  );
 }
 
 TODO: {
index b03d090..ab5b098 100644 (file)
@@ -20,6 +20,7 @@ __PACKAGE__->load_classes(qw/
   Tag
   Year2000CDs
   Year1999CDs
+  CustomSql
   /,
   { 'DBICTest::Schema' => [qw/
     LinerNotes
diff --git a/t/lib/DBICTest/Schema/CustomSql.pm b/t/lib/DBICTest/Schema/CustomSql.pm
new file mode 100644 (file)
index 0000000..d169d72
--- /dev/null
@@ -0,0 +1,15 @@
+package # hide from PAUSE 
+    DBICTest::Schema::CustomSql;
+
+use base qw/DBICTest::Schema::Artist/;
+
+__PACKAGE__->table('dummy');
+
+__PACKAGE__->result_source_instance->name(\<<SQL);
+  ( SELECT a.*, cd.cdid AS cdid, cd.title AS title, cd.year AS year 
+  FROM artist a
+  JOIN cd ON cd.artist = a.artistid
+  WHERE cd.year = ?)
+SQL
+
+1;