File Coverage

SQLeet.xsi
Criterion Covered Total %
statement 193 246 78.4
branch 213 502 42.4
condition n/a
subroutine n/a
pod n/a
total 406 748 54.2


line stmt bran cond sub pod time code
1             # $Id$
2             # Copyright (c) 1997-2002 Tim Bunce Ireland
3             # Copyright (c) 2002 Jonathan Leffler
4             #
5             # You may distribute under the terms of either the GNU General Public
6             # License or the Artistic License, as specified in the Perl README file.
7              
8              
9             #include "Driver_xst.h"
10              
11             # Historically dbd_db_do4, dbd_st_execute, and dbd_st_rows returned an 'int' type.
12             # That's only 32 bits (31+sign) so isn't sufficient for very large row counts
13             # So now instead of defining those macros, drivers can define dbd_db_do4_iv,
14             # dbd_st_execute_iv, and dbd_st_rows_iv to be the names of functions that
15             # return an 'IV' type. They could also set DBIc_ROW_COUNT(imp_sth).
16             #
17             # To save a mess of #ifdef's we arrange for dbd_st_execute (etc) to work
18             # as dbd_st_execute_iv if that's defined
19             #
20             #if defined(dbd_st_execute_iv)
21             #undef dbd_st_execute
22             #define dbd_st_execute dbd_st_execute_iv
23             #endif
24             #if defined(dbd_st_rows_iv)
25             #undef dbd_st_rows
26             #define dbd_st_rows dbd_st_rows_iv
27             #endif
28             #if defined(dbd_db_do4_iv)
29             #undef dbd_db_do4
30             #define dbd_db_do4 dbd_db_do4_iv
31             #endif
32              
33             MODULE = DBD::SQLeet PACKAGE = DBD::SQLeet
34              
35             REQUIRE: 1.929
36             PROTOTYPES: DISABLE
37              
38             BOOT:
39             PERL_UNUSED_VAR(items);
40 101 50         DBISTATE_INIT;
41             /* XXX this interface will change: */
42 101           DBI_IMP_SIZE("DBD::SQLeet::dr::imp_data_size", sizeof(imp_drh_t));
43 101           DBI_IMP_SIZE("DBD::SQLeet::db::imp_data_size", sizeof(imp_dbh_t));
44 101           DBI_IMP_SIZE("DBD::SQLeet::st::imp_data_size", sizeof(imp_sth_t));
45 101           dbd_init(DBIS);
46              
47              
48             # ------------------------------------------------------------
49             # driver level interface
50             # ------------------------------------------------------------
51             MODULE = DBD::SQLeet PACKAGE = DBD::SQLeet::dr
52              
53              
54             void
55             dbixs_revision(...)
56             PPCODE:
57 0           ST(0) = sv_2mortal(newSViv(DBIXS_REVISION));
58              
59              
60             #ifdef dbd_discon_all
61              
62             # disconnect_all renamed and ALIAS'd to avoid length clash on VMS :-(
63             void
64             discon_all_(drh)
65             SV * drh
66             ALIAS:
67             disconnect_all = 1
68             CODE:
69 95           D_imp_drh(drh);
70             PERL_UNUSED_VAR(ix);
71 95 50         ST(0) = dbd_discon_all(drh, imp_drh) ? &PL_sv_yes : &PL_sv_no;
72              
73             #endif /* dbd_discon_all */
74              
75              
76             #ifdef dbd_dr_data_sources
77              
78             void
79             data_sources(drh, attr = Nullsv)
80             SV *drh
81             SV *attr
82             PPCODE:
83             {
84             D_imp_drh(drh);
85             AV *av = dbd_dr_data_sources(drh, imp_drh, attr);
86             if (av) {
87             int i;
88             int n = AvFILL(av)+1;
89             EXTEND(sp, n);
90             for (i = 0; i < n; ++i) {
91             PUSHs(AvARRAY(av)[i]);
92             }
93             }
94             }
95              
96             #endif
97              
98              
99             # ------------------------------------------------------------
100             # database level interface
101             # ------------------------------------------------------------
102             MODULE = DBD::SQLeet PACKAGE = DBD::SQLeet::db
103              
104              
105             void
106             _login(dbh, dbname, username, password, attribs=Nullsv)
107             SV * dbh
108             SV * dbname
109             SV * username
110             SV * password
111             SV * attribs
112             CODE:
113             {
114 253           D_imp_dbh(dbh);
115             #if !defined(dbd_db_login6_sv)
116             STRLEN lna;
117 253 100         char *u = (SvOK(username)) ? SvPV(username,lna) : (char*)"";
    50          
    50          
    50          
118 253 100         char *p = (SvOK(password)) ? SvPV(password,lna) : (char*)"";
    50          
    50          
    50          
119             #endif
120             #ifdef dbd_db_login6_sv
121             ST(0) = dbd_db_login6_sv(dbh, imp_dbh, dbname, username, password, attribs) ? &PL_sv_yes : &PL_sv_no;
122             #elif defined(dbd_db_login6)
123 253 50         ST(0) = dbd_db_login6(dbh, imp_dbh, SvPV_nolen(dbname), u, p, attribs) ? &PL_sv_yes : &PL_sv_no;
    100          
124             #else
125             PERL_UNUSED_ARG(attribs);
126             ST(0) = dbd_db_login( dbh, imp_dbh, SvPV_nolen(dbname), u, p) ? &PL_sv_yes : &PL_sv_no;
127             #endif
128             }
129              
130              
131             void
132             selectall_arrayref(...)
133             PREINIT:
134             SV *sth;
135             SV **maxrows_svp;
136             SV **tmp_svp;
137             SV *tmp_sv;
138 322           SV *attr = &PL_sv_undef;
139             imp_sth_t *imp_sth;
140             CODE:
141 322 100         if (items > 2) {
142 69           attr = ST(2);
143 159 100         if (SvROK(attr) &&
    100          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
144 137 50         (DBD_ATTRIB_TRUE(attr,"Slice",5,tmp_svp) || DBD_ATTRIB_TRUE(attr,"Columns",7,tmp_svp))
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
145             ) {
146             /* fallback to perl implementation */
147 43           SV *tmp =dbixst_bounce_method("DBD::SQLeet::db::SUPER::selectall_arrayref", items);
148 43           SPAGAIN;
149 43           ST(0) = tmp;
150 43           XSRETURN(1);
151             }
152             }
153             /* --- prepare --- */
154 279 50         if (SvROK(ST(1))) {
155             MAGIC *mg;
156 0           sth = ST(1);
157             /* switch to inner handle if not already */
158 0 0         if ( (mg = mg_find(SvRV(sth),'P')) )
159 0           sth = mg->mg_obj;
160             }
161             else {
162 279           sth = dbixst_bounce_method("prepare", 3);
163 279           SPAGAIN; SP -= items; /* because stack might have been realloc'd */
164 279 50         if (!SvROK(sth))
165 0           XSRETURN_UNDEF;
166             /* switch to inner handle */
167 279           sth = mg_find(SvRV(sth),'P')->mg_obj;
168             }
169 279           imp_sth = (imp_sth_t*)(DBIh_COM(sth));
170             /* --- bind_param --- */
171 279 100         if (items > 3) { /* need to bind params before execute */
172 26 50         if (!dbdxst_bind_params(sth, imp_sth, items-2, ax+2) ) {
173 0           XSRETURN_UNDEF;
174             }
175             }
176             /* --- execute --- */
177 279           DBIc_ROW_COUNT(imp_sth) = 0;
178 279 50         if ( dbd_st_execute(sth, imp_sth) <= -2 ) { /* -2 == error */
179 0           XSRETURN_UNDEF;
180             }
181             /* --- fetchall --- */
182 279 50         maxrows_svp = DBD_ATTRIB_GET_SVP(attr, "MaxRows", 7);
    100          
    50          
