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