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 254           D_imp_dbh(dbh);
115             #if !defined(dbd_db_login6_sv)
116             STRLEN lna;
117 254 100         char *u = (SvOK(username)) ? SvPV(username,lna) : (char*)"";
    50          
    50          
    50          
118 254 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 254 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 334           SV *attr = &PL_sv_undef;
139             imp_sth_t *imp_sth;
140             CODE:
141 334 100         if (items > 2) {
142 81           attr = ST(2);
143 179 100         if (SvROK(attr) &&
    100          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
144 149 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 47           SV *tmp =dbixst_bounce_method("DBD::SQLeet::db::SUPER::selectall_arrayref", items);
148 47           SPAGAIN;
149 47           ST(0) = tmp;
150 47           XSRETURN(1);
151             }
152             }
153             /* --- prepare --- */
154 287 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 287           sth = dbixst_bounce_method("prepare", 3);
163 287           SPAGAIN; SP -= items; /* because stack might have been realloc'd */
164 287 50         if (!SvROK(sth))
165 0           XSRETURN_UNDEF;
166             /* switch to inner handle */
167 287           sth = mg_find(SvRV(sth),'P')->mg_obj;
168             }
169 287           imp_sth = (imp_sth_t*)(DBIh_COM(sth));
170             /* --- bind_param --- */
171 287 100         if (items > 3) { /* need to bind params before execute */
172 34 50         if (!dbdxst_bind_params(sth, imp_sth, items-2, ax+2) ) {
173 0           XSRETURN_UNDEF;
174             }
175             }
176             /* --- execute --- */
177 287           DBIc_ROW_COUNT(imp_sth) = 0;
178 287 50         if ( dbd_st_execute(sth, imp_sth) <= -2 ) { /* -2 == error */
179 0           XSRETURN_UNDEF;
180             }
181             /* --- fetchall --- */
182 287 50         maxrows_svp = DBD_ATTRIB_GET_SVP(attr, "MaxRows", 7);
    100          
    50          
183 287 50         tmp_sv = dbdxst_fetchall_arrayref(sth, &PL_sv_undef, (maxrows_svp) ? *maxrows_svp : &PL_sv_undef);
184 287           SPAGAIN;
185 287           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             #ifdef dbd_db_do4 /* deebeedee-deebee-doo, deebee-doobee-dah? */
255              
256             void
257             do(dbh, statement, params = Nullsv)
258             SV * dbh
259             char * statement
260             SV * params
261             CODE:
262             {
263             D_imp_dbh(dbh);
264             IV retval;
265             retval = dbd_db_do4(dbh, imp_dbh, statement, params); /* might be dbd_db_do4_iv via macro */
266             /* remember that dbd_db_do4 must return <= -2 for error */
267             if (retval == 0) /* ok with no rows affected */
268             XST_mPV(0, "0E0"); /* (true but zero) */
269             else if (retval < -1) /* -1 == unknown number of rows */
270             XST_mUNDEF(0); /* <= -2 means error */
271             else
272             XST_mIV(0, retval); /* typically 1, rowcount or -1 */
273             }
274              
275             #endif
276              
277              
278             #ifdef dbd_db_last_insert_id
279              
280             void
281             last_insert_id(dbh, catalog, schema, table, field, attr=Nullsv)
282             SV * dbh
283             SV * catalog
284             SV * schema
285             SV * table
286             SV * field
287             SV * attr
288             CODE:
289             {
290 211           D_imp_dbh(dbh);
291 211           ST(0) = dbd_db_last_insert_id(dbh, imp_dbh, catalog, schema, table, field, attr);
292             }
293              
294             #endif
295              
296              
297             void
298             commit(dbh)
299             SV * dbh
300             CODE:
301 76           D_imp_dbh(dbh);
302 76 100         if (DBIc_has(imp_dbh,DBIcf_AutoCommit) && DBIc_WARN(imp_dbh))
    50          
303 2           warn("commit ineffective with AutoCommit enabled");
304 76 100         ST(0) = dbd_db_commit(dbh, imp_dbh) ? &PL_sv_yes : &PL_sv_no;
305              
306              
307             void
308             rollback(dbh)
309             SV * dbh
310             CODE:
311 23           D_imp_dbh(dbh);
312 23 100         if (DBIc_has(imp_dbh,DBIcf_AutoCommit) && DBIc_WARN(imp_dbh))
    50          
