Introduce GOVERNANCE document and empty RESOLUTIONS file.
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / ACCESS.pm
1 package DBIx::Class::Storage::DBI::ACCESS;
2
3 use strict;
4 use warnings;
5 use base 'DBIx::Class::Storage::DBI::UniqueIdentifier';
6 use mro 'c3';
7
8 use DBI ();
9
10 __PACKAGE__->sql_limit_dialect ('Top');
11 __PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::ACCESS');
12 __PACKAGE__->sql_quote_char ([qw/[ ]/]);
13
14 sub sqlt_type { 'ACCESS' }
15
16 __PACKAGE__->new_guid(undef);
17
18 =head1 NAME
19
20 DBIx::Class::Storage::DBI::ACCESS - Support specific to MS Access
21
22 =head1 DESCRIPTION
23
24 This is the base class for Microsoft Access support.
25
26 This driver supports L<last_insert_id|DBIx::Class::Storage::DBI/last_insert_id>,
27 empty inserts for tables with C<AUTOINCREMENT> columns, nested transactions via
28 L<auto_savepoint|DBIx::Class::Storage::DBI/auto_savepoint>, C<GUID> columns via
29 L<DBIx::Class::Storage::DBI::UniqueIdentifier>.
30
31 =head1 SUPPORTED VERSIONS
32
33 This module has currently only been tested on MS Access 2010.
34
35 Information about how well it works on different version of MS Access is welcome
36 (write the mailing list, or submit a ticket to RT if you find bugs.)
37
38 =head1 USING GUID COLUMNS
39
40 If you have C<GUID> PKs or other C<GUID> columns with
41 L<auto_nextval|DBIx::Class::ResultSource/auto_nextval> you will need to set a
42 L<new_guid|DBIx::Class::Storage::DBI::UniqueIdentifier/new_guid> callback, like
43 so:
44
45   $schema->storage->new_guid(sub { Data::GUID->new->as_string });
46
47 Under L<Catalyst> you can use code similar to this in your
48 L<Catalyst::Model::DBIC::Schema> C<Model.pm>:
49
50   after BUILD => sub {
51     my $self = shift;
52     $self->storage->new_guid(sub { Data::GUID->new->as_string });
53   };
54
55 =cut
56
57 sub _dbh_last_insert_id { $_[1]->selectrow_array('select @@identity') }
58
59 # support empty insert
60 sub insert {
61   my $self = shift;
62   my ($source, $to_insert) = @_;
63
64   my $columns_info = $source->columns_info;
65
66   if (keys %$to_insert == 0) {
67     my ($autoinc_col) = grep {
68       $columns_info->{$_}{is_auto_increment}
69     } keys %$columns_info;
70
71     $self->throw_exception(
72       'empty insert only supported for tables with an autoincrement column'
73     ) unless $autoinc_col;
74
75     my $table = $source->from;
76     $table = $$table if ref $table;
77
78     $to_insert->{$autoinc_col} = \"dmax('${autoinc_col}', '${table}')+1";
79   }
80
81   return $self->next::method(@_);
82 }
83
84 sub bind_attribute_by_data_type {
85   my $self = shift;
86   my ($data_type) = @_;
87
88   my $attributes = $self->next::method(@_) || {};
89
90   if ($self->_is_text_lob_type($data_type)) {
91     $attributes->{TYPE} = DBI::SQL_LONGVARCHAR;
92   }
93   elsif ($self->_is_binary_lob_type($data_type)) {
94     $attributes->{TYPE} = DBI::SQL_LONGVARBINARY;
95   }
96
97   return $attributes;
98 }
99
100 # savepoints are not supported, but nested transactions are.
101 # Unfortunately DBI does not support nested transactions.
102 # WARNING: this code uses the undocumented 'BegunWork' DBI attribute.
103
104 sub _exec_svp_begin {
105   my ($self, $name) = @_;
106
107   local $self->_dbh->{AutoCommit} = 1;
108   local $self->_dbh->{BegunWork}  = 0;
109   $self->_exec_txn_begin;
110 }
111
112 # A new nested transaction on the same level releases the previous one.
113 sub _exec_svp_release { 1 }
114
115 sub _exec_svp_rollback {
116   my ($self, $name) = @_;
117
118   local $self->_dbh->{AutoCommit} = 0;
119   local $self->_dbh->{BegunWork}  = 1;
120   $self->_exec_txn_rollback;
121 }
122
123 =head1 FURTHER QUESTIONS?
124
125 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
126
127 =head1 COPYRIGHT AND LICENSE
128
129 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
130 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
131 redistribute it and/or modify it under the same terms as the
132 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
133
134 =cut
135
136 1;
137
138 # vim:sts=2 sw=2: