ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/PApp-SQL/SQL.pm
Revision: 1.16
Committed: Sun Apr 22 15:13:58 2001 UTC (23 years, 1 month ago) by root
Branch: MAIN
CVS Tags: papp_last_stable, pre_big_pcode_semantic_change, DEVEL9916
Changes since 1.15: +2 -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.15 $VERSION = 0.123;
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     =cut
129    
130     sub connect_cached {
131     my ($id, $dsn, $user, $pass, $flags, $connect) = @_;
132     # the following line is duplicated in PApp::SQL::Database::new
133     $id = "$id\0$dsn\0$user\0$pass";
134     unless ($dbcache{$id} && $dbcache{$id}->ping) {
135     #warn "connecting to ($dsn|$user|$pass|$flags)\n";#d#
136 root 1.5 # first, nuke our statement cache (sooory ;)
137 root 1.1 cachesize cachesize 0;
138     # then connect anew
139     $dbcache{$id} =
140     eval { DBI->connect($dsn, $user, $pass, $flags) }
141     || eval { DBI->connect($dsn, $user, $pass, $flags) }
142 root 1.5 || die "unable to connect to database $dsn: $DBI::errstr\n";
143 root 1.1 $connect->($dbcache{$id}) if $connect;
144     }
145     $dbcache{$id};
146     }
147    
148     =item $sth = sql_exec [dbh,] [bind-vals...,] "sql-statement", [arguments...]
149    
150 root 1.15 =item $sth = sql_uexec <see sql_exec>
151    
152 root 1.1 C<sql_exec> is the most important and most-used function in this module.
153    
154     Runs the given sql command with the given parameters and returns the
155     statement handle. The command and the statement handle will be cached
156     (with the database handle and the sql string as key), so prepare will be
157     called only once for each distinct sql call (please keep in mind that the
158     returned statement will always be the same, so, if you call C<sql_exec>
159     with the same dbh and sql-statement twice (e.g. in a subroutine you
160     called), the statement handle for the first call mustn't be used.
161    
162     The database handle (the first argument) is optional. If it is missing,
163     C<sql_exec> first tries to use the variable C<$DBH> in the current (=
164     calling) package and, if that fails, it tries to use database handle in
165     C<$PApp::SQL::DBH>, which you can set before calling these functions.
166    
167     The actual return value from the C<$sth->execute> call is stored in the
168     package-global (and exported) variable C<$sql_exec>.
169    
170     If any error occurs C<sql_exec> will throw an exception.
171    
172 root 1.15 C<sql_uexec> is similar to C<sql_exec> but upgrades all input arguments to
173     utf8 before calling the C<execute> method.
174    
175 root 1.1 Examples:
176    
177     # easy one
178     my $st = sql_exec "select name, id from table where id = ?", $id;
179     while (my ($name, $id) = $st->fetchrow_array) { ... };
180    
181     # the fastest way to use dbi, using bind_columns
182     my $st = sql_exec \my($name, $id),
183     "select name, id from table where id = ?",
184     $id;
185     while ($st->fetch) { ...}
186    
187     # now use a different dastabase:
188     sql_exec $dbh, "update file set name = ?", "oops.txt";
189    
190    
191     =item sql_fetch <see sql_exec>
192    
193 root 1.15 =item sql_ufetch <see sql_uexec>
194    
195     Execute an sql-statement and fetch the first row of results. Depending on
196 root 1.1 the caller context the row will be returned as a list (array context), or
197     just the first columns. In table form:
198    
199     CONTEXT RESULT
200     void ()
201     scalar first column
202     list array
203    
204     C<sql_fetch> is quite efficient in conjunction with bind variables:
205    
206     sql_fetch \my($name, $amount),
207     "select name, amount from table where id name = ?",
208     "Toytest";
209    
210     But of course the normal way to call it is simply:
211    
212     my($name, $amount) = sql_fetch "select ...", args...
213    
214     ... and it's still quite fast unless you fetch large amounts of data.
215    
216 root 1.15 C<sql_ufetch> is similar to C<sql_fetch> but upgrades all input values to
217     utf8 and forces all result values to utf8.
218    
219 root 1.1 =item sql_fetchall <see sql_exec>
220    
221 root 1.15 =item sql_ufetchall <see sql_uexec>
222    
223 root 1.1 Similarly to C<sql_fetch>, but all result rows will be fetched (this is
224     of course inefficient for large results!). The context is ignored (only
225     list context makes sense), but the result still depends on the number of
226     columns in the result:
227    
228     COLUMNS RESULT
229     0 ()
230     1 (row1, row2, row3...)
231     many ([row1], [row2], [row3]...)
232    
233     Examples (all of which are inefficient):
234    
235     for (sql_fetchall "select id from table") { ... }
236    
237     my @names = sql_fetchall "select name from user";
238    
239     for (sql_fetchall "select name, age, place from user") {
240     my ($name, $age, $place) = @$_;
241     }
242    
243 root 1.15 C<sql_ufetchall> is similar to C<sql_fetchall> but upgrades all input
244     values to utf8 and forces all result values to utf8.
245    
246 root 1.1 =item sql_exists "<table> where ...", args...
247    
248 root 1.15 =item sql_uexists <see sql_exists>
249    
250 root 1.1 Check wether the result of the sql-statement "select xxx from
251     $first_argument" would be empty or not (that is, imagine the string
252 root 1.13 "select * from" were prepended to your statement (it isn't)). Should work
253 root 1.1 with every database but can be quite slow, except on mysql, where this
254     should be quite fast.
255    
256 root 1.15 C<sql_uexists> is similar to C<sql_exists> but upgrades all parameters to
257     utf8.
258    
259 root 1.1 Examples:
260    
261     print "user 7 exists!\n"
262     if sql_exists "user where id = ?", 7;
263    
264     die "duplicate key"
265     if sql_exists "user where name = ? and pass = ?", "stefan", "geheim";
266    
267     =cut
268    
269 root 1.3 =item $lastid = sql_insertid $sth
270    
271 root 1.8 Returns the last automatically created key value. It must be executed
272     directly after executing the insert statement that created it. This is
273     what is actually returned for various databases. If your database is
274     missing, please send me an e-mail on how to implement this ;)
275    
276     mysql: first C<AUTO_INCREMENT> column set to NULL
277     postgres: C<oid> column (is there a way to get the last SERIAL?)
278     sybase: C<IDENTITY> column of the last insert (slow)
279     informix: C<SERIAL> or C<SERIAL8> column of the last insert
280    
281     Except for sybase, this does not require a server access.
282 root 1.3
283     =cut
284    
285     sub sql_insertid($) {
286     my $sth = shift or die "sql_insertid requires a statement handle";
287     my $dbh = $sth->{Database};
288     my $driver = $dbh->{Driver}{Name};
289    
290 root 1.8 $driver eq "mysql" and return $sth->{mysql_insertid};
291     $driver eq "Pg" and return $sth->{pg_oid_status};
292     $driver eq "Sybase" and return sql_fetch($dbh, 'SELECT @@IDENTITY');
293 root 1.3 $driver eq "Informix" and return $sth->{ix_sqlerrd}[1];
294    
295     die "sql_insertid does not spport the dbd driver '$driver', please see PApp::SQL::sql_insertid";
296 root 1.1 }
297    
298     =item [old-size] = cachesize [new-size]
299    
300     Returns (and possibly changes) the LRU cache size used by C<sql_exec>. The
301     default is somewhere around 50 (= the 50 last recently used statements
302     will be cached). It shouldn't be too large, since a simple linear listed
303     is used for the cache at the moment (which, for small (<100) cache sizes
304     is actually quite fast).
305    
306     The function always returns the cache size in effect I<before> the call,
307     so, to nuke the cache (for example, when a database connection has died
308     or you want to garbage collect old database/statement handles), this
309     construct can be used:
310    
311     PApp::SQL::cachesize PApp::SQL::cachesize 0;
312    
313     =cut
314    
315     =item reinitialize [not exported]
316    
317 root 1.9 Clears any internal caches (statement cache, database handle
318     cache). Should be called after C<fork> and other accidents that invalidate
319     database handles.
320 root 1.1
321     =cut
322    
323     sub reinitialize {
324     cachesize cachesize 0;
325     for (values %dbcache) {
326 root 1.11 eval { $_->{InactiveDestroy} = 1 };
327 root 1.1 }
328     undef %dbcache;
329     }
330    
331     =back
332    
333     =cut
334    
335 root 1.7 reinitialize;
336    
337 root 1.1 package PApp::SQL::Database;
338    
339     =head2 THE DATABASE CLASS
340    
341 root 1.15 Again (sigh) the problem of persistency. What do you do when you have
342     to serialize on object that contains (or should contain) a database
343     handle? Short answer: you don't. Long answer: you can embed the necessary
344     information to recreate the dbh when needed.
345 root 1.1
346     The C<PApp::SQL::Database> class does that, in a relatively efficient
347     fashion: the overhead is currently a single method call per access (you
348     can cache the real dbh if you want).
349    
350     =over 4
351    
352     =item $db = new <same arguments as C<connect_cached>>
353    
354     The C<new> call takes the same arguments as C<connect_cached> (obviously,
355     if you supply a connect callback it better is serializable, see
356     L<PApp::Callback>!) and returns a serializable database class. No database
357     handle is actually being created.
358    
359     =item $db->dbh
360    
361     Return the database handle as fast as possible (usually just a hash lookup).
362    
363     =item $db->checked_dbh
364    
365     Return the database handle, but first check that the database is still
366     available and re-open the connection if necessary.
367    
368     =cut
369    
370     sub new($$;@) {
371     my $class = shift;
372     my ($id, $dsn, $user, $pass, $flags, $connect) = @_;
373     # the following line is duplicated in PApp::SQL::Database::new
374     my $id2 = "$id\0$dsn\0$user\0$pass";
375     bless [$id2, $flags, $connect], $class;
376     }
377    
378     # the following two functions better be fast!
379     sub dbh($) {
380     $dbcache{$_[0][0]} || $_[0]->checked_dbh;
381     }
382    
383     sub checked_dbh($) {
384     my $dbh = $dbcache{$_[0][0]};
385     $dbh && $dbh->ping
386     ? $dbh
387     : PApp::SQL::connect_cached((split /\x00/, $_[0][0]), $_[0][1], $_[0][2]);
388     }
389    
390     =item $db->dsn
391    
392     Return the DSN (L<DBI>) fo the database object (e.g. for error messages).
393    
394 root 1.14 =item $db->login
395    
396     Return the login name.
397    
398     =item $db->password
399    
400     Return the password (emphasizing the fact that the apssword is stored plaintext ;)
401    
402 root 1.1 =cut
403    
404     sub dsn($) {
405     my $self = shift;
406 root 1.9 (split /\x00/, $self->[0])[1];
407 root 1.14 }
408    
409     sub login($) {
410     my $self = shift;
411     (split /\x00/, $self->[0])[2];
412     }
413    
414     sub password($) {
415     my $self = shift;
416     (split /\x00/, $self->[0])[3];
417 root 1.1 }
418    
419     =back
420    
421     =cut
422    
423     1;
424    
425     =head1 SEE ALSO
426    
427     L<PApp>.
428    
429     =head1 AUTHOR
430    
431     Marc Lehmann <pcg@goof.com>
432     http://www.goof.com/pcg/marc/
433    
434     =cut
435