1 /* vim: ts=8:sw=4:expandtab
2  *
3  * $Id$
4  *
5  * Copyright (c) 1994-2010  Tim Bunce  Ireland
6  *
7  * See COPYRIGHT section in DBI.pm for usage and distribution rights.
8  */
9 
10 /* DBI Interface Definitions for DBD Modules */
11 
12 #ifndef DBIXS_VERSION                           /* prevent multiple inclusion */
13 
14 #ifndef DBIS
15 #define DBIS    dbis    /* default name for dbistate_t variable */
16 #endif
17 
18 /* Here for backwards compat. PERL_POLLUTE was removed in perl 5.13.3 */
19 #define PERL_POLLUTE
20 
21 /* first pull in the standard Perl header files for extensions  */
22 #include <EXTERN.h>
23 #include <perl.h>
24 #include <XSUB.h>
25 
26 #ifdef debug            /* causes problems with DBIS->debug     */
27 #undef debug
28 #endif
29 
30 #ifdef std             /* causes problems with STLport <tscheresky@micron.com> */
31 #undef std
32 #endif
33 
34 /* define DBIXS_REVISION */
35 #include "dbixs_rev.h"
36 
37 /* Perl backwards compatibility definitions */
38 #define NEED_sv_2pv_flags
39 #include "dbipport.h"
40 
41 /* DBI SQL_* type definitions */
42 #include "dbi_sql.h"
43 
44 
45 #define DBIXS_VERSION 93 /* superseded by DBIXS_REVISION */
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  pid;           /* pid of process that created handle */
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          *_old_cached_kids; /* not used, here for binary compat */
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          *_old_cached_kids; /* not used, here for binary compat */
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) /* private */
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 /*  d = DBD flags,  l = DBD level (needs to be shifted down)
202  *  D - DBI flags,  r = reserved,  L = DBI trace level
203  *  Trace level bit allocation: 0xddlDDDrL   */
204 #define DBIc_TRACE_LEVEL_MASK   0x0000000F
205 #define DBIc_TRACE_FLAGS_MASK   0xFF0FFF00  /* includes DBD flag bits for DBIc_TRACE */
206 #define DBIc_TRACE_SETTINGS(imp) (DBIc_DBISTATE(imp)->debug)
207 #define DBIc_TRACE_LEVEL(imp)   (DBIc_TRACE_SETTINGS(imp) & DBIc_TRACE_LEVEL_MASK)
208 #define DBIc_TRACE_FLAGS(imp)   (DBIc_TRACE_SETTINGS(imp) & DBIc_TRACE_FLAGS_MASK)
209 /* DBI defined trace flags */
210 #define DBIf_TRACE_SQL          0x00000100
211 #define DBIf_TRACE_CON          0x00000200
212 #define DBIf_TRACE_ENC          0x00000400
213 #define DBIf_TRACE_DBD          0x00000800
214 #define DBIf_TRACE_TXN          0x00001000
215 
216 #define DBDc_TRACE_LEVEL_MASK   0x00F00000
217 #define DBDc_TRACE_LEVEL_SHIFT  20
218 #define DBDc_TRACE_LEVEL(imp)         ( (DBIc_TRACE_SETTINGS(imp) & DBDc_TRACE_LEVEL_MASK) >> DBDc_TRACE_LEVEL_SHIFT )
219 #define DBDc_TRACE_LEVEL_set(imp, l)  ( DBIc_TRACE_SETTINGS(imp) |= (((l) << DBDc_TRACE_LEVEL_SHIFT) & DBDc_TRACE_LEVEL_MASK ))
220 
221 /* DBIc_TRACE_MATCHES(this, crnt): true if this 'matches' (is within) crnt
222    DBIc_TRACE_MATCHES(foo, DBIc_TRACE_SETTINGS(imp))
223 */
224 #define DBIc_TRACE_MATCHES(this, crnt)  \
225         (  ((crnt & DBIc_TRACE_LEVEL_MASK) >= (this & DBIc_TRACE_LEVEL_MASK)) \
226         || ((crnt & DBIc_TRACE_FLAGS_MASK)  & (this & DBIc_TRACE_FLAGS_MASK)) )
227 
228 /* DBIc_TRACE(imp, flags, flag_level, fallback_level)
229    True if flags match the handle trace flags & handle trace level >= flag_level,
230    OR if handle trace_level > fallback_level (typically > flag_level).
231    This is the main trace testing macro to be used by drivers.
232    (Drivers should define their own DBDf_TRACE_* macros for the top 8 bits: 0xFF000000)
233    DBIc_TRACE(imp,              0, 0, 4) = if trace level >= 4
234    DBIc_TRACE(imp, DBDf_TRACE_FOO, 2, 4) = if tracing DBDf_FOO & level>=2 or level>=4
235    DBIc_TRACE(imp, DBDf_TRACE_FOO, 2, 0) = as above but never trace just due to level
236    e.g.
237     if (DBIc_TRACE(imp_xxh, DBIf_TRACE_SQL|DBIf_TRACE_xxx, 2, 0)) {
238         PerlIO_printf(DBIc_LOGPIO(imp_sth), "\tThe %s wibbled the %s\n", ...);
239     }
240 */
241 #define DBIc_TRACE(imp, flags, flaglevel, level)        \
242         (  (flags && (DBIc_TRACE_FLAGS(imp) & flags) && (DBIc_TRACE_LEVEL(imp) >= flaglevel)) \
243         || (level && DBIc_TRACE_LEVEL(imp) >= level) )
244 
245 #define DBIc_DEBUG(imp)         (_imp2com(imp, attr.TraceLevel)) /* deprecated */
246 #define DBIc_DEBUGIV(imp)       SvIV(DBIc_DEBUG(imp))            /* deprecated */
247 #define DBIc_STATE(imp)         SvRV(_imp2com(imp, attr.State))
248 #define DBIc_ERR(imp)           SvRV(_imp2com(imp, attr.Err))
249 #define DBIc_ERRSTR(imp)        SvRV(_imp2com(imp, attr.Errstr))
250 #define DBIc_ErrCount(imp)      _imp2com(imp, attr.ErrCount)
251 #define DBIc_LongReadLen(imp)   _imp2com(imp, attr.LongReadLen)
252 #define DBIc_LongReadLen_init   80      /* may change */
253 #define DBIc_FetchHashKeyName(imp) (_imp2com(imp, attr.FetchHashKeyName))
254 
255 /* handle sub-type specific fields                                              */
256 /*      dbh & drh       */
257 #define DBIc_CACHED_KIDS(imp)   Nullhv /* no longer used, here for src compat */
258 /*      sth     */
259 #define DBIc_NUM_FIELDS(imp)    _imp2com(imp, num_fields)
260 #define DBIc_NUM_PARAMS(imp)    _imp2com(imp, num_params)
261 #define DBIc_NUM_PARAMS_AT_EXECUTE      -9 /* see Driver.xst */
262 #define DBIc_ROW_COUNT(imp)     _imp2com(imp, row_count)
263 #define DBIc_FIELDS_AV(imp)     _imp2com(imp, fields_svav)
264 #define DBIc_FDESC_AV(imp)      _imp2com(imp, fields_fdav)
265 #define DBIc_FDESC(imp, i)      ((imp_fdh_t*)(void*)SvPVX(AvARRAY(DBIc_FDESC_AV(imp))[i]))
266 
267 /* XXX --- DO NOT CHANGE THESE VALUES AS THEY ARE COMPILED INTO DRIVERS --- XXX */
268 #define DBIcf_COMSET      0x000001      /* needs to be clear'd before free'd    */
269 #define DBIcf_IMPSET      0x000002      /* has implementor data to be clear'd   */
270 #define DBIcf_ACTIVE      0x000004      /* needs finish/disconnect before clear */
271 #define DBIcf_IADESTROY   0x000008      /* do DBIc_ACTIVE_off before DESTROY    */
272 #define DBIcf_WARN        0x000010      /* warn about poor practice etc         */
273 #define DBIcf_COMPAT      0x000020      /* compat/emulation mode (eg oraperl)   */
274 #define DBIcf_ChopBlanks  0x000040      /* rtrim spaces from fetch char columns */
275 #define DBIcf_RaiseError  0x000080      /* throw exception (croak) on error     */
276 #define DBIcf_PrintError  0x000100      /* warn() on error                      */
277 #define DBIcf_AutoCommit  0x000200      /* dbh only. used by drivers            */
278 #define DBIcf_LongTruncOk 0x000400      /* truncation to LongReadLen is okay    */
279 #define DBIcf_MultiThread 0x000800      /* allow multiple threads to enter      */
280 #define DBIcf_HandleSetErr 0x001000     /* has coderef HandleSetErr attribute   */
281 #define DBIcf_ShowErrorStatement  0x002000   /* include Statement in error      */
282 #define DBIcf_BegunWork   0x004000      /* between begin_work & commit/rollback */
283 #define DBIcf_HandleError 0x008000      /* has coderef in HandleError attribute */
284 #define DBIcf_Profile     0x010000      /* profile activity on this handle      */
285 #define DBIcf_TaintIn     0x020000      /* check inputs for taintedness */
286 #define DBIcf_TaintOut    0x040000      /* taint outgoing data */
287 #define DBIcf_Executed    0x080000      /* do/execute called since commit/rollb */
288 #define DBIcf_PrintWarn   0x100000      /* warn() on warning (err="0")          */
289 #define DBIcf_Callbacks   0x200000      /* has Callbacks attribute hash         */
290 #define DBIcf_AIADESTROY  0x400000      /* auto DBIcf_IADESTROY if pid changes  */
291 #define DBIcf_RaiseWarn   0x800000      /* throw exception (croak) on warn      */
292 /* NOTE: new flags may require clone() to be updated */
293 
294 #define DBIcf_INHERITMASK               /* what NOT to pass on to children */   \
295   (U32)( DBIcf_COMSET | DBIcf_IMPSET | DBIcf_ACTIVE | DBIcf_IADESTROY \
296   | DBIcf_AutoCommit | DBIcf_BegunWork | DBIcf_Executed | DBIcf_Callbacks )
297 
298 /* general purpose bit setting and testing macros                       */
299 #define DBIbf_is( bitset,flag)          ((bitset) &   (flag))
300 #define DBIbf_has(bitset,flag)          DBIbf_is(bitset, flag) /* alias for _is */
301 #define DBIbf_on( bitset,flag)          ((bitset) |=  (flag))
302 #define DBIbf_off(bitset,flag)          ((bitset) &= ~(flag))
303 #define DBIbf_set(bitset,flag,on)       ((on) ? DBIbf_on(bitset, flag) : DBIbf_off(bitset,flag))
304 
305 /* as above, but specifically for DBIc_FLAGS imp flags (except ACTIVE)  */
306 #define DBIc_is(imp, flag)      DBIbf_is( DBIc_FLAGS(imp), flag)
307 #define DBIc_has(imp,flag)      DBIc_is(imp, flag) /* alias for DBIc_is */
308 #define DBIc_on(imp, flag)      DBIbf_on( DBIc_FLAGS(imp), flag)
309 #define DBIc_off(imp,flag)      DBIbf_off(DBIc_FLAGS(imp), flag)
310 #define DBIc_set(imp,flag,on)   DBIbf_set(DBIc_FLAGS(imp), flag, on)
311 
312 #define DBIc_COMSET(imp)        DBIc_is(imp, DBIcf_COMSET)
313 #define DBIc_COMSET_on(imp)     DBIc_on(imp, DBIcf_COMSET)
314 #define DBIc_COMSET_off(imp)    DBIc_off(imp,DBIcf_COMSET)
315 
316 #define DBIc_IMPSET(imp)        DBIc_is(imp, DBIcf_IMPSET)
317 #define DBIc_IMPSET_on(imp)     DBIc_on(imp, DBIcf_IMPSET)
318 #define DBIc_IMPSET_off(imp)    DBIc_off(imp,DBIcf_IMPSET)
319 
320 #define DBIc_ACTIVE(imp)        (DBIc_FLAGS(imp) &   DBIcf_ACTIVE)
321 #define DBIc_ACTIVE_on(imp)     /* adjust parent's active kid count */  \
322     do {                                                                \
323         imp_xxh_t *ph_com = DBIc_PARENT_COM(imp);                       \
324         if (!DBIc_ACTIVE(imp) && ph_com && !PL_dirty                    \
325                 && ++DBIc_ACTIVE_KIDS(ph_com) > DBIc_KIDS(ph_com))      \
326             croak("panic: DBI active kids (%ld) > kids (%ld)",          \
327                 (long)DBIc_ACTIVE_KIDS(ph_com),                         \
328                 (long)DBIc_KIDS(ph_com));                               \
329         DBIc_FLAGS(imp) |=  DBIcf_ACTIVE;                               \
330     } while(0)
331 #define DBIc_ACTIVE_off(imp)    /* adjust parent's active kid count */  \
332     do {                                                                \
333         imp_xxh_t *ph_com = DBIc_PARENT_COM(imp);                       \
334         if (DBIc_ACTIVE(imp) && ph_com && !PL_dirty                     \
335                 && (--DBIc_ACTIVE_KIDS(ph_com) > DBIc_KIDS(ph_com)      \
336                    || DBIc_ACTIVE_KIDS(ph_com) < 0) )                   \
337             croak("panic: DBI active kids (%ld) < 0 or > kids (%ld)",   \
338                 (long)DBIc_ACTIVE_KIDS(ph_com),                         \
339                 (long)DBIc_KIDS(ph_com));                               \
340         DBIc_FLAGS(imp) &= ~DBIcf_ACTIVE;                               \
341     } while(0)
342 
343 #define DBIc_IADESTROY(imp)     (DBIc_FLAGS(imp) &   DBIcf_IADESTROY)
344 #define DBIc_IADESTROY_on(imp)  (DBIc_FLAGS(imp) |=  DBIcf_IADESTROY)
345 #define DBIc_IADESTROY_off(imp) (DBIc_FLAGS(imp) &= ~DBIcf_IADESTROY)
346 
347 #define DBIc_AIADESTROY(imp)     (DBIc_FLAGS(imp) &   DBIcf_AIADESTROY)
348 #define DBIc_AIADESTROY_on(imp)  (DBIc_FLAGS(imp) |=  DBIcf_AIADESTROY)
349 #define DBIc_AIADESTROY_off(imp) (DBIc_FLAGS(imp) &= ~DBIcf_AIADESTROY)
350 
351 #define DBIc_WARN(imp)          (DBIc_FLAGS(imp) &   DBIcf_WARN)
352 #define DBIc_WARN_on(imp)       (DBIc_FLAGS(imp) |=  DBIcf_WARN)
353 #define DBIc_WARN_off(imp)      (DBIc_FLAGS(imp) &= ~DBIcf_WARN)
354 
355 #define DBIc_COMPAT(imp)        (DBIc_FLAGS(imp) &   DBIcf_COMPAT)
356 #define DBIc_COMPAT_on(imp)     (DBIc_FLAGS(imp) |=  DBIcf_COMPAT)
357 #define DBIc_COMPAT_off(imp)    (DBIc_FLAGS(imp) &= ~DBIcf_COMPAT)
358 
359 
360 #ifdef IN_DBI_XS                /* get Handle Common Data Structure     */
361 #define DBIh_COM(h)             (dbih_getcom2(aTHX_ h, 0))
362 #else
363 #define DBIh_COM(h)             (DBIS->getcom(h))
364 #define neatsvpv(sv,len)        (DBIS->neat_svpv(sv,len))
365 #endif
366 
367 /* --- For sql_type_cast_svpv() --- */
368 
369 #define DBIstcf_DISCARD_STRING  0x0001
370 #define DBIstcf_STRICT          0x0002
371 
372 /* --- Implementors Private Data Support --- */
373 
374 #define D_impdata(name,type,h)  type *name = (type*)(DBIh_COM(h))
375 #define D_imp_drh(h) D_impdata(imp_drh, imp_drh_t, h)
376 #define D_imp_dbh(h) D_impdata(imp_dbh, imp_dbh_t, h)
377 #define D_imp_sth(h) D_impdata(imp_sth, imp_sth_t, h)
378 #define D_imp_xxh(h) D_impdata(imp_xxh, imp_xxh_t, h)
379 
380 #define D_imp_from_child(name,type,child)       \
381                                 type *name = (type*)(DBIc_PARENT_COM(child))
382 #define D_imp_drh_from_dbh D_imp_from_child(imp_drh, imp_drh_t, imp_dbh)
383 #define D_imp_dbh_from_sth D_imp_from_child(imp_dbh, imp_dbh_t, imp_sth)
384 
385 #define DBI_IMP_SIZE(n,s) sv_setiv(get_sv((n), GV_ADDMULTI), (s)) /* XXX */
386 
387 
388 
389 /* --- Event Support (VERY LIABLE TO CHANGE) --- */
390 
391 #define DBIh_EVENTx(h,t,a1,a2)  /* deprecated XXX */ &PL_sv_no
392 #define DBIh_EVENT0(h,t)        DBIh_EVENTx((h), (t), &PL_sv_undef, &PL_sv_undef)
393 #define DBIh_EVENT1(h,t, a1)    DBIh_EVENTx((h), (t), (a1),         &PL_sv_undef)
394 #define DBIh_EVENT2(h,t, a1,a2) DBIh_EVENTx((h), (t), (a1),         (a2))
395 
396 #define ERROR_event     "ERROR"
397 #define WARN_event      "WARN"
398 #define MSG_event       "MESSAGE"
399 #define DBEVENT_event   "DBEVENT"
400 #define UNKNOWN_event   "UNKNOWN"
401 
402 #define DBIh_SET_ERR_SV(h,i, err, errstr, state, method) \
403         (DBIc_DBISTATE(i)->set_err_sv(h,i, err, errstr, state, method))
404 #define DBIh_SET_ERR_CHAR(h,i, err_c, err_i, errstr, state, method) \
405         (DBIc_DBISTATE(i)->set_err_char(h,i, err_c, err_i, errstr, state, method))
406 
407 
408 /* --- Handy Macros --- */
409 
410 #define DBIh_CLEAR_ERROR(imp_xxh) (void)( \
411         (void)SvOK_off(DBIc_ERR(imp_xxh)),      \
412         (void)SvOK_off(DBIc_ERRSTR(imp_xxh)),   \
413         (void)SvOK_off(DBIc_STATE(imp_xxh))     \
414     )
415 
416 
417 /* --- DBI State Structure --- */
418 
419 struct dbistate_st {
420 
421 /* DBISTATE_VERSION is checked at runtime via DBISTATE_INIT and check_version.
422  * It should be incremented on incompatible changes to dbistate_t structure.
423  * Additional function pointers being assigned from spare padding, where the
424  * size of the structure doesn't change, doesn't require an increment.
425  * Incrementing forces all XS drivers to need to be recompiled.
426  * (See also DBIXS_REVISION as a driver source compatibility tool.)
427  */
428 #define DBISTATE_VERSION  94   /* ++ on incompatible dbistate_t changes */
429 
430     /* this must be the first member in structure                       */
431     void (*check_version) _((const char *name,
432                 int dbis_cv, int dbis_cs, int need_dbixs_cv,
433                 int drc_s, int dbc_s, int stc_s, int fdc_s));
434 
435     /* version and size are used to check for DBI/DBD version mis-match */
436     U16 version;        /* version of this structure                    */
437     U16 size;
438     U16 xs_version;     /* version of the overall DBIXS / DBD interface */
439     U16 spare_pad;
440 
441     I32 debug;
442     PerlIO *logfp;
443 
444     /* pointers to DBI functions which the DBD's will want to use       */
445     char      * (*neat_svpv)    _((SV *sv, STRLEN maxlen));
446     imp_xxh_t * (*getcom)       _((SV *h));     /* see DBIh_COM macro   */
447     void        (*clearcom)     _((imp_xxh_t *imp_xxh));
448     SV        * (*event)        _((SV *h, const char *name, SV*, SV*));
449     int         (*set_attr_k)   _((SV *h, SV *keysv, int dbikey, SV *valuesv));
450     SV        * (*get_attr_k)   _((SV *h, SV *keysv, int dbikey));
451     AV        * (*get_fbav)     _((imp_sth_t *imp_sth));
452     SV        * (*make_fdsv)    _((SV *sth, const char *imp_class, STRLEN imp_size, const char *col_name));
453     int         (*bind_as_num)  _((int sql_type, int p, int s, int *t, void *v)); /* XXX deprecated */
454     I32         (*hash)         _((const char *string, long i));
455     SV        * (*preparse)     _((SV *sth, char *statement, IV ps_return, IV ps_accept, void *foo));
456 
457     SV *neatsvpvlen;            /* only show dbgpvlen chars when debugging pv's */
458 
459     PerlInterpreter * thr_owner;        /* thread that owns this dbistate       */
460 
461     int         (*logmsg)       _((imp_xxh_t *imp_xxh, const char *fmt, ...));
462     int         (*set_err_sv)   _((SV *h, imp_xxh_t *imp_xxh, SV   *err, SV   *errstr, SV   *state, SV   *method));
463     int         (*set_err_char) _((SV *h, imp_xxh_t *imp_xxh, const char *err, IV err_i, const char *errstr, const char *state, const char *method));
464     int         (*bind_col)     _((SV *sth, SV *col, SV *ref, SV *attribs));
465 
466     IO *logfp_ref;              /* keep ptr to filehandle for refcounting */
467 
468     int         (*sql_type_cast_svpv) _((pTHX_ SV *sv, int sql_type, U32 flags, void *v));
469 
470     /* WARNING: Only add new structure members here, and reduce pad2 to keep */
471     /* the memory footprint exactly the same */
472     void *pad2[3];
473 };
474 
475 /* macros for backwards compatibility */
476 #define set_attr(h, k, v)       set_attr_k(h, k, 0, v)
477 #define get_attr(h, k)          get_attr_k(h, k, 0)
478 
479 #define DBILOGFP        (DBIS->logfp)
480 #ifdef IN_DBI_XS
481 #define DBILOGMSG       (dbih_logmsg)
482 #else
483 #define DBILOGMSG       (DBIS->logmsg)
484 #endif
485 
486 /* --- perl object (ActiveState) / multiplicity hooks and hoops --- */
487 /* note that USE_ITHREADS implies MULTIPLICITY                      */
488 
489 typedef dbistate_t** (*_dbi_state_lval_t)(pTHX);
490 
491 # define _DBISTATE_DECLARE_COMMON \
492     static _dbi_state_lval_t dbi_state_lval_p = 0;                          \
493     static dbistate_t** dbi_get_state(pTHX) {                               \
494         if (!dbi_state_lval_p) {                                            \
495             CV *cv = get_cv("DBI::_dbi_state_lval", 0);                     \
496             if (!cv)                                                        \
497                 croak("Unable to get DBI state function. DBI not loaded."); \
498             dbi_state_lval_p = (_dbi_state_lval_t)CvXSUB(cv);               \
499         }                                                                   \
500         return dbi_state_lval_p(aTHX);                                      \
501     }                                                                       \
502     typedef int dummy_dbistate /* keep semicolon from feeling lonely */
503 
504 #if defined(MULTIPLICITY) || defined(PERL_OBJECT) || defined(PERL_CAPI)
505 
506 # define DBISTATE_DECLARE _DBISTATE_DECLARE_COMMON
507 # define _DBISTATE_INIT_DBIS
508 # undef  DBIS
509 # define DBIS (*dbi_get_state(aTHX))
510 # define dbis DBIS /* temp for old drivers using 'dbis' instead of 'DBIS' */
511 
512 #else   /* plain and simple non perl object / multiplicity case */
513 
514 # define DBISTATE_DECLARE \
515     static dbistate_t *DBIS; \
516     _DBISTATE_DECLARE_COMMON
517 
518 # define _DBISTATE_INIT_DBIS      DBIS = *dbi_get_state(aTHX);
519 #endif
520 
521 # define DBISTATE_INIT {        /* typically use in BOOT: of XS file    */    \
522     _DBISTATE_INIT_DBIS \
523     if (DBIS == NULL)   \
524         croak("Unable to get DBI state. DBI not loaded."); \
525     DBIS->check_version(__FILE__, DBISTATE_VERSION, sizeof(*DBIS), NEED_DBIXS_VERSION, \
526                 sizeof(dbih_drc_t), sizeof(dbih_dbc_t), sizeof(dbih_stc_t), sizeof(dbih_fdc_t) \
527     ); \
528 }
529 
530 
531 /* --- Assorted Utility Macros  --- */
532 
533 #define DBD_ATTRIB_OK(attribs)  /* is this a usable attrib value */     \
534         (attribs && SvROK(attribs) && SvTYPE(SvRV(attribs))==SVt_PVHV)
535 
536 /* If attribs value supplied then croak if it's not a hash ref.         */
537 /* Also map undef to Null. Should always be called to pre-process the   */
538 /* attribs value. One day we may add some extra magic in here.          */
539 #define DBD_ATTRIBS_CHECK(func, h, attribs)     \
540     if ((attribs) && SvOK(attribs)) {           \
541         if (!SvROK(attribs) || SvTYPE(SvRV(attribs))!=SVt_PVHV)         \
542             croak("%s->%s(...): attribute parameter '%s' is not a hash ref",    \
543                     SvPV_nolen(h), func, SvPV_nolen(attribs));          \
544     } else (attribs) = Nullsv
545 
546 #define DBD_ATTRIB_GET_SVP(attribs, key,klen)                   \
547         (DBD_ATTRIB_OK(attribs)                                 \
548             ? hv_fetch((HV*)SvRV(attribs), key,klen, 0)         \
549             : (SV **)Nullsv)
550 
551 #define DBD_ATTRIB_GET_IV(attribs, key,klen, svp, var)                  \
552         if ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)        \
553             var = SvIV(*svp)
554 
555 #define DBD_ATTRIB_GET_UV(attribs, key,klen, svp, var)                  \
556         if ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)        \
557             var = SvUV(*svp)
558 
559 #define DBD_ATTRIB_GET_BOOL(attribs, key,klen, svp, var)                \
560         if ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)        \
561             var = SvTRUE(*svp)
562 
563 #define DBD_ATTRIB_TRUE(attribs, key,klen, svp)                         \
564         (  ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)        \
565             ? SvTRUE(*svp) : 0 )
566 
567 #define DBD_ATTRIB_GET_PV(attribs, key,klen, svp, dflt)                 \
568         (((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)          \
569             ? SvPV_nolen(*svp) : (dflt))
570 
571 #define DBD_ATTRIB_DELETE(attribs, key, klen)                   \
572         hv_delete((HV*)SvRV(attribs), key, klen, G_DISCARD)
573 
574 #endif /* DBIXS_VERSION */
575 /* end of DBIXS.h */
576