From: Rafael Kitover Date: Fri, 4 Feb 2011 14:42:31 +0000 (-0500) Subject: Refactor UUID generation logic in ::Storage::DBI::UniqueIdentifier X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=40d8d018f03631cf38c5bebf854abef604de33bd;p=dbsrgits%2FDBIx-Class-Historic.git Refactor UUID generation logic in ::Storage::DBI::UniqueIdentifier --- diff --git a/lib/DBIx/Class/Storage/DBI/MSSQL.pm b/lib/DBIx/Class/Storage/DBI/MSSQL.pm index 8f5b528..d4f87cc 100644 --- a/lib/DBIx/Class/Storage/DBI/MSSQL.pm +++ b/lib/DBIx/Class/Storage/DBI/MSSQL.pm @@ -17,6 +17,8 @@ __PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::MSSQL'); __PACKAGE__->sql_quote_char([qw/[ ]/]); +__PACKAGE__->new_guid('NEWID()'); + sub _set_identity_insert { my ($self, $table) = @_; diff --git a/lib/DBIx/Class/Storage/DBI/SQLAnywhere.pm b/lib/DBIx/Class/Storage/DBI/SQLAnywhere.pm index 38fd196..3705b9e 100644 --- a/lib/DBIx/Class/Storage/DBI/SQLAnywhere.pm +++ b/lib/DBIx/Class/Storage/DBI/SQLAnywhere.pm @@ -12,6 +12,8 @@ __PACKAGE__->mk_group_accessors(simple => qw/_identity/); __PACKAGE__->sql_limit_dialect ('RowNumberOver'); __PACKAGE__->sql_quote_char ('"'); +__PACKAGE__->new_guid('UUIDTOSTR(NEWID())'); + =head1 NAME DBIx::Class::Storage::DBI::SQLAnywhere - Driver for Sybase SQL Anywhere @@ -36,8 +38,6 @@ Recommended L settings: sub last_insert_id { shift->_identity } -sub _new_uuid { 'UUIDTOSTR(NEWID())' } - sub _prefetch_autovalues { my $self = shift; my ($source, $to_insert) = @_; diff --git a/lib/DBIx/Class/Storage/DBI/UniqueIdentifier.pm b/lib/DBIx/Class/Storage/DBI/UniqueIdentifier.pm index a748994..92e7c15 100644 --- a/lib/DBIx/Class/Storage/DBI/UniqueIdentifier.pm +++ b/lib/DBIx/Class/Storage/DBI/UniqueIdentifier.pm @@ -5,30 +5,56 @@ use warnings; use base 'DBIx::Class::Storage::DBI'; use mro 'c3'; +__PACKAGE__->mk_group_accessors(inherited => 'new_guid'); + =head1 NAME DBIx::Class::Storage::DBI::UniqueIdentifier - Storage component for RDBMSes -supporting the 'uniqueidentifier' type +supporting GUID types =head1 DESCRIPTION -This is a storage component for databases that support the C -type and the C function for generating UUIDs. +This is a storage component for databases that support GUID types such as +C, C or C. + +GUIDs are generated automatically for PK columns with a supported +L, as well as non-PK with +L set. + +=head1 METHODS + +=head2 new_guid + +The composing class must set C to the method used to generate a new +GUID. It can also set it to C, in which case the user is required to set +it, or a runtime error will be thrown. It can be: + +=over 4 + +=item string + +In which case it is used as the name of database function to create a new GUID, + +=item coderef -UUIDs are generated automatically for PK columns with the C -L, as well as non-PK with this -L and -L. +In which case the coderef should return a string GUID, using L, or +whatever GUID generation method you prefer. -Currently used by L and -L. +=back -The composing class can define a C<_new_uuid> method to override the function -used to generate a new UUID. +For example: + + $schema->storage->new_guid(sub { Data::GUID->new->as_string }); =cut -sub _new_uuid { 'NEWID()' } +my $GUID_TYPE = qr/^(?:uniqueidentifier(?:str)?|guid)\z/i; + +sub _is_guid_type { + my ($self, $data_type) = @_; + + return $data_type =~ $GUID_TYPE; +} sub insert { my $self = shift; @@ -44,13 +70,13 @@ sub insert { my @pk_guids = grep { $col_info->{$_}{data_type} && - $col_info->{$_}{data_type} =~ /^uniqueidentifier/i + $col_info->{$_}{data_type} =~ $GUID_TYPE } @pk_cols; my @auto_guids = grep { $col_info->{$_}{data_type} && - $col_info->{$_}{data_type} =~ /^uniqueidentifier/i + $col_info->{$_}{data_type} =~ $GUID_TYPE && $col_info->{$_}{auto_nextval} } grep { not exists $pk_cols{$_} } $source->columns; @@ -61,7 +87,24 @@ sub insert { my $updated_cols = {}; for my $guid_col (@get_guids_for) { - my ($new_guid) = $self->_get_dbh->selectrow_array('SELECT '.$self->_new_uuid); + my $new_guid; + + my $guid_method = $self->new_guid; + + if (not defined $guid_method) { + $self->throw_exception( + 'You must set new_guid on your storage. See perldoc ' + .'DBIx::Class::Storage::DBI::UniqueIdentifier' + ); + } + + if (ref $guid_method eq 'CODE') { + $new_guid = $guid_method->(); + } + else { + ($new_guid) = $self->_get_dbh->selectrow_array("SELECT $guid_method"); + } + $updated_cols->{$guid_col} = $to_insert->{$guid_col} = $new_guid; }