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