Merge 'trunk' into 'oracle_quotes'
Peter Rabbitson [Tue, 23 Feb 2010 10:38:55 +0000 (10:38 +0000)]
r8808@Thesaurus (orig r8795):  caelum | 2010-02-22 20:16:07 +0100
with_deferred_fk_checks for Oracle
r8809@Thesaurus (orig r8796):  rabbit | 2010-02-22 21:26:20 +0100
Add a hidden option to dbicadmin to self-inject autogenerated POD
r8810@Thesaurus (orig r8797):  caelum | 2010-02-22 21:48:43 +0100
improve with_deferred_fk_checks for Oracle, add tests
r8812@Thesaurus (orig r8799):  rbuels | 2010-02-22 23:09:40 +0100
added package name to DBD::Pg warning in Pg storage driver to make it explicit where the warning is coming from
r8815@Thesaurus (orig r8802):  rabbit | 2010-02-23 11:21:10 +0100
Looks like the distdir wrapping is finally taken care of

.gitignore
Makefile.PL
lib/DBIx/Class/Admin/Usage.pm
lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm
lib/DBIx/Class/Storage/DBI/Pg.pm
script/dbicadmin
t/73oracle.t

index ea0a947..5aa3840 100644 (file)
@@ -10,6 +10,5 @@ _build/
 blib/
 inc/
 lib/DBIx/Class/Optional/Dependencies.pod
-lib/dbicadmin.pod
 pm_to_blib
 t/var/
index d98c782..706b7b6 100644 (file)
@@ -49,6 +49,8 @@ my $runtime_requires = {
   'SQL::Abstract::Limit'     => '0.13',
   'Sub::Name'                => '0.04',
   'Data::Dumper::Concise'    => '1.000',
+  'Scope::Guard'             => '0.03',
+  'Context::Preserve'        => '0.01',
 };
 
 # this is so we can order requires alphabetically
@@ -114,9 +116,6 @@ if ($Module::Install::AUTHOR) {
     unlink 'MANIFEST';
   }
 
-  print "Regenerating dbicadmin.pod\n";
-  system('perl script/dbicadmin --pod > lib/dbicadmin.pod');
-
   print "Regenerating Optional/Dependencies.pod\n";
   require DBIx::Class::Optional::Dependencies;
   DBIx::Class::Optional::Dependencies->_gen_pod;
@@ -126,13 +125,38 @@ if ($Module::Install::AUTHOR) {
   #  PodInherit();
 }
 
+tests_recursive (qw|
+    t
+|);
+
 install_script (qw|
     script/dbicadmin
 |);
 
-tests_recursive (qw|
-    t
-|);
+
+### Mangle makefile - read the comments for more info
+#
+postamble <<"EOP";
+
+# This will add an extra dep-spec for the distdir target,
+# which `make` will fold together in a first-come first-serve
+# fashion. What we do here is essentially adding extra
+# commands to execute once the distdir is assembled (via
+# create_distdir), but before control is returned to a higher
+# calling rule.
+distdir : dbicadmin_pod_inject
+
+# The pod self-injection code is in fact a hidden option in
+# dbicadmin itself
+dbicadmin_pod_inject :
+\tcd \$(DISTVNAME) && \$(ABSPERL) -Ilib script/dbicadmin --selfinject-pod
+
+# Regenerate manifest before running create_distdir.
+create_distdir : manifest
+
+EOP
+
+
 
 resources 'IRC'         => 'irc://irc.perl.org/#dbix-class';
 resources 'license'     => 'http://dev.perl.org/licenses/';
index 9cae79b..291fd1e 100644 (file)
@@ -52,6 +52,8 @@ See L<DBIx::Class/CONTRIBUTORS>
 =head1 LICENSE
 
 You may distribute this code under the same terms as Perl itself
+
+=cut
 EOA
 }
 
index 854566a..2644d43 100644 (file)
@@ -2,6 +2,8 @@ package DBIx::Class::Storage::DBI::Oracle::Generic;
 
 use strict;
 use warnings;
+use Scope::Guard ();
+use Context::Preserve ();
 
 =head1 NAME
 
@@ -349,6 +351,35 @@ sub relname_to_table_alias {
   return $new_alias;
 }
 
