Permalink
Browse files

Interim commit. Not useful.

  • Loading branch information...
1 parent 7b54733 commit 19c7bad2b08a09b90a6048475ba611c55bd2ea2b @bluefeet committed Sep 20, 2011
View
@@ -0,0 +1,3 @@
+DBIx-AutoID*
+*.db
+.build
View
@@ -0,0 +1,3 @@
+\.db$
+dist.ini
+MANIFEST.SKIP
View
@@ -0,0 +1,41 @@
+name = DBIx-AutoID
+author = Aran Deltac <bluefeet@gmail.com>
+license = Perl_5
+copyright_holder = Aran Deltac
+
+[@Basic]
+[ManifestSkip]
+
+[NextRelease]
+format = %-9v %{yyyy-MM-dd}d
+
+[@Git]
+
+[Git::NextVersion]
+first_version = 0.01
+
+[Repository]
+
+[PkgVersion]
+[PodCoverageTests]
+[PodSyntaxTests]
+
+[Bugtracker]
+web = https://github.com/bluefeet/DBIx-AutoID/issues
+
+[Test::Compile]
+
+[ReadmeAnyFromPod / ReadmePodInRoot]
+type = pod
+filename = README.pod
+location = root
+
+[Prereqs]
+SQL::Abstract::Query = 0.02
+Moose = 2.0204
+namespace::autoclean = 0.13
+
+[Prereqs / TestRequires]
+Test::More = 0.98
+Try::Tiny = 0.11
+
View
@@ -0,0 +1,181 @@
+package DBIx::AutoID;
+use Moose;
+
+=head1 NAME
+
+DBIx::AutoID - Automatically generated ID retrieval for DBI.
+
+=head1 SYNOPSIS
+
+ use DBIx::AutoID;
+
+ # Use a DBIx::Connector object:
+ my $auto = DBIx::AutoID->new( $connector );
+
+ # or, use a DB handle created with DBI:
+ my $auto = DBIx::AutoID->new( $dbh );
+
+ # Insert a row somewhere, then get the automatically generated ID:
+ my $id = $auto->insert( $sql, \@bind_values, \%options );
+
+=head1 DESCRIPTION
+
+This module provides a very simple interface to a complex problem: retrieving
+automatically generated IDs after an INSERT. This problem is complex since
+every database does this in a different way from the simplest where you can
+call a function to retrieve the last auto-incrementing ID (mysql, and others)
+to the most complex where database metadata has to be traveresed (Oracle).
+
+L<DBIx::Class> supports very extensive auto-ID retrieval which
+can be very usefull outside of that context. L<DBIx::ResultSet> needs this
+logic so this package was built to abstract this logic out of DBIx::Class
+and make it available in a generic re-useable fashion.
+
+In order for this module to have an external API that works nearly identical
+under all supported databases the INSERT(s) themselves must be managed by
+this module, not just the post-INSERT step of retrieving the ID. This is
+due to the fact that some databases (MSSQL for one) require that the INSERT
+contain special logic so that the ID may be retrieved afterwards.
+
+=cut
+
+use Module::Load qw();
+
+around BUILDARGS => sub {
+ my $orig = shift;
+ my $class = shift;
+
+ if (@_ == 1) {
+ return $class->$orig( connector => $_[0] );
+ }
+
+ return $class->$orig( @_ );
+};
+
+=head1 ATTRIBUTES
+
+These attributes may be set as part of the call to new(). Once an object is
+instantiated none of these attributes may be changed. Typically you will just want
+to use the short-hand form of new() where you are implicitly setting the
+connector attribute (whether it is a DBI handle or a DBIx::Connector object):
+
+ my $auto = DBIx::AutoID->new( $dbh_or_connector );
+
+=head2 connector
+
+This attribute is required and should be a L<DBIx::Connector> object. If a
+DBI database handle is passed instead it will be wrapped up in a
+L<DBIx::AutoID::Connector> object behind the scenes. Even though a DBI
+database handle is supported it is highly recommended that you start
+using DBIx::Connector to better manage you DBI connections and transactions.
+
+=cut
+
+subtype 'DBIxAutoIDAnyConnector',
+ as 'Object'
+ where { $_->isa('DBIx::Connector') or $_->isa('DBIx::AutoID::Connector') };
+
+coerce 'DBIxAutoIDAnyConnector',
+ from 'DBI::db',
+ via { DBIx::AutoID::Connector->new( $_ ) };
+
+has connector => (
+ is => 'ro',
+ isa => 'DBIxAutoIDAnyConnector',
+ required => 1,
+ coerce => 1,
+);
+
+=head2 driver_name
+
+The name of the DBD driver, such as mysql or SQLite. If not set this will
+default to whatever driver name the connector() reports. Generally you
+do not want to set this yourself, instead just set the connector() and
+everything will be figured out automatically.
+
+=cut
+
+has driver_name => (
+ is => 'ro',
+ isa => 'Str',
+ lazy_build => 1,
+);
+sub _build_driver_name {
+ my ($self) = @_;
+ return $self->connector->{driver};
+}
+
+=head2 driver
+
+A L<DBIx::AutoID::Driver>, such as L<DBIx::AutoID::Driver::mysql>. If not
+set this will default to whichever driver matches the driver_name().
+
+=cut
+
+has driver => (
+ is => 'ro',
+ does => 'DBIx::AutoID::Driver',
+ lazy_build => 1,
+);
+sub _build_driver {
+ my ($self) = @_;
+ my $class = 'DBIx::AutoID::Driver::' . $self->driver_name();
+ Module::Load::load( $class );
+ return $class->new( connector => $self->connector() );
+}
+
+=head1 METHODS
+
+=head2 insert
+
+ my $id = $auto->insert( $sql, \@bind_values, \%hints );
+
+This method is dispatched to the current driver's insert() method after
+all arguments are validated. The bind_values and hints arguments
+are optional. Drivers are encourages to use DBI's prepare_cached() if
+bind_values are supplied.
+
+Different drivers need different hints in order to figure out the ID of
+the row that is INSERTed. If you specify the table and column hints
+you are pretty much garaunteed to be compatible with most database types:
+
+ my $user_id = $auto->insert(
+ 'INSERT INTO users SET email=?, password=?',
+ [ $email, sha1_hex( $password ) ],
+ { table => 'users', column => 'user_id' },
+ );
+
+Some drivers need no hints (such as SQLite and mysql). Check your
+driver's documentation for details.
+
+=cut
+
+sub insert {
+ my ($self, $sql, $bind_values, $options) = @_;
+
+ croak 'SQL must be passed as the first argument' if !$sql;
+ croak 'The SQL argument cannot be a reference' if ref($sql);
+ croak 'The SQL argument does not look like an INSERT' if $sql !~ m{\binsert\b}i;
+
+ $bind_values ||= [];
+ $options ||= {};
+
+ croak 'The bind_values argument must be an array reference' if ref($bind_values) ne 'ARRAY';
+ croak 'The options argument must be a hash reference' if ref($options) ne 'HASH';
+
+ return $self->driver->insert( $sql, $bind_values, $options );
+}
+
+__PACKAGE__->meta->make_immutable;
+1;
+__END__
+
+=head1 AUTHOR
+
+Aran Clary Deltac <bluefeet@gmail.com>
+
+=head1 LICENSE
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
@@ -0,0 +1,110 @@
+package DBIx::AutoID::Connector;
+use Moose;
+
+=head1 NAME
+
+DBIx::AutoID::Connector - A mock DBIx::Connector.
+
+=head1 SYNOPSIS
+
+ use DBIx::AutoID::Connector;
+
+ my $connector = DBIx::AutoID::Connector->new( $dbh );
+
+ $connector->run(sub{
+ my ($dbh) = @_;
+ ...
+ });
+
+=head1 DESCRIPTION
+
+L<DBIx::AutoID> recommends that a L<DBIx::Connector> object
+be passed to it. If a DBI database handle is passed to it instead
+then a new DBIx::AutoID::Connector object is created to wrap around
+the handle so that the rest of the AutoID code can simply
+treat the connector as a DBIx::Connector no matter what.
+
+This module impliments an extermily crippled API that is barely
+compatible with DBIx::Connector. It is only compatible enough
+for DIBx::AutoID to use it.
+
+=cut
+
+use Carp qw( croak );
+
+around BUILDARGS => sub {
+ my $orig = shift;
+ my $class = shift;
+
+ if (@_ == 1) {
+ return $class->$orig( dbh => $_[0] );
+ }
+
+ return $class->$orig( @_ );
+};
+
+=head1 ATTRIBUTES
+
+=head2 dbh
+
+The DBI database connection handle. This is required.
+
+=cut
+
+has dbh => (
+ is => 'ro',
+ isa => 'DBI::db',
+ required => 1,
+);
+
+=head1 METHODS
+
+=head2 run
+
+
+
+=head2 txn
+
+Given a code reference this will execute the reference, passing in the
+$dbh as the first argument. A mode may be declared, but it will be ignored.
+
+This method does NOT provide transaction support. Instead it works just
+like DBIx::Connector's run() with the mode 'no_ping'. This method is provided
+purely so that driver's can use transactions if the connector is a real
+DBIx::Connector object.
+
+=cut
+
+
+
+sub txn {
+ my $self = shift;
+ my $sub = pop;
+
+ return $sub->( $self->dbh() );
+}
+
+=head2 in_txn
+
+Returns true if the DBI database handle is currently within a transaction.
+
+=cut
+
+sub in_txn {
+ my ($self) = @_;
+ return $self->dbh->{AutoCommit} ? 0 : 1;
+}
+
+__PACKAGE__->meta->make_immutable;
+1;
+__END__
+
+=head1 AUTHOR
+
+Aran Clary Deltac <bluefeet@gmail.com>
+
+=head1 LICENSE
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
Oops, something went wrong.

0 comments on commit 19c7bad

Please sign in to comment.