fbcd0eadc94eae9cabc4186b37b0e3d06ed4c111
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / ADO / MS_Jet.pm
1 package DBIx::Class::Storage::DBI::ADO::MS_Jet;
2
3 use strict;
4 use warnings;
5
6 use base qw/
7   DBIx::Class::Storage::DBI::ADO
8   DBIx::Class::Storage::DBI::ACCESS
9 /;
10 use mro 'c3';
11
12 use DBIx::Class::Storage::DBI::ADO::CursorUtils '_normalize_guids';
13 use DBIx::Class::ResultSource::FromSpec::Util 'fromspec_columns_info';
14 use namespace::clean;
15
16 __PACKAGE__->cursor_class('DBIx::Class::Storage::DBI::ADO::MS_Jet::Cursor');
17
18 =head1 NAME
19
20 DBIx::Class::Storage::DBI::ADO::MS_Jet - Support for MS Access over ADO
21
22 =head1 DESCRIPTION
23
24 This driver is a subclass of L<DBIx::Class::Storage::DBI::ADO> and
25 L<DBIx::Class::Storage::DBI::ACCESS> for connecting to MS Access via
26 L<DBD::ADO>.
27
28 See the documentation for L<DBIx::Class::Storage::DBI::ACCESS> for
29 information on the MS Access driver for L<DBIx::Class>.
30
31 This driver implements workarounds for C<TEXT/IMAGE/MEMO> columns, sets the
32 L<cursor_class|DBIx::Class::Storage::DBI/cursor_class> to
33 L<DBIx::Class::Storage::DBI::ADO::MS_Jet::Cursor> to normalize returned
34 C<GUID> values and provides L<DBIx::Class::InflateColumn::DateTime> support
35 for C<DATETIME> columns.
36
37 =head1 EXAMPLE DSNs
38
39   # older Access versions:
40   dbi:ADO:Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\rkitover\Documents\access_sample.accdb
41
42   # newer Access versions:
43   dbi:ADO:Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\rkitover\Documents\access_sample.accdb;Persist Security Info=False'
44
45 =head1 TEXT/IMAGE/MEMO COLUMNS
46
47 The ADO driver does not suffer from the
48 L<problems|DBIx::Class::Storage::DBI::ODBC::ACCESS/"TEXT/IMAGE/MEMO COLUMNS">
49 the L<ODBC|DBIx::Class::Storage::DBI::ODBC::ACCESS> driver has with these types
50 of columns. You can use them safely.
51
52 When you execute a C<CREATE TABLE> statement over this driver with a C<TEXT>
53 column, it will be converted to C<MEMO>, while in the
54 L<ODBC|DBIx::Class::Storage::DBI::ODBC::ACCESS> driver it is converted to
55 C<VARCHAR(255)>.
56
57 However, the caveat about L<LongReadLen|DBI/LongReadLen> having to be twice the
58 max size of your largest C<MEMO/TEXT> column C<+1> still applies. L<DBD::ADO>
59 sets L<LongReadLen|DBI/LongReadLen> to a large value by default, so it should be
60 safe to just leave it unset. If you do pass a L<LongReadLen|DBI/LongReadLen> in
61 your L<connect_info|DBIx::Class::Storage::DBI/connect_info>, it will be
62 multiplied by two and C<1> added, just as for the
63 L<ODBC|DBIx::Class::Storage::DBI::ODBC::ACCESS> driver.
64
65 =cut
66
67 # set LongReadLen = LongReadLen * 2 + 1 (see docs on MEMO)
68 sub _run_connection_actions {
69   my $self = shift;
70
71   my $long_read_len = $self->_dbh->{LongReadLen};
72
73 # This is the DBD::ADO default.
74   if ($long_read_len != 2147483647) {
75     $self->_dbh->{LongReadLen} = $long_read_len * 2 + 1;
76   }
77
78   return $self->next::method(@_);
79 }
80
81 # AutoCommit does not get reset properly after transactions for some reason
82 # (probably because of my nested transaction hacks in ACCESS.pm) fix it up
83 # here.
84
85 sub _exec_txn_commit {
86   my $self = shift;
87   $self->next::method(@_);
88   $self->_dbh->{AutoCommit} = $self->_dbh_autocommit
89     if $self->{transaction_depth} == 1;
90 }
91
92 sub _exec_txn_rollback {
93   my $self = shift;
94   $self->next::method(@_);
95   $self->_dbh->{AutoCommit} = $self->_dbh_autocommit
96     if $self->{transaction_depth} == 1;
97 }
98
99 # Fix up GUIDs for ->find, for cursors see the cursor_class above.
100
101 sub select_single {
102   my $self = shift;
103   my ($ident, $select) = @_;
104
105   my @row = $self->next::method(@_);
106
107   return @row unless
108     $self->cursor_class->isa('DBIx::Class::Storage::DBI::ADO::MS_Jet::Cursor');
109
110   my $col_infos = fromspec_columns_info($ident);
111
112   _normalize_guids($select, $col_infos, \@row, $self);
113
114   return @row;
115 }
116
117 sub datetime_parser_type {
118   'DBIx::Class::Storage::DBI::ADO::MS_Jet::DateTime::Format'
119 }
120
121 package # hide from PAUSE
122   DBIx::Class::Storage::DBI::ADO::MS_Jet::DateTime::Format;
123
124 my $datetime_format = '%m/%d/%Y %I:%M:%S %p';
125 my $datetime_parser;
126
127 sub parse_datetime {
128   shift;
129   require DateTime::Format::Strptime;
130   $datetime_parser ||= DateTime::Format::Strptime->new(
131     pattern  => $datetime_format,
132     on_error => 'croak',
133   );
134   return $datetime_parser->parse_datetime(shift);
135 }
136
137 sub format_datetime {
138   shift;
139   require DateTime::Format::Strptime;
140   $datetime_parser ||= DateTime::Format::Strptime->new(
141     pattern  => $datetime_format,
142     on_error => 'croak',
143   );
144   return $datetime_parser->format_datetime(shift);
145 }
146
147 =head1 FURTHER QUESTIONS?
148
149 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
150
151 =head1 COPYRIGHT AND LICENSE
152
153 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
154 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
155 redistribute it and/or modify it under the same terms as the
156 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
157
158 =cut
159
160 1;
161
162 # vim:sts=2 sw=2: