home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Driver.xst < prev    next >
Encoding:
Text File  |  2003-08-22  |  16.4 KB  |  687 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(DBILOGFP,
  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) && (!dirty || DBIc_DBISTATE(imp_dbh)->debug >= 3))
  349.              warn("Issuing rollback() for database handle being DESTROY'd without explicit disconnect()");
  350.         dbd_db_rollback(dbh, imp_dbh);            /* ROLLBACK! */
  351.         }
  352.         dbd_db_disconnect(dbh, imp_dbh);
  353.         DBIc_ACTIVE_off(imp_dbh);    /* ensure it's off, regardless */
  354.     }
  355.     dbd_db_destroy(dbh, imp_dbh);
  356.     }
  357.  
  358.  
  359. #ifdef dbd_take_imp_data
  360.  
  361. void
  362. take_imp_data(h)
  363.     SV * h
  364.     CODE:
  365.     D_imp_xxh(h);
  366.     ST(0) = (dbd_take_imp_data(h, imp_xxh, NULL))
  367.     ? dbixst_bounce_method("DBD::~DRIVER~::db::SUPER::take_imp_data", items)
  368.     : &sv_undef;
  369.  
  370. #endif
  371.  
  372. #ifdef dbd_db_data_sources
  373.  
  374. void
  375. data_sources(dbh, attr = Nullsv)
  376.     SV *dbh
  377.     SV *attr
  378.     PPCODE:
  379.     {
  380.     D_imp_dbh(dbh);
  381.     AV *av = dbd_db_data_sources(dbh, imp_dbh, attr);
  382.     if (av) {
  383.         int i;
  384.         int n = AvFILL(av)+1;
  385.         EXTEND(sp, n);
  386.         for (i = 0; i < n; ++i) {
  387.         PUSHs(AvARRAY(av)[i]);
  388.         }
  389.     }
  390.     }
  391.  
  392. #endif
  393.  
  394. # -- end of DBD::~DRIVER~::db
  395.  
  396. # ------------------------------------------------------------
  397. # statement interface
  398. # ------------------------------------------------------------
  399. MODULE = DBD::~DRIVER~    PACKAGE = DBD::~DRIVER~::st
  400.  
  401.  
  402. void
  403. _prepare(sth, statement, attribs=Nullsv)
  404.     SV *    sth
  405.     char *    statement
  406.     SV *    attribs
  407.     CODE:
  408.     {
  409.     D_imp_sth(sth);
  410.     DBD_ATTRIBS_CHECK("_prepare", sth, attribs);
  411.     ST(0) = dbd_st_prepare(sth, imp_sth, statement, attribs) ? &sv_yes : &sv_no;
  412.     }
  413.  
  414.  
  415. #ifdef dbd_st_rows
  416.  
  417. void
  418. rows(sth)
  419.     SV *    sth
  420.     CODE:
  421.     D_imp_sth(sth);
  422.     XST_mIV(0, dbd_st_rows(sth, imp_sth));
  423.  
  424. #endif /* dbd_st_rows */
  425.  
  426.  
  427. void
  428. bind_param(sth, param, value, attribs=Nullsv)
  429.     SV *    sth
  430.     SV *    param
  431.     SV *    value
  432.     SV *    attribs
  433.     CODE:
  434.     {
  435.     IV sql_type = 0;
  436.     D_imp_sth(sth);
  437.     if (SvGMAGICAL(value))
  438.     mg_get(value);
  439.     if (attribs) {
  440.     if (SvNIOK(attribs)) {
  441.         sql_type = SvIV(attribs);
  442.         attribs = Nullsv;
  443.     }
  444.     else {
  445.         SV **svp;
  446.         DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
  447.         /* XXX we should perhaps complain if TYPE is not SvNIOK */
  448.         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
  449.     }
  450.     }
  451.     ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, FALSE, 0)
  452.         ? &sv_yes : &sv_no;
  453.     }
  454.  
  455.  
  456. void
  457. bind_param_inout(sth, param, value_ref, maxlen, attribs=Nullsv)
  458.     SV *    sth
  459.     SV *    param
  460.     SV *    value_ref
  461.     IV         maxlen
  462.     SV *    attribs
  463.     CODE:
  464.     {
  465.     IV sql_type = 0;
  466.     D_imp_sth(sth);
  467.     SV *value;
  468.     if (!SvROK(value_ref) || SvTYPE(SvRV(value_ref)) > SVt_PVMG)
  469.     croak("bind_param_inout needs a reference to a scalar value");
  470.     value = SvRV(value_ref);
  471.     if (SvREADONLY(value))
  472.     croak("Modification of a read-only value attempted");
  473.     if (SvGMAGICAL(value))
  474.     mg_get(value);
  475.     if (attribs) {
  476.     if (SvNIOK(attribs)) {
  477.         sql_type = SvIV(attribs);
  478.         attribs = Nullsv;
  479.     }
  480.     else {
  481.         SV **svp;
  482.         DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
  483.         DBD_ATTRIB_GET_IV(attribs, "TYPE",4, svp, sql_type);
  484.     }
  485.     }
  486.     ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, TRUE, maxlen)
  487.         ? &sv_yes : &sv_no;
  488.     }
  489.  
  490.  
  491. void
  492. execute(sth, ...)
  493.     SV *    sth
  494.     CODE:
  495.     D_imp_sth(sth);
  496.     int retval;
  497.     if (items > 1) {    /* need to bind params */
  498.     if (!dbdxst_bind_params(sth, imp_sth, items, ax) ) {
  499.         XSRETURN_UNDEF;
  500.     }
  501.     }
  502.     /* XXX this code is duplicated in selectrow_arrayref above    */
  503.     if (DBIc_ROW_COUNT(imp_sth) > 0) /* reset for re-execute */
  504.     DBIc_ROW_COUNT(imp_sth) = 0;
  505.     retval = dbd_st_execute(sth, imp_sth);
  506.     /* remember that dbd_st_execute must return <= -2 for error    */
  507.     if (retval == 0)        /* ok with no rows affected    */
  508.     XST_mPV(0, "0E0");    /* (true but zero)        */
  509.     else if (retval < -1)    /* -1 == unknown number of rows    */
  510.     XST_mUNDEF(0);        /* <= -2 means error           */
  511.     else
  512.     XST_mIV(0, retval);    /* typically 1, rowcount or -1    */
  513.  
  514.  
  515. #ifdef dbd_st_execute_for_fetch
  516.  
  517. void
  518. execute_for_fetch(sth, fetch_tuple_sub, tuple_status = Nullsv)
  519.     SV *    sth
  520.     SV *    fetch_tuple_sub
  521.     SV *    tuple_status
  522.     CODE:
  523.     {
  524.     D_imp_sth(sth);
  525.     ST(0) = dbd_st_execute_for_fetch(sth, imp_sth, fetch_tuple_sub, tuple_status);
  526.     }
  527.  
  528. #endif
  529.  
  530.  
  531.  
  532. void
  533. fetchrow_arrayref(sth)
  534.     SV *    sth
  535.     ALIAS:
  536.     fetch = 1
  537.     CODE:
  538.     D_imp_sth(sth);
  539.     AV *av;
  540.     if (0) ix = ix;    /* avoid unused variable warning */
  541.     av = dbd_st_fetch(sth, imp_sth);
  542.     ST(0) = (av) ? sv_2mortal(newRV((SV *)av)) : &PL_sv_undef;
  543.  
  544.  
  545. void
  546. fetchrow_array(sth)
  547.     SV *    sth
  548.     ALIAS:
  549.     fetchrow = 1
  550.     PPCODE:
  551.     D_imp_sth(sth);
  552.     AV *av;
  553.     av = dbd_st_fetch(sth, imp_sth);
  554.     if (av) {
  555.     int i;
  556.     int num_fields = AvFILL(av)+1;
  557.     EXTEND(sp, num_fields);
  558.     for(i=0; i < num_fields; ++i) {
  559.         PUSHs(AvARRAY(av)[i]);
  560.     }
  561.     if (0) ix = ix;    /* avoid unused variable warning */
  562.     }
  563.  
  564.  
  565. void
  566. fetchall_arrayref(sth, slice=&PL_sv_undef, batch_row_count=&PL_sv_undef)
  567.     SV *    sth
  568.     SV *    slice
  569.     SV *    batch_row_count
  570.     CODE:
  571.     if (SvOK(slice)) {  /* fallback to perl implementation */
  572.         ST(0) = dbixst_bounce_method("DBD::~DRIVER~::st::SUPER::fetchall_arrayref", 3);
  573.     }
  574.     else {
  575.     ST(0) = dbdxst_fetchall_arrayref(sth, slice, batch_row_count);
  576.     }
  577.  
  578.  
  579. void
  580. finish(sth)
  581.     SV *    sth
  582.     CODE:
  583.     D_imp_sth(sth);
  584.     D_imp_dbh_from_sth;
  585.     if (!DBIc_ACTIVE(imp_sth)) {
  586.     /* No active statement to finish    */
  587.     XSRETURN_YES;
  588.     }
  589.     if (!DBIc_ACTIVE(imp_dbh)) {
  590.     /* Either an explicit disconnect() or global destruction    */
  591.     /* has disconnected us from the database. Finish is meaningless    */
  592.     DBIc_ACTIVE_off(imp_sth);
  593.     XSRETURN_YES;
  594.     }
  595. #ifdef dbd_st_finish3
  596.     ST(0) = dbd_st_finish3(sth, imp_sth, 0) ? &sv_yes : &sv_no;
  597. #else
  598.     ST(0) = dbd_st_finish(sth, imp_sth) ? &sv_yes : &sv_no;
  599. #endif
  600.  
  601.  
  602. void
  603. blob_read(sth, field, offset, len, destrv=Nullsv, destoffset=0)
  604.     SV *        sth
  605.     int field
  606.     long        offset
  607.     long        len
  608.     SV *        destrv
  609.     long        destoffset
  610.     CODE:
  611.     {
  612.     D_imp_sth(sth);
  613.     if (!destrv)
  614.         destrv = sv_2mortal(newRV(sv_2mortal(newSV(0))));
  615.     if (dbd_st_blob_read(sth, imp_sth, field, offset, len, destrv, destoffset))
  616.          ST(0) = SvRV(destrv);
  617.     else ST(0) = &PL_sv_undef;
  618.     }
  619.  
  620.  
  621. void
  622. STORE(sth, keysv, valuesv)
  623.     SV *    sth
  624.     SV *    keysv
  625.     SV *    valuesv
  626.     CODE:
  627.     D_imp_sth(sth);
  628.     if (SvGMAGICAL(valuesv))
  629.     mg_get(valuesv);
  630.     ST(0) = &sv_yes;
  631.     if (!dbd_st_STORE_attrib(sth, imp_sth, keysv, valuesv))
  632.     if (!DBIc_DBISTATE(imp_sth)->set_attr(sth, keysv, valuesv))
  633.         ST(0) = &sv_no;
  634.  
  635.  
  636. # FETCH renamed and ALIAS'd to avoid case clash on VMS :-(
  637. void
  638. FETCH_attrib(sth, keysv)
  639.     SV *    sth
  640.     SV *    keysv
  641.     ALIAS:
  642.     FETCH = 1
  643.     CODE:
  644.     D_imp_sth(sth);
  645.     SV *valuesv;
  646.     if (0) ix = ix;    /* avoid unused variable warning */
  647.     valuesv = dbd_st_FETCH_attrib(sth, imp_sth, keysv);
  648.     if (!valuesv)
  649.     valuesv = DBIc_DBISTATE(imp_sth)->get_attr(sth, keysv);
  650.     ST(0) = valuesv;    /* dbd_st_FETCH_attrib did sv_2mortal    */
  651.  
  652.  
  653. void
  654. DESTROY(sth)
  655.     SV *    sth
  656.     PPCODE:
  657.     D_imp_sth(sth);
  658.     ST(0) = &sv_yes;
  659.     if (!DBIc_IMPSET(imp_sth)) {    /* was never fully set up    */
  660.     STRLEN lna;
  661.     if (DBIc_WARN(imp_sth) && !dirty && DBIc_DBISTATE(imp_sth)->debug >= 2)
  662.          PerlIO_printf(DBIc_LOGPIO(imp_sth),
  663.         "Statement handle %s DESTROY ignored - never set up\n",
  664.             SvPV(sth,lna));
  665.     }
  666.     else {
  667.         if (DBIc_IADESTROY(imp_sth)) { /* want's ineffective destroy    */
  668.             DBIc_ACTIVE_off(imp_sth);
  669.         }
  670.     if (DBIc_ACTIVE(imp_sth)) {
  671.         D_imp_dbh_from_sth;
  672.         if (!dirty && DBIc_ACTIVE(imp_dbh)) {
  673. #ifdef dbd_st_finish3
  674.         dbd_st_finish3(sth, imp_sth, 1);
  675. #else
  676.         dbd_st_finish(sth, imp_sth);
  677. #endif
  678.         }
  679.         else {
  680.         DBIc_ACTIVE_off(imp_sth);
  681.         }
  682.     }
  683.     dbd_st_destroy(sth, imp_sth);
  684.     }
  685.  
  686. # end of ~DRIVER~.xst
  687.