+=head2 with_deferred_fk_checks
+
+Runs a coderef between:
+
+  alter session set constraints = deferred
+  ...
+  alter session set constraints = immediate
+
+to defer foreign key checks.
+
+Constraints must be declared C<DEFERRABLE> for this to work.
+
+=cut
+
+sub with_deferred_fk_checks {
+  my ($self, $sub) = @_;
+
+  my $txn_scope_guard = $self->txn_scope_guard;
+
+  $self->_do_query('alter session set constraints = deferred');
+  
+  my $sg = Scope::Guard->new(sub {
+    $self->_do_query('alter session set constraints = immediate');
+  });
+
+  return Context::Preserve::preserve_context(sub { $sub->() },
+    after => sub { $txn_scope_guard->commit });
+}
+
 =head1 AUTHOR
 
 See L<DBIx::Class/CONTRIBUTORS>.
index 6636201..92153ec 100644 (file)
@@ -9,7 +9,7 @@ use mro 'c3';
 use DBD::Pg qw(:pg_types);
 
 # Ask for a DBD::Pg with array support
-warn "DBD::Pg 2.9.2 or greater is strongly recommended\n"
+warn __PACKAGE__.": DBD::Pg 2.9.2 or greater is strongly recommended\n"
   if ($DBD::Pg::VERSION < 2.009002);  # pg uses (used?) version::qv()
 
 sub with_deferred_fk_checks {
index 59c48c6..44eba49 100755 (executable)
@@ -43,8 +43,8 @@ my ($opts, $usage) = describe_options(
       ['update|u'   => 'Update data in the schema', ], 
       ['delete|D'   => 'Delete data from the schema',],
       ['op:s' => 'compatiblity option all of the above can be suppied as --op=<action>'],
-      ['help|h' => 'display this help', { implies => { schema_class => 'main' } } ],
-      ['pod' => 'Output this usage as pod', { implies => { schema_class => 'main' } } ],
+      ['help|h' => 'display this help', { implies => { schema_class => '__dummy__' } } ],
+      ['selfinject-pod' => 'hidden', { implies => { schema_class => '__dummy__' } } ],
     ], required=> 1 }],
     ['Arguments'],
     ['schema-class|schema|C:s' => 'The class of the schema to load', { required => 1 } ],
