I was wrong about 2d12a809 - the crash is real
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / NoBindVars.pm
CommitLineData
3885cff6 1package DBIx::Class::Storage::DBI::NoBindVars;
2
3use strict;
4use warnings;
5
6use base 'DBIx::Class::Storage::DBI';
2ad62d97 7use mro 'c3';
3885cff6 8
fcb7fcbb 9use DBIx::Class::SQLMaker::LimitDialects;
10use List::Util qw/first/;
11
12use namespace::clean;
13
14=head1 NAME
b43345f2 15
16DBIx::Class::Storage::DBI::NoBindVars - Sometime DBDs have poor to no support for bind variables
17
18=head1 DESCRIPTION
19
20This class allows queries to work when the DBD or underlying library does not
21support the usual C<?> placeholders, or at least doesn't support them very
22well, as is the case with L<DBD::Sybase>
23
24=head1 METHODS
25
b33697ef 26=head2 connect_info
b43345f2 27
b33697ef 28We can't cache very effectively without bind variables, so force the C<disable_sth_caching> setting to be turned on when the connect info is set.
b43345f2 29
30=cut
31
b33697ef 32sub connect_info {
33 my $self = shift;
d944c5ae 34 my $retval = $self->next::method(@_);
b33697ef 35 $self->disable_sth_caching(1);
36 $retval;
b43345f2 37}
38
d5130dd2 39=head2 _prep_for_execute
b43345f2 40
d5130dd2 41Manually subs in the values for the usual C<?> placeholders.
b43345f2 42
43=cut
44
d5130dd2 45sub _prep_for_execute {
46 my $self = shift;
b50a5275 47
d944c5ae 48 my ($sql, $bind) = $self->next::method(@_);
49
7c63f828 50 # stringify bind args, quote via $dbh, and manually insert
0e773352 51 #my ($op, $ident, $args) = @_;
52 my $ident = $_[1];
d944c5ae 53
b4474f31 54 my @sql_part = split /\?/, $sql;
55 my $new_sql;
56
0e773352 57 for (@$bind) {
abe9977d 58 my $data = (ref $_->[1]) ? "$_->[1]" : $_->[1]; # always stringify, array types are currently not supported
b55e97a7 59
abe9977d 60 my $datatype = $_->[0]{sqlt_datatype};
b55e97a7 61
0e773352 62 $data = $self->_prep_interpolated_value($datatype, $data)
63 if $datatype;
6636ad53 64
0e773352 65 $data = $self->_get_dbh->quote($data)
abe9977d 66 unless ($datatype and $self->interpolate_unquoted($datatype, $data) );
e06ad5d5 67
0e773352 68 $new_sql .= shift(@sql_part) . $data;
d944c5ae 69 }
0e773352 70
b4474f31 71 $new_sql .= join '', @sql_part;
d5130dd2 72
01c04b1b 73 return ($new_sql, []);
3885cff6 74}
75
80007f97 76=head2 interpolate_unquoted
e06ad5d5 77
148e3b50 78This method is called by L</_prep_for_execute> for every column in
79order to determine if its value should be quoted or not. The arguments
80are the current column data type and the actual bind value. The return
80007f97 81value is interpreted as: true - do not quote, false - do quote. You should
148e3b50 82override this in you Storage::DBI::<database> subclass, if your RDBMS
83does not like quotes around certain datatypes (e.g. Sybase and integer
fcb7fcbb 84columns). The default method returns false, except for integer datatypes
85paired with values containing nothing but digits.
e06ad5d5 86
0ac07712 87 WARNING!!!
e06ad5d5 88
148e3b50 89 Always validate that the bind-value is valid for the current datatype.
90 Otherwise you may very well open the door to SQL injection attacks.
e06ad5d5 91
0ac07712 92=cut
e06ad5d5 93
80007f97 94sub interpolate_unquoted {
0ac07712 95 #my ($self, $datatype, $value) = @_;
fcb7fcbb 96
97 return 1 if (
98 defined $_[2]
99 and
100 $_[1]
101 and
102 $_[2] !~ /\D/
103 and
104 $_[1] =~ /int(?:eger)? | (?:tiny|small|medium|big)int/ix
105 );
106
80007f97 107 return 0;
0ac07712 108}
148e3b50 109
166c6561 110=head2 _prep_interpolated_value
e06ad5d5 111
112Given a datatype and the value to be inserted directly into a SQL query, returns
0ac07712 113the necessary string to represent that value (by e.g. adding a '$' sign)
e06ad5d5 114
115=cut
116
166c6561 117sub _prep_interpolated_value {
0ac07712 118 #my ($self, $datatype, $value) = @_;
119 return $_[2];
120}
e06ad5d5 121
3885cff6 122=head1 AUTHORS
123
0ac07712 124See L<DBIx::Class/CONTRIBUTORS>
3885cff6 125
126=head1 LICENSE
127
128You may distribute this code under the same terms as Perl itself.
129
130=cut
b43345f2 131
1321;