183 279 50         tmp_sv = dbdxst_fetchall_arrayref(sth, &PL_sv_undef, (maxrows_svp) ? *maxrows_svp : &PL_sv_undef);
184 279           SPAGAIN;
185 279           ST(0) = tmp_sv;
186              
187              
188             void
189             selectrow_arrayref(...)
190             ALIAS:
191             selectrow_array = 1
192             PREINIT:
193 230           int is_selectrow_array = (ix == 1);
194             imp_sth_t *imp_sth;
195             SV *sth;
196             AV *row_av;
197             PPCODE:
198 230 100         if (SvROK(ST(1))) {
199             MAGIC *mg;
200 4           sth = ST(1);
201             /* switch to inner handle if not already */
202 4 50         if ( (mg = mg_find(SvRV(sth),'P')) )
203 4           sth = mg->mg_obj;
204             }
205             else {
206             /* --- prepare --- */
207 226           sth = dbixst_bounce_method("prepare", 3);
208 226           SPAGAIN; SP -= items; /* because stack might have been realloc'd */
209 226 100         if (!SvROK(sth)) {
210 2 50         if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; }
211             }
212             /* switch to inner handle */
213 224           sth = mg_find(SvRV(sth),'P')->mg_obj;
214             }
215 228           imp_sth = (imp_sth_t*)(DBIh_COM(sth));
216             /* --- bind_param --- */
217 228 100         if (items > 3) { /* need to bind params before execute */
218 35 50         if (!dbdxst_bind_params(sth, imp_sth, items-2, ax+2) ) {
219 0 0         if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; }
220             }
221             }
222             /* --- execute --- */
223 228           DBIc_ROW_COUNT(imp_sth) = 0;
224 228 100         if ( dbd_st_execute(sth, imp_sth) <= -2 ) { /* -2 == error */
225 6 50         if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; }
226             }
227             /* --- fetchrow_arrayref --- */
228 222           row_av = dbd_st_fetch(sth, imp_sth);
229 222 100         if (!row_av) {
230 4 50         if (GIMME == G_SCALAR)
    50          
231 4           PUSHs(&PL_sv_undef);
232             }
233 218 100         else if (is_selectrow_array) {
234             int i;
235 39 50         int num_fields = AvFILL(row_av)+1;
236 39 50         if (GIMME == G_SCALAR)
    100          
237 5           num_fields = 1; /* return just first field */
238 39 50         EXTEND(sp, num_fields);
    50          
239 79 100         for(i=0; i < num_fields; ++i) {
240 40           PUSHs(AvARRAY(row_av)[i]);
241             }
242             }
243             else {
244 179           PUSHs( sv_2mortal(newRV((SV *)row_av)) );
245             }
246             /* --- finish --- */
247             #ifdef dbd_st_finish3
248 222           dbd_st_finish3(sth, imp_sth, 0);
249             #else
250             dbd_st_finish(sth, imp_sth);
251             #endif
252              
253              
254             #if defined(dbd_db_do6) || defined(dbd_db_do4)
255              
256             void
257             do(dbh, statement, params = Nullsv, ...)
258             SV * dbh
259             SV * statement
260             SV * params
261             CODE:
262             {
263             D_imp_dbh(dbh);
264             IV retval;
265             #ifdef dbd_db_do6
266             /* items is a number of arguments passed to XSUB, supplied by xsubpp compiler */
267             /* ax contains stack base offset used by ST() macro, supplied by xsubpp compiler */
268             retval = dbd_db_do6(dbh, imp_dbh, statement, params, items-3, ax+3);
269             #else
270             if (items > 3)
271             croak_xs_usage(cv, "dbh, statement, params = Nullsv");
272             retval = dbd_db_do4(dbh, imp_dbh, SvPV_nolen(statement), params); /* might be dbd_db_do4_iv via macro */
273             #endif
274             /* remember that dbd_db_do* must return <= -2 for error */
275             if (retval == 0) /* ok with no rows affected */
276             XST_mPV(0, "0E0"); /* (true but zero) */
277             else if (retval < -1) /* -1 == unknown number of rows */
278             XST_mUNDEF(0); /* <= -2 means error */
279             else
280             XST_mIV(0, retval); /* typically 1, rowcount or -1 */
281             }
282              
283             #endif
284              
285              
286             #ifdef dbd_db_last_insert_id
287              
288             void
289             last_insert_id(dbh, catalog=&PL_sv_undef, schema=&PL_sv_undef, table=&PL_sv_undef, field=&PL_sv_undef, attr=Nullsv)
290             SV * dbh
291             SV * catalog
292             SV * schema
293             SV * table
294             SV * field
295             SV * attr
296             CODE:
297             {
298 211           D_imp_dbh(dbh);
299 211           ST(0) = dbd_db_last_insert_id(dbh, imp_dbh, catalog, schema, table, field, attr);
300             }
301              
302             #endif
303              
304              
305             void
306             commit(dbh)
307             SV * dbh
308             CODE:
309 76           D_imp_dbh(dbh);
310 76 100         if (DBIc_has(imp_dbh,DBIcf_AutoCommit) && DBIc_WARN(imp_dbh))
    50          
