ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/PApp-SQL/SQL.pm
Revision: 1.18
Committed: Mon Dec 31 03:01:49 2001 UTC (22 years, 4 months ago) by root
Branch: MAIN
Changes since 1.17: +10 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     PApp::SQL - absolutely easy yet fast and powerful sql access
4    
5     =head1 SYNOPSIS
6    
7     use PApp::SQL;
8 root 1.10
9     my $st = sql_exec $DBH, "select ... where a = ?", $a;
10    
11     local $DBH = <database handle>;
12     my $st = sql_exec \my($bind_a, $bind_b), "select a,b ...";
13     my $st = sql_insertid
14     sql_exec "insert into ... values (?, ?)", $v1, $v2;
15     my $a = sql_fetch "select a from ...";
16     sql_fetch \my($a, $b), "select a,b ...";
17    
18     sql_exists "name from table where name like 'a%'"
19     or die "a* required but not existent";
20    
21     my $db = new PApp::SQL::Database "", "DBI:mysql:test", "user", "pass";
22     local $PApp::SQL::DBH = $db->checked_dbh; # does 'ping'
23    
24     sql_exec $db->dbh, "select ...";
25 root 1.1
26     =head1 DESCRIPTION
27    
28     This module provides you with easy-to-use functions to execute sql
29     commands (using DBI). Despite being easy to use, they are also quite
30 root 1.10 efficient and allow you to write faster programs in less lines of code. It
31     should work with anything from perl-5.004_01 onwards, but I only support
32 root 1.15 5.005+. UTF8 handling (the C<sql_u*> family of functions) will only be
33     effective with perl version 5.006 and beyond.
34 root 1.10
35     If the descriptions here seem terse or if you always wanted to know
36     what PApp is then have a look at the PApp module which uses this module
37     extensively but also provides you with a lot more gimmicks to play around
38     with to help you create cool applications ;)
39 root 1.1
40     =cut
41    
42     package PApp::SQL;
43    
44 root 1.10 use DBI ();
45 root 1.1
46     BEGIN {
47 root 1.10 use base qw(Exporter DynaLoader);
48 root 1.1
49 root 1.18 $VERSION = 0.1241;
50 root 1.1 @EXPORT = qw(
51 root 1.16 sql_exec sql_fetch sql_fetchall sql_exists sql_insertid $sql_exec
52     sql_uexec sql_ufetch sql_ufetchall sql_uexists
53 root 1.1 );
54     @EXPORT_OK = qw(
55     connect_cached
56     );
57    
58 root 1.10 bootstrap PApp::SQL $VERSION;
59 root 1.1 }
60    
61     our $sql_exec; # last result of sql_exec's execute call
62     our $DBH; # the default database handle
63 root 1.10 our $Database; # the current SQL::Database object, if applicable
64 root 1.1
65     our %dbcache;
66    
67 root 1.10 =head2 GLOBAL VARIABLES
68    
69     =over 4
70    
71     =item $sql_exec
72    
73     Since the C<sql_exec> family of functions return a statement handle there
74     must eb another way to test the return value of the C<execute> call. This
75     global variable contains the result of the most recent call to C<execute>
76     done by this module.
77    
78     =item $PApp::SQL::DBH
79    
80     The default database handle used by this module if no C<$DBH> was
81     specified as argument and no C<$DBH> is found in the current package. See
82     C<sql_exec> for a discussion.
83    
84     =item $PApp::SQL::Database
85    
86     The current default C<PApp::SQL::Database>-object. Future versions might
87     automatically fall back on this database and create database handles from
88     it if neccessary. At the moment this is not used by this module but might
89     be nice as a placeholder for the database object that corresponds to
90     $PApp::SQL::DBH.
91    
92     =back
93    
94     =head2 FUNCTIONS
95    
96     =over 4
97    
98 root 1.1 =item $dbh = connect_cached $id, $dsn, $user, $pass, $flags, $connect
99    
100     (not exported by by default)
101    
102     Connect to the database given by C<($dsn,$user,$pass)>, while using the
103     flags from C<$flags>. These are just the same arguments as given to
104     C<DBI->connect>.
105    
106 root 1.6 The database handle will be cached under the unique id
107     C<$id|$dsn|$user|$pass>. If the same id is requested later, the
108     cached handle will be checked (using ping), and the connection will
109     be re-established if necessary (be sure to prefix your application or
110     module name to the id to make it "more" unique. Things like __PACKAGE__ .
111     __LINE__ work fine as well).
112    
113     The reason C<$id> is necessary is that you might specify special connect
114     arguments or special flags, or you might want to configure your $DBH
115     differently than maybe other applications requesting the same database
116     connection. If none of this is becessary for your application you can
117     leave $id empty (i.e. "").
118 root 1.1
119     If specified, C<$connect> is a callback (e.g. a coderef) that will be
120     called each time a new connection is being established, with the new
121     C<$dbh> as first argument.
122    
123     Examples:
124    
125     # try your luck opening the papp database without access info
126     $dbh = connect_cached __FILE__, "DBI:mysql:papp";
127    
128 root 1.18 Mysql-specific behaviour: The default setting of mysql_client_found_rows
129     is TRUE, you can overwrite this, though.
130    
131 root 1.1 =cut
132    
133     sub connect_cached {
134     my ($id, $dsn, $user, $pass, $flags, $connect) = @_;
135     # the following line is duplicated in PApp::SQL::Database::new
136     $id = "$id\0$dsn\0$user\0$pass";
137     unless ($dbcache{$id} && $dbcache{$id}->ping) {
138 root 1.5 # first, nuke our statement cache (sooory ;)
139 root 1.1 cachesize cachesize 0;
140 root 1.18
141     # then make mysql behave more standardly by default
142     $dsn =~ /^[Dd][Bb][Ii]:mysql:/
143     and $dsn !~ /;mysql_client_found_rows/
144     and $dsn .= ";mysql_client_found_rows=1";
145    
146 root 1.1 # then connect anew
147     $dbcache{$id} =
148     eval { DBI->connect($dsn, $user, $pass, $flags) }
149     || eval { DBI->connect($dsn, $user, $pass, $flags) }
150 root 1.5 || die "unable to connect to database $dsn: $DBI::errstr\n";
151 root 1.1 $connect->($dbcache{$id}) if $connect;
152     }
153     $dbcache{$id};
154     }
155    
156     =item $sth = sql_exec [dbh,] [bind-vals...,] "sql-statement", [arguments...]
157    
158 root 1.15 =item $sth = sql_uexec <see sql_exec>
159    
160 root 1.1 C<sql_exec> is the most important and most-used function in this module.
161    
162     Runs the given sql command with the given parameters and returns the
163     statement handle. The command and the statement handle will be cached
164     (with the database handle and the sql string as key), so prepare will be
165     called only once for each distinct sql call (please keep in mind that the
166     returned statement will always be the same, so, if you call C<sql_exec>
167     with the same dbh and sql-statement twice (e.g. in a subroutine you
168     called), the statement handle for the first call mustn't be used.
169    
170     The database handle (the first argument) is optional. If it is missing,
171     C<sql_exec> first tries to use the variable C<$DBH> in the current (=
172     calling) package and, if that fails, it tries to use database handle in
173     C<$PApp::SQL::DBH>, which you can set before calling these functions.
174    
175     The actual return value from the C<$sth->execute> call is stored in the
176     package-global (and exported) variable C<$sql_exec>.
177    
178     If any error occurs C<sql_exec> will throw an exception.
179    
180 root 1.15 C<sql_uexec> is similar to C<sql_exec> but upgrades all input arguments to
181     utf8 before calling the C<execute> method.
182    
183 root 1.1 Examples:
184    
185     # easy one
186     my $st = sql_exec "select name, id from table where id = ?", $id;
187     while (my ($name, $id) = $st->fetchrow_array) { ... };
188    
189     # the fastest way to use dbi, using bind_columns
190     my $st = sql_exec \my($name, $id),
191     "select name, id from table where id = ?",
192     $id;
193     while ($st->fetch) { ...}
194    
195     # now use a different dastabase:
196     sql_exec $dbh, "update file set name = ?", "oops.txt";
197    
198    
199     =item sql_fetch <see sql_exec>
200    
201 root 1.15 =item sql_ufetch <see sql_uexec>
202    
203     Execute an sql-statement and fetch the first row of results. Depending on
204 root 1.1 the caller context the row will be returned as a list (array context), or
205     just the first columns. In table form:
206    
207     CONTEXT RESULT
208     void ()
209     scalar first column
210     list array
211    
212     C<sql_fetch> is quite efficient in conjunction with bind variables:
213    
214     sql_fetch \my($name, $amount),
215     "select name, amount from table where id name = ?",
216     "Toytest";
217    
218     But of course the normal way to call it is simply:
219    
220     my($name, $amount) = sql_fetch "select ...", args...
221    
222     ... and it's still quite fast unless you fetch large amounts of data.
223    
224 root 1.15 C<sql_ufetch> is similar to C<sql_fetch> but upgrades all input values to
225     utf8 and forces all result values to utf8.
226    
227 root 1.1 =item sql_fetchall <see sql_exec>
228    
229 root 1.15 =item sql_ufetchall <see sql_uexec>
230    
231 root 1.1 Similarly to C<sql_fetch>, but all result rows will be fetched (this is
232     of course inefficient for large results!). The context is ignored (only
233     list context makes sense), but the result still depends on the number of
234     columns in the result:
235    
236     COLUMNS RESULT
237     0 ()
238     1 (row1, row2, row3...)
239     many ([row1], [row2], [row3]...)
240    
241     Examples (all of which are inefficient):
242    
243     for (sql_fetchall "select id from table") { ... }
244    
245     my @names = sql_fetchall "select name from user";
246    
247     for (sql_fetchall "select name, age, place from user") {
248     my ($name, $age, $place) = @$_;
249     }
250    
251 root 1.15 C<sql_ufetchall> is similar to C<sql_fetchall> but upgrades all input
252     values to utf8 and forces all result values to utf8.
253    
254 root 1.1 =item sql_exists "<table> where ...", args...
255    
256 root 1.15 =item sql_uexists <see sql_exists>
257    
258 root 1.1 Check wether the result of the sql-statement "select xxx from
259     $first_argument" would be empty or not (that is, imagine the string
260 root 1.13 "select * from" were prepended to your statement (it isn't)). Should work
261 root 1.1 with every database but can be quite slow, except on mysql, where this
262     should be quite fast.
263    
264 root 1.15 C<sql_uexists> is similar to C<sql_exists> but upgrades all parameters to
265     utf8.
266    
267 root 1.1 Examples:
268    
269     print "user 7 exists!\n"
270     if sql_exists "user where id = ?", 7;
271    
272     die "duplicate key"
273     if sql_exists "user where name = ? and pass = ?", "stefan", "geheim";
274    
275     =cut
276    
277 root 1.3 =item $lastid = sql_insertid $sth
278    
279 root 1.8 Returns the last automatically created key value. It must be executed
280     directly after executing the insert statement that created it. This is
281     what is actually returned for various databases. If your database is
282     missing, please send me an e-mail on how to implement this ;)
283    
284     mysql: first C<AUTO_INCREMENT> column set to NULL
285     postgres: C<oid> column (is there a way to get the last SERIAL?)
286     sybase: C<IDENTITY> column of the last insert (slow)
287     informix: C<SERIAL> or C<SERIAL8> column of the last insert
288    
289     Except for sybase, this does not require a server access.
290 root 1.3
291     =cut
292    
293     sub sql_insertid($) {
294     my $sth = shift or die "sql_insertid requires a statement handle";
295     my $dbh = $sth->{Database};
296     my $driver = $dbh->{Driver}{Name};
297    
298 root 1.8 $driver eq "mysql" and return $sth->{mysql_insertid};
299     $driver eq "Pg" and return $sth->{pg_oid_status};
300     $driver eq "Sybase" and return sql_fetch($dbh, 'SELECT @@IDENTITY');
301 root 1.3 $driver eq "Informix" and return $sth->{ix_sqlerrd}[1];
302    
303     die "sql_insertid does not spport the dbd driver '$driver', please see PApp::SQL::sql_insertid";
304 root 1.1 }
305    
306     =item [old-size] = cachesize [new-size]
307    
308     Returns (and possibly changes) the LRU cache size used by C<sql_exec>. The
309     default is somewhere around 50 (= the 50 last recently used statements
310     will be cached). It shouldn't be too large, since a simple linear listed
311     is used for the cache at the moment (which, for small (<100) cache sizes
312     is actually quite fast).
313    
314     The function always returns the cache size in effect I<before> the call,
315     so, to nuke the cache (for example, when a database connection has died
316     or you want to garbage collect old database/statement handles), this
317     construct can be used:
318    
319     PApp::SQL::cachesize PApp::SQL::cachesize 0;
320    
321     =cut
322    
323     =item reinitialize [not exported]
324    
325 root 1.9 Clears any internal caches (statement cache, database handle
326     cache). Should be called after C<fork> and other accidents that invalidate
327     database handles.
328 root 1.1
329     =cut
330    
331     sub reinitialize {
332     cachesize cachesize 0;
333     for (values %dbcache) {
334 root 1.11 eval { $_->{InactiveDestroy} = 1 };
335 root 1.1 }
336     undef %dbcache;
337     }
338    
339     =back
340    
341     =cut
342    
343 root 1.7 reinitialize;
344    
345 root 1.1 package PApp::SQL::Database;
346    
347     =head2 THE DATABASE CLASS
348    
349 root 1.15 Again (sigh) the problem of persistency. What do you do when you have
350     to serialize on object that contains (or should contain) a database
351     handle? Short answer: you don't. Long answer: you can embed the necessary
352     information to recreate the dbh when needed.
353 root 1.1
354     The C<PApp::SQL::Database> class does that, in a relatively efficient
355     fashion: the overhead is currently a single method call per access (you
356     can cache the real dbh if you want).
357    
358     =over 4
359    
360     =item $db = new <same arguments as C<connect_cached>>
361    
362     The C<new> call takes the same arguments as C<connect_cached> (obviously,
363     if you supply a connect callback it better is serializable, see
364     L<PApp::Callback>!) and returns a serializable database class. No database
365     handle is actually being created.
366    
367     =item $db->dbh
368    
369     Return the database handle as fast as possible (usually just a hash lookup).
370    
371     =item $db->checked_dbh
372    
373     Return the database handle, but first check that the database is still
374     available and re-open the connection if necessary.
375    
376     =cut
377    
378     sub new($$;@) {
379     my $class = shift;
380     my ($id, $dsn, $user, $pass, $flags, $connect) = @_;
381     # the following line is duplicated in PApp::SQL::Database::new
382     my $id2 = "$id\0$dsn\0$user\0$pass";
383     bless [$id2, $flags, $connect], $class;
384     }
385    
386     # the following two functions better be fast!
387     sub dbh($) {
388     $dbcache{$_[0][0]} || $_[0]->checked_dbh;
389     }
390    
391     sub checked_dbh($) {
392     my $dbh = $dbcache{$_[0][0]};
393     $dbh && $dbh->ping
394     ? $dbh
395     : PApp::SQL::connect_cached((split /\x00/, $_[0][0]), $_[0][1], $_[0][2]);
396     }
397    
398     =item $db->dsn
399    
400     Return the DSN (L<DBI>) fo the database object (e.g. for error messages).
401    
402 root 1.14 =item $db->login
403    
404     Return the login name.
405    
406     =item $db->password
407    
408     Return the password (emphasizing the fact that the apssword is stored plaintext ;)
409    
410 root 1.1 =cut
411    
412     sub dsn($) {
413     my $self = shift;
414 root 1.9 (split /\x00/, $self->[0])[1];
415 root 1.14 }
416    
417     sub login($) {
418     my $self = shift;
419     (split /\x00/, $self->[0])[2];
420     }
421    
422     sub password($) {
423     my $self = shift;
424     (split /\x00/, $self->[0])[3];
425 root 1.1 }
426    
427     =back
428    
429     =cut
430    
431     1;
432    
433     =head1 SEE ALSO
434    
435     L<PApp>.
436    
437     =head1 AUTHOR
438    
439     Marc Lehmann <pcg@goof.com>
440     http://www.goof.com/pcg/marc/
441    
442     =cut
443