313 2           warn("rollback ineffective with AutoCommit enabled");
314 23 100         ST(0) = dbd_db_rollback(dbh, imp_dbh) ? &PL_sv_yes : &PL_sv_no;
315              
316              
317             void
318             disconnect(dbh)
319             SV * dbh
320             CODE:
321 92           D_imp_dbh(dbh);
322 92 100         if ( !DBIc_ACTIVE(imp_dbh) ) {
323 2           XSRETURN_YES;
324             }
325             /* Check for disconnect() being called whilst refs to cursors */
326             /* still exists. This possibly needs some more thought. */
327 90 100         if (DBIc_ACTIVE_KIDS(imp_dbh) && DBIc_WARN(imp_dbh) && !PL_dirty) {
    50          
    50          
328             STRLEN lna;
329 1 50         char *plural = (DBIc_ACTIVE_KIDS(imp_dbh)==1) ? (char*)"" : (char*)"s";
330 1 50         warn("%s->disconnect invalidates %d active statement handle%s %s",
331 1           SvPV(dbh,lna), (int)DBIc_ACTIVE_KIDS(imp_dbh), plural,
332             "(either destroy statement handles or call finish on them before disconnecting)");
333             }
334 90 50         ST(0) = dbd_db_disconnect(dbh, imp_dbh) ? &PL_sv_yes : &PL_sv_no;
335 90 50         DBIc_ACTIVE_off(imp_dbh); /* ensure it's off, regardless */
    0          
    0          
    0          
    0          
336              
337              
338             void
339             STORE(dbh, keysv, valuesv)
340             SV * dbh
341             SV * keysv
342             SV * valuesv
343             CODE:
344 1334           D_imp_dbh(dbh);
345 1334 50         if (SvGMAGICAL(valuesv))
346 0           mg_get(valuesv);
347 1334           ST(0) = &PL_sv_yes;
348 1334 100         if (!dbd_db_STORE_attrib(dbh, imp_dbh, keysv, valuesv))
349 965 100         if (!DBIc_DBISTATE(imp_dbh)->set_attr(dbh, keysv, valuesv))
350 17           ST(0) = &PL_sv_no;
351              
352              
353             void
354             FETCH(dbh, keysv)
355             SV * dbh
356             SV * keysv
357             CODE:
358 3183           D_imp_dbh(dbh);
359 3183           SV *valuesv = dbd_db_FETCH_attrib(dbh, imp_dbh, keysv);
360 3183 100         if (!valuesv)
361 287           valuesv = DBIc_DBISTATE(imp_dbh)->get_attr(dbh, keysv);
362 3183           ST(0) = valuesv; /* dbd_db_FETCH_attrib did sv_2mortal */
363              
364              
365             void
366             DESTROY(dbh)
367             SV * dbh
368             PPCODE:
369             /* keep in sync with default DESTROY in DBI.xs */
370 254           D_imp_dbh(dbh);
371 254           ST(0) = &PL_sv_yes;
372 254 100         if (!DBIc_IMPSET(imp_dbh)) { /* was never fully set up */
373             STRLEN lna;
374 6 50         if (DBIc_WARN(imp_dbh) && !PL_dirty && DBIc_DBISTATE(imp_dbh)->debug >= 2)
    50          
    50          
375 6 0         PerlIO_printf(DBIc_LOGPIO(imp_dbh),
376             " DESTROY for %s ignored - handle not initialised\n",
377 0           SvPV(dbh,lna));
378             }
379             else {
380 248 100         if (DBIc_IADESTROY(imp_dbh)) { /* wants ineffective destroy */
381 2 50         DBIc_ACTIVE_off(imp_dbh);
    0          
    0          
    0          
    0          
382 2 50         if (DBIc_DBISTATE(imp_dbh)->debug)
383 0 0         PerlIO_printf(DBIc_LOGPIO(imp_dbh), " DESTROY %s skipped due to InactiveDestroy\n", SvPV_nolen(dbh));
384             }
385 248 100         if (DBIc_ACTIVE(imp_dbh)) {
386 156 100         if (!DBIc_has(imp_dbh,DBIcf_AutoCommit)) {
387             /* Application is using transactions and hasn't explicitly disconnected.
388             Some databases will automatically commit on graceful disconnect.
389             Since we're about to gracefully disconnect as part of the DESTROY
390             we want to be sure we're not about to implicitly commit changes
391             that are incomplete and should be rolled back. (The DESTROY may
392             be due to a RaiseError, for example.) So we rollback here.
393             This will be harmless if the application has issued a commit,
394             XXX Could add an attribute flag to indicate that the driver
395             doesn't have this problem. Patches welcome.
396             */
397 5 100         if (DBIc_WARN(imp_dbh) /* only warn if likely to be useful... */
398 4 50         && DBIc_is(imp_dbh, DBIcf_Executed) /* has not just called commit/rollback */
399             /* && !DBIc_is(imp_dbh, DBIcf_ReadOnly) -- is not read only */
400 0 0         && (!PL_dirty || DBIc_DBISTATE(imp_dbh)->debug >= 3)
    0          
401             ) {
402 0 0         warn("Issuing rollback() due to DESTROY without explicit disconnect() of %s handle %s",
    0          
403 0           SvPV_nolen(*hv_fetch((HV*)SvRV(dbh), "ImplementorClass", 16, 1)),
404 0           SvPV_nolen(*hv_fetch((HV*)SvRV(dbh), "Name", 4, 1))
405             );
406             }
407 5           dbd_db_rollback(dbh, imp_dbh); /* ROLLBACK! */
408             }
409 156           dbd_db_disconnect(dbh, imp_dbh);
410 156 50         DBIc_ACTIVE_off(imp_dbh); /* ensure it's off, regardless */
    0          
    0          
    0          
    0          
411             }
412 248           dbd_db_destroy(dbh, imp_dbh);
413             }
414              
415              
416             #ifdef dbd_take_imp_data
417              
418             void
419             take_imp_data(h)
420             SV * h
421             CODE:
422             D_imp_xxh(h);
423             /* dbd_take_imp_data() returns &sv_no (or other defined but false value)
424             * to indicate "preparations complete, now call SUPER::take_imp_data" for me.
425             * Anything else is returned to the caller via sv_2mortal(sv), typically that
426             * would be &sv_undef for error or an SV holding the imp_data.
427             */
428             SV *sv = dbd_take_imp_data(h, imp_xxh, NULL);
429             if (SvOK(sv) && !SvTRUE(sv)) {
430             SV *tmp = dbixst_bounce_method("DBD::SQLeet::db::SUPER::take_imp_data", items);
431             SPAGAIN;
432             ST(0) = tmp;
433             } else {
434             ST(0) = sv_2mortal(sv);
435             }
436              
437             #endif
438              
439             #ifdef dbd_db_data_sources
440              
441             void
442             data_sources(dbh, attr = Nullsv)
443             SV *dbh
444             SV *attr
445             PPCODE:
446             {
447             D_imp_dbh(dbh);
448             AV *av = dbd_db_data_sources(dbh, imp_dbh, attr);
449             if (av) {
450             int i;
451             int n = AvFILL(av)+1;
452             EXTEND(sp, n);
453             for (i = 0; i < n; ++i) {
454             PUSHs(AvARRAY(av)[i]);
455             }
456             }
457             }
458              
459             #endif
460              
461             # -- end of DBD::SQLeet::db
462              
463             # ------------------------------------------------------------
464             # statement interface
465             # ------------------------------------------------------------
466             MODULE = DBD::SQLeet PACKAGE = DBD::SQLeet::st
467              
468              
469             void
470             _prepare(sth, statement, attribs=Nullsv)
471             SV * sth
472             SV * statement
473             SV * attribs
474             CODE:
475             {
476 1137           D_imp_sth(sth);
477 1137 100         DBD_ATTRIBS_CHECK("_prepare", sth, attribs);
    100          
    50          
    50          
    50          
    50          
    0          
    0          
478             #ifdef dbd_st_prepare_sv
479 1137 100         ST(0) = dbd_st_prepare_sv(sth, imp_sth, statement, attribs) ? &PL_sv_yes : &PL_sv_no;
480             #else
481             ST(0) = dbd_st_prepare(sth, imp_sth, SvPV_nolen(statement), attribs) ? &PL_sv_yes : &PL_sv_no;
482             #endif
483             }
484              
485              
486             #ifdef dbd_st_rows
487              
488             void
489             rows(sth)
490             SV * sth
491             CODE:
492 117           D_imp_sth(sth);
493 117           XST_mIV(0, dbd_st_rows(sth, imp_sth));
494              
495             #endif /* dbd_st_rows */
496              
497              
498             #ifdef dbd_st_bind_col
499              
500             void
501             bind_col(sth, col, ref, attribs=Nullsv)
502             SV * sth
503             SV * col
504             SV * ref
505             SV * attribs
506             CODE:
507             {
508 235           IV sql_type = 0;
509 235           D_imp_sth(sth);
510 235 50         if (SvGMAGICAL(ref))
511 0           mg_get(ref);
512 235 100         if (attribs) {
513 145 100         if (SvNIOK(attribs)) {
514 1 50         sql_type = SvIV(attribs);
515 1           attribs = Nullsv;
516             }
517             else {
518             SV **svp;
519 144 50         DBD_ATTRIBS_CHECK("bind_col", sth, attribs);
    100          
    50          
    50          
    50          
    50          
    0          
    0          
520             /* XXX we should perhaps complain if TYPE is not SvNIOK */
521 144 100         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
    50          
    50          
    100          
    50          
522             }
523             }
524 235           switch(dbd_st_bind_col(sth, imp_sth, col, ref, sql_type, attribs)) {
525 0           case 2: ST(0) = &PL_sv_yes; /* job done completely */
526 0           break;
527             case 1: /* fallback to DBI default */
528 235           ST(0) = (DBIc_DBISTATE(imp_sth)->bind_col(sth, col, ref, attribs))
529 235 50         ? &PL_sv_yes : &PL_sv_no;
530 235           break;
531 0           default: ST(0) = &PL_sv_no; /* dbd_st_bind_col has called set_err */
532 0           break;
533             }
534             }
535              
536             #endif /* dbd_st_bind_col */
537              
538             void
539             bind_param(sth, param, value, attribs=Nullsv)
540             SV * sth
541             SV * param
542             SV * value
543             SV * attribs
544             CODE:
545             {
546 271           IV sql_type = 0;
547 271           D_imp_sth(sth);
548 271 50         if (SvGMAGICAL(value))
549 0           mg_get(value);
550 271 100         if (attribs) {
551 229 100         if (SvNIOK(attribs)) {
552 162 50         sql_type = SvIV(attribs);
553 162           attribs = Nullsv;
554             }
555             else {
556             SV **svp;
557 67 50         DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
    100          
    50          
    50          
    50          
    50          
    0          
    0          
558             /* XXX we should perhaps complain if TYPE is not SvNIOK */
559 67 100         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
    50          
    50          
    100          
    50          
560             }
561             }
562 271           ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, FALSE, 0)
563 271 100         ? &PL_sv_yes : &PL_sv_no;
564             }
565              
566              
567             void
568             bind_param_inout(sth, param, value_ref, maxlen, attribs=Nullsv)
569             SV * sth
570             SV * param
571             SV * value_ref
572             IV maxlen
573             SV * attribs
574             CODE:
575             {
576 0           IV sql_type = 0;
577 0           D_imp_sth(sth);
578             SV *value;
579 0 0         if (!SvROK(value_ref) || SvTYPE(SvRV(value_ref)) > SVt_PVMG)
    0          
580 0           croak("bind_param_inout needs a reference to a scalar value");
581 0           value = SvRV(value_ref);
582 0 0         if (SvREADONLY(value))
583 0           croak("Modification of a read-only value attempted");
584 0 0         if (SvGMAGICAL(value))
585 0           mg_get(value);
586 0 0         if (attribs) {
587 0 0         if (SvNIOK(attribs)) {
588 0 0         sql_type = SvIV(attribs);
589 0           attribs = Nullsv;
590             }
591             else {
592             SV **svp;
593 0 0         DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
594 0 0         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
    0          
    0          
    0          
    0          
595             }
596             }
597 0           ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, TRUE, maxlen)
598 0 0         ? &PL_sv_yes : &PL_sv_no;
599             }
600              
601              
602             void
603             execute(sth, ...)
604             SV * sth
605             CODE:
606 952           D_imp_sth(sth);
607             IV retval;
608 952 100         if (items > 1) { /* need to bind params */
609 357 50         if (!dbdxst_bind_params(sth, imp_sth, items, ax) ) {
610 0           XSRETURN_UNDEF;
611             }
612             }
613             /* XXX this code is duplicated in selectrow_arrayref above */
614 952           DBIc_ROW_COUNT(imp_sth) = 0;
615 952           retval = dbd_st_execute(sth, imp_sth); /* might be dbd_st_execute_iv via macro */
616             /* remember that dbd_st_execute must return <= -2 for error */
617 952 100         if (retval == 0) /* ok with no rows affected */
618 462           XST_mPV(0, "0E0"); /* (true but zero) */
619 490 100         else if (retval < -1) /* -1 == unknown number of rows */
620 11           XST_mUNDEF(0); /* <= -2 means error */
621             else
622 479           XST_mIV(0, retval); /* typically 1, rowcount or -1 */
623              
624              
625             #ifdef dbd_st_execute_for_fetch
626              
627             void
628             execute_for_fetch(sth, fetch_tuple_sub, tuple_status = Nullsv)
629             SV * sth
630             SV * fetch_tuple_sub
631             SV * tuple_status
632             CODE:
633             {
634             D_imp_sth(sth);
635             ST(0) = dbd_st_execute_for_fetch(sth, imp_sth, fetch_tuple_sub, tuple_status);
636             }
637              
638             #endif
639              
640              
641              
642             void
643             fetchrow_arrayref(sth)
644             SV * sth
645             ALIAS:
646             fetch = 1
647             CODE:
648 1189           D_imp_sth(sth);
649             AV *av;
650             PERL_UNUSED_VAR(ix);
651 1189           av = dbd_st_fetch(sth, imp_sth);
652 1189 100         ST(0) = (av) ? sv_2mortal(newRV((SV *)av)) : &PL_sv_undef;
653              
654              
655             void
656             fetchrow_array(sth)
657             SV * sth
658             ALIAS:
659             fetchrow = 1
660             PPCODE:
661 44           D_imp_sth(sth);
662             AV *av;
663 44           av = dbd_st_fetch(sth, imp_sth);
664 44 100         if (av) {
665             int i;
666 34 50         int num_fields = AvFILL(av)+1;
667 34 50         EXTEND(sp, num_fields);
    50          
668 84 100         for(i=0; i < num_fields; ++i) {
669 50           PUSHs(AvARRAY(av)[i]);
670             }
671             PERL_UNUSED_VAR(ix);
672             }
673              
674              
675             void
676             fetchall_arrayref(sth, slice=&PL_sv_undef, batch_row_count=&PL_sv_undef)
677             SV * sth
678             SV * slice
679             SV * batch_row_count
680             CODE:
681 112 100         if (SvOK(slice)) { /* fallback to perl implementation */
    50          
    50          
682 47           SV *tmp = dbixst_bounce_method("DBD::SQLeet::st::SUPER::fetchall_arrayref", 3);
683 47           SPAGAIN;
684 47           ST(0) = tmp;
685             }
686             else {
687 18           SV *tmp = dbdxst_fetchall_arrayref(sth, slice, batch_row_count);
688 18           SPAGAIN;
689 18           ST(0) = tmp;
690             }
691              
692              
693             void
694             finish(sth)
695             SV * sth
696             CODE:
697 61           D_imp_sth(sth);
698 61           D_imp_dbh_from_sth;
699 61 100         if (!DBIc_ACTIVE(imp_sth)) {
700             /* No active statement to finish */
701 44           XSRETURN_YES;
702             }
703 17 50         if (!DBIc_ACTIVE(imp_dbh)) {
704             /* Either an explicit disconnect() or global destruction */
705             /* has disconnected us from the database. Finish is meaningless */
706 0 0         DBIc_ACTIVE_off(imp_sth);
    0          
    0          
    0          
    0          
707 0           XSRETURN_YES;
708             }
709             #ifdef dbd_st_finish3
710 17 50         ST(0) = dbd_st_finish3(sth, imp_sth, 0) ? &PL_sv_yes : &PL_sv_no;
711             #else
712             ST(0) = dbd_st_finish(sth, imp_sth) ? &PL_sv_yes : &PL_sv_no;
713             #endif
714              
715              
716             void
717             blob_read(sth, field, offset, len, destrv=Nullsv, destoffset=0)
718             SV * sth
719             int field
720             long offset
721             long len
722             SV * destrv
723             long destoffset
724             CODE:
725             {
726 0           D_imp_sth(sth);
727 0 0         if (!destrv)
728 0           destrv = sv_2mortal(newRV(sv_2mortal(newSV(0))));
729 0 0         if (dbd_st_blob_read(sth, imp_sth, field, offset, len, destrv, destoffset))
730 0           ST(0) = SvRV(destrv);
731 0           else ST(0) = &PL_sv_undef;
732             }
733              
734              
735             void
736             STORE(sth, keysv, valuesv)
737             SV * sth
738             SV * keysv
739             SV * valuesv
740             CODE:
741 5           D_imp_sth(sth);
742 5 50         if (SvGMAGICAL(valuesv))
743 0           mg_get(valuesv);
744 5           ST(0) = &PL_sv_yes;
745 5 50         if (!dbd_st_STORE_attrib(sth, imp_sth, keysv, valuesv))
746 5 50         if (!DBIc_DBISTATE(imp_sth)->set_attr(sth, keysv, valuesv))
747 0           ST(0) = &PL_sv_no;
748              
749              
750             # FETCH renamed and ALIAS'd to avoid case clash on VMS :-(
751             void
752             FETCH_attrib(sth, keysv)
753             SV * sth
754             SV * keysv
755             ALIAS:
756             FETCH = 1
757             CODE:
758 885           D_imp_sth(sth);
759             SV *valuesv;
760             PERL_UNUSED_VAR(ix);
761 885           valuesv = dbd_st_FETCH_attrib(sth, imp_sth, keysv);
762 885 100         if (!valuesv)
763 199           valuesv = DBIc_DBISTATE(imp_sth)->get_attr(sth, keysv);
764 885           ST(0) = valuesv; /* dbd_st_FETCH_attrib did sv_2mortal */
765              
766              
767             void
768             DESTROY(sth)
769             SV * sth
770             PPCODE:
771             /* keep in sync with default DESTROY in DBI.xs */
772 1137           D_imp_sth(sth);
773 1137           ST(0) = &PL_sv_yes;
774 1137 100         if (!DBIc_IMPSET(imp_sth)) { /* was never fully set up */
775             STRLEN lna;
776 10 50         if (DBIc_WARN(imp_sth) && !PL_dirty && DBIc_DBISTATE(imp_sth)->debug >= 2)
    50          
    50          
777 10 0         PerlIO_printf(DBIc_LOGPIO(imp_sth),
778             " DESTROY for %s ignored - handle not initialised\n",
779 0           SvPV(sth,lna));
780             }
781             else {
782 1127 50         if (DBIc_IADESTROY(imp_sth)) { /* wants ineffective destroy */
783 0 0         DBIc_ACTIVE_off(imp_sth);
    0          
    0          
    0          
    0          
784 0 0         if (DBIc_DBISTATE(imp_sth)->debug)
785 0 0         PerlIO_printf(DBIc_LOGPIO(imp_sth), " DESTROY %s skipped due to InactiveDestroy\n", SvPV_nolen(sth));
786             }
787 1127 100         if (DBIc_ACTIVE(imp_sth)) {
788 58           D_imp_dbh_from_sth;
789 58 50         if (!PL_dirty && DBIc_ACTIVE(imp_dbh)) {
    100          
790             #ifdef dbd_st_finish3
791 57           dbd_st_finish3(sth, imp_sth, 1);
792             #else
793             dbd_st_finish(sth, imp_sth);
794             #endif
795             }
796             else {
797 1 50         DBIc_ACTIVE_off(imp_sth);
    50          
    50          
    50          
    50          
798             }
799             }
800 1127           dbd_st_destroy(sth, imp_sth);
801             }
802              
803             # end of SQLeet.xst
804             # vim:ts=8:sw=4:et