1 package DBIx::Class::Storage::DBI::ACCESS;
5 use base 'DBIx::Class::Storage::DBI::UniqueIdentifier';
9 use List::Util 'first';
12 __PACKAGE__->sql_limit_dialect ('Top');
13 __PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::ACCESS');
14 __PACKAGE__->sql_quote_char ([qw/[ ]/]);
16 sub sqlt_type { 'ACCESS' }
18 __PACKAGE__->new_guid(undef);
22 DBIx::Class::Storage::DBI::ACCESS - Support specific to MS Access
26 This is the base class for Microsoft Access support.
28 This driver supports L<last_insert_id|DBIx::Class::Storage::DBI/last_insert_id>,
29 empty inserts for tables with C<AUTOINCREMENT> columns, nested transactions via
30 L<auto_savepoint|DBIx::Class::Storage::DBI/auto_savepoint>, C<GUID> columns via
31 L<DBIx::Class::Storage::DBI::UniqueIdentifier>.
33 =head1 SUPPORTED VERSIONS
35 This module has currently only been tested on MS Access 2010.
37 Information about how well it works on different version of MS Access is welcome
38 (write the mailing list, or submit a ticket to RT if you find bugs.)
40 =head1 USING GUID COLUMNS
42 If you have C<GUID> PKs or other C<GUID> columns with
43 L<auto_nextval|DBIx::Class::ResultSource/auto_nextval> you will need to set a
44 L<new_guid|DBIx::Class::Storage::DBI::UniqueIdentifier/new_guid> callback, like
47 $schema->storage->new_guid(sub { Data::GUID->new->as_string });
49 Under L<Catalyst> you can use code similar to this in your
50 L<Catalyst::Model::DBIC::Schema> C<Model.pm>:
54 $self->storage->new_guid(sub { Data::GUID->new->as_string });
59 sub _dbh_last_insert_id { $_[1]->selectrow_array('select @@identity') }
61 # support empty insert
64 my ($source, $to_insert) = @_;
66 my $columns_info = $source->columns_info;
68 if (keys %$to_insert == 0) {
69 my $autoinc_col = first {
70 $columns_info->{$_}{is_auto_increment}
71 } keys %$columns_info;
73 $self->throw_exception(
74 'empty insert only supported for tables with an autoincrement column'
75 ) unless $autoinc_col;
77 my $table = $source->from;
78 $table = $$table if ref $table;
80 $to_insert->{$autoinc_col} = \"dmax('${autoinc_col}', '${table}')+1";
83 return $self->next::method(@_);
86 sub bind_attribute_by_data_type {
90 my $attributes = $self->next::method(@_) || {};
92 if ($self->_is_text_lob_type($data_type)) {
93 $attributes->{TYPE} = DBI::SQL_LONGVARCHAR;
95 elsif ($self->_is_binary_lob_type($data_type)) {
96 $attributes->{TYPE} = DBI::SQL_LONGVARBINARY;
102 # savepoints are not supported, but nested transactions are.
103 # Unfortunately DBI does not support nested transactions.
104 # WARNING: this code uses the undocumented 'BegunWork' DBI attribute.
106 sub _exec_svp_begin {
107 my ($self, $name) = @_;
109 local $self->_dbh->{AutoCommit} = 1;
110 local $self->_dbh->{BegunWork} = 0;
111 $self->_exec_txn_begin;
114 # A new nested transaction on the same level releases the previous one.
115 sub _exec_svp_release { 1 }
117 sub _exec_svp_rollback {
118 my ($self, $name) = @_;
120 local $self->_dbh->{AutoCommit} = 0;
121 local $self->_dbh->{BegunWork} = 1;
122 $self->_exec_txn_rollback;
125 =head1 FURTHER QUESTIONS?
127 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
129 =head1 COPYRIGHT AND LICENSE
131 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
132 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
133 redistribute it and/or modify it under the same terms as the
134 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.