Commit | Line | Data |
726c8f65 |
1 | package DBIx::Class::Storage::DBI::ADO::MS_Jet; |
2 | |
3 | use strict; |
4 | use warnings; |
616ca57f |
5 | |
726c8f65 |
6 | use base qw/ |
7 | DBIx::Class::Storage::DBI::ADO |
8 | DBIx::Class::Storage::DBI::ACCESS |
9 | /; |
10 | use mro 'c3'; |
616ca57f |
11 | |
2edf3352 |
12 | use DBIx::Class::Storage::DBI::ADO::CursorUtils '_normalize_guids'; |
616ca57f |
13 | use DBIx::Class::ResultSource::FromSpec::Util 'fromspec_columns_info'; |
2edf3352 |
14 | use namespace::clean; |
726c8f65 |
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 | |
90d7422f |
85 | sub _exec_txn_commit { |
726c8f65 |
86 | my $self = shift; |
87 | $self->next::method(@_); |
88 | $self->_dbh->{AutoCommit} = $self->_dbh_autocommit |
89 | if $self->{transaction_depth} == 1; |
90 | } |
91 | |
90d7422f |
92 | sub _exec_txn_rollback { |
726c8f65 |
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 | |
616ca57f |
110 | my $col_infos = fromspec_columns_info($ident); |
726c8f65 |
111 | |
2edf3352 |
112 | _normalize_guids($select, $col_infos, \@row, $self); |
726c8f65 |
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 | |
a2bd3796 |
147 | =head1 FURTHER QUESTIONS? |
726c8f65 |
148 | |
a2bd3796 |
149 | Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>. |
726c8f65 |
150 | |
a2bd3796 |
151 | =head1 COPYRIGHT AND LICENSE |
726c8f65 |
152 | |
a2bd3796 |
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>. |
726c8f65 |
157 | |
158 | =cut |
a2bd3796 |
159 | |
160 | 1; |
161 | |
726c8f65 |
162 | # vim:sts=2 sw=2: |