@@ -68,11 +68,19 @@ my ($opts, $usage) = describe_options(
 
 die "please only use one of --config or --connect-info\n" if ($opts->{config} and $opts->{connect_info});
 
-if($opts->{pod}) {
+if($opts->{selfinject_pod}) {
     $usage->synopsis($synopsis_text);
     $usage->short_description($short_description);
-    print $usage->pod();
-    exit 0;
+    exec (
+      $^X,
+      qw/-p -0777 -i -e/,
+      (
+        's/^# auto_pod_begin.*^# auto_pod_end/'
+      . quotemeta($usage->pod)
+      . '/ms'
+      ),
+      __FILE__
+    );
 }
 
 if($opts->{help}) {
@@ -112,28 +120,12 @@ if ($action eq 'select') {
 }
 
 
-#__END__
-#
-#=begin pod_begin
-#
-#BEGIN MARKER FOR DYNAMIC POD
-#
-#=end pod_begin
-#
-#=begin pod_end
-#
-#END MARKER FOR DYNAMIC POD
-#
-#=end pod_end
-#
-#=head1 AUTHOR
-#
-#See L<DBIx::Class/CONTRIBUTORS>.
-#
-#=head1 LICENSE
+__END__
+
+# auto_pod_begin
 #
-#You may distribute this code under the same terms as Perl itself
+# This will be replaced by the actual pod when selfinject-pod is invoked
 #
-#=cut
+# auto_pod_end
 
 # vim: et ft=perl
index 50c519f..0aa3ee7 100644 (file)
@@ -53,22 +53,26 @@ eval {
   $dbh->do("DROP SEQUENCE nonpkid_seq");
   $dbh->do("DROP TABLE artist");
   $dbh->do("DROP TABLE sequence_test");
-  $dbh->do("DROP TABLE cd");
   $dbh->do("DROP TABLE track");
+  $dbh->do("DROP TABLE cd");
 };
 $dbh->do("CREATE SEQUENCE artist_seq START WITH 1 MAXVALUE 999999 MINVALUE 0");
 $dbh->do("CREATE SEQUENCE cd_seq START WITH 1 MAXVALUE 999999 MINVALUE 0");
 $dbh->do("CREATE SEQUENCE pkid1_seq START WITH 1 MAXVALUE 999999 MINVALUE 0");
 $dbh->do("CREATE SEQUENCE pkid2_seq START WITH 10 MAXVALUE 999999 MINVALUE 0");
 $dbh->do("CREATE SEQUENCE nonpkid_seq START WITH 20 MAXVALUE 999999 MINVALUE 0");
+
 $dbh->do("CREATE TABLE artist (artistid NUMBER(12), name VARCHAR(255), rank NUMBER(38), charfield VARCHAR2(10))");
+$dbh->do("ALTER TABLE artist ADD (CONSTRAINT artist_pk PRIMARY KEY (artistid))");
+
 $dbh->do("CREATE TABLE sequence_test (pkid1 NUMBER(12), pkid2 NUMBER(12), nonpkid NUMBER(12), name VARCHAR(255))");
-$dbh->do("CREATE TABLE cd (cdid NUMBER(12), artist NUMBER(12), title VARCHAR(255), year VARCHAR(4), genreid NUMBER(12), single_track NUMBER(12))");
-$dbh->do("CREATE TABLE track (trackid NUMBER(12), cd NUMBER(12), position NUMBER(12), title VARCHAR(255), last_updated_on DATE, last_updated_at DATE, small_dt DATE)");
+$dbh->do("ALTER TABLE sequence_test ADD (CONSTRAINT sequence_test_constraint PRIMARY KEY (pkid1, pkid2))");
 
-$dbh->do("ALTER TABLE artist ADD (CONSTRAINT artist_pk PRIMARY KEY (artistid))");
+$dbh->do("CREATE TABLE cd (cdid NUMBER(12), artist NUMBER(12), title VARCHAR(255), year VARCHAR(4), genreid NUMBER(12), single_track NUMBER(12))");
 $dbh->do("ALTER TABLE cd ADD (CONSTRAINT cd_pk PRIMARY KEY (cdid))");
-$dbh->do("ALTER TABLE sequence_test ADD (CONSTRAINT sequence_test_constraint PRIMARY KEY (pkid1, pkid2))");
+
+$dbh->do("CREATE TABLE track (trackid NUMBER(12), cd NUMBER(12) REFERENCES cd(cdid) DEFERRABLE, position NUMBER(12), title VARCHAR(255), last_updated_on DATE, last_updated_at DATE, small_dt DATE)");
+
 $dbh->do(qq{
   CREATE OR REPLACE TRIGGER artist_insert_trg
   BEFORE INSERT ON artist
@@ -218,6 +222,27 @@ is( $it->next, undef, "next past end of resultset ok" );
   is( scalar @results, 1, "Group by with limit OK" );
 }
 
+# test with_deferred_fk_checks
+lives_ok {
+  $schema->storage->with_deferred_fk_checks(sub {
+    $schema->resultset('Track')->create({
+      trackid => 999, cd => 999, position => 1, title => 'deferred FK track'
+    });
+    $schema->resultset('CD')->create({
+      artist => 1, cdid => 999, year => '2003', title => 'deferred FK cd'
+    });
+  });
+} 'with_deferred_fk_checks code survived';
+
+is eval { $schema->resultset('Track')->find(999)->title }, 'deferred FK track',
+   'code in with_deferred_fk_checks worked'; 
+
+throws_ok {
+  $schema->resultset('Track')->create({
+    trackid => 1, cd => 9999, position => 1, title => 'Track1'
+  });
+} qr/constraint/i, 'with_deferred_fk_checks is off';
+
 # test auto increment using sequences WITHOUT triggers
 for (1..5) {
     my $st = $schema->resultset('SequenceTest')->create({ name => 'foo' });
@@ -271,8 +296,8 @@ END {
         $dbh->do("DROP SEQUENCE nonpkid_seq");
         $dbh->do("DROP TABLE artist");
         $dbh->do("DROP TABLE sequence_test");
-        $dbh->do("DROP TABLE cd");
         $dbh->do("DROP TABLE track");
+        $dbh->do("DROP TABLE cd");
         $dbh->do("DROP TABLE bindtype_test");
     }
 }