[Dbix-class] PK::Sequence

Lee Standen nom at standen.id.au
Thu Aug 3 16:29:44 CEST 2006


Hi Guys,

I've build PK::Sequence...apologies in advance, but i'm having issues 
getting this to work in the current SVN build for some reason...i'm 
probably doing something silly (again).  As a result, i'm going to 
include the PK::Sequence file, and the functions for Pg, since 
i've tested it as working.

I'll include the DB2 and Oracle functions too, but I don't have a copy of 
Oracle to test it.  I kind of got the DB2 one to work, but I an into the 
SVN problems with it too :)


DB2 Function: File - DBIx::Class::Storage::DBI::DB2.pm
--------------------------------------------------------------------------
sub seq_nextval {
     my ($self,$seq) = @_;

     my $dbh = $self->dbh;
     my $sth = $dbh->prepare_cached("NEXTVAL FOR ?");

     $sth->execute($seq);
     my $id = $sth->fetchrow_arrayref()->[0];
     $sth->finish();
     return $id;
}
--------------------------------------------------------------------------


Pg Function: File - DBIx::Class::Storage::DBI::Pg.pm
--------------------------------------------------------------------------
sub seq_nextval {
     my ($self,$seq) = @_;

     my $dbh = $self->dbh;
     my $sth = $dbh->prepare_cached("SELECT nextval(?)");

     $sth->execute($seq);
     my $id = $sth->fetchrow_arrayref()->[0];
     $sth->finish();

     return $id;
}
--------------------------------------------------------------------------


Oracle Function: File - DBIx::Class::Storage::DBI::Oracle.pm
--------------------------------------------------------------------------
sub seq_nextval {
     my ($self,$seq) = @_;

     my $dbh = $self->dbh;
     my $sth = $dbh->prepare_cached("SELECT $seq.nextval");

     $sth->execute($seq);
     my $id = $sth->fetchrow_arrayref()->[0];
     return $id;
}
--------------------------------------------------------------------------


It would probably make sense to put a standard 'someone hasn't written 
this function' message into DBIx::Class::Storage::DBI.pm, but i'll leave 
that up to the masters :)

Thanks :)
-------------- next part --------------
Index: Sequence.pm
===================================================================
--- Sequence.pm	(revision 0)
+++ Sequence.pm	(revision 0)
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+
+package DBIx::Class::PK::Sequence;
+
+=head2 NAME
+
+DBIx::Class::PK::Sequence - support for named sequences on inserting rows
+
+=head2 SYNOPSYS
+
+Allows you to use a standalone sequence (created with the standard CREATE
+SEQUENCE command) to populate the primary key column of a table upon inserts.
+
+=head2 USAGE
+
+Add the B<sequence> key to your column definitions, for example:
+
+    package My::Schema::Table;
+    __PACKAGE__->load_components( qw/PK::Sequence Core/ );
+
+    __PACKAGE__->add_column( 
+        table_id => {
+            data_type => 'integer',
+            sequence => 'seq_table_pk',
+            },
+        username => {
+            data_type => 'varchar',
+            size => '32',
+            },
+        );
+    __PACKAGE__->set_primary_key( qw/table_id/ );
+
+Then, just insert rows as you would normally:
+
+    My::Schema->populate( 'Table', [ [qw/username/], [qw/test1/], [qw/test2] ] );
+
+This will call the driver function get_nextval with the sequence name specified and 
+insert the row.
+
+=head2 AUTHOR
+
+Lee Standen <nom at standen.id.au>
+
+=head2 ACKNOWLEDGEMENTS
+
+mst, castaway, purl :) and anyone else in #dbix-class who helped out!
+    
+=cut
+
+use base 'DBIx::Class';
+use strict;
+use warnings;
+
+sub insert {
+    my ($self, at rest) = @_;
+
+    my $storage = $self->result_source->storage();
+    $storage->ensure_connected;
+    
+    foreach my $col ($self->primary_columns) {
+        next if $self->$col;
+        if ($self->column_info($col)->{sequence}) {
+            $self->throw_exception("Missing primary key, but Storage doesn't support nextval()") unless $storage->can('seq_nextval');
+            my $id = $storage->seq_nextval( $self->column_info($col)->{sequence} );
+            $self->store_column($col => $id);
+        }
+    }
+
+    return $self->next::method(@rest);
+}
+
+
+1;


More information about the Dbix-class mailing list