311 2           warn("commit ineffective with AutoCommit enabled");
312 76 100         ST(0) = dbd_db_commit(dbh, imp_dbh) ? &PL_sv_yes : &PL_sv_no;
313              
314              
315             void
316             rollback(dbh)
317             SV * dbh
318             CODE:
319 23           D_imp_dbh(dbh);
320 23 100         if (DBIc_has(imp_dbh,DBIcf_AutoCommit) && DBIc_WARN(imp_dbh))
    50          
321 2           warn("rollback ineffective with AutoCommit enabled");
322 23 100         ST(0) = dbd_db_rollback(dbh, imp_dbh) ? &PL_sv_yes : &PL_sv_no;
323              
324              
325             void
326             disconnect(dbh)
327             SV * dbh
328             CODE:
329 91           D_imp_dbh(dbh);
330 91 100         if ( !DBIc_ACTIVE(imp_dbh) ) {
331 2           XSRETURN_YES;
332             }
333             /* Check for disconnect() being called whilst refs to cursors */
334             /* still exists. This possibly needs some more thought. */
335 89 100         if (DBIc_ACTIVE_KIDS(imp_dbh) && DBIc_WARN(imp_dbh) && !PL_dirty) {
    50          
    50          
336             STRLEN lna;
337 1 50         char *plural = (DBIc_ACTIVE_KIDS(imp_dbh)==1) ? (char*)"" : (char*)"s";
338 1 50         warn("%s->disconnect invalidates %d active statement handle%s %s",
339 1           SvPV(dbh,lna), (int)DBIc_ACTIVE_KIDS(imp_dbh), plural,
340             "(either destroy statement handles or call finish on them before disconnecting)");
341             }
342 89 50         ST(0) = dbd_db_disconnect(dbh, imp_dbh) ? &PL_sv_yes : &PL_sv_no;
343 89 50         DBIc_ACTIVE_off(imp_dbh); /* ensure it's off, regardless */
    0          
    0          
    0          
    0          
