| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
=head1 NAME |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
DBD::Sprite - Perl extension for DBI, providing database emmulation via flat files. |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 AUTHOR |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
This module is Copyright (C) 2000 by |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
Jim Turner |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
Email: jim.turner@lmco.com |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
All rights reserved. |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
You may distribute this module under the terms of either the GNU General |
|
16
|
|
|
|
|
|
|
Public License or the Artistic License, as specified in the Perl README |
|
17
|
|
|
|
|
|
|
file. |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
JSprite.pm is a derived work by Jim Turner from Sprite.pm, a module |
|
20
|
|
|
|
|
|
|
written and copyrighted (c) 1995-1998, by Shishir Gurdavaram |
|
21
|
|
|
|
|
|
|
(shishir@ora.com). |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
use DBI; |
|
26
|
|
|
|
|
|
|
$dbh = DBI->connect("DBI:Sprite:spritedb",'user','password') |
|
27
|
|
|
|
|
|
|
or die "Cannot connect: " . $DBI::errstr; |
|
28
|
|
|
|
|
|
|
$sth = $dbh->prepare("CREATE TABLE a (id INTEGER, name CHAR(10))") |
|
29
|
|
|
|
|
|
|
or die "Cannot prepare: " . $dbh->errstr(); |
|
30
|
|
|
|
|
|
|
$sth->execute() or die "Cannot execute: " . $sth->errstr(); |
|
31
|
|
|
|
|
|
|
$sth->finish(); |
|
32
|
|
|
|
|
|
|
$dbh->disconnect(); |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
DBD::Sprite is a DBI extension module adding database emulation via flat-files |
|
37
|
|
|
|
|
|
|
to Perl's database-independent database interface. Unlike other DBD::modules, |
|
38
|
|
|
|
|
|
|
DBD::Sprite does not require you to purchase or obtain a database. Every |
|
39
|
|
|
|
|
|
|
thing you need to prototype database-independent applications using Perl and |
|
40
|
|
|
|
|
|
|
DBI are included here. You will, however, probably wish to obtain a real |
|
41
|
|
|
|
|
|
|
database, such as "mysql", for your production and larger data needs. This |
|
42
|
|
|
|
|
|
|
is because emulating databases and SQL with flat text files gets very slow as |
|
43
|
|
|
|
|
|
|
the size of your "database" grows to a non-trivial size (a few dozen records |
|
44
|
|
|
|
|
|
|
or so per table). |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
DBD::Sprite is built upon an old Perl module called "Sprite", written by |
|
47
|
|
|
|
|
|
|
Shishir Gurdavaram. This code was used as a starting point. It was completly |
|
48
|
|
|
|
|
|
|
reworked and many new features were added, producing a module called |
|
49
|
|
|
|
|
|
|
"JSprite.pm" (Jim Turner's Sprite). This was then merged in to DBI::DBD to |
|
50
|
|
|
|
|
|
|
produce what you are installing now. (DBD::Sprite). JSprite.pm is included |
|
51
|
|
|
|
|
|
|
in this module as a separate file, and is required. |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
Many thanks go to Mr. Gurdavaram. |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
The main advantage of DBD::Sprite is the ability to develop and test |
|
56
|
|
|
|
|
|
|
prototype applications on personal machines (or other machines which do not |
|
57
|
|
|
|
|
|
|
have an Oracle licence or some other "mainstream" database) before releasing |
|
58
|
|
|
|
|
|
|
them on "production" machines which do have a "real" database. This can all |
|
59
|
|
|
|
|
|
|
be done with minimal or no changes to your Perl code. |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
Another advantage of DBD::Sprite is that you can use Perl's regular |
|
62
|
|
|
|
|
|
|
expressions to search through your data. Maybe, someday, more "real" |
|
63
|
|
|
|
|
|
|
databases will include this feature too! |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
DBD::Sprite provides the ability to emulate basic database tables |
|
66
|
|
|
|
|
|
|
and SQL calls via flat-files. The primary use envisioned |
|
67
|
|
|
|
|
|
|
for this to permit website developers who can not afford |
|
68
|
|
|
|
|
|
|
to purchase an Oracle licence to prototype and develop Perl |
|
69
|
|
|
|
|
|
|
applications on their own equipment for later hosting at |
|
70
|
|
|
|
|
|
|
larger customer sites where Oracle is used. :-) |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
DBD::Sprite attempts to do things in as database-independent manner as possible, |
|
73
|
|
|
|
|
|
|
but where differences occurr, JSprite most closely emmulates Oracle, for |
|
74
|
|
|
|
|
|
|
example "sequences/autonumbering". JSprite uses tiny one-line text files |
|
75
|
|
|
|
|
|
|
called "sequence files" (.seq). and "seq_file_name.NEXTVAL" function to |
|
76
|
|
|
|
|
|
|
insert into autonumbered fields. The reason for this is that the Author |
|
77
|
|
|
|
|
|
|
works in an Oracle shop and wrote this module to allow himself to work on |
|
78
|
|
|
|
|
|
|
code on his PC, and machines which did not have Oracle on them, since |
|
79
|
|
|
|
|
|
|
obtaining Oracle licences was sometimes time-consuming. |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
DBD::Sprite is similar to DBD::CSV, but differs in the following ways: |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
1) It creates and works on true "databases" with user-ids and passwords, |
|
84
|
|
|
|
|
|
|
real datatypes like numeric, varchar, blob, etc. with max. precisions and |
|
85
|
|
|
|
|
|
|
scales. |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
2) The database author specifies the field delimiters, record delimiters, |
|
88
|
|
|
|
|
|
|
user, password, table file path, AND extension for each database. |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
3) Transactions (commits and rollbacks) are fully supported! |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
4) Autonumbering and user-defined functions are supported. |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
5) You don't need any other modules or databases. (NO prerequisites |
|
95
|
|
|
|
|
|
|
except Perl 5 and the DBI module! |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
6) Quotes are not used around data. |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
7) It is not necessary to call the "$dbh->quote()" method all the time |
|
100
|
|
|
|
|
|
|
in your sql. |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
8) NULL is handled as an empty string. |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
9) Users can "register" their own data-conversion functions for use in |
|
105
|
|
|
|
|
|
|
sql. See "fn_register" method below. |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
10) Optional data encryption. |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
11) Optional table storage in XML format. |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
12) Two-table joins now supported! |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=head1 INSTALLATION |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
Installing this module (and the prerequisites from above) is quite |
|
117
|
|
|
|
|
|
|
simple. You just fetch the archive, extract it with |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
gzip -cd DBD-Sprite-0.1000.tar.gz | tar xf - |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
(this is for Unix users, Windows users would prefer WinZip or something |
|
122
|
|
|
|
|
|
|
similar) and then enter the following: |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
cd DBD-Sprite-#.### |
|
125
|
|
|
|
|
|
|
perl Makefile.PL |
|
126
|
|
|
|
|
|
|
make |
|
127
|
|
|
|
|
|
|
make test |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
If any tests fail, let me know. Otherwise go on with |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
make install |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
Note that you almost definitely need root or administrator permissions. |
|
134
|
|
|
|
|
|
|
If you don't have them, read the ExtUtils::MakeMaker man page for |
|
135
|
|
|
|
|
|
|
details on installing in your own directories. the ExtUtils::MakeMaker |
|
136
|
|
|
|
|
|
|
manpage. |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
NOTE: You may also need to copy "makesdb.pl" to /usr/local/bin or |
|
139
|
|
|
|
|
|
|
somewhere in your path. |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head1 GETTING STARTED: |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
1) cd to where you wish to store your database. |
|
144
|
|
|
|
|
|
|
2) run makesdb.pl to create your database, ie. |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Database name: mydb |
|
147
|
|
|
|
|
|
|
Database user: me |
|
148
|
|
|
|
|
|
|
User password: mypassword |
|
149
|
|
|
|
|
|
|
Database path: . |
|
150
|
|
|
|
|
|
|
Table file extension (default .stb): |
|
151
|
|
|
|
|
|
|
Record delimiter (default \n): |
|
152
|
|
|
|
|
|
|
Field delimiter (default ::): |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
This will create a new database text file (mydb.sdb) in the current |
|
155
|
|
|
|
|
|
|
directory. This ascii file contains the information you enterred |
|
156
|
|
|
|
|
|
|
above. To add additional user-spaces, simply rerun makesdb.pl with |
|
157
|
|
|
|
|
|
|
"mydb" as your database name, and enter additional users (name, |
|
158
|
|
|
|
|
|
|
password, path, extension, and delimiters). For an example, after |
|
159
|
|
|
|
|
|
|
running "make test", look at the file "test.sdb". |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
When connecting to a Sprite database, Sprite will look in the current |
|
162
|
|
|
|
|
|
|
directory, then, if specified, the path in the SPRITE_HOME environment |
|
163
|
|
|
|
|
|
|
variable. |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
The database name, user, and password are used in the "db->connect()" |
|
166
|
|
|
|
|
|
|
method described below. The "database path" is where your tables will |
|
167
|
|
|
|
|
|
|
be created and reside. Table files are ascii text files which will |
|
168
|
|
|
|
|
|
|
have, by default, the extension ".stb" (Sprite table). By default, |
|
169
|
|
|
|
|
|
|
each record will be written to a single line (separated by \n -- |
|
170
|
|
|
|
|
|
|
Windows users should probably use "\r\n"). Each field datum will be |
|
171
|
|
|
|
|
|
|
written without quotes separated by the "field delimiter (default: |
|
172
|
|
|
|
|
|
|
double-colon). The first line of the table file consists of the |
|
173
|
|
|
|
|
|
|
a field name, an equal ("=") sign, an asterisk if it is a key field, |
|
174
|
|
|
|
|
|
|
then the datatype and size. This information is included for each |
|
175
|
|
|
|
|
|
|
field and separated by the field separator. For an example, after |
|
176
|
|
|
|
|
|
|
running "make test", look at the file "testtable.stb". |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
3) write your script to use DBI, ie: |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
#!/usr/bin/perl |
|
181
|
|
|
|
|
|
|
use DBI; |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
$dbh = DBI->connect('DBI:Sprite:mydb','me','mypassword') || |
|
184
|
|
|
|
|
|
|
die "Could not connect (".$DBI->err.':'.$DBI->errstr.")!"; |
|
185
|
|
|
|
|
|
|
... |
|
186
|
|
|
|
|
|
|
#CREATE A TABLE, INSERT SOME RECORDS, HAVE SOME FUN! |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
4) get your application working. |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
5) rehost your application on a "production" machine and change "Sprite" |
|
191
|
|
|
|
|
|
|
to a DBI driver for a "real" database! |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
=head1 CREATING AND DROPPING TABLES |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
You can create and drop tables with commands like the following: |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
$dbh->do("CREATE TABLE $table (id INTEGER, name CHAR(64))"); |
|
198
|
|
|
|
|
|
|
$dbh->do("DROP TABLE $table"); |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
Column names, datatypes, precision, scales, and autonumber sequences are |
|
201
|
|
|
|
|
|
|
stored on the top line as COLUNM_NAME(PRECISION[,SCALE])=DEFAULT_VALUE |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
A drop just removes the file without any warning. |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
See the DBI(3) manpage for more details. |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
Table names cannot be arbitrary, due to restrictions of the SQL syntax. |
|
208
|
|
|
|
|
|
|
I recommend that table names are valid SQL identifiers: The first |
|
209
|
|
|
|
|
|
|
character is alphabetic, followed by an arbitrary number of alphanumeric |
|
210
|
|
|
|
|
|
|
characters. If you want to use other files, the file names must start |
|
211
|
|
|
|
|
|
|
with '/', './' or '../' and they must not contain white space. |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=head1 INSERTING, FETCHING AND MODIFYING DATA |
|
214
|
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
The following examples insert some data in a table and fetch it back: |
|
216
|
|
|
|
|
|
|
First all data in the string: |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
$dbh->do("INSERT INTO $table VALUES (1, 'foobar')"); |
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
Note the use of the quote method for escaping the word 'foobar'. Any |
|
221
|
|
|
|
|
|
|
string must be escaped, even if it doesn't contain binary data. |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Next an example using parameters: |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
$dbh->do("INSERT INTO $table VALUES (?, ?)", undef, |
|
226
|
|
|
|
|
|
|
2, "It's a string!"); |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
To retrieve data, you can use the following: |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
my($query) = "SELECT * FROM $table WHERE id > 1 ORDER BY id"; |
|
231
|
|
|
|
|
|
|
my($sth) = $dbh->prepare($query); |
|
232
|
|
|
|
|
|
|
$sth->execute(); |
|
233
|
|
|
|
|
|
|
while (my $row = $sth->fetchrow_hashref) { |
|
234
|
|
|
|
|
|
|
print("Found result row: id = ", $row->{'id'}, |
|
235
|
|
|
|
|
|
|
", name = ", $row->{'name'}); |
|
236
|
|
|
|
|
|
|
} |
|
237
|
|
|
|
|
|
|
$sth->finish(); |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Again, column binding works: The same example again. |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
my($query) = "SELECT * FROM $table WHERE id > 1 ORDER BY id"; |
|
242
|
|
|
|
|
|
|
my($sth) = $dbh->prepare($query); |
|
243
|
|
|
|
|
|
|
$sth->execute(); |
|
244
|
|
|
|
|
|
|
my($id, $name); |
|
245
|
|
|
|
|
|
|
$sth->bind_columns(undef, \$id, \$name); |
|
246
|
|
|
|
|
|
|
while ($sth->fetch) { |
|
247
|
|
|
|
|
|
|
print("Found result row: id = $id, name = $name\n"); |
|
248
|
|
|
|
|
|
|
} |
|
249
|
|
|
|
|
|
|
$sth->finish(); |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
Of course you can even use input parameters. Here's the same example for |
|
252
|
|
|
|
|
|
|
the third time: |
|
253
|
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
my($query) = "SELECT * FROM $table WHERE id = ?"; |
|
255
|
|
|
|
|
|
|
my($sth) = $dbh->prepare($query); |
|
256
|
|
|
|
|
|
|
$sth->bind_columns(undef, \$id, \$name); |
|
257
|
|
|
|
|
|
|
for (my($i) = 1; $i <= 2; $i++) { |
|
258
|
|
|
|
|
|
|
$sth->execute($id); |
|
259
|
|
|
|
|
|
|
if ($sth->fetch) { |
|
260
|
|
|
|
|
|
|
print("Found result row: id = $id, name = $name\n"); |
|
261
|
|
|
|
|
|
|
} |
|
262
|
|
|
|
|
|
|
$sth->finish(); |
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
See the DBI(3) manpage for details on these methods. See the |
|
266
|
|
|
|
|
|
|
SQL::Statement(3) manpage for details on the WHERE clause. |
|
267
|
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
Data rows are modified with the UPDATE statement: |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
$dbh->do("UPDATE $table SET id = 3 WHERE id = 1"); |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Likewise you use the DELETE statement for removing rows: |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
$dbh->do("DELETE FROM $table WHERE id > 1"); |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
I |
|
277
|
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
Method takes 2 arguments: Function name and optionally, a |
|
279
|
|
|
|
|
|
|
package name (default is "main"). |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
$dbh->fn_register ('myfn','mypackage'); |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
-or- |
|
284
|
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
use JSprite; |
|
286
|
|
|
|
|
|
|
JSprite::fn_register ('myfn',__PACKAGE__); |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
Then, you could say in sql: |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
insert into mytable values (myfn(?)) |
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
and bind some value to "?", which is passed to "myfn", and the return-value |
|
293
|
|
|
|
|
|
|
is inserted into the database. You could also say (without binding): |
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
insert into mytable values (myfn('mystring')) |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
-or (if the function takes a number)- |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
select field1, field2 from mytable where field3 = myfn(123) |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
I |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
None |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=head1 ERROR HANDLING |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
In the above examples we have never cared about return codes. Of course, |
|
308
|
|
|
|
|
|
|
this cannot be recommended. Instead we should have written (for |
|
309
|
|
|
|
|
|
|
example): |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
my($query) = "SELECT * FROM $table WHERE id = ?"; |
|
312
|
|
|
|
|
|
|
my($sth) = $dbh->prepare($query) |
|
313
|
|
|
|
|
|
|
or die "prepare: " . $dbh->errstr(); |
|
314
|
|
|
|
|
|
|
$sth->bind_columns(undef, \$id, \$name) |
|
315
|
|
|
|
|
|
|
or die "bind_columns: " . $dbh->errstr(); |
|
316
|
|
|
|
|
|
|
for (my($i) = 1; $i <= 2; $i++) { |
|
317
|
|
|
|
|
|
|
$sth->execute($id) |
|
318
|
|
|
|
|
|
|
or die "execute: " . $dbh->errstr(); |
|
319
|
|
|
|
|
|
|
if ($sth->fetch) { |
|
320
|
|
|
|
|
|
|
print("Found result row: id = $id, name = $name\n"); |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
} |
|
323
|
|
|
|
|
|
|
$sth->finish($id) |
|
324
|
|
|
|
|
|
|
or die "finish: " . $dbh->errstr(); |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Obviously this is tedious. Fortunately we have DBI's *RaiseError* |
|
327
|
|
|
|
|
|
|
attribute: |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
$dbh->{'RaiseError'} = 1; |
|
330
|
|
|
|
|
|
|
$@ = ''; |
|
331
|
|
|
|
|
|
|
eval { |
|
332
|
|
|
|
|
|
|
my($query) = "SELECT * FROM $table WHERE id = ?"; |
|
333
|
|
|
|
|
|
|
my($sth) = $dbh->prepare($query); |
|
334
|
|
|
|
|
|
|
$sth->bind_columns(undef, \$id, \$name); |
|
335
|
|
|
|
|
|
|
for (my($i) = 1; $i <= 2; $i++) { |
|
336
|
|
|
|
|
|
|
$sth->execute($id); |
|
337
|
|
|
|
|
|
|
if ($sth->fetch) { |
|
338
|
|
|
|
|
|
|
print("Found result row: id = $id, name = $name\n"); |
|
339
|
|
|
|
|
|
|
} |
|
340
|
|
|
|
|
|
|
} |
|
341
|
|
|
|
|
|
|
$sth->finish($id); |
|
342
|
|
|
|
|
|
|
}; |
|
343
|
|
|
|
|
|
|
if ($@) { die "SQL database error: $@"; } |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
This is not only shorter, it even works when using DBI methods within |
|
346
|
|
|
|
|
|
|
subroutines. |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=head1 METADATA |
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
The following attributes are handled by DBI itself and not by DBD::File, |
|
351
|
|
|
|
|
|
|
thus they should all work as expected: I have only used the last 3. |
|
352
|
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
I |
|
354
|
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
I |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
I |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
I (Not used) |
|
360
|
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
I |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
I |
|
364
|
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
I |
|
366
|
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
I |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
I |
|
370
|
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
The following DBI attributes are handled by DBD::Sprite: |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
B |
|
374
|
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
Works |
|
376
|
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
B |
|
378
|
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
Should Work |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
B |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
Valid after `$sth->execute' |
|
384
|
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
B |
|
386
|
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
Valid after `$sth->prepare' |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
B |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Valid after `$sth->execute'; undef for Non-Select statements. |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
B |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
Not really working. Always returns an array ref of one's, as |
|
396
|
|
|
|
|
|
|
DBD::Sprite always allows NULL (handled as an empty string). |
|
397
|
|
|
|
|
|
|
Valid after `$sth->execute'. |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
B |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
Works |
|
402
|
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
B |
|
404
|
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
Works |
|
406
|
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
B |
|
408
|
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
Should work |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
B |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
Works |
|
414
|
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
These attributes and methods are not supported: |
|
416
|
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
B |
|
418
|
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
B |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
In addition to the DBI attributes, you can use the following dbh |
|
423
|
|
|
|
|
|
|
attributes. These attributes are read-only after "connect". |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
I |
|
426
|
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
Path to tables for database. |
|
428
|
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
I |
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
File extension used on table files in the database. |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
I |
|
434
|
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
Current database user. |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
I |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
Field delimiter string in use for the database. |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
I |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
Record delimiter string in use for the database. |
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
The following are environment variables specifically recognized by Sprite. |
|
446
|
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
I |
|
448
|
|
|
|
|
|
|
Environment variable specifying a path to search for Sprite |
|
449
|
|
|
|
|
|
|
databases (*.sdb) files. |
|
450
|
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
The following are Sprite-specific options which can be set when connecting. |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
I => 0 | 1 |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
By default, table names are case-insensitive (as they are in Oracle), |
|
457
|
|
|
|
|
|
|
to make table names case-sensitive (as in MySql), so that one could |
|
458
|
|
|
|
|
|
|
have two separate tables such as "test" and "TEST", set this option |
|
459
|
|
|
|
|
|
|
to 1. |
|
460
|
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
I => 0 | 1 |
|
462
|
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
By default, field names are case-insensitive (as they are in Oracle), |
|
464
|
|
|
|
|
|
|
to make field names case-sensitive, so that one could |
|
465
|
|
|
|
|
|
|
have two separate fields such as "test" and "TEST", set this option |
|
466
|
|
|
|
|
|
|
to 1. The default is 1 (case-sensitive) if XML. |
|
467
|
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
I => 0 | 1 |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
CHAR fields are always right-padded with spaces to fill out |
|
471
|
|
|
|
|
|
|
the field. Old (pre 5.17) Sprite behaviour was to require the |
|
472
|
|
|
|
|
|
|
padding be included in literals used for testing equality in |
|
473
|
|
|
|
|
|
|
"where" clauses. I discovered that Oracle and some other databases |
|
474
|
|
|
|
|
|
|
do not require this when testing DBIx-Recordset, so Sprite will |
|
475
|
|
|
|
|
|
|
automatically right-pad literals when testing for equality. |
|
476
|
|
|
|
|
|
|
To disable this and force the old behavior, set this option to 1. |
|
477
|
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
I => [encrypt=|decrypt=][Crypt]::CBC;][[IDEA[_PP]|DES[_PP]|BLOWFISH[_PP];]keystring |
|
479
|
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
Optional encryption and/or decryption of data stored in tables. By |
|
481
|
|
|
|
|
|
|
omitting "encrypt=" and "decrypt=", data will be decrypted when read |
|
482
|
|
|
|
|
|
|
from the table and encrypted when written to the table using the |
|
483
|
|
|
|
|
|
|
"keystring" as the key. |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
I => 0 | 1 |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
This option forces the table file to first be deleted before being |
|
488
|
|
|
|
|
|
|
overwritten. Default is 0 (do not delete, just overwrite it). This |
|
489
|
|
|
|
|
|
|
was need by the author on certain network filesystems on one jobsite. |
|
490
|
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
I => xsl_stylesheet_url |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
Optional xsl stylesheet url to be included in database tables in XML |
|
494
|
|
|
|
|
|
|
format. Otherwise, ignored. Default none. |
|
495
|
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
I => 0 | 1 |
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
By default, on error, Sprite prints the legacy |
|
499
|
|
|
|
|
|
|
"Oops! Sprite encountered the following error when processing your request..." |
|
500
|
|
|
|
|
|
|
multiline error message carried over from the original Sprite by |
|
501
|
|
|
|
|
|
|
Shishir Gurdavaram. Set to 1 to silense this, if it annoys you, or if you |
|
502
|
|
|
|
|
|
|
are using Sprite in a CGI script. |
|
503
|
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
The following attributes can be specified as a hash reference in "prepare" |
|
505
|
|
|
|
|
|
|
statements: |
|
506
|
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
I => # |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
Limit processing the table to # records. This is NOT the same as a |
|
510
|
|
|
|
|
|
|
"LIMIT #" clause in selects. This limits the query to the first # |
|
511
|
|
|
|
|
|
|
records in the table UNSORTED - BEFORE any constraints or sorting are |
|
512
|
|
|
|
|
|
|
applied. This is useful for limiting queries to, say 1 record |
|
513
|
|
|
|
|
|
|
simply to populate the column metadata. |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
I => # |
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
This is the same as adding a "LIMIT #" clause to a select statement |
|
518
|
|
|
|
|
|
|
when preparing it, as it will limit a query to returning # records |
|
519
|
|
|
|
|
|
|
AFTER applying any constraints and sorting. |
|
520
|
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=head1 DRIVER PRIVATE METHODS |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
B->B() |
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
The `data_sources' method returns a list of "databases" (.sdb files) |
|
526
|
|
|
|
|
|
|
found in the current directory and, if specified, the path in |
|
527
|
|
|
|
|
|
|
the SPRITE_HOME environment variable. |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
$dbh->B() |
|
530
|
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
This method returns a list of table names specified in the current |
|
532
|
|
|
|
|
|
|
database. |
|
533
|
|
|
|
|
|
|
Example: |
|
534
|
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
my($dbh) = DBI->connect("DBI:Sprite:mydatabase",'me','mypswd'); |
|
536
|
|
|
|
|
|
|
my(@list) = $dbh->func('tables'); |
|
537
|
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
B('myfn', __PACKAGE__); |
|
539
|
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
This method takes the name of a user-defined data-conversion function |
|
541
|
|
|
|
|
|
|
for use in SQL commands. Your function can optionally take arguments, |
|
542
|
|
|
|
|
|
|
but should return a single number or string. Unless your function |
|
543
|
|
|
|
|
|
|
is defined in package "main", you must also specify the package name |
|
544
|
|
|
|
|
|
|
or "__PACKAGE__" for the current package. For an example, see the |
|
545
|
|
|
|
|
|
|
section "INSERTING, FETCHING AND MODIFYING DATA" above or (JSprite(3)). |
|
546
|
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
=head1 OTHER SUPPORTING UTILITIES |
|
548
|
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
B |
|
550
|
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
This utility lets you build new Sprite databases and later add |
|
552
|
|
|
|
|
|
|
additional user-spaces to them. Simply cd to the directory where |
|
553
|
|
|
|
|
|
|
you wish to create / modify a database, and run. It prompts as |
|
554
|
|
|
|
|
|
|
follows: |
|
555
|
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
Database name: Enter a 1-word name for your database. |
|
557
|
|
|
|
|
|
|
Database user: Enter a 1-word user-name. |
|
558
|
|
|
|
|
|
|
User password: Enter a 1-word password for this user. |
|
559
|
|
|
|
|
|
|
Database path: Enter a path (no trailing backslash) to store tables. |
|
560
|
|
|
|
|
|
|
Table file extension (default .stb): |
|
561
|
|
|
|
|
|
|
Record delimiter (default \n): |
|
562
|
|
|
|
|
|
|
Field delimiter (default ::): |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
The last 6 prompts repeat until you do not enter another user-name |
|
565
|
|
|
|
|
|
|
allowing you to set up multiple users in a single database. Each |
|
566
|
|
|
|
|
|
|
"user" can have it's own separate tables by specifying different |
|
567
|
|
|
|
|
|
|
paths, file-extensions, password, and delimiters! You can invoke |
|
568
|
|
|
|
|
|
|
"makesdb.pl" on an existing database to add new users. You can |
|
569
|
|
|
|
|
|
|
edit it with vi to remove users, delete the 5 lines starting with |
|
570
|
|
|
|
|
|
|
the path for that user. The file is all text, except for the |
|
571
|
|
|
|
|
|
|
password, which is encrypted for your protection! |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
=head1 RESTRICTIONS |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
Although DBD::Sprite supports the following datatypes: |
|
576
|
|
|
|
|
|
|
NUMBER FLOAT DOUBLE INT INTEGER NUM CHAR VARCHAR VARCHAR2 |
|
577
|
|
|
|
|
|
|
DATE LONG BLOB and MEMO, there are really only 4 basic datatypes |
|
578
|
|
|
|
|
|
|
(NUMBER, CHAR, VARCHAR, and BLOB). This is because Perl treates |
|
579
|
|
|
|
|
|
|
everything as simple strings. The first 5 are all treated as "numbers" |
|
580
|
|
|
|
|
|
|
by Perl for sorting purposes and the rest as strings. This is seen |
|
581
|
|
|
|
|
|
|
when sorting, ie NUMERIC types sort as 1,5,10,40,200, whereas |
|
582
|
|
|
|
|
|
|
STRING types sort these as 1,10,200,40,5. CHAR fields are right- |
|
583
|
|
|
|
|
|
|
padded with spaces when stored. LONG-type fields are subject to |
|
584
|
|
|
|
|
|
|
truncation by the "LongReadLen" attribute value. |
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
DBD::Sprite works with the tieDBI module, if "Sprite => 1" lines are added |
|
587
|
|
|
|
|
|
|
to the "%CAN_BIND" and "%CAN_BINDSELECT" hashes. This should not be |
|
588
|
|
|
|
|
|
|
necessary, and I will investigate when I have time. |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
=head1 KNOWN BUGS |
|
591
|
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
* The module is using flock() internally. However, this function is |
|
593
|
|
|
|
|
|
|
not available on platforms. Using flock() is disabled on MacOS |
|
594
|
|
|
|
|
|
|
and Windows 95: There's no locking at all (perhaps not so |
|
595
|
|
|
|
|
|
|
important on these operating systems, as they are for single |
|
596
|
|
|
|
|
|
|
users anyways). |
|
597
|
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
600
|
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
B, B |
|
602
|
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=cut |
|
604
|
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
package DBD::Sprite; |
|
606
|
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
#no warnings 'uninitialized'; |
|
608
|
|
|
|
|
|
|
|
|
609
|
1
|
|
|
1
|
|
2479
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
30
|
|
|
610
|
|
|
|
|
|
|
#use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); |
|
611
|
1
|
|
|
1
|
|
5
|
use vars qw($VERSION $err $errstr $state $sqlstate $drh $i $j $dbcnt); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
250
|
|
|
612
|
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
#require Exporter; |
|
614
|
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
#@ISA = qw(Exporter AutoLoader); |
|
616
|
|
|
|
|
|
|
# Items to export into callers namespace by default. Note: do not export |
|
617
|
|
|
|
|
|
|
# names by default without a very good reason. Use EXPORT_OK instead. |
|
618
|
|
|
|
|
|
|
# Do not simply export all your public functions/methods/constants. |
|
619
|
|
|
|
|
|
|
#@EXPORT = qw( |
|
620
|
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
#); |
|
622
|
|
|
|
|
|
|
$VERSION = '6.1'; |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
# Preloaded methods go here. |
|
625
|
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
$err = 0; # holds error code for DBI::err |
|
627
|
|
|
|
|
|
|
$errstr = ''; # holds error string for DBI::errstr |
|
628
|
|
|
|
|
|
|
$sqlstate = ''; |
|
629
|
|
|
|
|
|
|
$drh = undef; # holds driver handle once initialised |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
sub driver{ |
|
632
|
1
|
50
|
|
1
|
0
|
936012
|
return $drh if $drh; |
|
633
|
1
|
|
|
|
|
8
|
my($class, $attr) = @_; |
|
634
|
|
|
|
|
|
|
|
|
635
|
1
|
|
|
|
|
7
|
$class .= "::dr"; |
|
636
|
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
# not a 'my' since we use it above to prevent multiple drivers |
|
638
|
1
|
|
|
|
|
54
|
$drh = DBI::_new_drh($class, { 'Name' => 'Sprite', |
|
639
|
|
|
|
|
|
|
'Version' => $VERSION, |
|
640
|
|
|
|
|
|
|
'Err' => \$DBD::Sprite::err, |
|
641
|
|
|
|
|
|
|
'Errstr' => \$DBD::Sprite::errstr, |
|
642
|
|
|
|
|
|
|
'State' => \$DBD::Sprite::state, |
|
643
|
|
|
|
|
|
|
'Attribution' => 'DBD::Sprite by Shishir Gurdavaram & Jim Turner', |
|
644
|
|
|
|
|
|
|
}); |
|
645
|
1
|
|
|
|
|
110
|
$drh; |
|
646
|
|
|
|
|
|
|
} |
|
647
|
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
sub DESTROY #ADDED 20001108 |
|
649
|
|
|
|
0
|
|
|
{ |
|
650
|
|
|
|
|
|
|
} |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
#sub AUTOLOAD { |
|
653
|
|
|
|
|
|
|
# print "***** AUTOLOAD CALLED! *****\n"; |
|
654
|
|
|
|
|
|
|
#} |
|
655
|
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
1; |
|
657
|
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
package DBD::Sprite::dr; # ====== DRIVER ====== |
|
660
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
9
|
|
|
|
1
|
|
|
|
|
26
|
|
|
661
|
1
|
|
|
1
|
|
5
|
use vars qw($imp_data_size); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
1665
|
|
|
662
|
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
$DBD::Sprite::dr::imp_data_size = 0; |
|
664
|
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
sub connect { |
|
666
|
1
|
|
|
1
|
|
180
|
my($drh, $dbname, $dbuser, $dbpswd, $attr, $old_driver, $connect_meth) = @_; |
|
667
|
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
#DON'T PASS ATTRIBUTES IN AS A STRING, MUST BE A HASH-REF! |
|
669
|
|
|
|
|
|
|
|
|
670
|
1
|
|
|
|
|
4
|
my($port); |
|
671
|
1
|
|
|
|
|
2
|
my($cWarn, $i, $j); |
|
672
|
|
|
|
|
|
|
|
|
673
|
1
|
|
|
|
|
8
|
$_ = ''; #ONLY WAY I KNOW HOW TO RETURN ERRORS FROM HERE ($DBI::err WON'T WORK!) |
|
674
|
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
# Avoid warnings for undefined values |
|
676
|
1
|
|
50
|
|
|
7
|
$dbuser ||= ''; |
|
677
|
1
|
|
50
|
|
|
6
|
$dbpswd ||= ''; |
|
678
|
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
# create a 'blank' dbh |
|
680
|
1
|
|
|
|
|
10
|
my($privateattr) = { |
|
681
|
|
|
|
|
|
|
'Name' => $dbname, |
|
682
|
|
|
|
|
|
|
'user' => $dbuser, |
|
683
|
|
|
|
|
|
|
'dbpswd' => $dbpswd |
|
684
|
|
|
|
|
|
|
}; |
|
685
|
|
|
|
|
|
|
#if (!defined($this = DBI::_new_dbh($drh, { |
|
686
|
1
|
|
|
|
|
16
|
my $this = DBI::_new_dbh($drh, { |
|
687
|
|
|
|
|
|
|
'Name' => $dbname, |
|
688
|
|
|
|
|
|
|
'USER' => $dbuser, |
|
689
|
|
|
|
|
|
|
'CURRENT_USER' => $dbuser, |
|
690
|
|
|
|
|
|
|
}); |
|
691
|
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
# Call Sprite Connect function |
|
693
|
|
|
|
|
|
|
# and populate internal handle data. |
|
694
|
1
|
50
|
|
|
|
104
|
if ($this) #ADDED 20010226 TO FIX BAD ERROR MESSAGE HANDLING IF INVALID UN/PW ENTERED. |
|
695
|
|
|
|
|
|
|
{ |
|
696
|
1
|
|
|
|
|
4
|
my $dbfid = $dbname; |
|
697
|
1
|
50
|
|
|
|
23
|
$dbfid .= '.sdb' unless ($dbfid =~ /\.\w+$/); |
|
698
|
1
|
|
50
|
|
|
40
|
$ENV{SPRITE_HOME} ||= ''; |
|
699
|
1
|
50
|
|
|
|
10
|
if ($dbfid =~ m#^/#) |
|
700
|
|
|
|
|
|
|
{ |
|
701
|
0
|
0
|
|
|
|
0
|
unless (open(DBFILE, "<$dbfid")) |
|
702
|
|
|
|
|
|
|
{ |
|
703
|
|
|
|
|
|
|
#DBI::set_err($this, -1, "No such database ($dbname)!"); #REPLACED W/NEXT LINE 20021021! |
|
704
|
0
|
0
|
|
|
|
0
|
warn "No such database ($dbname)!" if ($attr->{PrintError}); |
|
705
|
0
|
|
|
|
|
0
|
$_ = "-1:No such database ($dbname)!"; |
|
706
|
0
|
|
|
|
|
0
|
return undef; |
|
707
|
|
|
|
|
|
|
} |
|
708
|
|
|
|
|
|
|
} |
|
709
|
|
|
|
|
|
|
else |
|
710
|
|
|
|
|
|
|
{ |
|
711
|
1
|
50
|
|
|
|
266
|
unless (open(DBFILE, "<$ENV{SPRITE_HOME}/$dbfid")) |
|
712
|
|
|
|
|
|
|
{ |
|
713
|
1
|
50
|
|
|
|
17
|
unless (open(DBFILE, "<$dbfid")) |
|
714
|
|
|
|
|
|
|
{ |
|
715
|
1
|
50
|
|
|
|
183
|
unless (open(DBFILE, "<$ENV{HOME}/$dbfid")) #NEXT 4 ADDED 20040909 |
|
716
|
|
|
|
|
|
|
{ |
|
717
|
1
|
|
|
|
|
7
|
my $pgmhome = $0; |
|
718
|
1
|
|
|
|
|
10
|
$pgmhome =~ s#[^/\\]*$##; #SET NAME TO SQL.PL FOR ORAPERL! |
|
719
|
1
|
|
50
|
|
|
7
|
$pgmhome ||= '.'; |
|
720
|
1
|
50
|
33
|
|
|
8
|
$pgmhome .= '/' unless ($pgmhome =~ m#\/$# || $dbfid =~ m#^\/#); |
|
721
|
1
|
50
|
|
|
|
11
|
unless (open(DBFILE, "<${pgmhome}$dbfid")) |
|
722
|
|
|
|
|
|
|
{ |
|
723
|
1
|
|
|
|
|
39
|
$_ = "-1:No such database ($dbname) ($!)!"; |
|
724
|
1
|
|
|
|
|
17
|
DBI::set_err($this, -1, $_); #REPLACED W/NEXT LINE 20021021! |
|
725
|
1
|
50
|
|
|
|
49
|
warn $DBI::errstr if ($attr->{PrintError}); |
|
726
|
1
|
|
|
|
|
28
|
return undef; |
|
727
|
|
|
|
|
|
|
} |
|
728
|
|
|
|
|
|
|
} |
|
729
|
|
|
|
|
|
|
} |
|
730
|
|
|
|
|
|
|
} |
|
731
|
|
|
|
|
|
|
} |
|
732
|
0
|
|
|
|
|
0
|
my (@dbinputs) = ; |
|
733
|
0
|
|
|
|
|
0
|
foreach $i (0..$#dbinputs) |
|
734
|
|
|
|
|
|
|
{ |
|
735
|
0
|
|
|
|
|
0
|
chomp ($dbinputs[$i]); |
|
736
|
|
|
|
|
|
|
} |
|
737
|
0
|
|
|
|
|
0
|
my ($inputcnt) = $#dbinputs; |
|
738
|
0
|
|
|
|
|
0
|
my ($dfltattrs, %dfltattr); |
|
739
|
0
|
|
|
|
|
0
|
for ($i=0;$i<=$inputcnt;$i+=5) #SHIFT OFF LINES UNTIL RIGHT USER FOUND. |
|
740
|
|
|
|
|
|
|
{ |
|
741
|
0
|
0
|
|
|
|
0
|
last if ($dbinputs[1] eq $dbuser); |
|
742
|
0
|
0
|
|
|
|
0
|
if ($dbinputs[1] =~ s/^$dbuser\:(.*)/$dbuser/) |
|
743
|
|
|
|
|
|
|
{ |
|
744
|
0
|
|
|
|
|
0
|
$dfltattrs = $1; |
|
745
|
0
|
|
|
|
|
0
|
eval "\%dfltattr = ($dfltattrs)"; |
|
746
|
0
|
|
|
|
|
0
|
foreach my $j (keys %dfltattr) |
|
747
|
|
|
|
|
|
|
{ |
|
748
|
|
|
|
|
|
|
#$attr->{$j} = $dfltattr{$j}; #CHGD. TO NEXT 20030207 |
|
749
|
0
|
0
|
|
|
|
0
|
$attr->{$j} = $dfltattr{$j} unless (defined $attr->{$j}); |
|
750
|
|
|
|
|
|
|
} |
|
751
|
0
|
|
|
|
|
0
|
last; |
|
752
|
|
|
|
|
|
|
} |
|
753
|
0
|
|
|
|
|
0
|
for ($j=0;$j<=4;$j++) |
|
754
|
|
|
|
|
|
|
{ |
|
755
|
0
|
|
|
|
|
0
|
shift (@dbinputs); |
|
756
|
|
|
|
|
|
|
} |
|
757
|
|
|
|
|
|
|
} |
|
758
|
|
|
|
|
|
|
#foreach my $x (keys %{$attr}) { print STDERR "-attr($x)=$attr->{$x}=\n"; }; |
|
759
|
0
|
0
|
|
|
|
0
|
if ($dbinputs[1] eq $dbuser) |
|
760
|
|
|
|
|
|
|
{ |
|
761
|
|
|
|
|
|
|
#if ($dbinputs[2] eq crypt($dbpswd, substr($dbuser,0,2))) |
|
762
|
0
|
|
|
|
|
0
|
my ($crypted); |
|
763
|
0
|
|
|
|
|
0
|
eval { $crypted = crypt($dbpswd, substr($dbuser,0,2)); }; |
|
|
0
|
|
|
|
|
0
|
|
|
764
|
0
|
0
|
0
|
|
|
0
|
if ($dbinputs[2] eq $crypted || $@ =~ /excessive paranoia/) |
|
765
|
|
|
|
|
|
|
{ |
|
766
|
0
|
|
|
|
|
0
|
++$DBD::Sprite::dbcnt; |
|
767
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_dbname',$dbname); |
|
768
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_dbuser',$dbuser); |
|
769
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_dbpswd',$dbpswd); |
|
770
|
0
|
|
|
|
|
0
|
close (DBFILE); |
|
771
|
|
|
|
|
|
|
#$this->STORE('sprite_autocommit',0); #CHGD TO NEXT 20010912. |
|
772
|
0
|
|
0
|
|
|
0
|
$this->STORE('sprite_autocommit',($attr->{AutoCommit} || 0)); |
|
773
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_SpritesOpen',{}); |
|
774
|
0
|
|
|
|
|
0
|
my ($t) = $dbinputs[0]; |
|
775
|
0
|
|
|
|
|
0
|
$t =~ s#(.*)/.*#$1#; |
|
776
|
0
|
0
|
|
|
|
0
|
if ($dbinputs[0] =~ /(.*)(\..*)/) |
|
777
|
|
|
|
|
|
|
{ |
|
778
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_dbdir', $t); |
|
779
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_dbext', $2); |
|
780
|
|
|
|
|
|
|
} |
|
781
|
|
|
|
|
|
|
else |
|
782
|
|
|
|
|
|
|
{ |
|
783
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_dbdir', $dbinputs[0]); |
|
784
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_dbext', '.stb'); |
|
785
|
|
|
|
|
|
|
} |
|
786
|
0
|
|
|
|
|
0
|
for (my $i=0;$i<=$#dbinputs;$i++) |
|
787
|
|
|
|
|
|
|
{ |
|
788
|
0
|
|
|
|
|
0
|
$dbinputs[$i] =~ /^(.*)$/; |
|
789
|
0
|
|
|
|
|
0
|
$dbinputs[$i] = $1; |
|
790
|
|
|
|
|
|
|
} |
|
791
|
0
|
|
0
|
|
|
0
|
$this->STORE('sprite_dbfdelim', $attr->{sprite_read} || $attr->{sprite_field} || eval("return(\"$dbinputs[3]\");") || '::'); |
|
792
|
0
|
|
0
|
|
|
0
|
$this->STORE('sprite_dbwdelim', $attr->{sprite_write} || $attr->{sprite_field} || eval("return(\"$dbinputs[3]\");") || '::'); |
|
793
|
0
|
|
0
|
|
|
0
|
$this->STORE('sprite_dbrdelim', $attr->{sprite_record} || eval("return(\"$dbinputs[4]\");") || "\n"); |
|
794
|
0
|
|
|
|
|
0
|
$this->STORE('sprite_attrhref', $attr); |
|
795
|
0
|
|
0
|
|
|
0
|
$this->STORE('AutoCommit', ($attr->{AutoCommit} || 0)); |
|
796
|
|
|
|
|
|
|
|
|
797
|
0
|
|
0
|
|
|
0
|
$this->STORE('sprite_autocommit',($attr->{AutoCommit} || 0)); |
|
798
|
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
#NOTE: "PrintError" and "AutoCommit" are ON by DEFAULT! |
|
800
|
|
|
|
|
|
|
#I KNOW OF NO WAY TO DETECT WHETHER AUTOCOMMIT IS SET BY |
|
801
|
|
|
|
|
|
|
#DEFAULT OR BY USER IN "AutoCommit => 1", THEREFORE I CAN'T |
|
802
|
|
|
|
|
|
|
#FORCE THE DEFAULT TO ZERO. JWT |
|
803
|
|
|
|
|
|
|
|
|
804
|
0
|
|
|
|
|
0
|
return $this; |
|
805
|
|
|
|
|
|
|
} |
|
806
|
|
|
|
|
|
|
} |
|
807
|
|
|
|
|
|
|
} |
|
808
|
0
|
|
|
|
|
0
|
close (DBFILE); |
|
809
|
|
|
|
|
|
|
#DBI::set_err($this, -1, "Invalid username/password!"); #REPLACED W/NEXT LINE 20021021! |
|
810
|
0
|
0
|
|
|
|
0
|
warn "Invalid username/password!" if ($attr->{PrintError}); |
|
811
|
0
|
|
|
|
|
0
|
$_ = "-1:Invalid username/password!"; |
|
812
|
0
|
|
|
|
|
0
|
return undef; |
|
813
|
|
|
|
|
|
|
} |
|
814
|
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
sub data_sources |
|
816
|
|
|
|
|
|
|
{ |
|
817
|
1
|
|
|
1
|
|
58
|
my ($self) = shift; |
|
818
|
|
|
|
|
|
|
|
|
819
|
1
|
|
|
|
|
6
|
my (@dsources) = (); |
|
820
|
1
|
|
|
|
|
6
|
my $path; |
|
821
|
1
|
50
|
|
|
|
11
|
if (defined $ENV{SPRITE_HOME}) |
|
822
|
|
|
|
|
|
|
{ |
|
823
|
0
|
|
|
|
|
0
|
$path = "$ENV{SPRITE_HOME}/*.sdb"; |
|
824
|
0
|
|
|
|
|
0
|
my $code = "while (my \$i = <$path>)\n"; |
|
825
|
0
|
|
|
|
|
0
|
$code .= <<'END_CODE'; |
|
826
|
|
|
|
|
|
|
{ |
|
827
|
|
|
|
|
|
|
chomp ($i); |
|
828
|
|
|
|
|
|
|
push (@dsources,"DBI:Sprite:$1") if ($i =~ m#([^\/\.]+)\.sdb$#); |
|
829
|
|
|
|
|
|
|
} |
|
830
|
|
|
|
|
|
|
END_CODE |
|
831
|
0
|
|
|
|
|
0
|
eval $code; |
|
832
|
0
|
|
|
|
|
0
|
$code =~ s/\.sdb([\>\$])/\.SDB$1/g; #HANDLE WINDOWSEY FILENAMES :( |
|
833
|
0
|
|
|
|
|
0
|
eval $code; |
|
834
|
|
|
|
|
|
|
} |
|
835
|
1
|
|
|
|
|
9
|
$path = '*.sdb'; |
|
836
|
1
|
|
|
|
|
7
|
my $code = "while (my \$i = <$path>)\n"; |
|
837
|
1
|
|
|
|
|
5
|
$code .= <<'END_CODE'; |
|
838
|
|
|
|
|
|
|
{ |
|
839
|
|
|
|
|
|
|
chomp ($i); |
|
840
|
|
|
|
|
|
|
push (@dsources,"DBI:Sprite:$1") if ($i =~ m#([^\/\.]+)\.sdb$#); |
|
841
|
|
|
|
|
|
|
} |
|
842
|
|
|
|
|
|
|
END_CODE |
|
843
|
1
|
|
|
|
|
318
|
eval $code; |
|
844
|
1
|
|
|
|
|
37
|
$code =~ s/\.sdb([\>\$])/\.SDB$1/g; #HANDLE WINDOWSEY FILENAMES :( |
|
845
|
1
|
|
|
|
|
186
|
eval $code; |
|
846
|
1
|
50
|
|
|
|
11
|
unless (@dsources) |
|
847
|
|
|
|
|
|
|
{ |
|
848
|
1
|
50
|
|
|
|
12
|
if (defined $ENV{HOME}) |
|
849
|
|
|
|
|
|
|
{ |
|
850
|
1
|
|
|
|
|
7
|
$path = "$ENV{HOME}/*.sdb"; |
|
851
|
1
|
|
|
|
|
7
|
my $code = "while (my \$i = <$path>)\n"; |
|
852
|
1
|
|
|
|
|
4
|
$code .= <<'END_CODE'; |
|
853
|
|
|
|
|
|
|
{ |
|
854
|
|
|
|
|
|
|
chomp ($i); |
|
855
|
|
|
|
|
|
|
push (@dsources,"DBI:Sprite:$1") if ($i =~ m#([^\/\.]+)\.sdb$#); |
|
856
|
|
|
|
|
|
|
} |
|
857
|
|
|
|
|
|
|
END_CODE |
|
858
|
1
|
|
|
|
|
187
|
eval $code; |
|
859
|
1
|
|
|
|
|
25
|
$code =~ s/\.sdb([\>\$])/\.SDB$1/g; #HANDLE WINDOWSEY FILENAMES :( |
|
860
|
1
|
|
|
|
|
179
|
eval $code; |
|
861
|
|
|
|
|
|
|
} |
|
862
|
|
|
|
|
|
|
} |
|
863
|
1
|
|
|
|
|
18
|
return (@dsources); |
|
864
|
|
|
|
|
|
|
} |
|
865
|
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
sub DESTROY |
|
867
|
|
|
|
|
|
|
{ |
|
868
|
0
|
|
|
0
|
|
0
|
my($drh) = shift; |
|
869
|
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
# if ($drh->FETCH('AutoCommit') == 1) #REMOVED 20020225 TO ELIMINATE -w WARNING. |
|
871
|
|
|
|
|
|
|
# { |
|
872
|
|
|
|
|
|
|
# $drh->STORE('AutoCommit',0); |
|
873
|
|
|
|
|
|
|
# $drh->rollback(); #COMMIT IT IF AUTOCOMMIT ON! |
|
874
|
|
|
|
|
|
|
# $drh->STORE('AutoCommit',1); |
|
875
|
|
|
|
|
|
|
# } |
|
876
|
0
|
|
|
|
|
0
|
$drh = undef; |
|
877
|
|
|
|
|
|
|
} |
|
878
|
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
sub disconnect_all |
|
880
|
|
|
|
1
|
|
|
{ |
|
881
|
|
|
|
|
|
|
} |
|
882
|
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
sub admin { #I HAVE NO IDEA WHAT THIS DOES! |
|
884
|
0
|
|
|
0
|
|
0
|
my($drh) = shift; |
|
885
|
0
|
|
|
|
|
0
|
my($command) = shift; |
|
886
|
|
|
|
|
|
|
|
|
887
|
0
|
0
|
0
|
|
|
0
|
my($dbname) = ($command eq 'createdb' || $command eq 'dropdb') ? |
|
888
|
|
|
|
|
|
|
shift : ''; |
|
889
|
0
|
|
0
|
|
|
0
|
my($host, $port) = DBD::Sprite->_OdbcParseHost(shift(@_) || ''); |
|
890
|
0
|
|
0
|
|
|
0
|
my($user) = shift || ''; |
|
891
|
0
|
|
0
|
|
|
0
|
my($password) = shift || ''; |
|
892
|
|
|
|
|
|
|
|
|
893
|
0
|
|
0
|
|
|
0
|
$drh->func(undef, $command, |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
894
|
|
|
|
|
|
|
$dbname || '', |
|
895
|
|
|
|
|
|
|
$host || '', |
|
896
|
|
|
|
|
|
|
$port || '', |
|
897
|
|
|
|
|
|
|
$user, $password, '_admin_internal'); |
|
898
|
|
|
|
|
|
|
} |
|
899
|
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
1; |
|
901
|
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
package DBD::Sprite::db; # ====== DATABASE ====== |
|
904
|
1
|
|
|
1
|
|
6
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
29
|
|
|
905
|
1
|
|
|
1
|
|
1171
|
use JSprite; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
49
|
|
|
906
|
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
$DBD::Sprite::db::imp_data_size = 0; |
|
908
|
1
|
|
|
1
|
|
24
|
use vars qw($imp_data_size); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4958
|
|
|
909
|
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
sub last_insert_id #MUST BE CALLED W/"$dbh->func"! ADDED 20040407 TO SUPPORT NEW DBI FUNCTION. |
|
911
|
|
|
|
|
|
|
{ |
|
912
|
0
|
|
|
0
|
|
0
|
my ($resptr, $cat, $schema, $tablename, $seqfield) = @_; |
|
913
|
0
|
0
|
0
|
|
|
0
|
return $resptr->{sprite_insertid} if (defined $resptr->{sprite_insertid} && $resptr->{sprite_insertid} =~ /\d$/); |
|
914
|
0
|
|
|
|
|
0
|
my $mycsr; |
|
915
|
0
|
0
|
|
|
|
0
|
if ($mycsr = $resptr->prepare("select ${seqfield}.CURRVAL from DUAL")) |
|
916
|
|
|
|
|
|
|
{ |
|
917
|
0
|
|
|
|
|
0
|
my $myexe; |
|
918
|
0
|
0
|
|
|
|
0
|
if ($myexe = $mycsr->execute()) |
|
919
|
|
|
|
|
|
|
{ |
|
920
|
0
|
|
|
|
|
0
|
my ($lastseq) = $mycsr->fetchrow_array(); |
|
921
|
0
|
|
|
|
|
0
|
$mycsr->finish(); |
|
922
|
|
|
|
|
|
|
###return $lastseq if ($lastseq =~ /\d$/); #CHGD. TO NEXT 20061006 TO HANDLE ERRORS, IE. WHEN SEQ IS AN AUTONUMBER, NOT A SEQ! |
|
923
|
0
|
0
|
0
|
|
|
0
|
return $lastseq if ($lastseq =~ /\d$/ && $lastseq > 0); |
|
924
|
|
|
|
|
|
|
} |
|
925
|
|
|
|
|
|
|
} |
|
926
|
0
|
0
|
|
|
|
0
|
if ($seqfield) #IF ALL ELSE FAILS, FETCH A DESCENDING LIST OF VALUES FOR THE FIELD THE SEQUENCE WAS INSERTED INTO (USER MUST SPECIFY THE FIELD!) |
|
927
|
|
|
|
|
|
|
{ |
|
928
|
0
|
|
|
|
|
0
|
my $sql = <
|
|
929
|
|
|
|
|
|
|
select $seqfield |
|
930
|
|
|
|
|
|
|
from $tablename |
|
931
|
|
|
|
|
|
|
order by $seqfield desc |
|
932
|
|
|
|
|
|
|
END_SQL |
|
933
|
0
|
0
|
|
|
|
0
|
if ($mycsr = $resptr->prepare($sql)) |
|
934
|
|
|
|
|
|
|
{ |
|
935
|
0
|
|
|
|
|
0
|
my $myexe; |
|
936
|
0
|
0
|
|
|
|
0
|
if ($myexe = $mycsr->execute()) |
|
937
|
|
|
|
|
|
|
{ |
|
938
|
0
|
|
|
|
|
0
|
my ($lastseq) = $mycsr->fetchrow_array(); |
|
939
|
0
|
|
|
|
|
0
|
$mycsr->finish(); |
|
940
|
0
|
|
|
|
|
0
|
return $lastseq; |
|
941
|
|
|
|
|
|
|
} |
|
942
|
|
|
|
|
|
|
else |
|
943
|
|
|
|
|
|
|
{ |
|
944
|
0
|
|
|
|
|
0
|
return undef; |
|
945
|
|
|
|
|
|
|
} |
|
946
|
|
|
|
|
|
|
} |
|
947
|
0
|
|
|
|
|
0
|
return undef; |
|
948
|
|
|
|
|
|
|
} |
|
949
|
0
|
|
|
|
|
0
|
return undef; |
|
950
|
|
|
|
|
|
|
} |
|
951
|
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
sub Statement #MUST BE CALLED W/"dbh->func([undef, undef, 'tablename', 'seq/field name',] 'last_insert_id')"! ADDED 20040407 TO SUPPORT NEW DBI FUNCTION. |
|
953
|
|
|
|
|
|
|
{ |
|
954
|
0
|
0
|
|
0
|
|
0
|
return undef unless ($_[0]); |
|
955
|
0
|
|
|
|
|
0
|
return $_[0]->FETCH('sprite_last_prepare_sql'); |
|
956
|
|
|
|
|
|
|
} |
|
957
|
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
sub prepare |
|
959
|
|
|
|
|
|
|
{ |
|
960
|
0
|
|
|
0
|
|
0
|
my ($resptr, $sqlstr, $attribs) = @_; |
|
961
|
0
|
|
|
|
|
0
|
my ($indx, @QS); |
|
962
|
0
|
|
|
|
|
0
|
local ($_); |
|
963
|
|
|
|
|
|
|
#$sqlstr =~ s/\n/ /g; #REMOVED 20011107. |
|
964
|
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
#DBI::set_err($resptr, 0, ''); #CHGD. TO NEXT 20041104. |
|
966
|
0
|
|
|
|
|
0
|
DBI::set_err($resptr, undef); |
|
967
|
|
|
|
|
|
|
|
|
968
|
0
|
0
|
|
|
|
0
|
my $limit = ($sqlstr =~ s/^(.+)\s*limit\s+(\d+)\s*$/$1/i) ? $2 : 0; #ADDED 20160111 TO SUPPORT "limit #" ON QUERIES. |
|
969
|
0
|
|
|
|
|
0
|
$sqlstr =~ s/^\s*listfields\s+(\w+)/select * from $1 where 1 = 0/i; #ADDED 20030901. |
|
970
|
0
|
|
|
|
|
0
|
my $csr = DBI::_new_sth($resptr, { |
|
971
|
|
|
|
|
|
|
'Statement' => $sqlstr, |
|
972
|
|
|
|
|
|
|
}); |
|
973
|
|
|
|
|
|
|
|
|
974
|
0
|
|
|
|
|
0
|
my ($spritefid); |
|
975
|
0
|
|
|
|
|
0
|
$resptr->STORE('sprite_last_prepare_sql', $sqlstr); |
|
976
|
0
|
|
|
|
|
0
|
$csr->STORE('sprite_fetchcnt', 0); |
|
977
|
0
|
|
|
|
|
0
|
$csr->STORE('sprite_reslinev',''); |
|
978
|
0
|
|
|
|
|
0
|
$sqlstr =~ s/\\\'|\'\'/\x02\^3jSpR1tE\x02/gso; #PROTECT "\'" IN QUOTES. |
|
979
|
0
|
|
|
|
|
0
|
$sqlstr =~ s/\\\"|\"\"/\x02\^4jSpR1tE\x02/gso; #PROTECT "\"" IN QUOTES. |
|
980
|
0
|
|
|
|
|
0
|
$indx = 0; |
|
981
|
0
|
|
|
|
|
0
|
$indx++ while ($sqlstr =~ s/([\'\"])([^\1]*?)\1/ |
|
982
|
0
|
|
|
|
|
0
|
$QS[$indx] = "$1$2"; "\$QS\[$indx]"/e); |
|
|
0
|
|
|
|
|
0
|
|
|
983
|
|
|
|
|
|
|
#$sqlstr =~ /(into|from|update|table) \s*(\w+)/gi; #CHANGED 20000831 TO NEXT LINE! |
|
984
|
|
|
|
|
|
|
#$sqlstr =~ /(into|from|update|table|sequence)\s+(\w+)/is; #CHGD. 20040305 TO NEXT. |
|
985
|
0
|
0
|
|
|
|
0
|
$spritefid = $2 if ($sqlstr =~ /(into|from|update|table|sequence)\s+(\w+)/ios); |
|
986
|
0
|
0
|
|
|
|
0
|
$spritefid = $1 if ($sqlstr =~ /primary_key_info\s+(\w+)/ios); |
|
987
|
0
|
0
|
|
|
|
0
|
unless ($spritefid) #ADDED 20061010 TO SUPPORT "select fn" (like MySQL, et al.) |
|
988
|
|
|
|
|
|
|
{ |
|
989
|
0
|
0
|
|
|
|
0
|
$spritefid = 'DUAL' if ($sqlstr =~ s/^(\s*select\s+\w+\s*)(\(.*\))?$/$1$2 from DUAL/is); |
|
990
|
|
|
|
|
|
|
} |
|
991
|
|
|
|
|
|
|
|
|
992
|
0
|
0
|
|
|
|
0
|
unless ($spritefid) #NEXT 5 ADDED 20000831! |
|
993
|
|
|
|
|
|
|
{ |
|
994
|
0
|
|
|
|
|
0
|
DBI::set_err($resptr, -1, "Prepare:(bad sql) Must specify a table name!"); |
|
995
|
0
|
|
|
|
|
0
|
return undef; |
|
996
|
|
|
|
|
|
|
} |
|
997
|
0
|
0
|
|
|
|
0
|
$spritefid =~ tr/A-Z/a-z/ unless ($resptr->{sprite_attrhref}->{sprite_CaseTableNames}); |
|
998
|
0
|
|
|
|
|
0
|
$csr->STORE('sprite_spritefid', $spritefid); |
|
999
|
|
|
|
|
|
|
|
|
1000
|
0
|
|
|
|
|
0
|
my $join = 0; |
|
1001
|
0
|
|
|
|
|
0
|
my $joininfo; |
|
1002
|
|
|
|
|
|
|
#$joininfo = $1 if ($sqlstr =~ /from\s+([\w\.\, ]+)\s*(?:where|order\s+by)/is); |
|
1003
|
|
|
|
|
|
|
#$joininfo = $1 if (!$joininfo && $sqlstr =~ /from\s+([\w\.\, ]+)/is); |
|
1004
|
|
|
|
|
|
|
#LAST 2 CHGD. TO NEXT 2 20040914. |
|
1005
|
0
|
0
|
|
|
|
0
|
$joininfo = $1 if ($sqlstr =~ /from\s+([\w\.\,\s]+)\s*(?:where|order\s+by)/iso); |
|
1006
|
0
|
0
|
0
|
|
|
0
|
$joininfo = $1 if (!$joininfo && $sqlstr =~ /from\s+([\w\.\,\s]+)/iso); |
|
1007
|
0
|
|
|
|
|
0
|
my @joinfids; |
|
1008
|
0
|
0
|
|
|
|
0
|
@joinfids = split(/\,\s*/o, $joininfo) if (defined $joininfo); |
|
1009
|
0
|
|
|
|
|
0
|
my (@joinfid, @joinalias); |
|
1010
|
0
|
0
|
|
|
|
0
|
if ($#joinfids >= 1) |
|
1011
|
|
|
|
|
|
|
{ |
|
1012
|
0
|
0
|
|
|
|
0
|
unless ($#joinfids == 1) |
|
1013
|
|
|
|
|
|
|
{ |
|
1014
|
0
|
|
|
|
|
0
|
DBI::set_err($resptr, -1, "Only 2-table joins currently supported!"); |
|
1015
|
0
|
|
|
|
|
0
|
return undef; |
|
1016
|
|
|
|
|
|
|
} |
|
1017
|
0
|
|
|
|
|
0
|
for (my $i=0;$i<=$#joinfids;$i++) |
|
1018
|
|
|
|
|
|
|
{ |
|
1019
|
0
|
|
|
|
|
0
|
($joinfid[$i], $joinalias[$i]) = split(/\s+/o, $joinfids[$i]); |
|
1020
|
0
|
|
0
|
|
|
0
|
$joinfid[$i] ||= $joinfids[$i]; |
|
1021
|
0
|
0
|
|
|
|
0
|
$joinfid[$i] =~ tr/A-Z/a-z/ unless ($resptr->{sprite_attrhref}->{sprite_CaseTableNames}); |
|
1022
|
|
|
|
|
|
|
} |
|
1023
|
0
|
|
|
|
|
0
|
$csr->STORE('sprite_joinfid', \@joinfid); |
|
1024
|
0
|
|
|
|
|
0
|
$csr->STORE('sprite_joinalias', \@joinalias); |
|
1025
|
0
|
|
|
|
|
0
|
$join = 1; |
|
1026
|
|
|
|
|
|
|
} |
|
1027
|
|
|
|
|
|
|
#CHECK TO SEE IF A PREVIOUSLY-CLOSED SPRITE OBJECT EXISTS FOR THIS TABLE. |
|
1028
|
|
|
|
|
|
|
#IF SET, THE "RECYCLE" OPTION TELLS SPRITE NOT TO RELOAD THE TABLE DATA. |
|
1029
|
|
|
|
|
|
|
#THIS IS USEFUL TO SAVE TIME AND MEMORY FOR APPS DOING MULTIPLE |
|
1030
|
|
|
|
|
|
|
#TRANSACTIONS ON SEVERAL LARGE TABLES. |
|
1031
|
|
|
|
|
|
|
#RELOADING IS NECESSARY, HOWEVER, IF ANOTHER USER CAN CHANGE THE |
|
1032
|
|
|
|
|
|
|
#DATA SINCE YOUR LAST COMMIT, SO RECYCLE IS OFF BY DEFAULT! |
|
1033
|
|
|
|
|
|
|
#THE SPRITE HANDLE AND ALL IT'S BASIC CONFIGURATION IS RECYCLED REGARDLESS. |
|
1034
|
0
|
|
|
|
|
0
|
my (@spritedbs) = (qw(sprite_spritedb sprite_joindb)); |
|
1035
|
0
|
|
|
|
|
0
|
my ($myspriteref); |
|
1036
|
0
|
|
|
|
|
0
|
my $i = 0; |
|
1037
|
0
|
|
|
|
|
0
|
$myspriteref = undef; |
|
1038
|
0
|
|
|
|
|
0
|
foreach my $fid ($spritefid, $joinfid[1]) |
|
1039
|
|
|
|
|
|
|
{ |
|
1040
|
0
|
0
|
|
|
|
0
|
last unless ($fid); |
|
1041
|
0
|
0
|
0
|
|
|
0
|
if (ref($resptr->{'sprite_SpritesOpen'}) && ref($resptr->{'sprite_SpritesOpen'}->{$fid})) |
|
1042
|
|
|
|
|
|
|
{ |
|
1043
|
0
|
|
|
|
|
0
|
$myspriteref = ${$resptr->{'sprite_SpritesOpen'}->{$fid}}; |
|
|
0
|
|
|
|
|
0
|
|
|
1044
|
0
|
|
|
|
|
0
|
$csr->STORE($spritedbs[$i], ${$resptr->{'sprite_SpritesOpen'}->{$fid}}); |
|
|
0
|
|
|
|
|
0
|
|
|
1045
|
0
|
|
|
|
|
0
|
$myspriteref->{TYPE} = undef; |
|
1046
|
0
|
|
|
|
|
0
|
$myspriteref->{NAME} = undef; |
|
1047
|
0
|
|
|
|
|
0
|
$myspriteref->{PRECISION} = undef; |
|
1048
|
0
|
|
|
|
|
0
|
$myspriteref->{SCALE} = undef; |
|
1049
|
|
|
|
|
|
|
} |
|
1050
|
|
|
|
|
|
|
else #CREATE A NEW SPRITE OBJECT. |
|
1051
|
|
|
|
|
|
|
{ |
|
1052
|
0
|
|
|
|
|
0
|
$myspriteref = new JSprite(%{$resptr->{sprite_attrhref}}); |
|
|
0
|
|
|
|
|
0
|
|
|
1053
|
0
|
0
|
|
|
|
0
|
unless ($myspriteref) |
|
1054
|
|
|
|
|
|
|
{ |
|
1055
|
0
|
|
|
|
|
0
|
DBI::set_err($resptr, -1, "Unable to create JSprite handle ($@)!"); |
|
1056
|
0
|
|
|
|
|
0
|
return undef; |
|
1057
|
|
|
|
|
|
|
} |
|
1058
|
0
|
|
|
|
|
0
|
$csr->STORE($spritedbs[$i], $myspriteref); |
|
1059
|
0
|
|
|
|
|
0
|
my ($openhash) = $resptr->FETCH('sprite_SpritesOpen'); |
|
1060
|
0
|
|
|
|
|
0
|
$openhash->{$fid} = \$myspriteref; |
|
1061
|
0
|
|
0
|
|
|
0
|
$myspriteref->set_delimiter("-read",($attribs->{sprite_read} || $attribs->{sprite_field} || $resptr->FETCH('sprite_dbfdelim'))); |
|
1062
|
0
|
|
0
|
|
|
0
|
$myspriteref->set_delimiter("-write",($attribs->{sprite_write} || $attribs->{sprite_field} || $resptr->FETCH('sprite_dbwdelim'))); |
|
1063
|
0
|
|
0
|
|
|
0
|
$myspriteref->set_delimiter("-record",($attribs->{sprite_record} || $attribs->{sprite_field} || $resptr->FETCH('sprite_dbrdelim'))); |
|
1064
|
0
|
|
|
|
|
0
|
$myspriteref->set_db_dir($resptr->FETCH('sprite_dbdir')); |
|
1065
|
0
|
|
|
|
|
0
|
$myspriteref->set_db_ext($resptr->FETCH('sprite_dbext')); |
|
1066
|
0
|
|
|
|
|
0
|
$myspriteref->{CaseTableNames} = $resptr->{sprite_attrhref}->{sprite_CaseTableNames}; |
|
1067
|
0
|
|
|
|
|
0
|
$myspriteref->{sprite_CaseFieldNames} = $resptr->{sprite_attrhref}->{sprite_CaseFieldNames}; |
|
1068
|
0
|
|
|
|
|
0
|
$myspriteref->{StrictCharComp} = $resptr->{sprite_attrhref}->{sprite_StrictCharComp}; |
|
1069
|
|
|
|
|
|
|
#DON'T NEED!#$myspriteref->{Crypt} = $resptr->{sprite_attrhref}->{sprite_Crypt}; #ADDED 20020109. |
|
1070
|
0
|
|
|
|
|
0
|
$myspriteref->{sprite_forcereplace} = $resptr->{sprite_attrhref}->{sprite_forcereplace}; #ADDED 20010912. |
|
1071
|
0
|
|
|
|
|
0
|
$myspriteref->{dbuser} = $resptr->FETCH('sprite_dbuser'); #ADDED 20011026. |
|
1072
|
0
|
|
|
|
|
0
|
$myspriteref->{dbname} = $resptr->FETCH('sprite_dbname'); #ADDED 20011026. |
|
1073
|
0
|
|
|
|
|
0
|
$myspriteref->{dbhandle} = $resptr; #ADDED 20020516 |
|
1074
|
|
|
|
|
|
|
} |
|
1075
|
0
|
|
|
|
|
0
|
$myspriteref->{LongTruncOk} = $resptr->FETCH('LongTruncOk'); |
|
1076
|
0
|
|
|
|
|
0
|
my ($silent) = $resptr->FETCH('PrintError'); |
|
1077
|
0
|
0
|
|
|
|
0
|
$myspriteref->{silent} = ($silent ? 0 : 1); #ADDED 20000103 TO SUPPRESS "OOPS" MSG ON WEBSITES! |
|
1078
|
0
|
0
|
|
|
|
0
|
$myspriteref->{sprite_reclimit} = (defined $attribs->{sprite_reclimit}) ? $attribs->{sprite_reclimit} : 0; #ADDED 20020123. |
|
1079
|
0
|
0
|
|
|
|
0
|
$myspriteref->{sprite_sizelimit} = (defined $attribs->{sprite_sizelimit}) ? $attribs->{sprite_sizelimit} : 0; #ADDED 20020530. |
|
1080
|
0
|
|
|
|
|
0
|
$myspriteref->{sprite_actlimit} = $limit; #ADDED 20160111 TO SUPPORT "limit #" ON QUERIES. |
|
1081
|
0
|
|
|
|
|
0
|
++$i; |
|
1082
|
|
|
|
|
|
|
} |
|
1083
|
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
#PARSE OUT SQL IF JOIN. |
|
1085
|
|
|
|
|
|
|
|
|
1086
|
0
|
|
|
|
|
0
|
my $num_of_params; |
|
1087
|
|
|
|
|
|
|
my @bindindices; |
|
1088
|
0
|
|
|
|
|
0
|
my @joinsql; |
|
1089
|
0
|
0
|
|
|
|
0
|
if ($join) |
|
1090
|
|
|
|
|
|
|
{ |
|
1091
|
0
|
|
|
|
|
0
|
my ($whereclause, $joinfid); |
|
1092
|
0
|
|
|
|
|
0
|
my %addfields; #FIELDS IN UNION CRITERIA THAT MUST BE ADDED TO FETCH. |
|
1093
|
0
|
|
|
|
|
0
|
my @selectfields; #FIELD NAMES OF FIELDS TO BE FETCHED. |
|
1094
|
0
|
|
|
|
|
0
|
my $addthesefields; #COLLECT LIST OF FIELDS THAT ACTUALLY NEED ADDING. |
|
1095
|
0
|
|
|
|
|
0
|
my @union; #LIST OF FIELDS IN THE JOIN UNION(S). |
|
1096
|
0
|
|
|
|
|
0
|
my $listprefix; |
|
1097
|
|
|
|
|
|
|
|
|
1098
|
0
|
|
|
|
|
0
|
for (my $jj=0;$jj<=1;$jj++) |
|
1099
|
|
|
|
|
|
|
{ |
|
1100
|
0
|
|
|
|
|
0
|
$joinsql[$jj] = $sqlstr; |
|
1101
|
0
|
0
|
|
|
|
0
|
$joinfid = $joinalias[$jj] ? $joinalias[$jj] : $joinfid[$jj]; |
|
1102
|
0
|
|
|
|
|
0
|
%addfields = (); |
|
1103
|
|
|
|
|
|
|
|
|
1104
|
0
|
|
|
|
|
0
|
$joinsql[$jj] =~ s/^\s+//gso; #STRIP LEADING, TRAILING SPACES. |
|
1105
|
0
|
|
|
|
|
0
|
$joinsql[$jj] =~ s/\s+$//gso; |
|
1106
|
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
#CONVERT ALL "jointable.fieldname" to "fieldname" & REMOVE ALL "othertables.fieldname". |
|
1108
|
|
|
|
|
|
|
|
|
1109
|
0
|
|
|
|
|
0
|
$joinsql[$jj] =~ s!^\s*select(?:\s*distinct)?\s+(.+)\s+from\s+! |
|
1110
|
0
|
|
|
|
|
0
|
my $one = $1; |
|
1111
|
0
|
|
|
|
|
0
|
$one =~ s/$joinfid\.//g; |
|
1112
|
0
|
|
|
|
|
0
|
$one =~ s/\w+\.\w+(?:\s*\,)?//go; |
|
1113
|
0
|
|
|
|
|
0
|
$one =~ s/\,\s*$//o; |
|
1114
|
0
|
|
|
|
|
0
|
"select $one from " |
|
1115
|
|
|
|
|
|
|
!eis; |
|
1116
|
|
|
|
|
|
|
|
|
1117
|
0
|
0
|
|
|
|
0
|
$whereclause = $1 if ($joinsql[$jj] =~ s/\s+where\s+(.+)$/ /iso); |
|
1118
|
|
|
|
|
|
|
# $csr->STORE("sprite_where0", $whereclause) unless ($jj); |
|
1119
|
0
|
0
|
|
|
|
0
|
unless ($jj) |
|
1120
|
|
|
|
|
|
|
{ |
|
1121
|
0
|
|
|
|
|
0
|
my $unprotectedWhere = $whereclause; |
|
1122
|
0
|
0
|
|
|
|
0
|
if ($whereclause =~ /\S/o) |
|
1123
|
|
|
|
|
|
|
{ |
|
1124
|
|
|
|
|
|
|
#RESTORE QUOTED STRINGS AND ESCAPED QUOTES WITHIN THEM. |
|
1125
|
0
|
|
|
|
|
0
|
1 while ($unprotectedWhere =~ s/\$QS\[(\d+)\]/ |
|
1126
|
0
|
|
|
|
|
0
|
my $one = $1; |
|
1127
|
0
|
|
|
|
|
0
|
my $quotechar = substr($QS[$one],0,1); |
|
1128
|
0
|
|
|
|
|
0
|
($quotechar.substr($QS[$one],1).$quotechar) |
|
1129
|
|
|
|
|
|
|
/es); |
|
1130
|
0
|
|
|
|
|
0
|
$unprotectedWhere =~ s/\x02\^4jSpR1tE\x02/\"\"/gso; #UNPROTECT QUOTES WITHIN QUOTES! |
|
1131
|
0
|
|
|
|
|
0
|
$unprotectedWhere =~ s/\x02\^3jSpR1tE\x02/\'\'/gso; |
|
1132
|
|
|
|
|
|
|
} |
|
1133
|
0
|
|
|
|
|
0
|
$csr->STORE("sprite_where0", $unprotectedWhere); |
|
1134
|
|
|
|
|
|
|
} |
|
1135
|
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
# $whereclause =~ s/([\'\"])([^\1]*?)\1//g; #STRIP OUT QUOTED STRINGS TO PREVENT INTERFEARANCE W/OTHER REGICES. |
|
1138
|
0
|
0
|
|
|
|
0
|
$_ = $1 if ($joinsql[$jj] =~ /select\s+(.+?)\s+from\s+/o); |
|
1139
|
0
|
|
|
|
|
0
|
s/\s+//go; |
|
1140
|
0
|
|
|
|
|
0
|
@selectfields = split(/\,/o, $_); |
|
1141
|
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
#DEAL WITH THE ORDER-BY CLAUSE, IF ANY. |
|
1143
|
|
|
|
|
|
|
|
|
1144
|
0
|
0
|
0
|
|
|
0
|
if ($whereclause =~ s/\s+order\s+by\s*(.*)//iso || $joinsql[$jj] =~ s/\s+order\s+by\s*(.*)//iso) |
|
1145
|
|
|
|
|
|
|
{ |
|
1146
|
0
|
|
|
|
|
0
|
my $ordbyclause = $1; |
|
1147
|
0
|
0
|
|
|
|
0
|
if ($jj) |
|
1148
|
|
|
|
|
|
|
{ |
|
1149
|
0
|
|
|
|
|
0
|
$ordbyclause =~ s/(?:$joinalias[0]|$joinfid[0])\.\w+(?:\s+desc)?//gis; |
|
1150
|
|
|
|
|
|
|
} |
|
1151
|
|
|
|
|
|
|
else |
|
1152
|
|
|
|
|
|
|
{ |
|
1153
|
0
|
0
|
|
|
|
0
|
$csr->STORE('sprite_joinorder', ( |
|
1154
|
|
|
|
|
|
|
($ordbyclause =~ /^(?:$joinalias[1]|$joinfid[1])\./) |
|
1155
|
|
|
|
|
|
|
? 1 : 0)); |
|
1156
|
0
|
|
|
|
|
0
|
$ordbyclause =~ s/(?:$joinalias[1]|$joinfid[1])\.\w+(?:\s+desc)?\s*\,?//gis; |
|
1157
|
|
|
|
|
|
|
} |
|
1158
|
0
|
|
|
|
|
0
|
$ordbyclause =~ s/\w+\.(\w+)/$1/gs; |
|
1159
|
0
|
|
|
|
|
0
|
$ordbyclause =~ s/\,\s*$//so; |
|
1160
|
0
|
|
|
|
|
0
|
$ordbyclause =~ s/^\s*\,//so; |
|
1161
|
0
|
0
|
|
|
|
0
|
$joinsql[$jj] .= " order by $ordbyclause" if ($ordbyclause =~ /\S/o); |
|
1162
|
|
|
|
|
|
|
} |
|
1163
|
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
#ADD ANY FIELDS IN WHERE-CLAUSE BUT NOT FETCHED (WE MUST FETCH THEM)! |
|
1165
|
0
|
|
|
|
|
0
|
@union = (); |
|
1166
|
0
|
|
|
|
|
0
|
while ($whereclause =~ s/$joinfid\.(\w+)//is) |
|
1167
|
|
|
|
|
|
|
{ |
|
1168
|
0
|
|
|
|
|
0
|
$addfields{$1} = 1; |
|
1169
|
0
|
|
|
|
|
0
|
push (@union, "$joinfid.$1"); |
|
1170
|
|
|
|
|
|
|
} |
|
1171
|
0
|
|
|
|
|
0
|
$csr->STORE("sprite_union$jj", [@union]); |
|
1172
|
0
|
|
|
|
|
0
|
$joinsql[$jj] =~ s/$joinfid\.(\w+)/$1/gs; |
|
1173
|
|
|
|
|
|
|
# unless ($whereclause) |
|
1174
|
|
|
|
|
|
|
# { |
|
1175
|
|
|
|
|
|
|
# DBI::set_err($resptr, -1, 'Join queries require "where"-clause!'); |
|
1176
|
|
|
|
|
|
|
# return undef; |
|
1177
|
|
|
|
|
|
|
# } |
|
1178
|
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
#REMOVE THE OTHER TABLES FROM THE FROM CLAUSE. |
|
1180
|
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
#$joinsql[$jj] =~ s!\s+from\s+(\w+.*?)(\s+where.*)?$!" from $joinfid[$jj] $2"!egs; |
|
1182
|
0
|
|
|
|
|
0
|
$joinsql[$jj] =~ s!\s+from\s+(\w+.*?)(\s+(?:where|order\s+by).*)?$!" from $joinfid[$jj] $2"!egs; |
|
|
0
|
|
|
|
|
0
|
|
|
1183
|
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
#APPEND UNION FIELDS FROM JOINTABLE NOT IN SELECT LIST TO SELECT LIST. |
|
1185
|
|
|
|
|
|
|
|
|
1186
|
0
|
|
|
|
|
0
|
$addthesefields = ''; |
|
1187
|
0
|
|
|
|
|
0
|
$listprefix = ''; |
|
1188
|
0
|
0
|
|
|
|
0
|
unless ($selectfields[0] eq '*') |
|
1189
|
|
|
|
|
|
|
{ |
|
1190
|
0
|
|
|
|
|
0
|
outer: foreach my $j (keys %addfields) |
|
1191
|
|
|
|
|
|
|
{ |
|
1192
|
0
|
|
|
|
|
0
|
for (my $k=0;$k<=$#selectfields;$k++) |
|
1193
|
|
|
|
|
|
|
{ |
|
1194
|
0
|
0
|
|
|
|
0
|
next outer if ($selectfields[$k] eq $j); |
|
1195
|
|
|
|
|
|
|
# $listprefix = ','; #REMOVED 20040913 |
|
1196
|
|
|
|
|
|
|
} |
|
1197
|
|
|
|
|
|
|
#$addthesefields .= $listprefix . $j; #CHGD. TO NEXT 20040913 |
|
1198
|
0
|
|
|
|
|
0
|
$addthesefields .= $listprefix . $j . ','; |
|
1199
|
|
|
|
|
|
|
} |
|
1200
|
0
|
|
|
|
|
0
|
$addthesefields =~ s/\,$//o; |
|
1201
|
|
|
|
|
|
|
#$joinsql[$jj] =~ s/\s+from\s+/ $addthesefields from /; #CHGD. TO NEXT IF-STMT. 20040929. |
|
1202
|
0
|
0
|
|
|
|
0
|
if ($addthesefields) |
|
1203
|
|
|
|
|
|
|
{ |
|
1204
|
0
|
0
|
|
|
|
0
|
($joinsql[$jj] =~ s/^\s*select\s+from\s+$joinfid[$jj]/select $addthesefields from $joinfid[$jj]/is) |
|
1205
|
|
|
|
|
|
|
or |
|
1206
|
|
|
|
|
|
|
($joinsql[$jj] =~ s/\s+from\s+$joinfid[$jj]/,$addthesefields from $joinfid[$jj]/is); |
|
1207
|
|
|
|
|
|
|
} |
|
1208
|
|
|
|
|
|
|
} |
|
1209
|
|
|
|
|
|
|
#$csr->STORE("sprite_bi$jj", $bindindices[$jj]); |
|
1210
|
0
|
|
|
|
|
0
|
$csr->STORE("sprite_joinnops$jj", 0); |
|
1211
|
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
#RESTORE QUOTED STRINGS AND ESCAPED QUOTES WITHIN THEM. |
|
1213
|
0
|
|
|
|
|
0
|
1 while ($joinsql[$jj] =~ s/\$QS\[(\d+)\]/ |
|
1214
|
0
|
|
|
|
|
0
|
my $one = $1; |
|
1215
|
0
|
|
|
|
|
0
|
my $quotechar = substr($QS[$one],0,1); |
|
1216
|
0
|
|
|
|
|
0
|
($quotechar.substr($QS[$one],1).$quotechar) |
|
1217
|
|
|
|
|
|
|
/es); |
|
1218
|
0
|
|
|
|
|
0
|
$joinsql[$jj] =~ s/\x02\^4jSpR1tE\x02/\"\"/gso; #UNPROTECT QUOTES WITHIN QUOTES! |
|
1219
|
0
|
|
|
|
|
0
|
$joinsql[$jj] =~ s/\x02\^3jSpR1tE\x02/\'\'/gso; |
|
1220
|
0
|
|
|
|
|
0
|
$csr->STORE("sprite_joinstmt$jj", $joinsql[$jj]); |
|
1221
|
|
|
|
|
|
|
} |
|
1222
|
0
|
|
|
|
|
0
|
$csr->STORE('sprite_joinparams', []); |
|
1223
|
|
|
|
|
|
|
} |
|
1224
|
|
|
|
|
|
|
else |
|
1225
|
|
|
|
|
|
|
{ |
|
1226
|
0
|
|
|
|
|
0
|
$sqlstr =~ s/select\s+(.*?)\s+from\s+(\w+)\s+(\w+)\s+(where\s+.+|order\s+.+)?$/ |
|
1227
|
0
|
|
|
|
|
0
|
my ($one, $two, $three, $four) = ($1, $2, $3, $4); |
|
1228
|
0
|
|
|
|
|
0
|
$one =~ s|\b$three\.(\w)|$1|g; |
|
1229
|
0
|
|
|
|
|
0
|
$four =~ s|\b$three\.(\w)|$1|g; |
|
1230
|
0
|
|
|
|
|
0
|
"select $one from $two $four" |
|
1231
|
|
|
|
|
|
|
/eis; |
|
1232
|
|
|
|
|
|
|
} |
|
1233
|
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
#SET UP STMT. PARAMETERS. |
|
1235
|
|
|
|
|
|
|
|
|
1236
|
0
|
|
|
|
|
0
|
$csr->STORE('sprite_params', []); |
|
1237
|
0
|
|
|
|
|
0
|
$num_of_params = ($sqlstr =~ tr/\?//); |
|
1238
|
0
|
|
|
|
|
0
|
$sqlstr =~ s/\x02\^2jSpR1tE\x02/\?/gso; |
|
1239
|
0
|
|
|
|
|
0
|
$csr->STORE('NUM_OF_PARAMS', $num_of_params); |
|
1240
|
0
|
0
|
|
|
|
0
|
$sqlstr = $joinsql[0] if ($joinsql[0]); |
|
1241
|
|
|
|
|
|
|
|
|
1242
|
|
|
|
|
|
|
#RESTORE QUOTED STRINGS. |
|
1243
|
0
|
|
|
|
|
0
|
1 while ($sqlstr =~ s/\$QS\[(\d+)\]/ |
|
1244
|
0
|
|
|
|
|
0
|
my $one = $1; |
|
1245
|
0
|
|
|
|
|
0
|
my $quotechar = substr($QS[$one],0,1); |
|
1246
|
0
|
|
|
|
|
0
|
($quotechar.substr($QS[$one],1).$quotechar) |
|
1247
|
|
|
|
|
|
|
/es); |
|
1248
|
|
|
|
|
|
|
#$sqlstr =~ s/\x02\^3jSpR1tE\x02/\"\"/gs; #BUGFIX: CHGD NEXT 2 TO FOLLOWING 2 20050429. |
|
1249
|
|
|
|
|
|
|
#$sqlstr =~ s/\x02\^2jSpR1tE\x02/\'\'/gs; |
|
1250
|
0
|
|
|
|
|
0
|
$sqlstr =~ s/\x02\^4jSpR1tE\x02/\"\"/gso; #UNPROTECT QUOTES WITHIN QUOTES! |
|
1251
|
0
|
|
|
|
|
0
|
$sqlstr =~ s/\x02\^3jSpR1tE\x02/\'\'/gso; |
|
1252
|
0
|
|
|
|
|
0
|
$csr->STORE('sprite_statement', $sqlstr); |
|
1253
|
0
|
|
|
|
|
0
|
return ($csr); |
|
1254
|
|
|
|
|
|
|
} |
|
1255
|
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
sub parseParins #RECURSIVELY ASSIGN ALL PARENTHAASZED EXPRESSIONS TO AN ARRAY TO PROTECT FROM OTHER REGICES. |
|
1257
|
|
|
|
|
|
|
{ |
|
1258
|
0
|
|
|
0
|
|
0
|
my ($T, $tindx, $s) = @_; |
|
1259
|
|
|
|
|
|
|
|
|
1260
|
0
|
|
|
|
|
0
|
$tindx++ while ($s =~ s/\(([^\(\)]+)\)/ |
|
1261
|
0
|
|
|
|
|
0
|
$T->[$tindx] = &parseParins($T, $tindx, $1); |
|
1262
|
0
|
|
|
|
|
0
|
"\$T\[$tindx]" |
|
1263
|
|
|
|
|
|
|
/e); |
|
1264
|
0
|
|
|
|
|
0
|
return $s; |
|
1265
|
|
|
|
|
|
|
} |
|
1266
|
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
sub commit |
|
1268
|
|
|
|
|
|
|
{ |
|
1269
|
0
|
|
|
0
|
|
0
|
my ($dB) = shift; |
|
1270
|
|
|
|
|
|
|
|
|
1271
|
0
|
0
|
0
|
|
|
0
|
if ($dB->FETCH('AutoCommit') && $dB->FETCH('Warn')) |
|
1272
|
|
|
|
|
|
|
{ |
|
1273
|
0
|
|
|
|
|
0
|
warn ('Commit ineffective while AutoCommit is ON!'); |
|
1274
|
0
|
|
|
|
|
0
|
return 1; |
|
1275
|
|
|
|
|
|
|
} |
|
1276
|
0
|
|
|
|
|
0
|
my ($commitResult) = 1; #ADDED 20000103 |
|
1277
|
|
|
|
|
|
|
|
|
1278
|
0
|
|
|
|
|
0
|
foreach (keys %{$dB->{sprite_SpritesOpen}}) |
|
|
0
|
|
|
|
|
0
|
|
|
1279
|
|
|
|
|
|
|
{ |
|
1280
|
0
|
0
|
|
|
|
0
|
next unless (defined($dB->{'sprite_SpritesOpen'}->{$_})); |
|
1281
|
0
|
0
|
|
|
|
0
|
next if (/^(USER|ALL)_TABLES$/i); |
|
1282
|
0
|
0
|
|
|
|
0
|
next unless (defined(${$dB->{'sprite_SpritesOpen'}->{$_}})); |
|
|
0
|
|
|
|
|
0
|
|
|
1283
|
0
|
|
|
|
|
0
|
$commitResult = ${$dB->{'sprite_SpritesOpen'}->{$_}}->commit($_); |
|
|
0
|
|
|
|
|
0
|
|
|
1284
|
0
|
0
|
0
|
|
|
0
|
return undef if (!defined($commitResult) || $commitResult <= 0); |
|
1285
|
|
|
|
|
|
|
} |
|
1286
|
0
|
|
|
|
|
0
|
return 1; |
|
1287
|
|
|
|
|
|
|
} |
|
1288
|
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
sub rollback |
|
1290
|
|
|
|
|
|
|
{ |
|
1291
|
0
|
|
|
0
|
|
0
|
my ($dB) = shift; |
|
1292
|
|
|
|
|
|
|
|
|
1293
|
0
|
0
|
0
|
|
|
0
|
if (!shift && $dB->FETCH('AutoCommit') && $dB->FETCH('Warn')) |
|
|
|
|
0
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
{ |
|
1295
|
0
|
|
|
|
|
0
|
warn ('Rollback ineffective while AutoCommit is ON!'); |
|
1296
|
0
|
|
|
|
|
0
|
return 1; |
|
1297
|
|
|
|
|
|
|
} |
|
1298
|
|
|
|
|
|
|
|
|
1299
|
0
|
|
|
|
|
0
|
foreach my $s (keys %{$dB->{sprite_SpritesOpen}}) |
|
|
0
|
|
|
|
|
0
|
|
|
1300
|
|
|
|
|
|
|
{ |
|
1301
|
0
|
0
|
|
|
|
0
|
next unless (defined($dB->{'sprite_SpritesOpen'}->{$s})); |
|
1302
|
0
|
0
|
|
|
|
0
|
next if ($s =~ /^(USER|ALL)_TABLES$/i); |
|
1303
|
0
|
0
|
|
|
|
0
|
next unless (defined(${$dB->{'sprite_SpritesOpen'}->{$s}})); |
|
|
0
|
|
|
|
|
0
|
|
|
1304
|
0
|
|
|
|
|
0
|
${$dB->{'sprite_SpritesOpen'}->{$s}}->rollback($s); |
|
|
0
|
|
|
|
|
0
|
|
|
1305
|
|
|
|
|
|
|
} |
|
1306
|
0
|
|
|
|
|
0
|
return 1; |
|
1307
|
|
|
|
|
|
|
} |
|
1308
|
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
sub STORE |
|
1310
|
|
|
|
|
|
|
{ |
|
1311
|
0
|
|
|
0
|
|
0
|
my($dbh, $attr, $val) = @_; |
|
1312
|
0
|
0
|
|
|
|
0
|
if ($attr eq 'AutoCommit') |
|
1313
|
|
|
|
|
|
|
{ |
|
1314
|
|
|
|
|
|
|
# AutoCommit is currently the only standard attribute we have |
|
1315
|
|
|
|
|
|
|
# to consider. |
|
1316
|
|
|
|
|
|
|
|
|
1317
|
0
|
0
|
0
|
|
|
0
|
$dbh->commit() if ($val == 1 && !$dbh->FETCH('AutoCommit')); |
|
1318
|
0
|
|
|
|
|
0
|
$dbh->{AutoCommit} = $val; |
|
1319
|
0
|
|
|
|
|
0
|
return 1; |
|
1320
|
|
|
|
|
|
|
} |
|
1321
|
0
|
0
|
|
|
|
0
|
if ($attr =~ /^sprite/o) |
|
1322
|
|
|
|
|
|
|
{ |
|
1323
|
|
|
|
|
|
|
# Handle only our private attributes here |
|
1324
|
|
|
|
|
|
|
# Note that we could trigger arbitrary actions. |
|
1325
|
|
|
|
|
|
|
# Ideally we should catch unknown attributes. |
|
1326
|
0
|
|
|
|
|
0
|
$dbh->{$attr} = $val; # Yes, we are allowed to do this, |
|
1327
|
0
|
|
|
|
|
0
|
return 1; # but only for our private attributes |
|
1328
|
|
|
|
|
|
|
} |
|
1329
|
|
|
|
|
|
|
# Else pass up to DBI to handle for us |
|
1330
|
0
|
|
|
|
|
0
|
$dbh->SUPER::STORE($attr, $val); |
|
1331
|
|
|
|
|
|
|
} |
|
1332
|
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
sub FETCH |
|
1334
|
|
|
|
|
|
|
{ |
|
1335
|
1
|
|
|
1
|
|
3
|
my($dbh, $attr) = @_; |
|
1336
|
1
|
50
|
|
|
|
4
|
if ($attr eq 'AutoCommit') { return $dbh->{AutoCommit}; } |
|
|
1
|
|
|
|
|
16
|
|
|
1337
|
0
|
0
|
|
|
|
0
|
if ($attr =~ /^sprite_/o) |
|
1338
|
|
|
|
|
|
|
{ |
|
1339
|
|
|
|
|
|
|
# Handle only our private attributes here |
|
1340
|
|
|
|
|
|
|
# Note that we could trigger arbitrary actions. |
|
1341
|
0
|
|
|
|
|
0
|
return $dbh->{$attr}; # Yes, we are allowed to do this, |
|
1342
|
|
|
|
|
|
|
# but only for our private attributes |
|
1343
|
0
|
|
|
|
|
0
|
return $dbh->{$attr}; |
|
1344
|
|
|
|
|
|
|
} |
|
1345
|
|
|
|
|
|
|
# Else pass up to DBI to handle |
|
1346
|
0
|
|
|
|
|
0
|
$dbh->SUPER::FETCH($attr); |
|
1347
|
|
|
|
|
|
|
} |
|
1348
|
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
sub disconnect |
|
1350
|
|
|
|
|
|
|
{ |
|
1351
|
0
|
|
|
0
|
|
0
|
my ($db) = shift; |
|
1352
|
|
|
|
|
|
|
|
|
1353
|
|
|
|
|
|
|
#DBI::set_err($db, 0, ''); #CHGD. TO NEXT 20041104. |
|
1354
|
0
|
|
|
|
|
0
|
DBI::set_err($db, undef); |
|
1355
|
0
|
|
|
|
|
0
|
return (1); #20000114: MAKE WORK LIKE DBI! |
|
1356
|
|
|
|
|
|
|
} |
|
1357
|
|
|
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
sub do |
|
1359
|
|
|
|
|
|
|
{ |
|
1360
|
0
|
|
|
0
|
|
0
|
my ($dB, $sqlstr, $attr, @bind_values) = @_; |
|
1361
|
0
|
0
|
|
|
|
0
|
my ($csr) = $dB->prepare($sqlstr, $attr) or return undef; |
|
1362
|
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
#DBI::set_err($dB, 0, ''); #CHGD. TO NEXT 20041104. |
|
1364
|
0
|
|
|
|
|
0
|
DBI::set_err($dB, undef); |
|
1365
|
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
#my $retval = $csr->execute(@bind_values) || undef; |
|
1367
|
0
|
|
0
|
|
|
0
|
return ($csr->execute(@bind_values) || undef); |
|
1368
|
|
|
|
|
|
|
} |
|
1369
|
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
sub table_info |
|
1371
|
|
|
|
|
|
|
{ |
|
1372
|
0
|
|
|
0
|
|
0
|
my($dbh) = @_; # XXX add qualification |
|
1373
|
0
|
0
|
|
|
|
0
|
my $sth = $dbh->prepare('select TABLE_NAME from USER_TABLES') |
|
1374
|
|
|
|
|
|
|
or return undef; |
|
1375
|
0
|
0
|
|
|
|
0
|
$sth->execute or return undef; |
|
1376
|
0
|
|
|
|
|
0
|
return $sth; |
|
1377
|
|
|
|
|
|
|
} |
|
1378
|
|
|
|
|
|
|
|
|
1379
|
|
|
|
|
|
|
sub primary_key_info #ADDED 20060613 TO SUPPORT DBI primary_key/primary_key_info FUNCTIONS! |
|
1380
|
|
|
|
|
|
|
{ |
|
1381
|
0
|
|
|
0
|
|
0
|
my ($dbh, $cat, $schema, $tablename) = @_; |
|
1382
|
0
|
0
|
|
|
|
0
|
my $sth = $dbh->prepare("PRIMARY_KEY_INFO $tablename") |
|
1383
|
|
|
|
|
|
|
or return undef; |
|
1384
|
0
|
0
|
|
|
|
0
|
$sth->execute() or return undef; |
|
1385
|
0
|
|
|
|
|
0
|
return $sth; |
|
1386
|
|
|
|
|
|
|
} |
|
1387
|
|
|
|
|
|
|
|
|
1388
|
|
|
|
|
|
|
sub type_info_all #ADDED 20010312, BORROWED FROM "Oracle.pm". |
|
1389
|
|
|
|
|
|
|
{ |
|
1390
|
0
|
|
|
0
|
|
0
|
my ($dbh) = @_; |
|
1391
|
0
|
|
|
|
|
0
|
my $names = |
|
1392
|
|
|
|
|
|
|
{ |
|
1393
|
|
|
|
|
|
|
TYPE_NAME => 0, |
|
1394
|
|
|
|
|
|
|
DATA_TYPE => 1, |
|
1395
|
|
|
|
|
|
|
COLUMN_SIZE => 2, |
|
1396
|
|
|
|
|
|
|
LITERAL_PREFIX => 3, |
|
1397
|
|
|
|
|
|
|
LITERAL_SUFFIX => 4, |
|
1398
|
|
|
|
|
|
|
CREATE_PARAMS => 5, |
|
1399
|
|
|
|
|
|
|
NULLABLE => 6, |
|
1400
|
|
|
|
|
|
|
CASE_SENSITIVE => 7, |
|
1401
|
|
|
|
|
|
|
SEARCHABLE => 8, |
|
1402
|
|
|
|
|
|
|
UNSIGNED_ATTRIBUTE => 9, |
|
1403
|
|
|
|
|
|
|
FIXED_PREC_SCALE =>10, |
|
1404
|
|
|
|
|
|
|
AUTO_UNIQUE_VALUE =>11, |
|
1405
|
|
|
|
|
|
|
LOCAL_TYPE_NAME =>12, |
|
1406
|
|
|
|
|
|
|
MINIMUM_SCALE =>13, |
|
1407
|
|
|
|
|
|
|
MAXIMUM_SCALE =>14, |
|
1408
|
|
|
|
|
|
|
} |
|
1409
|
|
|
|
|
|
|
; |
|
1410
|
|
|
|
|
|
|
# Based on the values from Oracle 8.0.4 ODBC driver |
|
1411
|
0
|
|
|
|
|
0
|
my $ti = [ |
|
1412
|
|
|
|
|
|
|
$names, |
|
1413
|
|
|
|
|
|
|
[ 'LONG RAW', -4, '2147483647', '\'', '\'', undef, 1, '0', '0', |
|
1414
|
|
|
|
|
|
|
undef, '0', undef, undef, undef, undef |
|
1415
|
|
|
|
|
|
|
], |
|
1416
|
|
|
|
|
|
|
[ 'RAW', -2, 255, '\'', '\'', 'max length', 1, '0', 3, |
|
1417
|
|
|
|
|
|
|
undef, '0', undef, undef, undef, undef |
|
1418
|
|
|
|
|
|
|
], |
|
1419
|
|
|
|
|
|
|
[ 'LONG', -1, '2147483647', '\'', '\'', undef, 1, 1, '0', |
|
1420
|
|
|
|
|
|
|
undef, '0', undef, undef, undef, undef |
|
1421
|
|
|
|
|
|
|
], |
|
1422
|
|
|
|
|
|
|
[ 'CHAR', 1, 255, '\'', '\'', 'max length', 1, 1, 3, |
|
1423
|
|
|
|
|
|
|
undef, '0', '0', undef, undef, undef |
|
1424
|
|
|
|
|
|
|
], |
|
1425
|
|
|
|
|
|
|
[ 'NUMBER', 3, 38, undef, undef, 'precision,scale', 1, '0', 3, |
|
1426
|
|
|
|
|
|
|
'0', '0', '0', undef, '0', 38 |
|
1427
|
|
|
|
|
|
|
], |
|
1428
|
|
|
|
|
|
|
[ 'AUTONUMBER', 4, 38, undef, undef, 'precision,scale', 1, '0', 3, |
|
1429
|
|
|
|
|
|
|
'0', '0', '0', undef, '0', 38 |
|
1430
|
|
|
|
|
|
|
], |
|
1431
|
|
|
|
|
|
|
[ 'DOUBLE', 8, 15, undef, undef, undef, 1, '0', 3, |
|
1432
|
|
|
|
|
|
|
'0', '0', '0', undef, undef, undef |
|
1433
|
|
|
|
|
|
|
], |
|
1434
|
|
|
|
|
|
|
[ 'DATE', 11, 19, '\'', '\'', undef, 1, '0', 3, |
|
1435
|
|
|
|
|
|
|
undef, '0', '0', undef, '0', '0' |
|
1436
|
|
|
|
|
|
|
], |
|
1437
|
|
|
|
|
|
|
[ 'VARCHAR2', 12, 2000, '\'', '\'', 'max length', 1, 1, 3, |
|
1438
|
|
|
|
|
|
|
undef, '0', '0', undef, undef, undef |
|
1439
|
|
|
|
|
|
|
] |
|
1440
|
|
|
|
|
|
|
]; |
|
1441
|
0
|
|
|
|
|
0
|
return $ti; |
|
1442
|
|
|
|
|
|
|
} |
|
1443
|
|
|
|
|
|
|
sub tables #CONVENIENCE METHOD FOR FETCHING LIST OF TABLES IN THE DATABASE. |
|
1444
|
|
|
|
|
|
|
{ |
|
1445
|
0
|
|
|
0
|
|
0
|
my($dbh) = @_; # XXX add qualification |
|
1446
|
|
|
|
|
|
|
|
|
1447
|
0
|
|
|
|
|
0
|
my $sth = $dbh->table_info(); |
|
1448
|
|
|
|
|
|
|
|
|
1449
|
0
|
0
|
|
|
|
0
|
return undef unless ($sth); |
|
1450
|
|
|
|
|
|
|
|
|
1451
|
0
|
|
|
|
|
0
|
my ($row, @tables); |
|
1452
|
|
|
|
|
|
|
|
|
1453
|
0
|
|
|
|
|
0
|
while ($row = $sth->fetchrow_arrayref()) |
|
1454
|
|
|
|
|
|
|
{ |
|
1455
|
0
|
|
|
|
|
0
|
push (@tables, $row->[0]); |
|
1456
|
|
|
|
|
|
|
} |
|
1457
|
0
|
|
|
|
|
0
|
$sth->finish(); |
|
1458
|
0
|
0
|
|
|
|
0
|
return undef unless ($#tables >= 0); |
|
1459
|
0
|
|
|
|
|
0
|
return (@tables); |
|
1460
|
|
|
|
|
|
|
} |
|
1461
|
|
|
|
|
|
|
|
|
1462
|
|
|
|
|
|
|
sub rows |
|
1463
|
|
|
|
|
|
|
{ |
|
1464
|
0
|
|
|
0
|
|
0
|
return $DBI::rows; |
|
1465
|
|
|
|
|
|
|
} |
|
1466
|
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
sub DESTROY #ADDED 20001108 |
|
1468
|
|
|
|
|
|
|
{ |
|
1469
|
1
|
|
|
1
|
|
2
|
my($drh) = shift; |
|
1470
|
|
|
|
|
|
|
|
|
1471
|
1
|
50
|
|
|
|
18
|
if ($drh->FETCH('AutoCommit') == 1) |
|
1472
|
|
|
|
|
|
|
{ |
|
1473
|
0
|
|
|
|
|
0
|
$drh->STORE('AutoCommit',0); |
|
1474
|
0
|
|
|
|
|
0
|
$drh->rollback(); #COMMIT IT IF AUTOCOMMIT ON! |
|
1475
|
0
|
|
|
|
|
0
|
$drh->STORE('AutoCommit',1); |
|
1476
|
|
|
|
|
|
|
} |
|
1477
|
1
|
|
|
|
|
31
|
$drh = undef; |
|
1478
|
|
|
|
|
|
|
} |
|
1479
|
|
|
|
|
|
|
|
|
1480
|
|
|
|
|
|
|
1; |
|
1481
|
|
|
|
|
|
|
|
|
1482
|
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
package DBD::Sprite::st; # ====== STATEMENT ====== |
|
1484
|
1
|
|
|
1
|
|
9
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
110
|
|
|
1485
|
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
my (%typehash) = ( |
|
1487
|
|
|
|
|
|
|
'LONG RAW' => -4, |
|
1488
|
|
|
|
|
|
|
'RAW' => -3, |
|
1489
|
|
|
|
|
|
|
'LONG' => -1, |
|
1490
|
|
|
|
|
|
|
'CHAR' => 1, |
|
1491
|
|
|
|
|
|
|
'NUMBER' => 3, |
|
1492
|
|
|
|
|
|
|
'AUTONUMBER' => 4, |
|
1493
|
|
|
|
|
|
|
'DOUBLE' => 8, |
|
1494
|
|
|
|
|
|
|
'DATE' => 11, |
|
1495
|
|
|
|
|
|
|
'VARCHAR' => 12, |
|
1496
|
|
|
|
|
|
|
'VARCHAR2' => 12, |
|
1497
|
|
|
|
|
|
|
'BOOLEAN' => -7, #ADDED 20000308! |
|
1498
|
|
|
|
|
|
|
'BLOB' => 113, #ADDED 20020110! |
|
1499
|
|
|
|
|
|
|
'MEMO' => -1, #ADDED 20020110! |
|
1500
|
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
'DATE' => 9, |
|
1502
|
|
|
|
|
|
|
'REAL' => 7, |
|
1503
|
|
|
|
|
|
|
'TINYINT' => -6, |
|
1504
|
|
|
|
|
|
|
'NCHAR' => -8, |
|
1505
|
|
|
|
|
|
|
'NVARCHAR' => -9, |
|
1506
|
|
|
|
|
|
|
'NTEXT' => -10, |
|
1507
|
|
|
|
|
|
|
'SMALLDATETIME' => 93, |
|
1508
|
|
|
|
|
|
|
'BIGINT' => -5, |
|
1509
|
|
|
|
|
|
|
'DECIMAL' => 3, |
|
1510
|
|
|
|
|
|
|
'INTEGER' => 4, |
|
1511
|
|
|
|
|
|
|
); |
|
1512
|
|
|
|
|
|
|
|
|
1513
|
|
|
|
|
|
|
$DBD::Sprite::st::imp_data_size = 0; |
|
1514
|
1
|
|
|
1
|
|
4
|
use vars qw($imp_data_size *fetch); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4321
|
|
|
1515
|
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
sub bind_param |
|
1517
|
|
|
|
|
|
|
{ |
|
1518
|
0
|
|
|
0
|
|
|
my($sth, $pNum, $val, $attr) = @_; |
|
1519
|
0
|
0
|
|
|
|
|
my $type = (ref $attr) ? $attr->{TYPE} : $attr; |
|
1520
|
|
|
|
|
|
|
|
|
1521
|
0
|
0
|
|
|
|
|
if ($type) |
|
1522
|
|
|
|
|
|
|
{ |
|
1523
|
0
|
|
|
|
|
|
my $dbh = $sth->{Database}; |
|
1524
|
0
|
|
|
|
|
|
$val = $dbh->quote($val, $type); |
|
1525
|
0
|
|
|
|
|
|
$val =~ s/^\'//o; |
|
1526
|
0
|
|
|
|
|
|
$val =~ s/\'$//o; |
|
1527
|
|
|
|
|
|
|
} |
|
1528
|
0
|
|
|
|
|
|
my $params = $sth->FETCH('sprite_params'); |
|
1529
|
0
|
|
|
|
|
|
$params->[$pNum-1] = $val; |
|
1530
|
|
|
|
|
|
|
|
|
1531
|
|
|
|
|
|
|
#${$sth->{bindvars}}[($pNum-1)] = $val; #FOR SPRITE. #REMOVED 20010312 (LVALUE NOT FOUND ANYWHERE ELSE). |
|
1532
|
|
|
|
|
|
|
|
|
1533
|
0
|
|
|
|
|
|
$sth->STORE('sprite_params', $params); |
|
1534
|
0
|
|
|
|
|
|
return 1; |
|
1535
|
|
|
|
|
|
|
} |
|
1536
|
|
|
|
|
|
|
|
|
1537
|
|
|
|
|
|
|
sub execute |
|
1538
|
|
|
|
|
|
|
{ |
|
1539
|
0
|
|
|
0
|
|
|
my ($sth, @bind_values) = @_; |
|
1540
|
0
|
0
|
|
|
|
|
my $params = (@bind_values) ? \@bind_values : $sth->FETCH('sprite_params'); |
|
1541
|
0
|
|
|
|
|
|
my @ocolnames; |
|
1542
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#{$params};$i++) #ADDED 20000303 FIX QUOTE PROBLEM WITH BINDS. |
|
|
0
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
{ |
|
1544
|
0
|
|
|
|
|
|
$params->[$i] =~ s/\'/\'\'/go; |
|
1545
|
|
|
|
|
|
|
} |
|
1546
|
0
|
|
|
|
|
|
my $numParam = $sth->FETCH('NUM_OF_PARAMS'); |
|
1547
|
|
|
|
|
|
|
|
|
1548
|
0
|
0
|
0
|
|
|
|
if ($params && scalar(@$params) != $numParam) #CHECK FOR RIGHT # PARAMS. |
|
1549
|
|
|
|
|
|
|
{ |
|
1550
|
0
|
|
|
|
|
|
DBI::set_err($sth, (scalar(@$params)-$numParam), |
|
1551
|
|
|
|
|
|
|
"..execute: Wrong number of bind variables (".(scalar(@$params)-$numParam) |
|
1552
|
|
|
|
|
|
|
." too many!)"); |
|
1553
|
0
|
|
|
|
|
|
return undef; |
|
1554
|
|
|
|
|
|
|
} |
|
1555
|
|
|
|
|
|
|
#my $sqlstr = $sth->{'Statement'}; #CHGD. TO NEXT 20040205 TO PERMIT JOINS. |
|
1556
|
0
|
|
|
|
|
|
my $sqlstr = $sth->FETCH('sprite_statement'); |
|
1557
|
|
|
|
|
|
|
#NEXT 8 LINES ADDED 20010911 TO FIX BUG WHEN QUOTED VALUES CONTAIN "?"s. |
|
1558
|
0
|
|
|
|
|
|
$sqlstr =~ s/\\\'/\x02\^3jSpR1tE\x02/gso; #PROTECT ESCAPED DOUBLE-QUOTES. |
|
1559
|
0
|
|
|
|
|
|
$sqlstr =~ s/\'\'/\x02\^4jSpR1tE\x02/gso; #PROTECT DOUBLED DOUBLE-QUOTES. |
|
1560
|
0
|
|
|
|
|
|
$sqlstr =~ s/\'([^\']*?)\'/ |
|
1561
|
0
|
|
|
|
|
|
my ($str) = $1; |
|
1562
|
0
|
|
|
|
|
|
$str =~ s|\?|\x02\^2jSpR1tE\x02|gs; #PROTECT QUESTION-MARKS WITHIN QUOTES. |
|
1563
|
0
|
|
|
|
|
|
"'$str'"/egs; |
|
1564
|
0
|
|
|
|
|
|
$sqlstr =~ s/\x02\^4jSpR1tE\x02/\'\'/gso; #UNPROTECT DOUBLED DOUBLE-QUOTES. |
|
1565
|
0
|
|
|
|
|
|
$sqlstr =~ s/\x02\^3jSpR1tE\x02/\\\'/gso; #UNPROTECT ESCAPED DOUBLE-QUOTES. |
|
1566
|
|
|
|
|
|
|
|
|
1567
|
|
|
|
|
|
|
#CONVERT REMAINING QUESTION-MARKS TO BOUND VALUES. |
|
1568
|
|
|
|
|
|
|
|
|
1569
|
|
|
|
|
|
|
# my $bindindices = $sth->FETCH('sprite_bi0') || [0..($numParam-1)]; |
|
1570
|
|
|
|
|
|
|
# foreach my $i (@$bindindices) |
|
1571
|
0
|
|
|
|
|
|
for (my $i = 0; $i < $numParam; $i++) |
|
1572
|
|
|
|
|
|
|
{ |
|
1573
|
0
|
|
|
|
|
|
$params->[$i] =~ s/\?/\x02\^2jSpR1tE\x02/gso; #ADDED 20001023 TO FIX BUG WHEN PARAMETER OTHER THAN LAST CONTAINS A "?"! |
|
1574
|
0
|
|
|
|
|
|
$sqlstr =~ s/\?/"'".$params->[$i]."'"/es; |
|
|
0
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
} |
|
1576
|
0
|
|
|
|
|
|
$sqlstr =~ s/\x02\^2jSpR1tE\x02/\?/gso; #ADDED 20001023! - UNPROTECT PROTECTED "?"s. |
|
1577
|
0
|
|
|
|
|
|
my ($spriteref) = $sth->FETCH('sprite_spritedb'); |
|
1578
|
|
|
|
|
|
|
|
|
1579
|
|
|
|
|
|
|
#CALL JSPRITE TO DO THE SQL! |
|
1580
|
0
|
|
|
|
|
|
my (@resv) = $spriteref->sql($sqlstr); |
|
1581
|
|
|
|
|
|
|
#!!! HANDLE SPRITE ERRORS HERE (SEE SPRITE.PM)!!! |
|
1582
|
0
|
|
|
|
|
|
my ($retval) = undef; |
|
1583
|
0
|
0
|
|
|
|
|
if ($#resv < 0) #GENERAL ERROR! |
|
|
|
0
|
|
|
|
|
|
|
1584
|
|
|
|
|
|
|
{ |
|
1585
|
|
|
|
|
|
|
DBI::set_err($sth, ($spriteref->{lasterror} || -601), |
|
1586
|
0
|
|
0
|
|
|
|
($spriteref->{lastmsg} || 'Unknown Error!')); |
|
|
|
|
0
|
|
|
|
|
|
1587
|
0
|
|
|
|
|
|
return $retval; |
|
1588
|
|
|
|
|
|
|
} |
|
1589
|
|
|
|
|
|
|
elsif ($resv[0]) #NORMAL ACTION IF NON SELECT OR >0 ROWS SELECTED. |
|
1590
|
|
|
|
|
|
|
{ |
|
1591
|
0
|
|
|
|
|
|
$retval = $resv[0]; |
|
1592
|
0
|
|
|
|
|
|
my $dB = $sth->{Database}; |
|
1593
|
|
|
|
|
|
|
#if ($dB->FETCH('AutoCommit') == 1 && $sth->FETCH('Statement') !~ /^\s*select/i) #CHGD. TO NEXT 20040205 TO PERMIT JOINS. |
|
1594
|
0
|
0
|
|
|
|
|
if ($sth->FETCH('sprite_statement') !~ /^\s*(?:select|primary_key_info)/io) |
|
1595
|
|
|
|
|
|
|
{ |
|
1596
|
0
|
0
|
|
|
|
|
if ($dB->FETCH('AutoCommit') == 1) |
|
1597
|
|
|
|
|
|
|
{ |
|
1598
|
0
|
0
|
|
|
|
|
$retval = undef unless ($spriteref->commit()); #ADDED 20010911 TO MAKE AUTOCOMMIT WORK (OOPS :( ) |
|
1599
|
|
|
|
|
|
|
#$dB->STORE('AutoCommit',1); #COMMIT DONE HERE! |
|
1600
|
|
|
|
|
|
|
} |
|
1601
|
|
|
|
|
|
|
} |
|
1602
|
|
|
|
|
|
|
else |
|
1603
|
|
|
|
|
|
|
{ |
|
1604
|
|
|
|
|
|
|
#OCOL* = ORIGINAL SQL. |
|
1605
|
|
|
|
|
|
|
#ICOL* = BASE SQL. |
|
1606
|
|
|
|
|
|
|
#JCOL* = JOIN SQL. |
|
1607
|
0
|
|
|
|
|
|
$sqlstr = $sth->FETCH('sprite_joinstmt1'); |
|
1608
|
0
|
0
|
|
|
|
|
if ($sqlstr) |
|
1609
|
|
|
|
|
|
|
{ |
|
1610
|
0
|
|
|
|
|
|
$sqlstr =~ s/\\\'/\x02\^3jSpR1tE\x02/gso; #PROTECT ESCAPED DOUBLE-QUOTES. |
|
1611
|
0
|
|
|
|
|
|
$sqlstr =~ s/\'\'/\x02\^4jSpR1tE\x02/gso; #PROTECT DOUBLED DOUBLE-QUOTES. |
|
1612
|
0
|
|
|
|
|
|
$sqlstr =~ s/\'([^\']*?)\'/ |
|
1613
|
0
|
|
|
|
|
|
my ($str) = $1; |
|
1614
|
0
|
|
|
|
|
|
$str =~ s|\?|\x02\^2jSpR1tE\x02|gso; #PROTECT QUESTION-MARKS WITHIN QUOTES. |
|
1615
|
0
|
|
|
|
|
|
"'$str'"/egs; |
|
1616
|
0
|
|
|
|
|
|
$sqlstr =~ s/\x02\^4jSpR1tE\x02/\'\'/gso; #UNPROTECT DOUBLED DOUBLE-QUOTES. |
|
1617
|
0
|
|
|
|
|
|
$sqlstr =~ s/\x02\^3jSpR1tE\x02/\\\'/gso; #UNPROTECT ESCAPED DOUBLE-QUOTES. |
|
1618
|
|
|
|
|
|
|
|
|
1619
|
|
|
|
|
|
|
#CONVERT REMAINING QUESTION-MARKS TO BOUND VALUES. |
|
1620
|
|
|
|
|
|
|
|
|
1621
|
|
|
|
|
|
|
#!!! my $bindindices = $sth->FETCH('sprite_bi1'); |
|
1622
|
|
|
|
|
|
|
# foreach my $i (@$bindindices) |
|
1623
|
|
|
|
|
|
|
# { |
|
1624
|
|
|
|
|
|
|
# $params->[$i] =~ s/\?/\x02\^2jSpR1tE\x02/gs; #ADDED 20001023 TO FIX BUG WHEN PARAMETER OTHER THAN LAST CONTAINS A "?"! |
|
1625
|
|
|
|
|
|
|
# $sqlstr =~ s/\?/"'".$params->[$i]."'"/es; |
|
1626
|
|
|
|
|
|
|
# } |
|
1627
|
0
|
|
|
|
|
|
$sqlstr =~ s/\x02\^2jSpR1tE\x02/\?/gso; #ADDED 20001023! - UNPROTECT PROTECTED "?"s. |
|
1628
|
0
|
|
|
|
|
|
my @icolnames = split(/\,/o, $spriteref->{use_fields}); |
|
1629
|
0
|
|
|
|
|
|
my %icolHash; |
|
1630
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#icolnames;$i++) |
|
1631
|
|
|
|
|
|
|
{ |
|
1632
|
0
|
|
|
|
|
|
$icolHash{$icolnames[$i]} = $i; |
|
1633
|
|
|
|
|
|
|
} |
|
1634
|
0
|
|
|
|
|
|
my $origsql = $sth->FETCH('Statement'); |
|
1635
|
0
|
|
|
|
|
|
$origsql =~ s/select\s+(.+)?\s+from\s+.+$/$1/is; |
|
1636
|
0
|
|
|
|
|
|
$origsql =~ s/\s+//g; |
|
1637
|
0
|
|
|
|
|
|
my $joinfids = $sth->FETCH('sprite_joinfid'); |
|
1638
|
0
|
|
|
|
|
|
my $joinalii = $sth->FETCH('sprite_joinalias'); |
|
1639
|
|
|
|
|
|
|
# unless ($spriteref->{sprite_CaseFieldNames}) #CHGD. TO NEXT 20040929. |
|
1640
|
0
|
0
|
|
|
|
|
$origsql =~ tr/a-z/A-Z/ unless ($spriteref->{sprite_CaseFieldNames}); |
|
1641
|
0
|
0
|
|
|
|
|
unless ($spriteref->{sprite_CaseTableNames}) |
|
1642
|
|
|
|
|
|
|
{ |
|
1643
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#{$joinfids};$i++) |
|
|
0
|
|
|
|
|
|
|
|
1644
|
|
|
|
|
|
|
{ |
|
1645
|
0
|
|
|
|
|
|
$joinfids->[$i] =~ tr/a-z/A-Z/; |
|
1646
|
0
|
|
|
|
|
|
$joinalii->[$i] =~ tr/a-z/A-Z/; |
|
1647
|
|
|
|
|
|
|
} |
|
1648
|
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
} |
|
1650
|
|
|
|
|
|
|
#CALL JSPRITE TO DO THE SQL! |
|
1651
|
|
|
|
|
|
|
|
|
1652
|
0
|
|
|
|
|
|
my $joinspriteref = $sth->FETCH('sprite_joindb'); |
|
1653
|
0
|
|
|
|
|
|
my (@joinresv) = $joinspriteref->sql($sqlstr); |
|
1654
|
0
|
|
|
|
|
|
my $joinunion0 = $sth->FETCH('sprite_union0'); |
|
1655
|
|
|
|
|
|
|
|
|
1656
|
|
|
|
|
|
|
#BUILD ARRAYS OF INDICES FOR UNION FIELDS TO BE COMPARED. |
|
1657
|
0
|
|
|
|
|
|
my @icolindx; |
|
1658
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#{$joinunion0};$i++) |
|
|
0
|
|
|
|
|
|
|
|
1659
|
|
|
|
|
|
|
{ |
|
1660
|
0
|
|
|
|
|
|
$joinunion0->[$i] =~ s/[^\.]*\.(.*)/$1/; |
|
1661
|
|
|
|
|
|
|
$joinunion0->[$i] =~ tr/a-z/A-Z/ |
|
1662
|
0
|
0
|
|
|
|
|
unless ($joinspriteref->{sprite_CaseFieldNames}); |
|
1663
|
0
|
|
|
|
|
|
for (my $j=0;$j<=$#icolnames;$j++) |
|
1664
|
|
|
|
|
|
|
{ |
|
1665
|
0
|
0
|
|
|
|
|
if ($joinunion0->[$i] eq $icolnames[$j]) |
|
1666
|
|
|
|
|
|
|
{ |
|
1667
|
0
|
|
|
|
|
|
push (@icolindx, $j); |
|
1668
|
0
|
|
|
|
|
|
last; |
|
1669
|
|
|
|
|
|
|
} |
|
1670
|
|
|
|
|
|
|
} |
|
1671
|
|
|
|
|
|
|
} |
|
1672
|
0
|
|
|
|
|
|
my $joinunion1 = $sth->FETCH('sprite_union1'); |
|
1673
|
0
|
|
|
|
|
|
my @jcolnames = split(/\,/o, $joinspriteref->{use_fields}); |
|
1674
|
0
|
|
|
|
|
|
my %jcolHash; |
|
1675
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#jcolnames;$i++) |
|
1676
|
|
|
|
|
|
|
{ |
|
1677
|
0
|
|
|
|
|
|
$jcolHash{$jcolnames[$i]} = $i; |
|
1678
|
|
|
|
|
|
|
} |
|
1679
|
0
|
|
|
|
|
|
my @jcolindx; |
|
1680
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#{$joinunion1};$i++) |
|
|
0
|
|
|
|
|
|
|
|
1681
|
|
|
|
|
|
|
{ |
|
1682
|
0
|
|
|
|
|
|
$joinunion1->[$i] =~ s/[^\.]*\.(.*)/$1/; |
|
1683
|
|
|
|
|
|
|
$joinunion1->[$i] =~ tr/a-z/A-Z/ |
|
1684
|
0
|
0
|
|
|
|
|
unless ($joinspriteref->{sprite_CaseFieldNames}); |
|
1685
|
0
|
|
|
|
|
|
for (my $j=0;$j<=$#jcolnames;$j++) |
|
1686
|
|
|
|
|
|
|
{ |
|
1687
|
0
|
0
|
|
|
|
|
if ($joinunion1->[$i] eq $jcolnames[$j]) |
|
1688
|
|
|
|
|
|
|
{ |
|
1689
|
0
|
|
|
|
|
|
push (@jcolindx, $j); |
|
1690
|
0
|
|
|
|
|
|
last; |
|
1691
|
|
|
|
|
|
|
} |
|
1692
|
|
|
|
|
|
|
} |
|
1693
|
|
|
|
|
|
|
} |
|
1694
|
0
|
|
|
|
|
|
@ocolnames = split(/\,/o, $origsql); |
|
1695
|
0
|
|
|
|
|
|
my ($tbl,$fld); |
|
1696
|
0
|
|
|
|
|
|
my (@ocolwhich, %newtypes, %newlens, %newscales); |
|
1697
|
|
|
|
|
|
|
|
|
1698
|
0
|
|
|
|
|
|
I1: for (my $i=0;$i<=$#ocolnames;$i++) |
|
1699
|
|
|
|
|
|
|
{ |
|
1700
|
0
|
|
|
|
|
|
($tbl,$fld) = split(/\./o, $ocolnames[$i]); |
|
1701
|
0
|
|
|
|
|
|
$ocolnames[$i] = $fld; |
|
1702
|
0
|
0
|
0
|
|
|
|
if ($tbl eq $joinfids->[1] || $tbl eq $joinalii->[1]) |
|
1703
|
|
|
|
|
|
|
{ |
|
1704
|
0
|
|
|
|
|
|
$ocolwhich[$i] = 1; |
|
1705
|
0
|
|
|
|
|
|
for (my $j=0;$j<=$#jcolindx;$j++) |
|
1706
|
|
|
|
|
|
|
{ |
|
1707
|
0
|
0
|
|
|
|
|
if ($fld eq $jcolnames[$j]) |
|
1708
|
|
|
|
|
|
|
{ |
|
1709
|
0
|
|
|
|
|
|
$newtypes{$fld} = ${$joinspriteref->{types}}{$fld}; |
|
|
0
|
|
|
|
|
|
|
|
1710
|
0
|
|
|
|
|
|
$newlens{$fld} = ${$joinspriteref->{lengths}}{$fld}; |
|
|
0
|
|
|
|
|
|
|
|
1711
|
0
|
|
|
|
|
|
$newscales{$fld} = ${$joinspriteref->{scales}}{$fld}; |
|
|
0
|
|
|
|
|
|
|
|
1712
|
0
|
|
|
|
|
|
next I1; |
|
1713
|
|
|
|
|
|
|
} |
|
1714
|
|
|
|
|
|
|
} |
|
1715
|
|
|
|
|
|
|
} |
|
1716
|
|
|
|
|
|
|
else |
|
1717
|
|
|
|
|
|
|
{ |
|
1718
|
0
|
|
|
|
|
|
$ocolwhich[$i] = 0; |
|
1719
|
0
|
|
|
|
|
|
for (my $j=0;$j<=$#icolindx;$j++) |
|
1720
|
|
|
|
|
|
|
{ |
|
1721
|
0
|
0
|
|
|
|
|
if ($fld eq $icolnames[$j]) |
|
1722
|
|
|
|
|
|
|
{ |
|
1723
|
0
|
|
|
|
|
|
$newtypes{$fld} = ${$spriteref->{types}}{$fld}; |
|
|
0
|
|
|
|
|
|
|
|
1724
|
0
|
|
|
|
|
|
$newlens{$fld} = ${$spriteref->{lengths}}{$fld}; |
|
|
0
|
|
|
|
|
|
|
|
1725
|
0
|
|
|
|
|
|
$newscales{$fld} = ${$spriteref->{scales}}{$fld}; |
|
|
0
|
|
|
|
|
|
|
|
1726
|
0
|
|
|
|
|
|
next I1; |
|
1727
|
|
|
|
|
|
|
} |
|
1728
|
|
|
|
|
|
|
} |
|
1729
|
|
|
|
|
|
|
} |
|
1730
|
|
|
|
|
|
|
} |
|
1731
|
0
|
|
|
|
|
|
%{$spriteref->{types}} = %newtypes; |
|
|
0
|
|
|
|
|
|
|
|
1732
|
0
|
|
|
|
|
|
%{$spriteref->{lengths}} = %newlens; |
|
|
0
|
|
|
|
|
|
|
|
1733
|
0
|
|
|
|
|
|
%{$spriteref->{scales}} = %newscales; |
|
|
0
|
|
|
|
|
|
|
|
1734
|
0
|
|
|
|
|
|
$spriteref->{TYPE} = undef; |
|
1735
|
0
|
|
|
|
|
|
my $jrow = shift(@joinresv); |
|
1736
|
0
|
|
|
|
|
|
my $row = shift(@resv); |
|
1737
|
0
|
|
|
|
|
|
my $orig_whereclause = $sth->FETCH('sprite_where0'); |
|
1738
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/\s+order\s+by\s+[\w\,\.\s]+$//is; |
|
1739
|
0
|
|
0
|
|
|
|
my @tblname = (($joinalii->[0] || $joinfids->[0]), |
|
|
|
|
0
|
|
|
|
|
|
1740
|
|
|
|
|
|
|
($joinalii->[1] || $joinfids->[1])); |
|
1741
|
0
|
|
|
|
|
|
my $validColumnnames = "(?:$tblname[0].".$spriteref->{use_fields}; |
|
1742
|
0
|
|
|
|
|
|
$validColumnnames =~ s/\,/\|$tblname[0]\./g; |
|
1743
|
0
|
|
|
|
|
|
$validColumnnames .= "|$tblname[1].".$joinspriteref->{use_fields}.')'; |
|
1744
|
0
|
|
|
|
|
|
$validColumnnames =~ s/\,/\|$tblname[1]\./g; |
|
1745
|
|
|
|
|
|
|
#DE-ALIAS ALL TABLE-ALIASES IN THE WHERE-CLAUSE. |
|
1746
|
0
|
0
|
|
|
|
|
if ($spriteref->{sprite_CaseTableNames}) #CONDITION ADDED 20040929. |
|
1747
|
|
|
|
|
|
|
{ |
|
1748
|
0
|
|
|
|
|
|
for (my $i=0;$i<=1;$i++) |
|
1749
|
|
|
|
|
|
|
{ |
|
1750
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/ $joinalii->[$i]\./ $joinfids->[$i]\./gs; |
|
1751
|
|
|
|
|
|
|
} |
|
1752
|
|
|
|
|
|
|
} |
|
1753
|
|
|
|
|
|
|
else |
|
1754
|
|
|
|
|
|
|
{ |
|
1755
|
0
|
|
|
|
|
|
for (my $i=0;$i<=1;$i++) |
|
1756
|
|
|
|
|
|
|
{ |
|
1757
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/ $joinalii->[$i]\./ $joinfids->[$i]\./igs; |
|
1758
|
|
|
|
|
|
|
} |
|
1759
|
|
|
|
|
|
|
} |
|
1760
|
|
|
|
|
|
|
|
|
1761
|
|
|
|
|
|
|
#NOW, BIND ALL BIND VARIABLES HERE! |
|
1762
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/\\\'/\x02\^3jSpR1tE\x02/gso; #PROTECT ESCAPED DOUBLE-QUOTES. |
|
1763
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/\'\'/\x02\^4jSpR1tE\x02/gso; #PROTECT DOUBLED DOUBLE-QUOTES. |
|
1764
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/\'([^\']*?)\'/ |
|
1765
|
0
|
|
|
|
|
|
my ($str) = $1; |
|
1766
|
0
|
|
|
|
|
|
$str =~ s|\?|\x02\^2jSpR1tE\x02|gso; #PROTECT QUESTION-MARKS WITHIN QUOTES. |
|
1767
|
0
|
|
|
|
|
|
"'$str'"/egs; |
|
1768
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/\x02\^4jSpR1tE\x02/\'\'/gso; #UNPROTECT DOUBLED DOUBLE-QUOTES. |
|
1769
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/\x02\^3jSpR1tE\x02/\\\'/gso; #UNPROTECT ESCAPED DOUBLE-QUOTES. |
|
1770
|
|
|
|
|
|
|
|
|
1771
|
|
|
|
|
|
|
#CONVERT REMAINING QUESTION-MARKS TO BOUND VALUES. |
|
1772
|
|
|
|
|
|
|
|
|
1773
|
0
|
|
|
|
|
|
for (my $i = 0; $i < $numParam; $i++) |
|
1774
|
|
|
|
|
|
|
{ |
|
1775
|
0
|
|
|
|
|
|
$params->[$i] =~ s/\?/\x02\^2jSpR1tE\x02/gso; #ADDED 20001023 TO FIX BUG WHEN PARAMETER OTHER THAN LAST CONTAINS A "?"! |
|
1776
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/\?/"'".$params->[$i]."'"/es; |
|
|
0
|
|
|
|
|
|
|
|
1777
|
|
|
|
|
|
|
} |
|
1778
|
0
|
|
|
|
|
|
$orig_whereclause =~ s/\x02\^2jSpR1tE\x02/\?/gso; #ADDED 20001023! - UNPROTECT PROTECTED "?"s. |
|
1779
|
0
|
|
|
|
|
|
my $cond = $spriteref->parse_expression($orig_whereclause, $validColumnnames); |
|
1780
|
|
|
|
|
|
|
#$cond =~ s/\$\_\-\>\{\w+\.(\w+)\}/BASE($icolHash{$1})/g; |
|
1781
|
|
|
|
|
|
|
#$cond =~ s/\$\_\-\>\{\w+\.(\w+)\}/\$baseresv\-\>\[\$icolHash\{$1\}\]/g; |
|
1782
|
|
|
|
|
|
|
#$cond =~ s/\$\_\-\>\{\w+\.(\w+)\}/JOIN($jcolHash{$1})/g; |
|
1783
|
0
|
|
|
|
|
|
$cond =~ s/\$\_\-\>\{$tblname[0]\.(\w+)\}/\$baserow\-\>\[\$icolHash\{$1\}\]/g; |
|
1784
|
0
|
|
|
|
|
|
$cond =~ s/\$\_\-\>\{$tblname[1]\.(\w+)\}/\$joinrow\-\>\[\$jcolHash\{$1\}\]/g; |
|
1785
|
|
|
|
|
|
|
#DONT NEED?$cond =~ s/[\r\n\t]/ /gs; |
|
1786
|
|
|
|
|
|
|
|
|
1787
|
|
|
|
|
|
|
#NOW EVAL THE *ORIGINAL* WHERE-CLAUSE CONDITION TO WEED OUT UNDESIRED RECORDS. |
|
1788
|
|
|
|
|
|
|
|
|
1789
|
0
|
|
|
|
|
|
my ($j, $k, $baserow, $joinrow, @newresv, @newrow); |
|
1790
|
0
|
0
|
|
|
|
|
if ($sth->FETCH('sprite_joinorder')) |
|
1791
|
|
|
|
|
|
|
{ |
|
1792
|
0
|
|
|
|
|
|
while (@joinresv) |
|
1793
|
|
|
|
|
|
|
{ |
|
1794
|
0
|
|
|
|
|
|
$joinrow = shift(@joinresv); |
|
1795
|
0
|
|
|
|
|
|
J2A: for ($j=0;$j<$row;$j++) |
|
1796
|
|
|
|
|
|
|
{ |
|
1797
|
0
|
|
|
|
|
|
$baserow = $resv[$j]; |
|
1798
|
0
|
|
|
|
|
|
$@ = ''; |
|
1799
|
0
|
|
0
|
|
|
|
$_ = ($cond !~ /\S/o || eval $cond); |
|
1800
|
0
|
0
|
|
|
|
|
next J2A unless ($_); |
|
1801
|
0
|
|
|
|
|
|
for ($k=0;$k<=$#ocolnames;$k++) |
|
1802
|
|
|
|
|
|
|
{ |
|
1803
|
0
|
0
|
|
|
|
|
if ($ocolwhich[$k]) |
|
1804
|
|
|
|
|
|
|
{ |
|
1805
|
0
|
|
|
|
|
|
push (@newrow, $joinrow->[$jcolHash{$ocolnames[$k]}]); |
|
1806
|
|
|
|
|
|
|
} |
|
1807
|
|
|
|
|
|
|
else |
|
1808
|
|
|
|
|
|
|
{ |
|
1809
|
0
|
|
|
|
|
|
push (@newrow, $baserow->[$icolHash{$ocolnames[$k]}]); |
|
1810
|
|
|
|
|
|
|
} |
|
1811
|
|
|
|
|
|
|
} |
|
1812
|
0
|
|
|
|
|
|
push (@newresv, [@newrow]); |
|
1813
|
0
|
|
|
|
|
|
@newrow = (); |
|
1814
|
|
|
|
|
|
|
} |
|
1815
|
|
|
|
|
|
|
} |
|
1816
|
|
|
|
|
|
|
} |
|
1817
|
|
|
|
|
|
|
else |
|
1818
|
|
|
|
|
|
|
{ |
|
1819
|
0
|
|
|
|
|
|
while (@resv) |
|
1820
|
|
|
|
|
|
|
{ |
|
1821
|
0
|
|
|
|
|
|
$baserow = shift(@resv); |
|
1822
|
0
|
|
|
|
|
|
J2B: for ($j=0;$j<$jrow;$j++) |
|
1823
|
|
|
|
|
|
|
{ |
|
1824
|
0
|
|
|
|
|
|
$joinrow = $joinresv[$j]; |
|
1825
|
0
|
|
|
|
|
|
$@ = ''; |
|
1826
|
0
|
|
0
|
|
|
|
$_ = ($cond !~ /\S/o || eval $cond); |
|
1827
|
0
|
0
|
|
|
|
|
next J2B unless ($_); |
|
1828
|
0
|
|
|
|
|
|
for ($k=0;$k<=$#ocolnames;$k++) |
|
1829
|
|
|
|
|
|
|
{ |
|
1830
|
0
|
0
|
|
|
|
|
if ($ocolwhich[$k]) |
|
1831
|
|
|
|
|
|
|
{ |
|
1832
|
0
|
|
|
|
|
|
push (@newrow, $joinrow->[$jcolHash{$ocolnames[$k]}]); |
|
1833
|
|
|
|
|
|
|
} |
|
1834
|
|
|
|
|
|
|
else |
|
1835
|
|
|
|
|
|
|
{ |
|
1836
|
0
|
|
|
|
|
|
push (@newrow, $baserow->[$icolHash{$ocolnames[$k]}]); |
|
1837
|
|
|
|
|
|
|
} |
|
1838
|
|
|
|
|
|
|
} |
|
1839
|
0
|
|
|
|
|
|
push (@newresv, [@newrow]); |
|
1840
|
0
|
|
|
|
|
|
@newrow = (); |
|
1841
|
|
|
|
|
|
|
} |
|
1842
|
|
|
|
|
|
|
} |
|
1843
|
|
|
|
|
|
|
} |
|
1844
|
0
|
|
|
|
|
|
@resv = (scalar(@newresv), @newresv); |
|
1845
|
0
|
|
0
|
|
|
|
$retval = $resv[0] || '0E0'; |
|
1846
|
|
|
|
|
|
|
} |
|
1847
|
|
|
|
|
|
|
} |
|
1848
|
|
|
|
|
|
|
} |
|
1849
|
|
|
|
|
|
|
else #SELECT SELECTED ZERO RECORDS. |
|
1850
|
|
|
|
|
|
|
{ |
|
1851
|
0
|
0
|
|
|
|
|
if ($spriteref->{lasterror}) |
|
1852
|
|
|
|
|
|
|
{ |
|
1853
|
0
|
|
|
|
|
|
DBI::set_err($sth, $spriteref->{lasterror}, $spriteref->{lastmsg}); |
|
1854
|
0
|
|
|
|
|
|
$retval = undef; |
|
1855
|
|
|
|
|
|
|
} |
|
1856
|
0
|
|
|
|
|
|
$retval = '0E0'; |
|
1857
|
|
|
|
|
|
|
} |
|
1858
|
|
|
|
|
|
|
|
|
1859
|
|
|
|
|
|
|
#EVERYTHING WORKED, SO SAVE SPRITE RESULT (# ROWS) AND FETCH FIELD INFO. |
|
1860
|
|
|
|
|
|
|
|
|
1861
|
|
|
|
|
|
|
#if ($retval) #CHGD TO NEXT 20020606. |
|
1862
|
0
|
0
|
0
|
|
|
|
if (defined($retval) && $retval) |
|
1863
|
|
|
|
|
|
|
{ |
|
1864
|
0
|
|
|
|
|
|
$sth->{'driver_rows'} = $retval; # number of rows |
|
1865
|
0
|
|
|
|
|
|
$sth->{'sprite_rows'} = $retval; # number of rows |
|
1866
|
0
|
|
|
|
|
|
$sth->STORE('sprite_rows', $retval); |
|
1867
|
0
|
|
|
|
|
|
$sth->STORE('driver_rows', $retval); |
|
1868
|
|
|
|
|
|
|
} |
|
1869
|
|
|
|
|
|
|
else |
|
1870
|
|
|
|
|
|
|
{ |
|
1871
|
0
|
|
|
|
|
|
$sth->{'driver_rows'} = 0; # number of rows |
|
1872
|
0
|
|
|
|
|
|
$sth->{'sprite_rows'} = 0; # number of rows |
|
1873
|
0
|
|
|
|
|
|
$sth->STORE('sprite_rows', 0); |
|
1874
|
0
|
|
|
|
|
|
$sth->STORE('driver_rows', 0); |
|
1875
|
|
|
|
|
|
|
} |
|
1876
|
|
|
|
|
|
|
|
|
1877
|
|
|
|
|
|
|
#### NOTE #### IF THIS FAILS, IT PROBABLY NEEDS TO BE "sprite_rows"? |
|
1878
|
|
|
|
|
|
|
|
|
1879
|
0
|
|
|
|
|
|
shift @resv; #REMOVE 1ST COLUMN FROM DATA RETURNED (THE SPRITE RESULT). |
|
1880
|
0
|
0
|
|
|
|
|
my @l = ($#ocolnames >= 0) ? @ocolnames : split(/,/,$spriteref->{use_fields}); |
|
1881
|
0
|
|
|
|
|
|
$sth->STORE('NUM_OF_FIELDS',($#l+1)); |
|
1882
|
0
|
|
|
|
|
|
my (@keyfields) = split(',', $spriteref->{key_fields}); #ADDED 20030520 TO IMPROVE NULLABLE. |
|
1883
|
|
|
|
|
|
|
|
|
1884
|
0
|
0
|
|
|
|
|
unless ($spriteref->{TYPE}) |
|
1885
|
|
|
|
|
|
|
{ |
|
1886
|
0
|
|
|
|
|
|
@{$spriteref->{NAME}} = @l; |
|
|
0
|
|
|
|
|
|
|
|
1887
|
0
|
|
|
|
|
|
for my $i (0..$#l) |
|
1888
|
|
|
|
|
|
|
{ |
|
1889
|
0
|
0
|
|
|
|
|
if (defined ${$spriteref->{types}}{$l[$i]}) |
|
|
0
|
|
|
|
|
|
|
|
1890
|
|
|
|
|
|
|
{ |
|
1891
|
0
|
|
|
|
|
|
${$spriteref->{TYPE}}[$i] = $typehash{"\U${$spriteref->{types}}{$l[$i]}\E"}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
1892
|
0
|
|
|
|
|
|
${$spriteref->{PRECISION}}[$i] = ${$spriteref->{lengths}}{$l[$i]}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
1893
|
0
|
|
|
|
|
|
${$spriteref->{SCALE}}[$i] = ${$spriteref->{scales}}{$l[$i]}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
1894
|
|
|
|
|
|
|
} |
|
1895
|
|
|
|
|
|
|
else |
|
1896
|
|
|
|
|
|
|
{ |
|
1897
|
0
|
|
|
|
|
|
${$spriteref->{TYPE}}[$i] = ''; |
|
|
0
|
|
|
|
|
|
|
|
1898
|
0
|
|
|
|
|
|
${$spriteref->{PRECISION}}[$i] = 0; |
|
|
0
|
|
|
|
|
|
|
|
1899
|
0
|
|
|
|
|
|
${$spriteref->{SCALE}}[$i] = 0; |
|
|
0
|
|
|
|
|
|
|
|
1900
|
|
|
|
|
|
|
} |
|
1901
|
0
|
|
|
|
|
|
${$spriteref->{NULLABLE}}[$i] = 1; |
|
|
0
|
|
|
|
|
|
|
|
1902
|
0
|
|
|
|
|
|
foreach my $j (@keyfields) #ADDED 20030520 TO IMPROVE NULLABLE. |
|
1903
|
|
|
|
|
|
|
{ |
|
1904
|
0
|
0
|
|
|
|
|
if (${$spriteref->{NAME}}[$i] eq $j) |
|
|
0
|
|
|
|
|
|
|
|
1905
|
|
|
|
|
|
|
{ |
|
1906
|
0
|
|
|
|
|
|
${$spriteref->{NULLABLE}}[$i] = 0; |
|
|
0
|
|
|
|
|
|
|
|
1907
|
0
|
|
|
|
|
|
last; |
|
1908
|
|
|
|
|
|
|
} |
|
1909
|
|
|
|
|
|
|
} |
|
1910
|
|
|
|
|
|
|
} |
|
1911
|
|
|
|
|
|
|
} |
|
1912
|
|
|
|
|
|
|
|
|
1913
|
|
|
|
|
|
|
#TRANSFER SPRITE'S FIELD DATA TO DBI. |
|
1914
|
|
|
|
|
|
|
|
|
1915
|
0
|
|
|
|
|
|
$sth->{'driver_data'} = \@resv; |
|
1916
|
0
|
|
|
|
|
|
$sth->STORE('sprite_data', \@resv); |
|
1917
|
|
|
|
|
|
|
#$sth->STORE('sprite_rows', ($#resv+1)); # number of rows |
|
1918
|
0
|
|
|
|
|
|
$sth->{'TYPE'} = \@{$spriteref->{TYPE}}; |
|
|
0
|
|
|
|
|
|
|
|
1919
|
0
|
|
|
|
|
|
$sth->{'NAME'} = \@{$spriteref->{NAME}}; |
|
|
0
|
|
|
|
|
|
|
|
1920
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#{$sth->{'NAME'}};$i++) |
|
|
0
|
|
|
|
|
|
|
|
1921
|
|
|
|
|
|
|
{ |
|
1922
|
|
|
|
|
|
|
$sth->{'NAME'}->[$i] = $spriteref->{ASNAMES}->{$sth->{'NAME'}->[$i]} |
|
1923
|
0
|
0
|
|
|
|
|
if ($spriteref->{ASNAMES}->{$sth->{'NAME'}->[$i]}); |
|
1924
|
|
|
|
|
|
|
} |
|
1925
|
0
|
|
|
|
|
|
$sth->{'PRECISION'} = \@{$spriteref->{PRECISION}}; |
|
|
0
|
|
|
|
|
|
|
|
1926
|
0
|
|
|
|
|
|
$sth->{'SCALE'} = \@{$spriteref->{SCALE}}; |
|
|
0
|
|
|
|
|
|
|
|
1927
|
0
|
|
|
|
|
|
$sth->{'NULLABLE'} = \@{$spriteref->{NULLABLE}}; |
|
|
0
|
|
|
|
|
|
|
|
1928
|
0
|
|
|
|
|
|
$sth->STORE('sprite_resv',\@resv); |
|
1929
|
|
|
|
|
|
|
#ADDED NEXT LINE 20020905 TO SUPPORT DBIx::GeneratedKey! |
|
1930
|
0
|
|
|
|
|
|
$sth->{Database}->STORE('sprite_insertid', $spriteref->{'sprite_lastsequence'}); |
|
1931
|
0
|
0
|
|
|
|
|
if (defined $retval) |
|
1932
|
|
|
|
|
|
|
{ |
|
1933
|
0
|
0
|
|
|
|
|
return $retval ? $retval : '0E0'; |
|
1934
|
|
|
|
|
|
|
} |
|
1935
|
0
|
|
|
|
|
|
return undef; |
|
1936
|
|
|
|
|
|
|
} |
|
1937
|
|
|
|
|
|
|
|
|
1938
|
|
|
|
|
|
|
sub fetchrow_arrayref |
|
1939
|
|
|
|
|
|
|
{ |
|
1940
|
0
|
|
|
0
|
|
|
my($sth) = @_; |
|
1941
|
0
|
|
|
|
|
|
my $data = $sth->FETCH('driver_data'); |
|
1942
|
0
|
|
|
|
|
|
my $row = shift @$data; |
|
1943
|
|
|
|
|
|
|
#return undef if (!$row || !scalar(@$row)); #CHGD. TO NEXT 20040913 TO AVOID _FBAV ERROR IF NO ROWS RETURNED! |
|
1944
|
0
|
0
|
0
|
|
|
|
return undef if (!$row || !scalar(@$row)); |
|
1945
|
|
|
|
|
|
|
#my ($longreadlen) = $sth->{Database}->FETCH('LongReadLen'); #CHGD. TO NEXT 20020606 AS WORKAROUND FOR DBI::PurePerl; |
|
1946
|
0
|
|
0
|
|
|
|
my ($longreadlen) = $sth->{Database}->FETCH('LongReadLen') || 0; |
|
1947
|
0
|
0
|
|
|
|
|
if ($longreadlen > 0) |
|
1948
|
|
|
|
|
|
|
{ |
|
1949
|
0
|
0
|
|
|
|
|
if ($sth->FETCH('ChopBlanks')) |
|
1950
|
|
|
|
|
|
|
{ |
|
1951
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#{$row};$i++) |
|
|
0
|
|
|
|
|
|
|
|
1952
|
|
|
|
|
|
|
{ |
|
1953
|
0
|
0
|
|
|
|
|
if (${$sth->{TYPE}}[$i] < 0) #LONG, LONG RAW, etc. |
|
|
0
|
|
|
|
|
|
|
|
1954
|
|
|
|
|
|
|
{ |
|
1955
|
0
|
|
|
|
|
|
my ($t) = substr($row->[$i],0,$longreadlen); |
|
1956
|
0
|
0
|
0
|
|
|
|
return undef unless (($row->[$i] eq $t) || $sth->{Database}->FETCH('LongTruncOk')); |
|
1957
|
0
|
|
|
|
|
|
$row->[$i] = $t; |
|
1958
|
|
|
|
|
|
|
} |
|
1959
|
|
|
|
|
|
|
} |
|
1960
|
0
|
|
|
|
|
|
map { $_ =~ s/\s+$//; } @$row; |
|
|
0
|
|
|
|
|
|
|
|
1961
|
|
|
|
|
|
|
} |
|
1962
|
|
|
|
|
|
|
} |
|
1963
|
|
|
|
|
|
|
else |
|
1964
|
|
|
|
|
|
|
{ |
|
1965
|
0
|
0
|
|
|
|
|
if ($sth->FETCH('ChopBlanks')) |
|
1966
|
|
|
|
|
|
|
{ |
|
1967
|
0
|
|
|
|
|
|
map { $_ =~ s/\s+$//; } @$row; |
|
|
0
|
|
|
|
|
|
|
|
1968
|
|
|
|
|
|
|
} |
|
1969
|
|
|
|
|
|
|
} |
|
1970
|
0
|
|
|
|
|
|
my $myres; |
|
1971
|
0
|
|
|
|
|
|
eval { $myres = $sth->_set_fbav($row); }; |
|
|
0
|
|
|
|
|
|
|
|
1972
|
|
|
|
|
|
|
# $myres = $sth->_set_fbav($row); |
|
1973
|
0
|
|
|
|
|
|
return $myres; |
|
1974
|
|
|
|
|
|
|
} |
|
1975
|
|
|
|
|
|
|
|
|
1976
|
|
|
|
|
|
|
*fetch = \&fetchrow_arrayref; # required alias for fetchrow_arrayref |
|
1977
|
|
|
|
|
|
|
sub rows |
|
1978
|
|
|
|
|
|
|
{ |
|
1979
|
0
|
|
|
0
|
|
|
my($sth) = @_; |
|
1980
|
0
|
0
|
0
|
|
|
|
return $sth->FETCH('driver_rows') or $sth->FETCH('sprite_rows') or $sth->{drv_rows}; |
|
1981
|
|
|
|
|
|
|
} |
|
1982
|
|
|
|
|
|
|
#### NOTE #### IF THIS FAILS, IT PROBABLY NEEDS TO BE "sprite_rows"? |
|
1983
|
|
|
|
|
|
|
|
|
1984
|
|
|
|
|
|
|
|
|
1985
|
|
|
|
|
|
|
sub STORE |
|
1986
|
|
|
|
|
|
|
{ |
|
1987
|
0
|
|
|
0
|
|
|
my($dbh, $attr, $val) = @_; |
|
1988
|
0
|
0
|
|
|
|
|
if ($attr eq 'AutoCommit') |
|
1989
|
|
|
|
|
|
|
{ |
|
1990
|
|
|
|
|
|
|
# AutoCommit is currently the only standard attribute we have |
|
1991
|
|
|
|
|
|
|
# to consider. |
|
1992
|
|
|
|
|
|
|
#if (!$val) { die "Can't disable AutoCommit"; } |
|
1993
|
|
|
|
|
|
|
|
|
1994
|
0
|
|
|
|
|
|
$dbh->{AutoCommit} = $val; |
|
1995
|
0
|
|
|
|
|
|
return 1; |
|
1996
|
|
|
|
|
|
|
} |
|
1997
|
0
|
0
|
|
|
|
|
if ($attr =~ /^sprite/o) |
|
1998
|
|
|
|
|
|
|
{ |
|
1999
|
|
|
|
|
|
|
# Handle only our private attributes here |
|
2000
|
|
|
|
|
|
|
# Note that we could trigger arbitrary actions. |
|
2001
|
|
|
|
|
|
|
# Ideally we should catch unknown attributes. |
|
2002
|
0
|
|
|
|
|
|
$dbh->{$attr} = $val; # Yes, we are allowed to do this, |
|
2003
|
0
|
|
|
|
|
|
return 1; # but only for our private attributes |
|
2004
|
|
|
|
|
|
|
} |
|
2005
|
|
|
|
|
|
|
# Else pass up to DBI to handle for us |
|
2006
|
0
|
|
|
|
|
|
eval {$dbh->SUPER::STORE($attr, $val);}; |
|
|
0
|
|
|
|
|
|
|
|
2007
|
|
|
|
|
|
|
} |
|
2008
|
|
|
|
|
|
|
|
|
2009
|
|
|
|
|
|
|
sub FETCH |
|
2010
|
|
|
|
|
|
|
{ |
|
2011
|
0
|
|
|
0
|
|
|
my($dbh, $attr) = @_; |
|
2012
|
0
|
0
|
|
|
|
|
if ($attr eq 'AutoCommit') { return $dbh->{AutoCommit}; } |
|
|
0
|
|
|
|
|
|
|
|
2013
|
0
|
0
|
|
|
|
|
if ($attr =~ /^sprite_/o) |
|
2014
|
|
|
|
|
|
|
{ |
|
2015
|
|
|
|
|
|
|
# Handle only our private attributes here |
|
2016
|
|
|
|
|
|
|
# Note that we could trigger arbitrary actions. |
|
2017
|
0
|
|
|
|
|
|
return $dbh->{$attr}; # Yes, we are allowed to do this, |
|
2018
|
|
|
|
|
|
|
# but only for our private attributes |
|
2019
|
0
|
|
|
|
|
|
return $dbh->{$attr}; |
|
2020
|
|
|
|
|
|
|
} |
|
2021
|
|
|
|
|
|
|
# Else pass up to DBI to handle |
|
2022
|
0
|
|
|
|
|
|
$dbh->SUPER::FETCH($attr); |
|
2023
|
|
|
|
|
|
|
} |
|
2024
|
|
|
|
|
|
|
|
|
2025
|
|
|
|
|
|
|
sub DESTROY #ADDED 20010221 |
|
2026
|
|
|
|
0
|
|
|
{ |
|
2027
|
|
|
|
|
|
|
} |
|
2028
|
|
|
|
|
|
|
|
|
2029
|
|
|
|
|
|
|
1; |
|
2030
|
|
|
|
|
|
|
|
|
2031
|
|
|
|
|
|
|
package DBD::Sprite; # ====== HAD TO HAVE TO PREVENT MAKE ERROR! ====== |
|
2032
|
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
1; |
|
2034
|
|
|
|
|
|
|
|
|
2035
|
|
|
|
|
|
|
__END__ |