ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/PApp-SQL/SQL.pm
Revision: 1.21
Committed: Wed Feb 27 04:32:39 2002 UTC (22 years, 2 months ago) by root
Branch: MAIN
CVS Tags: Klinik_Kis_25032002_2245
Changes since 1.20: +6 -3 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.19 PApp::SQL - absolutely easy yet fast and powerful sql access.
4 root 1.1
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 root 1.20 sql_exists "table where name like 'a%'"
19 root 1.10 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.21 $VERSION = 0.13;
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.19 Mysql-specific behaviour: The default setting of
129     C<mysql_client_found_rows> is TRUE, you can overwrite this, though.
130 root 1.18
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 root 1.21 utf8 and forces all result values to utf8 (this does I<not> include result
226     parameters, only return values. Using bind variables in cinjunction with
227     sql_u* functions results in undefined behaviour).
228 root 1.15
229 root 1.1 =item sql_fetchall <see sql_exec>
230    
231 root 1.15 =item sql_ufetchall <see sql_uexec>
232    
233 root 1.1 Similarly to C<sql_fetch>, but all result rows will be fetched (this is
234     of course inefficient for large results!). The context is ignored (only
235     list context makes sense), but the result still depends on the number of
236     columns in the result:
237    
238     COLUMNS RESULT
239     0 ()
240     1 (row1, row2, row3...)
241     many ([row1], [row2], [row3]...)
242    
243     Examples (all of which are inefficient):
244    
245     for (sql_fetchall "select id from table") { ... }
246    
247     my @names = sql_fetchall "select name from user";
248    
249     for (sql_fetchall "select name, age, place from user") {
250     my ($name, $age, $place) = @$_;
251     }
252    
253 root 1.15 C<sql_ufetchall> is similar to C<sql_fetchall> but upgrades all input
254 root 1.21 values to utf8 and forces all result values to utf8 (see the caveats in
255     the description of C<sql_ufetch>, though).
256 root 1.15
257 root 1.20 =item sql_exists "<table_references> where <where_condition>...", args...
258 root 1.1
259 root 1.15 =item sql_uexists <see sql_exists>
260    
261 root 1.1 Check wether the result of the sql-statement "select xxx from
262     $first_argument" would be empty or not (that is, imagine the string
263 root 1.13 "select * from" were prepended to your statement (it isn't)). Should work
264 root 1.1 with every database but can be quite slow, except on mysql, where this
265     should be quite fast.
266    
267 root 1.15 C<sql_uexists> is similar to C<sql_exists> but upgrades all parameters to
268     utf8.
269    
270 root 1.1 Examples:
271    
272     print "user 7 exists!\n"
273     if sql_exists "user where id = ?", 7;
274    
275     die "duplicate key"
276     if sql_exists "user where name = ? and pass = ?", "stefan", "geheim";
277    
278     =cut
279    
280 root 1.3 =item $lastid = sql_insertid $sth
281    
282 root 1.8 Returns the last automatically created key value. It must be executed
283     directly after executing the insert statement that created it. This is
284     what is actually returned for various databases. If your database is
285     missing, please send me an e-mail on how to implement this ;)
286    
287     mysql: first C<AUTO_INCREMENT> column set to NULL
288     postgres: C<oid> column (is there a way to get the last SERIAL?)
289     sybase: C<IDENTITY> column of the last insert (slow)
290     informix: C<SERIAL> or C<SERIAL8> column of the last insert
291    
292     Except for sybase, this does not require a server access.
293 root 1.3
294     =cut
295    
296     sub sql_insertid($) {
297     my $sth = shift or die "sql_insertid requires a statement handle";
298     my $dbh = $sth->{Database};
299     my $driver = $dbh->{Driver}{Name};
300    
301 root 1.8 $driver eq "mysql" and return $sth->{mysql_insertid};
302     $driver eq "Pg" and return $sth->{pg_oid_status};
303     $driver eq "Sybase" and return sql_fetch($dbh, 'SELECT @@IDENTITY');
304 root 1.3 $driver eq "Informix" and return $sth->{ix_sqlerrd}[1];
305    
306     die "sql_insertid does not spport the dbd driver '$driver', please see PApp::SQL::sql_insertid";
307 root 1.1 }
308    
309     =item [old-size] = cachesize [new-size]
310    
311     Returns (and possibly changes) the LRU cache size used by C<sql_exec>. The
312     default is somewhere around 50 (= the 50 last recently used statements
313     will be cached). It shouldn't be too large, since a simple linear listed
314     is used for the cache at the moment (which, for small (<100) cache sizes
315     is actually quite fast).
316    
317     The function always returns the cache size in effect I<before> the call,
318     so, to nuke the cache (for example, when a database connection has died
319     or you want to garbage collect old database/statement handles), this
320     construct can be used:
321    
322     PApp::SQL::cachesize PApp::SQL::cachesize 0;
323    
324     =cut
325    
326     =item reinitialize [not exported]
327    
328 root 1.9 Clears any internal caches (statement cache, database handle
329     cache). Should be called after C<fork> and other accidents that invalidate
330     database handles.
331 root 1.1
332     =cut
333    
334     sub reinitialize {
335     cachesize cachesize 0;
336     for (values %dbcache) {
337 root 1.11 eval { $_->{InactiveDestroy} = 1 };
338 root 1.1 }
339     undef %dbcache;
340     }
341    
342     =back
343    
344     =cut
345    
346 root 1.7 reinitialize;
347    
348 root 1.1 package PApp::SQL::Database;
349    
350     =head2 THE DATABASE CLASS
351    
352 root 1.15 Again (sigh) the problem of persistency. What do you do when you have
353     to serialize on object that contains (or should contain) a database
354     handle? Short answer: you don't. Long answer: you can embed the necessary
355     information to recreate the dbh when needed.
356 root 1.1
357     The C<PApp::SQL::Database> class does that, in a relatively efficient
358     fashion: the overhead is currently a single method call per access (you
359     can cache the real dbh if you want).
360    
361     =over 4
362    
363     =item $db = new <same arguments as C<connect_cached>>
364    
365     The C<new> call takes the same arguments as C<connect_cached> (obviously,
366     if you supply a connect callback it better is serializable, see
367     L<PApp::Callback>!) and returns a serializable database class. No database
368     handle is actually being created.
369    
370     =item $db->dbh
371    
372     Return the database handle as fast as possible (usually just a hash lookup).
373    
374     =item $db->checked_dbh
375    
376     Return the database handle, but first check that the database is still
377     available and re-open the connection if necessary.
378    
379     =cut
380    
381     sub new($$;@) {
382     my $class = shift;
383     my ($id, $dsn, $user, $pass, $flags, $connect) = @_;
384     # the following line is duplicated in PApp::SQL::Database::new
385     my $id2 = "$id\0$dsn\0$user\0$pass";
386     bless [$id2, $flags, $connect], $class;
387     }
388    
389     # the following two functions better be fast!
390     sub dbh($) {
391     $dbcache{$_[0][0]} || $_[0]->checked_dbh;
392     }
393    
394     sub checked_dbh($) {
395     my $dbh = $dbcache{$_[0][0]};
396     $dbh && $dbh->ping
397     ? $dbh
398     : PApp::SQL::connect_cached((split /\x00/, $_[0][0]), $_[0][1], $_[0][2]);
399     }
400    
401     =item $db->dsn
402    
403     Return the DSN (L<DBI>) fo the database object (e.g. for error messages).
404    
405 root 1.14 =item $db->login
406    
407     Return the login name.
408    
409     =item $db->password
410    
411     Return the password (emphasizing the fact that the apssword is stored plaintext ;)
412    
413 root 1.1 =cut
414    
415     sub dsn($) {
416     my $self = shift;
417 root 1.9 (split /\x00/, $self->[0])[1];
418 root 1.14 }
419    
420     sub login($) {
421     my $self = shift;
422     (split /\x00/, $self->[0])[2];
423     }
424    
425     sub password($) {
426     my $self = shift;
427     (split /\x00/, $self->[0])[3];
428 root 1.1 }
429    
430     =back
431    
432     =cut
433    
434     1;
435    
436     =head1 SEE ALSO
437    
438     L<PApp>.
439    
440     =head1 AUTHOR
441    
442     Marc Lehmann <pcg@goof.com>
443     http://www.goof.com/pcg/marc/
444    
445     =cut
446