#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef I_MEMORY
#include <memory.h>
#endif
#define DBIXS_VERSION 7
#ifdef NEED_DBIXS_VERSION
#if NEED_DBIXS_VERSION > DBIXS_VERSION
#error You need to upgrade your DBI module before building this driver.
#endif
#endif
typedef
struct
imp_drh_st imp_drh_t;
typedef
struct
imp_dbh_st imp_dbh_t;
typedef
struct
imp_sth_st imp_sth_t;
typedef
struct
imp_xxh_st imp_xxh_t;
#define DBIt_DR 1
#define DBIt_DB 2
#define DBIt_ST 3
typedef
struct
dbih_com_std_st {
U16 flags;
U16 type;
SV *my_h;
SV *parent_h;
imp_xxh_t *parent_com;
HV *imp_stash;
SV *imp_data;
I32 kids;
char
*last_method;
} dbih_com_std_t;
typedef
struct
dbih_com_attr_st {
SV *Debug;
SV *Err;
SV *Errstr;
SV *Handlers;
} dbih_com_attr_t;
struct
dbih_com_st {
dbih_com_std_t std;
dbih_com_attr_t attr;
};
struct
imp_xxh_st {
struct
dbih_com_st com; };
typedef
struct
dbih_com_st
dbih_drc_t;
typedef
struct
{
dbih_com_std_t std;
dbih_com_attr_t attr;
} dbih_dbc_t;
typedef
struct
{
dbih_com_std_t std;
dbih_com_attr_t attr;
int
num_params;
int
num_fields;
AV *fields_av;
} dbih_stc_t;
#define _imp2com(p,f) ((p)->com.f)
#define _imp2std(p,f) ((p)->com.std.f)
#define _imp2atr(p,f) ((p)->com.attr.f)
#define DBIc_FLAGS(imp) _imp2com(imp, std.flags)
#define DBIc_TYPE(imp) _imp2com(imp, std.type)
#define DBIc_MY_H(imp) _imp2com(imp, std.my_h)
#define DBIc_PARENT_H(imp) _imp2com(imp, std.parent_h)
#define DBIc_PARENT_COM(imp) _imp2com(imp, std.parent_com)
#define DBIc_IMP_STASH(imp) _imp2com(imp, std.imp_stash)
#define DBIc_IMP_DATA(imp) _imp2com(imp, std.imp_data)
#define DBIc_KIDS(imp) _imp2com(imp, std.kids)
#define DBIc_LAST_METHOD(imp) _imp2com(imp, std.last_method)
#define DBIc_ATTR(imp, field) _imp2atr(imp, field)
#define DBIc_DEBUGIV(imp) SvIV(DBIc_ATTR(imp, Debug))
#define DBIc_ERR(imp) SvRV(DBIc_ATTR(imp, Err))
#define DBIc_ERRSTR(imp) SvRV(DBIc_ATTR(imp, Errstr))
#define DBIc_HANDLERS(imp) SvRV(DBIc_ATTR(imp, Handlers))
#define DBIc_NUM_FIELDS(imp) _imp2com(imp, num_fields)
#define DBIc_FIELDS_AV(imp) _imp2com(imp, fields_av)
#define DBIc_NUM_PARAMS(imp) _imp2com(imp, num_params)
#define DBIcf_COMSET 0x0001 /* needs to be clear'd before free'd */
#define DBIcf_IMPSET 0x0002 /* has implementor data to be clear'd */
#define DBIcf_ACTIVE 0x0004 /* needs finish/disconnect before clear */
#define DBIcf_spare 0x0008 /* */
#define DBIcf_WARN 0x0010 /* warn about poor practice etc */
#define DBIcf_COMPAT 0x0020 /* compat/emulation mode (eg oraperl) */
#define DBIcf_INHERITMASK /* what flags to pass on to children */ \
(DBIcf_WARN | DBIcf_COMPAT)
#define DBIc_COMSET(imp) (DBIc_FLAGS(imp) & DBIcf_COMSET)
#define DBIc_COMSET_on(imp) (DBIc_FLAGS(imp) |= DBIcf_COMSET)
#define DBIc_COMSET_off(imp) (DBIc_FLAGS(imp) &= ~DBIcf_COMSET)
#define DBIc_IMPSET(imp) (DBIc_FLAGS(imp) & DBIcf_IMPSET)
#define DBIc_IMPSET_on(imp) (DBIc_FLAGS(imp) |= DBIcf_IMPSET)
#define DBIc_IMPSET_off(imp) (DBIc_FLAGS(imp) &= ~DBIcf_IMPSET)
#define DBIc_ACTIVE(imp) (DBIc_FLAGS(imp) & DBIcf_ACTIVE)
#define DBIc_ACTIVE_on(imp) (DBIc_FLAGS(imp) |= DBIcf_ACTIVE)
#define DBIc_ACTIVE_off(imp) (DBIc_FLAGS(imp) &= ~DBIcf_ACTIVE)
#define DBIc_WARN(imp) (DBIc_FLAGS(imp) & DBIcf_WARN)
#define DBIc_WARN_on(imp) (DBIc_FLAGS(imp) |= DBIcf_WARN)
#define DBIc_WARN_off(imp) (DBIc_FLAGS(imp) &= ~DBIcf_WARN)
#define DBIc_COMPAT(imp) (DBIc_FLAGS(imp) & DBIcf_COMPAT)
#define DBIc_COMPAT_on(imp) (DBIc_FLAGS(imp) |= DBIcf_COMPAT)
#define DBIc_COMPAT_off(imp) (DBIc_FLAGS(imp) &= ~DBIcf_COMPAT)
#ifdef IN_DBI_XS /* get Handle Common Data Structure */
#define DBIh_COM(h) (dbih_getcom(h))
#else
#define DBIh_COM(h) (DBIS->getcom(h))
#endif
#define D_impdata(name,type,h) type *name = (type*)(DBIh_COM(h))
#define D_imp_drh(h) D_impdata(imp_drh, imp_drh_t, h)
#define D_imp_dbh(h) D_impdata(imp_dbh, imp_dbh_t, h)
#define D_imp_sth(h) D_impdata(imp_sth, imp_sth_t, h)
#define D_imp_xxh(h) D_impdata(imp_xxh, imp_xxh_t, h)
#define D_imp_from_child(name,type,child) \
type *name = (type*)(DBIc_PARENT_COM(child))
#define D_imp_drh_from_dbh D_imp_from_child(imp_drh, imp_drh_t, imp_dbh)
#define D_imp_dbh_from_sth D_imp_from_child(imp_dbh, imp_dbh_t, imp_sth)
#define DBI_IMP_SIZE(n,s) sv_setiv(perl_get_sv((n), GV_ADDMULTI), (s)) /* XXX */
#define DBIh_EVENTx(h,t,a1,a2) (DBIS->event((h), (t), (a1), (a2)))
#define DBIh_EVENT0(h,t) DBIh_EVENTx((h), (t), &sv_undef, &sv_undef)
#define DBIh_EVENT1(h,t, a1) DBIh_EVENTx((h), (t), (a1), &sv_undef)
#define DBIh_EVENT2(h,t, a1,a2) DBIh_EVENTx((h), (t), (a1), (a2))
#define ERROR_event "ERROR"
#define WARN_event "WARN"
#define MSG_event "MESSAGE"
#define DBEVENT_event "DBEVENT"
#define UNKNOWN_event "UNKNOWN"
typedef
struct
{
U16 version;
U16 size;
U16 xs_version;
int
debug;
int
debugpvlen;
FILE
*logfp;
imp_xxh_t * (*getcom) _((SV *h));
void
(*clearcom) _((imp_xxh_t *imp_xxh));
SV * (*event) _((SV *h,
char
*name, SV*, SV*));
int
(*set_attr) _((SV *h, SV *keysv, SV *valuesv));
SV * (*get_attr) _((SV *h, SV *keysv));
AV * (*get_fbav) _((imp_sth_t *imp_sth));
SV *pad1;
SV *pad2;
} dbistate_t;
#define DBISTATE_VERSION 7 /* Must change whenever dbistate_t does */
#define DBIS dbis /* default name for dbistate_t variable */
#define DBISTATE_DECLARE static dbistate_t *DBIS
#define DBISTATE_PERLNAME "DBI::_dbistate"
#define DBISTATE_ADDRSV (perl_get_sv(DBISTATE_PERLNAME, 0x05))
#define DBISTATE_INIT_DBIS (DBIS = (dbistate_t*)SvIV(DBISTATE_ADDRSV))
#define DBISTATE_INIT { /* typically use in BOOT: of XS file */ \
DBISTATE_INIT_DBIS; \
if
(DBIS == NULL) \
croak(
"Unable to get DBI state. DBI not loaded."
); \
if
(DBIS->version < DBISTATE_VERSION || DBIS->size <
sizeof
(*DBIS)) \
croak(
"DBI version mismatch (DBI actual v%d/s%d, expected v%d/s%d)"
, \
DBIS->version, DBIS->size, DBISTATE_VERSION, (
int
)
sizeof
(*DBIS)); \
}
#define DBILOGFP (DBIS->logfp)
#define DBI_INTERNAL_ERROR(msg) \
croak(
"%s: file \"%s\", line %d"
, msg, __FILE__, __LINE__);
#define DBD_ATTRIBS_CHECK(func, h, attribs) \
if
((attribs) && SvOK(attribs)) { \
if
(!SvROK(attribs) || SvTYPE(SvRV(attribs))!=SVt_PVHV) \
croak(
"%s->%s(...): attribute parameter is not a hash ref"
, \
SvPV(h,na), func); \
}
else
(attribs) = Nullsv
#define DBD_ATTRIB_GET_SVP(attribs, key, klen) \
hv_fetch((HV*)SvRV(attribs), key, klen, 0)
#define DBD_ATTRIB_GET_BOOL(attribs, key,klen, svp, var) \
if
( (svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL) \
var = SvTRUE(*svp)
#define DBD_ATTRIB_GET_IV(attribs, key,klen, svp, var) \
if
( (svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL) \
var = SvIV(*svp)