DBD-Informix4

 view release on metacpan or  search on metacpan

dbdimp.c  view on Meta::CPAN

/*---------------------------------------------------------
 *
 * 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

dbdimp.c  view on Meta::CPAN

    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];

dbdimp.c  view on Meta::CPAN

      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 )