Author: turnstep
Date: Tue Jul 10 17:11:47 2007
New Revision: 9721
Modified:
DBD-Pg/trunk/dbdimp.c
Log:
More cleanups and rearrangements
Modified: DBD-Pg/trunk/dbdimp.c
==============================================================================
--- DBD-Pg/trunk/dbdimp.c (original)
+++ DBD-Pg/trunk/dbdimp.c Tue Jul 10 17:11:47 2007
@@ -598,9 +598,7 @@
/* ================================================================== */
-void dbd_db_destroy (dbh, imp_dbh)
- SV *dbh;
- imp_dbh_t *imp_dbh;
+void dbd_db_destroy (SV * dbh, imp_dbh_t * imp_dbh)
{
if (dbis->debug >= 4) { (void)PerlIO_printf(DBILOGFP, "dbdpg:
dbd_db_destroy\n"); }
@@ -617,10 +615,129 @@
/* ================================================================== */
-int dbd_db_STORE_attrib (SV * dbh, imp_dbh_t * imp_dbh, SV * keysv, SV *
valuesv)
+SV * dbd_db_FETCH_attrib (SV * dbh, imp_dbh_t * imp_dbh, SV * keysv)
{
STRLEN kl;
- char *key = SvPV(keysv,kl);
+ char * key = SvPV(keysv,kl);
+ SV * retsv = Nullsv;
+
+ if (dbis->debug >= 4)
+ (void)PerlIO_printf(DBILOGFP, "dbdpg: dbd_db_FETCH (%s)
dbh=%d\n", key, dbh);
+
+ switch (kl) {
+
+ case 5: /* pg_db */
+
+ if (strEQ("pg_db", key))
+ retsv = newSVpv(PQdb(imp_dbh->conn),0);
+ break;
+
+ case 6: /* pg_pid */
+
+ if (strEQ("pg_pid", key))
+ retsv = newSViv((IV)PQbackendPID(imp_dbh->conn));
+ break;
+
+ case 7: /* pg_user pg_pass pg_port pg_host */
+
+ if (strEQ("pg_user", key))
+ retsv = newSVpv(PQuser(imp_dbh->conn),0);
+ else if (strEQ("pg_pass", key))
+ retsv = newSVpv(PQpass(imp_dbh->conn),0);
+ else if (strEQ("pg_port", key))
+ retsv = newSVpv(PQport(imp_dbh->conn),0);
+ else if (strEQ("pg_host", key)) {
+ retsv = PQhost(imp_dbh->conn) ?
newSVpv(PQhost(imp_dbh->conn),0) : Nullsv;
+ }
+ break;
+
+ case 9: /* pg_socket */
+
+ if (strEQ("pg_socket", key))
+ retsv = newSViv((IV)PQsocket(imp_dbh->conn));
+ break;
+
+ case 10: /* AutoCommit pg_bool_tf pg_pid_number pg_options */
+
+ if (strEQ("AutoCommit", key))
+ retsv = boolSV(DBIc_has(imp_dbh, DBIcf_AutoCommit));
+ else if (strEQ("pg_bool_tf", key))
+ retsv = newSViv((IV)imp_dbh->pg_bool_tf);
+ else if (strEQ("pg_pid_number", key))
+ retsv = newSViv((IV)imp_dbh->pid_number);
+ else if (strEQ("pg_options", key))
+ retsv = newSVpv(PQoptions(imp_dbh->conn),0);
+ break;
+
+ case 11: /* pg_INV_READ pg_protocol */
+
+ if (strEQ("pg_INV_READ", key))
+ retsv = newSViv((IV)INV_READ);
+ else if (strEQ("pg_protocol", key))
+ retsv = newSViv((IV)imp_dbh->pg_protocol);
+ break;
+
+ case 12: /* pg_INV_WRITE */
+
+ if (strEQ("pg_INV_WRITE", key))
+ retsv = newSViv((IV) INV_WRITE );
+ break;
+
+ case 13: /* pg_errorlevel */
+
+ if (strEQ("pg_errorlevel", key))
+ retsv = newSViv((IV)imp_dbh->pg_errorlevel);
+ break;
+
+ case 14: /* pg_lib_version pg_prepare_now pg_enable_utf8 */
+
+ if (strEQ("pg_lib_version", key))
+ retsv = newSViv((IV) PGLIBVERSION );
+ else if (strEQ("pg_prepare_now", key))
+ retsv = newSViv((IV)imp_dbh->prepare_now);
+#ifdef is_utf8_string
+ else if (strEQ("pg_enable_utf8", key))
+ retsv = newSViv((IV)imp_dbh->pg_enable_utf8);
+#endif
+ break;
+
+ case 15: /* pg_default_port */
+
+ if (strEQ("pg_default_port", key))
+ retsv = newSViv((IV) PGDEFPORT );
+ break;
+
+ case 17: /* pg_server_prepare pg_server_version */
+
+ if (strEQ("pg_server_prepare", key))
+ retsv = newSViv((IV)imp_dbh->server_prepare);
+ else if (strEQ("pg_server_version", key))
+ retsv = newSViv((IV)imp_dbh->pg_server_version);
+ break;
+
+ case 25: /* pg_placeholder_dollaronly */
+
+ if (strEQ("pg_placeholder_dollaronly", key))
+ retsv = newSViv((IV)imp_dbh->dollaronly);
+ break;
+ }
+
+ if (!retsv)
+ return Nullsv;
+
+ if (retsv == &sv_yes || retsv == &sv_no) {
+ return retsv; /* no need to mortalize yes or no */
+ }
+ return sv_2mortal(retsv);
+
+} /* end of dbd_db_FETCH_attrib */
+
+
+/* ================================================================== */
+int dbd_db_STORE_attrib (SV * dbh, imp_dbh_t * imp_dbh, SV * keysv, SV *
valuesv)
+{
+ STRLEN kl;
+ char * key = SvPV(keysv,kl);
unsigned int newval = SvTRUE(valuesv);
if (dbis->debug >= 4)
@@ -702,185 +819,383 @@
/* ================================================================== */
-SV * dbd_db_FETCH_attrib (SV * dbh, imp_dbh_t * imp_dbh, SV * keysv)
+SV * dbd_st_FETCH_attrib (SV * sth, imp_sth_t * imp_sth, SV * keysv)
{
- STRLEN kl;
- char *key = SvPV(keysv,kl);
- SV *retsv = Nullsv;
- char *host = NULL;
-
+ STRLEN kl;
+ char * key = SvPV(keysv,kl);
+ SV * retsv = Nullsv;
+ int fields, x;
+
if (dbis->debug >= 4)
- (void)PerlIO_printf(DBILOGFP, "dbdpg: dbd_db_FETCH (%s)
dbh=%d\n", key, dbh);
+ (void)PerlIO_printf(DBILOGFP, "dbdpg: dbd_st_FETCH (%s)
sth=%d\n", key, sth);
+ /* Some can be done before we have a result: */
switch (kl) {
- case 5: /* pg_db */
+ case 9: /* pg_direct */
- if (strEQ("pg_db", key))
- retsv = newSVpv(PQdb(imp_dbh->conn),0);
+ if (strEQ("pg_direct", key))
+ retsv = newSViv((IV)imp_sth->direct);
break;
- case 6: /* pg_pid */
+ case 10: /* ParamTypes pg_segments */
- if (strEQ("pg_pid", key))
- retsv = newSViv((IV)PQbackendPID(imp_dbh->conn));
+ if (strEQ("ParamTypes", key)) {
+ HV *pvhv = newHV();
+ ph_t *currph;
+ int i;
+ for (i=0,currph=imp_sth->ph; NULL != currph;
currph=currph->nextph,i++) {
+ if (NULL == currph->bind_type) {
+ (void)hv_store_ent
+ (pvhv,
(3==imp_sth->placeholder_type ? newSVpv(currph->fooname,0) : newSViv(i+1)),
+ newSV(0), 0);
+ }
+ else {
+ (void)hv_store_ent
+ (pvhv,
(3==imp_sth->placeholder_type ? newSVpv(currph->fooname,0) : newSViv(i+1)),
+
newSVpv(currph->bind_type->type_name,0),0);
+ }
+ }
+ retsv = newRV_noinc((SV*)pvhv);
+ }
+ else if (strEQ("pg_segments", key)) {
+ AV *arr = newAV();
+ seg_t *currseg;
+ int i;
+ for (i=0,currseg=imp_sth->seg; NULL != currseg;
currseg=currseg->nextseg,i++) {
+ av_push(arr, newSVpv(currseg->segment ?
currseg->segment : "NULL",0));
+ }
+ retsv = newRV_noinc((SV*)arr);
+ }
break;
- case 7: /* pg_user pg_pass pg_port pg_host */
+ case 11: /* ParamValues */
- if (strEQ("pg_user", key))
- retsv = newSVpv(PQuser(imp_dbh->conn),0);
- else if (strEQ("pg_pass", key))
- retsv = newSVpv(PQpass(imp_dbh->conn),0);
- else if (strEQ("pg_port", key))
- retsv = newSVpv(PQport(imp_dbh->conn),0);
- else if (strEQ("pg_host", key)) {
- host = PQhost(imp_dbh->conn); /* May return null */
- if (NULL==host)
- return Nullsv;
- retsv = newSVpv(host,0);
+ if (strEQ("ParamValues", key)) {
+ HV *pvhv = newHV();
+ ph_t *currph;
+ int i;
+ for (i=0,currph=imp_sth->ph; NULL != currph;
currph=currph->nextph,i++) {
+ if (NULL == currph->value) {
+ (void)hv_store_ent
+ (pvhv,
+ (3==imp_sth->placeholder_type
? newSVpv(currph->fooname,0) : newSViv(i+1)),
+ newSV(0), 0);
+ }
+ else {
+ (void)hv_store_ent
+ (pvhv,
+ (3==imp_sth->placeholder_type
? newSVpv(currph->fooname,0) : newSViv(i+1)),
+ newSVpv(currph->value,0),0);
+ }
+ }
+ retsv = newRV_noinc((SV*)pvhv);
}
break;
- case 9: /* pg_socket */
+ case 14: /* pg_prepare_now */
- if (strEQ("pg_socket", key))
- retsv = newSViv((IV)PQsocket(imp_dbh->conn));
+ if (strEQ("pg_prepare_now", key))
+ retsv = newSViv((IV)imp_sth->prepare_now);
break;
- case 10: /* AutoCommit pg_bool_tf pg_pid_number pg_options */
+ case 15: /* pg_prepare_name */
- if (strEQ("AutoCommit", key))
- retsv = boolSV(DBIc_has(imp_dbh, DBIcf_AutoCommit));
- else if (strEQ("pg_bool_tf", key))
- retsv = newSViv((IV)imp_dbh->pg_bool_tf);
- else if (strEQ("pg_pid_number", key))
- retsv = newSViv((IV)imp_dbh->pid_number);
- else if (strEQ("pg_options", key))
- retsv = newSVpv(PQoptions(imp_dbh->conn),0);
+ if (strEQ("pg_prepare_name", key))
+ retsv = newSVpv((char *)imp_sth->prepare_name, 0);
break;
- case 11: /* pg_INV_READ */
+ case 17: /* pg_server_prepare */
- if (strEQ("pg_INV_READ", key))
- retsv = newSViv((IV)INV_READ);
- else if (strEQ("pg_protocol", key))
- retsv = newSViv((IV)imp_dbh->pg_protocol);
+ if (strEQ("pg_server_prepare", key))
+ retsv = newSViv((IV)imp_sth->server_prepare);
break;
- case 12: /* pg_INV_WRITE */
+ case 25: /* pg_placeholder_dollaronly */
- if (strEQ("pg_INV_WRITE", key))
- retsv = newSViv((IV) INV_WRITE );
+ if (strEQ("pg_placeholder_dollaronly", key))
+ retsv = newSViv((IV)imp_sth->dollaronly);
break;
- case 13: /* pg_errorlevel */
+ }
- if (strEQ("pg_errorlevel", key))
- retsv = newSViv((IV)imp_dbh->pg_errorlevel);
+ if (retsv != Nullsv)
+ return retsv;
+
+ if (! imp_sth->result) {
+ if (dbis->debug >= 1)
+ (void)PerlIO_printf(DBILOGFP, "dbdpg: Cannot fetch
value of %s pre-execute\n", key);
+ return Nullsv;
+ }
+
+ fields = DBIc_NUM_FIELDS(imp_sth);
+
+ switch (kl) {
+
+ case 4: /* NAME TYPE */
+
+ if (strEQ("NAME", key)) {
+ AV *av = newAV();
+ retsv = newRV(sv_2mortal((SV*)av));
+ while(--fields >= 0) {
+ (void)av_store(av, fields,
newSVpv(PQfname(imp_sth->result, fields),0));
+ }
+ }
+ else if (strEQ("TYPE", key)) {
+ /* Need to convert the Pg type to ANSI/SQL type. */
+ sql_type_info_t * type_info;
+ AV *av = newAV();
+ retsv = newRV(sv_2mortal((SV*)av));
+ while(--fields >= 0) {
+ type_info =
pg_type_data((int)PQftype(imp_sth->result, fields));
+ (void)av_store(av, fields, newSViv( type_info ?
type_info->type.sql : 0 ) );
+ }
+ }
break;
- case 14: /* pg_lib_version pg_prepare_now pg_enable_utf8 */
+ case 5: /* SCALE */
- if (strEQ("pg_lib_version", key))
- retsv = newSViv((IV) PGLIBVERSION );
- else if (strEQ("pg_prepare_now", key))
- retsv = newSViv((IV)imp_dbh->prepare_now);
-#ifdef is_utf8_string
- else if (strEQ("pg_enable_utf8", key))
- retsv = newSViv((IV)imp_dbh->pg_enable_utf8);
-#endif
+ if (strEQ("SCALE", key)) {
+ AV *av = newAV();
+ retsv = newRV(sv_2mortal((SV*)av));
+ while(--fields >= 0) {
+ x = PQftype(imp_sth->result, fields);
+ if (NUMERICOID==x) {
+ x = PQfmod(imp_sth->result, fields)-4;
+ (void)av_store(av, fields, newSViv(x %
(x>>16)));
+ }
+ else {
+ (void)av_store(av, fields, &sv_undef);
+ }
+ }
+ }
break;
- case 15: /* pg_default_port */
+ case 7: /* pg_size pg_type */
- if (strEQ("pg_default_port", key))
- retsv = newSViv((IV) PGDEFPORT );
+ if (strEQ("pg_size", key)) {
+ AV *av = newAV();
+ retsv = newRV(sv_2mortal((SV*)av));
+ while(--fields >= 0) {
+ (void)av_store(av, fields,
newSViv(PQfsize(imp_sth->result, fields)));
+ }
+ }
+ else if (strEQ("pg_type", key)) {
+ sql_type_info_t * type_info;
+ AV *av = newAV();
+ retsv = newRV(sv_2mortal((SV*)av));
+ while(--fields >= 0) {
+ type_info =
pg_type_data((int)PQftype(imp_sth->result,fields));
+ (void)av_store(av, fields, newSVpv(type_info ?
type_info->type_name : "unknown", 0));
+ }
+ }
break;
- case 17: /* pg_server_prepare */
+ case 8: /* NULLABLE */
- if (strEQ("pg_server_prepare", key))
- retsv = newSViv((IV)imp_dbh->server_prepare);
- else if (strEQ("pg_server_version", key))
- retsv = newSViv((IV)imp_dbh->pg_server_version);
+ if (strEQ("NULLABLE", key)) {
+ AV *av = newAV();
+ PGresult *result;
+ int status = -1;
+ D_imp_dbh_from_sth;
+ char *statement;
+ int nullable; /* 0 = not nullable, 1 = nullable 2 =
unknown */
+ int y;
+ retsv = newRV(sv_2mortal((SV*)av));
+
+ Newx(statement, 100, char); /* freed below */
+ statement[0] = '\0';
+ while(--fields >= 0) {
+ nullable=2;
+ x = PQftable(imp_sth->result, fields);
+ y = PQftablecol(imp_sth->result, fields);
+ if (InvalidOid != x && y > 0) { /* We know what
table and column this came from */
+ sprintf(statement,
+ "SELECT attnotnull FROM
pg_catalog.pg_attribute WHERE attrelid=%d AND attnum=%d", x, y);
+ statement[strlen(statement)]='\0';
+ result = PQexec(imp_dbh->conn,
statement);
+ status = PQresultStatus(result);
+ if (PGRES_TUPLES_OK == status &&
PQntuples(result)!=0) {
+ switch
(PQgetvalue(result,0,0)[0]) {
+ case 't':
+ nullable = 0;
+ break;
+ case 'f':
+ default:
+ nullable = 1;
+ break;
+ }
+ }
+ PQclear(result);
+ }
+ (void)av_store(av, fields, newSViv(nullable));
+ }
+ Safefree(statement);
+ }
break;
- case 25: /* pg_placeholder_dollaronly */
+ case 9: /* PRECISION */
- if (strEQ("pg_placeholder_dollaronly", key))
- retsv = newSViv((IV)imp_dbh->dollaronly);
+ if (strEQ("PRECISION", key)) {
+ AV *av = newAV();
+ int sz = 0;
+ retsv = newRV(sv_2mortal((SV*)av));
+ while(--fields >= 0) {
+ x = PQftype(imp_sth->result, fields);
+ switch (x) {
+ case BPCHAROID:
+ case VARCHAROID:
+ sz = PQfmod(imp_sth->result, fields);
+ break;
+ case NUMERICOID:
+ sz = PQfmod(imp_sth->result, fields)-4;
+ if (sz > 0)
+ sz = sz >> 16;
+ break;
+ default:
+ sz = PQfsize(imp_sth->result, fields);
+ break;
+ }
+ (void)av_store(av, fields, sz > 0 ? newSViv(sz)
: &sv_undef);
+ }
+ }
+ break;
+
+ case 10: /* CursorName */
+
+ if (strEQ("CursorName", key))
+ retsv = &sv_undef;
+ break;
+
+ case 11: /* RowsInCache */
+
+ if (strEQ("RowsInCache", key))
+ retsv = &sv_undef;
break;
+
+ case 13: /* pg_oid_status pg_cmd_status */
+ if (strEQ("pg_oid_status", key))
+ retsv = newSVuv((unsigned
int)PQoidValue(imp_sth->result));
+ else if (strEQ("pg_cmd_status", key))
+ retsv = newSVpv((char *)PQcmdStatus(imp_sth->result),
0);
+ break;
+
}
-
- if (!retsv)
+
+ if (retsv == Nullsv)
return Nullsv;
-
- if (retsv == &sv_yes || retsv == &sv_no) {
- return retsv; /* no need to mortalize yes or no */
- }
+
return sv_2mortal(retsv);
-} /* end of dbd_db_FETCH_attrib */
+} /* end of dbd_st_FETCH_attrib */
/* ================================================================== */
-int dbd_discon_all (drh, imp_drh)
- SV *drh;
- imp_drh_t *imp_drh;
+int dbd_st_STORE_attrib (SV * sth, imp_sth_t * imp_sth, SV * keysv, SV *
valuesv)
{
+ STRLEN kl;
+ char * key = SvPV(keysv,kl);
+ STRLEN vl;
+ char * value = SvPV(valuesv,vl);
+ // unsigned int newval = SvTRUE(valuesv);
+
+ if (dbis->debug >= 4)
+ (void)PerlIO_printf(DBILOGFP, "dbdpg: dbd_st_STORE (%s) (%s)
sth=%d\n", key, value, sth);
- if (dbis->debug >= 4) { (void)PerlIO_printf(DBILOGFP, "dbdpg:
dbd_discon_all drh=%d\n", drh); }
+ switch (kl) {
+
+ case 14: /* pg_prepare_now */
+
+ if (strEQ("pg_prepare_now", key)) {
+ imp_sth->prepare_now = strEQ(value,"0") ? DBDPG_FALSE :
DBDPG_TRUE;
+ return 1;
+ }
+
+ case 15: /* pg_prepare_name */
+
+ if (strEQ("pg_prepare_name", key)) {
+ Safefree(imp_sth->prepare_name);
+ Newx(imp_sth->prepare_name, vl+1, char); /* freed in
dbd_st_destroy */
+ Copy(value, imp_sth->prepare_name, vl, char);
+ imp_sth->prepare_name[vl] = '\0';
+ return 1;
+ }
+
+ case 17: /* pg_server_prepare*/
+
+ if (strEQ("pg_server_prepare", key)) {
+ imp_sth->server_prepare = strEQ(value,"0") ?
DBDPG_FALSE : DBDPG_TRUE;
+ return 1;
+ }
+
+ case 25: /* pg_placeholder_dollaronly */
+
+ if (strEQ("pg_placeholder_dollaronly", key)) {
+ imp_sth->dollaronly = SvTRUE(valuesv) ? DBDPG_TRUE :
DBDPG_FALSE;
+ return 1;
+ }
+ }
+
+ return 0;
+
+
+} /* end of sbs_st_STORE_attrib */
+
+
+/* ================================================================== */
+int dbd_discon_all (SV * drh, imp_drh_t * imp_drh)
+{
+ if (dbis->debug >= 4)
+ (void)PerlIO_printf(DBILOGFP, "dbdpg: dbd_discon_all drh=%d\n",
drh);
+
/* The disconnect_all concept is flawed and needs more work */
if (!PL_dirty && !SvTRUE(perl_get_sv("DBI::PERL_ENDING",0))) {
sv_setiv(DBIc_ERR(imp_drh), (IV)1);
sv_setpv(DBIc_ERRSTR(imp_drh), "disconnect_all not
implemented");
}
- return DBDPG_FALSE;
+
+ return 0;
} /* end of dbd_discon_all */
+// XXX IS this really needed die to $dbh->{pg_socket}?
/* ================================================================== */
-int dbd_db_getfd (dbh, imp_dbh)
- SV *dbh;
- imp_dbh_t *imp_dbh;
+int dbd_db_getfd (SV * dbh, imp_dbh_t * imp_dbh)
{
- if (dbis->debug >= 4) { (void)PerlIO_printf(DBILOGFP, "dbdpg:
dbd_db_getfd dbh=%d\n", dbh); }
-
+ if (dbis->debug >= 4)
+ (void)PerlIO_printf(DBILOGFP, "dbdpg: dbd_db_getfd dbh=%d\n",
dbh);
+
return PQsocket(imp_dbh->conn);
} /* end of dbd_db_getfd */
/* ================================================================== */
-SV * dbd_db_pg_notifies (dbh, imp_dbh)
-SV *dbh;
-imp_dbh_t *imp_dbh;
-{
- PGnotify *notify;
- AV *ret;
- SV *retsv;
- int status;
-
- if (dbis->debug >= 3) { (void)PerlIO_printf(DBILOGFP, "dbdpg:
dbd_db_pg_notifies\n"); }
-
+SV * dbd_db_pg_notifies (SV * dbh, imp_dbh_t * imp_dbh)
+{
+ int status;
+ PGnotify * notify;
+ AV * ret;
+ SV * retsv;
+
+ if (dbis->debug >= 4)
+ (void)PerlIO_printf(DBILOGFP, "dbdpg: dbd_db_pg_notifies\n");
+
status = PQconsumeInput(imp_dbh->conn);
if (0 == status) {
- status = PQstatus(imp_dbh->conn);
- pg_error(dbh, status, PQerrorMessage(imp_dbh->conn));
+ pg_error(dbh, PQstatus(imp_dbh->conn),
PQerrorMessage(imp_dbh->conn));
return &sv_undef;
}
-
+
notify = PQnotifies(imp_dbh->conn);
-
+
if (!notify)
return &sv_undef;
-
+
ret=newAV();
-
av_push(ret, newSVpv(notify->relname,0) );
av_push(ret, newSViv(notify->be_pid) );
@@ -891,49 +1206,49 @@
#endif
retsv = newRV(sv_2mortal((SV*)ret));
-
+
return sv_2mortal(retsv);
} /* end of dbd_db_pg_notifies */
/* ================================================================== */
-int dbd_st_prepare (sth, imp_sth, statement, attribs)
- SV *sth;
- imp_sth_t *imp_sth;
- char *statement;
- SV *attribs; /* hashref of arguments passed to prepare */
+int dbd_st_prepare (SV * sth, imp_sth_t * imp_sth, char * statement, SV *
attribs)
{
-
D_imp_dbh_from_sth;
STRLEN mypos=0, wordstart, newsize; /* Used to find and set firstword */
SV **svp; /* To help parse the arguments */
- if (dbis->debug >= 4) { (void)PerlIO_printf(DBILOGFP, "dbdpg:
dbd_st_prepare (%s)\n", statement); }
+ if (dbis->debug >= 4)
+ (void)PerlIO_printf(DBILOGFP, "dbdpg: dbd_st_prepare (%s)\n",
statement);
/* Set default values for this statement handle */
- imp_sth->is_dml = DBDPG_FALSE; /* Not preparable DML until proved
otherwise */
- imp_sth->prepared_by_us = DBDPG_FALSE; /* Set to 1 when actually done
preparing */
- imp_sth->has_binary = DBDPG_FALSE; /* Are any of the params binary? */
- imp_sth->has_default = DBDPG_FALSE; /* Are any of the params DEFAULT? */
- imp_sth->has_current = DBDPG_FALSE; /* Are any of the params DEFAULT? */
- imp_sth->onetime = DBDPG_FALSE; /* Allow internal shortcut */
- imp_sth->result = NULL;
- imp_sth->cur_tuple = 0;
imp_sth->placeholder_type = 0;
- imp_sth->rows = -1;
- imp_sth->totalsize = 0;
- imp_sth->numsegs = imp_sth->numphs = imp_sth->numbound = 0;
- imp_sth->direct = DBDPG_FALSE;
- imp_sth->prepare_name = NULL;
- imp_sth->seg = NULL;
- imp_sth->ph = NULL;
- imp_sth->type_info = NULL;
+ imp_sth->numsegs = 0;
+ imp_sth->numphs = 0;
+ imp_sth->numbound = 0;
+ imp_sth->cur_tuple = 0;
+ imp_sth->rows = -1; /* per DBI spec */
+ imp_sth->totalsize = 0;
+ imp_sth->prepare_name = NULL;
+ imp_sth->firstword = NULL;
+ imp_sth->result = NULL;
+ imp_sth->type_info = NULL;
+ imp_sth->seg = NULL;
+ imp_sth->ph = NULL;
+ imp_sth->prepared_by_us = DBDPG_FALSE; /* Set to 1 when actually done
preparing */
+ imp_sth->onetime = DBDPG_FALSE; /* Allow internal shortcut */
+ imp_sth->direct = DBDPG_FALSE;
+ imp_sth->is_dml = DBDPG_FALSE; /* Not preparable DML until
proved otherwise */
+ imp_sth->has_binary = DBDPG_FALSE; /* Are any of the params
binary? */
+ imp_sth->has_default = DBDPG_FALSE; /* Are any of the params
DEFAULT? */
+ imp_sth->has_current = DBDPG_FALSE; /* Are any of the params
DEFAULT? */
+
/* We inherit some preferences from the database handle */
- imp_sth->server_prepare = imp_dbh->server_prepare;
- imp_sth->prepare_now = imp_dbh->prepare_now;
- imp_sth->dollaronly = imp_dbh->dollaronly;
+ imp_sth->server_prepare = imp_dbh->server_prepare;
+ imp_sth->prepare_now = imp_dbh->prepare_now;
+ imp_sth->dollaronly = imp_dbh->dollaronly;
/* Parse and set any attributes passed in */
if (attribs) {
@@ -961,22 +1276,20 @@
mypos++;
statement++;
}
- if ((*statement=='\0') || !isALPHA(*statement)) {
- imp_sth->firstword = NULL;
- }
- else {
+ if (isALPHA(*statement)) {
wordstart = mypos;
- while((*statement!='\0') && isALPHA(*statement)) {
+ while (isALPHA(*statement)) {
mypos++;
statement++;
}
newsize = mypos-wordstart;
- New(0, imp_sth->firstword, newsize+1, char); /* freed in
dbd_st_destroy, and above */
- Copy(statement-newsize,imp_sth->firstword,newsize,char);
+ Newx(imp_sth->firstword, newsize+1, char); /* freed in
dbd_st_destroy */
+ Copy(statement-newsize, imp_sth->firstword, newsize, char);
imp_sth->firstword[newsize] = '\0';
+
/* Try to prevent transaction commands unless "pg_direct" is
set */
- if (0==strcasecmp(imp_sth->firstword, "END") ||
- 0==strcasecmp(imp_sth->firstword, "BEGIN") ||
+ if (0==strcasecmp(imp_sth->firstword, "BEGIN") ||
+ 0==strcasecmp(imp_sth->firstword, "END") ||
0==strcasecmp(imp_sth->firstword, "ABORT") ||
0==strcasecmp(imp_sth->firstword, "COMMIT") ||
0==strcasecmp(imp_sth->firstword, "ROLLBACK") ||
@@ -985,7 +1298,6 @@
) {
if (!imp_sth->direct)
croak ("Please use DBI functions for
transaction handling");
- imp_sth->is_dml = DBDPG_TRUE; /* Close enough for our
purposes */
}
/* Note whether this is preparable DML */
if (0==strcasecmp(imp_sth->firstword, "SELECT") ||
@@ -1010,12 +1322,10 @@
5. The attribute "pg_prepare_now" is true
6. We are compiled on a 8 or greater server
*/
- if (dbis->debug >= 6)
- (void)PerlIO_printf
- (DBILOGFP,
- "dbdpg: Immediate prepare decision: dml=%d direct=%d
protocol=%d server_prepare=%d prepare_now=%d PGLIBVERSION=%d\n",
- imp_sth->is_dml, imp_sth->direct,
imp_dbh->pg_protocol, imp_sth->server_prepare, imp_sth->prepare_now,
PGLIBVERSION
- );
+ if (dbis->debug >= 5)
+ (void)PerlIO_printf(DBILOGFP,
+ "dbdpg: Immediate prepare decision: dml=%d direct=%d protocol=%d
server_prepare=%d prepare_now=%d PGLIBVERSION=%d\n",
+ imp_sth->is_dml, imp_sth->direct, imp_dbh->pg_protocol,
imp_sth->server_prepare, imp_sth->prepare_now, PGLIBVERSION);
if (imp_sth->is_dml
&& !imp_sth->direct
@@ -1034,16 +1344,13 @@
DBIc_IMPSET_on(imp_sth);
- return imp_sth->numphs;
+ return 1;
} /* end of dbd_st_prepare */
/* ================================================================== */
-static void dbd_st_split_statement (imp_sth, version, statement)
- imp_sth_t *imp_sth;
- int version;
- char *statement;
+static void dbd_st_split_statement (imp_sth_t * imp_sth, int version, char *
statement)
{
/* Builds the "segment" and "placeholder" structures for a statement
handle */
@@ -2581,246 +2888,6 @@
} /* end of dbd_st_destroy */
-/* ================================================================== */
-int dbd_st_STORE_attrib (sth, imp_sth, keysv, valuesv)
- SV *sth;
- imp_sth_t *imp_sth;
- SV *keysv;
- SV *valuesv;
-{
- STRLEN kl;
- char *key = SvPV(keysv,kl);
- STRLEN vl;
- char *value = SvPV(valuesv,vl);
-
- if (dbis->debug >= 4) { (void)PerlIO_printf(DBILOGFP, "dbdpg:
dbd_st_STORE (%s) (%s) sth=%d\n", key, value, sth); }
-
- if (17==kl && strEQ(key, "pg_server_prepare")) {
- imp_sth->server_prepare = strEQ(value,"0") ? DBDPG_FALSE :
DBDPG_TRUE;
- }
- else if (14==kl && strEQ(key, "pg_prepare_now")) {
- imp_sth->prepare_now = strEQ(value,"0") ? DBDPG_FALSE :
DBDPG_TRUE;
- }
- else if (25==kl && strEQ(key, "pg_placeholder_dollaronly")) {
- imp_sth->dollaronly = SvTRUE(valuesv) ? DBDPG_TRUE :
DBDPG_FALSE;
- }
- else if (15==kl && strEQ(key, "pg_prepare_name")) {
- Safefree(imp_sth->prepare_name);
- New(0, imp_sth->prepare_name, vl+1, char); /* freed in
dbd_st_destroy (and above) */
- Copy(value, imp_sth->prepare_name, vl, char);
- imp_sth->prepare_name[vl] = '\0';
- }
- else {
- return 0;
- }
- return 1;
-
-} /* end of sbs_st_STORE_attrib */
-
-
-/* ================================================================== */
-SV * dbd_st_FETCH_attrib (sth, imp_sth, keysv)
-SV *sth;
-imp_sth_t *imp_sth;
-SV *keysv;
-{
- STRLEN kl;
- char *key = SvPV(keysv,kl);
- int i, x, y, sz;
- SV *retsv = Nullsv;
- sql_type_info_t *type_info;
-
- if (dbis->debug >= 4) { (void)PerlIO_printf(DBILOGFP, "dbdpg:
dbd_st_FETCH (%s) sth=%d\n", key, sth); }
-
- /* Some can be done before the execute */
- if (15==kl && strEQ(key, "pg_prepare_name")) {
- retsv = newSVpv((char *)imp_sth->prepare_name, 0);
- return retsv;
- }
- else if (17==kl && strEQ(key, "pg_server_prepare")) {
- retsv = newSViv((IV)imp_sth->server_prepare);
- return retsv;
- }
- else if (14==kl && strEQ(key, "pg_prepare_now")) {
- retsv = newSViv((IV)imp_sth->prepare_now);
- return retsv;
- }
- else if (11==kl && strEQ(key, "ParamValues")) {
- HV *pvhv = newHV();
- ph_t *currph;
- for (i=0,currph=imp_sth->ph; NULL != currph;
currph=currph->nextph,i++) {
- if (NULL == currph->value) {
- (void)hv_store_ent
- (pvhv,
- (3==imp_sth->placeholder_type ?
newSVpv(currph->fooname,0) : newSViv(i+1)),
- newSV(0), 0);
- }
- else {
- (void)hv_store_ent
- (pvhv,
- (3==imp_sth->placeholder_type ?
newSVpv(currph->fooname,0) : newSViv(i+1)),
- newSVpv(currph->value,0),0);
- }
- }
- retsv = newRV_noinc((SV*)pvhv);
- return retsv;
- }
- else if (10==kl && strEQ(key, "ParamTypes")) {
- HV *pvhv = newHV();
- ph_t *currph;
- for (i=0,currph=imp_sth->ph; NULL != currph;
currph=currph->nextph,i++) {
- if (NULL == currph->bind_type) {
- (void)hv_store_ent
- (pvhv, (3==imp_sth->placeholder_type ?
newSVpv(currph->fooname,0) : newSViv(i+1)),
- newSV(0), 0);
- }
- else {
- (void)hv_store_ent
- (pvhv, (3==imp_sth->placeholder_type ?
newSVpv(currph->fooname,0) : newSViv(i+1)),
-
newSVpv(currph->bind_type->type_name,0),0);
- }
- }
- retsv = newRV_noinc((SV*)pvhv);
- return retsv;
- }
- else if (11==kl && strEQ(key, "pg_segments")) {
- AV *arr = newAV();
- seg_t *currseg;
- for (i=0,currseg=imp_sth->seg; NULL != currseg;
currseg=currseg->nextseg,i++) {
- av_push(arr, newSVpv(currseg->segment ?
currseg->segment : "NULL",0));
- }
- retsv = newRV_noinc((SV*)arr);
- return retsv;
- }
-
- if (! imp_sth->result) {
- return Nullsv;
- }
- i = DBIc_NUM_FIELDS(imp_sth);
-
- if (4==kl && strEQ(key, "NAME")) {
- AV *av = newAV();
- retsv = newRV(sv_2mortal((SV*)av));
- while(--i >= 0) {
- (void)av_store(av, i, newSVpv(PQfname(imp_sth->result,
i),0));
- }
- }
- else if (4==kl && strEQ(key, "TYPE")) {
- /* Need to convert the Pg type to ANSI/SQL type. */
- AV *av = newAV();
- retsv = newRV(sv_2mortal((SV*)av));
- while(--i >= 0) {
- type_info = pg_type_data((int)PQftype(imp_sth->result,
i));
- (void)av_store(av, i, newSViv( type_info ?
type_info->type.sql : 0 ) );
- }
- }
- else if (9==kl && strEQ(key, "PRECISION")) {
- AV *av = newAV();
- retsv = newRV(sv_2mortal((SV*)av));
- while(--i >= 0) {
- x = PQftype(imp_sth->result, i);
- switch (x) {
- case BPCHAROID:
- case VARCHAROID:
- sz = PQfmod(imp_sth->result, i);
- break;
- case NUMERICOID:
- sz = PQfmod(imp_sth->result, i)-4;
- if (sz > 0)
- sz = sz >> 16;
- break;
- default:
- sz = PQfsize(imp_sth->result, i);
- break;
- }
- (void)av_store(av, i, sz > 0 ? newSViv(sz) : &sv_undef);
- }
- }
- else if (5==kl && strEQ(key, "SCALE")) {
- AV *av = newAV();
- retsv = newRV(sv_2mortal((SV*)av));
- while(--i >= 0) {
- x = PQftype(imp_sth->result, i);
- if (NUMERICOID==x) {
- x = PQfmod(imp_sth->result, i)-4;
- (void)av_store(av, i, newSViv(x % (x>>16)));
- }
- else {
- (void)av_store(av, i, &sv_undef);
- }
- }
- }
- else if (8==kl && strEQ(key, "NULLABLE")) {
- AV *av = newAV();
- PGresult *result;
- int status = -1;
- D_imp_dbh_from_sth;
- char *statement;
- int nullable; /* 0 = not nullable, 1 = nullable 2 = unknown */
- retsv = newRV(sv_2mortal((SV*)av));
-
- New(0, statement, 100, char); /* freed below */
- statement[0] = '\0';
- while(--i >= 0) {
- nullable=2;
- x = PQftable(imp_sth->result, i);
- y = PQftablecol(imp_sth->result, i);
- if (InvalidOid != x && y > 0) { /* We know what table
and column this came from */
- sprintf(statement, "SELECT attnotnull FROM
pg_catalog.pg_attribute WHERE attrelid=%d AND attnum=%d", x, y);
- statement[strlen(statement)]='\0';
- result = PQexec(imp_dbh->conn, statement);
- status = PQresultStatus(result);
- if (PGRES_TUPLES_OK == status &&
PQntuples(result)!=0) {
- switch (PQgetvalue(result,0,0)[0]) {
- case 't':
- nullable = 0;
- break;
- case 'f':
- default:
- nullable = 1;
- break;
- }
- }
- PQclear(result);
- }
- (void)av_store(av, i, newSViv(nullable));
- }
- Safefree(statement);
- }
- else if (10==kl && strEQ(key, "CursorName")) {
- retsv = &sv_undef;
- }
- else if (11==kl && strEQ(key, "RowsInCache")) {
- retsv = &sv_undef;
- }
- else if (7==kl && strEQ(key, "pg_size")) {
- AV *av = newAV();
- retsv = newRV(sv_2mortal((SV*)av));
- while(--i >= 0) {
- (void)av_store(av, i, newSViv(PQfsize(imp_sth->result,
i)));
- }
- }
- else if (7==kl && strEQ(key, "pg_type")) {
- AV *av = newAV();
- retsv = newRV(sv_2mortal((SV*)av));
- while(--i >= 0) {
- type_info =
pg_type_data((int)PQftype(imp_sth->result,i));
- (void)av_store(av, i, newSVpv(type_info ?
type_info->type_name : "unknown", 0));
- }
- }
- else if (13==kl && strEQ(key, "pg_oid_status")) {
- retsv = newSVuv((unsigned int)PQoidValue(imp_sth->result));
- }
- else if (13==kl && strEQ(key, "pg_cmd_status")) {
- retsv = newSVpv((char *)PQcmdStatus(imp_sth->result), 0);
- }
- else {
- return Nullsv;
- }
-
- return sv_2mortal(retsv);
-
-} /* end of dbd_st_FETCH_attrib */
/* ================================================================== */