G:/ScriptBasic/source/extensions/psql/interface.c

Go to the documentation of this file.
00001 /* FILE:pgsqlinterface.c
00002  *
00003  * by pts@fazekas.hu at Wed May  8 17:50:51 CEST 2002
00004  *
00005  * This file implements PostgreSQL 7.0 database inteface functionality using
00006  * the libpq C client library (shipped with the PostgreSQL sources) for the
00007  * ScriptBasic interpreter as an external module.
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018 
00019 UXLIBS: -lpq
00020 #NTLIBS: psql.lib
00021  */
00022 
00023 /* #define PTS_DEBUG 1 */
00024 #define PTS_MODULE "pgsqlinterf.c"
00025 
00026 /* vvv Debian GNU/Linux: /usr/include/postgresql/libpq-fe.h */
00027 #include <postgresql/libpq-fe.h>
00028 #include "../../basext.h"
00029 #include <stdio.h> /* simple debugging */
00030 #include <string.h> /* memcmp() */
00031 #include <stdlib.h> /* free() */
00032 
00033 #ifdef PTS_DEBUG
00034 #  define DEBUGMSG(x) x
00035 #  include <assert.h>
00036 #  undef NDEBUG
00037 #else
00038 #  define DEBUGMSG(x)
00039 #  define assert(x)
00040 #  define NDEBUG 1
00041 #endif
00042 
00043 #ifndef InvalidOid
00044 #define InvalidOid 0
00045 #endif
00046 
00047 typedef enum _TY {
00048   CON=1,
00049   RES=2,
00050 } TY;
00051 
00052 struct _Wrapper;
00053 typedef struct _Wrapper {
00054   union {
00055     PGconn   *con;
00056     PGresult *res;
00057   } u;
00058   struct _Wrapper *next, *prev; /* non-circular double-linked list */
00059   unsigned long handle; /* stupid scriba interface cannot return it */
00060   TY ty; /* CON or RES */
00061 } Wrapper, *pWrapper;
00062 
00063 typedef struct _ModuleGlobal {
00064   void *ha; /* HandleArray for PGconn and PGresult */
00065   Wrapper *first;
00066   VARIABLE s_keyword, s_envvar, s_compiled, s_val, s_label, s_dispchar, s_dispsize;
00067 } ModuleGlobal, *pModuleGlobal;
00068 
00069 /* Left value argument is needed for the command */
00070 #define PGSQL_ERROR_CON_EXPECTED  0x00081001
00071 #define PGSQL_ERROR_RES_EXPECTED  0x00081002
00072 #define PGSQL_ERROR_HAN_EXPECTED  0x00081003
00073 #define PGSQL_ERROR_CONNGET_KEY   0x00081004
00074 #define PGSQL_ERROR_LVAL_EXPECTED 0x00081005
00075 #define PGSQL_ERROR_EST_EXPECTED  0x00081006
00076 
00077 #define copystr(dst,src) (\
00078   ((dst)=besNEWSTRING(STRLEN(src))) && \
00079   (memcpy(STRINGVALUE(dst),STRINGVALUE(src),STRLEN(src)), 1) \
00080 )
00081 #define copystrz(dst,src) (tmplen=strlen(src), \
00082   ((dst)=besNEWSTRING(tmplen)) && \
00083   (memcpy(STRINGVALUE(dst),src,tmplen), 1) \
00084 )
00085 
00086 #define copystry(dst,src) (src ? (tmplen=strlen(src), \
00087   ((dst)=besNEWSTRING(tmplen)) && \
00088   (memcpy(STRINGVALUE(dst),src,tmplen), 1) \
00089 ) : ((dst)=NULL, 1) )
00090 #define copylong(dst,src) (\
00091   ((dst)=besNEWLONG) && \
00092   (LONGVALUE(dst)=src, 1) \
00093 )
00094 #define streq(var,strz) \
00095   (STRLEN(var)==strlen(strz) && 0==memcmp(STRINGVALUE(var),strz,STRLEN(var)))
00096 #define strbegins(var,strz) \
00097   (STRLEN(var)>=strlen(strz) && 0==memcmp(STRINGVALUE(var),strz,strlen(strz)))
00098 
00099 static void stderrNoticeProcessor(void * arg, const char * message) {
00100   (void)arg;
00101   /* Dat: message already contains \n */
00102   fprintf(stderr, "PGSQL: %s", message);
00103 }
00104 static void silentNoticeProcessor(void * arg, const char * message) {
00105   (void)arg;
00106   (void)message;
00107 }
00108 
00109 besSUB_ERRMSG
00110   (void)pSt; (void)ppModuleInternal;
00111   /* assert(0); */
00112   DEBUGMSG(fprintf(stderr, PTS_MODULE": iError=%lx.\n", (long)iError););
00113   switch (iError) {
00114    case PGSQL_ERROR_CON_EXPECTED: return "PGSQL error: PGSQL Connection handle expected";
00115    case PGSQL_ERROR_RES_EXPECTED: return "PGSQL error: PGSQL ResultSet handle expected";
00116    case PGSQL_ERROR_HAN_EXPECTED: return "PGSQL error: PGSQL handle expected";
00117    case PGSQL_ERROR_CONNGET_KEY:  return "PGSQL error: invalid key specified for PGconnget()";
00118    case PGSQL_ERROR_LVAL_EXPECTED:return "PGSQL error: left value expected";
00119    case PGSQL_ERROR_EST_EXPECTED: return "PGSQL error: ExecStatusType expected";
00120   }
00121   return NULL;
00122   /* return "ERRMSG from "PTS_MODULE; */
00123 besEND
00124 
00125 besVERSION_NEGOTIATE
00126   (void)Version; (void)pszVariation; (void)ppModuleInternal;
00127   return (int)INTERFACE_VERSION;
00128 besEND
00129 
00130 besDLL_MAIN
00131 
00132 SUPPORT_MULTITHREAD
00133 
00134 besSUB_PROCESS_START
00135   INIT_MULTITHREAD
00136   (void)lThreadCounter;
00137   DEBUGMSG(fprintf(stderr, PTS_MODULE ": Process Hi!\n"););
00138   return 1;
00139 besEND
00140 
00141 besSUB_PROCESS_FINISH
00142   DEBUGMSG(fprintf(stderr, PTS_MODULE ": Process Bye!\n"););
00143 besEND
00144 
00145 /* Imp: ?? */
00146 besSUB_KEEP
00147   return 0;
00148 besEND
00149 
00150 static MUTEX mutex;
00151 
00152 besSUB_START
00153   unsigned long tmplen;
00154   ModuleGlobal *p;
00155   (void)pEo; (void)pParameters; (void)pReturnValue;
00156   INITLOCK /* Imp: ez kell?? */
00157   besInitMutex(&mutex);
00158   INITUNLO
00159   if (NULL==(besMODULEPOINTER=besALLOC(sizeof*p))) return COMMAND_ERROR_MEMORY_LOW;
00160   p=(ModuleGlobal*)besMODULEPOINTER;
00161   p->ha=NULL;
00162   p->first=NULL;
00163   if (0
00164    || !copystrz(p->s_keyword , "keyword")
00165    || !copystrz(p->s_envvar  , "envvar")
00166    || !copystrz(p->s_compiled, "compiled")
00167    || !copystrz(p->s_val     , "val")
00168    || !copystrz(p->s_label   , "label")
00169    || !copystrz(p->s_dispchar, "dispchar")
00170    || !copystrz(p->s_dispsize, "dispsize")
00171      ) return COMMAND_ERROR_MEMORY_LOW;
00172   DEBUGMSG(fprintf(stderr, PTS_MODULE ": Hi %p!\n", p););
00173 besEND
00174 
00175 besSUB_FINISH
00176   ModuleGlobal *p;
00177   Wrapper *q;
00178   (void)pEo; (void)pParameters; (void)pReturnValue;
00179   DEBUGMSG(fprintf(stderr, PTS_MODULE ": Bye!\n"););
00180   if (NULL!=(p=(ModuleGlobal*)besMODULEPOINTER)) {
00181     /* Dat: PGconn and PGresult are independent */
00182     for (q = p->first ; q ; q = q->next) {
00183       DEBUGMSG(fprintf(stderr, PTS_MODULE ": Finish %p!\n", q););
00184       switch (q->ty) {
00185        case CON: PQfinish(q->u.con); break;
00186        case RES: PQclear (q->u.res); break;
00187        default:  assert(0);
00188       }
00189     }
00190     besHandleDestroyHandleArray(p->ha);
00191   }
00192   #if 0 /* No need to free these because scriba frees them when the memory segment is freed */
00193     pSt->ReleaseVariable(pSt->pEo->pMo, p->s_keyword);
00194     pSt->ReleaseVariable(pSt->pEo->pMo, p->s_envvar);
00195     pSt->ReleaseVariable(pSt->pEo->pMo, p->s_compiled);
00196     pSt->ReleaseVariable(pSt->pEo->pMo, p->s_val);
00197     pSt->ReleaseVariable(pSt->pEo->pMo, p->s_label);
00198     pSt->ReleaseVariable(pSt->pEo->pMo, p->s_dispchar);
00199     pSt->ReleaseVariable(pSt->pEo->pMo, p->s_dispsize);
00200   #endif
00201   return 0;                                                                     
00202 besEND
00203 
00205 static Wrapper *alloc_Wrapper(pSupportTable pSt, ModuleGlobal *mg/*, unsigned long *handle_ret*/) {
00206   Wrapper *w=besALLOC(sizeof*w);
00207   if (w!=NULL) {
00208     DEBUGMSG(fprintf(stderr, PTS_MODULE ": Alloc %p -> %p!\n", mg, w););
00209     besLockMutex(&mutex);
00210     if (mg->first!=NULL) mg->first->prev=w;
00211     w->next=mg->first;
00212     mg->first=w;
00213     w->prev=NULL;
00214     /*if (NULL!=handle_ret) *handle_ret=*/w->handle=besHandleGetHandle(mg->ha, w);
00215     besUnlockMutex(&mutex);
00216   }
00217   return w;
00218 }
00219 
00221 static void delete_Wrapper(pSupportTable pSt, ModuleGlobal *mg, Wrapper *w) {
00222   if (w!=NULL) {
00223     switch (w->ty) {
00224      case CON: PQfinish(w->u.con); break;
00225      case RES: PQclear (w->u.res); break;
00226      default:  assert(0);
00227     }
00228     besLockMutex(&mutex);
00229     if (w->prev!=NULL) w->prev->next=w->next;
00230                   else mg->first=w->next;
00231     if (w->next!=NULL) w->next->prev=w->prev;
00232     assert((w->prev=w->next=NULL, 1)); /* play it safe */
00233     besHandleFreeHandle(mg->ha, w->handle);
00234     besUnlockMutex(&mutex);
00235     DEBUGMSG(fprintf(stderr, PTS_MODULE ": Free %p!\n", w););
00236     besFREE(w);
00237   } 
00238 }
00239 
00240 besFUNCTION(PGopen)
00241   Wrapper *w=NULL;
00242   VARIABLE Argument=besARGUMENT(1); /* 0! */
00243   (void)pEo;
00244   besDEREFERENCE(Argument);
00245   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00246   if (TYPE(Argument)==VTYPE_LONG) { /* PQreset() */
00247     if (NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00248      || w->ty!=CON
00249        ) return PGSQL_ERROR_CON_EXPECTED;
00250     if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00251     PQreset(w->u.con);
00252   } else if (TYPE(Argument)==VTYPE_STRING) { /* PQconnectdb() */
00253     char *specs;
00254     PGconn *con;
00255     if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00256     besCONVERT2ZCHAR(Argument,specs); /* Dat: no automatic sentinel in scriba :-( */
00257     con=PQconnectdb(specs);
00258     /* assert(con!=NULL);: almost always true */
00259     besFREE(specs);
00260     if (!con || PQstatus(con)!=CONNECTION_OK) {
00261       /* printf("conn err=(%s)\n", PQerrorMessage(con)); */
00262       specs=con ? PQerrorMessage(con) : "PQconnectdb() returned NULL";
00263       besALLOC_RETURN_STRING(strlen(specs));
00264       memcpy(STRINGVALUE(besRETURNVALUE),specs,strlen(specs));
00265       if (con) PQfinish(con); /* free mem ?? */
00266       return 0;
00267       /* return COMMAND_ERROR_CHDIR; */
00268     }
00269     if (NULL==(w=alloc_Wrapper(pSt, (ModuleGlobal*)besMODULEPOINTER))) {
00270       PQfinish(con);
00271       return COMMAND_ERROR_MEMORY_LOW;
00272     }
00273     w->ty=CON; w->u.con=con;
00274     PQsetNoticeProcessor(con, stderrNoticeProcessor, con);
00275   }
00276   besALLOC_RETURN_LONG;
00277   LONGVALUE(besRETURNVALUE)=(long)w->handle;
00278   /*return NULL;*/ /*notreached*/
00279 besEND
00280 
00281 besFUNCTION(PGclose)
00282   Wrapper *w;
00283   VARIABLE Argument=besARGUMENT(1); /* 0! */
00284   (void)pEo;
00285   besDEREFERENCE(Argument);
00286   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00287   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00288   /* Dat: automatic type conversion is disabled deliberately (author's taste) */
00289   if (TYPE(Argument)!=VTYPE_LONG || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument))))
00290     return PGSQL_ERROR_HAN_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00291   delete_Wrapper(pSt, (ModuleGlobal*)besMODULEPOINTER, w);
00292   /* besALLOC_RETURN_LONG;  LONGVALUE(besRETURNVALUE)=0; */
00293   besRETURNVALUE=NULL; /* return undef */
00294 besEND
00295 
00296 static int isSSL(PGconn const*c) {
00297 #ifdef USE_SSL
00298   return (SSL*)0!=PQgetssl(c);
00299 #else
00300   (void)c;
00301   return 0;
00302 #endif
00303 }
00304 
00305 besFUNCTION(PGconnget)
00306   char *s=NULL;
00307   Wrapper *w;
00308   VARIABLE Argument=besARGUMENT(1); /* 0! */
00309   VARIABLE Argument2=besARGUMENT(2);
00310   (void)pEo;
00311   besDEREFERENCE(Argument);
00312   besDEREFERENCE(Argument2);
00313   if (besARGNR>2) return EX_ERROR_TOO_MANY_ARGUMENTS;
00314   if (NULL==Argument2) return EX_ERROR_TOO_FEW_ARGUMENTS;
00315   if (TYPE(Argument)!=VTYPE_LONG
00316    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00317    || w->ty!=CON
00318      ) return PGSQL_ERROR_CON_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00319   besCONVERT2STRING(Argument2);
00320   if (STRLEN(Argument2)==2 && 0==memcmp("db", STRINGVALUE(Argument2), 2)) s=PQdb(w->u.con);
00321   else if (STRLEN(Argument2)==4 && 0==memcmp("user", STRINGVALUE(Argument2), 4)) s=PQuser(w->u.con);
00322   else if (STRLEN(Argument2)==4 && 0==memcmp("pass", STRINGVALUE(Argument2), 4)) s=PQpass(w->u.con);
00323   else if (STRLEN(Argument2)==4 && 0==memcmp("host", STRINGVALUE(Argument2), 4)) s=PQhost(w->u.con);
00324   else if (STRLEN(Argument2)==4 && 0==memcmp("port", STRINGVALUE(Argument2), 4)) s=PQport(w->u.con);
00325   else if (STRLEN(Argument2)==3 && 0==memcmp("tty", STRINGVALUE(Argument2), 3)) s=PQtty(w->u.con);
00326   else if (STRLEN(Argument2)==7 && 0==memcmp("options", STRINGVALUE(Argument2), 7)) s=PQoptions(w->u.con);
00327   else {
00328     int pid;
00329     if (STRLEN(Argument2)==7 && 0==memcmp("SSLused", STRINGVALUE(Argument2), 7)) pid=-isSSL(w->u.con);
00330     else if (STRLEN(Argument2)==10 && 0==memcmp("backendPID", STRINGVALUE(Argument2), 10)) pid=PQbackendPID(w->u.con);
00331     else return PGSQL_ERROR_CONNGET_KEY/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00332     besALLOC_RETURN_LONG;
00333     LONGVALUE(besRETURNVALUE)=(long)pid;
00334     return 0;
00335   }
00336   besALLOC_RETURN_STRING(strlen(s));
00337   memcpy(STRINGVALUE(besRETURNVALUE), s, STRLEN(besRETURNVALUE));
00338 besEND
00339 
00340 besFUNCTION(PGok)
00341   /* char *s=NULL; */
00342   ExecStatusType est;
00343   Wrapper *w;
00344   VARIABLE Argument=besARGUMENT(1); /* 0! */
00345   (void)pEo;
00346   besDEREFERENCE(Argument);
00347   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00348   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00349   if (TYPE(Argument)!=VTYPE_LONG
00350    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00351    || (w->ty!=CON && w->ty!=RES)
00352      ) return PGSQL_ERROR_HAN_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00353   besALLOC_RETURN_LONG;
00354   LONGVALUE(besRETURNVALUE)=-(long)(
00355     w->ty==CON ? CONNECTION_OK==PQstatus(w->u.con)
00356                : PGRES_COMMAND_OK==(est=PQresultStatus(w->u.res)) || PGRES_TUPLES_OK==est
00357   );
00358 besEND
00359 
00361 besFUNCTION(PGconndefaults)
00362   unsigned long tmplen;
00363   PQconninfoOption *cio, *p, *cioend;
00364   LEFTVALUE Lval;
00365   VARIABLE Argument=besARGUMENT(1), v;
00366   long __refcount_; /* used by besLEFTVALUE */
00367   (void)pEo;
00368   (void)ppModuleInternal;
00369   /* besDEREFERENCE(Argument); */
00370   /* fprintf(stderr, "%d\n", besARGNR); */
00371   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00372   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00373   /* assert(0); */
00374   besLEFTVALUE(Argument,Lval);
00375   if (!Lval) return PGSQL_ERROR_LVAL_EXPECTED;
00376   besRELEASE(*Lval); *Lval=NULL;
00377 
00378   cio=PQconndefaults();
00379   cioend=cio; while (cioend->keyword!=NULL) cioend++;
00380   if (!(*Lval=besNEWARRAY(0,cioend-cio-1))) { /* min idx, max idx */
00381    outmem:
00382     PQconninfoFree(cio);
00383     return COMMAND_ERROR_MEMORY_LOW;
00384   }
00385   for (p=cio; p!=cioend-3; p++) {
00386     /* Imp: free temp alloced memory, even when out of memory */
00387     /* vvv Imp: really should make refs to ->s_* */
00388     if (!(v=ARRAYVALUE(*Lval,p-cio)=besNEWARRAY(0,13))
00389      || !copystr (ARRAYVALUE(v, 0), ((ModuleGlobal*)besMODULEPOINTER)->s_keyword)
00390      || !copystrz(ARRAYVALUE(v, 1), p->keyword)
00391      || !copystr (ARRAYVALUE(v, 2), ((ModuleGlobal*)besMODULEPOINTER)->s_envvar)
00392      || !copystrz(ARRAYVALUE(v, 3), p->envvar)
00393      || !copystr (ARRAYVALUE(v, 4), ((ModuleGlobal*)besMODULEPOINTER)->s_compiled)
00394      || !copystry(ARRAYVALUE(v, 5), p->compiled)
00395      || !copystr (ARRAYVALUE(v, 6), ((ModuleGlobal*)besMODULEPOINTER)->s_val)
00396      || !copystry(ARRAYVALUE(v, 7), p->val)
00397      || !copystr (ARRAYVALUE(v, 8), ((ModuleGlobal*)besMODULEPOINTER)->s_label)
00398      || !copystrz(ARRAYVALUE(v, 9), p->label)
00399      || !copystr (ARRAYVALUE(v,10), ((ModuleGlobal*)besMODULEPOINTER)->s_dispchar)
00400      || !copystrz(ARRAYVALUE(v,11), p->dispchar)
00401      || !copystr (ARRAYVALUE(v,12), ((ModuleGlobal*)besMODULEPOINTER)->s_dispsize)
00402      || !copylong(ARRAYVALUE(v,13), p->dispsize)
00403        ) goto outmem;
00404   }
00405   PQconninfoFree(cio);
00406   besRETURNVALUE=NULL; /* return undef */
00407 besEND
00408 
00409 besFUNCTION(PGnotified)
00410   long __refcount_; /* used by besLEFTVALUE */
00411   unsigned len;
00412   Wrapper *w;
00413   LEFTVALUE Lval;
00414   VARIABLE Argument=besARGUMENT(1); /* 0! */
00415   VARIABLE Argument2=besARGUMENT(2);
00416   VARIABLE Argument3=besARGUMENT(3);
00417   PGnotify *no;
00418   (void)pEo;
00419   besDEREFERENCE(Argument);
00420   /* besDEREFERENCE(Argument2); */
00421   /* besDEREFERENCE(Argument3); */
00422   if (besARGNR>3) return EX_ERROR_TOO_MANY_ARGUMENTS;
00423   if (NULL==Argument3) return EX_ERROR_TOO_FEW_ARGUMENTS;
00424   if (TYPE(Argument)!=VTYPE_LONG
00425    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00426    || w->ty!=CON
00427      ) return PGSQL_ERROR_CON_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00428 
00429   if (0==PQconsumeInput(w->u.con)) {
00430     besRETURNVALUE=NULL; /* return undef */
00431     return 0;
00432   }
00433   if (!(no=PQnotifies(w->u.con))) {
00434     besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)0;
00435     return 0;
00436     besRETURNVALUE=NULL; /* return undef */
00437   }
00438   
00439   besLEFTVALUE(Argument2,Lval);
00440   len=0; while (len<NAMEDATALEN && no->relname[len]!='\0') len++;
00441   *Lval=besNEWSTRING(len);
00442   memcpy(STRINGVALUE(*Lval), no->relname, len);
00443 
00444   besLEFTVALUE(Argument3,Lval);
00445   *Lval=besNEWLONG;
00446   LONGVALUE(*Lval)=no->be_pid;
00447   
00448   free(no);
00449   besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)-1;
00450 besEND
00451 
00452 
00453 besFUNCTION(PGdumpNotices)
00454   /* char *s=NULL; */
00455   Wrapper *w;
00456   VARIABLE Argument=besARGUMENT(1); /* 0! */
00457   VARIABLE Argument2=besARGUMENT(2); /* 0! */
00458   (void)pEo;
00459   besDEREFERENCE(Argument);
00460   besDEREFERENCE(Argument2);
00461   if (besARGNR>2) return EX_ERROR_TOO_MANY_ARGUMENTS;
00462   if (NULL==Argument2) return EX_ERROR_TOO_FEW_ARGUMENTS;
00463   if (TYPE(Argument)!=VTYPE_LONG
00464    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00465    || w->ty!=CON
00466      ) return PGSQL_ERROR_CON_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00467   PQsetNoticeProcessor(w->u.con, besGETLONGVALUE(Argument2) ? stderrNoticeProcessor : silentNoticeProcessor, w->u.con);
00468   besRETURNVALUE=NULL; /* return undef */
00469 besEND
00470 
00471 
00472 besFUNCTION(PGexec)
00473   /* char *s=NULL; */
00474   ExecStatusType est;
00475   unsigned long sumlen;
00476   size_t tmp;
00477   unsigned i, argi;
00478   char **subs, *query, *dst, *s;
00479   Wrapper *w;
00480   PGresult *res;
00481   VARIABLE Argument=besARGUMENT(1); /* 0! */
00482   (void)pEo;
00483   besDEREFERENCE(Argument);
00484   /* if (besARGNR>2) return EX_ERROR_TOO_MANY_ARGUMENTS; */
00485   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00486   if (TYPE(Argument)!=VTYPE_LONG
00487    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00488    || w->ty!=CON
00489      ) return PGSQL_ERROR_CON_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00490   if (!(subs=besALLOC(besARGNR*sizeof*subs))) return COMMAND_ERROR_MEMORY_LOW;
00491   /* ^^^ Dat: we allocate a little more */
00492   for (sumlen=1, i=0, argi=2; argi<=(unsigned)besARGNR; argi++) {
00493     if ((i&1)==0) { /* unquoted */
00494       Argument=besCONVERT2STRING(besARGUMENT((int)argi));
00495       sumlen+=STRLEN(Argument);
00496       i++;
00497     } else if (besARGUMENT((int)argi)==NULL/*undef*/ && (int)argi<besARGNR) {
00498       argi++;
00499       Argument=besCONVERT2STRING(besARGUMENT((int)argi));
00500       tmp=STRLEN(Argument);
00501       if (!(subs[i]=PQescapeBytea(STRINGVALUE(Argument), tmp, &tmp))) return COMMAND_ERROR_MEMORY_LOW;
00502       /* Dat: SUXX: PQescapeBytea in PostgreSQL 7.2 never returns NULL, but it crashes the process */
00503       sumlen+=2+strlen(subs[i++]);
00504     } else {
00505       Argument=besCONVERT2STRING(besARGUMENT((int)argi));
00506       if (!(subs[i]=besALLOC(STRLEN(Argument)*2+1))) return COMMAND_ERROR_MEMORY_LOW;
00507       PQescapeString(subs[i], STRINGVALUE(Argument), STRLEN(Argument));
00508       sumlen+=2+strlen(subs[i++]);
00509     }
00510   }
00511   /* Dat: this function is binary safe, because PQescape* always return a
00512    *      null-terminated string
00513    */
00514   if (!(query=besALLOC(sumlen))) return COMMAND_ERROR_MEMORY_LOW;
00515   for (dst=query, i=0, argi=2; (int)argi<=besARGNR; argi++) {
00516     /* fprintf(stderr, "NOW %u\n", i); */
00517     if ((i&1)==0) { /* unquoted */
00518       Argument=besCONVERT2STRING(besARGUMENT((int)argi));
00519       memcpy(dst, STRINGVALUE(Argument), STRLEN(Argument));
00520       /* Imp: change \0s ?! */
00521       dst+=STRLEN(Argument);
00522       i++;
00523     } else {
00524       sumlen=strlen(subs[i]);
00525       *dst++='\'';
00526       memcpy(dst, subs[i], sumlen);
00527       dst+=sumlen;
00528       *dst++='\'';
00529       if (besARGUMENT((int)argi)==NULL/*undef*/ && (int)argi<besARGNR) {
00530         argi++;
00531         free(subs[i]);
00532       } else besFREE(subs[i]);
00533       i++; /* Dat: unsafe inside subs[i] */
00534     }
00535   }
00536   *dst='\0';
00537   DEBUGMSG(fprintf(stderr, "qry=(%s)\n", query);)
00538   besFREE(subs);
00539   res=PQexec(w->u.con, query);
00540   besFREE(query);
00541   if (!res) { besRETURNVALUE=NULL; return 0; /* return undef */ }
00542   /* ^^^ Dat: only on fatal error conditions such as out of memory */
00543   est=!res ? PGRES_FATAL_ERROR : PQresultStatus(res);
00544   if (est==PGRES_COMMAND_OK || est==PGRES_TUPLES_OK) {
00545     if (NULL==(w=alloc_Wrapper(pSt, (ModuleGlobal*)besMODULEPOINTER))) {
00546       PQclear(res);
00547       return COMMAND_ERROR_MEMORY_LOW;
00548     }
00549     w->ty=RES; w->u.res=res;
00550     besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)w->handle;
00551     return 0;
00552   }
00553   s=PQresStatus(est); /* "PGRES_..." */
00554   dst=res ? PQresultErrorMessage(res) : "PQexec() returned NULL";
00555   besALLOC_RETURN_STRING(strlen(s)+2+strlen(dst));
00556   memcpy(STRINGVALUE(besRETURNVALUE), s, strlen(s));
00557   memcpy(STRINGVALUE(besRETURNVALUE)+strlen(s), ": ", 2);
00558   memcpy(STRINGVALUE(besRETURNVALUE)+strlen(s)+2, dst, strlen(dst));
00559   if (res) PQclear(res);
00560 besEND
00561 
00562 besFUNCTION(PGresultStatus)
00563   /* char *s=NULL; */
00564   ExecStatusType est;
00565   Wrapper *w;
00566   char *s, *dst;
00567   VARIABLE Argument=besARGUMENT(1); /* 0! */
00568   (void)pEo;
00569   besDEREFERENCE(Argument);
00570   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00571   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00572   if (TYPE(Argument)!=VTYPE_LONG
00573    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00574    || w->ty!=RES
00575      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00576 
00577   assert(NULL!=w->u.res);
00578 
00579   est=!w->u.res ? PGRES_FATAL_ERROR : PQresultStatus(w->u.res);
00580   if (est==PGRES_COMMAND_OK) {
00581     besALLOC_RETURN_STRING(1);
00582     STRINGVALUE(besRETURNVALUE)[0]='-';
00583   } else if (est==PGRES_TUPLES_OK) {
00584     besALLOC_RETURN_STRING(0);
00585   } else {
00586     s=PQresStatus(est); /* "PGRES_..." */
00587     dst=w->u.res ? PQresultErrorMessage(w->u.res) : "PQexec() returned NULL";
00588     besALLOC_RETURN_STRING(strlen(s)+2+strlen(dst));
00589     memcpy(STRINGVALUE(besRETURNVALUE), s, strlen(s));
00590     memcpy(STRINGVALUE(besRETURNVALUE)+strlen(s), ": ", 2);
00591     memcpy(STRINGVALUE(besRETURNVALUE)+strlen(s)+2, dst, strlen(dst));
00592   }
00593 besEND
00594 
00595 besFUNCTION(PGmakeEmptyPGresult)
00596   ExecStatusType est;
00597   Wrapper *w;
00598   PGconn *con=NULL;
00599   PGresult *res;
00600   VARIABLE Argument=besARGUMENT(1); /* 0! */
00601   VARIABLE Argument2=besARGUMENT(2);
00602   (void)pEo;
00603   besDEREFERENCE(Argument);
00604   besDEREFERENCE(Argument2);
00605   if (besARGNR>2) return EX_ERROR_TOO_MANY_ARGUMENTS;
00606   if (NULL==Argument2) return EX_ERROR_TOO_FEW_ARGUMENTS;
00607   if (Argument!=NULL) {
00608     if (TYPE(Argument)!=VTYPE_LONG
00609      || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00610      || w->ty!=CON
00611        ) return PGSQL_ERROR_CON_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00612     con=w->u.con;    
00613   }
00614   besCONVERT2STRING(Argument2);
00615 
00616   if (strbegins(Argument2,"PGRES_EMPTY_QUERY")) est=PGRES_EMPTY_QUERY;
00617   else if (strbegins(Argument2,"PGRES_COMMAND_OK")) est=PGRES_COMMAND_OK;
00618   else if (strbegins(Argument2,"PGRES_TUPLES_OK")) est=PGRES_TUPLES_OK;
00619   else if (strbegins(Argument2,"PGRES_COPY_OUT")) est=PGRES_COPY_OUT;
00620   else if (strbegins(Argument2,"PGRES_COPY_IN")) est=PGRES_COPY_IN;
00621   else if (strbegins(Argument2,"PGRES_BAD_RESPONSE")) est=PGRES_BAD_RESPONSE;
00622   else if (strbegins(Argument2,"PGRES_NONFATAL_ERROR")) est=PGRES_NONFATAL_ERROR;
00623   else if (strbegins(Argument2,"PGRES_FATAL_ERROR")) est=PGRES_FATAL_ERROR;
00624   else return PGSQL_ERROR_EST_EXPECTED;
00625 
00626   if (!(res=PQmakeEmptyPGresult(con, est))) return COMMAND_ERROR_MEMORY_LOW;
00627   if (NULL==(w=alloc_Wrapper(pSt, (ModuleGlobal*)besMODULEPOINTER))) {
00628     PQclear(res);
00629     return COMMAND_ERROR_MEMORY_LOW;
00630   }
00631   w->ty=RES; w->u.res=res;
00632   besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)w->handle;
00633 besEND
00634 
00635 besFUNCTION(PGoid)
00636   /* char *s=NULL; */
00637   Oid oid;
00638   Wrapper *w;
00639   VARIABLE Argument=besARGUMENT(1); /* 0! */
00640   (void)pEo;
00641   besDEREFERENCE(Argument);
00642   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00643   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00644   if (TYPE(Argument)!=VTYPE_LONG
00645    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00646    || w->ty!=RES
00647      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00648   if (InvalidOid==(oid=PQoidValue(w->u.res))) {
00649     besRETURNVALUE=NULL;
00650   } else {
00651     besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)oid;
00652   }
00653 besEND
00654 
00655 besFUNCTION(PGescapeString)
00656   char *s;
00657   VARIABLE Argument=besARGUMENT(1); /* 0! */
00658   (void)pEo;
00659   (void)ppModuleInternal;
00660   besDEREFERENCE(Argument);
00661   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00662   besCONVERT2STRING(Argument);
00663   s=besALLOC(2*STRLEN(Argument)+1);
00664   PQescapeString(s, STRINGVALUE(Argument), STRLEN(Argument));
00665   besALLOC_RETURN_STRING(strlen(s));
00666   memcpy(STRINGVALUE(besRETURNVALUE), s, STRLEN(besRETURNVALUE));
00667   besFREE(s);
00668 besEND
00669 
00670 besFUNCTION(PGescapeBytea)
00671   char *s;
00672   size_t tmp;
00673   VARIABLE Argument=besARGUMENT(1); /* 0! */
00674   (void)pEo;
00675   (void)ppModuleInternal;
00676   besDEREFERENCE(Argument);
00677   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00678   besCONVERT2STRING(Argument);
00679   tmp=STRLEN(Argument);
00680   if (!(s=PQescapeBytea(STRINGVALUE(Argument), tmp, &tmp))) return COMMAND_ERROR_MEMORY_LOW;
00681   /* ^^^ Dat: SUXX: PQescapeBytea in PostgreSQL 7.2 never returns NULL, but it crashes the process */
00682   tmp=strlen(s);
00683   besALLOC_RETURN_STRING(tmp);
00684   memcpy(STRINGVALUE(besRETURNVALUE), s, STRLEN(besRETURNVALUE));
00685   free(s);
00686 besEND
00687 
00688 besFUNCTION(PGnrows)
00689   /* char *s=NULL; */
00690   Wrapper *w;
00691   VARIABLE Argument=besARGUMENT(1); /* 0! */
00692   (void)pEo;
00693   besDEREFERENCE(Argument);
00694   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00695   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00696   if (TYPE(Argument)!=VTYPE_LONG
00697    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00698    || w->ty!=RES
00699      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00700   besALLOC_RETURN_LONG;
00701   LONGVALUE(besRETURNVALUE)=PQntuples(w->u.res);
00702 besEND
00703 
00704 besFUNCTION(PGncols)
00705   /* char *s=NULL; */
00706   Wrapper *w;
00707   VARIABLE Argument=besARGUMENT(1); /* 0! */
00708   (void)pEo;
00709   besDEREFERENCE(Argument);
00710   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00711   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00712   if (TYPE(Argument)!=VTYPE_LONG
00713    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00714    || w->ty!=RES
00715      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00716   besALLOC_RETURN_LONG;
00717   LONGVALUE(besRETURNVALUE)=PQnfields(w->u.res);
00718 besEND
00719 
00720 besFUNCTION(PGcol)
00721   Wrapper *w;
00722   char *s;
00723   size_t tmp;
00724   VARIABLE Argument=besARGUMENT(1); /* 0! */
00725   VARIABLE Argument2=besARGUMENT(2);
00726   (void)pEo;
00727   besDEREFERENCE(Argument);
00728   besDEREFERENCE(Argument2);
00729   if (besARGNR>2) return EX_ERROR_TOO_MANY_ARGUMENTS;
00730   if (NULL==Argument2) return EX_ERROR_TOO_FEW_ARGUMENTS;
00731   if (TYPE(Argument)!=VTYPE_LONG
00732    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00733    || w->ty!=RES
00734      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00735   if (TYPE(Argument2)==VTYPE_LONG) {
00736     if (NULL==(s=PQfname(w->u.res, LONGVALUE(Argument2)))) {
00737       besRETURNVALUE=NULL;
00738     } else {
00739       tmp=strlen(s);
00740       besALLOC_RETURN_STRING(tmp);
00741       memcpy(STRINGVALUE(besRETURNVALUE), s, STRLEN(besRETURNVALUE));
00742     }
00743   } else {
00744     int idx;
00745     besCONVERT2ZCHAR(besCONVERT2STRING(Argument2),s); /* Dat: no automatic sentinel in scriba :-( */
00746     idx=PQfnumber(w->u.res, s);
00747     besFREE(s);
00748     if (idx<0) {
00749       besRETURNVALUE=NULL;
00750     } else {
00751       besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)idx;
00752     }
00753   }
00754 besEND
00755 
00756 besFUNCTION(PGcoltype)
00757   Oid oid;
00758   Wrapper *w;
00759   int idx=-1;
00760   char *s=NULL;
00761   VARIABLE Argument=besARGUMENT(1); /* 0! */
00762   VARIABLE Argument2=besARGUMENT(2);
00763   (void)pEo;
00764   besDEREFERENCE(Argument);
00765   besDEREFERENCE(Argument2);
00766   if (besARGNR>2) return EX_ERROR_TOO_MANY_ARGUMENTS;
00767   if (NULL==Argument2) return EX_ERROR_TOO_FEW_ARGUMENTS;
00768   if (TYPE(Argument)!=VTYPE_LONG
00769    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00770    || w->ty!=RES
00771      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00772   if (TYPE(Argument2)!=VTYPE_LONG) {
00773     besCONVERT2ZCHAR(besCONVERT2STRING(Argument2),s); /* Dat: no automatic sentinel in scriba :-( */
00774     idx=PQfnumber(w->u.res, s);
00775     if (idx<0) { besFREE(s); besRETURNVALUE=NULL; return 0; }
00776   } else idx=LONGVALUE(Argument2);
00777   if (InvalidOid==(oid=PQftype(w->u.res, idx))) {
00778     besRETURNVALUE=NULL; /* should really not hapen */
00779   } else {
00780     besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)oid;
00781   }
00782   if (s) besFREE(s);
00783 besEND
00784 
00785 besFUNCTION(PGcolmod)
00786   Oid oid;
00787   Wrapper *w;
00788   int idx=-1;
00789   char *s=NULL;
00790   VARIABLE Argument=besARGUMENT(1); /* 0! */
00791   VARIABLE Argument2=besARGUMENT(2);
00792   (void)pEo;
00793   besDEREFERENCE(Argument);
00794   besDEREFERENCE(Argument2);
00795   if (besARGNR>2) return EX_ERROR_TOO_MANY_ARGUMENTS;
00796   if (NULL==Argument2) return EX_ERROR_TOO_FEW_ARGUMENTS;
00797   if (TYPE(Argument)!=VTYPE_LONG
00798    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00799    || w->ty!=RES
00800      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00801   if (TYPE(Argument2)!=VTYPE_LONG) {
00802     besCONVERT2ZCHAR(besCONVERT2STRING(Argument2),s); /* Dat: no automatic sentinel in scriba :-( */
00803     idx=PQfnumber(w->u.res, s);
00804     if (idx<0) { besFREE(s); besRETURNVALUE=NULL; return 0; }
00805   } else idx=LONGVALUE(Argument2);
00806   if (InvalidOid==(oid=PQfmod(w->u.res, idx))) {
00807     besRETURNVALUE=NULL; /* should really not hapen */
00808   } else {
00809     besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)oid;
00810   }
00811   if (s) besFREE(s);
00812 besEND
00813 
00814 besFUNCTION(PGcolsize)
00815   Oid oid;
00816   Wrapper *w;
00817   int idx=-1;
00818   char *s=NULL;
00819   VARIABLE Argument=besARGUMENT(1); /* 0! */
00820   VARIABLE Argument2=besARGUMENT(2);
00821   (void)pEo;
00822   besDEREFERENCE(Argument);
00823   besDEREFERENCE(Argument2);
00824   if (besARGNR>2) return EX_ERROR_TOO_MANY_ARGUMENTS;
00825   if (NULL==Argument2) return EX_ERROR_TOO_FEW_ARGUMENTS;
00826   if (TYPE(Argument)!=VTYPE_LONG
00827    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00828    || w->ty!=RES
00829      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00830   if (TYPE(Argument2)!=VTYPE_LONG) {
00831     besCONVERT2ZCHAR(besCONVERT2STRING(Argument2),s); /* Dat: no automatic sentinel in scriba :-( */
00832     DEBUGMSG(fprintf(stderr, "colname=(%s)\n", s);)
00833     idx=PQfnumber(w->u.res, s);
00834     if (idx<0) { besFREE(s); besRETURNVALUE=NULL; return 0; }
00835     DEBUGMSG(fprintf(stderr, "colidx=(%d)\n", idx);)
00836   } else idx=LONGVALUE(Argument2);
00837   if (InvalidOid==(oid=PQfsize(w->u.res, idx))) {
00838     besRETURNVALUE=NULL; /* should really not hapen */
00839   } else {
00840     besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=(long)oid;
00841   }
00842   if (s) besFREE(s);
00843 besEND
00844 
00845 besFUNCTION(PGgetvalue)
00846   Wrapper *w;
00847   int idx=-1;
00848   size_t tmp;
00849   char *s=NULL, *v;
00850   VARIABLE Argument=besARGUMENT(1); /* 0! */
00851   VARIABLE Argument2=besARGUMENT(2);
00852   VARIABLE Argument3=besARGUMENT(3);
00853   (void)pEo;
00854   besDEREFERENCE(Argument);
00855   besDEREFERENCE(Argument2);
00856   besDEREFERENCE(Argument3);
00857   if (besARGNR>3) return EX_ERROR_TOO_MANY_ARGUMENTS;
00858   if (NULL==Argument3) return EX_ERROR_TOO_FEW_ARGUMENTS;
00859   if (TYPE(Argument)!=VTYPE_LONG
00860    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00861    || w->ty!=RES
00862      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00863   if (TYPE(Argument3)!=VTYPE_LONG) {
00864     besCONVERT2ZCHAR(besCONVERT2STRING(Argument2),s); /* Dat: no automatic sentinel in scriba :-( */
00865     idx=PQfnumber(w->u.res, s);
00866     if (idx<0) { besFREE(s); besRETURNVALUE=NULL; return 0; }
00867   } else idx=LONGVALUE(Argument3);
00868   besCONVERT2LONG(Argument2);
00869   /* Dat: memory returned in v is managed by libpq */
00870   if (!(v=PQgetvalue(w->u.res, LONGVALUE(Argument2), idx))
00871     || PQgetisnull(w->u.res, LONGVALUE(Argument2), idx)>0) {
00872     besRETURNVALUE=NULL; /* invalid field index? */
00873   } else {
00874     tmp=strlen(v);
00875     besALLOC_RETURN_STRING(tmp);
00876     memcpy(STRINGVALUE(besRETURNVALUE), v, STRLEN(besRETURNVALUE));
00877   }
00878   if (s) besFREE(s);
00879 besEND
00880 
00881 besFUNCTION(PGgetlength)
00882   Wrapper *w;
00883   int idx=-1;
00884   long len;
00885   char *s=NULL;
00886   VARIABLE Argument=besARGUMENT(1); /* 0! */
00887   VARIABLE Argument2=besARGUMENT(2);
00888   VARIABLE Argument3=besARGUMENT(3);
00889   (void)pEo;
00890   besDEREFERENCE(Argument);
00891   besDEREFERENCE(Argument2);
00892   besDEREFERENCE(Argument3);
00893   if (besARGNR>3) return EX_ERROR_TOO_MANY_ARGUMENTS;
00894   if (NULL==Argument3) return EX_ERROR_TOO_FEW_ARGUMENTS;
00895   if (TYPE(Argument)!=VTYPE_LONG
00896    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00897    || w->ty!=RES
00898      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00899   if (TYPE(Argument3)!=VTYPE_LONG) {
00900     besCONVERT2ZCHAR(besCONVERT2STRING(Argument2),s); /* Dat: no automatic sentinel in scriba :-( */
00901     idx=PQfnumber(w->u.res, s);
00902     if (idx<0) { besFREE(s); besRETURNVALUE=NULL; return 0; }
00903   } else idx=LONGVALUE(Argument3);
00904   besCONVERT2LONG(Argument2);
00905   if (0>(len=PQgetlength(w->u.res, LONGVALUE(Argument2), idx))) {
00906     besRETURNVALUE=NULL; /* should really not hapen */
00907   } else {
00908     besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=len;
00909   }
00910   if (s) besFREE(s);
00911 besEND
00912 
00913 besFUNCTION(PGgetisnull)
00914   Wrapper *w;
00915   int idx=-1;
00916   long len;
00917   char *s=NULL;
00918   VARIABLE Argument=besARGUMENT(1); /* 0! */
00919   VARIABLE Argument2=besARGUMENT(2);
00920   VARIABLE Argument3=besARGUMENT(3);
00921   (void)pEo;
00922   besDEREFERENCE(Argument);
00923   besDEREFERENCE(Argument2);
00924   besDEREFERENCE(Argument3);
00925   if (besARGNR>3) return EX_ERROR_TOO_MANY_ARGUMENTS;
00926   if (NULL==Argument3) return EX_ERROR_TOO_FEW_ARGUMENTS;
00927   if (TYPE(Argument)!=VTYPE_LONG
00928    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00929    || w->ty!=RES
00930      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00931   if (TYPE(Argument3)!=VTYPE_LONG) {
00932     besCONVERT2ZCHAR(besCONVERT2STRING(Argument2),s); /* Dat: no automatic sentinel in scriba :-( */
00933     idx=PQfnumber(w->u.res, s);
00934     if (idx<0) { besFREE(s); besRETURNVALUE=NULL; return 0; }
00935   } else idx=LONGVALUE(Argument3);
00936   besCONVERT2LONG(Argument2);
00937   if (0>(len=PQgetisnull(w->u.res, LONGVALUE(Argument2), idx))) {
00938     besRETURNVALUE=NULL; /* should really not hapen */
00939   } else {
00940     besALLOC_RETURN_LONG; LONGVALUE(besRETURNVALUE)=len;
00941   }
00942   if (s) besFREE(s);
00943 besEND
00944 
00945 besFUNCTION(PGbinaryTuples)
00946   /* char *s=NULL; */
00947   Wrapper *w;
00948   VARIABLE Argument=besARGUMENT(1); /* 0! */
00949   (void)pEo;
00950   besDEREFERENCE(Argument);
00951   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00952   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00953   if (TYPE(Argument)!=VTYPE_LONG
00954    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00955    || w->ty!=RES
00956      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00957   besALLOC_RETURN_LONG;
00958   LONGVALUE(besRETURNVALUE)=PQbinaryTuples(w->u.res) ? -1 : 0;
00959 besEND
00960 
00961 besFUNCTION(PGcmdStatus)
00962   char *s;
00963   size_t tmp;
00964   Wrapper *w;
00965   VARIABLE Argument=besARGUMENT(1); /* 0! */
00966   (void)pEo;
00967   besDEREFERENCE(Argument);
00968   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00969   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00970   if (TYPE(Argument)!=VTYPE_LONG
00971    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00972    || w->ty!=RES
00973      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00974   besALLOC_RETURN_LONG;
00975   if (!(s=PQcmdStatus(w->u.res))) { besRETURNVALUE=NULL; return 0; }
00976   tmp=strlen(s);
00977   besALLOC_RETURN_STRING(tmp);
00978   memcpy(STRINGVALUE(besRETURNVALUE), s, STRLEN(besRETURNVALUE));
00979 besEND
00980 
00981 besFUNCTION(PGcmdTuples)
00982   char *s;
00983   size_t tmp;
00984   Wrapper *w;
00985   VARIABLE Argument=besARGUMENT(1); /* 0! */
00986   (void)pEo;
00987   besDEREFERENCE(Argument);
00988   if (besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
00989   if (NULL==Argument) return EX_ERROR_TOO_FEW_ARGUMENTS;
00990   if (TYPE(Argument)!=VTYPE_LONG
00991    || NULL==(w=besHandleGetPointer(((ModuleGlobal*)besMODULEPOINTER)->ha, besGETLONGVALUE(Argument)))
00992    || w->ty!=RES
00993      ) return PGSQL_ERROR_RES_EXPECTED/*COMMAND_ERROR_ARGUMENT_RANGE*/;
00994   besALLOC_RETURN_LONG;
00995   if (!(s=PQcmdTuples(w->u.res))) { besRETURNVALUE=NULL; return 0; }
00996   tmp=strlen(s);
00997   besALLOC_RETURN_STRING(tmp);
00998   memcpy(STRINGVALUE(besRETURNVALUE), s, STRLEN(besRETURNVALUE));
00999   besRETURNVALUE=besCONVERT2LONG(besRETURNVALUE);
01000 besEND
01001 
01002 
01003 /* __END__ */

Generated on Sun Mar 12 23:56:29 2006 for ScriptBasic by  doxygen 1.4.6-NO