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