Part one of the sybase work by Caelum (mostly reviewed)
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / AutoCast.pm
CommitLineData
d047d650 1package DBIx::Class::Storage::DBI::AutoCast;
2
3use strict;
4use warnings;
5
6use base qw/DBIx::Class::Storage::DBI/;
7use mro 'c3';
8
9__PACKAGE__->mk_group_accessors('simple' => 'auto_cast' );
10
11=head1 NAME
12
13DBIx::Class::Storage::DBI::AutoCast
14
15=head1 SYNOPSIS
16
17 $schema->storage->auto_cast(1);
18
19=head1 DESCRIPTION
20
ce012195 21In some combinations of RDBMS and DBD drivers (e.g. FreeTDS and Sybase)
22statements with values bound to columns or conditions that are not strings will
23throw implicit type conversion errors.
d047d650 24
25As long as a column L<data_type|DBIx::Class::ResultSource/add_columns> is
0bd2c1cd 26defined, and it resolves to a base RDBMS native type via L</_native_data_type> as
ce012195 27defined in your Storage driver, the placeholder for this column will be
28converted to:
d047d650 29
ce012195 30 CAST(? as $mapped_type)
d047d650 31
d867eeda 32This 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
38sub _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
d867eeda 67=head2 connect_call_set_auto_cast
68
69Executes:
70
71 $schema->storage->auto_cast(1);
72
73on connection.
74
75Used as:
76
77 on_connect_call => ['set_auto_cast']
78
79in L<DBIx::Class::Storage::DBI/connect_info>.
80
81=cut
82
83sub connect_call_set_auto_cast {
84 my $self = shift;
85 $self->auto_cast(1);
86}
d047d650 87
07a5866e 88=head1 AUTHOR
d047d650 89
90See L<DBIx::Class/CONTRIBUTORS>
91
92=head1 LICENSE
93
94You may distribute this code under the same terms as Perl itself.
95
96=cut
97
981;