1 package DBIx::Class::Storage::DBI::ACCESS;
5 use base 'DBIx::Class::Storage::DBI::UniqueIdentifier';
8 use List::Util 'first';
11 __PACKAGE__->sql_limit_dialect ('Top');
12 __PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::ACCESS');
13 __PACKAGE__->sql_quote_char ([qw/[ ]/]);
15 sub sqlt_type { 'ACCESS' }
17 __PACKAGE__->new_guid(undef);
21 DBIx::Class::Storage::DBI::ACCESS - Support specific to MS Access
25 This is the base class for Microsoft Access support.
27 This driver supports L<last_insert_id|DBIx::Class::Storage::DBI/last_insert_id>,
28 empty inserts for tables with C<AUTOINCREMENT> columns, nested transactions via
29 L<auto_savepoint|DBIx::Class::Storage::DBI/auto_savepoint>, C<GUID> columns via
30 L<DBIx::Class::Storage::DBI::UniqueIdentifier>.
32 =head1 SUPPORTED VERSIONS
34 This module has currently only been tested on MS Access 2010.
36 Information about how well it works on different version of MS Access is welcome
37 (write the mailing list, or submit a ticket to RT if you find bugs.)
39 =head1 USING GUID COLUMNS
41 If you have C<GUID> PKs or other C<GUID> columns with
42 L<auto_nextval|DBIx::Class::ResultSource/auto_nextval> you will need to set a
43 L<new_guid|DBIx::Class::Storage::DBI::UniqueIdentifier/new_guid> callback, like
46 $schema->storage->new_guid(sub { Data::GUID->new->as_string });
48 Under L<Catalyst> you can use code similar to this in your
49 L<Catalyst::Model::DBIC::Schema> C<Model.pm>:
53 $self->storage->new_guid(sub { Data::GUID->new->as_string });
58 sub _dbh_last_insert_id { $_[1]->selectrow_array('select @@identity') }
60 # support empty insert
63 my ($source, $to_insert) = @_;
65 my $columns_info = $source->columns_info;
67 if (keys %$to_insert == 0) {
68 my $autoinc_col = first {
69 $columns_info->{$_}{is_auto_increment}
70 } keys %$columns_info;
72 if (not $autoinc_col) {
73 $self->throw_exception(
74 'empty insert only supported for tables with an autoincrement column'
78 my $table = $source->from;
79 $table = $$table if ref $table;
81 $to_insert->{$autoinc_col} = \"dmax('${autoinc_col}', '${table}')+1";
84 return $self->next::method(@_);
87 sub bind_attribute_by_data_type {
91 my $attributes = $self->next::method(@_) || {};
93 if ($self->_is_text_lob_type($data_type)) {
94 $attributes->{TYPE} = DBI::SQL_LONGVARCHAR;
96 elsif ($self->_is_binary_lob_type($data_type)) {
97 $attributes->{TYPE} = DBI::SQL_LONGVARBINARY;
103 # savepoints are not supported, but nested transactions are.
104 # Unfortunately DBI does not support nested transactions.
105 # WARNING: this code uses the undocumented 'BegunWork' DBI attribute.
108 my ($self, $name) = @_;
110 $self->throw_exception(
111 'cannot BEGIN a nested transaction on a disconnected handle'
112 ) unless $self->_dbh;
114 local $self->_dbh->{AutoCommit} = 1;
115 local $self->_dbh->{BegunWork} = 0;
116 $self->_dbh_begin_work;
119 # A new nested transaction on the same level releases the previous one.
120 sub _svp_release { 1 }
123 my ($self, $name) = @_;
125 $self->throw_exception(
126 'cannot ROLLBACK a nested transaction on a disconnected handle'
127 ) unless $self->_dbh;
129 local $self->_dbh->{AutoCommit} = 0;
130 local $self->_dbh->{BegunWork} = 1;
131 $self->_dbh_rollback;
138 See L<DBIx::Class/AUTHOR> and L<DBIx::Class/CONTRIBUTORS>.
142 You may distribute this code under the same terms as Perl itself.