From: Amiri Barksdale at Home Date: Thu, 23 Dec 2010 02:40:18 +0000 (-0800) Subject: Views are automatically excluded from using insert_returning. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=62ed3a33c8a6688e9428bb7973a327b50f521054;p=dbsrgits%2FDBIx-Class.git Views are automatically excluded from using insert_returning. There is also the bare skeleton of an API for setting insert_returning in the result class. --- diff --git a/lib/DBIx/Class/ResultSource/View.pm b/lib/DBIx/Class/ResultSource/View.pm index 9c0d51a..be29bdb 100644 --- a/lib/DBIx/Class/ResultSource/View.pm +++ b/lib/DBIx/Class/ResultSource/View.pm @@ -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} || [] } } diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index a4eb7c7..8cc55f3 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -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 index 0000000..fb22151 --- /dev/null +++ b/t/106storage_resultset_attributes.t @@ -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"); diff --git a/t/lib/DBICTest/Schema.pm b/t/lib/DBICTest/Schema.pm index 07b311a..baad9c8 100644 --- a/t/lib/DBICTest/Schema.pm +++ b/t/lib/DBICTest/Schema.pm @@ -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 index 0000000..3781eae --- /dev/null +++ b/t/lib/DBICTest/Schema/StorageFlagPole.pm @@ -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 index 0000000..c805895 --- /dev/null +++ b/t/lib/DBICTest/Schema/StorageFlagView.pm @@ -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; diff --git a/t/lib/sqlite.sql b/t/lib/sqlite.sql index ff9597f..dc419d6 100644 --- a/t/lib/sqlite.sql +++ b/t/lib/sqlite.sql @@ -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) +);