Merge 'sybase_noquote' into 'sybase'
Rafael Kitover [Fri, 5 Jun 2009 00:24:46 +0000 (00:24 +0000)]
manually merged in sybase_noquote branch

1  2 
lib/DBIx/Class/Storage/DBI/NoBindVars.pm
lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm

@@@ -64,6 -64,25 +64,25 @@@ sub _prep_for_execute 
    return ($new_sql, []);
  }
  
 -=head2 should_quote_data_type
 -
++=head2 should_quote_data_type   
++                                
+ This method is called by L</_prep_for_execute> for every column in
+ order to determine if its value should be quoted or not. The arguments
+ are the current column data type and the actual bind value. The return
+ value is interpreted as: true - do quote, false - do not quote. You should
+ override this in you Storage::DBI::<database> subclass, if your RDBMS
+ does not like quotes around certain datatypes (e.g. Sybase and integer
+ columns). The default method always returns true (do quote).
 -
 - WARNING!!!
 -
++                                
++ WARNING!!!                     
++                                
+  Always validate that the bind-value is valid for the current datatype.
+  Otherwise you may very well open the door to SQL injection attacks.
 -
 -=cut
 -
++                                
++=cut                            
++                                
+ sub should_quote_data_type { 1 }
  =head1 AUTHORS
  
  Brandon Black <blblack@gmail.com>
index 1f5dfc4,0000000..ed6f75c
mode 100644,000000..100644
--- /dev/null
@@@ -1,59 -1,0 +1,79 @@@
 +package DBIx::Class::Storage::DBI::Sybase::NoBindVars;
 +
 +use Class::C3;
 +use base qw/
 +  DBIx::Class::Storage::DBI::NoBindVars
 +  DBIx::Class::Storage::DBI::Sybase
 +/;
 +
 +sub _dbh_last_insert_id {
 +  my ($self, $dbh, $source, $col) = @_;
 +
 +  # @@identity works only if not using placeholders
 +  # Should this query be cached?
 +  return ($dbh->selectrow_array('select @@identity'))[0];
 +}
 +
++my $noquote = {
++    int => qr/^ \-? \d+ $/x,
++    integer => qr/^ \-? \d+ $/x,
++    # TODO maybe need to add float/real/etc
++};
++
++sub should_quote_data_type {
++  my $self = shift;
++  my ($type, $value) = @_;
++
++  return $self->next::method(@_) if not defined $value;
++
++  if (my $re = $noquote->{$type}) {
++    return 0 if $value =~ $re;
++  }
++
++  return $self->next::method(@_);
++}
++
++
 +1;
 +
 +=head1 NAME
 +
 +DBIx::Class::Storage::DBI::Sybase::NoBindVars - Storage::DBI subclass for Sybase
 +without placeholder support
 +
 +=head1 DESCRIPTION
 +
 +If you're using this driver than your version of Sybase does not support
 +placeholders. You can check with:
 +
 +  $dbh->{syb_dynamic_supported}
 +
 +You can also enable this driver explicitly using:
 +
 +  my $schema = SchemaClass->clone;
 +  $schema->storage_type('::DBI::Sybase::NoBindVars');
 +  $schema->connect($dsn, $user, $pass, \%opts);
 +
 +See the discussion in L<< DBD::Sybase/Using ? Placeholders & bind parameters to
 +$sth->execute >> for details on the pros and cons of using placeholders.
 +
 +One advantage of not using placeholders is that C<select @@identity> will work
 +for obtainging the last insert id of an C<IDENTITY> column, instead of having to
 +do C<select max(col)> as the base Sybase driver does.
 +
 +When using this driver, bind variables will be interpolated (properly quoted of
 +course) into the SQL query itself, without using placeholders.
 +
 +The caching of prepared statements is also explicitly disabled, as the
 +interpolation renders it useless.
 +
 +=head1 AUTHORS
 +
 +See L<DBIx::Class/CONTRIBUTORS>.
 +
 +=head1 LICENSE
 +
 +You may distribute this code under the same terms as Perl itself.
 +
 +=cut
 +# vim:sts=2 sw=2: