adding transactional support and preapred statements to WebGUI::SQL

This commit is contained in:
JT Smith 2004-07-05 03:42:46 +00:00
parent 3da0a252ce
commit 2b63ab6878
2 changed files with 145 additions and 31 deletions

View file

@ -29,8 +29,8 @@
WSClient. WSClient.
- Adding form param WSClient_skipCache when posting to WSClient wobject - Adding form param WSClient_skipCache when posting to WSClient wobject
allows us to ignore even good soap return caches (mostly for testing use) allows us to ignore even good soap return caches (mostly for testing use)
- Moved to a compiled internationalization and help system. At a cost of 3 - Moved to a compiled internationalization and help system. At a cost of 400
megabytes of RAM, it provides a boost in performance of over 35%. More kilobytes of RAM, it provides a boost in performance of over 35%. More
importantly though, it cuts the number of database queries in half on an importantly though, it cuts the number of database queries in half on an
average page, which leads to much greater scalability. See average page, which leads to much greater scalability. See
docs/migration.txt for API changes. docs/migration.txt for API changes.
@ -47,6 +47,9 @@
type in the same form. type in the same form.
- Sped up the page editing page by 50% by rearranging the javascript on the - Sped up the page editing page by 50% by rearranging the javascript on the
page. page.
- Added prepared statement handlers to WebGUI::SQL.
- Added transaction handlers to WebGUI::SQL.
- Added additional debugging to WebGUI::SQL.
6.0.3 6.0.3

View file

@ -36,7 +36,10 @@ Package for interfacing with SQL databases. This package implements Perl DBI fun
=head1 SYNOPSIS =head1 SYNOPSIS
use WebGUI::SQL; use WebGUI::SQL;
$sth = WebGUI::SQL->new($sql);
my $sth = WebGUI::SQL->prepare($sql);
$sth->execute(@values);
$sth = WebGUI::SQL->read($sql); $sth = WebGUI::SQL->read($sql);
$sth = WebGUI::SQL->unconditionalRead($sql); $sth = WebGUI::SQL->unconditionalRead($sql);
@arr = $sth->array; @arr = $sth->array;
@ -46,6 +49,12 @@ Package for interfacing with SQL databases. This package implements Perl DBI fun
$num = $sth->rows; $num = $sth->rows;
$sth->finish; $sth->finish;
WebGUI::SQL->write($sql);
WebGUI::SQL->beginTransaction;
WebGUI::SQL->commit;
WebGUI::SQL->rollback;
@arr = WebGUI::SQL->buildArray($sql); @arr = WebGUI::SQL->buildArray($sql);
$arrayRef = WebGUI::SQL->buildArrayRef($sql); $arrayRef = WebGUI::SQL->buildArrayRef($sql);
%hash = WebGUI::SQL->buildHash($sql); %hash = WebGUI::SQL->buildHash($sql);
@ -56,8 +65,6 @@ Package for interfacing with SQL databases. This package implements Perl DBI fun
$hashRef = WebGUI::SQL->quickHashRef($sql); $hashRef = WebGUI::SQL->quickHashRef($sql);
$text = WebGUI::SQL->quickTab($sql); $text = WebGUI::SQL->quickTab($sql);
WebGUI::SQL->write($sql);
$id = getNextId("wobjectId"); $id = getNextId("wobjectId");
$string = quote($string); $string = quote($string);
@ -81,6 +88,29 @@ sub array {
} }
#-------------------------------------------------------------------
=head2 beginTransaction ( [ dbh ])
Starts a transaction sequence. To be used with commit and rollback. Any writes after this point will not be applied to the database until commit is called.
=over
=item dbh
A database handler. Defaults to the WebGUI default database handler.
=back
=cut
sub beginTransaction {
my $class = shift;
my $dbh = shift;
$dbh->begin_work;
}
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 buildArray ( sql [, dbh ] ) =head2 buildArray ( sql [, dbh ] )
@ -200,6 +230,29 @@ sub buildHashRef {
} }
#-------------------------------------------------------------------
=head2 commit ( [ dbh ])
Ends a transaction sequence. To be used with beginTransaction. Applies all of the writes since beginTransaction to the database.
=over
=item dbh
A database handler. Defaults to the WebGUI default database handler.
=back
=cut
sub commit {
my $class = shift;
my $dbh = shift;
$dbh->commit;
}
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 errorCode { =head2 errorCode {
@ -226,11 +279,33 @@ sub errorMessage {
} }
#-------------------------------------------------------------------
=head2 execute ( values )
Executes a prepared SQL statement.
=over
=item values
A list of values to be used in the placeholders defined in the prepared statement.
=back
=cut
sub execute {
my $self = shift;
$self->{_sth}->execute(@_) or WebGUI::ErrorHandler::fatalError("Couldn't execute prepared statement: ". DBI->errstr);
}
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 finish ( ) =head2 finish ( )
Ends a query after calling the "new" or "read" methods. Ends a query after calling the "read" method.
=cut =cut
@ -354,37 +429,37 @@ sub hashRef {
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 new ( sql [, dbh ] ) =head2 prepare ( sql [, dbh ] ) {
Constructor. Returns a statement handler. Returns a statement handler. To be used in creating prepared statements. Use with the execute method.
=over =over
=item sql =item sql
An SQL query. An SQL statement. Can use the "?" placeholder for maximum performance on multiple statements with the execute method.
=item dbh =item dbh
By default this method uses the WebGUI database handler. However, you may choose to pass in your own if you wish. A database handler. Defaults to the WebGUI default database handler.
=back =back
=cut =cut
sub new { sub prepare {
my $class = shift; my $class = shift;
my $sql = shift; my $sql = shift;
my $dbh = shift || $WebGUI::Session::session{dbh}; my $dbh = shift || $WebGUI::Session::session{dbh};
if ($WebGUI::Session::session{setting}{showDebug}) { if ($WebGUI::Session::session{setting}{showDebug}) {
push(@{$WebGUI::Session::session{SQLquery}},$sql); push(@{$WebGUI::Session::session{SQLquery}},$sql);
} }
my $sth = $dbh->prepare($sql) or WebGUI::ErrorHandler::fatalError("Couldn't prepare statement: ".$sql." : ". DBI->errstr); my $sth = $dbh->prepare($sql) or WebGUI::ErrorHandler::fatalError("Couldn't prepare statement: ".$sql." : ". DBI->errstr);
$sth->execute or WebGUI::ErrorHandler::fatalError("Couldn't execute statement: ".$sql." : ". DBI->errstr);
bless ({_sth => $sth}, $class); bless ({_sth => $sth}, $class);
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 quickArray ( sql [, dbh ] ) =head2 quickArray ( sql [, dbh ] )
@ -407,7 +482,7 @@ By default this method uses the WebGUI database handler. However, you may choose
sub quickArray { sub quickArray {
my ($sth, @data); my ($sth, @data);
$sth = WebGUI::SQL->new($_[1],$_[2]); $sth = WebGUI::SQL->read($_[1],$_[2]);
@data = $sth->array; @data = $sth->array;
$sth->finish; $sth->finish;
return @data; return @data;
@ -436,7 +511,7 @@ By default this method uses the WebGUI database handler. However, you may choose
sub quickCSV { sub quickCSV {
my ($sth, $output, @data); my ($sth, $output, @data);
$sth = WebGUI::SQL->new($_[1],$_[2]); $sth = WebGUI::SQL->read($_[1],$_[2]);
$output = join(",",$sth->getColumnNames)."\n"; $output = join(",",$sth->getColumnNames)."\n";
while (@data = $sth->array) { while (@data = $sth->array) {
makeArrayCommaSafe(\@data); makeArrayCommaSafe(\@data);
@ -469,7 +544,7 @@ By default this method uses the WebGUI database handler. However, you may choose
sub quickHash { sub quickHash {
my ($sth, $data); my ($sth, $data);
$sth = WebGUI::SQL->new($_[1],$_[2]); $sth = WebGUI::SQL->read($_[1],$_[2]);
$data = $sth->hashRef; $data = $sth->hashRef;
$sth->finish; $sth->finish;
if (defined $data) { if (defined $data) {
@ -503,7 +578,7 @@ sub quickHashRef {
my $self = shift; my $self = shift;
my $sql = shift; my $sql = shift;
my $dbh = shift; my $dbh = shift;
my $sth = WebGUI::SQL->new($sql,$dbh); my $sth = WebGUI::SQL->read($sql,$dbh);
my $data = $sth->hashRef; my $data = $sth->hashRef;
$sth->finish; $sth->finish;
if (defined $data) { if (defined $data) {
@ -535,7 +610,7 @@ By default this method uses the WebGUI database handler. However, you may choose
sub quickTab { sub quickTab {
my ($sth, $output, @data); my ($sth, $output, @data);
$sth = WebGUI::SQL->new($_[1],$_[2]); $sth = WebGUI::SQL->read($_[1],$_[2]);
$output = join("\t",$sth->getColumnNames)."\n"; $output = join("\t",$sth->getColumnNames)."\n";
while (@data = $sth->array) { while (@data = $sth->array) {
makeArrayTabSafe(\@data); makeArrayTabSafe(\@data);
@ -573,7 +648,7 @@ sub quote {
=head2 read ( sql [, dbh ] ) =head2 read ( sql [, dbh ] )
An alias of the "new" method. Returns a statement handler. Returns a statement handler. This is a utility method that runs both a prepare and execute all in one.
=over =over
@ -590,7 +665,35 @@ By default this method uses the WebGUI database handler. However, you may choose
=cut =cut
sub read { sub read {
return WebGUI::SQL->new($_[1],$_[2],$_[3]); my $class = shift;
my $sql = shift;
my $dbh = shift;
my $sth = WebGUI::SQL->prepare($sql, $dbh);
$sth->execute;
return $sth;
}
#-------------------------------------------------------------------
=head2 rollback ( [ dbh ])
Ends a transaction sequence. To be used with beginTransaction. Cancels all of the writes since beginTransaction.
=over
=item dbh
A database handler. Defaults to the WebGUI default database handler.
=back
=cut
sub rollback {
my $class = shift;
my $dbh = shift;
$dbh->rollback;
} }
@ -675,12 +778,16 @@ By default this method uses the WebGUI database handler. However, you may choose
=cut =cut
sub unconditionalRead { sub unconditionalRead {
my ($sth,$dbh); my $class = shift;
$dbh = $_[2] || $WebGUI::Session::session{dbh}; my $sql = shift;
$sth = $dbh->prepare($_[1]) or WebGUI::ErrorHandler::warn("Unconditional read failed: ".$_[1]." : ".DBI->errstr); my $dbh = shift || $WebGUI::Session::session{dbh};
if ($WebGUI::Session::session{setting}{showDebug}) {
push(@{$WebGUI::Session::session{SQLquery}},$sql);
}
my $sth = $dbh->prepare($sql) or WebGUI::ErrorHandler::warn("Unconditional read failed: ".$sql." : ".DBI->errstr);
if ($sth) { if ($sth) {
$sth->execute or WebGUI::ErrorHandler::warn("Unconditional read failed: ".$_[1]." : ".DBI->errstr); $sth->execute or WebGUI::ErrorHandler::warn("Unconditional read failed: ".$sql." : ".DBI->errstr);
bless ({_sth => $sth}, $_[0]); bless ({_sth => $sth}, $class);
} }
} }
@ -689,7 +796,7 @@ sub unconditionalRead {
=head2 write ( sql [, dbh ] ) =head2 write ( sql [, dbh ] )
A method specifically designed for writing to the database in an efficient manner. Writing can be accomplished using the "new" method, but it is not as efficient. A method specifically designed for writing to the database in an efficient manner.
=over =over
@ -706,9 +813,13 @@ By default this method uses the WebGUI database handler. However, you may choose
=cut =cut
sub write { sub write {
my ($dbh); my $class = shift;
$dbh = $_[2] || $WebGUI::Session::session{dbh}; my $sql = shift;
$dbh->do($_[1]) or WebGUI::ErrorHandler::fatalError("Couldn't prepare statement: ".$_[1]." : ". DBI->errstr); my $dbh = shift || $WebGUI::Session::session{dbh};
if ($WebGUI::Session::session{setting}{showDebug}) {
push(@{$WebGUI::Session::session{SQLquery}},$sql);
}
$dbh->do($sql) or WebGUI::ErrorHandler::fatalError("Couldn't write to the database: ".$sql." : ". DBI->errstr);
} }