File Coverage

dbdimp.c
Criterion Covered Total %
statement 1113 1244 89.4
branch 934 1894 49.3
condition n/a
subroutine n/a
pod n/a
total 2047 3138 65.2


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2              
3             #define NEED_newSVpvn_flags
4             #define NEED_sv_2pvbyte
5              
6             #include "SQLeetXS.h"
7              
8             START_MY_CXT;
9              
10 202 50         DBISTATE_DECLARE;
    50          
11              
12             #define SvPV_nolen_undef_ok(x) (SvOK(x) ? SvPV_nolen(x) : "undef")
13              
14             /*-----------------------------------------------------*
15             * Debug Macros
16             *-----------------------------------------------------*/
17              
18             #undef DBD_SQLITE_CROAK_DEBUG
19              
20             #ifdef DBD_SQLITE_CROAK_DEBUG
21             #define croak_if_db_is_null() if (!imp_dbh->db) croak("imp_dbh->db is NULL at line %d in %s", __LINE__, __FILE__)
22             #define croak_if_stmt_is_null() if (!imp_sth->stmt) croak("imp_sth->stmt is NULL at line %d in %s", __LINE__, __FILE__)
23             #else
24             #define croak_if_db_is_null()
25             #define croak_if_stmt_is_null()
26             #endif
27              
28              
29             /*-----------------------------------------------------*
30             * Helper Methods
31             *-----------------------------------------------------*/
32              
33             #define sqlite_error(h,rc,what) _sqlite_error(aTHX_ __FILE__, __LINE__, h, rc, what)
34             #define sqlite_trace(h,xxh,level,what) if ( DBIc_TRACE_LEVEL((imp_xxh_t*)xxh) >= level ) _sqlite_trace(aTHX_ __FILE__, __LINE__, h, (imp_xxh_t*)xxh, what)
35             #define sqlite_exec(h,sql) _sqlite_exec(aTHX_ h, imp_dbh->db, sql)
36             #define sqlite_open(dbname,db) _sqlite_open(aTHX_ dbh, dbname, db, 0, 0)
37             #define sqlite_open2(dbname,db,flags,extended) _sqlite_open(aTHX_ dbh, dbname, db, flags, extended)
38             #define _isspace(c) (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f')
39              
40             #define _skip_whitespaces(sql) \
41             while ( _isspace(sql[0]) || (sql[0] == '-' && sql[1] == '-')) { \
42             if ( _isspace(sql[0]) ) { \
43             while ( _isspace(sql[0]) ) sql++; \
44             continue; \
45             } \
46             else if (sql[0] == '-') { \
47             while ( sql[0] != 0 && sql[0] != '\n' ) sql++; \
48             continue; \
49             } \
50             }
51              
52             bool
53 1901           _starts_with_begin(const char *sql) {
54 1901           return (
55 1901 50         ((sql[0] == 'B' || sql[0] == 'b') &&
    50          
56 23 0         (sql[1] == 'E' || sql[1] == 'e') &&
    50          
57 23 0         (sql[2] == 'G' || sql[2] == 'g') &&
    50          
58 23 0         (sql[3] == 'I' || sql[3] == 'i') &&
    50          
59 0 0         (sql[4] == 'N' || sql[4] == 'n')
60             ) || (
61 1878 100         (sql[0] == 'S' || sql[0] == 's') &&
    100          
62 750 50         (sql[1] == 'A' || sql[1] == 'a') &&
    50          
63 13 0         (sql[2] == 'V' || sql[2] == 'v') &&
    50          
64 13 0         (sql[3] == 'E' || sql[3] == 'e') &&
    50          
65 13 0         (sql[4] == 'P' || sql[4] == 'p') &&
    50          
66 13 0         (sql[5] == 'O' || sql[5] == 'o') &&
    50          
67 13 0         (sql[6] == 'I' || sql[6] == 'i') &&
    50          
68 13 0         (sql[7] == 'N' || sql[7] == 'n') &&
    50          
69 0 0         (sql[8] == 'T' || sql[8] == 't')
70             )
71 5680 100         ) ? TRUE : FALSE;
    100          
72             }
73              
74             /* adopted from sqlite3.c */
75              
76             #define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
77             #define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
78              
79 168           static int compare2pow63(const char *zNum) {
80 168           int c = 0;
81             int i;
82             /* 012345678901234567 */
83 168           const char *pow63 = "922337203685477580";
84 1152 100         for(i = 0; c == 0 && i < 18; i++){
    100          
85 984           c = (zNum[i] - pow63[i]) * 10;
86             }
87 168 100         if(c == 0){
88 48           c = zNum[18] - '8';
89             }
90 168           return c;
91             }
92              
93 850           int _sqlite_atoi64(const char *zNum, sqlite3_int64 *pNum) {
94 850           sqlite3_uint64 u = 0;
95 850           int neg = 0;
96             int i;
97 850           int c = 0;
98             const char *zStart;
99 850           const char *zEnd = zNum + strlen(zNum);
100 851 100         while(zNum < zEnd && _isspace(*zNum)) zNum++;
    100          
    50          
    50          
    50          
    50          
    50          
101 850 100         if (zNum < zEnd) {
102 632 100         if (*zNum == '-') {
103 188           neg = 1;
104 188           zNum++;
105 444 50         } else if (*zNum == '+') {
106 0           zNum++;
107             }
108             }
109 850           zStart = zNum;
110 894 100         while(zNum < zEnd && zNum[0] == '0') zNum++;
    100          
111 6026 100         for(i = 0; &zNum[i] < zEnd && (c = zNum[i]) >= '0' && c <= '9'; i++) {
    100          
    100          
112 5176           u = u * 10 + c - '0';
113             }
114 850 100         if (u > LARGEST_INT64) {
115 12 50         *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
116 838 100         } else if (neg) {
117 176           *pNum = -(sqlite3_int64)u;
118             } else {
119 662           *pNum = (sqlite3_int64)u;
120             }
121 850 100         if ((c != 0 && &zNum[i] < zEnd) || (i == 0 && zStart == zNum) || i > 19) {
    100          
    100          
    100          
    50          
122 232           return 1;
123 618 100         } else if (i < 19) {
124 450           return 0;
125             } else {
126 168           c = compare2pow63(zNum);
127 168 100         if (c < 0) {
128 156           return 0;
129 12 50         } else if (c > 0) {
130 0           return 1;
131             } else {
132 12 50         return neg ? 0 : 2;
133             }
134             }
135             }
136              
137             static void
138 0           _sqlite_trace(pTHX_ char *file, int line, SV *h, imp_xxh_t *imp_xxh, const char *what)
139             {
140 0           PerlIO_printf(
141 0           DBIc_LOGPIO(imp_xxh),
142             "sqlite trace: %s at %s line %d\n", what, file, line
143             );
144 0           }
145              
146             static void
147 183           _sqlite_error(pTHX_ char *file, int line, SV *h, int rc, const char *what)
148             {
149 183           D_imp_xxh(h);
150              
151 183           DBIh_SET_ERR_CHAR(h, imp_xxh, Nullch, rc, what, Nullch, Nullch);
152              
153 183 50         if ( DBIc_TRACE_LEVEL(imp_xxh) >= 3 ) {
154 0           PerlIO_printf(
155 0           DBIc_LOGPIO(imp_xxh),
156             "sqlite error %d recorded: %s at %s line %d\n",
157             rc, what, file, line
158             );
159             }
160 183           }
161              
162             int
163 2931           _sqlite_exec(pTHX_ SV *h, sqlite3 *db, const char *sql)
164             {
165             int rc;
166             char *errmsg;
167              
168 2931           rc = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
169 2931 100         if ( rc != SQLITE_OK ) {
170 39           sqlite_error(h, rc, errmsg);
171 39 50         if (errmsg) sqlite3_free(errmsg);
172             }
173 2931           return rc;
174             }
175              
176             int
177 257           _sqlite_open(pTHX_ SV *dbh, const char *dbname, sqlite3 **db, int flags, int extended)
178             {
179             int rc;
180 257 100         if (flags) {
181 19           rc = sqlite3_open_v2(dbname, db, flags, NULL);
182             } else {
183 238           rc = sqlite3_open(dbname, db);
184             }
185 257 100         if ( rc != SQLITE_OK ) {
186             #if SQLITE_VERSION_NUMBER >= 3006005
187 6 50         if (extended)
188 0           rc = sqlite3_extended_errcode(*db);
189             #endif
190 6           sqlite_error(dbh, rc, sqlite3_errmsg(*db));
191 6 50         if (*db) sqlite3_close(*db);
192             }
193 257           return rc;
194             }
195              
196             static int
197 6           sqlite_type_to_odbc_type(int type)
198             {
199 6           switch(type) {
200 0           case SQLITE_INTEGER: return SQL_INTEGER;
201 0           case SQLITE_FLOAT: return SQL_DOUBLE;
202 0           case SQLITE_TEXT: return SQL_VARCHAR;
203 0           case SQLITE_BLOB: return SQL_BLOB;
204 6           case SQLITE_NULL: return SQL_UNKNOWN_TYPE;
205 0           default: return SQL_UNKNOWN_TYPE;
206             }
207             }
208              
209             static int
210 947           sqlite_type_from_odbc_type(int type)
211             {
212 947           switch(type) {
213             case SQL_UNKNOWN_TYPE:
214 703           return SQLITE_NULL;
215             case SQL_INTEGER:
216             case SQL_SMALLINT:
217             case SQL_TINYINT:
218             case SQL_BIGINT:
219 207           return SQLITE_INTEGER;
220             case SQL_FLOAT:
221             case SQL_REAL:
222             case SQL_DOUBLE:
223 0           return SQLITE_FLOAT;
224             case SQL_BLOB:
225 25           return SQLITE_BLOB;
226             default:
227 12           return SQLITE_TEXT;
228             }
229             }
230              
231             void
232 101           init_cxt() {
233             dTHX;
234             MY_CXT_INIT;
235 101           MY_CXT.last_dbh_is_unicode = 0;
236 101           }
237              
238             SV *
239 960           stacked_sv_from_sqlite3_value(pTHX_ sqlite3_value *value, int is_unicode)
240             {
241             STRLEN len;
242             sqlite_int64 iv;
243 960           int type = sqlite3_value_type(value);
244             SV *sv;
245              
246 960           switch(type) {
247             case SQLITE_INTEGER:
248 84           iv = sqlite3_value_int64(value);
249             if ( iv >= IV_MIN && iv <= IV_MAX ) {
250             /* ^^^ compile-time constant (= true) when IV == int64 */
251 84           return sv_2mortal(newSViv((IV)iv));
252             }
253             else if ( iv >= 0 && iv <= UV_MAX ) {
254             /* warn("integer overflow, cast to UV"); */
255             return sv_2mortal(newSVuv((UV)iv));
256             }
257             else {
258             /* warn("integer overflow, cast to NV"); */
259             return sv_2mortal(newSVnv((NV)iv));
260             }
261             case SQLITE_FLOAT:
262 6           return sv_2mortal(newSVnv(sqlite3_value_double(value)));
263             break;
264             case SQLITE_TEXT:
265 718           len = sqlite3_value_bytes(value);
266 718           sv = newSVpvn((const char *)sqlite3_value_text(value), len);
267 718 100         if (is_unicode) {
268 336           SvUTF8_on(sv);
269             }
270 718           return sv_2mortal(sv);
271             case SQLITE_BLOB:
272 0           len = sqlite3_value_bytes(value);
273 0           return sv_2mortal(newSVpvn(sqlite3_value_blob(value), len));
274             default:
275 152           return &PL_sv_undef;
276             }
277             }
278              
279              
280              
281              
282              
283              
284             static void
285 574           sqlite_set_result(pTHX_ sqlite3_context *context, SV *result, int is_error)
286             {
287             STRLEN len;
288             char *s;
289             sqlite3_int64 iv;
290              
291 574 100         if ( is_error ) {
292 6 50         s = SvPV(result, len);
293 6           sqlite3_result_error( context, s, len );
294 6           return;
295             }
296              
297             /* warn("result: %s\n", SvPV_nolen(result)); */
298 568 100         if ( !SvOK(result) ) {
    50          
    50          
299 146           sqlite3_result_null( context );
300 422 50         } else if( SvIOK_UV(result) ) {
301             if ((UV)(sqlite3_int64)UV_MAX == UV_MAX)
302 0 0         sqlite3_result_int64( context, (sqlite3_int64)SvUV(result));
303             else {
304             s = SvPV(result, len);
305             sqlite3_result_text( context, s, len, SQLITE_TRANSIENT );
306             }
307 422 100         } else if ( !_sqlite_atoi64(SvPV(result, len), &iv) ) {
    100          
308 190           sqlite3_result_int64( context, iv );
309 232 100         } else if ( SvNOK(result) && ( sizeof(NV) == sizeof(double) || SvNVX(result) == (double) SvNVX(result) ) ) {
310 218 50         sqlite3_result_double( context, SvNV(result));
311             } else {
312 14 50         s = SvPV(result, len);
313 568           sqlite3_result_text( context, s, len, SQLITE_TRANSIENT );
314             }
315             }
316              
317             /*
318             * see also sqlite3IsNumber, sqlite3_int64 type definition,
319             * applyNumericAffinity, sqlite3Atoi64, etc from sqlite3.c
320             */
321             static int
322 224           sqlite_is_number(pTHX_ const char *v, int sql_type)
323             {
324             sqlite3_int64 iv;
325 224           const char *z = v;
326 224           const char *d = v;
327             int neg;
328 224           int digit = 0;
329 224           int precision = 0;
330 224           bool has_plus = FALSE;
331 224           bool maybe_int = TRUE;
332             char format[10];
333              
334 224 100         if (sql_type != SQLITE_NULL) {
335 208 100         while (*z == ' ') { z++; v++; d++; }
336             }
337              
338 224 100         if (*z == '-') { neg = 1; z++; d++; }
339 130 50         else if (*z == '+') { neg = 0; z++; d++; has_plus = TRUE; }
340 130           else { neg = 0; }
341 224 100         if (!isdigit(*z)) return 0;
342 2672 100         while (isdigit(*z)) { digit++; z++; }
343 222 50         if (digit > 19) maybe_int = FALSE; /* too large for i64 */
344 222 100         if (digit == 19) {
345             int c;
346             char tmp[22];
347 84           strncpy(tmp, d, z - d + 1);
348 84           c = memcmp(tmp, "922337203685477580", 18);
349 84 100         if (c == 0) {
350 24           c = tmp[18] - '7' - neg;
351             }
352 84 50         if (c > 0) maybe_int = FALSE;
353             }
354 222 100         if (*z == '.') {
355 6           maybe_int = FALSE;
356 6           z++;
357 6 50         if (!isdigit(*z)) return 0;
358 16 100         while (isdigit(*z)) { precision++; z++; }
359             }
360 222 100         if (*z == 'e' || *z == 'E') {
    50          
361 4           maybe_int = FALSE;
362 4           z++;
363 4 50         if (*z == '+' || *z == '-') { z++; }
    50          
364 4 50         if (!isdigit(*z)) return 0;
365 16 100         while (isdigit(*z)) { z++; }
366             }
367 222 50         if (*z && !isdigit(*z)) return 0;
    0          
368              
369 222 100         if (maybe_int && digit) {
    50          
370 214 50         if (!_sqlite_atoi64(v, &iv)) return 1;
371             }
372 8 100         if (sql_type != SQLITE_INTEGER) {
373 6 50         sprintf(format, (has_plus ? "+%%.%df" : "%%.%df"), precision);
374 6 100         if (strEQ(form(format, atof(v)), v)) return 2;
375             }
376 224           return 0;
377             }
378              
379             /*-----------------------------------------------------*
380             * DBD Methods
381             *-----------------------------------------------------*/
382              
383             void
384 101           sqlite_init(dbistate_t *dbistate)
385             {
386             dTHX;
387 101 50         DBISTATE_INIT; /* Initialize the DBI macros */
388 101           }
389              
390             int
391 95           sqlite_discon_all(SV *drh, imp_drh_t *imp_drh)
392             {
393             dTHX;
394 95           return FALSE; /* no way to do this */
395             }
396              
397             int
398 253           sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pass, SV *attr)
399             {
400             dTHX;
401             int rc;
402             HV *hv;
403             SV **val;
404 253           int extended = 0;
405 253           int flag = 0;
406 253           int unicode = 0;
407              
408 253 50         sqlite_trace(dbh, imp_dbh, 3, form("login '%s' (version %s)", dbname, sqlite3_version));
409              
410 253 50         if (SvROK(attr)) {
411 253           hv = (HV*)SvRV(attr);
412 253 50         if (hv_exists(hv, "sqlite_extended_result_codes", 28)) {
413 0           val = hv_fetch(hv, "sqlite_extended_result_codes", 28, 0);
414 0 0         extended = (val && SvOK(*val)) ? !(!SvTRUE(*val)) : 0;
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
415             }
416 253 100         if (hv_exists(hv, "ReadOnly", 8)) {
417 1           val = hv_fetch(hv, "ReadOnly", 8, 0);
418 1 50         if ((val && SvOK(*val)) ? SvIV(*val) : 0) {
    50          
    0          
    0          
    50          
    50          
419 1           flag |= SQLITE_OPEN_READONLY;
420             }
421             }
422 253 100         if (hv_exists(hv, "sqlite_open_flags", 17)) {
423 18           val = hv_fetch(hv, "sqlite_open_flags", 17, 0);
424 18 50         flag |= (val && SvOK(*val)) ? SvIV(*val) : 0;
    50          
    0          
    0          
    50          
425 18 100         if (flag & SQLITE_OPEN_READONLY) {
426 3           hv_stores(hv, "ReadOnly", newSViv(1));
427             }
428             }
429             /* sqlite_unicode should be detected earlier, to register default functions correctly */
430 253 100         if (hv_exists(hv, "sqlite_unicode", 14)) {
431 34           val = hv_fetch(hv, "sqlite_unicode", 14, 0);
432 34 50         unicode = (val && SvOK(*val)) ? SvIV(*val) : 0;
    50          
    0          
    0          
    100          
433 219 50         } else if (hv_exists(hv, "unicode", 7)) {
434 0           val = hv_fetch(hv, "unicode", 7, 0);
435 0 0         unicode = (val && SvOK(*val)) ? SvIV(*val) : 0;
    0          
    0          
    0          
    0          
436             }
437             }
438 253           rc = sqlite_open2(dbname, &(imp_dbh->db), flag, extended);
439 253 100         if ( rc != SQLITE_OK ) {
440 6           return FALSE; /* -> undef in lib/DBD/SQLeet.pm */
441             }
442 247           DBIc_IMPSET_on(imp_dbh);
443              
444 247           imp_dbh->unicode = unicode;
445 247           imp_dbh->functions = newAV();
446 247           imp_dbh->aggregates = newAV();
447 247           imp_dbh->collation_needed_callback = newSVsv( &PL_sv_undef );
448 247           imp_dbh->timeout = SQL_TIMEOUT;
449 247           imp_dbh->handle_binary_nulls = FALSE;
450 247           imp_dbh->allow_multiple_statements = FALSE;
451 247           imp_dbh->use_immediate_transaction = TRUE;
452 247           imp_dbh->see_if_its_a_number = FALSE;
453 247           imp_dbh->extended_result_codes = extended;
454 247           imp_dbh->stmt_list = NULL;
455 247           imp_dbh->began_transaction = FALSE;
456              
457 247           sqlite3_busy_timeout(imp_dbh->db, SQL_TIMEOUT);
458              
459             #if 0
460             /*
461             ** As of 1.26_06 foreign keys support was enabled by default,
462             ** but with further discussion, we agreed to follow what
463             ** sqlite team does, i.e. wait until the team think it
464             ** reasonable to enable the support by default, as they have
465             ** larger users and will allocate enough time for people to
466             ** get used to the foreign keys. However, we should say it loud
467             ** that sometime in the (near?) future, this feature may break
468             ** your applications (and it actually broke applications).
469             ** Let everyone be prepared.
470             */
471             sqlite_exec(dbh, "PRAGMA foreign_keys = ON");
472             #endif
473              
474             #if 0
475             /*
476             ** Enable this to see if you (wrongly) expect an implicit order
477             ** of return values from a SELECT statement without ORDER BY.
478             */
479             sqlite_exec(dbh, "PRAGMA reverse_unordered_selects = ON");
480             #endif
481              
482 247 50         DBIc_ACTIVE_on(imp_dbh);
    50          
    50          
    50          
483              
484 247           return TRUE;
485             }
486              
487             int
488 2755           sqlite_db_do_sv(SV *dbh, imp_dbh_t *imp_dbh, SV *sv_statement)
489             {
490             dTHX;
491 2755           int rc = 0;
492             int i;
493             char *statement;
494              
495 2755 50         if (!DBIc_ACTIVE(imp_dbh)) {
496 0           sqlite_error(dbh, -2, "attempt to do on inactive database handle");
497 0           return -2; /* -> undef in SQLeet.xsi */
498             }
499              
500             /* sqlite3_prepare wants an utf8-encoded SQL statement */
501 2755 100         if (imp_dbh->unicode) {
502 106           sv_utf8_upgrade(sv_statement);
503             }
504              
505 2755 50         statement = SvPV_nolen(sv_statement);
506              
507 2755 50         sqlite_trace(dbh, imp_dbh, 3, form("do statement: %s", statement));
508              
509             croak_if_db_is_null();
510              
511 2755 100         if (sqlite3_get_autocommit(imp_dbh->db)) {
512 517           const char *sql = statement;
513 629 100         _skip_whitespaces(sql);
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
514 517 100         if (_starts_with_begin(sql)) {
515 30 100         if (DBIc_is(imp_dbh, DBIcf_AutoCommit)) {
516 15 50         if (!DBIc_is(imp_dbh, DBIcf_BegunWork)) {
517 15           imp_dbh->began_transaction = TRUE;
518 15           DBIc_on(imp_dbh, DBIcf_BegunWork);
519 30           DBIc_off(imp_dbh, DBIcf_AutoCommit);
520             }
521             }
522             }
523 487 100         else if (!DBIc_is(imp_dbh, DBIcf_AutoCommit)) {
524 70 50         sqlite_trace(dbh, imp_dbh, 3, "BEGIN TRAN");
525 70 50         if (imp_dbh->use_immediate_transaction) {
526 70           rc = sqlite_exec(dbh, "BEGIN IMMEDIATE TRANSACTION");
527             } else {
528 0           rc = sqlite_exec(dbh, "BEGIN TRANSACTION");
529             }
530 70 100         if (rc != SQLITE_OK) {
531 5           return -2; /* -> undef in SQLeet.xsi */
532             }
533             }
534             }
535              
536 2750           rc = sqlite_exec(dbh, statement);
537 2750 100         if (rc != SQLITE_OK) {
538 28           sqlite_error(dbh, rc, sqlite3_errmsg(imp_dbh->db));
539 28           return -2;
540             }
541              
542 2722 100         if (DBIc_is(imp_dbh, DBIcf_BegunWork) && sqlite3_get_autocommit(imp_dbh->db)) {
    100          
543 17 100         if (imp_dbh->began_transaction) {
544 16           DBIc_off(imp_dbh, DBIcf_BegunWork);
545 16           DBIc_on(imp_dbh, DBIcf_AutoCommit);
546             }
547             }
548              
549 2722           return sqlite3_changes(imp_dbh->db);
550             }
551              
552             int
553 76           sqlite_db_commit(SV *dbh, imp_dbh_t *imp_dbh)
554             {
555             dTHX;
556             int rc;
557              
558 76 100         if (!DBIc_ACTIVE(imp_dbh)) {
559 2           sqlite_error(dbh, -2, "attempt to commit on inactive database handle");
560 2           return FALSE;
561             }
562              
563 74 100         if (DBIc_is(imp_dbh, DBIcf_AutoCommit)) {
564             /* We don't need to warn, because the DBI layer will do it for us */
565 1           return TRUE;
566             }
567              
568 73 100         if (DBIc_is(imp_dbh, DBIcf_BegunWork)) {
569             /* XXX: for rt_52573
570             imp_dbh->began_transaction = FALSE;
571             */
572 28           DBIc_off(imp_dbh, DBIcf_BegunWork);
573 28           DBIc_on(imp_dbh, DBIcf_AutoCommit);
574             }
575              
576             croak_if_db_is_null();
577              
578 73 100         if (!sqlite3_get_autocommit(imp_dbh->db)) {
579 71 50         sqlite_trace(dbh, imp_dbh, 3, "COMMIT TRAN");
580              
581 71           rc = sqlite_exec(dbh, "COMMIT TRANSACTION");
582 71 100         if (rc != SQLITE_OK) {
583 4           return FALSE; /* -> &sv_no in SQLeet.xsi */
584             }
585             }
586              
587 69           return TRUE;
588             }
589              
590             int
591 52           sqlite_db_rollback(SV *dbh, imp_dbh_t *imp_dbh)
592             {
593             dTHX;
594             int rc;
595              
596 52 100         if (!DBIc_ACTIVE(imp_dbh)) {
597 2           sqlite_error(dbh, -2, "attempt to rollback on inactive database handle");
598 2           return FALSE;
599             }
600              
601 50 100         if (DBIc_is(imp_dbh, DBIcf_BegunWork)) {
602             /* XXX: for rt_52573
603             imp_dbh->began_transaction = FALSE;
604             */
605 7           DBIc_off(imp_dbh, DBIcf_BegunWork);
606 7           DBIc_on(imp_dbh, DBIcf_AutoCommit);
607             }
608              
609             croak_if_db_is_null();
610              
611 50 100         if (!sqlite3_get_autocommit(imp_dbh->db)) {
612              
613 18 50         sqlite_trace(dbh, imp_dbh, 3, "ROLLBACK TRAN");
614              
615 18           rc = sqlite_exec(dbh, "ROLLBACK TRANSACTION");
616 18 50         if (rc != SQLITE_OK) {
617 0           return FALSE; /* -> &sv_no in SQLeet.xsi */
618             }
619             }
620              
621 50           return TRUE;
622             }
623              
624             int
625 245           sqlite_db_disconnect(SV *dbh, imp_dbh_t *imp_dbh)
626             {
627             dTHX;
628             int rc;
629             stmt_list_s * s;
630              
631 245 100         if (DBIc_is(imp_dbh, DBIcf_AutoCommit) == FALSE) {
632 24           sqlite_db_rollback(dbh, imp_dbh);
633             }
634 245 50         DBIc_ACTIVE_off(imp_dbh);
    50          
    100          
    50          
    50          
635              
636             croak_if_db_is_null();
637              
638 245 50         sqlite_trace( dbh, imp_dbh, 1, "Closing DB" );
639 245           rc = sqlite3_close( imp_dbh->db );
640 245 50         sqlite_trace( dbh, imp_dbh, 1, form("rc = %d", rc) );
641 245 100         if ( SQLITE_BUSY == rc ) { /* We have unfinalized statements */
642             /* Only close the statements that were prepared by this module */
643 20 100         while ( (s = imp_dbh->stmt_list) ) {
644 10 50         sqlite_trace( dbh, imp_dbh, 1, form("Finalizing statement (%p)", s->stmt) );
645 10           sqlite3_finalize( s->stmt );
646 10           imp_dbh->stmt_list = s->prev;
647 10           sqlite3_free( s );
648             }
649 10           imp_dbh->stmt_list = NULL;
650 10 50         sqlite_trace( dbh, imp_dbh, 1, "Trying to close DB again" );
651 10           rc = sqlite3_close( imp_dbh->db );
652             }
653 245 50         if ( SQLITE_OK != rc ) {
654 0           sqlite_error(dbh, rc, sqlite3_errmsg(imp_dbh->db));
655             }
656             /* The list should be empty at this point, but if for some unforseen reason
657             it isn't, free remaining nodes here */
658 249 100         while( (s = imp_dbh->stmt_list) ) {
659 4           imp_dbh->stmt_list = s->prev;
660 4           sqlite3_free( s );
661             }
662 245           imp_dbh->db = NULL;
663              
664 245           av_undef(imp_dbh->functions);
665 245           SvREFCNT_dec(imp_dbh->functions);
666 245           imp_dbh->functions = (AV *)NULL;
667              
668 245           av_undef(imp_dbh->aggregates);
669 245           SvREFCNT_dec(imp_dbh->aggregates);
670 245           imp_dbh->aggregates = (AV *)NULL;
671              
672 245           sv_setsv(imp_dbh->collation_needed_callback, &PL_sv_undef);
673 245           SvREFCNT_dec(imp_dbh->collation_needed_callback);
674 245           imp_dbh->collation_needed_callback = (SV *)NULL;
675              
676 245           return TRUE;
677             }
678              
679             void
680 247           sqlite_db_destroy(SV *dbh, imp_dbh_t *imp_dbh)
681             {
682             dTHX;
683 247 50         if (DBIc_ACTIVE(imp_dbh)) {
684 0           sqlite_db_disconnect(dbh, imp_dbh);
685             }
686              
687 247           DBIc_IMPSET_off(imp_dbh);
688 247           }
689              
690             int
691 1328           sqlite_db_STORE_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)
692             {
693             dTHX;
694 1328 50         char *key = SvPV_nolen(keysv);
695             int rc;
696              
697             croak_if_db_is_null();
698              
699 1328 100         if (strEQ(key, "AutoCommit")) {
700 322 50         if (SvTRUE(valuesv)) {
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    0          
    100          
701             /* commit tran? */
702 242 100         if ( DBIc_ACTIVE(imp_dbh) && (!DBIc_is(imp_dbh, DBIcf_AutoCommit)) && (!sqlite3_get_autocommit(imp_dbh->db)) ) {
    100          
    100          
703 2 50         sqlite_trace(dbh, imp_dbh, 3, "COMMIT TRAN");
704 2           rc = sqlite_exec(dbh, "COMMIT TRANSACTION");
705 2 50         if (rc != SQLITE_OK) {
706 0           return TRUE; /* XXX: is this correct? */
707             }
708             }
709             }
710 322 50         DBIc_set(imp_dbh, DBIcf_AutoCommit, SvTRUE(valuesv));
    50          
    0          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
711 322           return TRUE;
712             }
713             #if SQLITE_VERSION_NUMBER >= 3007011
714 1006 100         if (strEQ(key, "ReadOnly")) {
715 4 50         if (SvTRUE(valuesv) && !sqlite3_db_readonly(imp_dbh->db, "main")) {
    50          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
716 1           sqlite_error(dbh, 0, "ReadOnly is set but it's only advisory");
717             }
718 4           return FALSE;
719             }
720             #endif
721 1002 100         if (strEQ(key, "sqlite_allow_multiple_statements")) {
722 4 50         imp_dbh->allow_multiple_statements = !(! SvTRUE(valuesv));
    50          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    0          
723 4           return TRUE;
724             }
725 998 100         if (strEQ(key, "sqlite_use_immediate_transaction")) {
726 1 50         imp_dbh->use_immediate_transaction = !(! SvTRUE(valuesv));
    50          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    50          
    0          
727 1           return TRUE;
728             }
729 997 100         if (strEQ(key, "sqlite_see_if_its_a_number")) {
730 7 50         imp_dbh->see_if_its_a_number = !(! SvTRUE(valuesv));
    50          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
731 7           return TRUE;
732             }
733 990 50         if (strEQ(key, "sqlite_extended_result_codes")) {
734 0 0         imp_dbh->extended_result_codes = !(! SvTRUE(valuesv));
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
735 0           sqlite3_extended_result_codes(imp_dbh->db, imp_dbh->extended_result_codes);
736 0           return TRUE;
737             }
738 990 100         if (strEQ(key, "sqlite_unicode")) {
739             #if PERL_UNICODE_DOES_NOT_WORK_WELL
740             sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
741             imp_dbh->unicode = 0;
742             #else
743 34 50         imp_dbh->unicode = !(! SvTRUE(valuesv));
    50          
    0          
    50          
    0          
    0          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
744             #endif
745 34           return TRUE;
746             }
747 956 50         if (strEQ(key, "unicode")) {
748 0 0         if (DBIc_has(imp_dbh, DBIcf_WARN))
749 0           warn("\"unicode\" attribute will be deprecated. Use \"sqlite_unicode\" instead.");
750             #if PERL_UNICODE_DOES_NOT_WORK_WELL
751             sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
752             imp_dbh->unicode = 0;
753             #else
754 0 0         imp_dbh->unicode = !(! SvTRUE(valuesv));
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
755             #endif
756 0           return TRUE;
757             }
758 956           return FALSE;
759             }
760              
761             SV *
762 3183           sqlite_db_FETCH_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv)
763             {
764             dTHX;
765 3183 50         char *key = SvPV_nolen(keysv);
766              
767 3183 100         if (strEQ(key, "sqlite_version")) {
768 3           return sv_2mortal(newSVpv(sqlite3_version, 0));
769             }
770 3180 100         if (strEQ(key, "sqlite_allow_multiple_statements")) {
771 2881           return sv_2mortal(newSViv(imp_dbh->allow_multiple_statements ? 1 : 0));
772             }
773 299 100         if (strEQ(key, "sqlite_use_immediate_transaction")) {
774 2           return sv_2mortal(newSViv(imp_dbh->use_immediate_transaction ? 1 : 0));
775             }
776 297 100         if (strEQ(key, "sqlite_see_if_its_a_number")) {
777 4           return sv_2mortal(newSViv(imp_dbh->see_if_its_a_number ? 1 : 0));
778             }
779 293 50         if (strEQ(key, "sqlite_extended_result_codes")) {
780 0           return sv_2mortal(newSViv(imp_dbh->extended_result_codes ? 1 : 0));
781             }
782 293 100         if (strEQ(key, "sqlite_unicode")) {
783             #if PERL_UNICODE_DOES_NOT_WORK_WELL
784             sqlite_trace(dbh, imp_dbh, 3, "Unicode support is disabled for this version of perl.");
785             return sv_2mortal(newSViv(0));
786             #else
787 6           return sv_2mortal(newSViv(imp_dbh->unicode ? 1 : 0));
788             #endif
789             }
790 287 50         if (strEQ(key, "unicode")) {
791 0 0         if (DBIc_has(imp_dbh, DBIcf_WARN))
792 0           warn("\"unicode\" attribute will be deprecated. Use \"sqlite_unicode\" instead.");
793             #if PERL_UNICODE_DOES_NOT_WORK_WELL
794             sqlite_trace(dbh, imp_dbh, 3, "Unicode support is disabled for this version of perl.");
795             return sv_2mortal(newSViv(0));
796             #else
797 0           return sv_2mortal(newSViv(imp_dbh->unicode ? 1 : 0));
798             #endif
799             }
800              
801 287           return NULL;
802             }
803              
804             SV *
805 211           sqlite_db_last_insert_id(SV *dbh, imp_dbh_t *imp_dbh, SV *catalog, SV *schema, SV *table, SV *field, SV *attr)
806             {
807             dTHX;
808              
809 211 100         if (!DBIc_ACTIVE(imp_dbh)) {
810 2           sqlite_error(dbh, -2, "attempt to get last inserted id on inactive database handle");
811 2           return FALSE;
812             }
813              
814             croak_if_db_is_null();
815              
816 209           return sv_2mortal(newSViv((IV)sqlite3_last_insert_rowid(imp_dbh->db)));
817             }
818              
819             int
820 1117           sqlite_st_prepare_sv(SV *sth, imp_sth_t *imp_sth, SV *sv_statement, SV *attribs)
821             {
822             dTHX;
823             dMY_CXT;
824 1117           int rc = 0;
825             const char *extra;
826             char *statement;
827             stmt_list_s * new_stmt;
828 1117           D_imp_dbh_from_sth;
829              
830 1117           MY_CXT.last_dbh_is_unicode = imp_dbh->unicode;
831              
832 1117 100         if (!DBIc_ACTIVE(imp_dbh)) {
833 4           sqlite_error(sth, -2, "attempt to prepare on inactive database handle");
834 4           return FALSE; /* -> undef in lib/DBD/SQLeet.pm */
835             }
836              
837             /* sqlite3_prepare wants an utf8-encoded SQL statement */
838 1113 100         if (imp_dbh->unicode) {
839 124           sv_utf8_upgrade(sv_statement);
840             }
841              
842 1113 50         statement = SvPV_nolen(sv_statement);
843              
844             #if 0
845             if (*statement == '\0') {
846             sqlite_error(sth, -2, "attempt to prepare empty statement");
847             return FALSE; /* -> undef in lib/DBD/SQLeet.pm */
848             }
849             #endif
850              
851 1113 50         sqlite_trace(sth, imp_sth, 3, form("prepare statement: %s", statement));
852 1113           imp_sth->nrow = -1;
853 1113           imp_sth->retval = SQLITE_OK;
854 1113           imp_sth->params = newAV();
855 1113           imp_sth->col_types = newAV();
856              
857             croak_if_db_is_null();
858              
859             /* COMPAT: sqlite3_prepare_v2 is only available for 3003009 or newer */
860 1113           rc = sqlite3_prepare_v2(imp_dbh->db, statement, -1, &(imp_sth->stmt), &extra);
861 1113 100         if (rc != SQLITE_OK) {
862 6           sqlite_error(sth, rc, sqlite3_errmsg(imp_dbh->db));
863 6 50         if (imp_sth->stmt) {
864 0           rc = sqlite3_finalize(imp_sth->stmt);
865 0           imp_sth->stmt = NULL;
866 0 0         if (rc != SQLITE_OK) {
867 0           sqlite_error(sth, rc, sqlite3_errmsg(imp_dbh->db));
868             }
869             }
870 6           return FALSE; /* -> undef in lib/DBD/SQLeet.pm */
871             }
872 1107 100         if (imp_dbh->allow_multiple_statements) {
873 20           imp_sth->unprepared_statements = savepv(extra);
874             }
875             else {
876 1087 50         if (imp_dbh->allow_multiple_statements)
877 0           Safefree(imp_sth->unprepared_statements);
878 1087           imp_sth->unprepared_statements = NULL;
879             }
880             /* Add the statement to the front of the list to keep track of
881             statements that might need to be finalized later on disconnect */
882 1107           new_stmt = (stmt_list_s *) sqlite3_malloc( sizeof(stmt_list_s) );
883 1107           new_stmt->stmt = imp_sth->stmt;
884 1107           new_stmt->prev = imp_dbh->stmt_list;
885 1107           imp_dbh->stmt_list = new_stmt;
886              
887 1107           DBIc_NUM_PARAMS(imp_sth) = sqlite3_bind_parameter_count(imp_sth->stmt);
888 1107           DBIc_NUM_FIELDS(imp_sth) = sqlite3_column_count(imp_sth->stmt);
889 1107           DBIc_IMPSET_on(imp_sth);
890              
891 1117           return TRUE;
892             }
893              
894             int
895 117           sqlite_st_rows(SV *sth, imp_sth_t *imp_sth)
896             {
897 117           return imp_sth->nrow;
898             }
899              
900             int
901 1447           sqlite_st_execute(SV *sth, imp_sth_t *imp_sth)
902             {
903             dTHX;
904 1447           D_imp_dbh_from_sth;
905 1447           int rc = 0;
906 1447           int num_params = DBIc_NUM_PARAMS(imp_sth);
907             int i;
908             sqlite3_int64 iv;
909              
910 1447 100         if (!DBIc_ACTIVE(imp_dbh)) {
911 1           sqlite_error(sth, -2, "attempt to execute on inactive database handle");
912 1           return -2; /* -> undef in SQLeet.xsi */
913             }
914              
915 1446 100         if (!imp_sth->stmt) return 0;
916              
917             croak_if_db_is_null();
918             croak_if_stmt_is_null();
919              
920             /* COMPAT: sqlite3_sql is only available for 3006000 or newer */
921 1442 50         sqlite_trace(sth, imp_sth, 3, form("executing %s", sqlite3_sql(imp_sth->stmt)));
922              
923 1442 100         if (DBIc_ACTIVE(imp_sth)) {
924 4 50         sqlite_trace(sth, imp_sth, 3, "execute still active, reset");
925 4           imp_sth->retval = sqlite3_reset(imp_sth->stmt);
926 4 50         if (imp_sth->retval != SQLITE_OK) {
927 0           sqlite_error(sth, imp_sth->retval, sqlite3_errmsg(imp_dbh->db));
928 0           return -2; /* -> undef in SQLeet.xsi */
929             }
930             }
931              
932 2377 100         for (i = 0; i < num_params; i++) {
933 935           SV **pvalue = av_fetch(imp_sth->params, 2*i, 0);
934 935           SV **sql_type_sv = av_fetch(imp_sth->params, 2*i+1, 0);
935 935 50         SV *value = pvalue ? *pvalue : &PL_sv_undef;
936 935 100         int sql_type = sqlite_type_from_odbc_type(sql_type_sv ? SvIV(*sql_type_sv) : SQL_UNKNOWN_TYPE);
    50          
937              
938 935 50         sqlite_trace(sth, imp_sth, 4, form("bind %d type %d as %s", i, sql_type, SvPV_nolen_undef_ok(value)));
    0          
    0          
    0          
    0          
939              
940 935 100         if (!SvOK(value)) {
    50          
    50          
941 3 50         sqlite_trace(sth, imp_sth, 5, "binding null");
942 3           rc = sqlite3_bind_null(imp_sth->stmt, i+1);
943             }
944 932 100         else if (sql_type == SQLITE_BLOB) {
945             STRLEN len;
946 12 100         char * data = SvPVbyte(value, len);
947 12           rc = sqlite3_bind_blob(imp_sth->stmt, i+1, data, len, SQLITE_TRANSIENT);
948             }
949             else {
950             STRLEN len;
951             const char *data;
952 920           int numtype = 0;
953              
954 920 100         if (imp_dbh->unicode) {
955 76           sv_utf8_upgrade(value);
956             }
957 920 100         data = SvPV(value, len);
958              
959             /*
960             * XXX: For backward compatibility, it'd be better to
961             * accept a value like " 4" as an integer for an integer
962             * type column (see t/19_bindparam.t), at least when
963             * we explicitly specify its type. However, we should
964             * keep spaces when we just guess.
965             *
966             * see_if_its_a_number should be ignored if an explicit
967             * SQL type is set via bind_param().
968             */
969 920 100         if (sql_type == SQLITE_NULL && imp_dbh->see_if_its_a_number) {
    100          
970 17           numtype = sqlite_is_number(aTHX_ data, SQLITE_NULL);
971             }
972 903 100         else if (sql_type == SQLITE_INTEGER || sql_type == SQLITE_FLOAT) {
    50          
973 207           numtype = sqlite_is_number(aTHX_ data, sql_type);
974             }
975              
976 920 100         if (numtype == 1 && !_sqlite_atoi64(data, &iv)) {
    50          
977 214           rc = sqlite3_bind_int64(imp_sth->stmt, i+1, iv);
978             }
979 706 100         else if (numtype == 2 && sql_type != SQLITE_INTEGER) {
    50          
980 2           rc = sqlite3_bind_double(imp_sth->stmt, i+1, atof(data));
981             }
982             else {
983 704 100         if (sql_type == SQLITE_INTEGER || sql_type == SQLITE_FLOAT) {
    50          
984             /*
985             * die on datatype mismatch did more harm than good
986             * especially when DBIC heavily depends on this
987             * explicit type specification
988             */
989 4 50         if (DBIc_has(imp_dbh, DBIcf_PrintWarn))
990 0 0         warn(
    0          
991             "datatype mismatch: bind param (%d) %s as %s",
992 0 0         i, SvPV_nolen_undef_ok(value),
    0          
    0          
993             (sql_type == SQLITE_INTEGER ? "integer" : "float")
994             );
995             }
996 920           rc = sqlite3_bind_text(imp_sth->stmt, i+1, data, len, SQLITE_TRANSIENT);
997             }
998             }
999              
1000 935 50         if (rc != SQLITE_OK) {
1001 0           sqlite_error(sth, rc, sqlite3_errmsg(imp_dbh->db));
1002 0           return -4; /* -> undef in SQLeet.xsi */
1003             }
1004             }
1005              
1006 1442 100         if (sqlite3_get_autocommit(imp_dbh->db)) {
1007             /* COMPAT: sqlite3_sql is only available for 3006000 or newer */
1008 1384           const char *sql = sqlite3_sql(imp_sth->stmt);
1009 1572 100         _skip_whitespaces(sql);
    50          
    50          
    0          
    0          
    0          
    100          
    50          
    100          
    50          
    50          
    50          
    0          
    0          
    0          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    0          
1010 1384 100         if (_starts_with_begin(sql)) {
1011 6 50         if (DBIc_is(imp_dbh, DBIcf_AutoCommit)) {
1012 6 50         if (!DBIc_is(imp_dbh, DBIcf_BegunWork)) {
1013 6           imp_dbh->began_transaction = TRUE;
1014             }
1015 6           DBIc_on(imp_dbh, DBIcf_BegunWork);
1016 6           DBIc_off(imp_dbh, DBIcf_AutoCommit);
1017             }
1018             }
1019 1378 100         else if (!DBIc_is(imp_dbh, DBIcf_AutoCommit)) {
1020 20 50         sqlite_trace(sth, imp_sth, 3, "BEGIN TRAN");
1021 20 50         if (imp_dbh->use_immediate_transaction) {
1022 20           rc = sqlite_exec(sth, "BEGIN IMMEDIATE TRANSACTION");
1023             } else {
1024 0           rc = sqlite_exec(sth, "BEGIN TRANSACTION");
1025             }
1026 20 100         if (rc != SQLITE_OK) {
1027 2           return -2; /* -> undef in SQLeet.xsi */
1028             }
1029             }
1030             }
1031              
1032 1440           imp_sth->nrow = 0;
1033              
1034 1440 50         sqlite_trace(sth, imp_sth, 3, form("Execute returned %d cols", DBIc_NUM_FIELDS(imp_sth)));
1035 1440 100         if (DBIc_NUM_FIELDS(imp_sth) == 0) {
1036 527 100         while ((imp_sth->retval = sqlite3_step(imp_sth->stmt)) != SQLITE_DONE) {
1037 8 50         if (imp_sth->retval == SQLITE_ROW) {
1038 0           continue;
1039             }
1040 8           sqlite_error(sth, imp_sth->retval, sqlite3_errmsg(imp_dbh->db));
1041 8 50         if (sqlite3_reset(imp_sth->stmt) != SQLITE_OK) {
1042 8           sqlite_error(sth, imp_sth->retval, sqlite3_errmsg(imp_dbh->db));
1043             }
1044 8           return -5; /* -> undef in SQLeet.xsi */
1045             }
1046              
1047             /* transaction ended with commit/rollback/release */
1048 519 100         if (DBIc_is(imp_dbh, DBIcf_BegunWork) && sqlite3_get_autocommit(imp_dbh->db)) {
    100          
1049 5 50         if (imp_dbh->began_transaction) {
1050 5           DBIc_off(imp_dbh, DBIcf_BegunWork);
1051 5           DBIc_on(imp_dbh, DBIcf_AutoCommit);
1052             }
1053             }
1054              
1055             /* warn("Finalize\n"); */
1056 519           sqlite3_reset(imp_sth->stmt);
1057 519           imp_sth->nrow = sqlite3_changes(imp_dbh->db);
1058             /* warn("Total changes: %d\n", sqlite3_total_changes(imp_dbh->db)); */
1059             /* warn("Nrow: %d\n", imp_sth->nrow); */
1060 519           return imp_sth->nrow;
1061             }
1062              
1063 913           imp_sth->retval = sqlite3_step(imp_sth->stmt);
1064 913 100         switch (imp_sth->retval) {
1065             case SQLITE_ROW:
1066             case SQLITE_DONE:
1067 907 100         DBIc_ACTIVE_on(imp_sth);
    50          
    50          
    50          
1068 907 50         sqlite_trace(sth, imp_sth, 5, form("exec ok - %d rows, %d cols", imp_sth->nrow, DBIc_NUM_FIELDS(imp_sth)));
1069 907 100         if (DBIc_is(imp_dbh, DBIcf_AutoCommit) && !sqlite3_get_autocommit(imp_dbh->db)) {
    50          
1070             /* XXX: for rt_52573
1071             if (DBIc_is(imp_dbh, DBIcf_BegunWork)) {
1072             imp_dbh->began_transaction = TRUE;
1073             }
1074             */
1075 0           DBIc_on(imp_dbh, DBIcf_BegunWork);
1076 0           DBIc_off(imp_dbh, DBIcf_AutoCommit);
1077             }
1078 907           return 0; /* -> '0E0' in SQLeet.xsi */
1079             default:
1080 6           sqlite_error(sth, imp_sth->retval, sqlite3_errmsg(imp_dbh->db));
1081 6 50         if (sqlite3_reset(imp_sth->stmt) != SQLITE_OK) {
1082 6           sqlite_error(sth, imp_sth->retval, sqlite3_errmsg(imp_dbh->db));
1083             }
1084 1447           return -6; /* -> undef in SQLeet.xsi */
1085             }
1086             }
1087              
1088             AV *
1089 2067           sqlite_st_fetch(SV *sth, imp_sth_t *imp_sth)
1090             {
1091             dTHX;
1092              
1093             AV *av;
1094 2067           D_imp_dbh_from_sth;
1095 2067           int numFields = DBIc_NUM_FIELDS(imp_sth);
1096 2067           int chopBlanks = DBIc_is(imp_sth, DBIcf_ChopBlanks);
1097             int i;
1098             sqlite3_int64 iv;
1099              
1100 2067 50         if (!DBIc_ACTIVE(imp_dbh)) {
1101 0           sqlite_error(sth, -2, "attempt to fetch on inactive database handle");
1102 0           return FALSE;
1103             }
1104              
1105             croak_if_db_is_null();
1106             croak_if_stmt_is_null();
1107              
1108 2067 50         sqlite_trace(sth, imp_sth, 6, form("numFields == %d, nrow == %d", numFields, imp_sth->nrow));
1109              
1110 2067 100         if (!DBIc_ACTIVE(imp_sth)) {
1111 2           return Nullav;
1112             }
1113              
1114 2065 100         if (imp_sth->retval == SQLITE_DONE) {
1115 610           sqlite_st_finish(sth, imp_sth);
1116 610           return Nullav;
1117             }
1118              
1119 1455 50         if (imp_sth->retval != SQLITE_ROW) {
1120             /* error */
1121 0           sqlite_error(sth, imp_sth->retval, sqlite3_errmsg(imp_dbh->db));
1122 0           sqlite_st_finish(sth, imp_sth);
1123 0           return Nullav; /* -> undef in SQLeet.xsi */
1124             }
1125              
1126 1455           imp_sth->nrow++;
1127              
1128 1455           av = DBIc_DBISTATE((imp_xxh_t *)imp_sth)->get_fbav(imp_sth);
1129 4104 100         for (i = 0; i < numFields; i++) {
1130             int len;
1131             char * val;
1132 2649           int col_type = sqlite3_column_type(imp_sth->stmt, i);
1133 2649           SV **sql_type = av_fetch(imp_sth->col_types, i, 0);
1134 2649 100         if (sql_type && SvOK(*sql_type)) {
    50          
    0          
    0          
1135 709 50         if (SvIV(*sql_type)) {
    100          
1136 12 50         col_type = sqlite_type_from_odbc_type(SvIV(*sql_type));
1137             }
1138             }
1139 2649           switch(col_type) {
1140             case SQLITE_INTEGER:
1141 1032 50         sqlite_trace(sth, imp_sth, 5, form("fetch column %d as integer", i));
1142 1032           iv = sqlite3_column_int64(imp_sth->stmt, i);
1143             if ( iv >= IV_MIN && iv <= IV_MAX ) {
1144 1032           sv_setiv(AvARRAY(av)[i], (IV)iv);
1145             }
1146             else {
1147             val = (char*)sqlite3_column_text(imp_sth->stmt, i);
1148             sv_setpv(AvARRAY(av)[i], val);
1149             SvUTF8_off(AvARRAY(av)[i]);
1150             }
1151 1032           break;
1152             case SQLITE_FLOAT:
1153             /* fetching as float may lose precision info in the perl world */
1154 8 50         sqlite_trace(sth, imp_sth, 5, form("fetch column %d as float", i));
1155 8           sv_setnv(AvARRAY(av)[i], sqlite3_column_double(imp_sth->stmt, i));
1156 8           break;
1157             case SQLITE_TEXT:
1158 1357 50         sqlite_trace(sth, imp_sth, 5, form("fetch column %d as text", i));
1159 1357           val = (char*)sqlite3_column_text(imp_sth->stmt, i);
1160              
1161 1357           len = sqlite3_column_bytes(imp_sth->stmt, i);
1162 1357 100         if (chopBlanks) {
1163 5 100         while((len > 0) && (val[len-1] == ' ')) {
    100          
1164 2           len--;
1165             }
1166             }
1167 1357           sv_setpvn(AvARRAY(av)[i], val, len);
1168 1357 100         if (imp_dbh->unicode) {
1169 291           SvUTF8_on(AvARRAY(av)[i]);
1170             } else {
1171 1066           SvUTF8_off(AvARRAY(av)[i]);
1172             }
1173 1357           break;
1174             case SQLITE_BLOB:
1175 22 50         sqlite_trace(sth, imp_sth, 5, form("fetch column %d as blob", i));
1176 22           len = sqlite3_column_bytes(imp_sth->stmt, i);
1177 22           val = (char*)sqlite3_column_blob(imp_sth->stmt, i);
1178 22 100         sv_setpvn(AvARRAY(av)[i], len ? val : "", len);
1179 22           SvUTF8_off(AvARRAY(av)[i]);
1180 22           break;
1181             default:
1182 230 50         sqlite_trace(sth, imp_sth, 5, form("fetch column %d as default", i));
1183 230           sv_setsv(AvARRAY(av)[i], &PL_sv_undef);
1184 230           SvUTF8_off(AvARRAY(av)[i]);
1185 230           break;
1186             }
1187 2649 50         SvSETMAGIC(AvARRAY(av)[i]);
1188             }
1189              
1190 1455           imp_sth->retval = sqlite3_step(imp_sth->stmt);
1191              
1192 1455           return av;
1193             }
1194              
1195             int
1196 906           sqlite_st_finish3(SV *sth, imp_sth_t *imp_sth, int is_destroy)
1197             {
1198             dTHX;
1199              
1200 906           D_imp_dbh_from_sth;
1201              
1202             croak_if_db_is_null();
1203             croak_if_stmt_is_null();
1204              
1205             /* warn("finish statement\n"); */
1206 906 100         if (!DBIc_ACTIVE(imp_sth))
1207 4           return TRUE;
1208              
1209 902 50         DBIc_ACTIVE_off(imp_sth);
    50          
    50          
    50          
    50          
1210              
1211 902           av_clear(imp_sth->col_types);
1212              
1213 902 50         if (!DBIc_ACTIVE(imp_dbh)) /* no longer connected */
1214 0           return TRUE;
1215              
1216 902 100         if (is_destroy) {
1217 57           return TRUE;
1218             }
1219              
1220 845 50         if ((imp_sth->retval = sqlite3_reset(imp_sth->stmt)) != SQLITE_OK) {
1221 0           sqlite_error(sth, imp_sth->retval, sqlite3_errmsg(imp_dbh->db));
1222 0           return FALSE; /* -> &sv_no (or void) in SQLeet.xsi */
1223             }
1224              
1225 845           return TRUE;
1226             }
1227              
1228             int
1229 610           sqlite_st_finish(SV *sth, imp_sth_t *imp_sth)
1230             {
1231 610           return sqlite_st_finish3(sth, imp_sth, 0);
1232             }
1233              
1234             void
1235 1107           sqlite_st_destroy(SV *sth, imp_sth_t *imp_sth)
1236             {
1237             dTHX;
1238             int rc;
1239             stmt_list_s * i;
1240             stmt_list_s * temp;
1241              
1242 1107           D_imp_dbh_from_sth;
1243              
1244 1107 50         DBIc_ACTIVE_off(imp_sth);
    0          
    0          
    0          
    0          
1245 1107 100         if (DBIc_ACTIVE(imp_dbh)) {
1246 1097 100         if (imp_sth->stmt) {
1247             /* COMPAT: sqlite3_sql is only available for 3006000 or newer */
1248 1093 50         sqlite_trace(sth, imp_sth, 4, form("destroy statement: %s", sqlite3_sql(imp_sth->stmt)));
1249              
1250             croak_if_db_is_null();
1251             croak_if_stmt_is_null();
1252              
1253             /* finalize sth when active connection */
1254 1093 50         sqlite_trace( sth, imp_sth, 1, form("Finalizing statement: %p", imp_sth->stmt) );
1255 1093           rc = sqlite3_finalize(imp_sth->stmt);
1256 1093 50         if (rc != SQLITE_OK) {
1257 0           sqlite_error(sth, rc, sqlite3_errmsg(imp_dbh->db));
1258             }
1259              
1260             /* find the statement in the statement list and delete it */
1261 1093           i = imp_dbh->stmt_list;
1262 1093           temp = i;
1263 1118 50         while( i ) {
1264 1118 100         if ( i->stmt == imp_sth->stmt ) {
1265 1093 100         if ( temp != i ) temp->prev = i->prev;
1266 1093 100         if ( i == imp_dbh->stmt_list ) imp_dbh->stmt_list = i->prev;
1267 1093 50         sqlite_trace( sth, imp_sth, 1, form("Removing statement from list: %p", imp_sth->stmt) );
1268 1093           sqlite3_free( i );
1269 1093           break;
1270             }
1271             else {
1272 25           temp = i;
1273 25           i = i->prev;
1274             }
1275             }
1276 1093           imp_sth->stmt = NULL;
1277             }
1278             }
1279 1107 100         if (imp_dbh->allow_multiple_statements)
1280 20           Safefree(imp_sth->unprepared_statements);
1281 1107           SvREFCNT_dec((SV*)imp_sth->params);
1282 1107           SvREFCNT_dec((SV*)imp_sth->col_types);
1283 1107           DBIc_IMPSET_off(imp_sth);
1284 1107           }
1285              
1286             int
1287 0           sqlite_st_blob_read(SV *sth, imp_sth_t *imp_sth,
1288             int field, long offset, long len, SV *destrv, long destoffset)
1289             {
1290 0           return 0;
1291             }
1292              
1293             int
1294 5           sqlite_st_STORE_attrib(SV *sth, imp_sth_t *imp_sth, SV *keysv, SV *valuesv)
1295             {
1296             dTHX;
1297             /* char *key = SvPV_nolen(keysv); */
1298 5           return FALSE;
1299             }
1300              
1301             SV *
1302 857           sqlite_st_FETCH_attrib(SV *sth, imp_sth_t *imp_sth, SV *keysv)
1303             {
1304             dTHX;
1305 857           D_imp_dbh_from_sth;
1306 857 50         char *key = SvPV_nolen(keysv);
1307 857           SV *retsv = NULL;
1308             int i,n;
1309              
1310             croak_if_db_is_null();
1311             croak_if_stmt_is_null();
1312              
1313 857 100         if (!DBIc_ACTIVE(imp_dbh)) {
1314 1           sqlite_error(sth, -2, "attempt to fetch on inactive database handle");
1315 1           return FALSE;
1316             }
1317              
1318 856 100         if (strEQ(key, "sqlite_unprepared_statements")) {
1319 16           return sv_2mortal(newSVpv(imp_sth->unprepared_statements, 0));
1320             }
1321             /*
1322             if (!DBIc_ACTIVE(imp_sth)) {
1323             return NULL;
1324             }
1325             */
1326             /* warn("fetch: %s\n", key); */
1327              
1328 840           i = DBIc_NUM_FIELDS(imp_sth);
1329              
1330 840 100         if (strEQ(key, "NAME")) {
1331 464           AV *av = newAV();
1332             /* warn("Fetch NAME fields: %d\n", i); */
1333 464           av_extend(av, i);
1334 464           retsv = sv_2mortal(newRV_noinc((SV*)av));
1335 2356 100         for (n = 0; n < i; n++) {
1336             /* warn("Fetch col name %d\n", n); */
1337 1892           const char *fieldname = sqlite3_column_name(imp_sth->stmt, n);
1338 1892 50         if (fieldname) {
1339             /* warn("Name [%d]: %s\n", n, fieldname); */
1340             /* char *dot = instr(fieldname, "."); */
1341             /* if (dot) drop table name from field name */
1342             /* fieldname = ++dot; */
1343 1892           SV *sv_fieldname = newSVpv(fieldname, 0);
1344 1892 100         if (imp_dbh->unicode)
1345 142           SvUTF8_on(sv_fieldname);
1346 1892           av_store(av, n, sv_fieldname);
1347             }
1348             }
1349             }
1350 376 50         else if (strEQ(key, "PRECISION")) {
1351 0           AV *av = newAV();
1352 0           retsv = sv_2mortal(newRV_noinc((SV*)av));
1353             }
1354 376 100         else if (strEQ(key, "TYPE")) {
1355 2           AV *av = newAV();
1356 2           av_extend(av, i);
1357 2           retsv = sv_2mortal(newRV_noinc((SV*)av));
1358 8 100         for (n = 0; n < i; n++) {
1359 6           const char *fieldtype = sqlite3_column_decltype(imp_sth->stmt, n);
1360 6           int type = sqlite3_column_type(imp_sth->stmt, n);
1361             /* warn("got type: %d = %s\n", type, fieldtype); */
1362 6           type = sqlite_type_to_odbc_type(type);
1363             /* av_store(av, n, newSViv(type)); */
1364 6 50         if (fieldtype)
1365 6           av_store(av, n, newSVpv(fieldtype, 0));
1366             else
1367 0           av_store(av, n, newSVpv("VARCHAR", 0));
1368             }
1369             }
1370 374 100         else if (strEQ(key, "NULLABLE")) {
1371 1           AV *av = newAV();
1372 1           av_extend(av, i);
1373 1           retsv = sv_2mortal(newRV_noinc((SV*)av));
1374             #if defined(SQLITE_ENABLE_COLUMN_METADATA)
1375 5 100         for (n = 0; n < i; n++) {
1376 4           const char *database = sqlite3_column_database_name(imp_sth->stmt, n);
1377 4           const char *tablename = sqlite3_column_table_name(imp_sth->stmt, n);
1378 4           const char *fieldname = sqlite3_column_name(imp_sth->stmt, n);
1379             const char *datatype, *collseq;
1380             int notnull, primary, autoinc;
1381 4           int rc = sqlite3_table_column_metadata(imp_dbh->db, database, tablename, fieldname, &datatype, &collseq, ¬null, &primary, &autoinc);
1382 4 50         if (rc != SQLITE_OK) {
1383 0           sqlite_error(sth, rc, sqlite3_errmsg(imp_dbh->db));
1384 0           av_store(av, n, newSViv(2)); /* SQL_NULLABLE_UNKNOWN */
1385             }
1386             else {
1387 4           av_store(av, n, newSViv(!notnull));
1388             }
1389             }
1390             #endif
1391             }
1392 373 50         else if (strEQ(key, "SCALE")) {
1393 0           AV *av = newAV();
1394 0           retsv = sv_2mortal(newRV_noinc((SV*)av));
1395             }
1396 373 100         else if (strEQ(key, "NUM_OF_FIELDS")) {
1397 47           retsv = sv_2mortal(newSViv(i));
1398             }
1399 326 100         else if (strEQ(key, "NUM_OF_PARAMS")) {
1400 124           retsv = sv_2mortal(newSViv(sqlite3_bind_parameter_count(imp_sth->stmt)));
1401             }
1402 202 100         else if (strEQ(key, "ParamValues")) {
1403 4           HV *hv = newHV();
1404 4           int num_params = DBIc_NUM_PARAMS(imp_sth);
1405 4 50         if (num_params) {
1406 8 100         for (n = 0; n < num_params; n++) {
1407 4           SV **pvalue = av_fetch(imp_sth->params, 2 * n, 0);
1408 4 100         SV *value = pvalue ? *pvalue : &PL_sv_undef;
1409 4           const char *pname = sqlite3_bind_parameter_name(imp_sth->stmt, n + 1);
1410 4 100         SV *sv_name = pname ? newSVpv(pname, 0) : newSViv(n + 1);
1411 4           hv_store_ent(hv, sv_name, newSVsv(value), 0);
1412             }
1413             }
1414 4           retsv = sv_2mortal(newRV_noinc((SV*)hv));
1415             }
1416              
1417 840           return retsv;
1418             }
1419              
1420             /* bind parameter
1421             * NB: We store the params instead of bind immediately because
1422             * we might need to re-create the imp_sth->stmt (see top of execute() function)
1423             * and so we can't lose these params
1424             */
1425             int
1426 943           sqlite_bind_ph(SV *sth, imp_sth_t *imp_sth,
1427             SV *param, SV *value, IV sql_type, SV *attribs,
1428             int is_inout, IV maxlen)
1429             {
1430             dTHX;
1431             int pos;
1432              
1433             croak_if_stmt_is_null();
1434              
1435 943 50         if (is_inout) {
1436 0           sqlite_error(sth, -2, "InOut bind params not implemented");
1437 0           return FALSE; /* -> &sv_no in SQLeet.xsi */
1438             }
1439              
1440 943 100         if (!looks_like_number(param)) {
1441             STRLEN len;
1442             char *paramstring;
1443 7 50         paramstring = SvPV(param, len);
1444 7 50         if(paramstring[len] == 0 && strlen(paramstring) == len) {
    50          
1445 7           pos = sqlite3_bind_parameter_index(imp_sth->stmt, paramstring);
1446 7 100         if (pos == 0) {
1447 1           sqlite_error(sth, -2, form("Unknown named parameter: %s", paramstring));
1448 1           return FALSE; /* -> &sv_no in SQLeet.xsi */
1449             }
1450 6           pos = 2 * (pos - 1);
1451             }
1452             else {
1453 0           sqlite_error(sth, -2, " could not be coerced to a C string");
1454 0           return FALSE; /* -> &sv_no in SQLeet.xsi */
1455             }
1456             }
1457             else {
1458 936 50         pos = 2 * (SvIV(param) - 1);
1459             }
1460 942 50         sqlite_trace(sth, imp_sth, 3, form("bind into 0x%p: %"IVdf" => %s (%"IVdf") pos %d", imp_sth->params, SvIV(param), SvPV_nolen_undef_ok(value), sql_type, pos));
    0          
    0          
    0          
    0          
    0          
1461 942           av_store(imp_sth->params, pos, newSVsv(value));
1462 942 100         if (sql_type) {
1463 165           av_store(imp_sth->params, pos+1, newSViv(sql_type));
1464             }
1465              
1466 942           return TRUE;
1467             }
1468              
1469             int
1470 223           sqlite_bind_col(SV *sth, imp_sth_t *imp_sth, SV *col, SV *ref, IV sql_type, SV *attribs)
1471             {
1472             dTHX;
1473              
1474             /* store the type */
1475 223 50         av_store(imp_sth->col_types, SvIV(col)-1, newSViv(sql_type));
1476              
1477             /* Allow default implementation to continue */
1478 223           return 1;
1479             }
1480              
1481             /*-----------------------------------------------------*
1482             * Driver Private Methods
1483             *-----------------------------------------------------*/
1484              
1485             AV *
1486 13           sqlite_compile_options()
1487             {
1488             dTHX;
1489 13           int i = 0;
1490             const char *option;
1491 13           AV *av = newAV();
1492              
1493             #if SQLITE_VERSION_NUMBER >= 3006023
1494             #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
1495 117 100         while((option = sqlite3_compileoption_get(i++))) {
1496 104           av_push(av, newSVpv(option, 0));
1497             }
1498             #endif
1499             #endif
1500              
1501 13           return (AV*)sv_2mortal((SV*)av);
1502             }
1503              
1504             #define _stores_status(op, key) \
1505             if (sqlite3_status(op, &cur, &hi, reset) == SQLITE_OK) { \
1506             anon = newHV(); \
1507             hv_stores(anon, "current", newSViv(cur)); \
1508             hv_stores(anon, "highwater", newSViv(hi)); \
1509             hv_stores(hv, key, newRV_noinc((SV*)anon)); \
1510             }
1511              
1512             #define _stores_dbstatus(op, key) \
1513             if (sqlite3_db_status(imp_dbh->db, op, &cur, &hi, reset) == SQLITE_OK) { \
1514             anon = newHV(); \
1515             hv_stores(anon, "current", newSViv(cur)); \
1516             hv_stores(anon, "highwater", newSViv(hi)); \
1517             hv_stores(hv, key, newRV_noinc((SV*)anon)); \
1518             }
1519              
1520             #define _stores_ststatus(op, key) \
1521             hv_stores(hv, key, newSViv(sqlite3_stmt_status(imp_sth->stmt, op, reset)))
1522              
1523             HV *
1524 1           _sqlite_status(int reset)
1525             {
1526             dTHX;
1527             int cur, hi;
1528 1           HV *hv = newHV();
1529             HV *anon;
1530              
1531 1 50         _stores_status(SQLITE_STATUS_MEMORY_USED, "memory_used");
1532 1 50         _stores_status(SQLITE_STATUS_PAGECACHE_USED, "pagecache_used");
1533 1 50         _stores_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, "pagecache_overflow");
1534 1 50         _stores_status(SQLITE_STATUS_SCRATCH_USED, "scratch_used");
1535              
1536 1 50         _stores_status(SQLITE_STATUS_SCRATCH_OVERFLOW, "scratch_overflow");
1537              
1538 1 50         _stores_status(SQLITE_STATUS_MALLOC_SIZE, "malloc_size");
1539 1 50         _stores_status(SQLITE_STATUS_PARSER_STACK, "parser_stack");
1540 1 50         _stores_status(SQLITE_STATUS_PAGECACHE_SIZE, "pagecache_size");
1541 1 50         _stores_status(SQLITE_STATUS_SCRATCH_SIZE, "scratch_size");
1542             #if SQLITE_VERSION_NUMBER >= 3007001
1543 1 50         _stores_status(SQLITE_STATUS_MALLOC_COUNT, "malloc_count");
1544             #endif
1545 1 50         _stores_status(SQLITE_STATUS_SCRATCH_OVERFLOW, "scratch_overflow");
1546              
1547 1           return hv;
1548             }
1549              
1550             HV *
1551 2           _sqlite_db_status(pTHX_ SV* dbh, int reset)
1552             {
1553 2           D_imp_dbh(dbh);
1554             int cur, hi;
1555 2           HV *hv = newHV();
1556             HV *anon;
1557              
1558 2 50         _stores_dbstatus(SQLITE_DBSTATUS_LOOKASIDE_USED, "lookaside_used");
1559             #if SQLITE_VERSION_NUMBER >= 3007000
1560 2 50         _stores_dbstatus(SQLITE_DBSTATUS_CACHE_USED, "cache_used");
1561             #endif
1562             #if SQLITE_VERSION_NUMBER >= 3007001
1563 2 50         _stores_dbstatus(SQLITE_DBSTATUS_SCHEMA_USED, "schema_used");
1564 2 50         _stores_dbstatus(SQLITE_DBSTATUS_STMT_USED, "stmt_used");
1565             #endif
1566             #if SQLITE_VERSION_NUMBER >= 3007005
1567 2 50         _stores_dbstatus(SQLITE_DBSTATUS_LOOKASIDE_HIT, "lookaside_hit");
1568 2 50         _stores_dbstatus(SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, "lookaside_miss_size");
1569 2 50         _stores_dbstatus(SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, "lookaside_miss_full");
1570             #endif
1571             #if SQLITE_VERSION_NUMBER >= 3007009
1572 2 50         _stores_dbstatus(SQLITE_DBSTATUS_CACHE_HIT, "cache_hit");
1573 2 50         _stores_dbstatus(SQLITE_DBSTATUS_CACHE_MISS, "cache_miss");
1574             #endif
1575             #if SQLITE_VERSION_NUMBER >= 3007012
1576 2 50         _stores_dbstatus(SQLITE_DBSTATUS_CACHE_WRITE, "cache_write");
1577             #endif
1578              
1579 2           return hv;
1580             }
1581              
1582             HV *
1583 2           _sqlite_st_status(pTHX_ SV* sth, int reset)
1584             {
1585 2           D_imp_sth(sth);
1586 2           HV *hv = newHV();
1587              
1588             #if SQLITE_VERSION_NUMBER >= 3006004
1589 2           _stores_ststatus(SQLITE_STMTSTATUS_FULLSCAN_STEP, "fullscan_step");
1590 2           _stores_ststatus(SQLITE_STMTSTATUS_SORT, "sort");
1591             #endif
1592             #if SQLITE_VERSION_NUMBER >= 3007000
1593 2           _stores_ststatus(SQLITE_STMTSTATUS_AUTOINDEX, "autoindex");
1594             #endif
1595              
1596 2           return hv;
1597             }
1598              
1599             SV *
1600 11           sqlite_db_filename(pTHX_ SV *dbh)
1601             {
1602 11           D_imp_dbh(dbh);
1603             const char *filename;
1604              
1605 11 100         if (!imp_dbh->db) {
1606 2           return &PL_sv_undef;
1607             }
1608              
1609             croak_if_db_is_null();
1610              
1611             #if SQLITE_VERSION_NUMBER >= 3007010
1612 9           filename = sqlite3_db_filename(imp_dbh->db, "main");
1613             #endif
1614 9 50         return filename ? newSVpv(filename, 0) : &PL_sv_undef;
1615             }
1616              
1617             int
1618 26           sqlite_db_busy_timeout(pTHX_ SV *dbh, SV *timeout )
1619             {
1620 26           D_imp_dbh(dbh);
1621              
1622             croak_if_db_is_null();
1623              
1624 26 100         if (timeout && SvIOK(timeout)) {
    50          
1625 20 50         imp_dbh->timeout = SvIV(timeout);
1626 20 100         if (!DBIc_ACTIVE(imp_dbh)) {
1627 4           sqlite_error(dbh, -2, "attempt to set busy timeout on inactive database handle");
1628 4           return -2;
1629             }
1630 16           sqlite3_busy_timeout(imp_dbh->db, imp_dbh->timeout);
1631             }
1632 22           return imp_dbh->timeout;
1633             }
1634              
1635             static void
1636 514           sqlite_db_func_dispatcher(int is_unicode, sqlite3_context *context, int argc, sqlite3_value **value)
1637             {
1638             dTHX;
1639 514           dSP;
1640             int count;
1641             int i;
1642             SV *func;
1643              
1644 514           func = sqlite3_user_data(context);
1645              
1646 514           ENTER;
1647 514           SAVETMPS;
1648              
1649 514 50         PUSHMARK(SP);
1650 1438 100         for ( i=0; i < argc; i++ ) {
1651 924 50         XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ value[i], is_unicode));
1652             }
1653 514           PUTBACK;
1654              
1655 514           count = call_sv(func, G_SCALAR|G_EVAL);
1656              
1657 514           SPAGAIN;
1658              
1659             /* Check for an error */
1660 514 50         if (SvTRUE(ERRSV) ) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1661 6 50         sqlite_set_result(aTHX_ context, ERRSV, 1);
1662 6           POPs;
1663 508 50         } else if ( count != 1 ) {
1664 0           SV *err = sv_2mortal(newSVpvf( "function should return 1 argument, got %d",
1665             count ));
1666              
1667 0           sqlite_set_result(aTHX_ context, err, 1);
1668             /* Clear the stack */
1669 0 0         for ( i=0; i < count; i++ ) {
1670 0           POPs;
1671             }
1672             } else {
1673 508           sqlite_set_result(aTHX_ context, POPs, 0 );
1674             }
1675              
1676 514           PUTBACK;
1677 514 50         FREETMPS;
1678 514           LEAVE;
1679 514           }
1680              
1681             static void
1682 204           sqlite_db_func_dispatcher_unicode(sqlite3_context *context, int argc, sqlite3_value **value)
1683             {
1684 204           sqlite_db_func_dispatcher(1, context, argc, value);
1685 204           }
1686              
1687             static void
1688 310           sqlite_db_func_dispatcher_no_unicode(sqlite3_context *context, int argc, sqlite3_value **value)
1689             {
1690 310           sqlite_db_func_dispatcher(0, context, argc, value);
1691 310           }
1692              
1693             int
1694 307           sqlite_db_create_function(pTHX_ SV *dbh, const char *name, int argc, SV *func, int flags)
1695             {
1696 307           D_imp_dbh(dbh);
1697             int rc;
1698             SV *func_sv;
1699              
1700 307 100         if (!DBIc_ACTIVE(imp_dbh)) {
1701 4           sqlite_error(dbh, -2, "attempt to create function on inactive database handle");
1702 4           return FALSE;
1703             }
1704              
1705             /* Copy the function reference */
1706 303           func_sv = newSVsv(func);
1707 303           av_push( imp_dbh->functions, func_sv );
1708              
1709             croak_if_db_is_null();
1710              
1711             /* warn("create_function %s with %d args\n", name, argc); */
1712 303 100         rc = sqlite3_create_function( imp_dbh->db, name, argc, SQLITE_UTF8|flags,
1713             func_sv,
1714 303           imp_dbh->unicode ? sqlite_db_func_dispatcher_unicode
1715             : sqlite_db_func_dispatcher_no_unicode,
1716             NULL, NULL );
1717 303 50         if ( rc != SQLITE_OK ) {
1718 0           sqlite_error(dbh, rc, form("sqlite_create_function failed with error %s", sqlite3_errmsg(imp_dbh->db)));
1719 0           return FALSE;
1720             }
1721 303           return TRUE;
1722             }
1723              
1724             #ifndef SQLITE_OMIT_LOAD_EXTENSION
1725              
1726             int
1727 4           sqlite_db_enable_load_extension(pTHX_ SV *dbh, int onoff)
1728             {
1729 4           D_imp_dbh(dbh);
1730             int rc;
1731              
1732 4 50         if (!DBIc_ACTIVE(imp_dbh)) {
1733 4           sqlite_error(dbh, -2, "attempt to enable load extension on inactive database handle");
1734 4           return FALSE;
1735             }
1736              
1737             croak_if_db_is_null();
1738              
1739             /* COMPAT: sqlite3_enable_load_extension is only available for 3003006 or newer */
1740 0           rc = sqlite3_enable_load_extension( imp_dbh->db, onoff );
1741 0 0         if ( rc != SQLITE_OK ) {
1742 0           sqlite_error(dbh, rc, form("sqlite_enable_load_extension failed with error %s", sqlite3_errmsg(imp_dbh->db)));
1743 0           return FALSE;
1744             }
1745 0           return TRUE;
1746             }
1747              
1748             int
1749 0           sqlite_db_load_extension(pTHX_ SV *dbh, const char *file, const char *proc)
1750             {
1751 0           D_imp_dbh(dbh);
1752             int rc;
1753              
1754 0 0         if (!DBIc_ACTIVE(imp_dbh)) {
1755 0           sqlite_error(dbh, -2, "attempt to load extension on inactive database handle");
1756 0           return FALSE;
1757             }
1758              
1759             croak_if_db_is_null();
1760              
1761             /* COMPAT: sqlite3_load_extension is only available for 3003006 or newer */
1762 0           rc = sqlite3_load_extension( imp_dbh->db, file, proc, NULL );
1763 0 0         if ( rc != SQLITE_OK ) {
1764 0           sqlite_error(dbh, rc, form("sqlite_load_extension failed with error %s", sqlite3_errmsg(imp_dbh->db)));
1765 0           return FALSE;
1766             }
1767 0           return TRUE;
1768             }
1769              
1770             #endif
1771              
1772             HV*
1773 14           sqlite_db_table_column_metadata(pTHX_ SV *dbh, SV *dbname, SV *tablename, SV *columnname)
1774             {
1775 14           D_imp_dbh(dbh);
1776             const char *datatype, *collseq;
1777             int notnull, primary, autoinc;
1778             int rc;
1779 14           HV *metadata = newHV();
1780              
1781 14 100         if (!DBIc_ACTIVE(imp_dbh)) {
1782 2           sqlite_error(dbh, -2, "attempt to fetch table column metadata on inactive database handle");
1783 2           return metadata;
1784             }
1785              
1786             croak_if_db_is_null();
1787              
1788             /* dbname may be NULL but (table|column)name may not be NULL */
1789 12 50         if (!tablename || !SvPOK(tablename)) {
    100          
1790 2           sqlite_error(dbh, -2, "table_column_metadata requires a table name");
1791 2           return metadata;
1792             }
1793 10 50         if (!columnname || !SvPOK(columnname)) {
    100          
1794 2           sqlite_error(dbh, -2, "table_column_metadata requires a column name");
1795 2           return metadata;
1796             }
1797              
1798             #ifdef SQLITE_ENABLE_COLUMN_METADATA
1799 16 50         rc = sqlite3_table_column_metadata(
    50          
    50          
    0          
1800             imp_dbh->db,
1801 8 50         (dbname && SvPOK(dbname)) ? SvPV_nolen(dbname) : NULL,
1802 8           SvPV_nolen(tablename),
1803 8           SvPV_nolen(columnname),
1804             &datatype, &collseq, ¬null, &primary, &autoinc);
1805             #endif
1806              
1807 8 100         if (rc == SQLITE_OK) {
1808 4 100         hv_stores(metadata, "data_type", datatype ? newSVpv(datatype, 0) : newSV(0));
1809 4 50         hv_stores(metadata, "collation_name", collseq ? newSVpv(collseq, 0) : newSV(0));
1810 4           hv_stores(metadata, "not_null", newSViv(notnull));
1811 4           hv_stores(metadata, "primary", newSViv(primary));
1812 4           hv_stores(metadata, "auto_increment", newSViv(autoinc));
1813             }
1814              
1815 14           return metadata;
1816             }
1817              
1818             static void
1819 96           sqlite_db_aggr_new_dispatcher(pTHX_ sqlite3_context *context, aggrInfo *aggr_info)
1820             {
1821 96           dSP;
1822 96           SV *pkg = NULL;
1823 96           int count = 0;
1824              
1825 96           aggr_info->err = NULL;
1826 96           aggr_info->aggr_inst = NULL;
1827              
1828 96           pkg = sqlite3_user_data(context);
1829 96 50         if ( !pkg )
1830 0           return;
1831              
1832 96           ENTER;
1833 96           SAVETMPS;
1834              
1835 96 50         PUSHMARK(SP);
1836 96 50         XPUSHs( sv_2mortal( newSVsv(pkg) ) );
1837 96           PUTBACK;
1838              
1839 96           count = call_method ("new", G_EVAL|G_SCALAR);
1840 96           SPAGAIN;
1841              
1842 96           aggr_info->inited = 1;
1843              
1844 96 50         if ( SvTRUE( ERRSV ) ) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1845 24 50         aggr_info->err = newSVpvf("error during aggregator's new(): %s",
1846 24 50         SvPV_nolen (ERRSV));
    50          
    0          
1847 12           POPs;
1848 84 50         } else if ( count != 1 ) {
1849             int i;
1850              
1851 0           aggr_info->err = newSVpvf("new() should return one value, got %d",
1852             count );
1853             /* Clear the stack */
1854 0 0         for ( i=0; i < count; i++ ) {
1855 0           POPs;
1856             }
1857             } else {
1858 84           SV *aggr = POPs;
1859 84 100         if ( SvROK(aggr) ) {
1860 78           aggr_info->aggr_inst = newSVsv(aggr);
1861             } else{
1862 6           aggr_info->err = newSVpvf( "new() should return a blessed reference" );
1863             }
1864             }
1865              
1866 96           PUTBACK;
1867              
1868 96 50         FREETMPS;
1869 96           LEAVE;
1870              
1871 96           return;
1872             }
1873              
1874             static void
1875 144           sqlite_db_aggr_step_dispatcher(sqlite3_context *context,
1876             int argc, sqlite3_value **value)
1877             {
1878             dTHX;
1879 144           dSP;
1880 144           int i, is_unicode = 0; /* TODO : find out from db handle */
1881             aggrInfo *aggr;
1882              
1883 144           aggr = sqlite3_aggregate_context(context, sizeof (aggrInfo));
1884 144 50         if ( !aggr )
1885 0           return;
1886              
1887 144           ENTER;
1888 144           SAVETMPS;
1889              
1890             /* initialize on first step */
1891 144 100         if ( !aggr->inited ) {
1892 60           sqlite_db_aggr_new_dispatcher(aTHX_ context, aggr);
1893             }
1894              
1895 144 100         if ( aggr->err || !aggr->aggr_inst )
    50          
1896             goto cleanup;
1897              
1898              
1899 96 50         PUSHMARK(SP);
1900 96 50         XPUSHs( sv_2mortal( newSVsv( aggr->aggr_inst ) ));
1901 132 100         for ( i=0; i < argc; i++ ) {
1902 36 50         XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ value[i], is_unicode));
1903             }
1904 96           PUTBACK;
1905              
1906 96           call_method ("step", G_SCALAR|G_EVAL|G_DISCARD);
1907              
1908             /* Check for an error */
1909 96 50         if (SvTRUE(ERRSV) ) {
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
1910 12 50         aggr->err = newSVpvf("error during aggregator's step(): %s",
1911 12 50         SvPV_nolen(ERRSV));
    50          
    0          
1912 6           POPs;
1913             }
1914              
1915             cleanup:
1916 144 100         FREETMPS;
1917 144           LEAVE;
1918             }
1919              
1920             static void
1921 96           sqlite_db_aggr_finalize_dispatcher( sqlite3_context *context )
1922             {
1923             dTHX;
1924 96           dSP;
1925             aggrInfo *aggr, myAggr;
1926 96           int count = 0;
1927              
1928 96           aggr = sqlite3_aggregate_context(context, 0);
1929              
1930 96           ENTER;
1931 96           SAVETMPS;
1932              
1933 96 100         if ( !aggr ) {
1934             /* SQLite seems to refuse to create a context structure
1935             from finalize() */
1936 36           aggr = &myAggr;
1937 36           aggr->aggr_inst = NULL;
1938 36           aggr->err = NULL;
1939 36           sqlite_db_aggr_new_dispatcher(aTHX_ context, aggr);
1940             }
1941              
1942 96 100         if ( ! aggr->err && aggr->aggr_inst ) {
    50          
1943 72 50         PUSHMARK(SP);
1944 72 50         XPUSHs( sv_2mortal( newSVsv( aggr->aggr_inst )) );
1945 72           PUTBACK;
1946              
1947 72           count = call_method( "finalize", G_SCALAR|G_EVAL );
1948 72           SPAGAIN;
1949              
1950 72 50         if ( SvTRUE(ERRSV) ) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1951 24 50         aggr->err = newSVpvf("error during aggregator's finalize(): %s",
1952 24 50         SvPV_nolen(ERRSV) ) ;
    50          
    0          
1953 12           POPs;
1954 60 50         } else if ( count != 1 ) {
1955             int i;
1956 0           aggr->err = newSVpvf("finalize() should return 1 value, got %d",
1957             count );
1958             /* Clear the stack */
1959 0 0         for ( i=0; i
1960 0           POPs;
1961             }
1962             } else {
1963 60           sqlite_set_result(aTHX_ context, POPs, 0);
1964             }
1965 72           PUTBACK;
1966             }
1967              
1968 96 100         if ( aggr->err ) {
1969 36 50         warn( "DBD::SQLeet: error in aggregator cannot be reported to SQLite: %s",
1970 72           SvPV_nolen( aggr->err ) );
1971              
1972             /* sqlite_set_result(aTHX_ context, aggr->err, 1); */
1973 36           SvREFCNT_dec( aggr->err );
1974 36           aggr->err = NULL;
1975             }
1976              
1977 96 100         if ( aggr->aggr_inst ) {
1978 78           SvREFCNT_dec( aggr->aggr_inst );
1979 78           aggr->aggr_inst = NULL;
1980             }
1981              
1982 96 50         FREETMPS;
1983 96           LEAVE;
1984 96           }
1985              
1986             int
1987 40           sqlite_db_create_aggregate(pTHX_ SV *dbh, const char *name, int argc, SV *aggr_pkg, int flags)
1988             {
1989 40           D_imp_dbh(dbh);
1990             int rc;
1991             SV *aggr_pkg_copy;
1992              
1993 40 100         if (!DBIc_ACTIVE(imp_dbh)) {
1994 4           sqlite_error(dbh, -2, "attempt to create aggregate on inactive database handle");
1995 4           return FALSE;
1996             }
1997              
1998             /* Copy the aggregate reference */
1999 36           aggr_pkg_copy = newSVsv(aggr_pkg);
2000 36           av_push( imp_dbh->aggregates, aggr_pkg_copy );
2001              
2002             croak_if_db_is_null();
2003              
2004 36           rc = sqlite3_create_function( imp_dbh->db, name, argc, SQLITE_UTF8|flags,
2005             aggr_pkg_copy,
2006             NULL,
2007             sqlite_db_aggr_step_dispatcher,
2008             sqlite_db_aggr_finalize_dispatcher
2009             );
2010              
2011 36 50         if ( rc != SQLITE_OK ) {
2012 0           sqlite_error(dbh, rc, form("sqlite_create_aggregate failed with error %s", sqlite3_errmsg(imp_dbh->db)));
2013 0           return FALSE;
2014             }
2015 36           return TRUE;
2016             }
2017              
2018             int
2019 396           sqlite_db_collation_dispatcher(void *func, int len1, const void *string1,
2020             int len2, const void *string2)
2021             {
2022             dTHX;
2023 396           dSP;
2024 396           int cmp = 0;
2025             int n_retval, i;
2026              
2027 396           ENTER;
2028 396           SAVETMPS;
2029 396 50         PUSHMARK(SP);
2030 396 50         XPUSHs( sv_2mortal( newSVpvn( string1, len1) ) );
2031 396 50         XPUSHs( sv_2mortal( newSVpvn( string2, len2) ) );
2032 396           PUTBACK;
2033 396           n_retval = call_sv(func, G_SCALAR);
2034 396           SPAGAIN;
2035 396 50         if (n_retval != 1) {
2036 0           warn("collation function returned %d arguments", n_retval);
2037             }
2038 792 100         for(i = 0; i < n_retval; i++) {
2039 396 50         cmp = POPi;
2040             }
2041 396           PUTBACK;
2042 396 50         FREETMPS;
2043 396           LEAVE;
2044              
2045 396           return cmp;
2046             }
2047              
2048             int
2049 348           sqlite_db_collation_dispatcher_utf8(void *func, int len1, const void *string1,
2050             int len2, const void *string2)
2051             {
2052             dTHX;
2053 348           dSP;
2054 348           int cmp = 0;
2055             int n_retval, i;
2056             SV *sv1, *sv2;
2057              
2058 348           ENTER;
2059 348           SAVETMPS;
2060 348 50         PUSHMARK(SP);
2061 348           sv1 = newSVpvn(string1, len1);
2062 348           SvUTF8_on(sv1);
2063 348           sv2 = newSVpvn(string2, len2);
2064 348           SvUTF8_on(sv2);
2065 348 50         XPUSHs( sv_2mortal( sv1 ) );
2066 348 50         XPUSHs( sv_2mortal( sv2 ) );
2067 348           PUTBACK;
2068 348           n_retval = call_sv(func, G_SCALAR);
2069 348           SPAGAIN;
2070 348 50         if (n_retval != 1) {
2071 0           warn("collation function returned %d arguments", n_retval);
2072             }
2073 696 100         for(i = 0; i < n_retval; i++) {
2074 348 50         cmp = POPi;
2075             }
2076 348           PUTBACK;
2077 348 50         FREETMPS;
2078 348           LEAVE;
2079              
2080 348           return cmp;
2081             }
2082              
2083             int
2084 24           sqlite_db_create_collation(pTHX_ SV *dbh, const char *name, SV *func)
2085             {
2086 24           D_imp_dbh(dbh);
2087             int rv, rv2;
2088 24           void *aa = "aa";
2089 24           void *zz = "zz";
2090              
2091 24           SV *func_sv = newSVsv(func);
2092              
2093 24 100         if (!DBIc_ACTIVE(imp_dbh)) {
2094 8           sqlite_error(dbh, -2, "attempt to create collation on inactive database handle");
2095 8           return FALSE;
2096             }
2097              
2098             croak_if_db_is_null();
2099              
2100             /* Check that this is a proper collation function */
2101 16           rv = sqlite_db_collation_dispatcher(func_sv, 2, aa, 2, aa);
2102 16 50         if (rv != 0) {
2103 0 0         sqlite_trace(dbh, imp_dbh, 3, form("improper collation function: %s(aa, aa) returns %d!", name, rv));
2104             }
2105 16           rv = sqlite_db_collation_dispatcher(func_sv, 2, aa, 2, zz);
2106 16           rv2 = sqlite_db_collation_dispatcher(func_sv, 2, zz, 2, aa);
2107 16 50         if (rv2 != (rv * -1)) {
2108 0 0         sqlite_trace(dbh, imp_dbh, 3, form("improper collation function: '%s' is not symmetric", name));
2109             }
2110              
2111             /* Copy the func reference so that it can be deallocated at disconnect */
2112 16           av_push( imp_dbh->functions, func_sv );
2113              
2114             /* Register the func within sqlite3 */
2115 16 100         rv = sqlite3_create_collation(
2116             imp_dbh->db, name, SQLITE_UTF8,
2117             func_sv,
2118 16           imp_dbh->unicode ? sqlite_db_collation_dispatcher_utf8
2119             : sqlite_db_collation_dispatcher
2120             );
2121              
2122 16 50         if ( rv != SQLITE_OK ) {
2123 0           sqlite_error(dbh, rv, form("sqlite_create_collation failed with error %s", sqlite3_errmsg(imp_dbh->db)));
2124 0           return FALSE;
2125             }
2126 16           return TRUE;
2127             }
2128              
2129             void
2130 12           sqlite_db_collation_needed_dispatcher(
2131             void *dbh,
2132             sqlite3* db, /* unused */
2133             int eTextRep, /* unused */
2134             const char* collation_name
2135             )
2136             {
2137             dTHX;
2138 12           dSP;
2139              
2140 12           D_imp_dbh(dbh);
2141              
2142 12           ENTER;
2143 12           SAVETMPS;
2144 12 50         PUSHMARK(SP);
2145 12 50         XPUSHs( dbh );
2146 12 50         XPUSHs( sv_2mortal( newSVpv( collation_name, 0) ) );
2147 12           PUTBACK;
2148              
2149 12           call_sv( imp_dbh->collation_needed_callback, G_VOID );
2150 12           SPAGAIN;
2151              
2152 12           PUTBACK;
2153 12 50         FREETMPS;
2154 12           LEAVE;
2155 12           }
2156              
2157             void
2158 251           sqlite_db_collation_needed(pTHX_ SV *dbh, SV *callback)
2159             {
2160 251           D_imp_dbh(dbh);
2161              
2162 251 100         if (!DBIc_ACTIVE(imp_dbh)) {
2163 4           sqlite_error(dbh, -2, "attempt to see if collation is needed on inactive database handle");
2164 4           return;
2165             }
2166              
2167             croak_if_db_is_null();
2168              
2169             /* remember the callback within the dbh */
2170 247           sv_setsv(imp_dbh->collation_needed_callback, callback);
2171              
2172             /* Register the func within sqlite3 */
2173 247 50         (void) sqlite3_collation_needed( imp_dbh->db,
2174 0 0         (void*) (SvOK(callback) ? dbh : NULL),
    0          
2175             sqlite_db_collation_needed_dispatcher );
2176             }
2177              
2178             int
2179 332           sqlite_db_generic_callback_dispatcher( void *callback )
2180             {
2181             dTHX;
2182 332           dSP;
2183             int n_retval, i;
2184 332           int retval = 0;
2185              
2186 332           ENTER;
2187 332           SAVETMPS;
2188 332 50         PUSHMARK(SP);
2189 332           n_retval = call_sv( callback, G_SCALAR );
2190 332           SPAGAIN;
2191 332 50         if ( n_retval != 1 ) {
2192 0           warn( "callback returned %d arguments", n_retval );
2193             }
2194 664 100         for(i = 0; i < n_retval; i++) {
2195 332 50         retval = POPi;
2196             }
2197 332           PUTBACK;
2198 332 50         FREETMPS;
2199 332           LEAVE;
2200              
2201 332           return retval;
2202             }
2203              
2204             int
2205 8           sqlite_db_progress_handler(pTHX_ SV *dbh, int n_opcodes, SV *handler)
2206             {
2207 8           D_imp_dbh(dbh);
2208              
2209 8 100         if (!DBIc_ACTIVE(imp_dbh)) {
2210 4           sqlite_error(dbh, -2, "attempt to set progress handler on inactive database handle");
2211 4           return FALSE;
2212             }
2213              
2214             croak_if_db_is_null();
2215              
2216 4 100         if (!SvOK(handler)) {
    50          
    50          
2217             /* remove previous handler */
2218 2           sqlite3_progress_handler( imp_dbh->db, 0, NULL, NULL);
2219             }
2220             else {
2221 2           SV *handler_sv = newSVsv(handler);
2222              
2223             /* Copy the handler ref so that it can be deallocated at disconnect */
2224 2           av_push( imp_dbh->functions, handler_sv );
2225              
2226             /* Register the func within sqlite3 */
2227 2           sqlite3_progress_handler( imp_dbh->db, n_opcodes,
2228             sqlite_db_generic_callback_dispatcher,
2229             handler_sv );
2230             }
2231 4           return TRUE;
2232             }
2233              
2234             SV*
2235 12           sqlite_db_commit_hook(pTHX_ SV *dbh, SV *hook)
2236             {
2237 12           D_imp_dbh(dbh);
2238             void *retval;
2239              
2240 12 100         if (!DBIc_ACTIVE(imp_dbh)) {
2241 4           sqlite_error(dbh, -2, "attempt to set commit hook on inactive database handle");
2242 4           return &PL_sv_undef;
2243             }
2244              
2245             croak_if_db_is_null();
2246              
2247 8 100         if (!SvOK(hook)) {
    50          
    50          
2248             /* remove previous hook */
2249 4           retval = sqlite3_commit_hook( imp_dbh->db, NULL, NULL );
2250             }
2251             else {
2252 4           SV *hook_sv = newSVsv( hook );
2253              
2254             /* Copy the handler ref so that it can be deallocated at disconnect */
2255 4           av_push( imp_dbh->functions, hook_sv );
2256              
2257             /* Register the hook within sqlite3 */
2258 4           retval = sqlite3_commit_hook( imp_dbh->db,
2259             sqlite_db_generic_callback_dispatcher,
2260             hook_sv );
2261             }
2262              
2263 8 100         return retval ? newSVsv(retval) : &PL_sv_undef;
2264             }
2265              
2266             SV*
2267 8           sqlite_db_rollback_hook(pTHX_ SV *dbh, SV *hook)
2268             {
2269 8           D_imp_dbh(dbh);
2270             void *retval;
2271              
2272 8 100         if (!DBIc_ACTIVE(imp_dbh)) {
2273 4           sqlite_error(dbh, -2, "attempt to set rollback hook on inactive database handle");
2274 4           return &PL_sv_undef;
2275             }
2276              
2277             croak_if_db_is_null();
2278              
2279 4 100         if (!SvOK(hook)) {
    50          
    50          
2280             /* remove previous hook */
2281 2           retval = sqlite3_rollback_hook( imp_dbh->db, NULL, NULL );
2282             }
2283             else {
2284 2           SV *hook_sv = newSVsv( hook );
2285              
2286             /* Copy the handler ref so that it can be deallocated at disconnect */
2287 2           av_push( imp_dbh->functions, hook_sv );
2288              
2289             /* Register the hook within sqlite3 */
2290 2           retval = sqlite3_rollback_hook( imp_dbh->db,
2291             (void(*)(void *))
2292             sqlite_db_generic_callback_dispatcher,
2293             hook_sv );
2294             }
2295              
2296 4 100         return retval ? newSVsv(retval) : &PL_sv_undef;
2297             }
2298              
2299             void
2300 60           sqlite_db_update_dispatcher( void *callback, int op,
2301             char const *database, char const *table,
2302             sqlite3_int64 rowid )
2303             {
2304             dTHX;
2305 60           dSP;
2306              
2307 60           ENTER;
2308 60           SAVETMPS;
2309 60 50         PUSHMARK(SP);
2310              
2311 60 50         XPUSHs( sv_2mortal( newSViv( op ) ) );
2312 60 50         XPUSHs( sv_2mortal( newSVpv( database, 0 ) ) );
2313 60 50         XPUSHs( sv_2mortal( newSVpv( table, 0 ) ) );
2314 60 50         XPUSHs( sv_2mortal( newSViv( (IV)rowid ) ) );
2315 60           PUTBACK;
2316              
2317 60           call_sv( callback, G_VOID );
2318 60           SPAGAIN;
2319              
2320 60           PUTBACK;
2321 60 50         FREETMPS;
2322 60           LEAVE;
2323 60           }
2324              
2325             SV*
2326 8           sqlite_db_update_hook(pTHX_ SV *dbh, SV *hook)
2327             {
2328 8           D_imp_dbh(dbh);
2329             void *retval;
2330              
2331 8 100         if (!DBIc_ACTIVE(imp_dbh)) {
2332 4           sqlite_error(dbh, -2, "attempt to set update hook on inactive database handle");
2333 4           return &PL_sv_undef;
2334             }
2335              
2336             croak_if_db_is_null();
2337              
2338 4 100         if (!SvOK(hook)) {
    50          
    50          
2339             /* remove previous hook */
2340 2           retval = sqlite3_update_hook( imp_dbh->db, NULL, NULL );
2341             }
2342             else {
2343 2           SV *hook_sv = newSVsv( hook );
2344              
2345             /* Copy the handler ref so that it can be deallocated at disconnect */
2346 2           av_push( imp_dbh->functions, hook_sv );
2347              
2348             /* Register the hook within sqlite3 */
2349 2           retval = sqlite3_update_hook( imp_dbh->db,
2350             sqlite_db_update_dispatcher,
2351             hook_sv );
2352             }
2353              
2354 4 100         return retval ? newSVsv(retval) : &PL_sv_undef;
2355             }
2356              
2357             int
2358 4           sqlite_db_authorizer_dispatcher (
2359             void *authorizer,
2360             int action_code,
2361             const char *details_1,
2362             const char *details_2,
2363             const char *details_3,
2364             const char *details_4
2365             )
2366             {
2367             dTHX;
2368 4           dSP;
2369 4           int retval = 0;
2370             int n_retval, i;
2371              
2372 4           ENTER;
2373 4           SAVETMPS;
2374 4 50         PUSHMARK(SP);
2375              
2376 4 50         XPUSHs( sv_2mortal ( newSViv ( action_code ) ) );
2377              
2378             /* these ifs are ugly but without them, perl 5.8 segfaults */
2379 4 50         XPUSHs( sv_2mortal( details_1 ? newSVpv( details_1, 0 ) : &PL_sv_undef ) );
    50          
2380 4 50         XPUSHs( sv_2mortal( details_2 ? newSVpv( details_2, 0 ) : &PL_sv_undef ) );
    50          
2381 4 50         XPUSHs( sv_2mortal( details_3 ? newSVpv( details_3, 0 ) : &PL_sv_undef ) );
    50          
2382 4 50         XPUSHs( sv_2mortal( details_4 ? newSVpv( details_4, 0 ) : &PL_sv_undef ) );
    50          
2383 4           PUTBACK;
2384              
2385 4           n_retval = call_sv(authorizer, G_SCALAR);
2386 4           SPAGAIN;
2387 4 50         if ( n_retval != 1 ) {
2388 0           warn( "callback returned %d arguments", n_retval );
2389             }
2390 8 100         for(i = 0; i < n_retval; i++) {
2391 4 50         retval = POPi;
2392             }
2393              
2394 4           PUTBACK;
2395 4 50         FREETMPS;
2396 4           LEAVE;
2397              
2398 4           return retval;
2399             }
2400              
2401             int
2402 8           sqlite_db_set_authorizer(pTHX_ SV *dbh, SV *authorizer)
2403             {
2404 8           D_imp_dbh(dbh);
2405             int retval;
2406              
2407 8 100         if (!DBIc_ACTIVE(imp_dbh)) {
2408 4           sqlite_error(dbh, -2, "attempt to set authorizer on inactive database handle");
2409 4           return FALSE;
2410             }
2411              
2412             croak_if_db_is_null();
2413              
2414 4 100         if (!SvOK(authorizer)) {
    50          
    50          
2415             /* remove previous hook */
2416 2           retval = sqlite3_set_authorizer( imp_dbh->db, NULL, NULL );
2417             }
2418             else {
2419 2           SV *authorizer_sv = newSVsv( authorizer );
2420              
2421             /* Copy the coderef so that it can be deallocated at disconnect */
2422 2           av_push( imp_dbh->functions, authorizer_sv );
2423              
2424             /* Register the hook within sqlite3 */
2425 2           retval = sqlite3_set_authorizer( imp_dbh->db,
2426             sqlite_db_authorizer_dispatcher,
2427             authorizer_sv );
2428             }
2429              
2430 4           return retval;
2431             }
2432              
2433             #ifndef SQLITE_OMIT_TRACE
2434             void
2435 14           sqlite_db_trace_dispatcher(void *callback, const char *sql)
2436             {
2437             dTHX;
2438 14           dSP;
2439             int n_retval, i;
2440 14           int retval = 0;
2441              
2442 14           ENTER;
2443 14           SAVETMPS;
2444 14 50         PUSHMARK(SP);
2445 14 50         XPUSHs( sv_2mortal( newSVpv( sql, 0 ) ) );
2446 14           PUTBACK;
2447              
2448 14           n_retval = call_sv( callback, G_SCALAR );
2449 14           SPAGAIN;
2450 14 50         if ( n_retval != 1 ) {
2451 0           warn( "callback returned %d arguments", n_retval );
2452             }
2453 28 100         for(i = 0; i < n_retval; i++) {
2454 14 50         retval = POPi;
2455             }
2456 14           PUTBACK;
2457 14 50         FREETMPS;
2458 14           LEAVE;
2459 14           }
2460              
2461             int
2462 6           sqlite_db_trace(pTHX_ SV *dbh, SV *func)
2463             {
2464 6           D_imp_dbh(dbh);
2465              
2466 6 50         if (!DBIc_ACTIVE(imp_dbh)) {
2467 0           sqlite_error(dbh, -2, "attempt to set trace on inactive database handle");
2468 0           return FALSE;
2469             }
2470              
2471             croak_if_db_is_null();
2472              
2473 6 100         if (!SvOK(func)) {
    50          
    50          
2474             /* remove previous callback */
2475 2           sqlite3_trace( imp_dbh->db, NULL, NULL );
2476             }
2477             else {
2478 4           SV *func_sv = newSVsv(func);
2479              
2480             /* Copy the func ref so that it can be deallocated at disconnect */
2481 4           av_push( imp_dbh->functions, func_sv );
2482              
2483             /* Register the func within sqlite3 */
2484 4           sqlite3_trace( imp_dbh->db,
2485             sqlite_db_trace_dispatcher,
2486             func_sv );
2487             }
2488 6           return TRUE;
2489             }
2490             #endif
2491              
2492             void
2493 6           sqlite_db_profile_dispatcher(void *callback, const char *sql, sqlite3_uint64 elapsed)
2494             {
2495             dTHX;
2496 6           dSP;
2497             int n_retval, i;
2498 6           int retval = 0;
2499              
2500 6           ENTER;
2501 6           SAVETMPS;
2502 6 50         PUSHMARK(SP);
2503 6 50         XPUSHs( sv_2mortal( newSVpv( sql, 0 ) ) );
2504             /*
2505             * The profile callback time is in units of nanoseconds,
2506             * however the current implementation is only capable of
2507             * millisecond resolution so the six least significant digits
2508             * in the time are meaningless.
2509             * (http://sqlite.org/c3ref/profile.html)
2510             */
2511 6 50         XPUSHs( sv_2mortal( newSViv((IV)( elapsed / 1000000 )) ) );
2512 6           PUTBACK;
2513              
2514 6           n_retval = call_sv( callback, G_SCALAR );
2515 6           SPAGAIN;
2516 6 50         if ( n_retval != 1 ) {
2517 0           warn( "callback returned %d arguments", n_retval );
2518             }
2519 12 100         for(i = 0; i < n_retval; i++) {
2520 6 50         retval = POPi;
2521             }
2522 6           PUTBACK;
2523 6 50         FREETMPS;
2524 6           LEAVE;
2525 6           }
2526              
2527             int
2528 6           sqlite_db_profile(pTHX_ SV *dbh, SV *func)
2529             {
2530 6           D_imp_dbh(dbh);
2531              
2532 6 50         if (!DBIc_ACTIVE(imp_dbh)) {
2533 0           sqlite_error(dbh, -2, "attempt to profile on inactive database handle");
2534 0           return FALSE;
2535             }
2536              
2537             croak_if_db_is_null();
2538              
2539 6 100         if (!SvOK(func)) {
    50          
    50          
2540             /* remove previous callback */
2541 2           sqlite3_profile( imp_dbh->db, NULL, NULL );
2542             }
2543             else {
2544 4           SV *func_sv = newSVsv(func);
2545              
2546             /* Copy the func ref so that it can be deallocated at disconnect */
2547 4           av_push( imp_dbh->functions, func_sv );
2548              
2549             /* Register the func within sqlite3 */
2550 4           sqlite3_profile( imp_dbh->db,
2551             sqlite_db_profile_dispatcher,
2552             func_sv );
2553             }
2554 6           return TRUE;
2555             }
2556              
2557             /* Accesses the SQLite Online Backup API, and fills the currently loaded
2558             * database from the passed filename.
2559             * Usual usage of this would be when you're operating on the :memory:
2560             * special database connection and want to copy it in from a real db.
2561             */
2562             int
2563 6           sqlite_db_backup_from_file(pTHX_ SV *dbh, char *filename)
2564             {
2565 6           D_imp_dbh(dbh);
2566              
2567             #if SQLITE_VERSION_NUMBER >= 3006011
2568             int rc;
2569             sqlite3 *pFrom;
2570             sqlite3_backup *pBackup;
2571              
2572 6 100         if (!DBIc_ACTIVE(imp_dbh)) {
2573 4           sqlite_error(dbh, -2, "attempt to backup from file on inactive database handle");
2574 4           return FALSE;
2575             }
2576              
2577             croak_if_db_is_null();
2578              
2579 2           rc = sqlite_open(filename, &pFrom);
2580 2 50         if ( rc != SQLITE_OK ) {
2581 0           return FALSE;
2582             }
2583              
2584             /* COMPAT: sqlite3_backup_* are only available for 3006011 or newer */
2585 2           pBackup = sqlite3_backup_init(imp_dbh->db, "main", pFrom, "main");
2586 2 50         if (pBackup) {
2587 2           (void)sqlite3_backup_step(pBackup, -1);
2588 2           (void)sqlite3_backup_finish(pBackup);
2589             }
2590 2           rc = sqlite3_errcode(imp_dbh->db);
2591 2           (void)sqlite3_close(pFrom);
2592              
2593 2 50         if ( rc != SQLITE_OK ) {
2594 0           sqlite_error(dbh, rc, form("sqlite_backup_from_file failed with error %s", sqlite3_errmsg(imp_dbh->db)));
2595 0           return FALSE;
2596             }
2597              
2598 6           return TRUE;
2599             #else
2600             sqlite_error(dbh, SQLITE_ERROR, form("backup feature requires SQLite 3.6.11 and newer"));
2601             return FALSE;
2602             #endif
2603             }
2604              
2605             /* Accesses the SQLite Online Backup API, and copies the currently loaded
2606             * database into the passed filename.
2607             * Usual usage of this would be when you're operating on the :memory:
2608             * special database connection, and want to back it up to an on-disk file.
2609             */
2610             int
2611 6           sqlite_db_backup_to_file(pTHX_ SV *dbh, char *filename)
2612             {
2613 6           D_imp_dbh(dbh);
2614              
2615             #if SQLITE_VERSION_NUMBER >= 3006011
2616             int rc;
2617             sqlite3 *pTo;
2618             sqlite3_backup *pBackup;
2619              
2620 6 100         if (!DBIc_ACTIVE(imp_dbh)) {
2621 4           sqlite_error(dbh, -2, "attempt to backup to file on inactive database handle");
2622 4           return FALSE;
2623             }
2624              
2625             croak_if_db_is_null();
2626              
2627 2           rc = sqlite_open(filename, &pTo);
2628 2 50         if ( rc != SQLITE_OK ) {
2629 0           return FALSE;
2630             }
2631              
2632             /* COMPAT: sqlite3_backup_* are only available for 3006011 or newer */
2633 2           pBackup = sqlite3_backup_init(pTo, "main", imp_dbh->db, "main");
2634 2 50         if (pBackup) {
2635 2           (void)sqlite3_backup_step(pBackup, -1);
2636 2           (void)sqlite3_backup_finish(pBackup);
2637             }
2638 2           rc = sqlite3_errcode(pTo);
2639 2           (void)sqlite3_close(pTo);
2640              
2641 2 50         if ( rc != SQLITE_OK ) {
2642 0           sqlite_error(dbh, rc, form("sqlite_backup_to_file failed with error %s", sqlite3_errmsg(imp_dbh->db)));
2643 0           return FALSE;
2644             }
2645              
2646 6           return TRUE;
2647             #else
2648             sqlite_error(dbh, SQLITE_ERROR, form("backup feature requires SQLite 3.6.11 and newer"));
2649             return FALSE;
2650             #endif
2651             }
2652              
2653             #include "dbdimp_tokenizer.inc"
2654             #include "dbdimp_virtual_table.inc"
2655              
2656             /* end */