General cleanup of error messages - quote identifiers/names where sensible
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / ACCESS.pm
CommitLineData
726c8f65 1package DBIx::Class::Storage::DBI::ACCESS;
2
3use strict;
4use warnings;
5use base 'DBIx::Class::Storage::DBI::UniqueIdentifier';
6use mro 'c3';
7
696ba760 8use DBI ();
726c8f65 9use List::Util 'first';
10use namespace::clean;
11
12__PACKAGE__->sql_limit_dialect ('Top');
13__PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::ACCESS');
14__PACKAGE__->sql_quote_char ([qw/[ ]/]);
15
16sub sqlt_type { 'ACCESS' }
17
18__PACKAGE__->new_guid(undef);
19
20=head1 NAME
21
22DBIx::Class::Storage::DBI::ACCESS - Support specific to MS Access
23
24=head1 DESCRIPTION
25
26This is the base class for Microsoft Access support.
27
28This driver supports L<last_insert_id|DBIx::Class::Storage::DBI/last_insert_id>,
29empty inserts for tables with C<AUTOINCREMENT> columns, nested transactions via
30L<auto_savepoint|DBIx::Class::Storage::DBI/auto_savepoint>, C<GUID> columns via
31L<DBIx::Class::Storage::DBI::UniqueIdentifier>.
32
33=head1 SUPPORTED VERSIONS
34
35This module has currently only been tested on MS Access 2010.
36
37Information 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.)
39
40=head1 USING GUID COLUMNS
41
42If you have C<GUID> PKs or other C<GUID> columns with
43L<auto_nextval|DBIx::Class::ResultSource/auto_nextval> you will need to set a
44L<new_guid|DBIx::Class::Storage::DBI::UniqueIdentifier/new_guid> callback, like
45so:
46
47 $schema->storage->new_guid(sub { Data::GUID->new->as_string });
48
49Under L<Catalyst> you can use code similar to this in your
50L<Catalyst::Model::DBIC::Schema> C<Model.pm>:
51
52 after BUILD => sub {
53 my $self = shift;
54 $self->storage->new_guid(sub { Data::GUID->new->as_string });
55 };
56
57=cut
58
59sub _dbh_last_insert_id { $_[1]->selectrow_array('select @@identity') }
60
61# support empty insert
62sub insert {
63 my $self = shift;
64 my ($source, $to_insert) = @_;
65
66 my $columns_info = $source->columns_info;
67
68 if (keys %$to_insert == 0) {
69 my $autoinc_col = first {
70 $columns_info->{$_}{is_auto_increment}
71 } keys %$columns_info;
72
e705f529 73 $self->throw_exception(
74 'empty insert only supported for tables with an autoincrement column'
75 ) unless $autoinc_col;
726c8f65 76
77 my $table = $source->from;
78 $table = $$table if ref $table;
79
80 $to_insert->{$autoinc_col} = \"dmax('${autoinc_col}', '${table}')+1";
81 }
82
83 return $self->next::method(@_);
84}
85
86sub bind_attribute_by_data_type {
87 my $self = shift;
88 my ($data_type) = @_;
89
90 my $attributes = $self->next::method(@_) || {};
91
92 if ($self->_is_text_lob_type($data_type)) {
93 $attributes->{TYPE} = DBI::SQL_LONGVARCHAR;
94 }
95 elsif ($self->_is_binary_lob_type($data_type)) {
96 $attributes->{TYPE} = DBI::SQL_LONGVARBINARY;
97 }
98
99 return $attributes;
100}
101
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.
105
90d7422f 106sub _exec_svp_begin {
726c8f65 107 my ($self, $name) = @_;
108
726c8f65 109 local $self->_dbh->{AutoCommit} = 1;
110 local $self->_dbh->{BegunWork} = 0;
90d7422f 111 $self->_exec_txn_begin;
726c8f65 112}
113
114# A new nested transaction on the same level releases the previous one.
90d7422f 115sub _exec_svp_release { 1 }
726c8f65 116
90d7422f 117sub _exec_svp_rollback {
726c8f65 118 my ($self, $name) = @_;
119
726c8f65 120 local $self->_dbh->{AutoCommit} = 0;
121 local $self->_dbh->{BegunWork} = 1;
90d7422f 122 $self->_exec_txn_rollback;
726c8f65 123}
124
1251;
126
127=head1 AUTHOR
128
129See L<DBIx::Class/AUTHOR> and L<DBIx::Class/CONTRIBUTORS>.
130
131=head1 LICENSE
132
133You may distribute this code under the same terms as Perl itself.
134
135=cut
136# vim:sts=2 sw=2: