PApp::SQL - absolutely easy yet fast and powerful sql access |
PApp::SQL - absolutely easy yet fast and powerful sql access
use PApp::SQL;
my $st = sql_exec $DBH, "select ... where a = ?", $a;
local $DBH = <database handle>; my $st = sql_exec \my($bind_a, $bind_b), "select a,b ..."; my $st = sql_insertid sql_exec "insert into ... values (?, ?)", $v1, $v2; my $a = sql_fetch "select a from ..."; sql_fetch \my($a, $b), "select a,b ...";
sql_exists "name from table where name like 'a%'" or die "a* required but not existent";
my $db = new PApp::SQL::Database "", "DBI:mysql:test", "user", "pass"; local $PApp::SQL::DBH = $db->checked_dbh; # does 'ping'
sql_exec $db->dbh, "select ...";
This module provides you with easy-to-use functions to execute sql
commands (using DBI). Despite being easy to use, they are also quite
efficient and allow you to write faster programs in less lines of code. It
should work with anything from perl-5.004_01 onwards, but I only support
5.005+. UTF8 handling (the sql_u*
family of functions) will only be
effective with perl version 5.006 and beyond.
If the descriptions here seem terse or if you always wanted to know what PApp is then have a look at the PApp module which uses this module extensively but also provides you with a lot more gimmicks to play around with to help you create cool applications ;)
sql_exec
family of functions return a statement handle there
must eb another way to test the return value of the execute
call. This
global variable contains the result of the most recent call to execute
done by this module.
$DBH
was
specified as argument and no $DBH
is found in the current package. See
sql_exec
for a discussion.
PApp::SQL::Database
-object. Future versions might
automatically fall back on this database and create database handles from
it if neccessary. At the moment this is not used by this module but might
be nice as a placeholder for the database object that corresponds to
$PApp::SQL::DBH.
Connect to the database given by ($dsn,$user,$pass)
, while using the
flags from $flags
. These are just the same arguments as given to
DBI-
connect>.
The database handle will be cached under the unique id
$id|$dsn|$user|$pass
. If the same id is requested later, the
cached handle will be checked (using ping), and the connection will
be re-established if necessary (be sure to prefix your application or
module name to the id to make it ``more'' unique. Things like __PACKAGE__ .
__LINE__ work fine as well).
The reason $id
is necessary is that you might specify special connect
arguments or special flags, or you might want to configure your $DBH
differently than maybe other applications requesting the same database
connection. If none of this is becessary for your application you can
leave $id empty (i.e. ``'').
If specified, $connect
is a callback (e.g. a coderef) that will be
called each time a new connection is being established, with the new
$dbh
as first argument.
Examples:
# try your luck opening the papp database without access info $dbh = connect_cached __FILE__, "DBI:mysql:papp";
Mysql-specific behaviour: The default setting of mysql_client_found_rows is TRUE, you can overwrite this, though.
sql_exec
is the most important and most-used function in this module.
Runs the given sql command with the given parameters and returns the
statement handle. The command and the statement handle will be cached
(with the database handle and the sql string as key), so prepare will be
called only once for each distinct sql call (please keep in mind that the
returned statement will always be the same, so, if you call sql_exec
with the same dbh and sql-statement twice (e.g. in a subroutine you
called), the statement handle for the first call mustn't be used.
The database handle (the first argument) is optional. If it is missing,
sql_exec
first tries to use the variable $DBH
in the current (=
calling) package and, if that fails, it tries to use database handle in
$PApp::SQL::DBH
, which you can set before calling these functions.
The actual return value from the $sth-
execute> call is stored in the
package-global (and exported) variable $sql_exec
.
If any error occurs sql_exec
will throw an exception.
sql_uexec
is similar to sql_exec
but upgrades all input arguments to
utf8 before calling the execute
method.
Examples:
# easy one my $st = sql_exec "select name, id from table where id = ?", $id; while (my ($name, $id) = $st->fetchrow_array) { ... };
# the fastest way to use dbi, using bind_columns my $st = sql_exec \my($name, $id), "select name, id from table where id = ?", $id; while ($st->fetch) { ...}
# now use a different dastabase: sql_exec $dbh, "update file set name = ?", "oops.txt";
CONTEXT RESULT void () scalar first column list array
sql_fetch
is quite efficient in conjunction with bind variables:
sql_fetch \my($name, $amount), "select name, amount from table where id name = ?", "Toytest";
But of course the normal way to call it is simply:
my($name, $amount) = sql_fetch "select ...", args...
... and it's still quite fast unless you fetch large amounts of data.
sql_ufetch
is similar to sql_fetch
but upgrades all input values to
utf8 and forces all result values to utf8.
sql_fetch
, but all result rows will be fetched (this is
of course inefficient for large results!). The context is ignored (only
list context makes sense), but the result still depends on the number of
columns in the result:
COLUMNS RESULT 0 () 1 (row1, row2, row3...) many ([row1], [row2], [row3]...)
Examples (all of which are inefficient):
for (sql_fetchall "select id from table") { ... }
my @names = sql_fetchall "select name from user";
for (sql_fetchall "select name, age, place from user") { my ($name, $age, $place) = @$_; }
sql_ufetchall
is similar to sql_fetchall
but upgrades all input
values to utf8 and forces all result values to utf8.
sql_uexists
is similar to sql_exists
but upgrades all parameters to
utf8.
Examples:
print "user 7 exists!\n" if sql_exists "user where id = ?", 7;
die "duplicate key" if sql_exists "user where name = ? and pass = ?", "stefan", "geheim";
mysql: first C<AUTO_INCREMENT> column set to NULL postgres: C<oid> column (is there a way to get the last SERIAL?) sybase: C<IDENTITY> column of the last insert (slow) informix: C<SERIAL> or C<SERIAL8> column of the last insert
Except for sybase, this does not require a server access.
sql_exec
. The
default is somewhere around 50 (= the 50 last recently used statements
will be cached). It shouldn't be too large, since a simple linear listed
is used for the cache at the moment (which, for small (<100) cache sizes
is actually quite fast).
The function always returns the cache size in effect before the call, so, to nuke the cache (for example, when a database connection has died or you want to garbage collect old database/statement handles), this construct can be used:
PApp::SQL::cachesize PApp::SQL::cachesize 0;
fork
and other accidents that invalidate
database handles.
Again (sigh) the problem of persistency. What do you do when you have to serialize on object that contains (or should contain) a database handle? Short answer: you don't. Long answer: you can embed the necessary information to recreate the dbh when needed.
The PApp::SQL::Database
class does that, in a relatively efficient
fashion: the overhead is currently a single method call per access (you
can cache the real dbh if you want).
connect_cached
>new
call takes the same arguments as connect_cached
(obviously,
if you supply a connect callback it better is serializable, see
the PApp::Callback manpage!) and returns a serializable database class. No database
handle is actually being created.
PApp.
Marc Lehmann <pcg@goof.com> http://www.goof.com/pcg/marc/
PApp::SQL - absolutely easy yet fast and powerful sql access |