better FreeTDS support
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Sybase / NoBindVars.pm
CommitLineData
6b1f5ef7 1package DBIx::Class::Storage::DBI::Sybase::NoBindVars;
5608593e 2
b7505130 3use Class::C3;
5608593e 4use base qw/
5 DBIx::Class::Storage::DBI::NoBindVars
6 DBIx::Class::Storage::DBI::Sybase
7/;
b55e97a7 8use List::Util ();
0c449973 9use Scalar::Util ();
5608593e 10
9b3dabe0 11sub _rebless {
12 my $self = shift;
13 $self->disable_sth_caching(1);
a3a526cc 14 $self->_insert_txn(0);
9b3dabe0 15}
16
285baccb 17# this works when NOT using placeholders
18sub _fetch_identity_sql { 'SELECT @@IDENTITY' }
6b1f5ef7 19
0c449973 20my $number = sub { Scalar::Util::looks_like_number($_[0]) };
21
b88bf40a 22my $decimal = sub { $_[0] =~ /^ [-+]? \d+ (?:\.\d*)? \z/x };
23
b55e97a7 24my %noquote = (
b88bf40a 25 int => sub { $_[0] =~ /^ [-+]? \d+ \z/x },
0c449973 26 bit => => sub { $_[0] =~ /^[01]\z/ },
b88bf40a 27 money => sub { $_[0] =~ /^\$ \d+ (?:\.\d*)? \z/x },
0c449973 28 float => $number,
29 real => $number,
30 double => $number,
b88bf40a 31 decimal => $decimal,
32 numeric => $decimal,
b55e97a7 33);
0c1bedfc 34
7d17f469 35sub should_quote_value {
0c1bedfc 36 my $self = shift;
37 my ($type, $value) = @_;
38
7d17f469 39 return $self->next::method(@_) if not defined $value or not defined $type;
bbdc039b 40
17d750d7 41 if (my $key = List::Util::first { $type =~ /$_/i } keys %noquote) {
42 return 0 if $noquote{$key}->($value);
28cea3aa 43 } elsif ($self->is_datatype_numeric($type) && $number->($value)) {
9b3dabe0 44 return 0;
17d750d7 45 }
0c1bedfc 46
7d17f469 47## try to guess based on value
48# elsif (not $type) {
49# return 0 if $number->($value) || $noquote->{money}->($value);
50# }
51
0c1bedfc 52 return $self->next::method(@_);
53}
54
e06ad5d5 55sub transform_unbound_value {
56 my ($self, $type, $value) = @_;
57
58 if ($type =~ /money/i && defined $value) {
59 $value =~ s/^\$//;
60 $value = '$' . $value;
61 }
62
63 return $value;
64}
65
5608593e 661;
7e8cecc1 67
68=head1 NAME
69
70DBIx::Class::Storage::DBI::Sybase::NoBindVars - Storage::DBI subclass for Sybase
71without placeholder support
72
73=head1 DESCRIPTION
74
75If you're using this driver than your version of Sybase does not support
8c4b6c50 76placeholders, or your version of L<DBD::Sybase> was compiled with FreeTDS rather
77than the Sybase OpenClient libraries. You can check with:
7e8cecc1 78
79 $dbh->{syb_dynamic_supported}
80
8c4b6c50 81To see if you are using FreeTDS, run:
82
ed70dcb7 83 perl -MDBI -le 'my $dbh = DBI->connect($dsn, $user, $pass); print $dbh->{syb_oc_version}'
8c4b6c50 84
22b3249c 85You will get a warning on startup if you're using FreeTDS in any case.
86
7e8cecc1 87You can also enable this driver explicitly using:
88
89 my $schema = SchemaClass->clone;
90 $schema->storage_type('::DBI::Sybase::NoBindVars');
91 $schema->connect($dsn, $user, $pass, \%opts);
92
93See the discussion in L<< DBD::Sybase/Using ? Placeholders & bind parameters to
94$sth->execute >> for details on the pros and cons of using placeholders.
95
96One advantage of not using placeholders is that C<select @@identity> will work
97for obtainging the last insert id of an C<IDENTITY> column, instead of having to
98do C<select max(col)> as the base Sybase driver does.
99
100When using this driver, bind variables will be interpolated (properly quoted of
101course) into the SQL query itself, without using placeholders.
102
103The caching of prepared statements is also explicitly disabled, as the
104interpolation renders it useless.
105
106=head1 AUTHORS
107
108See L<DBIx::Class/CONTRIBUTORS>.
109
110=head1 LICENSE
111
112You may distribute this code under the same terms as Perl itself.
113
114=cut
115# vim:sts=2 sw=2: