Author: REHSACK
Date: Mon Jun 14 06:35:16 2010
New Revision: 14142
Modified:
dbi/trunk/lib/DBI/SQL/Nano.pm
Log:
- Fix i18n issue on DROP TABLE error msg parsing (detected by daxim)
- provide support for insert_new_row capability (fixes bug in DBD::DBM)
- port update optimization from SQL::Statement (allowes remove of
push_row from DBD::DBM)
Modified: dbi/trunk/lib/DBI/SQL/Nano.pm
==============================================================================
--- dbi/trunk/lib/DBI/SQL/Nano.pm (original)
+++ dbi/trunk/lib/DBI/SQL/Nano.pm Mon Jun 14 06:35:16 2010
@@ -49,6 +49,17 @@
###################################
use Carp qw(croak);
+use Errno;
+
+if ( eval { require Clone; } )
+{
+ Clone->import("clone");
+}
+else
+{
+ require Storable; # in CORE since 5.7.3
+ *clone = \&Storable::dclone;
+}
sub new
{
@@ -279,6 +290,9 @@
$self->{'NUM_OF_ROWS'} || '0E0';
}
+my $enoentstr = "Cannot open .*\(" . Errno::ENOENT . "\)";
+my $enoentrx = qr/$enoentstr/;
+
sub DROP ($$$)
{
my ( $self, $data, $params ) = @_;
@@ -286,16 +300,16 @@
my $table;
my @err;
eval {
- local $SIG{__WARN__} = sub { push @err, @_ };
- ($table) = $self->open_tables( $data, 0, 1 );
+ local $SIG{__WARN__} = sub { push @err, @_ };
+ ($table) = $self->open_tables( $data, 0, 1 );
};
- if ( $self->{ignore_missing_table} and ($@ or @err) and grep { m/no such
(table|file)/i } (@err, $@) )
+ if ( $self->{ignore_missing_table} and ( $@ or @err ) and grep { $_ =~
$enoentrx } ( @err, $@ ) )
{
- $@ = '';
+ $@ = '';
return ( -1, 0 );
}
- $self->do_err($@ || $err[0]) if ($@ || @err);
+ $self->do_err( $@ || $err[0] ) if ( $@ || @err );
return ( -1, 0 ) unless $table;
$table->drop($data);
@@ -315,7 +329,7 @@
my ( $self, $data, $params ) = @_;
my $table = $self->open_tables( $data, 0, 1 );
$self->verify_columns($table);
- $table->seek( $data, 0, 2 );
+ $table->seek( $data, 0, 2 ) unless ( $table->can('insert_one_row') );
my ($array) = [];
my ( $val, $col, $i );
$self->{column_names} = $table->col_names() unless ( $self->{column_names}
);
@@ -334,8 +348,10 @@
{
croak "Bad col names in INSERT";
}
- $table->push_row( $data, $array );
- ( 1, 0 );
+
+ $table->can('insert_new_row') ? $table->insert_new_row( $data, $array ) :
$table->push_row( $data, $array );
+
+ return ( 1, 0 );
}
sub DELETE ($$$)
@@ -408,14 +424,18 @@
$self->verify_columns($table);
my $tname = $self->{table_name};
my ($affected) = 0;
- my ( @rows, $array, $val, $col, $i );
+ my ( @rows, %cols, $array, $val, $col, $i );
while ( $array = $table->fetch_row($data) )
{
if ( $self->eval_where( $table, $array ) )
{
$array = $self->{fetched_value} if ( $self->{fetched_from_key} );
- my $col_nums = $self->column_nums($table);
- my %cols = reverse %{$col_nums};
+ unless ( keys %cols )
+ {
+ my $col_nums = $self->column_nums($table);
+ %cols = reverse %{$col_nums};
+ }
+
my $rowhash;
for ( sort keys %cols )
{
@@ -460,46 +480,68 @@
my $table = $self->open_tables( $data, 0, 1 );
$self->verify_columns($table);
return undef unless $table;
- my ($affected) = 0;
+ my $affected = 0;
+ my $can_usr = $table->can('update_specific_row');
+ my $can_uor = $table->can('update_one_row');
+ my $can_rwu = $can_usr || $can_uor;
my ( @rows, $array, $f_array, $val, $col, $i );
+
while ( $array = $table->fetch_row($data) )
{
-
if ( $self->eval_where( $table, $array ) )
{
- $array = $self->{fetched_value} if ( $self->{fetched_from_key} and
$table->can('update_one_row') );
- my $col_nums = $self->column_nums($table);
- my %cols = reverse %{$col_nums};
- my $rowhash;
- for ( sort keys %cols )
- {
- $rowhash->{ $cols{$_} } = $array->[$_];
- }
+ $array = $self->{fetched_value} if ( $self->{fetched_from_key} and
$can_rwu );
+ my $orig_ary = clone($array) if ($can_usr);
for ( $i = 0; $i < @{ $self->{column_names} }; $i++ )
{
$col = $self->{column_names}->[$i];
$array->[ $self->column_nums( $table, $col ) ] =
$self->row_values($i);
}
$affected++;
- if ( $self->{fetched_from_key} )
+ if ( $self->{fetched_value} )
{
- $table->update_one_row( $data, $array );
+ if ($can_usr)
+ {
+ $table->update_specific_row( $data, $array, $orig_ary );
+ }
+ elsif ($can_uor)
+ {
+ $table->update_one_row( $data, $array );
+ }
return ( $affected, 0 );
}
- push( @rows, $array );
+ push( @rows, $can_usr ? [ $array, $orig_ary ] : $array );
}
else
{
- push( @rows, $array );
+ push( @rows, $array ) unless ($can_rwu);
}
}
- $table->seek( $data, 0, 0 );
- foreach my $array (@rows)
+ if ($can_rwu)
{
- $table->push_row( $data, $array );
+ foreach my $array (@rows)
+ {
+ if ($can_usr)
+ {
+ $table->update_specific_row( $data, @$array );
+ }
+ elsif ($can_uor)
+ {
+ $table->update_one_row( $data, $array );
+ }
+ }
}
- $table->truncate($data);
- ( $affected, 0 );
+ else
+ {
+ $table->seek( $data, 0, 0 );
+ foreach my $array (@rows)
+ {
+ $table->push_row( $data, $array );
+ }
+ $table->truncate($data);
+ }
+
+ return ( $affected, 0 );
}
sub verify_columns
@@ -557,9 +599,7 @@
sub eval_where
{
- my $self = shift;
- my $table = shift;
- my $rowary = shift;
+ my ( $self, $table, $rowary ) = @_;
my $where = $self->{"where_clause"} || return 1;
my $col_nums = $table->col_nums();
my %cols = reverse %{$col_nums};
@@ -649,8 +689,7 @@
sub params
{
- my $self = shift;
- my $val_num = shift;
+ my ( $self, $val_num ) = @_;
if ( !$self->{"params"} ) { return 0; }
if ( defined $val_num )
{