line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DBIx::Class::Storage::DBI::ODBC::ACCESS; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
1785
|
use strict; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
85
|
|
4
|
3
|
|
|
3
|
|
13
|
use warnings; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
86
|
|
5
|
3
|
|
|
|
|
665
|
use base qw/ |
6
|
|
|
|
|
|
|
DBIx::Class::Storage::DBI::ODBC |
7
|
|
|
|
|
|
|
DBIx::Class::Storage::DBI::ACCESS |
8
|
3
|
|
|
3
|
|
12
|
/; |
|
3
|
|
|
|
|
4
|
|
9
|
3
|
|
|
3
|
|
43
|
use mro 'c3'; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
22
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
__PACKAGE__->mk_group_accessors(inherited => |
12
|
|
|
|
|
|
|
'disable_sth_caching_for_image_insert_or_update' |
13
|
|
|
|
|
|
|
); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
__PACKAGE__->disable_sth_caching_for_image_insert_or_update(1); |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 NAME |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
DBIx::Class::Storage::DBI::ODBC::ACCESS - Support specific to MS Access over ODBC |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 DESCRIPTION |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
This class implements support specific to Microsoft Access over ODBC. |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
It is a subclass of L and |
26
|
|
|
|
|
|
|
L, see those classes for more |
27
|
|
|
|
|
|
|
information. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
It is loaded automatically by L when it |
30
|
|
|
|
|
|
|
detects a MS Access back-end. |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
This driver implements workarounds for C and C columns, and |
33
|
|
|
|
|
|
|
L support for C columns. |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 EXAMPLE DSN |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
dbi:ODBC:driver={Microsoft Access Driver (*.mdb, *.accdb)};dbq=C:\Users\rkitover\Documents\access_sample.accdb |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 TEXT/IMAGE/MEMO COLUMNS |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
Avoid using C columns as they will be truncated to 255 bytes. Some other |
42
|
|
|
|
|
|
|
drivers (like L) will automatically |
43
|
|
|
|
|
|
|
convert C columns to C, but the ODBC driver does not. |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
C columns work correctly, but the statements for inserting or updating an |
46
|
|
|
|
|
|
|
C column will not be L, due to a bug in the |
47
|
|
|
|
|
|
|
Access ODBC driver. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
C columns work correctly as well, but you must take care to set |
50
|
|
|
|
|
|
|
L to C<$max_memo_size * 2 + 1>. This is done for |
51
|
|
|
|
|
|
|
you automatically if you pass L in your |
52
|
|
|
|
|
|
|
L; but if you set this |
53
|
|
|
|
|
|
|
attribute directly on the C<$dbh>, keep this limitation in mind. |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=cut |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
# set LongReadLen = LongReadLen * 2 + 1 (see docs on MEMO) |
58
|
|
|
|
|
|
|
sub _run_connection_actions { |
59
|
0
|
|
|
0
|
|
|
my $self = shift; |
60
|
|
|
|
|
|
|
|
61
|
0
|
|
|
|
|
|
my $long_read_len = $self->_dbh->{LongReadLen}; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# 80 is another default (just like 0) on some drivers |
64
|
0
|
0
|
0
|
|
|
|
if ($long_read_len != 0 && $long_read_len != 80) { |
65
|
0
|
|
|
|
|
|
$self->_dbh->{LongReadLen} = $long_read_len * 2 + 1; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# batch operations do not work |
69
|
0
|
|
|
|
|
|
$self->_disable_odbc_array_ops; |
70
|
|
|
|
|
|
|
|
71
|
0
|
|
|
|
|
|
return $self->next::method(@_); |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub insert { |
75
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
76
|
0
|
|
|
|
|
|
my ($source, $to_insert) = @_; |
77
|
|
|
|
|
|
|
|
78
|
0
|
|
|
|
|
|
my $columns_info = $source->columns_info; |
79
|
|
|
|
|
|
|
|
80
|
0
|
|
|
|
|
|
my $is_image_insert = 0; |
81
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
for my $col (keys %$to_insert) { |
83
|
0
|
0
|
|
|
|
|
if ($self->_is_binary_lob_type($columns_info->{$col}{data_type})) { |
84
|
0
|
|
|
|
|
|
$is_image_insert = 1; |
85
|
0
|
|
|
|
|
|
last; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
0
|
0
|
0
|
|
|
|
local $self->{disable_sth_caching} = 1 if $is_image_insert |
90
|
|
|
|
|
|
|
&& $self->disable_sth_caching_for_image_insert_or_update; |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
|
return $self->next::method(@_); |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub update { |
96
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
97
|
0
|
|
|
|
|
|
my ($source, $fields) = @_; |
98
|
|
|
|
|
|
|
|
99
|
0
|
|
|
|
|
|
my $columns_info = $source->columns_info; |
100
|
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
|
my $is_image_insert = 0; |
102
|
|
|
|
|
|
|
|
103
|
0
|
|
|
|
|
|
for my $col (keys %$fields) { |
104
|
0
|
0
|
|
|
|
|
if ($self->_is_binary_lob_type($columns_info->{$col}{data_type})) { |
105
|
0
|
|
|
|
|
|
$is_image_insert = 1; |
106
|
0
|
|
|
|
|
|
last; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
0
|
0
|
0
|
|
|
|
local $self->{disable_sth_caching} = 1 if $is_image_insert |
111
|
|
|
|
|
|
|
&& $self->disable_sth_caching_for_image_insert_or_update; |
112
|
|
|
|
|
|
|
|
113
|
0
|
|
|
|
|
|
return $self->next::method(@_); |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub datetime_parser_type { |
117
|
0
|
|
|
0
|
1
|
|
'DBIx::Class::Storage::DBI::ODBC::ACCESS::DateTime::Format' |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
package # hide from PAUSE |
121
|
|
|
|
|
|
|
DBIx::Class::Storage::DBI::ODBC::ACCESS::DateTime::Format; |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
my $datetime_format = '%Y-%m-%d %H:%M:%S'; # %F %T, no fractional part |
124
|
|
|
|
|
|
|
my $datetime_parser; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub parse_datetime { |
127
|
0
|
|
|
0
|
|
|
shift; |
128
|
0
|
|
|
|
|
|
require DateTime::Format::Strptime; |
129
|
0
|
|
0
|
|
|
|
$datetime_parser ||= DateTime::Format::Strptime->new( |
130
|
|
|
|
|
|
|
pattern => $datetime_format, |
131
|
|
|
|
|
|
|
on_error => 'croak', |
132
|
|
|
|
|
|
|
); |
133
|
0
|
|
|
|
|
|
return $datetime_parser->parse_datetime(shift); |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub format_datetime { |
137
|
0
|
|
|
0
|
|
|
shift; |
138
|
0
|
|
|
|
|
|
require DateTime::Format::Strptime; |
139
|
0
|
|
0
|
|
|
|
$datetime_parser ||= DateTime::Format::Strptime->new( |
140
|
|
|
|
|
|
|
pattern => $datetime_format, |
141
|
|
|
|
|
|
|
on_error => 'croak', |
142
|
|
|
|
|
|
|
); |
143
|
0
|
|
|
|
|
|
return $datetime_parser->format_datetime(shift); |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=head1 FURTHER QUESTIONS? |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
Check the list of L. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
This module is free software L |
153
|
|
|
|
|
|
|
by the L. You can |
154
|
|
|
|
|
|
|
redistribute it and/or modify it under the same terms as the |
155
|
|
|
|
|
|
|
L. |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=cut |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
1; |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# vim:sts=2 sw=2: |