Commit 9487ad84 authored by Marc G. Fournier's avatar Marc G. Fournier

Bring python up to date ...

From: D'Arcy J.M. Cain <darcy@druid.net>
parent 77ebed09
Announce: Release of PyGreSQL version 2.3 Announce: Release of PyGreSQL version 2.4
=============================================== ===============================================
PyGreSQL v2.3 has been released. PyGreSQL v2.4 has been released.
It is available at: ftp://ftp.druid.net/pub/distrib/PyGreSQL.tgz. If It is available at: ftp://ftp.druid.net/pub/distrib/PyGreSQL.tgz. If
you are on NetBSD, look in the packages directory under databases. If you are on NetBSD, look in the packages directory under databases. If
it isn't there yet, it should be there shortly. You can also pick up the it isn't there yet, it should be there shortly. You can also pick up the
...@@ -31,6 +31,9 @@ PostgreSQL features from a Python script. ...@@ -31,6 +31,9 @@ PostgreSQL features from a Python script.
I wanted to have DB-SIG API support in the next release but there are I wanted to have DB-SIG API support in the next release but there are
enough fixes and improvements to make one more release before starting enough fixes and improvements to make one more release before starting
on that. The next version will be 3.0 and have the DB-SIG API support. on that. The next version will be 3.0 and have the DB-SIG API support.
Note that I said this for 2.4 but some required changes from others have
been slow in coming (I'm not complaining, people do have lives) and
there were enough fixes that I didn't want to keep them from a release.
PyGreSQL 2.3 was developed and tested on a NetBSD 1.3_BETA system. It PyGreSQL 2.3 was developed and tested on a NetBSD 1.3_BETA system. It
is based on the PyGres95 code written by Pascal Andre, is based on the PyGres95 code written by Pascal Andre,
...@@ -39,6 +42,17 @@ code for Python 1.5 and PostgreSQL 6.2.1. While I was at it I upgraded ...@@ -39,6 +42,17 @@ code for Python 1.5 and PostgreSQL 6.2.1. While I was at it I upgraded
the code to use full ANSI style prototypes and changed the order of the code to use full ANSI style prototypes and changed the order of
arguments to connect. Later versions are fixes and enhancements to that. arguments to connect. Later versions are fixes and enhancements to that.
Important changes from PyGreSQL 2.3 to PyGreSQL 2.4:
- Insert returns None if the user doesn't have select permissions
on the table. It can (and does) happen that one has insert but
not select permissions on a table.
- Added ntuples() method to query object (brit@druid.net)
- Corrected a bug related to getresult() and the money type
- Corrected a but related to negative money amounts
- Allow update based on primary key if munged oid not available and
table has a primary key
- Add many __doc__ strings. (andre@via.ecp.fr)
Important changes from PyGreSQL 2.2 to PyGreSQL 2.3: Important changes from PyGreSQL 2.2 to PyGreSQL 2.3:
- connect.host returns "localhost" when connected to Unix socket - connect.host returns "localhost" when connected to Unix socket
(torppa@tuhnu.cutery.fi) (torppa@tuhnu.cutery.fi)
......
...@@ -5,6 +5,17 @@ This software is copyright (c) 1995, Pascal Andre (andre@via.ecp.fr) ...@@ -5,6 +5,17 @@ This software is copyright (c) 1995, Pascal Andre (andre@via.ecp.fr)
Further copyright 1997, 1998 and 1999 by D'Arcy J.M. Cain (darcy@druid.net) Further copyright 1997, 1998 and 1999 by D'Arcy J.M. Cain (darcy@druid.net)
See file README for copyright information. See file README for copyright information.
Version 2.4
- Insert returns None if the user doesn't have select permissions
on the table. It can (and does) happen that one has insert but
not select permissions on a table.
- Added ntuples() method to query object (brit@druid.net)
- Corrected a bug related to getresult() and the money type
- Corrected a but related to negative money amounts
- Allow update based on primary key if munged oid not available and
table has a primary key
- Add many __doc__ strings. (andre@via.ecp.fr)
Version 2.3 Version 2.3
- connect.host returns "localhost" when connected to Unix socket - connect.host returns "localhost" when connected to Unix socket
(torppa@tuhnu.cutery.fi) (torppa@tuhnu.cutery.fi)
......
PyGreSQL - v2.3: PostgreSQL module for Python PyGreSQL - v2.4: PostgreSQL module for Python
============================================== ==============================================
0. Copyright notice 0. Copyright notice
=================== ===================
PyGreSQL, version 2.3 PyGreSQL, version 2.4
A Python interface for PostgreSQL database. A Python interface for PostgreSQL database.
Written by D'Arcy J.M. Cain, darcy@druid.net<BR> Written by D'Arcy J.M. Cain, darcy@druid.net<BR>
Based heavily on code written by Pascal Andre, andre@chimay.via.ecp.fr. Based heavily on code written by Pascal Andre, andre@chimay.via.ecp.fr.
...@@ -129,12 +129,13 @@ style prototypes and changed the order of arguments to connect. ...@@ -129,12 +129,13 @@ style prototypes and changed the order of arguments to connect.
The home sites of the different packages are: The home sites of the different packages are:
- Python: ftp://ftp.python.org:/pub/python - Python: http://www.python.org/
- PosgreSQL: ftp://ftp.PostgreSQL.org/pub/postgresql-6.4.tar.gz - PosgreSQL: http://www.PostgreSQL.org/
- PyGreSQL: ftp://ftp.druid.net/pub/distrib/pygresql-2.2.tgz - PyGreSQL: http://www.druid.net/pygresql/
A Linux RPM can be picked up from ftp://www.eevolute.com/pub/python/. A Linux RPM can be picked up from ftp://www.eevolute.com/pub/python/.
A NetBSD package thould be in the distribution soon and is available
at ftp://ftp.druid.net/pub/distrib/pygresql.pkg.tgz.
1.5. Information and support 1.5. Information and support
---------------------------- ----------------------------
...@@ -164,6 +165,10 @@ and all the requests to the database, the pglargeobject that handles ...@@ -164,6 +165,10 @@ and all the requests to the database, the pglargeobject that handles
all the accesses to Postgres large objects and pgqueryobject that handles all the accesses to Postgres large objects and pgqueryobject that handles
query results. query results.
If you want to see a simple example of the use of some of these functions,
see http://www.druid.net/rides/ where I have a link at the bottom to the
actual Python code for the page.
2.1. pg module description 2.1. pg module description
---------------------------- ----------------------------
...@@ -471,6 +476,16 @@ methods are specified by the tag [LO]. ...@@ -471,6 +476,16 @@ methods are specified by the tag [LO].
type, using a hardcoded table definition. The number returned is the type, using a hardcoded table definition. The number returned is the
field rank in the result values list. field rank in the result values list.
2.2.1.5 ntuples - return number of tuples in query object
---------------------------------------------------------
Syntax: ntuples()
Parameters: None
Return type: integer
Description:
This method returns the number of tuples found in a query.
2.2.2. reset - resets the connection 2.2.2. reset - resets the connection
------------------------------------ ------------------------------------
...@@ -847,25 +862,7 @@ The following describes the methods and variables of this class. ...@@ -847,25 +862,7 @@ The following describes the methods and variables of this class.
Name of field which is the primary key of the table. Name of field which is the primary key of the table.
Description: Description:
This method returns the primary key of a table. Note that this raises This method returns the primary key of a table. Note that this raises
an exception if the table doesn't have a primary key. Further, in the an exception if the table doesn't have a primary key.
currently released implementation of PostgreSQL the 'PRIMARY KEY' syntax
doesn't actually fill in the necessary tables to determine primary keys.
You can do this yourself with the following query.
# Set up table and primary_field variables...
"""UPDATE pg_index SET indisprimary = 't'
WHERE pg_index.oid in (SELECT pg_index.oid
FROM pg_class, pg_attribute, pg_index
WHERE pg_class.oid = pg_attribute.attrelid AND
pg_class.oid = pg_index.indrelid AND
pg_index.indkey[0] = pg_attribute.attnum AND
pg_class.relname = '%(table)s' AND
pg_attribute.attname = '%(primary_field)');""" % locals()
This will be fixed in the upcoming 6.5 release of PostgreSQL or
you can download the current sources now. Downloading current
is, as usual, at your own risk.
3.3. get_databases - get list of databases in the system 3.3. get_databases - get list of databases in the system
-------------------------------------------------------- --------------------------------------------------------
......
...@@ -25,7 +25,7 @@ def _quote(d, t): ...@@ -25,7 +25,7 @@ def _quote(d, t):
return "'f'" return "'f'"
if d == "": return "null" if d == "": return "null"
return "'%s'" % string.strip(re.sub('\'', '\'\'', "%s" % d)) return "'%s'" % string.strip(re.sub("'", "''", "%s" % d))
class DB: class DB:
"""This class wraps the pg connection type""" """This class wraps the pg connection type"""
...@@ -175,16 +175,30 @@ class DB: ...@@ -175,16 +175,30 @@ class DB:
# reload the dictionary to catch things modified by engine # reload the dictionary to catch things modified by engine
# note that get() changes 'oid' below to oid_table # note that get() changes 'oid' below to oid_table
return self.get(cl, a, 'oid') # if no read perms (it can and does happen) return None
try: return self.get(cl, a, 'oid')
except: return None
# update always works on the oid which get returns # Update always works on the oid which get returns if available
# otherwise use the primary key. Fail if neither.
def update(self, cl, a): def update(self, cl, a):
q = "SELECT oid FROM %s WHERE oid = %s" % (cl, a['oid_%s' % cl]) foid = 'oid_%s' % cl
pk = self.pkeys[cl]
if a.has_key(foid):
where = "oid = %s" % a[foid]
elif a.has_key(pk):
where = "%s = '%s'" % (pk, a[pk])
else:
raise error, "Update needs key (%s) or oid as %s" % (pk, foid)
q = "SELECT oid FROM %s WHERE %s" % (cl, where)
if self.debug != None: print self.debug % q if self.debug != None: print self.debug % q
res = self.db.query(q).getresult() res = self.db.query(q).getresult()
if len(res) < 1: if len(res) < 1:
raise error, "No record in %s where oid = %s (%s)" % \ raise error, "No record in %s where %s (%s)" % \
(cl, a['oid_%s' % cl], sys.exc_value) (cl, where, sys.exc_value)
else: a[foid] = res[0][0]
v = [] v = []
k = 0 k = 0
...@@ -199,7 +213,7 @@ class DB: ...@@ -199,7 +213,7 @@ class DB:
try: try:
q = "UPDATE %s SET %s WHERE oid = %s" % \ q = "UPDATE %s SET %s WHERE oid = %s" % \
(cl, string.join(v, ','), a['oid_%s' % cl]) (cl, string.join(v, ','), a[foid])
if self.debug != None: print self.debug % q if self.debug != None: print self.debug % q
self.db.query(q) self.db.query(q)
except: except:
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
* AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS. * ENHANCEMENTS, OR MODIFICATIONS.
* *
* Further modifications copyright 1997 by D'Arcy J.M. Cain (darcy@druid.net) * Further modifications copyright 1997, 1998, 1999 by D'Arcy J.M. Cain
* subject to the same terms and conditions as above. * (darcy@druid.net) subject to the same terms and conditions as above.
* *
*/ */
...@@ -44,13 +44,21 @@ ...@@ -44,13 +44,21 @@
#define CASHOID 790 #define CASHOID 790
static PyObject *PGError; static PyObject *PGError;
static const char *PyPgVersion = "2.3"; static const char *PyPgVersion = "3.0 beta";
/* taken from fileobject.c */ /* taken from fileobject.c */
#define BUF(v) PyString_AS_STRING((PyStringObject *)(v)) #define BUF(v) PyString_AS_STRING((PyStringObject *)(v))
/* default values */
#define MODULE_NAME "pgsql"
#define ARRAYSIZE 1
/* flags for object validity checks */
#define CHECK_OPEN 1 #define CHECK_OPEN 1
#define CHECK_CLOSE 2 #define CHECK_CLOSE 2
#define CHECK_CNX 4
#define CHECK_RESULT 8
#define CHECK_DQL 16
#define MAX_BUFFER_SIZE 8192 /* maximum transaction size */ #define MAX_BUFFER_SIZE 8192 /* maximum transaction size */
...@@ -83,7 +91,6 @@ static PyObject *pg_default_passwd; /* default password */ ...@@ -83,7 +91,6 @@ static PyObject *pg_default_passwd; /* default password */
#endif /* DEFAULT_VARS */ #endif /* DEFAULT_VARS */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* OBJECTS DECLARATION */ /* OBJECTS DECLARATION */
/* pg connection object */ /* pg connection object */
...@@ -117,9 +124,9 @@ staticforward PyTypeObject PgQueryType; ...@@ -117,9 +124,9 @@ staticforward PyTypeObject PgQueryType;
typedef struct typedef struct
{ {
PyObject_HEAD PyObject_HEAD
pgobject * pgcnx; pgobject *pgcnx; /* parent connection object */
Oid lo_oid; Oid lo_oid; /* large object oid */
int lo_fd; int lo_fd; /* large object fd */
} pglargeobject; } pglargeobject;
staticforward PyTypeObject PglargeType; staticforward PyTypeObject PglargeType;
...@@ -128,14 +135,27 @@ staticforward PyTypeObject PglargeType; ...@@ -128,14 +135,27 @@ staticforward PyTypeObject PglargeType;
#endif /* LARGE_OBJECTS */ #endif /* LARGE_OBJECTS */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* INTERNAL FUNCTIONS */ /* INTERNAL FUNCTIONS */
/* checks connection validity */
static int
check_cnx_obj(pgobject * self)
{
if (!self->valid) {
PyErr_SetString(PGError, "connection has been closed");
return 0;
}
return 1;
}
#ifdef LARGE_OBJECTS #ifdef LARGE_OBJECTS
/* validity check (large object) */ /* checks large object validity */
static int static int
check_lo(pglargeobject * self, int level) check_lo_obj(pglargeobject * self, int level)
{ {
if (!check_cnx_obj(self->pgcnx))
return 0;
if (!self->lo_oid) if (!self->lo_oid)
{ {
PyErr_SetString(PGError, "object is not valid (null oid)."); PyErr_SetString(PGError, "object is not valid (null oid).");
...@@ -166,130 +186,32 @@ check_lo(pglargeobject * self, int level) ...@@ -166,130 +186,32 @@ check_lo(pglargeobject * self, int level)
#endif /* LARGE_OBJECTS */ #endif /* LARGE_OBJECTS */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
#ifdef LARGE_OBJECTS
/* PG CONNECTION OBJECT IMPLEMENTATION */ /* PG CONNECTION OBJECT IMPLEMENTATION */
/* pglargeobject initialisation (from pgobject) */ #ifdef LARGE_OBJECTS
/* creates large object */
static PyObject *
pg_locreate(pgobject * self, PyObject * args)
{
int mode;
pglargeobject *npglo;
if (!self->cnx)
{
PyErr_SetString(PyExc_TypeError, "Connection is not valid");
return NULL;
}
/* gets arguments */
if (!PyArg_ParseTuple(args, "i", &mode))
{
PyErr_SetString(PyExc_TypeError,
"locreate(mode), with mode (integer).");
return NULL;
}
if ((npglo = PyObject_NEW(pglargeobject, &PglargeType)) == NULL)
return NULL;
npglo->pgcnx = self;
Py_XINCREF(self);
npglo->lo_fd = -1;
npglo->lo_oid = lo_creat(self->cnx, mode);
/* checks result validity */
if (npglo->lo_oid == 0)
{
PyErr_SetString(PGError, "can't create large object.");
Py_XDECREF(npglo);
return NULL;
}
return (PyObject *) npglo;
}
/* init from already known oid */
static PyObject *
pg_getlo(pgobject * self, PyObject * args)
{
int lo_oid;
pglargeobject *npglo;
/* gets arguments */
if (!PyArg_ParseTuple(args, "i", &lo_oid))
{
PyErr_SetString(PyExc_TypeError, "loopen(oid), with oid (integer).");
return NULL;
}
if (!lo_oid)
{
PyErr_SetString(PyExc_ValueError, "the object oid can't be null.");
return NULL;
}
/* creates object */
if ((npglo = PyObject_NEW(pglargeobject, &PglargeType)) == NULL)
return NULL;
npglo->pgcnx = self;
Py_XINCREF(self);
npglo->lo_fd = -1;
npglo->lo_oid = lo_oid;
return (PyObject *) npglo;
}
/* import unix file */ /* constructor (internal use only) */
static PyObject * static pglargeobject *
pg_loimport(pgobject * self, PyObject * args) pglarge_new(pgobject * pgcnx, Oid oid)
{ {
char *name; pglargeobject * npglo;
pglargeobject *npglo;
if (!self->cnx)
{
PyErr_SetString(PyExc_TypeError, "Connection is not valid");
return NULL;
}
/* gets arguments */
if (!PyArg_ParseTuple(args, "s", &name))
{
PyErr_SetString(PyExc_TypeError, "loimport(name), with name (string).");
return NULL;
}
if ((npglo = PyObject_NEW(pglargeobject, &PglargeType)) == NULL) if ((npglo = PyObject_NEW(pglargeobject, &PglargeType)) == NULL)
return NULL; return NULL;
npglo->pgcnx = self; Py_XINCREF(pgcnx);
Py_XINCREF(self); npglo->pgcnx = pgcnx;
npglo->lo_fd = -1; npglo->lo_fd = -1;
npglo->lo_oid = lo_import(self->cnx, name); npglo->lo_oid = oid;
/* checks result validity */
if (npglo->lo_oid == 0)
{
PyErr_SetString(PGError, "can't create large object.");
Py_XDECREF(npglo);
return NULL;
}
return (PyObject *) npglo; return npglo;
} }
/* pglargeobject methods */
/* destructor */ /* destructor */
static void static void
pglarge_dealloc(pglargeobject * self) pglarge_dealloc(pglargeobject * self)
{ {
if (self->lo_fd >= 0 && self->pgcnx->valid == 1) if (self->lo_fd >= 0 && check_cnx_obj(self->pgcnx))
lo_close(self->pgcnx->cnx, self->lo_fd); lo_close(self->pgcnx->cnx, self->lo_fd);
Py_XDECREF(self->pgcnx); Py_XDECREF(self->pgcnx);
...@@ -297,13 +219,17 @@ pglarge_dealloc(pglargeobject * self) ...@@ -297,13 +219,17 @@ pglarge_dealloc(pglargeobject * self)
} }
/* opens large object */ /* opens large object */
static char pglarge_open__doc__[] =
"open(mode) -- open access to large object with specified mode "
"(INV_READ, INV_WRITE constants defined by module).";
static PyObject * static PyObject *
pglarge_open(pglargeobject * self, PyObject * args) pglarge_open(pglargeobject * self, PyObject * args)
{ {
int mode, fd; int mode, fd;
/* check validity */ /* check validity */
if (!check_lo(self, CHECK_CLOSE)) if (!check_lo_obj(self, CHECK_CLOSE))
return NULL; return NULL;
/* gets arguments */ /* gets arguments */
...@@ -327,6 +253,9 @@ pglarge_open(pglargeobject * self, PyObject * args) ...@@ -327,6 +253,9 @@ pglarge_open(pglargeobject * self, PyObject * args)
} }
/* close large object */ /* close large object */
static char pglarge_close__doc__[] =
"close() -- close access to large object data.";
static PyObject * static PyObject *
pglarge_close(pglargeobject * self, PyObject * args) pglarge_close(pglargeobject * self, PyObject * args)
{ {
...@@ -339,7 +268,7 @@ pglarge_close(pglargeobject * self, PyObject * args) ...@@ -339,7 +268,7 @@ pglarge_close(pglargeobject * self, PyObject * args)
} }
/* checks validity */ /* checks validity */
if (!check_lo(self, CHECK_OPEN)) if (!check_lo_obj(self, CHECK_OPEN))
return NULL; return NULL;
/* closes large object */ /* closes large object */
...@@ -356,6 +285,10 @@ pglarge_close(pglargeobject * self, PyObject * args) ...@@ -356,6 +285,10 @@ pglarge_close(pglargeobject * self, PyObject * args)
} }
/* reads from large object */ /* reads from large object */
static char pglarge_read__doc__[] =
"read(integer) -- read from large object to sized string. "
"Object must be opened in read mode before calling this method.";
static PyObject * static PyObject *
pglarge_read(pglargeobject * self, PyObject * args) pglarge_read(pglargeobject * self, PyObject * args)
{ {
...@@ -363,7 +296,7 @@ pglarge_read(pglargeobject * self, PyObject * args) ...@@ -363,7 +296,7 @@ pglarge_read(pglargeobject * self, PyObject * args)
PyObject *buffer; PyObject *buffer;
/* checks validity */ /* checks validity */
if (!check_lo(self, CHECK_OPEN)) if (!check_lo_obj(self, CHECK_OPEN))
return NULL; return NULL;
/* gets arguments */ /* gets arguments */
...@@ -395,6 +328,10 @@ pglarge_read(pglargeobject * self, PyObject * args) ...@@ -395,6 +328,10 @@ pglarge_read(pglargeobject * self, PyObject * args)
} }
/* write to large object */ /* write to large object */
static char pglarge_write__doc__[] =
"write(string) -- write sized string to large object. "
"Object must be opened in read mode before calling this method.";
static PyObject * static PyObject *
pglarge_write(pglargeobject * self, PyObject * args) pglarge_write(pglargeobject * self, PyObject * args)
{ {
...@@ -402,7 +339,7 @@ pglarge_write(pglargeobject * self, PyObject * args) ...@@ -402,7 +339,7 @@ pglarge_write(pglargeobject * self, PyObject * args)
int size; int size;
/* checks validity */ /* checks validity */
if (!check_lo(self, CHECK_OPEN)) if (!check_lo_obj(self, CHECK_OPEN))
return NULL; return NULL;
/* gets arguments */ /* gets arguments */
...@@ -427,13 +364,19 @@ pglarge_write(pglargeobject * self, PyObject * args) ...@@ -427,13 +364,19 @@ pglarge_write(pglargeobject * self, PyObject * args)
} }
/* go to position in large object */ /* go to position in large object */
static char pglarge_seek__doc__[] =
"seek(off, whence) -- move to specified position. Object must be opened "
"before calling this method. whence can be SEEK_SET, SEEK_CUR or SEEK_END, "
"constants defined by module.";
static PyObject * static PyObject *
pglarge_lseek(pglargeobject * self, PyObject * args) pglarge_lseek(pglargeobject * self, PyObject * args)
{ {
int ret, offset, whence; /* offset and whence are initialized to keep compiler happy */
int ret, offset = 0, whence = 0;
/* checks validity */ /* checks validity */
if (!check_lo(self, CHECK_OPEN)) if (!check_lo_obj(self, CHECK_OPEN))
return NULL; return NULL;
/* gets arguments */ /* gets arguments */
...@@ -456,6 +399,10 @@ pglarge_lseek(pglargeobject * self, PyObject * args) ...@@ -456,6 +399,10 @@ pglarge_lseek(pglargeobject * self, PyObject * args)
} }
/* gets large object size */ /* gets large object size */
static char pglarge_size__doc__[] =
"size() -- return large object size. "
"Object must be opened before calling this method.";
static PyObject * static PyObject *
pglarge_size(pglargeobject * self, PyObject * args) pglarge_size(pglargeobject * self, PyObject * args)
{ {
...@@ -470,7 +417,7 @@ pglarge_size(pglargeobject * self, PyObject * args) ...@@ -470,7 +417,7 @@ pglarge_size(pglargeobject * self, PyObject * args)
} }
/* checks validity */ /* checks validity */
if (!check_lo(self, CHECK_OPEN)) if (!check_lo_obj(self, CHECK_OPEN))
return NULL; return NULL;
/* gets current position */ /* gets current position */
...@@ -500,6 +447,10 @@ pglarge_size(pglargeobject * self, PyObject * args) ...@@ -500,6 +447,10 @@ pglarge_size(pglargeobject * self, PyObject * args)
} }
/* gets large object cursor position */ /* gets large object cursor position */
static char pglarge_tell__doc__[] =
"tell() -- give current position in large object. "
"Object must be opened before calling this method.";
static PyObject * static PyObject *
pglarge_tell(pglargeobject * self, PyObject * args) pglarge_tell(pglargeobject * self, PyObject * args)
{ {
...@@ -514,7 +465,7 @@ pglarge_tell(pglargeobject * self, PyObject * args) ...@@ -514,7 +465,7 @@ pglarge_tell(pglargeobject * self, PyObject * args)
} }
/* checks validity */ /* checks validity */
if (!check_lo(self, CHECK_OPEN)) if (!check_lo_obj(self, CHECK_OPEN))
return NULL; return NULL;
/* gets current position */ /* gets current position */
...@@ -529,13 +480,17 @@ pglarge_tell(pglargeobject * self, PyObject * args) ...@@ -529,13 +480,17 @@ pglarge_tell(pglargeobject * self, PyObject * args)
} }
/* exports large object as unix file */ /* exports large object as unix file */
static char pglarge_export__doc__[] =
"export(string) -- export large object data to specified file. "
"Object must be closed when calling this method.";
static PyObject * static PyObject *
pglarge_export(pglargeobject * self, PyObject * args) pglarge_export(pglargeobject * self, PyObject * args)
{ {
char *name; char *name;
/* checks validity */ /* checks validity */
if (!check_lo(self, CHECK_CLOSE)) if (!check_lo_obj(self, CHECK_CLOSE))
return NULL; return NULL;
/* gets arguments */ /* gets arguments */
...@@ -558,6 +513,10 @@ pglarge_export(pglargeobject * self, PyObject * args) ...@@ -558,6 +513,10 @@ pglarge_export(pglargeobject * self, PyObject * args)
} }
/* deletes a large object */ /* deletes a large object */
static char pglarge_unlink__doc__[] =
"unlink() -- destroy large object. "
"Object must be closed when calling this method.";
static PyObject * static PyObject *
pglarge_unlink(pglargeobject * self, PyObject * args) pglarge_unlink(pglargeobject * self, PyObject * args)
{ {
...@@ -570,7 +529,7 @@ pglarge_unlink(pglargeobject * self, PyObject * args) ...@@ -570,7 +529,7 @@ pglarge_unlink(pglargeobject * self, PyObject * args)
} }
/* checks validity */ /* checks validity */
if (!check_lo(self, CHECK_CLOSE)) if (!check_lo_obj(self, CHECK_CLOSE))
return NULL; return NULL;
/* deletes the object, invalidate it on success */ /* deletes the object, invalidate it on success */
...@@ -587,16 +546,16 @@ pglarge_unlink(pglargeobject * self, PyObject * args) ...@@ -587,16 +546,16 @@ pglarge_unlink(pglargeobject * self, PyObject * args)
/* large object methods */ /* large object methods */
static struct PyMethodDef pglarge_methods[] = { static struct PyMethodDef pglarge_methods[] = {
{"open", (PyCFunction) pglarge_open, 1}, /* opens large object */ {"open", (PyCFunction) pglarge_open, 1, pglarge_open__doc__ },
{"close", (PyCFunction) pglarge_close, 1},/* closes large object */ {"close", (PyCFunction) pglarge_close, 1, pglarge_close__doc__ },
{"read", (PyCFunction) pglarge_read, 1}, /* reads from large object */ {"read", (PyCFunction) pglarge_read, 1, pglarge_read__doc__ },
{"write", (PyCFunction) pglarge_write, 1},/* writes to large object */ {"write", (PyCFunction) pglarge_write, 1, pglarge_write__doc__ },
{"seek", (PyCFunction) pglarge_lseek, 1},/* seeks position */ {"seek", (PyCFunction) pglarge_lseek, 1, pglarge_seek__doc__ },
{"size", (PyCFunction) pglarge_size, 1}, /* gives object size */ {"size", (PyCFunction) pglarge_size, 1, pglarge_size__doc__ },
{"tell", (PyCFunction) pglarge_tell, 1}, /* gives position in lobj */ {"tell", (PyCFunction) pglarge_tell, 1, pglarge_tell__doc__ },
{"export", (PyCFunction) pglarge_export, 1},/* exports to unix file */ {"export", (PyCFunction) pglarge_export, 1, pglarge_export__doc__ },
{"unlink", (PyCFunction) pglarge_unlink, 1},/* deletes a large object */ {"unlink", (PyCFunction) pglarge_unlink, 1, pglarge_unlink__doc__ },
{NULL, NULL} /* sentinel */ {NULL, NULL}
}; };
/* get attribute */ /* get attribute */
...@@ -608,7 +567,7 @@ pglarge_getattr(pglargeobject * self, char *name) ...@@ -608,7 +567,7 @@ pglarge_getattr(pglargeobject * self, char *name)
/* associated pg connection object */ /* associated pg connection object */
if (!strcmp(name, "pgcnx")) if (!strcmp(name, "pgcnx"))
{ {
if (check_lo(self, 0)) if (check_lo_obj(self, 0))
{ {
Py_INCREF(self->pgcnx); Py_INCREF(self->pgcnx);
return (PyObject *) (self->pgcnx); return (PyObject *) (self->pgcnx);
...@@ -621,7 +580,7 @@ pglarge_getattr(pglargeobject * self, char *name) ...@@ -621,7 +580,7 @@ pglarge_getattr(pglargeobject * self, char *name)
/* large object oid */ /* large object oid */
if (!strcmp(name, "oid")) if (!strcmp(name, "oid"))
{ {
if (check_lo(self, 0)) if (check_lo_obj(self, 0))
return PyInt_FromLong(self->lo_oid); return PyInt_FromLong(self->lo_oid);
Py_INCREF(Py_None); Py_INCREF(Py_None);
...@@ -647,9 +606,40 @@ pglarge_getattr(pglargeobject * self, char *name) ...@@ -647,9 +606,40 @@ pglarge_getattr(pglargeobject * self, char *name)
return list; return list;
} }
/* module name */
if (!strcmp(name, "__module__"))
return PyString_FromString(MODULE_NAME);
/* class name */
if (!strcmp(name, "__class__"))
return PyString_FromString("pglarge");
/* seeks name in methods (fallback) */
return Py_FindMethod(pglarge_methods, (PyObject *) self, name); return Py_FindMethod(pglarge_methods, (PyObject *) self, name);
} }
/* prints query object in human readable format */
static int
pglarge_print(pglargeobject * self, FILE *fp, int flags)
{
char print_buffer[128];
if (self->lo_fd >= 0)
{
snprintf(print_buffer, sizeof(print_buffer),
"Opened large object, oid %ld", (long)self->lo_oid);
fputs(print_buffer, fp);
}
else
{
snprintf(print_buffer, sizeof(print_buffer),
"Closed large object, oid %ld", (long)self->lo_oid);
fputs(print_buffer, fp);
}
return 0;
};
/* object type definition */ /* object type definition */
staticforward PyTypeObject PglargeType = { staticforward PyTypeObject PglargeType = {
PyObject_HEAD_INIT(NULL) PyObject_HEAD_INIT(NULL)
...@@ -660,7 +650,7 @@ staticforward PyTypeObject PglargeType = { ...@@ -660,7 +650,7 @@ staticforward PyTypeObject PglargeType = {
/* methods */ /* methods */
(destructor) pglarge_dealloc, /* tp_dealloc */ (destructor) pglarge_dealloc, /* tp_dealloc */
0, /* tp_print */ (printfunc) pglarge_print, /* tp_print */
(getattrfunc) pglarge_getattr, /* tp_getattr */ (getattrfunc) pglarge_getattr, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
0, /* tp_compare */ 0, /* tp_compare */
...@@ -675,10 +665,12 @@ staticforward PyTypeObject PglargeType = { ...@@ -675,10 +665,12 @@ staticforward PyTypeObject PglargeType = {
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* PG QUERY OBJECT IMPLEMENTATION */
/* PG CONNECTION OBJECT IMPLEMENTATION */ /* connects to a database */
static char connect__doc__[] =
/* pgobject initialisation (from module) */ "connect(dbname, host, port, opt, tty) -- connect to a PostgreSQL database "
"using specified parameters (optionals, keywords aware).";
static PyObject * static PyObject *
pgconnect(pgobject *self, PyObject *args, PyObject *dict) pgconnect(pgobject *self, PyObject *args, PyObject *dict)
...@@ -693,7 +685,11 @@ pgconnect(pgobject *self, PyObject *args, PyObject *dict) ...@@ -693,7 +685,11 @@ pgconnect(pgobject *self, PyObject *args, PyObject *dict)
pghost = pgopt = pgtty = pgdbname = pguser = pgpasswd = NULL; pghost = pgopt = pgtty = pgdbname = pguser = pgpasswd = NULL;
pgport = -1; pgport = -1;
/* parses standard arguments */ /* parses standard arguments
* With the right compiler warnings, this will issue a diagnostic.
* There is really no way around it. If I don't declare kwlist as
* const char *kwlist[] then it complains when I try to assign all
* those constant strings to it. */
if (!PyArg_ParseTupleAndKeywords(args, dict, "|zzlzzzz", kwlist, if (!PyArg_ParseTupleAndKeywords(args, dict, "|zzlzzzz", kwlist,
&pgdbname, &pghost, &pgport, &pgopt, &pgtty, &pguser, &pgpasswd)) &pgdbname, &pghost, &pgport, &pgopt, &pgtty, &pguser, &pgpasswd))
return NULL; return NULL;
...@@ -759,6 +755,11 @@ pg_dealloc(pgobject * self) ...@@ -759,6 +755,11 @@ pg_dealloc(pgobject * self)
} }
/* close without deleting */ /* close without deleting */
static char pg_close__doc__[] =
"close() -- close connection. All instances of the connection object and "
"derived objects (queries and large objects) can no longer be used after "
"this call.";
static PyObject * static PyObject *
pg_close(pgobject *self, PyObject *args) pg_close(pgobject *self, PyObject *args)
{ {
...@@ -778,7 +779,7 @@ pg_close(pgobject *self, PyObject *args) ...@@ -778,7 +779,7 @@ pg_close(pgobject *self, PyObject *args)
} }
static void static void
pg_querydealloc(pgqueryobject * self) pgquery_dealloc(pgqueryobject * self)
{ {
if (self->last_result) if (self->last_result)
PQclear(self->last_result); PQclear(self->last_result);
...@@ -787,6 +788,11 @@ pg_querydealloc(pgqueryobject * self) ...@@ -787,6 +788,11 @@ pg_querydealloc(pgqueryobject * self)
} }
/* resets connection */ /* resets connection */
static char pg_reset__doc__[] =
"reset() -- reset connection with current parameters. All derived queries "
"and large objects derived from this connection will not be usable after "
"this call.";
static PyObject * static PyObject *
pg_reset(pgobject * self, PyObject * args) pg_reset(pgobject * self, PyObject * args)
{ {
...@@ -811,6 +817,9 @@ pg_reset(pgobject * self, PyObject * args) ...@@ -811,6 +817,9 @@ pg_reset(pgobject * self, PyObject * args)
} }
/* get connection socket */ /* get connection socket */
static char pg_fileno__doc__[] =
"fileno() -- return database connection socket file handle.";
static PyObject * static PyObject *
pg_fileno(pgobject * self, PyObject * args) pg_fileno(pgobject * self, PyObject * args)
{ {
...@@ -835,9 +844,30 @@ pg_fileno(pgobject * self, PyObject * args) ...@@ -835,9 +844,30 @@ pg_fileno(pgobject * self, PyObject * args)
#endif #endif
} }
/* get number of rows */
static char pgquery_ntuples__doc__[] =
"ntuples() -- returns number of tuples returned by query.";
static PyObject *
pgquery_ntuples(pgqueryobject * self, PyObject * args)
{
/* checks args */
if (!PyArg_ParseTuple(args, ""))
{
PyErr_SetString(PyExc_SyntaxError,
"method ntuples() takes no parameters.");
return NULL;
}
return PyInt_FromLong((long) PQntuples(self->last_result));
}
/* list fields names from query result */ /* list fields names from query result */
static char pgquery_listfields__doc__[] =
"listfields() -- Lists field names from result.";
static PyObject * static PyObject *
pg_listfields(pgqueryobject * self, PyObject * args) pgquery_listfields(pgqueryobject * self, PyObject * args)
{ {
int i, n; int i, n;
char *name; char *name;
...@@ -866,8 +896,11 @@ pg_listfields(pgqueryobject * self, PyObject * args) ...@@ -866,8 +896,11 @@ pg_listfields(pgqueryobject * self, PyObject * args)
} }
/* get field name from last result */ /* get field name from last result */
static char pgquery_fieldname__doc__[] =
"fieldname() -- returns name of field from result from its position.";
static PyObject * static PyObject *
pg_fieldname(pgqueryobject * self, PyObject * args) pgquery_fieldname(pgqueryobject * self, PyObject * args)
{ {
int i; int i;
char *name; char *name;
...@@ -893,8 +926,11 @@ pg_fieldname(pgqueryobject * self, PyObject * args) ...@@ -893,8 +926,11 @@ pg_fieldname(pgqueryobject * self, PyObject * args)
} }
/* gets fields number from name in last result */ /* gets fields number from name in last result */
static char pgquery_fieldnum__doc__[] =
"fieldnum() -- returns position in query for field from its name.";
static PyObject * static PyObject *
pg_fieldnum(pgqueryobject * self, PyObject * args) pgquery_fieldnum(pgqueryobject * self, PyObject * args)
{ {
char *name; char *name;
int num; int num;
...@@ -917,8 +953,13 @@ pg_fieldnum(pgqueryobject * self, PyObject * args) ...@@ -917,8 +953,13 @@ pg_fieldnum(pgqueryobject * self, PyObject * args)
} }
/* retrieves last result */ /* retrieves last result */
static char pgquery_getresult__doc__[] =
"getresult() -- Gets the result of a query. The result is returned "
"as a list of rows, each one a list of fields in the order returned "
"by the server.";
static PyObject * static PyObject *
pg_getresult(pgqueryobject * self, PyObject * args) pgquery_getresult(pgqueryobject * self, PyObject * args)
{ {
PyObject *rowtuple, *reslist, *val; PyObject *rowtuple, *reslist, *val;
int i, j, m, n, *typ; int i, j, m, n, *typ;
...@@ -972,6 +1013,7 @@ pg_getresult(pgqueryobject * self, PyObject * args) ...@@ -972,6 +1013,7 @@ pg_getresult(pgqueryobject * self, PyObject * args)
rowtuple = PyTuple_New(n); rowtuple = PyTuple_New(n);
for (j = 0; j < n; j++) for (j = 0; j < n; j++)
{ {
int k;
char *s = PQgetvalue(self->last_result, i, j); char *s = PQgetvalue(self->last_result, i, j);
char cashbuf[64]; char cashbuf[64];
...@@ -989,11 +1031,14 @@ pg_getresult(pgqueryobject * self, PyObject * args) ...@@ -989,11 +1031,14 @@ pg_getresult(pgqueryobject * self, PyObject * args)
if (*s == '$') /* there's talk of getting rid of it */ if (*s == '$') /* there's talk of getting rid of it */
s++; s++;
for (i = 0; *s; s++) if ((s[0] == '-' || s[0] == '(') && s[1] == '$')
*(++s) = '-';
for (k = 0; *s; s++)
if (*s != ',') if (*s != ',')
cashbuf[i++] = *s; cashbuf[k++] = *s;
cashbuf[i] = 0; cashbuf[k] = 0;
val = PyFloat_FromDouble(strtod(cashbuf, NULL)); val = PyFloat_FromDouble(strtod(cashbuf, NULL));
break; break;
...@@ -1016,8 +1061,13 @@ pg_getresult(pgqueryobject * self, PyObject * args) ...@@ -1016,8 +1061,13 @@ pg_getresult(pgqueryobject * self, PyObject * args)
} }
/* retrieves last result as a list of dictionaries*/ /* retrieves last result as a list of dictionaries*/
static char pgquery_dictresult__doc__[] =
"dictresult() -- Gets the result of a query. The result is returned "
"as a list of rows, each one a dictionary with the field names used "
"as the labels.";
static PyObject * static PyObject *
pg_dictresult(pgqueryobject * self, PyObject * args) pgquery_dictresult(pgqueryobject * self, PyObject * args)
{ {
PyObject *dict, *reslist, *val; PyObject *dict, *reslist, *val;
int i, j, m, n, *typ; int i, j, m, n, *typ;
...@@ -1037,7 +1087,7 @@ pg_dictresult(pgqueryobject * self, PyObject * args) ...@@ -1037,7 +1087,7 @@ pg_dictresult(pgqueryobject * self, PyObject * args)
if ((typ = malloc(sizeof(int) * n)) == NULL) if ((typ = malloc(sizeof(int) * n)) == NULL)
{ {
PyErr_SetString(PyExc_SyntaxError, "memory error in getresult()."); PyErr_SetString(PyExc_SyntaxError, "memory error in dictresult().");
return NULL; return NULL;
} }
...@@ -1089,6 +1139,9 @@ pg_dictresult(pgqueryobject * self, PyObject * args) ...@@ -1089,6 +1139,9 @@ pg_dictresult(pgqueryobject * self, PyObject * args)
if (*s == '$') /* there's talk of getting rid of it */ if (*s == '$') /* there's talk of getting rid of it */
s++; s++;
if ((s[0] == '-' || s[0] == '(') && s[1] == '$')
*(++s) = '-';
for (k = 0; *s; s++) for (k = 0; *s; s++)
if (*s != ',') if (*s != ',')
cashbuf[k++] = *s; cashbuf[k++] = *s;
...@@ -1116,7 +1169,10 @@ pg_dictresult(pgqueryobject * self, PyObject * args) ...@@ -1116,7 +1169,10 @@ pg_dictresult(pgqueryobject * self, PyObject * args)
return reslist; return reslist;
} }
/* getq asynchronous notify */ /* gets asynchronous notify */
static char pg_getnotify__doc__[] =
"getnotify() -- get database notify for this connection.";
static PyObject * static PyObject *
pg_getnotify(pgobject * self, PyObject * args) pg_getnotify(pgobject * self, PyObject * args)
{ {
...@@ -1164,6 +1220,9 @@ pg_getnotify(pgobject * self, PyObject * args) ...@@ -1164,6 +1220,9 @@ pg_getnotify(pgobject * self, PyObject * args)
} }
/* database query */ /* database query */
static char pg_query__doc__[] =
"query() -- creates a new query object for this connection.";
static PyObject * static PyObject *
pg_query(pgobject * self, PyObject * args) pg_query(pgobject * self, PyObject * args)
{ {
...@@ -1244,6 +1303,9 @@ pg_query(pgobject * self, PyObject * args) ...@@ -1244,6 +1303,9 @@ pg_query(pgobject * self, PyObject * args)
} }
#ifdef DIRECT_ACCESS #ifdef DIRECT_ACCESS
static char pg_putline__doc__[] =
"putline() -- sends a line directly to the backend";
/* direct acces function : putline */ /* direct acces function : putline */
static PyObject * static PyObject *
pg_putline(pgobject * self, PyObject * args) pg_putline(pgobject * self, PyObject * args)
...@@ -1270,6 +1332,9 @@ pg_putline(pgobject * self, PyObject * args) ...@@ -1270,6 +1332,9 @@ pg_putline(pgobject * self, PyObject * args)
} }
/* direct access function : getline */ /* direct access function : getline */
static char pg_getline__doc__[] =
"getline() -- gets a line directly from the backend.";
static PyObject * static PyObject *
pg_getline(pgobject * self, PyObject * args) pg_getline(pgobject * self, PyObject * args)
{ {
...@@ -1311,6 +1376,9 @@ pg_getline(pgobject * self, PyObject * args) ...@@ -1311,6 +1376,9 @@ pg_getline(pgobject * self, PyObject * args)
} }
/* direct access function : end copy */ /* direct access function : end copy */
static char pg_endcopy__doc__[] =
"endcopy() -- synchronizes client and server";
static PyObject * static PyObject *
pg_endcopy(pgobject * self, PyObject * args) pg_endcopy(pgobject * self, PyObject * args)
{ {
...@@ -1337,7 +1405,7 @@ pg_endcopy(pgobject * self, PyObject * args) ...@@ -1337,7 +1405,7 @@ pg_endcopy(pgobject * self, PyObject * args)
static PyObject * static PyObject *
pg_print(pgqueryobject *self, FILE *fp, int flags) pgquery_print(pgqueryobject *self, FILE *fp, int flags)
{ {
PQprintOpt op; PQprintOpt op;
...@@ -1351,6 +1419,10 @@ pg_print(pgqueryobject *self, FILE *fp, int flags) ...@@ -1351,6 +1419,10 @@ pg_print(pgqueryobject *self, FILE *fp, int flags)
} }
/* insert table */ /* insert table */
static char pg_inserttable__doc__[] =
"inserttable(string, list) -- insert list in table. The fields in the list "
"must be in the same order as in the table.";
static PyObject * static PyObject *
pg_inserttable(pgobject * self, PyObject * args) pg_inserttable(pgobject * self, PyObject * args)
{ {
...@@ -1492,25 +1564,120 @@ pg_inserttable(pgobject * self, PyObject * args) ...@@ -1492,25 +1564,120 @@ pg_inserttable(pgobject * self, PyObject * args)
return Py_None; return Py_None;
} }
/* creates large object */
static char pg_locreate__doc__[] =
"locreate() -- creates a new large object in the database.";
static PyObject *
pg_locreate(pgobject * self, PyObject * args)
{
int mode;
Oid lo_oid;
/* checks validity */
if (!check_cnx_obj(self))
return NULL;
/* gets arguments */
if (!PyArg_ParseTuple(args, "i", &mode))
{
PyErr_SetString(PyExc_TypeError,
"locreate(mode), with mode (integer).");
return NULL;
}
/* creates large object */
lo_oid = lo_creat(self->cnx, mode);
if (lo_oid == 0) {
PyErr_SetString(PGError, "can't create large object.");
return NULL;
}
return (PyObject *) pglarge_new(self, lo_oid);
}
/* init from already known oid */
static char pg_getlo__doc__[] =
"getlo(long) -- create a large object instance for the specified oid.";
static PyObject *
pg_getlo(pgobject * self, PyObject * args)
{
int lo_oid;
/* checks validity */
if (!check_cnx_obj(self))
return NULL;
/* gets arguments */
if (!PyArg_ParseTuple(args, "i", &lo_oid))
{
PyErr_SetString(PyExc_TypeError, "loopen(oid), with oid (integer).");
return NULL;
}
if (!lo_oid)
{
PyErr_SetString(PyExc_ValueError, "the object oid can't be null.");
return NULL;
}
/* creates object */
return (PyObject *) pglarge_new(self, lo_oid);
}
/* import unix file */
static char pg_loimport__doc__[] =
"loimport(string) -- create a new large object from specified file.";
static PyObject *
pg_loimport(pgobject * self, PyObject * args)
{
char *name;
Oid lo_oid;
/* checks validity */
if (!check_cnx_obj(self))
return NULL;
/* gets arguments */
if (!PyArg_ParseTuple(args, "s", &name))
{
PyErr_SetString(PyExc_TypeError, "loimport(name), with name (string).");
return NULL;
}
/* imports file and checks result */
lo_oid = lo_import(self->cnx, name);
if (lo_oid == 0)
{
PyErr_SetString(PGError, "can't create large object.");
return NULL;
}
return (PyObject *) pglarge_new(self, lo_oid);
}
/* connection object methods */ /* connection object methods */
static struct PyMethodDef pgobj_methods[] = { static struct PyMethodDef pgobj_methods[] = {
{"query", (PyCFunction) pg_query, 1}, /* query method */ {"query", (PyCFunction) pg_query, 1, pg_query__doc__ },
{"reset", (PyCFunction) pg_reset, 1}, /* connection reset */ {"reset", (PyCFunction) pg_reset, 1, pg_reset__doc__ },
{"close", (PyCFunction) pg_close, 1}, /* connection close */ {"close", (PyCFunction) pg_close, 1, pg_close__doc__ },
{"fileno", (PyCFunction) pg_fileno,1}, /* connection socket */ {"fileno", (PyCFunction) pg_fileno,1, pg_fileno__doc__ },
{"getnotify", (PyCFunction) pg_getnotify, 1}, /* checks for notify */ {"getnotify", (PyCFunction) pg_getnotify, 1, pg_getnotify__doc__ },
{"inserttable", (PyCFunction) pg_inserttable, 1}, /* table insert */ {"inserttable", (PyCFunction) pg_inserttable, 1, pg_inserttable__doc__ },
#ifdef DIRECT_ACCESS #ifdef DIRECT_ACCESS
{"putline", (PyCFunction) pg_putline, 1}, /* direct access: putline */ {"putline", (PyCFunction) pg_putline, 1, pg_putline__doc__ },
{"getline", (PyCFunction) pg_getline, 1}, /* direct access: getline */ {"getline", (PyCFunction) pg_getline, 1, pg_getline__doc__ },
{"endcopy", (PyCFunction) pg_endcopy, 1}, /* direct access: endcopy */ {"endcopy", (PyCFunction) pg_endcopy, 1, pg_endcopy__doc__ },
#endif /* DIRECT_ACCESS */ #endif /* DIRECT_ACCESS */
#ifdef LARGE_OBJECTS #ifdef LARGE_OBJECTS
{"locreate", (PyCFunction) pg_locreate, 1}, /* creates large object */ {"locreate", (PyCFunction) pg_locreate, 1, pg_locreate__doc__ },
{"getlo", (PyCFunction) pg_getlo, 1}, /* get lo from oid */ {"getlo", (PyCFunction) pg_getlo, 1, pg_getlo__doc__ },
{"loimport", (PyCFunction) pg_loimport, 1}, /* imports lo from file */ {"loimport", (PyCFunction) pg_loimport, 1, pg_loimport__doc__ },
#endif /* LARGE_OBJECTS */ #endif /* LARGE_OBJECTS */
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
...@@ -1613,16 +1780,18 @@ staticforward PyTypeObject PgType = { ...@@ -1613,16 +1780,18 @@ staticforward PyTypeObject PgType = {
/* query object methods */ /* query object methods */
static struct PyMethodDef pgquery_methods[] = { static struct PyMethodDef pgquery_methods[] = {
{"getresult", (PyCFunction) pg_getresult, 1}, /* get last result */ {"getresult", (PyCFunction) pgquery_getresult, 1, pgquery_getresult__doc__},
{"dictresult", (PyCFunction) pg_dictresult, 1}, /* get result as dict*/ {"dictresult", (PyCFunction) pgquery_dictresult, 1, pgquery_dictresult__doc__},
{"fieldname", (PyCFunction) pg_fieldname, 1}, /* get field name */ {"fieldname", (PyCFunction) pgquery_fieldname, 1, pgquery_fieldname__doc__},
{"fieldnum", (PyCFunction) pg_fieldnum, 1}, /* get field number */ {"fieldnum", (PyCFunction) pgquery_fieldnum, 1, pgquery_fieldnum__doc__},
{"listfields", (PyCFunction) pg_listfields, 1}, /* list fields names */ {"listfields", (PyCFunction) pgquery_listfields, 1, pgquery_listfields__doc__},
{NULL, NULL} /* sentinel */ {"ntuples", (PyCFunction) pgquery_ntuples, 1, pgquery_ntuples__doc__},
{NULL, NULL}
}; };
/* gets query object attributes */
static PyObject * static PyObject *
pg_querygetattr(pgqueryobject * self, char *name) pgquery_getattr(pgqueryobject * self, char *name)
{ {
/* list postgreSQL connection fields */ /* list postgreSQL connection fields */
return Py_FindMethod(pgquery_methods, (PyObject *) self, name); return Py_FindMethod(pgquery_methods, (PyObject *) self, name);
...@@ -1636,9 +1805,9 @@ staticforward PyTypeObject PgQueryType = { ...@@ -1636,9 +1805,9 @@ staticforward PyTypeObject PgQueryType = {
sizeof(pgqueryobject), /* tp_basicsize */ sizeof(pgqueryobject), /* tp_basicsize */
0, /* tp_itemsize */ 0, /* tp_itemsize */
/* methods */ /* methods */
(destructor) pg_querydealloc,/* tp_dealloc */ (destructor) pgquery_dealloc, /* tp_dealloc */
(printfunc) pg_print, /* tp_print */ (printfunc) pgquery_print, /* tp_print */
(getattrfunc) pg_querygetattr,/* tp_getattr */ (getattrfunc) pgquery_getattr, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
0, /* tp_compare */ 0, /* tp_compare */
0, /* tp_repr */ 0, /* tp_repr */
...@@ -1657,6 +1826,9 @@ staticforward PyTypeObject PgQueryType = { ...@@ -1657,6 +1826,9 @@ staticforward PyTypeObject PgQueryType = {
#ifdef DEFAULT_VARS #ifdef DEFAULT_VARS
/* gets default host */ /* gets default host */
static char getdefhost__doc__[] =
"get_defhost() -- return default database host.";
static PyObject * static PyObject *
pggetdefhost(PyObject *self, PyObject *args) pggetdefhost(PyObject *self, PyObject *args)
{ {
...@@ -1673,6 +1845,9 @@ pggetdefhost(PyObject *self, PyObject *args) ...@@ -1673,6 +1845,9 @@ pggetdefhost(PyObject *self, PyObject *args)
} }
/* sets default host */ /* sets default host */
static char setdefhost__doc__[] =
"set_defhost(string) -- set default database host. Return previous value.";
static PyObject * static PyObject *
pgsetdefhost(PyObject * self, PyObject *args) pgsetdefhost(PyObject * self, PyObject *args)
{ {
...@@ -1702,6 +1877,9 @@ pgsetdefhost(PyObject * self, PyObject *args) ...@@ -1702,6 +1877,9 @@ pgsetdefhost(PyObject * self, PyObject *args)
} }
/* gets default base */ /* gets default base */
static char getdefbase__doc__[] =
"get_defbase() -- return default database name.";
static PyObject * static PyObject *
pggetdefbase(PyObject * self, PyObject *args) pggetdefbase(PyObject * self, PyObject *args)
{ {
...@@ -1718,6 +1896,9 @@ pggetdefbase(PyObject * self, PyObject *args) ...@@ -1718,6 +1896,9 @@ pggetdefbase(PyObject * self, PyObject *args)
} }
/* sets default base */ /* sets default base */
static char setdefbase__doc__[] =
"set_defbase(string) -- set default database name. Return previous value";
static PyObject * static PyObject *
pgsetdefbase(PyObject * self, PyObject *args) pgsetdefbase(PyObject * self, PyObject *args)
{ {
...@@ -1747,6 +1928,9 @@ pgsetdefbase(PyObject * self, PyObject *args) ...@@ -1747,6 +1928,9 @@ pgsetdefbase(PyObject * self, PyObject *args)
} }
/* gets default options */ /* gets default options */
static char getdefopt__doc__[] =
"get_defopt() -- return default database options.";
static PyObject * static PyObject *
pggetdefopt(PyObject * self, PyObject *args) pggetdefopt(PyObject * self, PyObject *args)
{ {
...@@ -1763,6 +1947,9 @@ pggetdefopt(PyObject * self, PyObject *args) ...@@ -1763,6 +1947,9 @@ pggetdefopt(PyObject * self, PyObject *args)
} }
/* sets default opt */ /* sets default opt */
static char setdefopt__doc__[] =
"set_defopt(string) -- set default database options. Return previous value.";
static PyObject * static PyObject *
pgsetdefopt(PyObject * self, PyObject *args) pgsetdefopt(PyObject * self, PyObject *args)
{ {
...@@ -1792,6 +1979,9 @@ pgsetdefopt(PyObject * self, PyObject *args) ...@@ -1792,6 +1979,9 @@ pgsetdefopt(PyObject * self, PyObject *args)
} }
/* gets default tty */ /* gets default tty */
static char getdeftty__doc__[] =
"get_deftty() -- return default database debug terminal.";
static PyObject * static PyObject *
pggetdeftty(PyObject * self, PyObject *args) pggetdeftty(PyObject * self, PyObject *args)
{ {
...@@ -1808,6 +1998,10 @@ pggetdeftty(PyObject * self, PyObject *args) ...@@ -1808,6 +1998,10 @@ pggetdeftty(PyObject * self, PyObject *args)
} }
/* sets default tty */ /* sets default tty */
static char setdeftty__doc__[] =
"set_deftty(string) -- set default database debug terminal. "
"Return previous value.";
static PyObject * static PyObject *
pgsetdeftty(PyObject * self, PyObject *args) pgsetdeftty(PyObject * self, PyObject *args)
{ {
...@@ -1837,6 +2031,9 @@ pgsetdeftty(PyObject * self, PyObject *args) ...@@ -1837,6 +2031,9 @@ pgsetdeftty(PyObject * self, PyObject *args)
} }
/* gets default username */ /* gets default username */
static char getdefuser__doc__[] =
"get_defuser() -- return default database username.";
static PyObject * static PyObject *
pggetdefuser(PyObject * self, PyObject *args) pggetdefuser(PyObject * self, PyObject *args)
{ {
...@@ -1854,6 +2051,9 @@ pggetdefuser(PyObject * self, PyObject *args) ...@@ -1854,6 +2051,9 @@ pggetdefuser(PyObject * self, PyObject *args)
} }
/* sets default username */ /* sets default username */
static char setdefuser__doc__[] =
"set_defuser() -- set default database username. Return previous value.";
static PyObject * static PyObject *
pgsetdefuser(PyObject * self, PyObject *args) pgsetdefuser(PyObject * self, PyObject *args)
{ {
...@@ -1883,6 +2083,9 @@ pgsetdefuser(PyObject * self, PyObject *args) ...@@ -1883,6 +2083,9 @@ pgsetdefuser(PyObject * self, PyObject *args)
} }
/* sets default password */ /* sets default password */
static char setdefpasswd__doc__[] =
"set_defpasswd() -- set default database password.";
static PyObject * static PyObject *
pgsetdefpasswd(PyObject * self, PyObject *args) pgsetdefpasswd(PyObject * self, PyObject *args)
{ {
...@@ -1909,10 +2112,14 @@ None)."); ...@@ -1909,10 +2112,14 @@ None).");
pg_default_passwd = Py_None; pg_default_passwd = Py_None;
} }
return old; Py_INCREF(Py_None);
return Py_None;
} }
/* gets default port */ /* gets default port */
static char getdefport__doc__[] =
"get_defport() -- return default database port.";
static PyObject * static PyObject *
pggetdefport(PyObject * self, PyObject *args) pggetdefport(PyObject * self, PyObject *args)
{ {
...@@ -1929,6 +2136,9 @@ pggetdefport(PyObject * self, PyObject *args) ...@@ -1929,6 +2136,9 @@ pggetdefport(PyObject * self, PyObject *args)
} }
/* sets default port */ /* sets default port */
static char setdefport__doc__[] =
"set_defport(integer) -- set default database port. Return previous value.";
static PyObject * static PyObject *
pgsetdefport(PyObject * self, PyObject *args) pgsetdefport(PyObject * self, PyObject *args)
{ {
...@@ -1962,22 +2172,22 @@ pgsetdefport(PyObject * self, PyObject *args) ...@@ -1962,22 +2172,22 @@ pgsetdefport(PyObject * self, PyObject *args)
/* List of functions defined in the module */ /* List of functions defined in the module */
static struct PyMethodDef pg_methods[] = { static struct PyMethodDef pg_methods[] = {
{"connect", (PyCFunction) pgconnect, 3}, /* connect to a database */ {"connect", (PyCFunction) pgconnect, 3, connect__doc__ },
#ifdef DEFAULT_VARS #ifdef DEFAULT_VARS
{"get_defhost", pggetdefhost, 1}, /* gets default host */ {"get_defhost", pggetdefhost, 1, getdefhost__doc__ },
{"set_defhost", pgsetdefhost, 1}, /* sets default host */ {"set_defhost", pgsetdefhost, 1, setdefhost__doc__ },
{"get_defbase", pggetdefbase, 1}, /* gets default base */ {"get_defbase", pggetdefbase, 1, getdefbase__doc__ },
{"set_defbase", pgsetdefbase, 1}, /* sets default base */ {"set_defbase", pgsetdefbase, 1, setdefbase__doc__ },
{"get_defopt", pggetdefopt, 1}, /* gets default options */ {"get_defopt", pggetdefopt, 1, getdefopt__doc__ },
{"set_defopt", pgsetdefopt, 1}, /* sets default options */ {"set_defopt", pgsetdefopt, 1, setdefopt__doc__ },
{"get_deftty", pggetdeftty, 1}, /* gets default debug tty */ {"get_deftty", pggetdeftty, 1, getdeftty__doc__ },
{"set_deftty", pgsetdeftty, 1}, /* sets default debug tty */ {"set_deftty", pgsetdeftty, 1, setdeftty__doc__ },
{"get_defport", pggetdefport, 1}, /* gets default port */ {"get_defport", pggetdefport, 1, getdefport__doc__ },
{"set_defport", pgsetdefport, 1}, /* sets default port */ {"set_defport", pgsetdefport, 1, setdefport__doc__ },
{"get_defuser", pggetdefuser, 1}, /* gets default user */ {"get_defuser", pggetdefuser, 1, getdefuser__doc__ },
{"set_defuser", pgsetdefuser, 1}, /* sets default user */ {"set_defuser", pgsetdefuser, 1, setdefuser__doc__ },
{"set_defpasswd", pgsetdefpasswd, 1}, /* sets default passwd */ {"set_defpasswd", pgsetdefpasswd, 1, setdefpasswd__doc__ },
#endif /* DEFAULT_VARS */ #endif /* DEFAULT_VARS */
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment