Views are automatically excluded from using insert_returning. blocked_by_lack_of_per_resultset_storage_attributes/no_ir_on_views
Amiri Barksdale at Home [Thu, 23 Dec 2010 02:40:18 +0000 (18:40 -0800)]
There is also the bare skeleton of an API for setting insert_returning in the result
class.

lib/DBIx/Class/ResultSource/View.pm
lib/DBIx/Class/Storage/DBI.pm
t/106storage_resultset_attributes.t [new file with mode: 0644]
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Schema/StorageFlagPole.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/StorageFlagView.pm [new file with mode: 0644]
t/lib/sqlite.sql

index 9c0d51a..be29bdb 100644 (file)
@@ -164,6 +164,7 @@ The constructor.
 sub new {
     my ( $self, @args ) = @_;
     my $new = $self->next::method(@args);
+    $new->{resultset_attributes}->{storage}->{use_insert_returning} = 0;
     $new->{deploy_depends_on} =
       { map { $_ => 1 }
           @{ $new->{deploy_depends_on} || [] } }
index a4eb7c7..8cc55f3 100644 (file)
@@ -1782,6 +1782,11 @@ sub _prefetch_autovalues {
 
 sub insert {
   my ($self, $source, $to_insert) = @_;
+  
+  my $use_insert_returning =
+      defined $source->resultset_attributes->{storage}->{use_insert_returning}
+      ? $source->resultset_attributes->{storage}->{use_insert_returning}
+      : $self->_use_insert_returning;
 
   my $prefetched_values = $self->_prefetch_autovalues($source, $to_insert);
 
@@ -1797,7 +1802,7 @@ sub insert {
   }
 
   my ($sqla_opts, @ir_container);
-  if ($self->_use_insert_returning) {
+  if ($use_insert_returning) {
 
     # retain order as declared in the resultsource
     for (sort { $fetch_pks{$a} <=> $fetch_pks{$b} } keys %fetch_pks ) {
diff --git a/t/106storage_resultset_attributes.t b/t/106storage_resultset_attributes.t
new file mode 100644 (file)
index 0000000..fb22151
--- /dev/null
@@ -0,0 +1,43 @@
+use strict;
+use warnings;
+
+use Test::More qw/no_plan/;
+use Test::Exception;
+use lib qw(t/lib);
+use DBICTest;
+use DateTime;
+use Devel::Dwarn;
+
+my ( $dsn, $user, $pass )
+    = @ENV{ map {"DBICTEST_PG_${_}"} qw/DSN USER PASS/ };
+
+plan skip_all => <<'EOM' unless $dsn && $user;
+Set $ENV{DBICTEST_PG_DSN}, _USER and _PASS to run this test
+( NOTE: This test drops and creates tables called 'artist', 'cd',
+'timestamp_primary_key_test', 'track', 'casecheck', 'array_test' and
+'sequence_test' as well as following sequences: 'pkid1_seq', 'pkid2_seq' and
+'nonpkid_seq'. as well as following schemas: 'dbic_t_schema',
+'dbic_t_schema_2', 'dbic_t_schema_3', 'dbic_t_schema_4', and 'dbic_t_schema_5')
+EOM
+
+my $schema = DBICTest::Schema->connect( $dsn, $user, $pass );
+$schema->storage->dbh->{Warn} = 0;
+
+$schema->deploy( { add_drop_table => 1, add_drop_view => 1, debug => 0 } );
+
+
+### A table
+
+my $flagpole = $schema->resultset('StorageFlagPole');
+is_deeply( $flagpole->result_source->resultset_attributes, { storage => { use_insert_returning => 0 }}, "My table resultset does NOT want to use insert returning");
+my $flagged_row;
+
+throws_ok(sub { $flagged_row = $flagpole->create( { name => "My name is row." } ) }, qr/no sequence found for storage_flag_pole.id/, "Without insert_returning, insert throws a no-sequence defined error because the PK is not autoinc");
+lives_ok { $flagged_row = $flagpole->create( { id => DateTime->now, name => "My name is row." } ) }  "You have to pass the id" ;
+
+lives_ok { $flagged_row->insert } "It can be inserted after you put the id";
+
+### A view
+
+my $flagview = $schema->resultset('StorageFlagPole');
+is_deeply( $flagview->result_source->resultset_attributes, { storage => { use_insert_returning => 0 }}, "Upon mere instantiation my view resultset does NOT want to use insert returning");
index 07b311a..baad9c8 100644 (file)
@@ -50,6 +50,7 @@ __PACKAGE__->load_classes(qw/
   qw/SelfRefAlias TreeLike TwoKeyTreeLike Event EventTZ NoPrimaryKey/,
   qw/Collection CollectionObject TypedObject Owners BooksInLibrary/,
   qw/ForceForeign Encoded/,
+  qw/StorageFlagPole StorageFlagView/,
 );
 
 sub sqlt_deploy_hook {
diff --git a/t/lib/DBICTest/Schema/StorageFlagPole.pm b/t/lib/DBICTest/Schema/StorageFlagPole.pm
new file mode 100644 (file)
index 0000000..3781eae
--- /dev/null
@@ -0,0 +1,18 @@
+package    # hide from PAUSE
+    DBICTest::Schema::StorageFlagPole;
+
+use base qw/DBICTest::BaseResult/;
+
+__PACKAGE__->table('storage_flag_pole');
+__PACKAGE__->add_columns(
+    'id' => {
+        data_type     => 'datetime',
+        default_value => \'current_timestamp'
+    },
+    'name' => { data_type => 'text', },
+);
+__PACKAGE__->set_primary_key(qw/id/);
+__PACKAGE__->resultset_attributes(
+    { storage => { use_insert_returning => 0 } } );
+
+1;
diff --git a/t/lib/DBICTest/Schema/StorageFlagView.pm b/t/lib/DBICTest/Schema/StorageFlagView.pm
new file mode 100644 (file)
index 0000000..c805895
--- /dev/null
@@ -0,0 +1,12 @@
+package    # hide from PAUSE
+    DBICTest::Schema::StorageFlagView;
+
+use base qw/DBICTest::BaseResult/;
+
+__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
+__PACKAGE__->table('storage_flag_pole');
+__PACKAGE__->result_source_instance->is_virtual(1);
+__PACKAGE__->result_source_instance->view_definition(
+    "SELECT id, name FROM storage_flag_pole WHERE name like 'My name%'");
+
+1;
index ff9597f..dc419d6 100644 (file)
@@ -462,3 +462,12 @@ CREATE INDEX fourkeys_to_twokeys_idx_t_artist_t_cd ON fourkeys_to_twokeys (t_art
 --
 CREATE VIEW year2000cds AS
     SELECT cdid, artist, title, year, genreid, single_track FROM cd WHERE year = "2000";
+
+--
+-- Table: storage_flag_pole 
+--
+CREATE TABLE storage_flag_pole (
+  id timestamp NOT NULL DEFAULT current_timestamp,
+  name varchar(100) NOT NULL,
+  PRIMARY KEY (id)
+);