Commit | Line | Data |
d047d650 |
1 | package DBIx::Class::Storage::DBI::AutoCast; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
6 | use base qw/DBIx::Class::Storage::DBI/; |
7 | use mro 'c3'; |
8 | |
9 | __PACKAGE__->mk_group_accessors('simple' => 'auto_cast' ); |
10 | |
11 | =head1 NAME |
12 | |
13 | DBIx::Class::Storage::DBI::AutoCast |
14 | |
15 | =head1 SYNOPSIS |
16 | |
17 | $schema->storage->auto_cast(1); |
18 | |
19 | =head1 DESCRIPTION |
20 | |
ce012195 |
21 | In some combinations of RDBMS and DBD drivers (e.g. FreeTDS and Sybase) |
22 | statements with values bound to columns or conditions that are not strings will |
23 | throw implicit type conversion errors. |
d047d650 |
24 | |
25 | As long as a column L<data_type|DBIx::Class::ResultSource/add_columns> is |
0bd2c1cd |
26 | defined, and it resolves to a base RDBMS native type via L</_native_data_type> as |
ce012195 |
27 | defined in your Storage driver, the placeholder for this column will be |
28 | converted to: |
d047d650 |
29 | |
ce012195 |
30 | CAST(? as $mapped_type) |
d047d650 |
31 | |
07a5866e |
32 | This option can also be enabled in L<DBIx::Class::Storage::DBI/connect_info> as: |
33 | |
34 | on_connect_call => ['set_auto_cast'] |
35 | |
d047d650 |
36 | =cut |
37 | |
38 | sub _prep_for_execute { |
39 | my $self = shift; |
40 | my ($op, $extra_bind, $ident, $args) = @_; |
41 | |
42 | my ($sql, $bind) = $self->next::method (@_); |
43 | |
44 | # If we're using ::NoBindVars, there are no binds by this point so this code |
45 | # gets skippeed. |
46 | if ($self->auto_cast && @$bind) { |
47 | my $new_sql; |
48 | my @sql_part = split /\?/, $sql; |
49 | my $col_info = $self->_resolve_column_info($ident,[ map $_->[0], @$bind ]); |
50 | |
51 | foreach my $bound (@$bind) { |
52 | my $col = $bound->[0]; |
0bd2c1cd |
53 | my $type = $self->_native_data_type($col_info->{$col}{data_type}); |
d047d650 |
54 | |
a7741335 |
55 | foreach my $data (@{$bound}[1..$#$bound]) { |
d047d650 |
56 | $new_sql .= shift(@sql_part) . |
ce012195 |
57 | ($type ? "CAST(? AS $type)" : '?'); |
d047d650 |
58 | } |
59 | } |
60 | $new_sql .= join '', @sql_part; |
61 | $sql = $new_sql; |
62 | } |
63 | |
64 | return ($sql, $bind); |
65 | } |
66 | |
07a5866e |
67 | =head2 connect_call_set_auto_cast |
68 | |
69 | Executes: |
70 | |
71 | $schema->storage->auto_cast(1); |
72 | |
73 | on connection. |
74 | |
75 | Used as: |
76 | |
77 | on_connect_call => ['set_auto_cast'] |
78 | |
79 | in L<DBIx::Class::Storage::DBI/connect_info>. |
80 | |
81 | =cut |
82 | |
83 | sub connect_call_set_auto_cast { |
84 | my $self = shift; |
85 | $self->auto_cast(1); |
86 | } |
d047d650 |
87 | |
07a5866e |
88 | =head1 AUTHOR |
d047d650 |
89 | |
90 | See L<DBIx::Class/CONTRIBUTORS> |
91 | |
92 | =head1 LICENSE |
93 | |
94 | You may distribute this code under the same terms as Perl itself. |
95 | |
96 | =cut |
97 | |
98 | 1; |