From: Billy G. A. <bal...@us...> - 2001-10-13 20:40:41
|
Update of /cvsroot/pypgsql/pypgsql In directory usw-pr-cvs1:/tmp/cvs-serv8264 Modified Files: libpqmodule.c pgconnection.c pgconnection.h pglargeobject.c pglargeobject.h pgresult.c Log Message: 13OCT2001 bga Added support for pickling the following types/objects: PgVersion, PgBoolean, PgInt2, PgInt8, PgLargeObject. Index: libpqmodule.c =================================================================== RCS file: /cvsroot/pypgsql/pypgsql/libpqmodule.c,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** libpqmodule.c 2001/10/05 08:22:18 1.19 --- libpqmodule.c 2001/10/13 20:40:35 1.20 *************** *** 32,35 **** --- 32,38 ---- | Date Ini Description | | --------- --- ------------------------------------------------------- | + | 13OCT2001 bga Added support for the pickling of libpq objects. In | + | particular, for PgVersion and PgConnection objects. | + | --- Added a cntructor method for PgVersion objects. | | 01OCT2001 bga Changed all new style comments to original style. | | 30SEP2001 bga Change PgQuoteString and PgQuoteByta so that unsigned | *************** *** 533,536 **** --- 536,540 ---- static PyObject *libPQconnectdb(PyObject *self, PyObject *args) { + PyObject *conn; PGconn *cnx; char *conninfo; *************** *** 557,565 **** } ! return PgConnection_New(cnx); } /*--------------------------------------------------------------------------*/ static char libPQsetdbLogin_Doc[] = "PGsetdbLogin(pghost, pgport, pgopt, pgtty, dbname, login, passwd) ->\n" --- 561,574 ---- } ! conn = PgConnection_New(cnx); ! /* Save the connection info string (used for pickling). */ ! if (conn != (PyObject *)NULL) ! ((PgConnection *)conn)->cinfo = Py_BuildValue("s", conninfo); ! return conn; } /*--------------------------------------------------------------------------*/ + #if defined(DO_NOT_DEFINE_THIS_MACRO) static char libPQsetdbLogin_Doc[] = "PGsetdbLogin(pghost, pgport, pgopt, pgtty, dbname, login, passwd) ->\n" *************** *** 606,610 **** /*--------------------------------------------------------------------------*/ - #if defined(DO_NOT_DEFINE_THIS_MACRO) static char libPQconnectStart_Doc[] = "PQconnectStart(conninfo) -> PgConnection\n" --- 615,618 ---- *************** *** 633,637 **** } ! return PgConnection_New(cnx); } #endif --- 641,649 ---- } ! conn = PgConnection_New(cnx); ! /* Save the connection info string (used for pickling). */ ! if (conn) ! ((PgConnection *)conn)->cinfo = Py_BuildValue("s", conninfo); ! return conn; } #endif *************** *** 949,955 **** return NULL; ! return PgLargeObject_New(conn, loOid); } /***********************************************************************\ | Define the libpq methods and attributes. | --- 961,979 ---- return NULL; ! return PgLargeObject_New(conn, loOid, 1); } + /*--------------------------------------------------------------------------*/ + + static PyObject *libPQversion_New(PyObject *self, PyObject *args) + { + char* v; + + if (!PyArg_ParseTuple(args, "s:PgVersion", &v)) + return NULL; + + return PgVersion_New(v); + } + /***********************************************************************\ | Define the libpq methods and attributes. | *************** *** 960,965 **** { "PQresType", (PyCFunction)libPQresType, 1, libPQresType_Doc }, { "PQftypeName", (PyCFunction)libPQftypeName, 1, libPQftypeName_Doc }, - { "PQsetdbLogin", (PyCFunction)libPQsetdbLogin, 1, libPQsetdbLogin_Doc }, { "PQconnectdb", (PyCFunction)libPQconnectdb, 1, libPQconnectdb_Doc }, { "PQconndefaults", (PyCFunction)libPQconndefaults, 1, libPQconndefaults_Doc }, --- 984,993 ---- { "PQresType", (PyCFunction)libPQresType, 1, libPQresType_Doc }, { "PQftypeName", (PyCFunction)libPQftypeName, 1, libPQftypeName_Doc }, { "PQconnectdb", (PyCFunction)libPQconnectdb, 1, libPQconnectdb_Doc }, + #if defined(DO_NOT_DEFINE_THIS_MACRO) + { "PQsetdbLogin", (PyCFunction)libPQsetdbLogin, 1, libPQsetdbLogin_Doc }, + { "PQconnectStart", (PyCFunction)libPQconnectStart, 1, + libPQconnectStart_Doc }, + #endif { "PQconndefaults", (PyCFunction)libPQconndefaults, 1, libPQconndefaults_Doc }, *************** *** 968,975 **** { "PgUnQuoteBytea", (PyCFunction)libPQunQuoteBytea, 1, libPQunQuoteBytea_Doc }, - #if defined(DO_NOT_DEFINE_THIS_MACRO) - { "PQconnectStart", (PyCFunction)libPQconnectStart, 1, - libPQconnectStart_Doc }, - #endif { "PgBooleanFromString", (PyCFunction)libPQbool_FromString, 1 }, { "PgBooleanFromInteger", (PyCFunction)libPQbool_FromInt, 1 }, --- 996,999 ---- *************** *** 980,983 **** --- 1004,1008 ---- { "PgInt2", (PyCFunction)libPQint2_FromObject, 1 }, { "PgLargeObject", (PyCFunction)libPQlargeObject_New, 1 }, + { "PgVersion", (PyCFunction)libPQversion_New, 1 }, { NULL, NULL } }; *************** *** 1005,1008 **** --- 1030,1037 ---- #endif initpgversion(); + + /*-----------------------------------------------------------------------*/ + + PyDict_SetItemString(d, "__version__", Py_BuildValue("s", "$Revision$")); /*-----------------------------------------------------------------------*/ Index: pgconnection.c =================================================================== RCS file: /cvsroot/pypgsql/pypgsql/pgconnection.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pgconnection.c 2001/10/05 08:22:18 1.13 --- pgconnection.c 2001/10/13 20:40:35 1.14 *************** *** 29,32 **** --- 29,36 ---- | Date Ini Description | | --------- --- ------------------------------------------------------- | + | 13OCT2001 bga Added support for the pickling of PgConnection objects. | + | In particular, a hidden method was added to return the | + | connection information string used to create the con- | + | nection. | | 01OCT2001 bga Changed all new style comments to original style. | | 30SEP2001 bga Added some brakets to clarify ambiguous else clauses. | *************** *** 925,929 **** } ! return PgLargeObject_New((PyObject *)self, oid); } --- 929,933 ---- } ! return PgLargeObject_New((PyObject *)self, oid, 0); } *************** *** 949,953 **** } ! return PgLargeObject_New((PyObject *)self, oid); } --- 953,957 ---- } ! return PgLargeObject_New((PyObject *)self, oid, 0); } *************** *** 1105,1108 **** --- 1109,1115 ---- if (!strcmp(attr, "__class__")) return Py_BuildValue("s", self->ob_type->tp_name); + + if (!strcmp(attr, "_conninfo")) + return self->cinfo; /***********************************************************\ Index: pgconnection.h =================================================================== RCS file: /cvsroot/pypgsql/pypgsql/pgconnection.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pgconnection.h 2001/08/24 22:26:00 1.1 --- pgconnection.h 2001/10/13 20:40:35 1.2 *************** *** 51,54 **** --- 51,55 ---- PyObject *version; PyObject *notices; + PyObject *cinfo; int showQuery; } PgConnection; Index: pglargeobject.c =================================================================== RCS file: /cvsroot/pypgsql/pypgsql/pglargeobject.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pglargeobject.c 2001/09/24 16:54:40 1.9 --- pglargeobject.c 2001/10/13 20:40:35 1.10 *************** *** 30,33 **** --- 30,39 ---- | Date Ini Description | | --------- --- ------------------------------------------------------- | + | 13OCT2001 bga Added support for the pickling of large objects. | + | In particular, a method was added to retrieve the info | + | needed to recreate the large object. Also, the open() | + | and close() methods were changed to create and end | + | transaction in the un-pickled large objects in order to | + | create the context in which large object must be used. | | 24SEP2001 bga Added a _quote() funtion. | | 22SEP2001 bga Ensure that INV_BIN is not in the mode variable when | *************** *** 66,69 **** --- 72,77 ---- #include "libpqmodule.h" + #define LO_DEBUG (1) + /***************************************\ | PgLargeObject object definition | *************** *** 72,76 **** #define PgLargeObject_Get(v) ((v)->lo_oid) ! PyObject *PgLargeObject_New(PyObject *conn, Oid lo_oid) { PgLargeObject *self; --- 80,84 ---- #define PgLargeObject_Get(v) ((v)->lo_oid) ! PyObject *PgLargeObject_New(PyObject *conn, Oid lo_oid, int flag) { PgLargeObject *self; *************** *** 89,92 **** --- 97,101 ---- { self->lo_mode = self->lo_softspace = self->lo_offset = 0; + self->lo_dirty = 0; self->lo_fd = self->lo_size = -1; self->lo_buf = (char *)NULL; *************** *** 105,108 **** --- 114,122 ---- return (PyObject *)NULL; } + + if (flag) + self->need_commit = 0; /* Called from PgLargeObject */ + else + self->need_commit = -1; /* Called by getvalue() */ } *************** *** 429,436 **** oid = PgLargeObject_Get(self); ! if ((self->lo_fd = lo_open(cnx, oid, (mode & (INV_READ | INV_WRITE)))) < 0) { ! PyErr_SetString(PyExc_IOError, "can't open PgLargeObject"); ! return (PyObject *)NULL; } --- 443,475 ---- oid = PgLargeObject_Get(self); ! if ((self->lo_fd = lo_open(cnx, oid, (mode & (~INV_BIN)))) < 0) { ! PGresult *res; ! ! if (self->need_commit < 0) ! { ! PyErr_SetString(PyExc_IOError, "can't open PgLargeObject"); ! return (PyObject *)NULL; ! } ! ! Py_BEGIN_ALLOW_THREADS ! res = PQexec(cnx, "BEGIN WORK"); ! Py_END_ALLOW_THREADS ! ! if (res == (PGresult *)NULL) ! { ! PyErr_SetString(PyExc_IOError, "can't open PgLargeObject (begin)"); ! return (PyObject *)NULL; ! } ! ! PQclear(res); ! ! if ((self->lo_fd = lo_open(cnx, oid, (mode & (~INV_BIN)))) < 0) ! { ! PyErr_SetString(PyExc_IOError, "can't open PgLargeObject"); ! return (PyObject *)NULL; ! } ! ! self->need_commit = 1; } *************** *** 443,447 **** } self->lo_dirty = self->lo_idx = self->lo_size = 0; ! self->lo_mode = mode & (INV_READ | INV_WRITE); /* Update the mode (as text) and the closed flag. --- 482,486 ---- } self->lo_dirty = self->lo_idx = self->lo_size = 0; ! self->lo_mode = mode & (~INV_BIN); /* Update the mode (as text) and the closed flag. *************** *** 468,471 **** --- 507,517 ---- self->lo_buf = (char *)NULL; } + if (self->need_commit > 0) + { + Py_BEGIN_ALLOW_THREADS + PQclear(PQexec(cnx, "ROLLBACK WORK")); + Py_END_ALLOW_THREADS + self->need_commit = 0; + } return (PyObject *)NULL; } *************** *** 479,482 **** --- 525,529 ---- { PGconn *cnx; + int rollback = 0; int fd; *************** *** 484,492 **** return (PyObject *)NULL; ! if (!PyArg_ParseTuple(args,"")) { ! PyErr_SetString(PqErr_InterfaceError, ! "close() takes no parameters"); ! return (PyObject *)NULL; } --- 531,551 ---- return (PyObject *)NULL; ! if (self->need_commit > 0) { ! if (!PyArg_ParseTuple(args, "|i", &rollback)) ! { ! PyErr_SetString(PqErr_InterfaceError, ! "close() takes an optional integer parameters"); ! return (PyObject *)NULL; ! } ! } ! else ! { ! if (!PyArg_ParseTuple(args, "")) ! { ! PyErr_SetString(PqErr_InterfaceError, ! "close() takes no parameters"); ! return (PyObject *)NULL; ! } } *************** *** 503,506 **** --- 562,576 ---- } + if (self->need_commit > 0) + { + Py_BEGIN_ALLOW_THREADS + if (rollback) + PQclear(PQexec(cnx, "ROLLBACK WORK")); + else + PQclear(PQexec(cnx, "COMMIT WORK")); + Py_END_ALLOW_THREADS + self->need_commit = 0; + } + self->lo_mode = self->lo_softspace = self->lo_offset = 0; self->lo_fd = self->lo_size = -1; *************** *** 1116,1137 **** /*--------------------------------------------------------------------------*/ #define LoOFF(x) offsetof(PgLargeObject, x) /* PgLargeObject object members */ static struct memberlist PgLargeObject_members[] = { ! { "closed", T_OBJECT, LoOFF(lo_closed), RO }, ! { "mode", T_OBJECT, LoOFF(lo_mname), RO }, ! { "name", T_OBJECT, LoOFF(lo_name), RO }, ! { "softspace", T_INT, LoOFF(lo_softspace) }, #if defined(LO_DEBUG) ! { "conn", T_OBJECT, LoOFF(lo_conn), RO }, ! { "oid", T_INT, LoOFF(lo_oid), RO }, ! { "fd", T_INT, LoOFF(lo_fd), RO }, ! { "imode", T_INT, LoOFF(lo_mode), RO }, ! { "dirty", T_INT, LoOFF(lo_dirty), RO }, ! { "offset", T_INT, LoOFF(lo_offset), RO }, ! { "buffer", T_STRING, LoOFF(lo_buf), RO }, ! { "size", T_INT, LoOFF(lo_size), RO }, ! { "index", T_INT, LoOFF(lo_idx), RO }, #endif { NULL } --- 1186,1245 ---- /*--------------------------------------------------------------------------*/ + static PyObject *PgLo_pickle(PyObject *self) + { + PgLargeObject *lo; + PyObject *res; + PGconn *cnx; + int fd, offset = 0; + + + if (!PgLargeObject_Check(self)) + { + PyErr_SetString(PyExc_TypeError, "not a PgLargeObject"); + return (PyObject *)NULL; + } + + lo = (PgLargeObject *)self; + + if (lo->lo_closed != Py_True) + { + if (lo_flush(lo)) + return (PyObject *)NULL; + if (lo->lo_offset == -1) + offset = lo_tell(PgConnection_Get(lo->lo_conn), lo->lo_fd); + else + offset = lo->lo_offset + lo->lo_idx; + } + + if (lo->lo_closed == Py_True) + res = Py_BuildValue("(Oisii)", (lo->lo_conn)->cinfo, lo->lo_oid, "", + lo->lo_softspace, offset); + else + res = Py_BuildValue("(OiOii)", (lo->lo_conn)->cinfo, lo->lo_oid, + lo->lo_mname, lo->lo_softspace, offset); + return res; + } + + /*--------------------------------------------------------------------------*/ + #define LoOFF(x) offsetof(PgLargeObject, x) /* PgLargeObject object members */ static struct memberlist PgLargeObject_members[] = { ! { "closed", T_OBJECT, LoOFF(lo_closed), RO }, ! { "mode", T_OBJECT, LoOFF(lo_mname), RO }, ! { "name", T_OBJECT, LoOFF(lo_name), RO }, ! { "softspace", T_INT, LoOFF(lo_softspace) }, #if defined(LO_DEBUG) ! { "conn", T_OBJECT, LoOFF(lo_conn), RO }, ! { "oid", T_INT, LoOFF(lo_oid), RO }, ! { "fd", T_INT, LoOFF(lo_fd), RO }, ! { "imode", T_INT, LoOFF(lo_mode), RO }, ! { "dirty", T_INT, LoOFF(lo_dirty), RO }, ! { "offset", T_INT, LoOFF(lo_offset), RO }, ! { "buffer", T_STRING, LoOFF(lo_buf), RO }, ! { "size", T_INT, LoOFF(lo_size), RO }, ! { "index", T_INT, LoOFF(lo_idx), RO }, ! { "need_commit", T_INT, LoOFF(need_commit), RO }, #endif { NULL } *************** *** 1156,1159 **** --- 1264,1268 ---- { "export", (PyCFunction)PgLo_export, 1, PgLo_export_Doc}, { "_quote", (PyCFunction)PgLo_quote, 1}, + { "_pickle", (PyCFunction)PgLo_pickle, 1}, { NULL, NULL } }; Index: pglargeobject.h =================================================================== RCS file: /cvsroot/pypgsql/pypgsql/pglargeobject.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pglargeobject.h 2001/08/29 04:05:35 1.2 --- pglargeobject.h 2001/10/13 20:40:35 1.3 *************** *** 57,60 **** --- 57,61 ---- int lo_size; /* Bytes read/written into buffer. */ int lo_idx; /* Next byte to read from buffer. */ + int need_commit; /* Flag: !0 := commit needed on close. */ } PgLargeObject; *************** *** 63,67 **** #define PgLargeObject_Check(op) ((op)->ob_type == &PgLargeObject_Type) ! extern PyObject *PgLargeObject_New(PyObject *, Oid); /***********************************************************************\ --- 64,68 ---- #define PgLargeObject_Check(op) ((op)->ob_type == &PgLargeObject_Type) ! extern PyObject *PgLargeObject_New(PyObject *, Oid, int); /***********************************************************************\ Index: pgresult.c =================================================================== RCS file: /cvsroot/pypgsql/pypgsql/pgresult.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** pgresult.c 2001/10/01 03:14:23 1.14 --- pgresult.c 2001/10/13 20:40:35 1.15 *************** *** 29,32 **** --- 29,33 ---- | Date Ini Description | | --------- --- ------------------------------------------------------- | + | 13OCT2001 bga Added support for the pickling of pyPgSQL objects. | | 30SEP2001 bga Change error message returned by PgResult_ntuple_check | | if no tuples were returned in the result. The returned | *************** *** 501,505 **** valueObj = (PyObject *)PgLargeObject_New((PyObject *)self->conn, ! PyInt_AS_LONG(valueObj)); break; } --- 502,506 ---- valueObj = (PyObject *)PgLargeObject_New((PyObject *)self->conn, ! PyInt_AS_LONG(valueObj), 0); break; } *************** *** 570,574 **** valueObj = (PyObject *)PgLargeObject_New((PyObject *)self->conn, ! PyInt_AS_LONG(valueObj)); Py_XDECREF(pgres); --- 571,575 ---- valueObj = (PyObject *)PgLargeObject_New((PyObject *)self->conn, ! PyInt_AS_LONG(valueObj), 0); Py_XDECREF(pgres); |