344              
345              
346             void
347             STORE(dbh, keysv, valuesv)
348             SV * dbh
349             SV * keysv
350             SV * valuesv
351             CODE:
352 1328           D_imp_dbh(dbh);
353 1328 50         if (SvGMAGICAL(valuesv))
354 0           mg_get(valuesv);
355 1328           ST(0) = &PL_sv_yes;
356 1328 100         if (!dbd_db_STORE_attrib(dbh, imp_dbh, keysv, valuesv))
357 960 100         if (!DBIc_DBISTATE(imp_dbh)->set_attr(dbh, keysv, valuesv))
358 16           ST(0) = &PL_sv_no;
359              
360              
361             void
362             FETCH(dbh, keysv)
363             SV * dbh
364             SV * keysv
365             CODE:
366 3183           D_imp_dbh(dbh);
367 3183           SV *valuesv = dbd_db_FETCH_attrib(dbh, imp_dbh, keysv);
368 3183 100         if (!valuesv)
369 287           valuesv = DBIc_DBISTATE(imp_dbh)->get_attr(dbh, keysv);
370 3183           ST(0) = valuesv; /* dbd_db_FETCH_attrib did sv_2mortal */
371              
372              
373             void
374             DESTROY(dbh)
375             SV * dbh
376             PPCODE:
377             /* keep in sync with default DESTROY in DBI.xs */
378 253           D_imp_dbh(dbh);
379 253           ST(0) = &PL_sv_yes;
380 253 100         if (!DBIc_IMPSET(imp_dbh)) { /* was never fully set up */
381             STRLEN lna;
382 6 50         if (DBIc_WARN(imp_dbh) && !PL_dirty && DBIc_DBISTATE(imp_dbh)->debug >= 2)
    50          
    50          
383 6 0         PerlIO_printf(DBIc_LOGPIO(imp_dbh),
384             " DESTROY for %s ignored - handle not initialised\n",
385 0           SvPV(dbh,lna));
386             }
387             else {
388 247 100         if (DBIc_IADESTROY(imp_dbh)) { /* wants ineffective destroy */
389 2 50         DBIc_ACTIVE_off(imp_dbh);
    0          
    0          
    0          
    0          
390 2 50         if (DBIc_DBISTATE(imp_dbh)->debug)
391 0 0         PerlIO_printf(DBIc_LOGPIO(imp_dbh), " DESTROY %s skipped due to InactiveDestroy\n", SvPV_nolen(dbh));
392             }
393 247 100         if (DBIc_ACTIVE(imp_dbh)) {
394 156 100         if (!DBIc_has(imp_dbh,DBIcf_AutoCommit)) {
395             /* Application is using transactions and hasn't explicitly disconnected.
396             Some databases will automatically commit on graceful disconnect.
397             Since we're about to gracefully disconnect as part of the DESTROY
398             we want to be sure we're not about to implicitly commit changes
399             that are incomplete and should be rolled back. (The DESTROY may
400             be due to a RaiseError, for example.) So we rollback here.
401             This will be harmless if the application has issued a commit,
402             XXX Could add an attribute flag to indicate that the driver
403             doesn't have this problem. Patches welcome.
404             */
405 5 100         if (DBIc_WARN(imp_dbh) /* only warn if likely to be useful... */
406 4 50         && DBIc_is(imp_dbh, DBIcf_Executed) /* has not just called commit/rollback */
407             /* && !DBIc_is(imp_dbh, DBIcf_ReadOnly) -- is not read only */
408 0 0         && (!PL_dirty || DBIc_DBISTATE(imp_dbh)->debug >= 3)
    0          
409             ) {
410 0 0         warn("Issuing rollback() due to DESTROY without explicit disconnect() of %s handle %s",
    0          
411 0           SvPV_nolen(*hv_fetch((HV*)SvRV(dbh), "ImplementorClass", 16, 1)),
412 0           SvPV_nolen(*hv_fetch((HV*)SvRV(dbh), "Name", 4, 1))
413             );
414             }
415 5           dbd_db_rollback(dbh, imp_dbh); /* ROLLBACK! */
416             }
417 156           dbd_db_disconnect(dbh, imp_dbh);
418 156 50         DBIc_ACTIVE_off(imp_dbh); /* ensure it's off, regardless */
    0          
    0          
    0          
    0          
419             }
420 247           dbd_db_destroy(dbh, imp_dbh);
421             }
422              
423              
424             #ifdef dbd_take_imp_data
425              
426             void
427             take_imp_data(h)
428             SV * h
429             CODE:
430             D_imp_xxh(h);
431             /* dbd_take_imp_data() returns &sv_no (or other defined but false value)
432             * to indicate "preparations complete, now call SUPER::take_imp_data" for me.
433             * Anything else is returned to the caller via sv_2mortal(sv), typically that
434             * would be &sv_undef for error or an SV holding the imp_data.
435             */
436             SV *sv = dbd_take_imp_data(h, imp_xxh, NULL);
437             if (SvOK(sv) && !SvTRUE(sv)) {
438             SV *tmp = dbixst_bounce_method("DBD::SQLeet::db::SUPER::take_imp_data", items);
439             SPAGAIN;
440             ST(0) = tmp;
441             } else {
442             ST(0) = sv_2mortal(sv);
443             }
444              
445             #endif
446              
447             #ifdef dbd_db_data_sources
448              
449             void
450             data_sources(dbh, attr = Nullsv)
451             SV *dbh
452             SV *attr
453             PPCODE:
454             {
455             D_imp_dbh(dbh);
456             AV *av = dbd_db_data_sources(dbh, imp_dbh, attr);
457             if (av) {
458             int i;
459             int n = AvFILL(av)+1;
460             EXTEND(sp, n);
461             for (i = 0; i < n; ++i) {
462             PUSHs(AvARRAY(av)[i]);
463             }
464             }
465             }
466              
467             #endif
468              
469             # -- end of DBD::SQLeet::db
470              
471             # ------------------------------------------------------------
472             # statement interface
473             # ------------------------------------------------------------
474             MODULE = DBD::SQLeet PACKAGE = DBD::SQLeet::st
475              
476              
477             void
478             _prepare(sth, statement, attribs=Nullsv)
479             SV * sth
480             SV * statement
481             SV * attribs
482             CODE:
483             {
484 1117           D_imp_sth(sth);
485 1117 100         DBD_ATTRIBS_CHECK("_prepare", sth, attribs);
    100          
    50          
    50          
    50          
    50          
    0          
    0          
486             #ifdef dbd_st_prepare_sv
487 1117 100         ST(0) = dbd_st_prepare_sv(sth, imp_sth, statement, attribs) ? &PL_sv_yes : &PL_sv_no;
488             #else
489             ST(0) = dbd_st_prepare(sth, imp_sth, SvPV_nolen(statement), attribs) ? &PL_sv_yes : &PL_sv_no;
490             #endif
491             }
492              
493              
494             #ifdef dbd_st_rows
495              
496             void
497             rows(sth)
498             SV * sth
499             CODE:
500 117           D_imp_sth(sth);
501 117           XST_mIV(0, dbd_st_rows(sth, imp_sth));
502              
503             #endif /* dbd_st_rows */
504              
505              
506             #ifdef dbd_st_bind_col
507              
508             void
509             bind_col(sth, col, ref, attribs=Nullsv)
510             SV * sth
511             SV * col
512             SV * ref
513             SV * attribs
514             CODE:
515             {
516 223           IV sql_type = 0;
517 223           D_imp_sth(sth);
518 223 50         if (SvGMAGICAL(ref))
519 0           mg_get(ref);
520 223 100         if (attribs) {
521 133 100         if (SvNIOK(attribs)) {
522 1 50         sql_type = SvIV(attribs);
523 1           attribs = Nullsv;
524             }
525             else {
526             SV **svp;
527 132 50         DBD_ATTRIBS_CHECK("bind_col", sth, attribs);
    100          
    50          
    50          
    50          
    50          
    0          
    0          
528             /* XXX we should perhaps complain if TYPE is not SvNIOK */
529 132 100         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
    50          
    50          
    100          
    50          
530             }
531             }
532 223           switch(dbd_st_bind_col(sth, imp_sth, col, ref, sql_type, attribs)) {
533 0           case 2: ST(0) = &PL_sv_yes; /* job done completely */
534 0           break;
535             case 1: /* fallback to DBI default */
536 223           ST(0) = (DBIc_DBISTATE(imp_sth)->bind_col(sth, col, ref, attribs))
537 223 50         ? &PL_sv_yes : &PL_sv_no;
538 223           break;
539 0           default: ST(0) = &PL_sv_no; /* dbd_st_bind_col has called set_err */
540 0           break;
541             }
542             }
543              
544             #endif /* dbd_st_bind_col */
545              
546             void
547             bind_param(sth, param, value, attribs=Nullsv)
548             SV * sth
549             SV * param
550             SV * value
551             SV * attribs
552             CODE:
553             {
554 271           IV sql_type = 0;
555 271           D_imp_sth(sth);
556 271 50         if (SvGMAGICAL(value))
557 0           mg_get(value);
558 271 100         if (attribs) {
559 229 100         if (SvNIOK(attribs)) {
560 162 50         sql_type = SvIV(attribs);
561 162           attribs = Nullsv;
562             }
563             else {
564             SV **svp;
565 67 50         DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
    100          
    50          
    50          
    50          
    50          
    0          
    0          
566             /* XXX we should perhaps complain if TYPE is not SvNIOK */
567 67 100         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
    50          
    50          
    100          
    50          
568             }
569             }
570 271           ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, FALSE, 0)
571 271 100         ? &PL_sv_yes : &PL_sv_no;
572             }
573              
574              
575             void
576             bind_param_inout(sth, param, value_ref, maxlen, attribs=Nullsv)
577             SV * sth
578             SV * param
579             SV * value_ref
580             IV maxlen
581             SV * attribs
582             CODE:
583             {
584 0           IV sql_type = 0;
585 0           D_imp_sth(sth);
586             SV *value;
587 0 0         if (!SvROK(value_ref) || SvTYPE(SvRV(value_ref)) > SVt_PVMG)
    0          
588 0           croak("bind_param_inout needs a reference to a scalar value");
589 0           value = SvRV(value_ref);
590 0 0         if (SvREADONLY(value))
591 0           croak("Modification of a read-only value attempted");
592 0 0         if (SvGMAGICAL(value))
593 0           mg_get(value);
594 0 0         if (attribs) {
595 0 0         if (SvNIOK(attribs)) {
596 0 0         sql_type = SvIV(attribs);
597 0           attribs = Nullsv;
598             }
599             else {
600             SV **svp;
601 0 0         DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
602 0 0         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
    0          
    0          
    0          
    0          
603             }
604             }
605 0           ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, TRUE, maxlen)
606 0 0         ? &PL_sv_yes : &PL_sv_no;
607             }
608              
609              
610             void
611             execute(sth, ...)
612             SV * sth
613             CODE:
614 940           D_imp_sth(sth);
615             IV retval;
616 940 100         if (items > 1) { /* need to bind params */
617 357 50         if (!dbdxst_bind_params(sth, imp_sth, items, ax) ) {
618 0           XSRETURN_UNDEF;
619             }
620             }
621             /* XXX this code is duplicated in selectrow_arrayref above */
622 940           DBIc_ROW_COUNT(imp_sth) = 0;
623 940           retval = dbd_st_execute(sth, imp_sth); /* might be dbd_st_execute_iv via macro */
624             /* remember that dbd_st_execute must return <= -2 for error */
625 940 100         if (retval == 0) /* ok with no rows affected */
626 450           XST_mPV(0, "0E0"); /* (true but zero) */
627 490 100         else if (retval < -1) /* -1 == unknown number of rows */
628 11           XST_mUNDEF(0); /* <= -2 means error */
629             else
630 479           XST_mIV(0, retval); /* typically 1, rowcount or -1 */
631              
632              
633             #ifdef dbd_st_execute_for_fetch
634              
635             void
636             execute_for_fetch(sth, fetch_tuple_sub, tuple_status = Nullsv)
637             SV * sth
638             SV * fetch_tuple_sub
639             SV * tuple_status
640             CODE:
641             {
642             D_imp_sth(sth);
643             ST(0) = dbd_st_execute_for_fetch(sth, imp_sth, fetch_tuple_sub, tuple_status);
644             }
645              
646             #endif
647              
648              
649             #ifdef dbd_st_last_insert_id
650              
651             void
652             last_insert_id(sth, catalog=&PL_sv_undef, schema=&PL_sv_undef, table=&PL_sv_undef, field=&PL_sv_undef, attr=Nullsv)
653             SV * sth
654             SV * catalog
655             SV * schema
656             SV * table
657             SV * field
658             SV * attr
659             CODE:
660             {
661             D_imp_sth(sth);
662             ST(0) = dbd_st_last_insert_id(sth, imp_sth, catalog, schema, table, field, attr);
663             }
664              
665             #endif
666              
667              
668             void
669             fetchrow_arrayref(sth)
670             SV * sth
671             ALIAS:
672             fetch = 1
673             CODE:
674 1157           D_imp_sth(sth);
675             AV *av;
676             PERL_UNUSED_VAR(ix);
677 1157           av = dbd_st_fetch(sth, imp_sth);
678 1157 100         ST(0) = (av) ? sv_2mortal(newRV((SV *)av)) : &PL_sv_undef;
679              
680              
681             void
682             fetchrow_array(sth)
683             SV * sth
684             ALIAS:
685             fetchrow = 1
686             PPCODE:
687 44           D_imp_sth(sth);
688             AV *av;
689 44           av = dbd_st_fetch(sth, imp_sth);
690 44 100         if (av) {
691             int i;
692 34 50         int num_fields = AvFILL(av)+1;
693 34 50         EXTEND(sp, num_fields);
    50          
694 84 100         for(i=0; i < num_fields; ++i) {
695 50           PUSHs(AvARRAY(av)[i]);
696             }
697             PERL_UNUSED_VAR(ix);
698             }
699              
700              
701             void
702             fetchall_arrayref(sth, slice=&PL_sv_undef, batch_row_count=&PL_sv_undef)
703             SV * sth
704             SV * slice
705             SV * batch_row_count
706             CODE:
707 104 100         if (SvOK(slice)) { /* fallback to perl implementation */
    50          
    50          
708 43           SV *tmp = dbixst_bounce_method("DBD::SQLeet::st::SUPER::fetchall_arrayref", 3);
709 43           SPAGAIN;
710 43           ST(0) = tmp;
711             }
712             else {
713 18           SV *tmp = dbdxst_fetchall_arrayref(sth, slice, batch_row_count);
714 18           SPAGAIN;
715 18           ST(0) = tmp;
716             }
717              
718              
719             void
720             finish(sth)
721             SV * sth
722             CODE:
723 61           D_imp_sth(sth);
724 61           D_imp_dbh_from_sth;
725 61 100         if (!DBIc_ACTIVE(imp_sth)) {
726             /* No active statement to finish */
727 44           XSRETURN_YES;
728             }
729 17 50         if (!DBIc_ACTIVE(imp_dbh)) {
730             /* Either an explicit disconnect() or global destruction */
731             /* has disconnected us from the database. Finish is meaningless */
732 0 0         DBIc_ACTIVE_off(imp_sth);
    0          
    0          
    0          
    0          
733 0           XSRETURN_YES;
734             }
735             #ifdef dbd_st_finish3
736 17 50         ST(0) = dbd_st_finish3(sth, imp_sth, 0) ? &PL_sv_yes : &PL_sv_no;
737             #else
738             ST(0) = dbd_st_finish(sth, imp_sth) ? &PL_sv_yes : &PL_sv_no;
739             #endif
740              
741              
742             void
743             blob_read(sth, field, offset, len, destrv=Nullsv, destoffset=0)
744             SV * sth
745             int field
746             long offset
747             long len
748             SV * destrv
749             long destoffset
750             CODE:
751             {
752 0           D_imp_sth(sth);
753 0 0         if (!destrv)
754 0           destrv = sv_2mortal(newRV(sv_2mortal(newSV(0))));
755 0 0         if (dbd_st_blob_read(sth, imp_sth, field, offset, len, destrv, destoffset))
756 0           ST(0) = SvRV(destrv);
757 0           else ST(0) = &PL_sv_undef;
758             }
759              
760              
761             void
762             STORE(sth, keysv, valuesv)
763             SV * sth
764             SV * keysv
765             SV * valuesv
766             CODE:
767 5           D_imp_sth(sth);
768 5 50         if (SvGMAGICAL(valuesv))
769 0           mg_get(valuesv);
770 5           ST(0) = &PL_sv_yes;
771 5 50         if (!dbd_st_STORE_attrib(sth, imp_sth, keysv, valuesv))
772 5 50         if (!DBIc_DBISTATE(imp_sth)->set_attr(sth, keysv, valuesv))
773 0           ST(0) = &PL_sv_no;
774              
775              
776             # FETCH renamed and ALIAS'd to avoid case clash on VMS :-(
777             void
778             FETCH_attrib(sth, keysv)
779             SV * sth
780             SV * keysv
781             ALIAS:
782             FETCH = 1
783             CODE:
784 857           D_imp_sth(sth);
785             SV *valuesv;
786             PERL_UNUSED_VAR(ix);
787 857           valuesv = dbd_st_FETCH_attrib(sth, imp_sth, keysv);
788 857 100         if (!valuesv)
789 199           valuesv = DBIc_DBISTATE(imp_sth)->get_attr(sth, keysv);
790 857           ST(0) = valuesv; /* dbd_st_FETCH_attrib did sv_2mortal */
791              
792              
793             void
794             DESTROY(sth)
795             SV * sth
796             PPCODE:
797             /* keep in sync with default DESTROY in DBI.xs */
798 1117           D_imp_sth(sth);
799 1117           ST(0) = &PL_sv_yes;
800 1117 100         if (!DBIc_IMPSET(imp_sth)) { /* was never fully set up */
801             STRLEN lna;
802 10 50         if (DBIc_WARN(imp_sth) && !PL_dirty && DBIc_DBISTATE(imp_sth)->debug >= 2)
    50          
    50          
803 10 0         PerlIO_printf(DBIc_LOGPIO(imp_sth),
804             " DESTROY for %s ignored - handle not initialised\n",
805 0           SvPV(sth,lna));
806             }
807             else {
808 1107 50         if (DBIc_IADESTROY(imp_sth)) { /* wants ineffective destroy */
809 0 0         DBIc_ACTIVE_off(imp_sth);
    0          
    0          
    0          
    0          
810 0 0         if (DBIc_DBISTATE(imp_sth)->debug)
811 0 0         PerlIO_printf(DBIc_LOGPIO(imp_sth), " DESTROY %s skipped due to InactiveDestroy\n", SvPV_nolen(sth));
812             }
813 1107 100         if (DBIc_ACTIVE(imp_sth)) {
814 58           D_imp_dbh_from_sth;
815 58 50         if (!PL_dirty && DBIc_ACTIVE(imp_dbh)) {
    100          
816             #ifdef dbd_st_finish3
817 57           dbd_st_finish3(sth, imp_sth, 1);
818             #else
819             dbd_st_finish(sth, imp_sth);
820             #endif
821             }
822             else {
823 1 50         DBIc_ACTIVE_off(imp_sth);
    50          
    50          
    50          
    50          
824             }
825             }
826 1107           dbd_st_destroy(sth, imp_sth);
827             }
828              
829             # end of SQLeet.xst
830             # vim:ts=8:sw=4:et