DBIx::Class::Storage::DBI::ACCESS - Support specific to MS Access


DBIx-Class documentation Contained in the DBIx-Class distribution.

Index


Code Index:

NAME

Top

DBIx::Class::Storage::DBI::ACCESS - Support specific to MS Access

DESCRIPTION

Top

This is the base class for Microsoft Access support.

This driver supports last_insert_id, empty inserts for tables with AUTOINCREMENT columns, nested transactions via auto_savepoint, GUID columns via DBIx::Class::Storage::DBI::UniqueIdentifier.

SUPPORTED VERSIONS

Top

This module has currently only been tested on MS Access 2010.

Information about how well it works on different version of MS Access is welcome (write the mailing list, or submit a ticket to RT if you find bugs.)

USING GUID COLUMNS

Top

If you have GUID PKs or other GUID columns with auto_nextval you will need to set a new_guid callback, like so:

  $schema->storage->new_guid(sub { Data::GUID->new->as_string });

Under Catalyst you can use code similar to this in your Catalyst::Model::DBIC::Schema Model.pm:

  after BUILD => sub {
    my $self = shift;
    $self->storage->new_guid(sub { Data::GUID->new->as_string });
  };

AUTHOR

Top

See AUTHOR in DBIx::Class and CONTRIBUTORS in DBIx::Class.

LICENSE

Top

You may distribute this code under the same terms as Perl itself.


DBIx-Class documentation Contained in the DBIx-Class distribution.
package DBIx::Class::Storage::DBI::ACCESS;

use strict;
use warnings;
use base 'DBIx::Class::Storage::DBI::UniqueIdentifier';
use mro 'c3';

use List::Util 'first';
use namespace::clean;

__PACKAGE__->sql_limit_dialect ('Top');
__PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::ACCESS');
__PACKAGE__->sql_quote_char ([qw/[ ]/]);

sub sqlt_type { 'ACCESS' }

__PACKAGE__->new_guid(undef);

sub _dbh_last_insert_id { $_[1]->selectrow_array('select @@identity') }

# support empty insert
sub insert {
  my $self = shift;
  my ($source, $to_insert) = @_;

  my $columns_info = $source->columns_info;

  if (keys %$to_insert == 0) {
    my $autoinc_col = first {
      $columns_info->{$_}{is_auto_increment}
    } keys %$columns_info;

    if (not $autoinc_col) {
      $self->throw_exception(
'empty insert only supported for tables with an autoincrement column'
      );
    }

    my $table = $source->from;
    $table = $$table if ref $table;

    $to_insert->{$autoinc_col} = \"dmax('${autoinc_col}', '${table}')+1";
  }

  return $self->next::method(@_);
}

sub bind_attribute_by_data_type {
  my $self = shift;
  my ($data_type) = @_;

  my $attributes = $self->next::method(@_) || {};

  if ($self->_is_text_lob_type($data_type)) {
    $attributes->{TYPE} = DBI::SQL_LONGVARCHAR;
  }
  elsif ($self->_is_binary_lob_type($data_type)) {
    $attributes->{TYPE} = DBI::SQL_LONGVARBINARY;
  }

  return $attributes;
}

# savepoints are not supported, but nested transactions are.
# Unfortunately DBI does not support nested transactions.
# WARNING: this code uses the undocumented 'BegunWork' DBI attribute.

sub _exec_svp_begin {
  my ($self, $name) = @_;

  local $self->_dbh->{AutoCommit} = 1;
  local $self->_dbh->{BegunWork}  = 0;
  $self->_exec_txn_begin;
}

# A new nested transaction on the same level releases the previous one.
sub _exec_svp_release { 1 }

sub _exec_svp_rollback {
  my ($self, $name) = @_;

  local $self->_dbh->{AutoCommit} = 0;
  local $self->_dbh->{BegunWork}  = 1;
  $self->_exec_txn_rollback;
}

1;

# vim:sts=2 sw=2: