home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Driver.xst < prev    next >
Encoding:
Text File  |  2004-02-26  |  18.1 KB  |  730 lines

  1. #  $Id: Driver.xst,v 11.14 2003/08/22 21:23:39 timbo Exp $
  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.  
  12. MODULE = DBD::~DRIVER~    PACKAGE = DBD::~DRIVER~
  13.  
  14. REQUIRE:    1.929
  15. PROTOTYPES: DISABLE
  16.  
  17. BOOT:
  18.     items = 0;  /* avoid 'unused variable' warning */
  19.     DBISTATE_INIT;
  20.     /* XXX this interface will change: */
  21.     DBI_IMP_SIZE("DBD::~DRIVER~::dr::imp_data_size", sizeof(imp_drh_t));
  22.     DBI_IMP_SIZE("DBD::~DRIVER~::db::imp_data_size", sizeof(imp_dbh_t));
  23.     DBI_IMP_SIZE("DBD::~DRIVER~::st::imp_data_size", sizeof(imp_sth_t));
  24.     dbd_init(DBIS);
  25.  
  26.  
  27. # ------------------------------------------------------------
  28. # driver level interface
  29. # ------------------------------------------------------------
  30. MODULE = DBD::~DRIVER~    PACKAGE = DBD::~DRIVER~::dr
  31.  
  32.  
  33. #ifdef dbd_discon_all
  34.  
  35. # disconnect_all renamed and ALIAS'd to avoid length clash on VMS :-(
  36. void
  37. discon_all_(drh)
  38.     SV *    drh
  39.     ALIAS:
  40.     disconnect_all = 1
  41.     CODE:
  42.     D_imp_drh(drh);
  43.     if (0) ix = ix;    /* avoid unused variable warning */
  44.     ST(0) = dbd_discon_all(drh, imp_drh) ? &sv_yes : &sv_no;
  45.  
  46. #endif /* dbd_discon_all */
  47.  
  48.  
  49. #ifdef dbd_dr_data_sources
  50.  
  51. void
  52. data_sources(drh, attr = Nullsv)
  53.     SV *drh
  54.     SV *attr
  55.     PPCODE:
  56.     {
  57.     D_imp_drh(drh);
  58.     AV *av = dbd_dr_data_sources(drh, imp_drh, attr);
  59.     if (av) {
  60.         int i;
  61.         int n = AvFILL(av)+1;
  62.         EXTEND(sp, n);
  63.         for (i = 0; i < n; ++i) {
  64.         PUSHs(AvARRAY(av)[i]);
  65.         }
  66.     }
  67.     }
  68.  
  69. #endif
  70.  
  71.  
  72. # ------------------------------------------------------------
  73. # database level interface
  74. # ------------------------------------------------------------
  75. MODULE = DBD::~DRIVER~    PACKAGE = DBD::~DRIVER~::db
  76.  
  77.  
  78. void
  79. _login(dbh, dbname, username, password, attribs=Nullsv)
  80.     SV *    dbh
  81.     char *    dbname
  82.     SV *    username
  83.     SV *    password
  84.     SV *    attribs
  85.     CODE:
  86.     {
  87.     STRLEN lna;
  88.     D_imp_dbh(dbh);
  89.     char *u = (SvOK(username)) ? SvPV(username,lna) : "";
  90.     char *p = (SvOK(password)) ? SvPV(password,lna) : "";
  91. #ifdef dbd_db_login6
  92.     ST(0) = dbd_db_login6(dbh, imp_dbh, dbname, u, p, attribs) ? &sv_yes : &sv_no;
  93. #else
  94.     ST(0) = dbd_db_login( dbh, imp_dbh, dbname, u, p) ? &sv_yes : &sv_no;
  95. #endif
  96.     }
  97.  
  98.  
  99. void
  100. selectall_arrayref(...)
  101.     PREINIT:
  102.     SV *sth;
  103.     SV **maxrows_svp;
  104.     SV **tmp_svp;
  105.     SV *attr = &PL_sv_undef;
  106.     imp_sth_t *imp_sth;
  107.     CODE:
  108.     if (items > 2) {
  109.     attr = ST(2);
  110.     if (SvROK(attr) &&
  111.         (DBD_ATTRIB_TRUE(attr,"Slice",5,tmp_svp) || DBD_ATTRIB_TRUE(attr,"Columns",7,tmp_svp))
  112.     ) {
  113.         /* fallback to perl implementation */
  114.         ST(0) = dbixst_bounce_method("DBD::~DRIVER~::db::SUPER::selectall_arrayref", items);
  115.         XSRETURN(1);
  116.     }
  117.     }
  118.     /* --- prepare --- */
  119.     if (SvROK(ST(1))) {
  120.     sth = ST(1);
  121.     }
  122.     else {
  123.     sth = dbixst_bounce_method("prepare", 3);
  124.     if (!SvROK(sth))
  125.         XSRETURN_UNDEF;
  126.     }
  127.     imp_sth = (imp_sth_t*)(DBIh_COM(sth));
  128.     /* --- bind_param --- */
  129.     if (items > 3) {    /* need to bind params before execute */
  130.         if (!dbdxst_bind_params(sth, imp_sth, items-2, ax+2) ) {
  131.             XSRETURN_UNDEF;
  132.         }
  133.     }
  134.     /* --- execute --- */
  135.     DBIc_ROW_COUNT(imp_sth) = 0;
  136.     if ( dbd_st_execute(sth, imp_sth) <= -2 ) { /* -2 == error */
  137.         XSRETURN_UNDEF;
  138.     }
  139.     /* --- fetchall --- */
  140.     maxrows_svp = DBD_ATTRIB_GET_SVP(attr, "MaxRows", 7);
  141.     ST(0) = dbdxst_fetchall_arrayref(sth, &PL_sv_undef, (maxrows_svp) ? *maxrows_svp : &PL_sv_undef);
  142.  
  143.  
  144. void
  145. selectrow_arrayref(...)
  146.     ALIAS:
  147.     selectrow_array = 1
  148.     PREINIT:
  149.     imp_sth_t *imp_sth;
  150.     SV *sth;
  151.     AV *row_av;
  152.     PPCODE:
  153.     if (SvROK(ST(1))) {
  154.     sth = ST(1);
  155.     }
  156.     else {
  157.     /* --- prepare --- */
  158.     sth = dbixst_bounce_method("prepare", 3);
  159.     if (!SvROK(sth))
  160.         XSRETURN_UNDEF;
  161.     }
  162.     imp_sth = (imp_sth_t*)(DBIh_COM(sth));
  163.     /* --- bind_param --- */
  164.     if (items > 3) {    /* need to bind params before execute */
  165.     if (!dbdxst_bind_params(sth, imp_sth, items-2, ax+2) ) {
  166.         XSRETURN_UNDEF;
  167.     }
  168.     }
  169.     /* --- execute --- */
  170.     DBIc_ROW_COUNT(imp_sth) = 0;
  171.     if ( dbd_st_execute(sth, imp_sth) <= -2 ) {    /* -2 == error */
  172.         XSRETURN_UNDEF;
  173.     }
  174.     /* --- fetchrow_arrayref --- */
  175.     row_av = dbd_st_fetch(sth, imp_sth);
  176.     if (!row_av) {
  177.     if (GIMME == G_SCALAR)
  178.         PUSHs(&PL_sv_undef);
  179.     }
  180.     else if (ix == 1) { /* selectrow_array */
  181.     int i;
  182.     int num_fields = AvFILL(row_av)+1;
  183.     if (GIMME == G_SCALAR)
  184.         num_fields = 1; /* return just first field */
  185.     EXTEND(sp, num_fields);
  186.     for(i=0; i < num_fields; ++i) {
  187.         PUSHs(AvARRAY(row_av)[i]);
  188.     }
  189.     }
  190.     else {
  191.     PUSHs( sv_2mortal(newRV((SV *)row_av)) );
  192.     }
  193.     /* --- finish --- */
  194. #ifdef dbd_st_finish3
  195.     dbd_st_finish3(sth, imp_sth, 0);
  196. #else
  197.     dbd_st_finish(sth, imp_sth);
  198. #endif
  199.  
  200.  
  201. #ifdef dbd_db_do4 /* deebeedee-deebee-doo, deebee-doobee-dah? */
  202.  
  203. void
  204. do(dbh, statement, params = Nullsv)
  205.     SV *    dbh
  206.     char *    statement
  207.     SV *    params
  208.     CODE:
  209.     {
  210.     D_imp_dbh(dbh);
  211.     IV retval;
  212.     retval = dbd_db_do4(dbh, imp_dbh, statement, params);
  213.     /* remember that dbd_db_do4 must return <= -2 for error    */
  214.     if (retval == 0)        /* ok with no rows affected    */
  215.     XST_mPV(0, "0E0");    /* (true but zero)        */
  216.     else if (retval < -1)    /* -1 == unknown number of rows    */
  217.     XST_mUNDEF(0);        /* <= -2 means error           */
  218.     else
  219.     XST_mIV(0, retval);    /* typically 1, rowcount or -1    */
  220.     }
  221.  
  222. #endif
  223.  
  224.  
  225. #ifdef dbd_db_last_insert_id
  226.  
  227. void
  228. last_insert_id(dbh, catalog, schema, table, field, attr=Nullsv)
  229.     SV *    dbh
  230.     SV *    catalog
  231.     SV *    schema
  232.     SV *    table
  233.     SV *    field
  234.     SV *    attr
  235.     CODE:
  236.     {
  237.     D_imp_dbh(dbh);
  238.     ST(0) = dbd_db_last_insert_id(dbh, imp_dbh, catalog, schema, table, field, attr);
  239.     }
  240.  
  241. #endif
  242.  
  243.  
  244. void
  245. commit(dbh)
  246.     SV *    dbh
  247.     CODE:
  248.     D_imp_dbh(dbh);
  249.     if (DBIc_has(imp_dbh,DBIcf_AutoCommit) && DBIc_WARN(imp_dbh))
  250.     warn("commit ineffective with AutoCommit enabled");
  251.     ST(0) = dbd_db_commit(dbh, imp_dbh) ? &sv_yes : &sv_no;
  252.  
  253.  
  254. void
  255. rollback(dbh)
  256.     SV *    dbh
  257.     CODE:
  258.     D_imp_dbh(dbh);
  259.     if (DBIc_has(imp_dbh,DBIcf_AutoCommit) && DBIc_WARN(imp_dbh))
  260.     warn("rollback ineffective with AutoCommit enabled");
  261.     ST(0) = dbd_db_rollback(dbh, imp_dbh) ? &sv_yes : &sv_no;
  262.  
  263.  
  264. void
  265. disconnect(dbh)
  266.     SV *    dbh
  267.     CODE:
  268.     D_imp_dbh(dbh);
  269.     if ( !DBIc_ACTIVE(imp_dbh) ) {
  270.     XSRETURN_YES;
  271.     }
  272.     /* pre-disconnect checks and tidy-ups */
  273.     if (DBIc_CACHED_KIDS(imp_dbh)) {
  274.     SvREFCNT_dec(DBIc_CACHED_KIDS(imp_dbh));      /* cast them to the winds    */
  275.     DBIc_CACHED_KIDS(imp_dbh) = Nullhv;
  276.     }
  277.     /* Check for disconnect() being called whilst refs to cursors    */
  278.     /* still exists. This possibly needs some more thought.        */
  279.     if (DBIc_ACTIVE_KIDS(imp_dbh) && DBIc_WARN(imp_dbh) && !dirty) {
  280.     STRLEN lna;
  281.     char *plural = (DBIc_ACTIVE_KIDS(imp_dbh)==1) ? "" : "s";
  282.     warn("%s->disconnect invalidates %d active statement handle%s %s",
  283.         SvPV(dbh,lna), (int)DBIc_ACTIVE_KIDS(imp_dbh), plural,
  284.         "(either destroy statement handles or call finish on them before disconnecting)");
  285.     }
  286.     ST(0) = dbd_db_disconnect(dbh, imp_dbh) ? &sv_yes : &sv_no;
  287.     DBIc_ACTIVE_off(imp_dbh);    /* ensure it's off, regardless */
  288.  
  289.  
  290. void
  291. STORE(dbh, keysv, valuesv)
  292.     SV *    dbh
  293.     SV *    keysv
  294.     SV *    valuesv
  295.     CODE:
  296.     D_imp_dbh(dbh);
  297.     if (SvGMAGICAL(valuesv))
  298.     mg_get(valuesv);
  299.     ST(0) = &sv_yes;
  300.     if (!dbd_db_STORE_attrib(dbh, imp_dbh, keysv, valuesv))
  301.     if (!DBIc_DBISTATE(imp_dbh)->set_attr(dbh, keysv, valuesv))
  302.         ST(0) = &sv_no;
  303.  
  304.  
  305. void
  306. FETCH(dbh, keysv)
  307.     SV *    dbh
  308.     SV *    keysv
  309.     CODE:
  310.     D_imp_dbh(dbh);
  311.     SV *valuesv = dbd_db_FETCH_attrib(dbh, imp_dbh, keysv);
  312.     if (!valuesv)
  313.     valuesv = DBIc_DBISTATE(imp_dbh)->get_attr(dbh, keysv);
  314.     ST(0) = valuesv;    /* dbd_db_FETCH_attrib did sv_2mortal    */
  315.  
  316.  
  317. void
  318. DESTROY(dbh)
  319.     SV *    dbh
  320.     PPCODE:
  321.     D_imp_dbh(dbh);
  322.     ST(0) = &sv_yes;
  323.     if (!DBIc_IMPSET(imp_dbh)) {    /* was never fully set up    */
  324.     STRLEN lna;
  325.     if (DBIc_WARN(imp_dbh) && !dirty && DBIc_DBISTATE(imp_dbh)->debug >= 2)
  326.          PerlIO_printf(DBIc_LOGPIO(imp_dbh),
  327.         "         DESTROY for %s ignored - handle not initialised\n",
  328.             SvPV(dbh,lna));
  329.     }
  330.     else {
  331.     /* pre-disconnect checks and tidy-ups */
  332.     if (DBIc_CACHED_KIDS(imp_dbh)) {
  333.         SvREFCNT_dec(DBIc_CACHED_KIDS(imp_dbh));  /* cast them to the winds    */
  334.         DBIc_CACHED_KIDS(imp_dbh) = Nullhv;
  335.     }
  336.         if (DBIc_IADESTROY(imp_dbh)) {          /* want's ineffective destroy    */
  337.             DBIc_ACTIVE_off(imp_dbh);
  338.         }
  339.     if (DBIc_ACTIVE(imp_dbh)) {
  340.         /* The application has not explicitly disconnected. That's bad.    */
  341.         /* To ensure integrity we *must* issue a rollback. This will be    */
  342.         /* harmless    if the application has issued a commit. If it hasn't    */
  343.         /* then it'll ensure integrity. Consider a Ctrl-C killing perl    */
  344.         /* between two statements that must be executed as a transaction.    */
  345.         /* Perl will call DESTROY on the dbh and, if we don't rollback,    */
  346.         /* the server may automatically commit! Bham! Corrupt database!    */
  347.         if (!DBIc_has(imp_dbh,DBIcf_AutoCommit)) {
  348.         if (DBIc_WARN(imp_dbh)
  349.         &&  DBIc_is(imp_dbh, DBIcf_Executed)
  350.         && (!dirty || DBIc_DBISTATE(imp_dbh)->debug >= 3)
  351.         )
  352.              warn("Issuing rollback() for database handle being DESTROY'd without explicit disconnect()");
  353.         dbd_db_rollback(dbh, imp_dbh);            /* ROLLBACK! */
  354.         }
  355.         dbd_db_disconnect(dbh, imp_dbh);
  356.         DBIc_ACTIVE_off(imp_dbh);    /* ensure it's off, regardless */
  357.     }
  358.     dbd_db_destroy(dbh, imp_dbh);
  359.     }
  360.  
  361.  
  362. #ifdef dbd_take_imp_data
  363.  
  364. void
  365. take_imp_data(h)
  366.     SV * h
  367.     CODE:
  368.     D_imp_xxh(h);
  369.     ST(0) = (dbd_take_imp_data(h, imp_xxh, NULL))
  370.     ? dbixst_bounce_method("DBD::~DRIVER~::db::SUPER::take_imp_data", items)
  371.     : &sv_undef;
  372.  
  373. #endif
  374.  
  375. #ifdef dbd_db_data_sources
  376.  
  377. void
  378. data_sources(dbh, attr = Nullsv)
  379.     SV *dbh
  380.     SV *attr
  381.     PPCODE:
  382.     {
  383.     D_imp_dbh(dbh);
  384.     AV *av = dbd_db_data_sources(dbh, imp_dbh, attr);
  385.     if (av) {
  386.         int i;
  387.         int n = AvFILL(av)+1;
  388.         EXTEND(sp, n);
  389.         for (i = 0; i < n; ++i) {
  390.         PUSHs(AvARRAY(av)[i]);
  391.         }
  392.     }
  393.     }
  394.  
  395. #endif
  396.  
  397. # -- end of DBD::~DRIVER~::db
  398.  
  399. # ------------------------------------------------------------
  400. # statement interface
  401. # ------------------------------------------------------------
  402. MODULE = DBD::~DRIVER~    PACKAGE = DBD::~DRIVER~::st
  403.  
  404.  
  405. void
  406. _prepare(sth, statement, attribs=Nullsv)
  407.     SV *    sth
  408.     char *    statement
  409.     SV *    attribs
  410.     CODE:
  411.     {
  412.     D_imp_sth(sth);
  413.     DBD_ATTRIBS_CHECK("_prepare", sth, attribs);
  414.     ST(0) = dbd_st_prepare(sth, imp_sth, statement, attribs) ? &sv_yes : &sv_no;
  415.     }
  416.  
  417.  
  418. #ifdef dbd_st_rows
  419.  
  420. void
  421. rows(sth)
  422.     SV *    sth
  423.     CODE:
  424.     D_imp_sth(sth);
  425.     XST_mIV(0, dbd_st_rows(sth, imp_sth));
  426.  
  427. #endif /* dbd_st_rows */
  428.  
  429.  
  430. #ifdef dbd_st_bind_col
  431.  
  432. void
  433. bind_col(sth, col, ref, attribs=Nullsv)
  434.     SV *    sth
  435.     SV *    col
  436.     SV *    ref
  437.     SV *    attribs
  438.     CODE:
  439.     {
  440.     IV sql_type = 0;
  441.     D_imp_sth(sth);
  442.     if (SvGMAGICAL(ref))
  443.     mg_get(ref);
  444.     if (attribs) {
  445.     if (SvNIOK(attribs)) {
  446.         sql_type = SvIV(attribs);
  447.         attribs = Nullsv;
  448.     }
  449.     else {
  450.         SV **svp;
  451.         DBD_ATTRIBS_CHECK("bind_col", sth, attribs);
  452.         /* XXX we should perhaps complain if TYPE is not SvNIOK */
  453.         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
  454.     }
  455.     }
  456.     switch(dbd_st_bind_col(sth, imp_sth, col, ref, sql_type, attribs)) {
  457.     case 2:    ST(0) = &sv_yes;    /* job done completely */
  458.         break;
  459.     case 1:    /* fallback to DBI default */
  460.         ST(0) = (DBIc_DBISTATE(imp_sth)->bind_col(sth, col, ref, attribs))
  461.             ? &sv_yes : &sv_no;
  462.         break;
  463.     default:    ST(0) = &sv_no;        /* dbd_st_bind_col has called set_err */
  464.         break;
  465.     }
  466.     }
  467.  
  468. #endif /* dbd_st_bind_col */
  469.  
  470. void
  471. bind_param(sth, param, value, attribs=Nullsv)
  472.     SV *    sth
  473.     SV *    param
  474.     SV *    value
  475.     SV *    attribs
  476.     CODE:
  477.     {
  478.     IV sql_type = 0;
  479.     D_imp_sth(sth);
  480.     if (SvGMAGICAL(value))
  481.     mg_get(value);
  482.     if (attribs) {
  483.     if (SvNIOK(attribs)) {
  484.         sql_type = SvIV(attribs);
  485.         attribs = Nullsv;
  486.     }
  487.     else {
  488.         SV **svp;
  489.         DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
  490.         /* XXX we should perhaps complain if TYPE is not SvNIOK */
  491.         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
  492.     }
  493.     }
  494.     ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, FALSE, 0)
  495.         ? &sv_yes : &sv_no;
  496.     }
  497.  
  498.  
  499. void
  500. bind_param_inout(sth, param, value_ref, maxlen, attribs=Nullsv)
  501.     SV *    sth
  502.     SV *    param
  503.     SV *    value_ref
  504.     IV         maxlen
  505.     SV *    attribs
  506.     CODE:
  507.     {
  508.     IV sql_type = 0;
  509.     D_imp_sth(sth);
  510.     SV *value;
  511.     if (!SvROK(value_ref) || SvTYPE(SvRV(value_ref)) > SVt_PVMG)
  512.     croak("bind_param_inout needs a reference to a scalar value");
  513.     value = SvRV(value_ref);
  514.     if (SvREADONLY(value))
  515.     croak("Modification of a read-only value attempted");
  516.     if (SvGMAGICAL(value))
  517.     mg_get(value);
  518.     if (attribs) {
  519.     if (SvNIOK(attribs)) {
  520.         sql_type = SvIV(attribs);
  521.         attribs = Nullsv;
  522.     }
  523.     else {
  524.         SV **svp;
  525.         DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
  526.         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
  527.     }
  528.     }
  529.     ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, TRUE, maxlen)
  530.         ? &sv_yes : &sv_no;
  531.     }
  532.  
  533.  
  534. void
  535. execute(sth, ...)
  536.     SV *    sth
  537.     CODE:
  538.     D_imp_sth(sth);
  539.     int retval;
  540.     if (items > 1) {    /* need to bind params */
  541.     if (!dbdxst_bind_params(sth, imp_sth, items, ax) ) {
  542.         XSRETURN_UNDEF;
  543.     }
  544.     }
  545.     /* XXX this code is duplicated in selectrow_arrayref above    */
  546.     if (DBIc_ROW_COUNT(imp_sth) > 0) /* reset for re-execute */
  547.     DBIc_ROW_COUNT(imp_sth) = 0;
  548.     retval = dbd_st_execute(sth, imp_sth);
  549.     /* remember that dbd_st_execute must return <= -2 for error    */
  550.     if (retval == 0)        /* ok with no rows affected    */
  551.     XST_mPV(0, "0E0");    /* (true but zero)        */
  552.     else if (retval < -1)    /* -1 == unknown number of rows    */
  553.     XST_mUNDEF(0);        /* <= -2 means error           */
  554.     else
  555.     XST_mIV(0, retval);    /* typically 1, rowcount or -1    */
  556.  
  557.  
  558. #ifdef dbd_st_execute_for_fetch
  559.  
  560. void
  561. execute_for_fetch(sth, fetch_tuple_sub, tuple_status = Nullsv)
  562.     SV *    sth
  563.     SV *    fetch_tuple_sub
  564.     SV *    tuple_status
  565.     CODE:
  566.     {
  567.     D_imp_sth(sth);
  568.     ST(0) = dbd_st_execute_for_fetch(sth, imp_sth, fetch_tuple_sub, tuple_status);
  569.     }
  570.  
  571. #endif
  572.  
  573.  
  574.  
  575. void
  576. fetchrow_arrayref(sth)
  577.     SV *    sth
  578.     ALIAS:
  579.     fetch = 1
  580.     CODE:
  581.     D_imp_sth(sth);
  582.     AV *av;
  583.     if (0) ix = ix;    /* avoid unused variable warning */
  584.     av = dbd_st_fetch(sth, imp_sth);
  585.     ST(0) = (av) ? sv_2mortal(newRV((SV *)av)) : &PL_sv_undef;
  586.  
  587.  
  588. void
  589. fetchrow_array(sth)
  590.     SV *    sth
  591.     ALIAS:
  592.     fetchrow = 1
  593.     PPCODE:
  594.     D_imp_sth(sth);
  595.     AV *av;
  596.     av = dbd_st_fetch(sth, imp_sth);
  597.     if (av) {
  598.     int i;
  599.     int num_fields = AvFILL(av)+1;
  600.     EXTEND(sp, num_fields);
  601.     for(i=0; i < num_fields; ++i) {
  602.         PUSHs(AvARRAY(av)[i]);
  603.     }
  604.     if (0) ix = ix;    /* avoid unused variable warning */
  605.     }
  606.  
  607.  
  608. void
  609. fetchall_arrayref(sth, slice=&PL_sv_undef, batch_row_count=&PL_sv_undef)
  610.     SV *    sth
  611.     SV *    slice
  612.     SV *    batch_row_count
  613.     CODE:
  614.     if (SvOK(slice)) {  /* fallback to perl implementation */
  615.         ST(0) = dbixst_bounce_method("DBD::~DRIVER~::st::SUPER::fetchall_arrayref", 3);
  616.     }
  617.     else {
  618.     ST(0) = dbdxst_fetchall_arrayref(sth, slice, batch_row_count);
  619.     }
  620.  
  621.  
  622. void
  623. finish(sth)
  624.     SV *    sth
  625.     CODE:
  626.     D_imp_sth(sth);
  627.     D_imp_dbh_from_sth;
  628.     if (!DBIc_ACTIVE(imp_sth)) {
  629.     /* No active statement to finish    */
  630.     XSRETURN_YES;
  631.     }
  632.     if (!DBIc_ACTIVE(imp_dbh)) {
  633.     /* Either an explicit disconnect() or global destruction    */
  634.     /* has disconnected us from the database. Finish is meaningless    */
  635.     DBIc_ACTIVE_off(imp_sth);
  636.     XSRETURN_YES;
  637.     }
  638. #ifdef dbd_st_finish3
  639.     ST(0) = dbd_st_finish3(sth, imp_sth, 0) ? &sv_yes : &sv_no;
  640. #else
  641.     ST(0) = dbd_st_finish(sth, imp_sth) ? &sv_yes : &sv_no;
  642. #endif
  643.  
  644.  
  645. void
  646. blob_read(sth, field, offset, len, destrv=Nullsv, destoffset=0)
  647.     SV *        sth
  648.     int field
  649.     long        offset
  650.     long        len
  651.     SV *        destrv
  652.     long        destoffset
  653.     CODE:
  654.     {
  655.     D_imp_sth(sth);
  656.     if (!destrv)
  657.         destrv = sv_2mortal(newRV(sv_2mortal(newSV(0))));
  658.     if (dbd_st_blob_read(sth, imp_sth, field, offset, len, destrv, destoffset))
  659.          ST(0) = SvRV(destrv);
  660.     else ST(0) = &PL_sv_undef;
  661.     }
  662.  
  663.  
  664. void
  665. STORE(sth, keysv, valuesv)
  666.     SV *    sth
  667.     SV *    keysv
  668.     SV *    valuesv
  669.     CODE:
  670.     D_imp_sth(sth);
  671.     if (SvGMAGICAL(valuesv))
  672.     mg_get(valuesv);
  673.     ST(0) = &sv_yes;
  674.     if (!dbd_st_STORE_attrib(sth, imp_sth, keysv, valuesv))
  675.     if (!DBIc_DBISTATE(imp_sth)->set_attr(sth, keysv, valuesv))
  676.         ST(0) = &sv_no;
  677.  
  678.  
  679. # FETCH renamed and ALIAS'd to avoid case clash on VMS :-(
  680. void
  681. FETCH_attrib(sth, keysv)
  682.     SV *    sth
  683.     SV *    keysv
  684.     ALIAS:
  685.     FETCH = 1
  686.     CODE:
  687.     D_imp_sth(sth);
  688.     SV *valuesv;
  689.     if (0) ix = ix;    /* avoid unused variable warning */
  690.     valuesv = dbd_st_FETCH_attrib(sth, imp_sth, keysv);
  691.     if (!valuesv)
  692.     valuesv = DBIc_DBISTATE(imp_sth)->get_attr(sth, keysv);
  693.     ST(0) = valuesv;    /* dbd_st_FETCH_attrib did sv_2mortal    */
  694.  
  695.  
  696. void
  697. DESTROY(sth)
  698.     SV *    sth
  699.     PPCODE:
  700.     D_imp_sth(sth);
  701.     ST(0) = &sv_yes;
  702.     if (!DBIc_IMPSET(imp_sth)) {    /* was never fully set up    */
  703.     STRLEN lna;
  704.     if (DBIc_WARN(imp_sth) && !dirty && DBIc_DBISTATE(imp_sth)->debug >= 2)
  705.          PerlIO_printf(DBIc_LOGPIO(imp_sth),
  706.         "         DESTROY for %s ignored - handle not initialised\n",
  707.             SvPV(sth,lna));
  708.     }
  709.     else {
  710.         if (DBIc_IADESTROY(imp_sth)) { /* want's ineffective destroy    */
  711.             DBIc_ACTIVE_off(imp_sth);
  712.         }
  713.     if (DBIc_ACTIVE(imp_sth)) {
  714.         D_imp_dbh_from_sth;
  715.         if (!dirty && DBIc_ACTIVE(imp_dbh)) {
  716. #ifdef dbd_st_finish3
  717.         dbd_st_finish3(sth, imp_sth, 1);
  718. #else
  719.         dbd_st_finish(sth, imp_sth);
  720. #endif
  721.         }
  722.         else {
  723.         DBIc_ACTIVE_off(imp_sth);
  724.         }
  725.     }
  726.     dbd_st_destroy(sth, imp_sth);
  727.     }
  728.  
  729. # end of ~DRIVER~.xst
  730.