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