D.2 pgpylib.c

 /* Python Postgres Interface Library
    (C) by Hans Matzen, 1997, Frankfurt, Germany
 
 */
 
 /* this is pgpylib.c */
 
 #include <stdio.h>
 #include "pgpylib.h"
 
 /* pgres constructor and destructor */
 
 static pgres *new_pgres(pgres *init) {
   pgres *self;
 
   Py_Try((self=PyObject_NEW(pgres, &pgres_obj)));
   self->res=init->res;
 
   return self;
 }
 
 static void free_pgres(pgres *self) {
   PQclear(self->res);
   PyMem_DEL(self);
 }
 
 /* pgres methods */
 
 static PyObject* pgres_getattr(pgres *self,char *name) {
   return Py_FindMethod(pgres_methods, (PyObject *) self,name);
 }
 
 /* returns the number of records in the result */
 static PyObject* pgres_get_tuple_count(pgres *self) {
   int result;
 
   result=PQntuples(self->res);
   return Py_BuildValue("i",result);
  }
 
 /* returns the number of fileds per record in the result */
 static PyObject* pgres_get_field_count(pgres *self) {
   int result;
 
   result=PQnfields(self->res);
   return Py_BuildValue("i",result);
 }
 
 /* returns fieldname in column fieldindex */
 static PyObject*
    pgres_get_fieldname_byindex(pgres *self,PyObject *args) {
   char *result;
   int fieldindex;
 

   Py_Try(PyArg_Parse(args,"i",&fieldindex));
   result=PQfname(self->res,fieldindex);
   return Py_BuildValue("s",result);
 }
 
 /* returns column number of fieldname */
 static PyObject*
    pgres_get_fieldindex_byname(pgres *self, PyObject *args) {
   int result;
   char *fieldname;
 
   Py_Try(PyArg_Parse(args,"s",&fieldname));
   result= PQfnumber(self->res,fieldname);
   return Py_BuildValue("i",result);
 }
 
 /*  returns type of field with index fieldindex */
 static PyObject*
    pgres_get_fieldtype(pgres *self, PyObject *args) {
   int result;
   int fieldnum;
 
   Py_Try(PyArg_Parse(args,"i",&fieldnum));
   result=PQftype(self->res,fieldnum);
   return Py_BuildValue("i",result);
 }
 
 /*  returns size i bytes of field with index fieldindex */
 static PyObject*
    pgres_get_fieldsize(pgres *self, PyObject *args) {
   int result;
   int fieldindex;
 
   Py_Try(PyArg_Parse(args,"i",&fieldindex));
   result=PQfsize(self->res,fieldindex);
   return Py_BuildValue("i",result);
 }
 
 /* returns the value of field with index fieldnum
    in record tupnum     */
 static PyObject*
    pgres_get_fieldvalue(pgres *self, PyObject *args) {
   char *result;
   int tupnum;
   int fieldnum;
 
   Py_Try(PyArg_ParseTuple(args,"ii",&tupnum,&fieldnum));
   result=PQgetvalue(self->res,tupnum,fieldnum);
   return Py_BuildValue("s",result);
 }
 
 /* returns length in bytes of value in field given
    by fieldnum, tupnum     */
 static PyObject*
    pgres_get_fieldlength(pgres *self,PyObject *args) {
   int result;
   int tupnum, fieldnum;
 

   Py_Try(PyArg_ParseTuple(args,"ii",&tupnum,&fieldnum));
   result=PQgetlength(self->res,tupnum,fieldnum);
   return Py_BuildValue("i",result);
 }
 
 /* returns the returnvalue from the databaseserver */
 static PyObject* pgres_commandstatus(pgres *self) {
   char *result;
 
   result=PQcmdStatus(self->res);
   return Py_BuildValue("s",result);
 }
 
 /* returns the object status of the resultobject
    helpful for errorchecking  */
 static PyObject* pgres_objectstatus(pgres *self) {
  char *result;
 
   result=PQoidStatus(self->res);
   return Py_BuildValue("s",result);
 }
 
 /* returns an ASCII table of the whole resukt matrix */
 static PyObject*
    pgres_get_resultlist(pgres *self,PyObject *args) {
 
   int fillAllign;
   char * fieldSep;
   int printHeader;
   int quiet;
 
   Py_Try(PyArg_ParseTuple(args,"isii",&fillAllign,&fieldSep,
      &printHeader,&quiet));
   PQdisplayTuples(self->res,NULL,fillAllign,
      fieldSep,printHeader,quiet);
 
   return Py_BuildValue("s","EOL");
 }
 
 
 
 /* pgconn constructor and destructor */
 
 static pgconn *
    new_pgconn( char *host, char *port, char* dbname) {
 
   pgconn *self;
 
   Py_Try((self=PyObject_NEW(pgconn, &pgconn_obj)));
 
   self->trace=0;
   self->conn=PQsetdb(host,port,getenv("PGOPTIONS"),
      getenv("PGTTY"),dbname);
 
   return self;
 
 }
 

 static void free_pgconn(pgconn *self) {
   PQfinish(self->conn);
   PyMem_DEL(self);
 }
 
 
 
 /* pgconn methods */
 
 static char pgconn_getdbname__doc__[]="getdbname(pgconn)";
 
 /* returns the database name /*
 static PyObject* pgconn_get_dbname(pgconn *self) {
   char *result;
 
   result=PQdb(self->conn);
   return Py_BuildValue("s",result);
 }
 
 /* returns the hostname of the databaseserver */
 static PyObject* pgconn_get_host(pgconn *self) {
   char *result;
 
   result =PQhost(self->conn);
   return Py_BuildValue("s",result);
 }
 
 /* returns the portnumber of the databaseserver */
 static PyObject* pgconn_get_port(pgconn *self) {
   char *result;
 
   result =PQport(self->conn);
   return Py_BuildValue("s",result);
 }
 
 /* returns the options set for the connection */
 static PyObject* pgconn_get_options(pgconn *self) {
   char *result;
 
   result =PQoptions(self->conn);
   return Py_BuildValue("s",result);
 }
 
 /* returns the tty */
 static PyObject* pgconn_get_tty(pgconn *self) {
   char *result;
 
   result =PQtty(self->conn);
   return Py_BuildValue("s",result);
 }
 
 /* returns the connectionstatus
    helpful for errorchekcing */
 static PyObject* pgconn_connstatus(pgconn *self) {
   int result;
 
   result =PQstatus(self->conn);
   return Py_BuildValue("i",result);

 }
 
 /* if an error occured, this gets the errormessage
    from the server    */
 static PyObject* pgconn_get_error(pgconn *self) {
   char *result;
 
   result =PQerrorMessage(self->conn);
   return Py_BuildValue("s",result);
 }
 
 /* switches tracemode on/off */
 static PyObject* pgconn_switch_trace(pgconn *self) {
   if (self->trace == 1) {
     PQuntrace(self->conn);
     self->trace=0;
   } else {
     PQtrace(self->conn,stdout);
     self->trace=1;
   }
 
   return Py_BuildValue("i",self->trace);
 }
 
 /* resets the connection */
 static PyObject* pgconn_connreset(pgconn *self) {
 
   PQreset(self->conn);
   return Py_BuildValue("i",0);
 }
 
 /* executes the query given by qu
    returns a pgres objecthandle   */
 static PyObject*
    pgconn_exec_query(pgconn *self, PyObject *args) {
 
   PyObject *result;
   pgres *reshandle=malloc(sizeof(pgres)+1);
   char *qu;
 
   Py_Try(PyArg_Parse(args,"s",&qu));
   reshandle->res = PQexec(self->conn,qu);
   result= (PyObject *) new_pgres(reshandle);
   return result;
 }
 
 /* neede by python,  to resolve methodcalls */
 static PyObject *pgconn_getattr(pgconn *self, char *name) {
   if (strcmp(name,"trace")==0) {
     return Py_BuildValue("i",self->trace);
   } else {
     return Py_FindMethod(pgconn_methods,
        (PyObject *) self,name);
   }
 }
 
 
 /* pgblob constructor and destructor */

 
 static pgblob *new_pgblob( pgconn *init) {
 
   pgblob *self;
 
   Py_Try((self=PyObject_NEW(pgblob, &pgblob_obj)));
 
   self->blobid=0;
   self->fd=0;
   self->buff=malloc(1030);
   self->conn=init;
   Py_INCREF(init);
 
 
   return self;
 
 }
 
 static void free_pgblob( pgblob *self) {
     free(self->buff);
     Py_DECREF(self->conn);
     PyMem_DEL(self);
 }
 
 
 
 /* pgblob methods */
 
 /* opens a known blob */
 static PyObject* pgblob_bopen(pgblob *self, PyObject *args) {
   int result;
   int mode;
 
   Py_Try(PyArg_Parse(args,"i",&mode));
   result=lo_open(self->conn->conn,self->blobid,mode);
   self->fd=result;
   return Py_BuildValue("i", result);
 }
 
 
 /* closes a blob */
 static PyObject* pgblob_bclose(pgblob *self) {
   int result;
 
   result =lo_close(self->conn->conn,self->fd);
   return Py_BuildValue("i",result);
 }
 
 /* reads len bytes from blob and puts them into buff */
 static PyObject* pgblob_bread(pgblob *self,PyObject *args) {
   int result;
   int len;
 
 
   Py_Try(PyArg_Parse(args,("i"),&len));
   result =lo_read(self->conn->conn,self->fd,self->buff,len);
 
   return Py_BuildValue("i",result);

 }
 
 /* writes buff to blob returns number of written bytes */
 static PyObject*
    pgblob_bwrite(pgblob *self,PyObject *args) {
   int result;
   char *buff;
   int len;
 
   Py_Try(PyArg_ParseTuple(args,("si"),&buff,&len));
 
   result =lo_write(self->conn->conn,self->fd,buff,len);
 
   return Py_BuildValue("i",result);
 }
 
 /* changes the position of the filepointer */
 static PyObject* pgblob_bseek(pgblob *self,PyObject *args) {
   int result;
   int offset;
   int whence;
 
   Py_Try(PyArg_ParseTuple(args,"ii",&offset,&whence));
   result =lo_lseek(self->conn->conn,self->fd,offset,whence);
   return Py_BuildValue("i",result);
 }
 
 /* returns the position of the filepointer */
 static PyObject* pgblob_btell(pgblob *self) {
   int result;
 
   result =lo_tell(self->conn->conn,self->fd);
   return Py_BuildValue("i",result);
 }
 
 /* export the whole blob to file fname
    be careful using this sometimes causes trouble
    with postgres   */
 static PyObject*
    pgblob_bexport(pgblob *self,PyObject *args) {
   int result;
   char *fname;
 
   Py_Try(PyArg_Parse(args,"s",&fname));
   PQexec(self->conn->conn,"begin ");
   result =lo_export(self->conn->conn,self->blobid,fname);
   PQexec(self->conn->conn,"end;");
   return Py_BuildValue("i",result);
 }
 
 
 /* imports the file given by fname as blob into
    postgres, returns the blob-id */
 static PyObject*
    pgblob_bimport(pgblob *self,PyObject *args) {
   Oid result;
   char *fname;
 

   Py_Try(PyArg_Parse(args,"s",&fname));
   PQexec(self->conn->conn,"begin ");
   result =lo_import(self->conn->conn,fname);
   PQexec(self->conn->conn,"end;");
   self->blobid=result;
   return Py_BuildValue("i",(unsigned int)result);
 }
 
 
 /* creates a new blob and returns the blob-id  */
 static PyObject* pgblob_bcreate(pgblob *self,PyObject *args) {
     int mode;
     Oid result;
 
     Py_Try(PyArg_Parse(args,"i",&mode));
     result=lo_creat(self->conn->conn,mode);
     self->blobid=result;
     return Py_BuildValue("i",(unsigned int) result);
 }
 
 
 /* removes the blob given by blobid from the database */
 static PyObject* pgblob_bunlink(pgblob *self) {
   int result;
 
   result=lo_unlink(self->conn->conn,self->blobid);
   return Py_BuildValue("i",result);
 }
 
 /* this is for python, for resolving methodcalls  */
 static PyObject *pgblob_getattr(pgblob *self, char *name) {
   if (strcmp(name,"fd")==0) {
       return Py_BuildValue("i",self->fd);
   } else if (strcmp(name,"blobid")==0) {
       return Py_BuildValue("i",self->blobid);
   } else if (strcmp(name,"buff")==0) {
       return Py_BuildValue("s",self->buff);
   } else {
       return Py_FindMethod(pgblob_methods,
 (PyObject *) self,name);
   }
 }
 
 
 
 
 
 
 /* -------------------------------------------------------- */
 /* pgpy module methods                                      */
 /* -------------------------------------------------------- */
 
 static PyObject* pgpy_pgres(PyObject *self,PyObject *args) {
 
   PyObject *result;
   pgres *p;
 
   Py_Try(PyArg_ParseTuple(args,"O",p));

   result = (PyObject *) new_pgres(p);
 
   return result;
 }
 
 static PyObject* pgpy_pgconn(PyObject *self,PyObject *args) {
 
   PyObject *result;
   char *host, *port, *dbname;
 
   Py_Try(PyArg_ParseTuple(args,"sss",&host,&port,&dbname));
   result = (PyObject *) new_pgconn(host,port,dbname);
 
   return result;
 }
 
 static PyObject* pgpy_pgblob(PyObject *self,PyObject *args) {
 
   PyObject *result;
   pgconn *c;
 
 
   Py_Try(PyArg_ParseTuple(args,"O",&c));
   result = (PyObject *) new_pgblob(c);
 
   return result;
 }
 
 
 /* -------------------------------------------------------- */
 /* module pgpy init                                         */
 /* -------------------------------------------------------- */
 
 void initpgpy() {
   PyObject *m, *d;
 
 /* create module and add functions */
   m=Py_InitModule4("pgpy",pgpy_methods,
 pgpy_module_documentation,(PyObject*)NULL,PYTHON_API_VERSION);
 
 /* these are the symbols for error reporting */
 d= PyModule_GetDict(m);
 ErrorObject=PyString_FromString("pgpy.error");
 PyDict_SetItemString(d,"error",ErrorObject);
 
 /* any errors ?? */
 
 if (PyErr_Occurred()) {
   Py_FatalError("unable to initialize module pgpy");
 }
 
 }