[Bps-public-commit] dbix-searchbuilder branch, cud-from-select, created. 1.59-9-gbc97240
Ruslan Zakirov
ruz at bestpractical.com
Sun Mar 27 19:37:32 EDT 2011
The branch, cud-from-select has been created
at bc9724006933fbc870dacefa9d37d6fd9a24b4e5 (commit)
- Log -----------------------------------------------------------------
commit c351dfc0cf7f4e0ee7c1129db12a078a7e2857fb
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Sat Mar 26 04:20:46 2011 +0300
SimpleUpdateFromSelect method in SB::Handle
diff --git a/lib/DBIx/SearchBuilder/Handle.pm b/lib/DBIx/SearchBuilder/Handle.pm
index 51f1e8d..0bb91aa 100755
--- a/lib/DBIx/SearchBuilder/Handle.pm
+++ b/lib/DBIx/SearchBuilder/Handle.pm
@@ -473,6 +473,35 @@ sub UpdateTableValue {
return $self->UpdateRecordValue(%args)
}
+=head1 SimpleUpdateFromSelect
+
+Takes table name, hash reference with (column, value) pairs,
+select query and list of bind values.
+
+Updates the table, but only records with IDs returned by the
+selected query, eg:
+
+ UPDATE $table SET %values WHERE id IN ( $query )
+
+It's simple as values are static and search only allowed
+by id.
+
+=cut
+
+sub SimpleUpdateFromSelect {
+ my ($self, $table, $values, $query, @query_binds) = @_;
+
+ my @columns; my @binds;
+ while ( my ($k, $v) = each %$values ) {
+ push @columns, $k;
+ push @binds, $v;
+ }
+
+ my $full_query = "UPDATE $table SET ";
+ $full_query .= join ' AND ', map "$_ = ?", @columns;
+ $full_query .= ' WHERE id IN ('. $query .')';
+ return $self->SimpleQuery( $full_query, @binds );
+}
=head2 SimpleQuery QUERY_STRING, [ BIND_VALUE, ... ]
diff --git a/lib/DBIx/SearchBuilder/Handle/mysql.pm b/lib/DBIx/SearchBuilder/Handle/mysql.pm
index efaac1a..4fd3240 100755
--- a/lib/DBIx/SearchBuilder/Handle/mysql.pm
+++ b/lib/DBIx/SearchBuilder/Handle/mysql.pm
@@ -50,6 +50,50 @@ sub Insert {
}
+=head2 SimpleUpdateFromSelect
+
+Customization of L<DBIx::SearchBuilder::Handle/SimpleUpdateFromSelect>.
+Mysql doesn't support update with subqueries when those fetch data from
+the table that is updated.
+
+=cut
+
+sub SimpleUpdateFromSelect {
+ my ($self, $table, $values, $query, @query_binds) = @_;
+
+ return $self->SUPER::SimpleUpdateFromSelect(
+ $table, $values, $query, @query_binds
+ ) unless $query =~ /\b\Q$table\E\b/i;
+
+ my $sth = $self->SimpleQuery( $query, @query_binds );
+ return $sth unless $sth;
+
+ my (@binds, @columns);
+ while ( my ($k, $v) = each %$values ) {
+ push @columns, $k;
+ push @binds, $v;
+ }
+
+ my $update_query = "UPDATE $table SET "
+ . join( ' AND ', map "$_ = ?", @columns )
+ .' WHERE ID IN ';
+
+ my @ids;
+ while ( my $id = ($sth->fetchrow_array)[0] ) {
+ push @ids, $id;
+ next if @ids < 100;
+
+ my $q = $update_query .'('. join( ',', ('?')x at ids ) .')';
+ my $sth = $self->SimpleQuery( $q, @binds, splice @ids );
+ return $sth unless $sth;
+ }
+ if ( @ids ) {
+ my $q = $update_query .'('. join( ',', ('?')x at ids ) .')';
+ my $sth = $self->SimpleQuery( $q, @binds, splice @ids );
+ return $sth unless $sth;
+ }
+ return 1;
+}
=head2 DatabaseVersion
commit 3993ae988587e8733052944634a648e9bdb1275d
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Mon Mar 28 03:25:06 2011 +0400
DeleteFromSelect method
diff --git a/lib/DBIx/SearchBuilder/Handle.pm b/lib/DBIx/SearchBuilder/Handle.pm
index 0bb91aa..52f9427 100755
--- a/lib/DBIx/SearchBuilder/Handle.pm
+++ b/lib/DBIx/SearchBuilder/Handle.pm
@@ -503,6 +503,29 @@ sub SimpleUpdateFromSelect {
return $self->SimpleQuery( $full_query, @binds );
}
+=head1 DeleteFromSelect
+
+Takes table name, select query and list of bind values.
+
+Deletes from the table, but only records with IDs returned by the
+select query, eg:
+
+ DELETE FROM $table WHERE id IN ($query)
+
+=cut
+
+sub DeleteFromSelect {
+ my ($self, $table, $query, @binds) = @_;
+ my $sth = $self->SimpleQuery(
+ "DELETE FROM $table WHERE id IN ($query)",
+ @binds
+ );
+ return $sth unless $sth;
+
+ my $rows = $sth->rows;
+ return $rows == 0? '0E0' : $rows;
+}
+
=head2 SimpleQuery QUERY_STRING, [ BIND_VALUE, ... ]
Execute the SQL string specified in QUERY_STRING
commit ea17703152a118f0192dab94722196ece72adbef
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Mon Mar 28 03:25:54 2011 +0400
return number of affected rows from new *FromSelect methods
diff --git a/lib/DBIx/SearchBuilder/Handle.pm b/lib/DBIx/SearchBuilder/Handle.pm
index 52f9427..e53d10c 100755
--- a/lib/DBIx/SearchBuilder/Handle.pm
+++ b/lib/DBIx/SearchBuilder/Handle.pm
@@ -401,7 +401,11 @@ sub InsertFromSelect {
my $full_query = "INSERT INTO $table";
$full_query .= " ($columns)" if $columns;
$full_query .= ' '. $query;
- return $self->SimpleQuery( $full_query, @binds );
+ my $sth = $self->SimpleQuery( $full_query, @binds );
+ return $sth unless $sth;
+
+ my $rows = $sth->rows;
+ return $rows == 0? '0E0' : $rows;
}
=head2 UpdateRecordValue
@@ -500,7 +504,11 @@ sub SimpleUpdateFromSelect {
my $full_query = "UPDATE $table SET ";
$full_query .= join ' AND ', map "$_ = ?", @columns;
$full_query .= ' WHERE id IN ('. $query .')';
- return $self->SimpleQuery( $full_query, @binds );
+ my $sth = $self->SimpleQuery( $full_query, @binds );
+ return $sth unless $sth;
+
+ my $rows = $sth->rows;
+ return $rows == 0? '0E0' : $rows;
}
=head1 DeleteFromSelect
commit d4bfb7ba7d7bb6598c8b0016331e6144efd2c85e
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Mon Mar 28 03:27:19 2011 +0400
custom Delete and Update from select for mysql
* use one generic method for both
* process 1000 records at a time
* return number of rows
diff --git a/lib/DBIx/SearchBuilder/Handle/mysql.pm b/lib/DBIx/SearchBuilder/Handle/mysql.pm
index 4fd3240..c300df2 100755
--- a/lib/DBIx/SearchBuilder/Handle/mysql.pm
+++ b/lib/DBIx/SearchBuilder/Handle/mysql.pm
@@ -78,21 +78,56 @@ sub SimpleUpdateFromSelect {
. join( ' AND ', map "$_ = ?", @columns )
.' WHERE ID IN ';
+ return $self->SimpleMassChangeFromSelect(
+ $update_query, \@binds,
+ $query, @query_binds
+ );
+}
+
+
+sub DeleteFromSelect {
+ my ($self, $table, $query, @query_binds) = @_;
+
+ return $self->SUPER::DeleteFromSelect(
+ $table, $query, @query_binds
+ ) unless $query =~ /\b\Q$table\E\b/i;
+
+ my $sth = $self->SimpleQuery( $query, @query_binds );
+ return $sth unless $sth;
+
+ return $self->SimpleMassChangeFromSelect(
+ "DELETE FROM $table WHERE id IN ", [],
+ $query, @query_binds
+ );
+}
+
+sub SimpleMassChangeFromSelect {
+ my ($self, $update_query, $update_binds, $search, @search_binds) = @_;
+
+ my $sth = $self->SimpleQuery( $search, @search_binds );
+ return $sth unless $sth;
+
+ my $res = 0;
+
my @ids;
while ( my $id = ($sth->fetchrow_array)[0] ) {
push @ids, $id;
- next if @ids < 100;
+ next if @ids < 1000;
my $q = $update_query .'('. join( ',', ('?')x at ids ) .')';
- my $sth = $self->SimpleQuery( $q, @binds, splice @ids );
+ my $sth = $self->SimpleQuery( $q, @$update_binds, splice @ids );
return $sth unless $sth;
+
+ $res += @ids;
}
if ( @ids ) {
my $q = $update_query .'('. join( ',', ('?')x at ids ) .')';
- my $sth = $self->SimpleQuery( $q, @binds, splice @ids );
+ my $sth = $self->SimpleQuery( $q, @$update_binds, splice @ids );
return $sth unless $sth;
+
+ $res += @ids;
}
- return 1;
+ return $res == 0? '0E0': $res;
}
=head2 DatabaseVersion
commit bc9724006933fbc870dacefa9d37d6fd9a24b4e5
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Mon Mar 28 03:36:13 2011 +0400
comment why we don't use temporary tables for mass ops
diff --git a/lib/DBIx/SearchBuilder/Handle/mysql.pm b/lib/DBIx/SearchBuilder/Handle/mysql.pm
index c300df2..f619139 100755
--- a/lib/DBIx/SearchBuilder/Handle/mysql.pm
+++ b/lib/DBIx/SearchBuilder/Handle/mysql.pm
@@ -107,6 +107,10 @@ sub SimpleMassChangeFromSelect {
my $sth = $self->SimpleQuery( $search, @search_binds );
return $sth unless $sth;
+
+ # tried TEMPORARY tables, much slower than fetching and delete
+ # also size of ENGINE=MEMORY is limitted by option, on disk
+ # tables more slower than in memory
my $res = 0;
my @ids;
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list