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 / DBIXS.h < prev    next >
Encoding:
C/C++ Source or Header  |  2004-03-09  |  20.4 KB  |  511 lines

  1. /* $Id: DBIXS.h,v 11.18 2004/02/01 11:16:16 timbo Exp $
  2.  *
  3.  * Copyright (c) 1994-2002  Tim Bunce  Ireland
  4.  *
  5.  * See COPYRIGHT section in DBI.pm for usage and distribution rights.
  6.  */
  7.  
  8. /* DBI Interface Definitions for DBD Modules */
  9.  
  10. #ifndef DBIXS_VERSION                /* prevent multiple inclusion */
  11.  
  12. #ifndef DBIS
  13. #define DBIS    dbis    /* default name for dbistate_t variable    */
  14. #endif
  15.  
  16. /* first pull in the standard Perl header files for extensions    */
  17. #define PERL_POLLUTE
  18. #include <EXTERN.h>
  19. #include <perl.h>
  20. #include <XSUB.h>
  21.  
  22. #ifdef debug        /* causes problems with DBIS->debug    */
  23. #undef debug
  24. #endif
  25.  
  26. #ifdef std             /* causes problems with STLport <tscheresky@micron.com> */
  27. #undef std
  28. #endif
  29.  
  30. /* Perl backwards compatibility definitions */
  31. #include "dbipport.h"
  32.  
  33. /* DBI SQL_* type definitions */
  34. #include "dbi_sql.h"
  35.  
  36.  
  37. /* The DBIXS_VERSION value will be incremented whenever new code is
  38.  * added to the interface (this file) or significant changes are made.
  39.  * It's primary goal is to allow newer drivers to compile against an
  40.  * older installed DBI. This is mainly an issue whilst the API grows
  41.  * and learns from the needs of various drivers.  See also the
  42.  * DBISTATE_VERSION macro below. You can think of DBIXS_VERSION as
  43.  * being a compile time check and DBISTATE_VERSION as a runtime check.
  44.  */
  45. #define DBIXS_VERSION 93
  46.  
  47. #ifdef NEED_DBIXS_VERSION
  48. #if NEED_DBIXS_VERSION > DBIXS_VERSION
  49. error You_need_to_upgrade_your_DBI_module_before_building_this_driver
  50. #endif
  51. #else
  52. #define NEED_DBIXS_VERSION DBIXS_VERSION
  53. #endif
  54.  
  55.  
  56. #define DBI_LOCK
  57. #define DBI_UNLOCK
  58.  
  59. #ifndef DBI_NO_THREADS
  60. #ifdef USE_ITHREADS
  61. #define DBI_USE_THREADS
  62. #endif /* USE_ITHREADS */
  63. #endif /* DBI_NO_THREADS */
  64.  
  65.  
  66. /* forward struct declarations                        */
  67.  
  68. typedef struct dbistate_st dbistate_t;
  69. /* implementor needs to define actual struct { dbih_??c_t com; ... }*/
  70. typedef struct imp_drh_st imp_drh_t;    /* driver            */
  71. typedef struct imp_dbh_st imp_dbh_t;    /* database            */
  72. typedef struct imp_sth_st imp_sth_t;    /* statement            */
  73. typedef struct imp_fdh_st imp_fdh_t;    /* field descriptor        */
  74. typedef struct imp_xxh_st imp_xxh_t;    /* any (defined below)        */
  75. #define DBI_imp_data_ imp_xxh_t        /* friendly for take_imp_data    */
  76.  
  77.  
  78.  
  79. /* --- DBI Handle Common Data Structure (all handles have one) ---    */
  80.  
  81. /* Handle types. Code currently assumes child = parent + 1.        */
  82. #define DBIt_DR        1
  83. #define DBIt_DB        2
  84. #define DBIt_ST        3
  85. #define DBIt_FD        4
  86.  
  87. /* component structures */
  88.  
  89. typedef struct dbih_com_std_st {
  90.     U32  flags;
  91.     int  call_depth;    /* used by DBI to track nested calls (int)    */
  92.     U16  type;        /* DBIt_DR, DBIt_DB, DBIt_ST            */
  93.     HV   *my_h;        /* copy of outer handle HV (not refcounted)    */
  94.     SV   *parent_h;    /* parent inner handle (ref to hv) (r.c.inc)    */
  95.     imp_xxh_t *parent_com;    /* parent com struct shortcut        */
  96.     PerlInterpreter * thr_user;  /* thread that owns the handle         */
  97.  
  98.     HV   *imp_stash;    /* who is the implementor for this handle    */
  99.     SV   *imp_data;    /* optional implementors data (for perl imp's)    */
  100.  
  101.     I32  kids;        /* count of db's for dr's, st's for db's etc    */
  102.     I32  active_kids;    /* kids which are currently DBIc_ACTIVE        */
  103.     U32 pad;        /* keep binary compat */
  104.     dbistate_t *dbistate;
  105. } dbih_com_std_t;
  106.  
  107. typedef struct dbih_com_attr_st {
  108.     /* These are copies of the Hash values (ref.cnt.inc'd)    */
  109.     /* Many of the hash values are themselves references    */
  110.     SV *TraceLevel;
  111.     SV *State;        /* Standard SQLSTATE, 5 char string    */
  112.     SV *Err;        /* Native engine error code        */
  113.     SV *Errstr;        /* Native engine error message        */
  114.     UV ErrCount;
  115.     U32  LongReadLen;    /* auto read length for long/blob types    */
  116.     SV *FetchHashKeyName;    /* for fetchrow_hashref        */
  117.     /* (NEW FIELDS?... DON'T FORGET TO UPDATE dbih_clearcom()!)    */
  118. } dbih_com_attr_t;
  119.  
  120.  
  121. struct dbih_com_st {    /* complete core structure (typedef'd above)    */
  122.     dbih_com_std_t    std;
  123.     dbih_com_attr_t    attr;
  124. };
  125.  
  126. /* This 'implementors' type the DBI defines by default as a way to    */
  127. /* refer to the imp_??h data of a handle without considering its type.    */
  128. struct imp_xxh_st { struct dbih_com_st com; };
  129.  
  130. /* Define handle-type specific structures for implementors to include    */
  131. /* at the start of their private structures.                */
  132.  
  133. typedef struct {        /* -- DRIVER --                */
  134.     dbih_com_std_t    std;
  135.     dbih_com_attr_t    attr;
  136.     HV          *cached_kids;    /* $drh->connect_cached(...)        */
  137. } dbih_drc_t;
  138.  
  139. typedef struct {        /* -- DATABASE --            */
  140.     dbih_com_std_t    std;    /* \__ standard structure        */
  141.     dbih_com_attr_t    attr;    /* /   plus... (nothing else right now)    */
  142.     HV          *cached_kids;    /* $dbh->prepare_cached(...)        */
  143. } dbih_dbc_t;
  144.  
  145. typedef struct {        /* -- STATEMENT --            */
  146.     dbih_com_std_t    std;    /* \__ standard structure        */
  147.     dbih_com_attr_t    attr;    /* /   plus ...                */
  148.  
  149.     int     num_params;    /* number of placeholders        */
  150.     int     num_fields;    /* NUM_OF_FIELDS, must be set        */
  151.     AV      *fields_svav;    /* special row buffer (inc bind_cols)    */
  152.     IV        row_count;    /* incremented by get_fbav()        */
  153.  
  154.     AV        *fields_fdav;    /* not used yet, may change */
  155.  
  156.     I32  spare1;
  157.     void *spare2;
  158. } dbih_stc_t;
  159.  
  160.  
  161. /* XXX THIS STRUCTURE SHOULD NOT BE USED */
  162. typedef struct {        /* -- FIELD DESCRIPTOR --        */
  163.     dbih_com_std_t    std;    /* standard structure (not fully setup)    */
  164.  
  165.     /* core attributes (from DescribeCol in ODBC)        */
  166.     char *col_name;        /* see dbih_make_fdsv        */
  167.     I16   col_name_len;
  168.     I16   col_sql_type;
  169.     I16   col_precision;
  170.     I16   col_scale;
  171.     I16   col_nullable;
  172.  
  173.     /* additional attributes (from ColAttributes in ODBC)    */
  174.     I32   col_length;
  175.     I32   col_disp_size;
  176.  
  177.     I32  spare1;
  178.     void *spare2;
  179. } dbih_fdc_t;
  180.  
  181.  
  182. #define _imp2com(p,f)          ((p)->com.f)
  183.  
  184. #define DBIc_FLAGS(imp)        _imp2com(imp, std.flags)
  185. #define DBIc_TYPE(imp)        _imp2com(imp, std.type)
  186. #define DBIc_CALL_DEPTH(imp)    _imp2com(imp, std.call_depth)
  187. #define DBIc_MY_H(imp)      _imp2com(imp, std.my_h)
  188. #define DBIc_PARENT_H(imp)      _imp2com(imp, std.parent_h)
  189. #define DBIc_PARENT_COM(imp)      _imp2com(imp, std.parent_com)
  190. #define DBIc_THR_COND(imp)      _imp2com(imp, std.thr_cond)
  191. #define DBIc_THR_USER(imp)      _imp2com(imp, std.thr_user)
  192. #define DBIc_THR_USER_NONE      (0xFFFF)
  193. #define DBIc_IMP_STASH(imp)      _imp2com(imp, std.imp_stash)
  194. #define DBIc_IMP_DATA(imp)      _imp2com(imp, std.imp_data)
  195. #define DBIc_DBISTATE(imp)      _imp2com(imp, std.dbistate)
  196. #define DBIc_LOGPIO(imp)      DBIc_DBISTATE(imp)->logfp
  197. #define DBIc_KIDS(imp)      _imp2com(imp, std.kids)
  198. #define DBIc_ACTIVE_KIDS(imp)      _imp2com(imp, std.active_kids)
  199. #define DBIc_LAST_METHOD(imp)      _imp2com(imp, std.last_method)
  200.  
  201. #define DBIc_TRACE_LEVEL_MASK    0x0000000F
  202. #define DBIc_TRACE_FLAGS_MASK    0xFFFFFF00
  203. #define DBIc_TRACE_SETTINGS(imp) (DBIc_DBISTATE(imp)->debug)
  204. #define DBIc_TRACE_LEVEL(imp)    (DBIc_TRACE_SETTINGS(imp) & DBIc_TRACE_LEVEL_MASK)
  205. #define DBIc_TRACE_FLAGS(imp)    (DBIc_TRACE_SETTINGS(imp) & DBIc_TRACE_FLAGS_MASK)
  206. /* DBIc_TRACE_MATCHES(this, crnt): true if this 'matches' (is within) crnt
  207.    DBIc_TRACE_MATCHES(foo, DBIc_TRACE_SETTINGS(imp))
  208. */
  209. #define DBIc_TRACE_MATCHES(this, crnt)    \
  210.     (  ((crnt & DBIc_TRACE_LEVEL_MASK) >= (this & DBIc_TRACE_LEVEL_MASK)) \
  211.     || ((crnt & DBIc_TRACE_FLAGS_MASK)  & (this & DBIc_TRACE_FLAGS_MASK)) )
  212. /* DBIc_TRACE: true if flags match & DBI level>=flaglevel, or if DBI level>level
  213.    This is the main trace testing macro to be used by drivers.
  214.    (Drivers should define their own DBDtf_* macros for the top 8 bits: 0xFF000000)
  215.    DBIc_TRACE(imp,         0, 0, 4) = if level >= 4
  216.    DBIc_TRACE(imp, DBDtf_FOO, 2, 4) = if tracing DBDtf_FOO & level>=2 or level>=4
  217.    DBIc_TRACE(imp, DBDtf_FOO, 2, 0) = as above but never trace just due to level
  218. */
  219. #define DBIc_TRACE(imp, flags, flaglevel, level)    \
  220.     (  (flags && (DBIc_TRACE_FLAGS(imp) & flags) && (DBIc_TRACE_LEVEL(imp) >= flaglevel)) \
  221.     || (level && DBIc_TRACE_LEVEL(imp) >= level) )
  222.  
  223. #define DBIc_DEBUG(imp)        (_imp2com(imp, attr.TraceLevel)) /* deprecated */
  224. #define DBIc_DEBUGIV(imp)    SvIV(DBIc_DEBUG(imp))         /* deprecated */
  225. #define DBIc_STATE(imp)        SvRV(_imp2com(imp, attr.State))
  226. #define DBIc_ERR(imp)        SvRV(_imp2com(imp, attr.Err))
  227. #define DBIc_ERRSTR(imp)    SvRV(_imp2com(imp, attr.Errstr))
  228. #define DBIc_ErrCount(imp)    _imp2com(imp, attr.ErrCount)
  229. #define DBIc_LongReadLen(imp)      _imp2com(imp, attr.LongReadLen)
  230. #define DBIc_LongReadLen_init    80    /* may change */
  231. #define DBIc_FetchHashKeyName(imp) (_imp2com(imp, attr.FetchHashKeyName))
  232.  
  233. /* handle sub-type specific fields                        */
  234. /*    dbh    */
  235. #define DBIc_CACHED_KIDS(imp)      _imp2com(imp, cached_kids)
  236. /*    sth    */
  237. #define DBIc_NUM_FIELDS(imp)      _imp2com(imp, num_fields)
  238. #define DBIc_NUM_PARAMS(imp)      _imp2com(imp, num_params)
  239. #define DBIc_NUM_PARAMS_AT_EXECUTE    -9 /* see Driver.xst */
  240. #define DBIc_ROW_COUNT(imp)      _imp2com(imp, row_count)
  241. #define DBIc_FIELDS_AV(imp)      _imp2com(imp, fields_svav)
  242. #define DBIc_FDESC_AV(imp)      _imp2com(imp, fields_fdav)
  243. #define DBIc_FDESC(imp, i)      ((imp_fdh_t*)(void*)SvPVX(AvARRAY(DBIc_FDESC_AV(imp))[i]))
  244.  
  245. /* XXX --- DO NOT CHANGE THESE VALUES AS THEY ARE COMPILED INTO DRIVERS --- XXX */
  246. #define DBIcf_COMSET      0x000001    /* needs to be clear'd before free'd    */
  247. #define DBIcf_IMPSET      0x000002    /* has implementor data to be clear'd    */
  248. #define DBIcf_ACTIVE      0x000004    /* needs finish/disconnect before clear    */
  249. #define DBIcf_IADESTROY      0x000008    /* do DBIc_ACTIVE_off before DESTROY    */
  250. #define DBIcf_WARN        0x000010    /* warn about poor practice etc      */
  251. #define DBIcf_COMPAT        0x000020    /* compat/emulation mode (eg oraperl)    */
  252. #define DBIcf_ChopBlanks  0x000040    /* rtrim spaces from fetch char columns    */
  253. #define DBIcf_RaiseError  0x000080    /* throw exception (croak) on error    */
  254. #define DBIcf_PrintError  0x000100    /* warn() on error            */
  255. #define DBIcf_AutoCommit  0x000200    /* dbh only. used by drivers        */
  256. #define DBIcf_LongTruncOk 0x000400    /* truncation to LongReadLen is okay    */
  257. #define DBIcf_MultiThread 0x000800    /* allow multiple threads to enter    */
  258. #define DBIcf_HandleSetErr 0x001000    /* has coderef HandleSetErr attribute    */
  259. #define DBIcf_ShowErrorStatement  0x002000   /* include Statement in error    */
  260. #define DBIcf_BegunWork   0x004000    /* between begin_work & commit/rollback */
  261. #define DBIcf_HandleError 0x008000    /* has coderef in HandleError attribute */
  262. #define DBIcf_Profile     0x010000    /* profile activity on this handle      */
  263. #define DBIcf_TaintIn     0x020000    /* check inputs for taintedness */
  264. #define DBIcf_TaintOut    0x040000    /* taint outgoing data */
  265. #define DBIcf_Executed    0x080000    /* do/execute called since commit/rollb */
  266. #define DBIcf_PrintWarn   0x100000    /* warn() on warning (err="0")        */
  267. /* NOTE: new flags may require clone() to be updated */
  268.  
  269. #define DBIcf_INHERITMASK        /* what NOT to pass on to children */    \
  270.   (U32)( DBIcf_COMSET | DBIcf_IMPSET | DBIcf_ACTIVE | DBIcf_IADESTROY        \
  271.   | DBIcf_AutoCommit | DBIcf_BegunWork | DBIcf_Executed )
  272.  
  273. /* general purpose bit setting and testing macros            */
  274. #define DBIbf_is( bitset,flag)        ((bitset) &   (flag))
  275. #define DBIbf_has(bitset,flag)        DBIbf_is(bitset, flag) /* alias for _is */
  276. #define DBIbf_on( bitset,flag)        ((bitset) |=  (flag))
  277. #define DBIbf_off(bitset,flag)        ((bitset) &= ~(flag))
  278. #define DBIbf_set(bitset,flag,on)    ((on) ? DBIbf_on(bitset, flag) : DBIbf_off(bitset,flag))
  279.  
  280. /* as above, but specifically for DBIc_FLAGS imp flags (except ACTIVE)    */
  281. #define DBIc_is(imp, flag)    DBIbf_is( DBIc_FLAGS(imp), flag)
  282. #define DBIc_has(imp,flag)    DBIc_is(imp, flag) /* alias for DBIc_is */
  283. #define DBIc_on(imp, flag)    DBIbf_on( DBIc_FLAGS(imp), flag)
  284. #define DBIc_off(imp,flag)    DBIbf_off(DBIc_FLAGS(imp), flag)
  285. #define DBIc_set(imp,flag,on)    DBIbf_set(DBIc_FLAGS(imp), flag, on)
  286.  
  287. #define DBIc_COMSET(imp)    DBIc_is(imp, DBIcf_COMSET)
  288. #define DBIc_COMSET_on(imp)    DBIc_on(imp, DBIcf_COMSET)
  289. #define DBIc_COMSET_off(imp)    DBIc_off(imp,DBIcf_COMSET)
  290.  
  291. #define DBIc_IMPSET(imp)    DBIc_is(imp, DBIcf_IMPSET)
  292. #define DBIc_IMPSET_on(imp)    DBIc_on(imp, DBIcf_IMPSET)
  293. #define DBIc_IMPSET_off(imp)    DBIc_off(imp,DBIcf_IMPSET)
  294.  
  295. #define DBIc_ACTIVE(imp)    (DBIc_FLAGS(imp) &   DBIcf_ACTIVE)
  296. #define DBIc_ACTIVE_on(imp)    /* adjust parent's active kid count */    \
  297.     do {                                \
  298.     imp_xxh_t *ph_com = DBIc_PARENT_COM(imp);            \
  299.     if (!DBIc_ACTIVE(imp) && ph_com && !dirty            \
  300.         && ++DBIc_ACTIVE_KIDS(ph_com) > DBIc_KIDS(ph_com))    \
  301.         croak("panic: DBI active kids (%d) > kids (%d)",        \
  302.         DBIc_ACTIVE_KIDS(ph_com), DBIc_KIDS(ph_com));        \
  303.     DBIc_FLAGS(imp) |=  DBIcf_ACTIVE;                \
  304.     } while(0)
  305. #define DBIc_ACTIVE_off(imp)    /* adjust parent's active kid count */    \
  306.     do {                                \
  307.     imp_xxh_t *ph_com = DBIc_PARENT_COM(imp);            \
  308.     if (DBIc_ACTIVE(imp) && ph_com && !dirty            \
  309.         && (--DBIc_ACTIVE_KIDS(ph_com) > DBIc_KIDS(ph_com)    \
  310.            || DBIc_ACTIVE_KIDS(ph_com) < 0) )            \
  311.         croak("panic: DBI active kids (%d) < 0 or > kids (%d)",    \
  312.         DBIc_ACTIVE_KIDS(ph_com), DBIc_KIDS(ph_com));        \
  313.     DBIc_FLAGS(imp) &= ~DBIcf_ACTIVE;                \
  314.     } while(0)
  315.  
  316. #define DBIc_IADESTROY(imp)    (DBIc_FLAGS(imp) &   DBIcf_IADESTROY)
  317. #define DBIc_IADESTROY_on(imp)    (DBIc_FLAGS(imp) |=  DBIcf_IADESTROY)
  318. #define DBIc_IADESTROY_off(imp)    (DBIc_FLAGS(imp) &= ~DBIcf_IADESTROY)
  319.  
  320. #define DBIc_WARN(imp)       (DBIc_FLAGS(imp) &   DBIcf_WARN)
  321. #define DBIc_WARN_on(imp)    (DBIc_FLAGS(imp) |=  DBIcf_WARN)
  322. #define DBIc_WARN_off(imp)    (DBIc_FLAGS(imp) &= ~DBIcf_WARN)
  323.  
  324. #define DBIc_COMPAT(imp)       (DBIc_FLAGS(imp) &   DBIcf_COMPAT)
  325. #define DBIc_COMPAT_on(imp)    (DBIc_FLAGS(imp) |=  DBIcf_COMPAT)
  326. #define DBIc_COMPAT_off(imp)    (DBIc_FLAGS(imp) &= ~DBIcf_COMPAT)
  327.  
  328.  
  329. #ifdef IN_DBI_XS        /* get Handle Common Data Structure    */
  330. #define DBIh_COM(h)             (dbih_getcom2(h, 0))
  331. #else
  332. #define DBIh_COM(h)             (DBIS->getcom(h))
  333. #define neatsvpv(sv,len)           (DBIS->neat_svpv(sv,len))
  334. #endif
  335.  
  336.  
  337. /* --- Implementors Private Data Support --- */
  338.  
  339. #define D_impdata(name,type,h)    type *name = (type*)(DBIh_COM(h))
  340. #define D_imp_drh(h) D_impdata(imp_drh, imp_drh_t, h)
  341. #define D_imp_dbh(h) D_impdata(imp_dbh, imp_dbh_t, h)
  342. #define D_imp_sth(h) D_impdata(imp_sth, imp_sth_t, h)
  343. #define D_imp_xxh(h) D_impdata(imp_xxh, imp_xxh_t, h)
  344.  
  345. #define D_imp_from_child(name,type,child)    \
  346.                 type *name = (type*)(DBIc_PARENT_COM(child))
  347. #define D_imp_drh_from_dbh D_imp_from_child(imp_drh, imp_drh_t, imp_dbh)
  348. #define D_imp_dbh_from_sth D_imp_from_child(imp_dbh, imp_dbh_t, imp_sth)
  349.  
  350. #define DBI_IMP_SIZE(n,s) sv_setiv(perl_get_sv((n), GV_ADDMULTI), (s)) /* XXX */
  351.  
  352.  
  353.  
  354. /* --- Event Support (VERY LIABLE TO CHANGE) --- */
  355.  
  356. #define DBIh_EVENTx(h,t,a1,a2)    /* deprecated XXX */ &PL_sv_no
  357. #define DBIh_EVENT0(h,t)    DBIh_EVENTx((h), (t), &PL_sv_undef, &PL_sv_undef)
  358. #define DBIh_EVENT1(h,t, a1)    DBIh_EVENTx((h), (t), (a1),         &PL_sv_undef)
  359. #define DBIh_EVENT2(h,t, a1,a2)    DBIh_EVENTx((h), (t), (a1),         (a2))
  360.  
  361. #define ERROR_event    "ERROR"
  362. #define WARN_event    "WARN"
  363. #define MSG_event    "MESSAGE"
  364. #define DBEVENT_event    "DBEVENT"
  365. #define UNKNOWN_event    "UNKNOWN"
  366.  
  367. #define DBIh_SET_ERR_SV(h,i, err, errstr, state, method) \
  368.     (DBIc_DBISTATE(i)->set_err_sv(h,i, err, errstr, state, method))
  369. #define DBIh_SET_ERR_CHAR(h,i, err_c, err_i, errstr, state, method) \
  370.     (DBIc_DBISTATE(i)->set_err_char(h,i, err_c, err_i, errstr, state, method))
  371.  
  372.  
  373. /* --- Handy Macros --- */
  374.  
  375. #define DBIh_CLEAR_ERROR(imp_xxh) (void)( \
  376.     (void)SvOK_off(DBIc_ERR(imp_xxh)),        \
  377.     (void)SvOK_off(DBIc_ERRSTR(imp_xxh)),    \
  378.     (void)SvOK_off(DBIc_STATE(imp_xxh))    \
  379.     )
  380.  
  381.  
  382. /* --- DBI State Structure --- */
  383.  
  384. struct dbistate_st {
  385.  
  386. #define DBISTATE_VERSION  94    /* Must change whenever dbistate_t does    */
  387.  
  388.     /* this must be the first member in structure            */
  389.     void (*check_version) _((char *name,
  390.         int dbis_cv, int dbis_cs, int need_dbixs_cv,
  391.         int drc_s, int dbc_s, int stc_s, int fdc_s));
  392.  
  393.     /* version and size are used to check for DBI/DBD version mis-match    */
  394.     U16 version;    /* version of this structure            */
  395.     U16 size;
  396.     U16 xs_version;    /* version of the overall DBIXS / DBD interface    */
  397.     U16 spare_pad;
  398.  
  399.     I32 debug;
  400.     PerlIO *logfp;
  401.  
  402.     /* pointers to DBI functions which the DBD's will want to use    */
  403.     char      * (*neat_svpv)    _((SV *sv, STRLEN maxlen));
  404.     imp_xxh_t * (*getcom)    _((SV *h));    /* see DBIh_COM macro    */
  405.     void        (*clearcom)    _((imp_xxh_t *imp_xxh));
  406.     SV        * (*event)    _((SV *h, char *name, SV*, SV*));
  407.     int         (*set_attr_k)    _((SV *h, SV *keysv, int dbikey, SV *valuesv));
  408.     SV        * (*get_attr_k)    _((SV *h, SV *keysv, int dbikey));
  409.     AV        * (*get_fbav)    _((imp_sth_t *imp_sth));
  410.     SV        * (*make_fdsv)    _((SV *sth, char *imp_class, STRLEN imp_size, char *col_name));
  411.     int         (*bind_as_num)    _((int sql_type, int p, int s, int *t, void *v));
  412.     int         (*hash)        _((char *string, long i));
  413.     SV        * (*preparse)    _((SV *sth, char *statement, IV ps_return, IV ps_accept, void *foo));
  414.  
  415.     SV *neatsvpvlen;        /* only show dbgpvlen chars when debugging pv's    */
  416.  
  417.     PerlInterpreter * thr_owner;    /* thread that owns this dbistate    */
  418.  
  419.     int         (*logmsg)    _((imp_xxh_t *imp_xxh, char *fmt, ...));
  420.     int         (*set_err_sv)    _((SV *h, imp_xxh_t *imp_xxh, SV   *err, SV   *errstr, SV   *state, SV   *method));
  421.     int         (*set_err_char) _((SV *h, imp_xxh_t *imp_xxh, char *err, IV err_i, char *errstr, char *state, char *method));
  422.     int         (*bind_col)     _((SV *sth, SV *col, SV *ref, SV *attribs));
  423.  
  424.     void *pad2[5];
  425. };
  426.  
  427. /* macros for backwards compatibility */
  428. #define set_attr(h, k, v)    set_attr_k(h, k, 0, v)
  429. #define get_attr(h, k)        get_attr_k(h, k, 0)
  430.  
  431. #define DBISTATE_PERLNAME "DBI::_dbistate"
  432. #define DBISTATE_ADDRSV   (perl_get_sv(DBISTATE_PERLNAME, 0x05))
  433. #define DBILOGFP    (DBIS->logfp)
  434. #ifdef IN_DBI_XS
  435. #define DBILOGMSG    (dbih_logmsg)
  436. #else
  437. #define DBILOGMSG    (DBIS->logmsg)
  438. #endif
  439.  
  440.  
  441. /* --- perl object (ActiveState) / multiplicity hooks and hoops --- */
  442. /* note that USE_ITHREADS implies MULTIPLICITY                      */
  443. #if defined(MULTIPLICITY) || defined(PERL_OBJECT) || defined(PERL_CAPI)
  444.  
  445. # define DBISTATE_DECLARE typedef int dummy_dbistate /* keep semicolon from feeling lonely */
  446. # define DBISTATE_ASSIGN(st)
  447. # define DBISTATE_INIT
  448. # undef DBIS
  449. # define DBIS (*(INT2PTR(dbistate_t**, &SvIVX(DBISTATE_ADDRSV))))
  450. /* 'dbis' is temp for bad drivers using 'dbis' instead of 'DBIS' */
  451. # define dbis (*(INT2PTR(dbistate_t**, &SvIVX(DBISTATE_ADDRSV))))
  452.  
  453. #else    /* plain and simple non perl object / multiplicity case */
  454.  
  455. # define DBISTATE_DECLARE    static dbistate_t *DBIS
  456. # define DBISTATE_ASSIGN(st)    (DBIS = (st))
  457. # define DBISTATE_INIT_DBIS    DBISTATE_ASSIGN(INT2PTR(dbistate_t*, SvIV(DBISTATE_ADDRSV)))
  458. # define DBISTATE_INIT {    /* typically use in BOOT: of XS file    */    \
  459.     DBISTATE_INIT_DBIS;    \
  460.     if (DBIS == NULL)    \
  461.     croak("Unable to get DBI state from %s at %p. DBI not loaded.", DBISTATE_PERLNAME, DBISTATE_ADDRSV); \
  462.     DBIS->check_version(__FILE__, DBISTATE_VERSION, sizeof(*DBIS), NEED_DBIXS_VERSION, \
  463.         sizeof(dbih_drc_t), sizeof(dbih_dbc_t), sizeof(dbih_stc_t), sizeof(dbih_fdc_t) \
  464.     ); \
  465. }
  466. #endif
  467.  
  468.  
  469. /* --- Assorted Utility Macros    --- */
  470.  
  471. #define DBD_ATTRIB_OK(attribs)    /* is this a usable attrib value */    \
  472.     (attribs && SvROK(attribs) && SvTYPE(SvRV(attribs))==SVt_PVHV)
  473.  
  474. /* If attribs value supplied then croak if it's not a hash ref.        */
  475. /* Also map undef to Null. Should always be called to pre-process the    */
  476. /* attribs value. One day we may add some extra magic in here.        */
  477. #define DBD_ATTRIBS_CHECK(func, h, attribs)    \
  478.     if ((attribs) && SvOK(attribs)) {        \
  479.     STRLEN lna1=0, lna2=0;            \
  480.     if (!SvROK(attribs) || SvTYPE(SvRV(attribs))!=SVt_PVHV)        \
  481.         croak("%s->%s(...): attribute parameter '%s' is not a hash ref",    \
  482.             SvPV(h,lna1), func, SvPV(attribs,lna2));        \
  483.     } else (attribs) = Nullsv
  484.  
  485. #define DBD_ATTRIB_GET_SVP(attribs, key,klen)            \
  486.     (DBD_ATTRIB_OK(attribs)                    \
  487.         ? hv_fetch((HV*)SvRV(attribs), key,klen, 0)        \
  488.         : (SV **)Nullsv)
  489.     
  490. #define DBD_ATTRIB_GET_IV(attribs, key,klen, svp, var)            \
  491.     if ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)    \
  492.         var = SvIV(*svp)
  493.  
  494. #define DBD_ATTRIB_GET_BOOL(attribs, key,klen, svp, var)        \
  495.     if ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)    \
  496.         var = SvTRUE(*svp)
  497.  
  498. #define DBD_ATTRIB_TRUE(attribs, key,klen, svp)                \
  499.     (  ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)    \
  500.         ? SvTRUE(*svp) : 0 )
  501.  
  502. #define DBD_ATTRIB_GET_PV(attribs, key,klen, svp, dflt)            \
  503.     (((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)        \
  504.         ? SvPV_nolen(*svp) : (dflt))
  505.  
  506. #define DBD_ATTRIB_DELETE(attribs, key, klen)            \
  507.     hv_delete((HV*)attribs, key, klen, G_DISCARD)
  508.  
  509. #endif /* DBIXS_VERSION */
  510. /* end of DBIXS.h */
  511.