DBD-Informix4
view release on metacpan or search on metacpan
/*---------------------------------------------------------
*
* Portions Copyright (c) 1994,1995,1996,1997 Tim Bunce
* Portions Copyright (c) 1997 Edmund Mergl
* Portions Copyright (c) 1997 Göran Thyni
*
*---------------------------------------------------------
*/
#include "Informix4.h"
#include <string.h>
#define I4DEBUG 0
dbistate_t *dbis;
static SV *dbd_pad_empty;
static char* gDatabase;
#define MAXCURS 5
static _SQCURSOR _SQ[MAXCURS];
static struct sqlda *udesc[MAXCURS];
static int cursbusy[MAXCURS] = {0,0,0,0,0};
void
dbd_init(dbistate)
dbistate_t *dbistate;
{
DBIS = dbistate;
sqlca.sqlcode = 0;
if (getenv("DBD_PAD_EMPTY"))
sv_setiv(dbd_pad_empty, atoi(getenv("DBD_PAD_EMPTY")));
}
int dbd_error(SV * h, int rc)
{
D_imp_xxh(h);
char errbuf[256], fmtbuf[256];
#if I4DEBUG
fprintf(stderr, "dbd_error: %d, %s\n", error_num);
#endif
if (rc < 0)
{
/* Format SQL (primary) error */
if (rgetmsg(rc, errbuf, sizeof(errbuf)) != 0)
strcpy(errbuf, "<<Failed to locate SQL error message>>");
sprintf(fmtbuf, errbuf, sqlca.sqlerrm);
sprintf(errbuf, "SQL: %ld: %s", rc, fmtbuf);
sv_setiv(DBIc_ERR(imp_xxh), (IV)rc); /* set err early */
sv_setpv(DBIc_ERRSTR(imp_xxh), errbuf);
return 0;
}
return 1;
}
int dbd_error2(SV * h, int rc, char* sa)
{
D_imp_xxh(h);
#if I4DEBUG
fprintf(stderr, "dbd_error2: %d, %s\n", error_num);
#endif
if (rc < 0)
{
sv_setiv(DBIc_ERR(imp_xxh), (IV)rc); /* set err early */
sv_setpv(DBIc_ERRSTR(imp_xxh), sa);
return 0;
}
return 1;
}
/* ================================================================== */
int
dbd_db_login(dbh, imp_dbh, dbname, uid, pwd)
SV *dbh;
struct imp_dbh_st* imp_dbh;
char *dbname;
char *uid;
char *pwd;
{
char *conn_str;
#if I4DEBUG
if (dbis->debug >= 2)
fprintf(DBILOGFP, "bind %s <== %s (attribs: %s)\n",
name, neatsvpv(newvalue,0), attribs ? SvPV(attribs,na) : "" );
phs_svp = hv_fetch(imp_sth->all_params_hv, name, name_len, 0);
if (phs_svp == NULL)
croak("Can't bind unknown placeholder '%s'", name);
phs = (phs_t*)(void*)SvPVX(*phs_svp); /* placeholder struct */
if (phs->sv == &sv_undef) { /* first bind for this placeholder */
phs->ftype = 1; /* our default type VARCHAR2 */
phs->maxlen = maxlen; /* 0 if not inout */
phs->is_inout = is_inout;
if (is_inout) {
phs->sv = SvREFCNT_inc(newvalue); /* point to live var */
++imp_sth->has_inout_params;
/* build array of phs's so we can deal with out vars fast */
if (!imp_sth->out_params_av)
imp_sth->out_params_av = newAV();
av_push(imp_sth->out_params_av, SvREFCNT_inc(*phs_svp));
}
}
/* check later rebinds for any changes */
else if (is_inout || phs->is_inout) {
croak("Can't rebind or change param %s in/out mode after first bind", phs->name);
}
else if (maxlen && maxlen != phs->maxlen) {
croak("Can't change param %s maxlen (%ld->%ld) after first bind",
phs->name, phs->maxlen, maxlen);
}
if (!is_inout) { /* normal bind to take a (new) copy of current value */
if (phs->sv == &sv_undef) /* (first time bind) */
phs->sv = newSV(0);
sv_setsv(phs->sv, newvalue);
}
return _dbd_rebind_ph(sth, imp_sth, phs);
}
/* <= -2:error, >=0:ok row count, (-1=unknown count) */
int
dbd_st_execute(sth, imp_sth)
SV *sth;
struct imp_sth_st* imp_sth;
{
D_imp_dbh_from_sth;
/* ExecStatusType status = -1; */
int i, pos;
char* cp;
struct sqlvar_struct *col;
int ret = -2;
SV** svp = hv_fetch((HV *)SvRV(sth), "Statement", 9, FALSE);
char *statement = SvPV(*svp, na);
#if I4DEBUG
fprintf(stderr, "dbd_st_execute\n");
#endif
for (i = 0; i < MAXCURS; i++)
if (!cursbusy[i])
{
cursbusy[i] = 1;
imp_sth->index = i;
break;
}
_iqprepare(&_SQ[imp_sth->index], statement);
if (sqlca.sqlcode != 0)
return dbd_error(sth, sqlca.sqlcode);
_iqdscribe(&_SQ[imp_sth->index], &udesc[imp_sth->index]);
if (sqlca.sqlcode != 0)
return dbd_error(sth, sqlca.sqlcode);
#if I4DEBUG
fprintf(stderr, "dbd_st_execute 2\n");
#endif
/* STEP 1 */
pos = 0;
for (col = udesc[imp_sth->index]->sqlvar, i = 0;
i < udesc[imp_sth->index]->sqld; col++, i++)
{
switch (col->sqltype)
{
case SQLCHAR:
col->sqltype = CCHARTYPE;
break;
case SQLSMINT:
col->sqltype = CSHORTTYPE;
break;
case SQLINT:
col->sqltype = CINTTYPE;
break;
case SQLSMFLOAT:
col->sqltype = CFLOATTYPE;
break;
case SQLFLOAT:
col->sqltype = CDOUBLETYPE;
break;
case SQLMONEY:
case SQLDECIMAL:
col->sqltype = CDECIMALTYPE;
break;
default:
{
char str[100];
sprintf(str, "unknown type: %d\n", col->sqltype);
return dbd_error2(sth, -1, str);
}
}
col->sqllen = rtypmsize(col->sqltype, col->sqllen);
pos = rtypalign(pos, col->sqltype) + col->sqllen;
col->sqlind = NULL;
}
DBIc_NUM_FIELDS(imp_sth) = udesc[imp_sth->index]->sqld;
/* STEP 3 */
cp = malloc(pos);
for (col = udesc[imp_sth->index]->sqlvar, i = 0;
i < udesc[imp_sth->index]->sqld; col++, i++)
{
cp = col->sqldata = rtypalign(cp, col->sqltype);
cp += col->sqllen;
}
{
char cstr[20];
SV *sv = AvARRAY(av)[i];
switch (col->sqltype)
{
case CCHARTYPE:
sv_setpv(sv, col->sqldata);
if (ChopBlanks)
{
char *p = SvEND(sv);
int len = SvCUR(sv);
while(len && *--p == ' ') --len;
if (len != SvCUR(sv))
{
SvCUR_set(sv, len);
*SvEND(sv) = '\0';
}
}
continue;
case CSHORTTYPE:
sprintf(field, "%hd", *((short*) (col->sqldata)));
break;
case CINTTYPE:
sprintf(field, "%d", *((int*) (col->sqldata)));
break;
case CFLOATTYPE:
sprintf(field, "%f", (double) *((float*) (col->sqldata)));
break;
case CDOUBLETYPE:
sprintf(field, "%f", *((double*) (col->sqldata)));
break;
case CDECIMALTYPE:
dectoasc(col->sqldata, field, FLDSIZE, -1);
break;
default:
printf("unknown type 2: %d\n", col->sqltype);
return;
}
sv_setpv(sv, field);
}
imp_sth->n_rows++;
return av;
}
int
dbd_st_rows(sth, imp_sth)
SV *sth;
struct imp_sth_st* imp_sth;
{
return imp_sth->n_rows ? imp_sth->n_rows : 1;
}
int
dbd_st_finish(sth, imp_sth)
SV *sth;
struct imp_sth_st* imp_sth;
{
#if I4DEBUG
fprintf(stderr, "dbd_st_finish\n");
#endif
if (cursbusy[imp_sth->index])
{
cursbusy[imp_sth->index] = 0;
_iqclose(_SQ[imp_sth->index]);
imp_sth->execd = 0;
}
DBIc_ACTIVE_off(imp_sth);
return 1;
}
void
dbd_st_destroy(sth, imp_sth)
SV *sth;
struct imp_sth_st* imp_sth;
{
#if I4DEBUG
fprintf(stderr, "dbd_st_destroy\n");
#endif
/* Free off contents of imp_sth */
if (imp_sth->out_params_av)
sv_free((SV*)imp_sth->out_params_av);
if (imp_sth->all_params_hv) {
HV *hv = imp_sth->all_params_hv;
SV *sv;
char *key;
I32 retlen;
hv_iterinit(hv);
while( (sv = hv_iternextsv(hv, &key, &retlen)) != NULL ) {
if (sv != &sv_undef) {
phs_t *phs_tpl = (phs_t*)(void*)SvPVX(sv);
sv_free(phs_tpl->sv);
}
}
sv_free((SV*)imp_sth->all_params_hv);
}
DBIc_IMPSET_off(imp_sth); /* let DBI know we've done it */
}
int
dbd_st_STORE(sth, imp_sth, keysv, valuesv)
SV *sth;
struct imp_sth_st* imp_sth;
SV *keysv;
SV *valuesv;
{
return dbd_st_STORE_attrib(sth, imp_sth, keysv, valuesv);
}
int
dbd_st_STORE_attrib(sth, imp_sth, keysv, valuesv)
SV *sth;
struct imp_sth_st* imp_sth;
SV *keysv;
SV *valuesv;
{
return FALSE;
}
( run in 0.549 second using v1.01-cache-2.11-cpan-39bf76dae61 )