Fixed both Python 2.5 and 64 bit problems.

This commit is contained in:
Federico Di Gregorio 2007-04-10 06:36:18 +00:00
parent fadd1a6938
commit e5829292cd
37 changed files with 887 additions and 753 deletions

View File

@ -1,3 +1,8 @@
2007-04-10 Federico Di Gregorio <fog@initd.org>
* Applied super-patch from David Rushby to fix Python 2.5 and 64
bit problems (all of them, kudos!)
2007-02-22 Federico Di Gregorio <fog@initd.org>
* Added support for per-connection and per-cursor typecasters.

View File

@ -6,8 +6,8 @@ recursive-include psycopg2da *
recursive-include examples *.py somehackers.jpg whereareyou.jpg
recursive-include debian *
recursive-include doc TODO HACKING SUCCESS ChangeLog-1.x async.txt
recursive-include doc *.rst *.css *.html
recursive-include scripts *.py *.sh
include scripts/maketypes.sh scripts/buildtypes.py
include AUTHORS README INSTALL LICENSE ChangeLog
include PKG-INFO MANIFEST.in MANIFEST setup.py setup.cfg
recursive-include doc *.rst *.css *.html

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -55,14 +56,14 @@ PyObject *
asis_conform(asisObject *self, PyObject *args)
{
PyObject *res, *proto;
if (!PyArg_ParseTuple(args, "O", &proto)) return NULL;
if (proto == (PyObject*)&isqlquoteType)
res = (PyObject*)self;
else
res = Py_None;
Py_INCREF(res);
return res;
}
@ -90,14 +91,18 @@ static PyMethodDef asisObject_methods[] = {
static int
asis_setup(asisObject *self, PyObject *obj)
{
Dprintf("asis_setup: init asis object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("asis_setup: init asis object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
self->wrapped = obj;
Py_INCREF(self->wrapped);
Dprintf("asis_setup: good asis object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("asis_setup: good asis object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
return 0;
}
@ -107,10 +112,12 @@ asis_dealloc(PyObject* obj)
asisObject *self = (asisObject *)obj;
Py_XDECREF(self->wrapped);
Dprintf("asis_dealloc: deleted asis object at %p, refcnt = %d",
obj, obj->ob_refcnt);
Dprintf("asis_dealloc: deleted asis object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt
);
obj->ob_type->tp_free(obj);
}
@ -118,7 +125,7 @@ static int
asis_init(PyObject *obj, PyObject *args, PyObject *kwds)
{
PyObject *o;
if (!PyArg_ParseTuple(args, "O", &o))
return -1;
@ -127,7 +134,7 @@ asis_init(PyObject *obj, PyObject *args, PyObject *kwds)
static PyObject *
asis_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
return type->tp_alloc(type, 0);
}
@ -159,7 +166,7 @@ PyTypeObject asisType = {
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
@ -171,14 +178,14 @@ PyTypeObject asisType = {
0, /*tp_call*/
(reprfunc)asis_str, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
asisType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -195,11 +202,11 @@ PyTypeObject asisType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
asis_init, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
asis_new, /*tp_new*/
@ -219,9 +226,9 @@ PyObject *
psyco_AsIs(PyObject *module, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "O", &obj))
return NULL;
return PyObject_CallFunction((PyObject *)&asisType, "O", obj);
}

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_ASIS_H
#define PSYCOPG_ASIS_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus
@ -39,7 +40,7 @@ typedef struct {
} asisObject;
/* functions exported to psycopgmodule.c */
extern PyObject *psyco_AsIs(PyObject *module, PyObject *args);
#define psyco_AsIs_doc \
"AsIs(obj) -> new AsIs wrapper object"

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -38,8 +39,8 @@
#ifndef PSYCOPG_OWN_QUOTING
static unsigned char *
binary_escape(unsigned char *from, unsigned int from_length,
unsigned int *to_length, PGconn *conn)
binary_escape(unsigned char *from, size_t from_length,
size_t *to_length, PGconn *conn)
{
#if PG_MAJOR_VERSION > 8 || \
(PG_MAJOR_VERSION == 8 && PG_MINOR_VERSION > 1) || \
@ -52,11 +53,11 @@ binary_escape(unsigned char *from, unsigned int from_length,
}
#else
static unsigned char *
binary_escape(unsigned char *from, unsigned int from_length,
unsigned int *to_length, PGconn *conn)
binary_escape(unsigned char *from, size_t from_length,
size_t *to_length, PGconn *conn)
{
unsigneed char *quoted, *chptr, *newptr;
int i, space, new_space;
unsigned char *quoted, *chptr, *newptr;
size_t i, space, new_space;
space = from_length + 2;
@ -67,7 +68,7 @@ binary_escape(unsigned char *from, unsigned int from_length,
chptr = quoted;
for (i=0; i < len; i++) {
for (i = 0; i < from_length; i++) {
if (chptr - quoted > space - 6) {
new_space = space * ((space) / (i + 1)) + 2 + 6;
if (new_space - space < 1024) space += 1024;
@ -102,7 +103,7 @@ binary_escape(unsigned char *from, unsigned int from_length,
}
else {
unsigned char c;
/* escape to octal notation \nnn */
*chptr++ = '\\';
*chptr++ = '\\';
@ -122,7 +123,7 @@ binary_escape(unsigned char *from, unsigned int from_length,
Py_END_ALLOW_THREADS;
*to_size = chptr - quoted + 1;
*to_length = chptr - quoted + 1;
return quoted;
}
#endif
@ -142,26 +143,26 @@ binary_quote(binaryObject *self)
/* escape and build quoted buffer */
PyObject_AsCharBuffer(self->wrapped, &buffer, &buffer_len);
to = (char *)binary_escape((unsigned char*)buffer, buffer_len, &len,
self->conn ? ((connectionObject*)self->conn)->pgconn : NULL);
to = (char *)binary_escape((unsigned char*)buffer, (size_t) buffer_len,
&len, self->conn ? ((connectionObject*)self->conn)->pgconn : NULL);
if (to == NULL) {
PyErr_NoMemory();
return NULL;
}
if (len > 0)
self->buffer = PyString_FromFormat("'%s'", to);
else
self->buffer = PyString_FromString("''");
if (len > 0)
self->buffer = PyString_FromFormat("'%s'", to);
else
self->buffer = PyString_FromString("''");
PQfreemem(to);
}
/* if the wrapped object is not a string or a buffer, this is an error */
/* if the wrapped object is not a string or a buffer, this is an error */
else {
PyErr_SetString(PyExc_TypeError, "can't escape non-string object");
return NULL;
}
return self->buffer;
}
@ -206,14 +207,14 @@ PyObject *
binary_conform(binaryObject *self, PyObject *args)
{
PyObject *res, *proto;
if (!PyArg_ParseTuple(args, "O", &proto)) return NULL;
if (proto == (PyObject*)&isqlquoteType)
res = (PyObject*)self;
else
res = Py_None;
Py_INCREF(res);
return res;
}
@ -244,16 +245,19 @@ static PyMethodDef binaryObject_methods[] = {
static int
binary_setup(binaryObject *self, PyObject *str)
{
Dprintf("binary_setup: init binary object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("binary_setup: init binary object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
self->buffer = NULL;
self->conn = NULL;
self->wrapped = str;
Py_INCREF(self->wrapped);
Dprintf("binary_setup: good binary object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("binary_setup: good binary object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt);
return 0;
}
@ -265,10 +269,12 @@ binary_dealloc(PyObject* obj)
Py_XDECREF(self->wrapped);
Py_XDECREF(self->buffer);
Py_XDECREF(self->conn);
Dprintf("binary_dealloc: deleted binary object at %p, refcnt = %d",
obj, obj->ob_refcnt);
Dprintf("binary_dealloc: deleted binary object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt
);
obj->ob_type->tp_free(obj);
}
@ -276,7 +282,7 @@ static int
binary_init(PyObject *obj, PyObject *args, PyObject *kwds)
{
PyObject *str;
if (!PyArg_ParseTuple(args, "O", &str))
return -1;
@ -285,7 +291,7 @@ binary_init(PyObject *obj, PyObject *args, PyObject *kwds)
static PyObject *
binary_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
return type->tp_alloc(type, 0);
}
@ -315,7 +321,7 @@ PyTypeObject binaryType = {
binary_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)binary_repr, /*tp_repr*/
@ -333,7 +339,7 @@ PyTypeObject binaryType = {
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
binaryType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -350,11 +356,11 @@ PyTypeObject binaryType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
binary_init, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
binary_new, /*tp_new*/
@ -374,9 +380,9 @@ PyObject *
psyco_Binary(PyObject *module, PyObject *args)
{
PyObject *str;
if (!PyArg_ParseTuple(args, "O", &str))
return NULL;
return PyObject_CallFunction((PyObject *)&binaryType, "O", str);
}

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_BINARY_H
#define PSYCOPG_BINARY_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <libpq-fe.h>
@ -40,7 +41,7 @@ typedef struct {
} binaryObject;
/* functions exported to psycopgmodule.c */
extern PyObject *psyco_Binary(PyObject *module, PyObject *args);
#define psyco_Binary_doc \
"Binary(buffer) -> new binary object\n\n" \

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -62,11 +63,11 @@ pydatetime_str(pydatetimeObject *self)
}
else {
PyDateTime_Delta *obj = (PyDateTime_Delta*)self->wrapped;
char buffer[8];
int i;
int a = obj->microseconds;
for (i=0; i < 6 ; i++) {
buffer[5-i] = '0' + (a % 10);
a /= 10;
@ -89,14 +90,14 @@ PyObject *
pydatetime_conform(pydatetimeObject *self, PyObject *args)
{
PyObject *res, *proto;
if (!PyArg_ParseTuple(args, "O", &proto)) return NULL;
if (proto == (PyObject*)&isqlquoteType)
res = (PyObject*)self;
else
res = Py_None;
Py_INCREF(res);
return res;
}
@ -125,15 +126,19 @@ static PyMethodDef pydatetimeObject_methods[] = {
static int
pydatetime_setup(pydatetimeObject *self, PyObject *obj, int type)
{
Dprintf("pydatetime_setup: init datetime object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("pydatetime_setup: init datetime object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
self->type = type;
self->wrapped = obj;
Py_INCREF(self->wrapped);
Dprintf("pydatetime_setup: good pydatetime object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("pydatetime_setup: good pydatetime object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
return 0;
}
@ -143,10 +148,10 @@ pydatetime_dealloc(PyObject* obj)
pydatetimeObject *self = (pydatetimeObject *)obj;
Py_XDECREF(self->wrapped);
Dprintf("mpydatetime_dealloc: deleted pydatetime object at %p, "
"refcnt = %d", obj, obj->ob_refcnt);
"refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, obj->ob_refcnt);
obj->ob_type->tp_free(obj);
}
@ -155,7 +160,7 @@ pydatetime_init(PyObject *obj, PyObject *args, PyObject *kwds)
{
PyObject *dt;
int type = -1; /* raise an error if type was not passed! */
if (!PyArg_ParseTuple(args, "O|i", &dt, &type))
return -1;
@ -164,7 +169,7 @@ pydatetime_init(PyObject *obj, PyObject *args, PyObject *kwds)
static PyObject *
pydatetime_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
return type->tp_alloc(type, 0);
}
@ -195,7 +200,7 @@ PyTypeObject pydatetimeType = {
pydatetime_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)pydatetime_repr, /*tp_repr*/
@ -213,7 +218,7 @@ PyTypeObject pydatetimeType = {
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
pydatetimeType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -230,11 +235,11 @@ PyTypeObject pydatetimeType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
pydatetime_init, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
pydatetime_new, /*tp_new*/
@ -253,15 +258,15 @@ PyTypeObject pydatetimeType = {
#ifdef PSYCOPG_DEFAULT_PYDATETIME
PyObject *
psyco_Date(PyObject *self, PyObject *args)
psyco_Date(PyObject *self, PyObject *args)
{
PyObject *res = NULL;
int year, month, day;
PyObject *res = NULL;
int year, month, day;
PyObject* obj = NULL;
if (!PyArg_ParseTuple(args, "iii", &year, &month, &day))
return NULL;
if (!PyArg_ParseTuple(args, "iii", &year, &month, &day))
return NULL;
obj = PyObject_CallFunction(pyDateTypeP, "iii", year, month, day);
@ -275,18 +280,18 @@ psyco_Date(PyObject *self, PyObject *args)
}
PyObject *
psyco_Time(PyObject *self, PyObject *args)
psyco_Time(PyObject *self, PyObject *args)
{
PyObject *res = NULL;
PyObject *tzinfo = NULL;
int hours, minutes=0;
double micro, second=0.0;
PyObject* obj = NULL;
if (!PyArg_ParseTuple(args, "iid|O", &hours, &minutes, &second,
&tzinfo))
return NULL;
return NULL;
micro = (second - floor(second)) * 1000000.0;
second = floor(second);
@ -297,7 +302,7 @@ psyco_Time(PyObject *self, PyObject *args)
else
obj = PyObject_CallFunction(pyTimeTypeP, "iiiiO",
hours, minutes, (int)second, (int)round(micro), tzinfo);
if (obj) {
res = PyObject_CallFunction((PyObject *)&pydatetimeType,
"Oi", obj, PSYCO_DATETIME_TIME);
@ -308,7 +313,7 @@ psyco_Time(PyObject *self, PyObject *args)
}
PyObject *
psyco_Timestamp(PyObject *self, PyObject *args)
psyco_Timestamp(PyObject *self, PyObject *args)
{
PyObject *res = NULL;
PyObject *tzinfo = NULL;
@ -317,10 +322,10 @@ psyco_Timestamp(PyObject *self, PyObject *args)
double micro, second=0.0;
PyObject* obj = NULL;
if (!PyArg_ParseTuple(args, "lii|iidO", &year, &month, &day,
&hour, &minute, &second, &tzinfo))
return NULL;
return NULL;
micro = (second - floor(second)) * 1000000.0;
second = floor(second);
@ -333,13 +338,13 @@ psyco_Timestamp(PyObject *self, PyObject *args)
obj = PyObject_CallFunction(pyDateTimeTypeP, "iiiiiiiO",
year, month, day, hour, minute, (int)second,
(int)round(micro), tzinfo);
if (obj) {
res = PyObject_CallFunction((PyObject *)&pydatetimeType,
"Oi", obj, PSYCO_DATETIME_TIMESTAMP);
Py_DECREF(obj);
}
return res;
}
@ -361,8 +366,8 @@ psyco_DateFromTicks(PyObject *self, PyObject *args)
res = psyco_Date(self, args);
Py_DECREF(args);
}
}
return res;
}
return res;
}
PyObject *
@ -380,13 +385,13 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args)
ticks -= (double)t;
if (localtime_r(&t, &tm)) {
args = Py_BuildValue("iid", tm.tm_hour, tm.tm_min,
(double)tm.tm_sec + ticks);
(double)tm.tm_sec + ticks);
if (args) {
res = psyco_Time(self, args);
Py_DECREF(args);
}
}
return res;
}
return res;
}
PyObject *
@ -399,21 +404,21 @@ psyco_TimestampFromTicks(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args,"d", &ticks))
return NULL;
t = (time_t)round(ticks);
ticks -= (double)t;
if (localtime_r(&t, &tm)) {
args = Py_BuildValue("iiiiidO",
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
tm.tm_hour, tm.tm_min,
(double)tm.tm_sec + ticks,
(double)tm.tm_sec + ticks,
pyPsycopgTzLOCAL);
if (args) {
res = psyco_Timestamp(self, args);
Py_DECREF(args);
}
}
return res;
}
return res;
}
#endif
@ -425,7 +430,7 @@ psyco_DateFromPy(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!", pyDateTypeP, &obj))
return NULL;
return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj,
PSYCO_DATETIME_DATE);
}
@ -437,7 +442,7 @@ psyco_TimeFromPy(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!", pyTimeTypeP, &obj))
return NULL;
return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj,
PSYCO_DATETIME_TIME);
}
@ -449,7 +454,7 @@ psyco_TimestampFromPy(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!", pyDateTimeTypeP, &obj))
return NULL;
return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj,
PSYCO_DATETIME_TIMESTAMP);
}
@ -461,7 +466,7 @@ psyco_IntervalFromPy(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!", pyDeltaTypeP, &obj))
return NULL;
return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj,
PSYCO_DATETIME_INTERVAL);
}

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_DATETIME_H
#define PSYCOPG_DATETIME_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus
@ -38,14 +39,14 @@ typedef struct {
#define PSYCO_DATETIME_TIME 0
#define PSYCO_DATETIME_DATE 1
#define PSYCO_DATETIME_TIMESTAMP 2
#define PSYCO_DATETIME_INTERVAL 3
#define PSYCO_DATETIME_INTERVAL 3
} pydatetimeObject;
/* functions exported to psycopgmodule.c */
#ifdef PSYCOPG_DEFAULT_PYDATETIME
extern PyObject *psyco_Date(PyObject *module, PyObject *args);
#define psyco_Date_doc \
"Date(year, month, day) -> new date\n\n" \
@ -99,7 +100,7 @@ extern PyObject *psyco_TimestampFromPy(PyObject *module, PyObject *args);
extern PyObject *psyco_IntervalFromPy(PyObject *module, PyObject *args);
#define psyco_IntervalFromPy_doc \
"IntervalFromPy(datetime.timedelta) -> new wrapper"
#ifdef __cplusplus
}
#endif

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -43,20 +44,20 @@ list_quote(listObject *self)
Py_ssize_t i, len;
len = PyList_GET_SIZE(self->wrapped);
/* empty arrays are converted to NULLs (still searching for a way to
insert an empty array in postgresql */
if (len == 0) return PyString_FromString("'{}'");
tmp = PyTuple_New(len);
for (i=0; i<len; i++) {
PyObject *quoted;
PyObject *wrapped = PyList_GET_ITEM(self->wrapped, i);
if (wrapped == Py_None)
quoted = PyString_FromString("NULL");
else
quoted = microprotocol_getquoted(wrapped,
PyObject *wrapped = PyList_GET_ITEM(self->wrapped, i);
if (wrapped == Py_None)
quoted = PyString_FromString("NULL");
else
quoted = microprotocol_getquoted(wrapped,
(connectionObject*)self->connection);
if (quoted == NULL) goto error;
@ -73,7 +74,7 @@ list_quote(listObject *self)
if (joined == NULL) goto error;
res = PyString_FromFormat("ARRAY[%s]", PyString_AsString(joined));
error:
Py_XDECREF(tmp);
Py_XDECREF(str);
@ -110,7 +111,7 @@ list_prepare(listObject *self, PyObject *args)
Py_XDECREF(self->connection);
self->connection = (PyObject*)conn;
Py_INCREF(self->connection);
Py_INCREF(Py_None);
return Py_None;
}
@ -119,14 +120,14 @@ PyObject *
list_conform(listObject *self, PyObject *args)
{
PyObject *res, *proto;
if (!PyArg_ParseTuple(args, "O", &proto)) return NULL;
if (proto == (PyObject*)&isqlquoteType)
res = (PyObject*)self;
else
res = Py_None;
Py_INCREF(res);
return res;
}
@ -146,7 +147,7 @@ static PyMethodDef listObject_methods[] = {
{"getquoted", (PyCFunction)list_getquoted, METH_VARARGS,
"getquoted() -> wrapped object value as SQL date/time"},
{"prepare", (PyCFunction)list_prepare, METH_VARARGS,
"prepare(conn) -> set encoding to conn->encoding"},
"prepare(conn) -> set encoding to conn->encoding"},
{"__conform__", (PyCFunction)list_conform, METH_VARARGS, NULL},
{NULL} /* Sentinel */
};
@ -156,8 +157,10 @@ static PyMethodDef listObject_methods[] = {
static int
list_setup(listObject *self, PyObject *obj, char *enc)
{
Dprintf("list_setup: init list object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("list_setup: init list object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
if (!PyList_Check(obj))
return -1;
@ -168,9 +171,11 @@ list_setup(listObject *self, PyObject *obj, char *enc)
self->connection = NULL;
self->wrapped = obj;
Py_INCREF(self->wrapped);
Dprintf("list_setup: good list object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("list_setup: good list object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
return 0;
}
@ -182,10 +187,10 @@ list_dealloc(PyObject* obj)
Py_XDECREF(self->wrapped);
Py_XDECREF(self->connection);
if (self->encoding) free(self->encoding);
Dprintf("list_dealloc: deleted list object at %p, "
"refcnt = %d", obj, obj->ob_refcnt);
"refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, obj->ob_refcnt);
obj->ob_type->tp_free(obj);
}
@ -194,7 +199,7 @@ list_init(PyObject *obj, PyObject *args, PyObject *kwds)
{
PyObject *l;
char *enc = "latin-1"; /* default encoding as in Python */
if (!PyArg_ParseTuple(args, "O|s", &l, &enc))
return -1;
@ -203,7 +208,7 @@ list_init(PyObject *obj, PyObject *args, PyObject *kwds)
static PyObject *
list_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
return type->tp_alloc(type, 0);
}
@ -233,7 +238,7 @@ PyTypeObject listType = {
list_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)list_repr, /*tp_repr*/
@ -251,7 +256,7 @@ PyTypeObject listType = {
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
listType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -268,11 +273,11 @@ PyTypeObject listType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
list_init, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
list_new, /*tp_new*/
@ -293,9 +298,9 @@ psyco_List(PyObject *module, PyObject *args)
{
PyObject *str;
char *enc = "latin-1"; /* default encoding as in Python */
if (!PyArg_ParseTuple(args, "O|s", &str, &enc))
return NULL;
return PyObject_CallFunction((PyObject *)&listType, "Os", str, enc);
}

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_LIST_H
#define PSYCOPG_LIST_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -68,23 +69,23 @@ mxdatetime_str(mxdatetimeObject *self)
/* given the limitation of the mx.DateTime module that uses the same
type for both time and delta values we need to do some black magic
and make sure we're not using an adapt()ed interval as a simple
time */
time */
if (PyString_Size(str) > 8 && PyString_AsString(str)[8] == ':') {
mxDateTimeDeltaObject *obj = (mxDateTimeDeltaObject*)self->wrapped;
char buffer[8];
int i, j, x;
double ss = obj->hour*3600.0 + obj->minute*60.0 + obj->second;
int us = (int)((ss - floor(ss))*1000000);
for (i=1000000, j=0; i > 0 ; i /= 10) {
x = us/i;
us -= x*i;
buffer[j++] = '0'+x;
}
buffer[j] = '\0';
res = PyString_FromFormat("'%ld days %d.%s seconds'",
obj->day, (int)round(ss), buffer);
}
@ -94,7 +95,7 @@ mxdatetime_str(mxdatetimeObject *self)
if (str != NULL && res == NULL) {
res = PyString_FromFormat("'%s'", PyString_AsString(str));
}
Py_XDECREF(str);
Py_XDECREF(str);
return res;
}
@ -110,14 +111,14 @@ PyObject *
mxdatetime_conform(mxdatetimeObject *self, PyObject *args)
{
PyObject *res, *proto;
if (!PyArg_ParseTuple(args, "O", &proto)) return NULL;
if (proto == (PyObject*)&isqlquoteType)
res = (PyObject*)self;
else
res = Py_None;
Py_INCREF(res);
return res;
}
@ -146,15 +147,19 @@ static PyMethodDef mxdatetimeObject_methods[] = {
static int
mxdatetime_setup(mxdatetimeObject *self, PyObject *obj, int type)
{
Dprintf("mxdatetime_setup: init mxdatetime object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("mxdatetime_setup: init mxdatetime object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
self->type = type;
self->wrapped = obj;
Py_INCREF(self->wrapped);
Dprintf("mxdatetime_setup: good mxdatetime object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("mxdatetime_setup: good mxdatetime object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
return 0;
}
@ -164,10 +169,12 @@ mxdatetime_dealloc(PyObject* obj)
mxdatetimeObject *self = (mxdatetimeObject *)obj;
Py_XDECREF(self->wrapped);
Dprintf("mxdatetime_dealloc: deleted mxdatetime object at %p, refcnt = %d",
obj, obj->ob_refcnt);
Dprintf("mxdatetime_dealloc: deleted mxdatetime object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt
);
obj->ob_type->tp_free(obj);
}
@ -176,7 +183,7 @@ mxdatetime_init(PyObject *obj, PyObject *args, PyObject *kwds)
{
PyObject *mx;
int type = -1; /* raise an error if type was not passed! */
if (!PyArg_ParseTuple(args, "O|i", &mx, &type))
return -1;
@ -185,7 +192,7 @@ mxdatetime_init(PyObject *obj, PyObject *args, PyObject *kwds)
static PyObject *
mxdatetime_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
return type->tp_alloc(type, 0);
}
@ -216,7 +223,7 @@ PyTypeObject mxdatetimeType = {
mxdatetime_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)mxdatetime_repr, /*tp_repr*/
@ -234,7 +241,7 @@ PyTypeObject mxdatetimeType = {
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
mxdatetimeType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -251,11 +258,11 @@ PyTypeObject mxdatetimeType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
mxdatetime_init, /*tp_init*/
0, /*tp_alloc*/
mxdatetime_new, /*tp_new*/
@ -274,15 +281,15 @@ PyTypeObject mxdatetimeType = {
#ifdef PSYCOPG_DEFAULT_MXDATETIME
PyObject *
psyco_Date(PyObject *self, PyObject *args)
psyco_Date(PyObject *self, PyObject *args)
{
PyObject *res, *mx;
int year, month, day;
if (!PyArg_ParseTuple(args, "iii", &year, &month, &day))
return NULL;
mx = mxDateTimeP->DateTime_FromDateAndTime(year, month, day, 0, 0, 0.0);
PyObject *res, *mx;
int year, month, day;
if (!PyArg_ParseTuple(args, "iii", &year, &month, &day))
return NULL;
mx = mxDateTimeP->DateTime_FromDateAndTime(year, month, day, 0, 0, 0.0);
if (mx == NULL) return NULL;
res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
@ -292,35 +299,35 @@ psyco_Date(PyObject *self, PyObject *args)
}
PyObject *
psyco_Time(PyObject *self, PyObject *args)
psyco_Time(PyObject *self, PyObject *args)
{
PyObject *res, *mx;
PyObject *res, *mx;
int hours, minutes=0;
double seconds=0.0;
double seconds=0.0;
if (!PyArg_ParseTuple(args, "iid", &hours, &minutes, &seconds))
return NULL;
mx = mxDateTimeP->DateTimeDelta_FromTime(hours, minutes, seconds);
return NULL;
mx = mxDateTimeP->DateTimeDelta_FromTime(hours, minutes, seconds);
if (mx == NULL) return NULL;
res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_TIME);
Py_DECREF(mx);
return res;
return res;
}
PyObject *
psyco_Timestamp(PyObject *self, PyObject *args)
psyco_Timestamp(PyObject *self, PyObject *args)
{
PyObject *res, *mx;
PyObject *res, *mx;
int year, month, day;
int hour=0, minute=0; /* default to midnight */
double second=0.0;
int hour=0, minute=0; /* default to midnight */
double second=0.0;
if (!PyArg_ParseTuple(args, "lii|iid", &year, &month, &day,
&hour, &minute, &second))
return NULL;
return NULL;
mx = mxDateTimeP->DateTime_FromDateAndTime(year, month, day,
hour, minute, second);
@ -329,7 +336,7 @@ psyco_Timestamp(PyObject *self, PyObject *args)
res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_TIMESTAMP);
Py_DECREF(mx);
return res;
return res;
}
PyObject *
@ -340,14 +347,14 @@ psyco_DateFromTicks(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args,"d", &ticks))
return NULL;
if (!(mx = mxDateTimeP->DateTime_FromTicks(ticks)))
return NULL;
res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_DATE);
Py_DECREF(mx);
return res;
return res;
}
PyObject *
@ -358,7 +365,7 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args,"d", &ticks))
return NULL;
if (!(dt = mxDateTimeP->DateTime_FromTicks(ticks)))
return NULL;
@ -373,7 +380,7 @@ psyco_TimeFromTicks(PyObject *self, PyObject *args)
res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_TIME);
Py_DECREF(mx);
return res;
return res;
}
PyObject *
@ -384,14 +391,14 @@ psyco_TimestampFromTicks(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "d", &ticks))
return NULL;
if (!(mx = mxDateTimeP->DateTime_FromTicks(ticks)))
return NULL;
res = PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_TIMESTAMP);
Py_DECREF(mx);
return res;
return res;
}
#endif
@ -403,7 +410,7 @@ psyco_DateFromMx(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!", mxDateTimeP->DateTime_Type, &mx))
return NULL;
return PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_DATE);
}
@ -415,7 +422,7 @@ psyco_TimeFromMx(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!", mxDateTimeP->DateTimeDelta_Type, &mx))
return NULL;
return PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_TIME);
}
@ -427,7 +434,7 @@ psyco_TimestampFromMx(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!", mxDateTimeP->DateTime_Type, &mx))
return NULL;
return PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_TIMESTAMP);
}
@ -439,7 +446,7 @@ psyco_IntervalFromMx(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!", mxDateTimeP->DateTime_Type, &mx))
return NULL;
return PyObject_CallFunction((PyObject *)&mxdatetimeType, "Oi", mx,
PSYCO_MXDATETIME_INTERVAL);
}

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_MXDATETIME_H
#define PSYCOPG_MXDATETIME_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus
@ -38,13 +39,13 @@ typedef struct {
#define PSYCO_MXDATETIME_TIME 0
#define PSYCO_MXDATETIME_DATE 1
#define PSYCO_MXDATETIME_TIMESTAMP 2
#define PSYCO_MXDATETIME_INTERVAL 3
#define PSYCO_MXDATETIME_INTERVAL 3
} mxdatetimeObject;
/* functions exported to psycopgmodule.c */
#ifdef PSYCOPG_DEFAULT_MXDATETIME
extern PyObject *psyco_Date(PyObject *module, PyObject *args);
#define psyco_Date_doc \
"Date(year, month, day) -> new date"
@ -56,7 +57,7 @@ extern PyObject *psyco_Time(PyObject *module, PyObject *args);
extern PyObject *psyco_Timestamp(PyObject *module, PyObject *args);
#define psyco_Timestamp_doc \
"Time(year, month, day, hour, minutes, seconds) -> new timestamp"
extern PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args);
#define psyco_DateFromTicks_doc \
"DateFromTicks(ticks) -> new date"
@ -86,7 +87,7 @@ extern PyObject *psyco_TimestampFromMx(PyObject *module, PyObject *args);
extern PyObject *psyco_IntervalFromMx(PyObject *module, PyObject *args);
#define psyco_IntervalFromMx_doc \
"IntervalFromMx(mx) -> new interval"
#ifdef __cplusplus
}
#endif

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -65,14 +66,14 @@ PyObject *
pboolean_conform(pbooleanObject *self, PyObject *args)
{
PyObject *res, *proto;
if (!PyArg_ParseTuple(args, "O", &proto)) return NULL;
if (proto == (PyObject*)&isqlquoteType)
res = (PyObject*)self;
else
res = Py_None;
Py_INCREF(res);
return res;
}
@ -100,14 +101,18 @@ static PyMethodDef pbooleanObject_methods[] = {
static int
pboolean_setup(pbooleanObject *self, PyObject *obj)
{
Dprintf("pboolean_setup: init pboolean object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("pboolean_setup: init pboolean object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
self->wrapped = obj;
Py_INCREF(self->wrapped);
Dprintf("pboolean_setup: good pboolean object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("pboolean_setup: good pboolean object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
return 0;
}
@ -117,10 +122,12 @@ pboolean_dealloc(PyObject* obj)
pbooleanObject *self = (pbooleanObject *)obj;
Py_XDECREF(self->wrapped);
Dprintf("pboolean_dealloc: deleted pboolean object at %p, refcnt = %d",
obj, obj->ob_refcnt);
Dprintf("pboolean_dealloc: deleted pboolean object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt
);
obj->ob_type->tp_free(obj);
}
@ -128,7 +135,7 @@ static int
pboolean_init(PyObject *obj, PyObject *args, PyObject *kwds)
{
PyObject *o;
if (!PyArg_ParseTuple(args, "O", &o))
return -1;
@ -137,7 +144,7 @@ pboolean_init(PyObject *obj, PyObject *args, PyObject *kwds)
static PyObject *
pboolean_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
return type->tp_alloc(type, 0);
}
@ -170,7 +177,7 @@ PyTypeObject pbooleanType = {
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
@ -182,14 +189,14 @@ PyTypeObject pbooleanType = {
0, /*tp_call*/
(reprfunc)pboolean_str, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
pbooleanType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -206,11 +213,11 @@ PyTypeObject pbooleanType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
pboolean_init, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
pboolean_new, /*tp_new*/
@ -230,9 +237,9 @@ PyObject *
psyco_Boolean(PyObject *module, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "O", &obj))
return NULL;
return PyObject_CallFunction((PyObject *)&pbooleanType, "O", obj);
}

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_PBOOLEAN_H
#define PSYCOPG_PBOOLEAN_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus
@ -39,7 +40,7 @@ typedef struct {
} pbooleanObject;
/* functions exported to psycopgmodule.c */
extern PyObject *psyco_Boolean(PyObject *module, PyObject *args);
#define psyco_Boolean_doc \
"Boolean(obj) -> new boolean value"

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -100,7 +101,7 @@ qstring_quote(qstringObject *self)
/* TODO: we need a real translation table from postgres encoding names to
python ones here */
Dprintf("qstring_quote: encoding to %s", self->encoding);
if (PyUnicode_Check(self->wrapped) && self->encoding) {
@ -129,8 +130,8 @@ qstring_quote(qstringObject *self)
/* INCREF to make it ref-wise identical to unicode one */
Py_INCREF(str);
}
/* if the wrapped object is not a string, this is an error */
/* if the wrapped object is not a string, this is an error */
else {
PyErr_SetString(PyExc_TypeError,
"can't quote non-string object (or missing encoding)");
@ -139,7 +140,7 @@ qstring_quote(qstringObject *self)
/* encode the string into buffer */
PyString_AsStringAndSize(str, &s, &len);
buffer = (char *)PyMem_Malloc((len*2+3) * sizeof(char));
if (buffer == NULL) {
Py_DECREF(str);
@ -152,11 +153,11 @@ qstring_quote(qstringObject *self)
self->conn ? ((connectionObject*)self->conn)->pgconn : NULL);
buffer[0] = '\'' ; buffer[len+1] = '\'';
Py_END_ALLOW_THREADS;
self->buffer = PyString_FromStringAndSize(buffer, len+2);
PyMem_Free(buffer);
Py_DECREF(str);
return self->buffer;
}
@ -204,19 +205,19 @@ qstring_prepare(qstringObject *self, PyObject *args)
Py_INCREF(Py_None);
return Py_None;
}
PyObject *
qstring_conform(qstringObject *self, PyObject *args)
{
PyObject *res, *proto;
if (!PyArg_ParseTuple(args, "O", &proto)) return NULL;
if (proto == (PyObject*)&isqlquoteType)
res = (PyObject*)self;
else
res = Py_None;
Py_INCREF(res);
return res;
}
@ -248,20 +249,24 @@ static PyMethodDef qstringObject_methods[] = {
static int
qstring_setup(qstringObject *self, PyObject *str, char *enc)
{
Dprintf("qstring_setup: init qstring object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("qstring_setup: init qstring object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
self->buffer = NULL;
self->conn = NULL;
/* FIXME: remove this orrible strdup */
if (enc) self->encoding = strdup(enc);
self->wrapped = str;
Py_INCREF(self->wrapped);
Dprintf("qstring_setup: good qstring object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("qstring_setup: good qstring object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
return 0;
}
@ -275,10 +280,12 @@ qstring_dealloc(PyObject* obj)
Py_XDECREF(self->conn);
if (self->encoding) free(self->encoding);
Dprintf("qstring_dealloc: deleted qstring object at %p, refcnt = %d",
obj, obj->ob_refcnt);
Dprintf("qstring_dealloc: deleted qstring object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt
);
obj->ob_type->tp_free(obj);
}
@ -287,7 +294,7 @@ qstring_init(PyObject *obj, PyObject *args, PyObject *kwds)
{
PyObject *str;
char *enc = "latin-1"; /* default encoding as in Python */
if (!PyArg_ParseTuple(args, "O|s", &str, &enc))
return -1;
@ -296,7 +303,7 @@ qstring_init(PyObject *obj, PyObject *args, PyObject *kwds)
static PyObject *
qstring_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
return type->tp_alloc(type, 0);
}
@ -309,7 +316,7 @@ qstring_del(PyObject* self)
static PyObject *
qstring_repr(qstringObject *self)
{
return PyString_FromFormat("<psycopg2._psycopg.QuotedString object at %p>",
return PyString_FromFormat("<psycopg2._psycopg.QuotedString object at %p>",
self);
}
@ -327,7 +334,7 @@ PyTypeObject qstringType = {
qstring_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)qstring_repr, /*tp_repr*/
@ -345,7 +352,7 @@ PyTypeObject qstringType = {
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
qstringType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -362,11 +369,11 @@ PyTypeObject qstringType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
qstring_init, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
qstring_new, /*tp_new*/
@ -387,9 +394,9 @@ psyco_QuotedString(PyObject *module, PyObject *args)
{
PyObject *str;
char *enc = "latin-1"; /* default encoding as in Python */
if (!PyArg_ParseTuple(args, "O|s", &str, &enc))
return NULL;
return PyObject_CallFunction((PyObject *)&qstringType, "Os", str, enc);
}

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_QSTRING_H
#define PSYCOPG_QSTRING_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus
@ -39,9 +40,9 @@ typedef struct {
PyObject *conn;
} qstringObject;
/* functions exported to psycopgmodule.c */
extern PyObject *psyco_QuotedString(PyObject *module, PyObject *args);
#define psyco_QuotedString_doc \
"QuotedString(str, enc) -> new quoted string"

View File

@ -28,7 +28,7 @@
#include <sys/types.h>
#include <unistd.h>
#define Dprintf(fmt, args...) \
fprintf(stderr, "[%d] " fmt "\n", getpid() , ## args)
fprintf(stderr, "[%d] " fmt "\n", (int) getpid() , ## args)
#else
#define Dprintf(fmt, args...)
#endif

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_CONNECTION_H
#define PSYCOPG_CONNECTION_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <libpq-fe.h>
@ -34,7 +35,7 @@ extern "C" {
#define CONN_STATUS_BEGIN 2
#define CONN_STATUS_SYNC 3
#define CONN_STATUS_ASYNC 4
extern PyTypeObject connectionType;
typedef struct {
@ -45,17 +46,17 @@ typedef struct {
char *dsn; /* data source name */
char *critical; /* critical error on this connection */
char *encoding; /* current backend encoding */
long int closed; /* 2 means connection has been closed */
long int isolation_level; /* isolation level for this connection */
long int mark; /* number of commits/rollbacks done so far */
long int mark; /* number of commits/rollbacks done so far */
int status; /* status of the connection */
int protocol; /* protocol version */
PGconn *pgconn; /* the postgresql connection */
PyObject *async_cursor;
/* notice processing */
PyObject *notice_list;
PyObject *notice_filter;
@ -80,20 +81,20 @@ typedef struct {
PyObject *binary_types; /* a set of typecasters for binary types */
} connectionObject;
/* C-callable functions in connection_int.c and connection_ext.c */
extern int conn_connect(connectionObject *self);
extern void conn_close(connectionObject *self);
extern int conn_commit(connectionObject *self);
extern int conn_rollback(connectionObject *self);
extern int conn_switch_isolation_level(connectionObject *self, int level);
extern int conn_set_client_encoding(connectionObject *self, char *enc);
extern int conn_set_client_encoding(connectionObject *self, char *enc);
/* exception-raising macros */
#define EXC_IF_CONN_CLOSED(self) if ((self)->closed > 0) { \
PyErr_SetString(InterfaceError, "connection already closed"); \
return NULL; }
#ifdef __cplusplus
}
#endif

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <string.h>
@ -55,22 +56,22 @@ conn_connect(connectionObject *self)
PGresult *pgres;
char *data, *tmp;
int i;
/* we need the initial date style to be ISO, for typecasters; if the user
later change it, she must know what she's doing... */
const char *datestyle = "SET DATESTYLE TO 'ISO'";
const char *encoding = "SHOW client_encoding";
const char *isolevel = "SHOW default_transaction_isolation";
const char *lvl1a = "read uncommitted";
const char *lvl1b = "read committed";
const char *lvl2a = "repeatable read";
const char *lvl2b = "serializable";
Py_BEGIN_ALLOW_THREADS;
pgconn = PQconnectdb(self->dsn);
Py_END_ALLOW_THREADS;
Dprintf("conn_connect: new postgresql connection at %p", pgconn);
if (pgconn == NULL)
@ -118,12 +119,12 @@ conn_connect(connectionObject *self)
PQfinish(pgconn);
IFCLEARPGRES(pgres);
return -1;
}
}
for (i=0 ; i < strlen(tmp) ; i++)
self->encoding[i] = toupper(tmp[i]);
self->encoding[i] = '\0';
CLEARPGRES(pgres);
Py_BEGIN_ALLOW_THREADS;
pgres = PQexec(pgconn, isolevel);
Py_END_ALLOW_THREADS;
@ -159,7 +160,7 @@ conn_connect(connectionObject *self)
self->protocol = 2;
#endif
Dprintf("conn_connect: using protocol %d", self->protocol);
self->pgconn = pgconn;
return 0;
}
@ -178,7 +179,7 @@ conn_close(connectionObject *self)
self->closed = 1;
/* execute a forced rollback on the connection (but don't check the
result, we're going to close the pq connection anyway */
result, we're going to close the pq connection anyway */
if (self->pgconn) {
pq_abort(self);
PQfinish(self->pgconn);
@ -203,7 +204,7 @@ conn_commit(connectionObject *self)
res = pq_commit(self);
self->mark++;
pthread_mutex_unlock(&self->lock);
Py_END_ALLOW_THREADS;
@ -222,7 +223,7 @@ conn_rollback(connectionObject *self)
res = pq_abort(self);
self->mark++;
pthread_mutex_unlock(&self->lock);
Py_END_ALLOW_THREADS;
@ -241,7 +242,7 @@ conn_switch_isolation_level(connectionObject *self, int level)
Py_BEGIN_ALLOW_THREADS;
pthread_mutex_lock(&self->lock);
/* if the current isolation level is > 0 we need to abort the current
transaction before changing; that all folks! */
if (self->isolation_level != level && self->isolation_level > 0) {
@ -249,13 +250,13 @@ conn_switch_isolation_level(connectionObject *self, int level)
}
self->isolation_level = level;
self->mark++;
Dprintf("conn_switch_isolation_level: switched to level %d", level);
pthread_mutex_unlock(&self->lock);
Py_END_ALLOW_THREADS;
return res;
return res;
}
/* conn_set_client_encoding - switch client encoding on connection */
@ -266,16 +267,16 @@ conn_set_client_encoding(connectionObject *self, char *enc)
PGresult *pgres;
char query[48];
int res = 0;
/* If the current encoding is equal to the requested one we don't
issue any query to the backend */
if (strcmp(self->encoding, enc) == 0) return 0;
/* TODO: check for async query here and raise error if necessary */
Py_BEGIN_ALLOW_THREADS;
pthread_mutex_lock(&self->lock);
/* set encoding, no encoding string is longer than 24 bytes */
PyOS_snprintf(query, 47, "SET client_encoding = '%s'", enc);
@ -297,14 +298,14 @@ conn_set_client_encoding(connectionObject *self, char *enc)
IFCLEARPGRES(pgres);
}
Dprintf("conn_set_client_encoding: set encoding to %s", self->encoding);
pthread_mutex_unlock(&self->lock);
Py_END_ALLOW_THREADS;
if (res == -1)
PyErr_Format(OperationalError, "can't set encoding to %s", enc);
return res;
return res;
}

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -52,7 +53,7 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
PyObject *obj, *factory = NULL;
static char *kwlist[] = {"name", "cursor_factory", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sO", kwlist,
&name, &factory)) {
return NULL;
@ -62,10 +63,10 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
Dprintf("psyco_conn_cursor: new cursor for connection at %p", self);
Dprintf("psyco_conn_cursor: parameters: name = %s", name);
if (factory == NULL) factory = (PyObject *)&cursorType;
if (name)
obj = PyObject_CallFunction(factory, "Os", self, name);
obj = PyObject_CallFunction(factory, "Os", self, name);
else
obj = PyObject_CallFunction(factory, "O", self);
@ -76,9 +77,11 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
Py_DECREF(obj);
return NULL;
}
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = %d",
obj, obj->ob_refcnt);
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt
);
return obj;
}
@ -93,7 +96,7 @@ psyco_conn_close(connectionObject *self, PyObject *args)
EXC_IF_CONN_CLOSED(self);
if (!PyArg_ParseTuple(args, "")) return NULL;
Dprintf("psyco_conn_close: closing connection at %p", self);
conn_close(self);
Dprintf("psyco_conn_close: connection at %p closed", self);
@ -152,7 +155,7 @@ static PyObject *
psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
{
int level = 1;
EXC_IF_CONN_CLOSED(self);
if (!PyArg_ParseTuple(args, "i", &level)) return NULL;
@ -162,7 +165,7 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
"isolation level out of bounds (0,3)");
return NULL;
}
/* FIXME: check return status? */
conn_switch_isolation_level(self, level);
@ -186,19 +189,19 @@ psyco_conn_set_client_encoding(connectionObject *self, PyObject *args)
EXC_IF_CONN_CLOSED(self);
if (!PyArg_ParseTuple(args, "s", &enc)) return NULL;
/* convert to upper case and remove '-' and '_' from string */
buffer = PyMem_Malloc(strlen(enc));
for (i=j=0 ; i < strlen(enc) ; i++) {
if (enc[i] == '_' || enc[i] == '-')
continue;
else
buffer[j++] = toupper(enc[i]);
continue;
else
buffer[j++] = toupper(enc[i]);
}
buffer[j] = '\0';
if (conn_set_client_encoding(self, buffer) == 0) {
PyMem_Free(buffer);
PyMem_Free(buffer);
Py_INCREF(Py_None);
return Py_None;
}
@ -228,8 +231,8 @@ static struct PyMethodDef connectionObject_methods[] = {
{"set_isolation_level", (PyCFunction)psyco_conn_set_isolation_level,
METH_VARARGS, psyco_conn_set_isolation_level_doc},
{"set_client_encoding", (PyCFunction)psyco_conn_set_client_encoding,
METH_VARARGS, psyco_conn_set_client_encoding_doc},
#endif
METH_VARARGS, psyco_conn_set_client_encoding_doc},
#endif
{NULL}
};
@ -237,9 +240,9 @@ static struct PyMethodDef connectionObject_methods[] = {
static struct PyMemberDef connectionObject_members[] = {
/* DBAPI-2.0 extensions (exception objects) */
{"Error", T_OBJECT,
{"Error", T_OBJECT,
offsetof(connectionObject, exc_Error), RO, Error_doc},
{"Warning",
{"Warning",
T_OBJECT, offsetof(connectionObject, exc_Warning), RO, Warning_doc},
{"InterfaceError", T_OBJECT,
offsetof(connectionObject, exc_InterfaceError), RO,
@ -262,7 +265,7 @@ static struct PyMemberDef connectionObject_members[] = {
{"NotSupportedError", T_OBJECT,
offsetof(connectionObject, exc_NotSupportedError), RO,
NotSupportedError_doc},
#ifdef PSYCOPG_EXTENSIONS
#ifdef PSYCOPG_EXTENSIONS
{"closed", T_LONG, offsetof(connectionObject, closed), RO,
"True if the connection is closed."},
{"isolation_level", T_LONG,
@ -274,14 +277,14 @@ static struct PyMemberDef connectionObject_members[] = {
{"notifies", T_OBJECT, offsetof(connectionObject, notifies), RO},
{"dsn", T_STRING, offsetof(connectionObject, dsn), RO,
"The current connection string."},
{"status", T_LONG,
{"status", T_INT,
offsetof(connectionObject, status), RO,
"The current transaction status."},
"The current transaction status."},
{"string_types", T_OBJECT, offsetof(connectionObject, string_types), RO,
"A set of typecasters to convert textual values."},
{"binary_types", T_OBJECT, offsetof(connectionObject, binary_types), RO,
"A set of typecasters to convert binary values."},
#endif
#endif
{NULL}
};
@ -293,9 +296,11 @@ connection_setup(connectionObject *self, char *dsn)
char *pos;
int res;
Dprintf("connection_setup: init connection object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("connection_setup: init connection object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
self->dsn = strdup(dsn);
self->notice_list = PyList_New(0);
self->notifies = PyList_New(0);
@ -305,21 +310,23 @@ connection_setup(connectionObject *self, char *dsn)
self->async_cursor = NULL;
self->pgconn = NULL;
self->mark = 0;
self->string_types = PyDict_New();
self->string_types = PyDict_New();
self->binary_types = PyDict_New();
pthread_mutex_init(&(self->lock), NULL);
if (conn_connect(self) != 0) {
Dprintf("connection_init: FAILED");
res = -1;
}
else {
Dprintf("connection_setup: good connection object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("connection_setup: good connection object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
res = 0;
}
/* here we obfuscate the password even if there was a connection error */
pos = strstr(self->dsn, "password");
if (pos != NULL) {
@ -336,21 +343,23 @@ connection_dealloc(PyObject* obj)
connectionObject *self = (connectionObject *)obj;
if (self->closed == 0) conn_close(self);
if (self->dsn) free(self->dsn);
if (self->encoding) PyMem_Free(self->encoding);
if (self->critical) free(self->critical);
Py_XDECREF(self->notice_list);
Py_XDECREF(self->notifies);
Py_XDECREF(self->async_cursor);
Py_XDECREF(self->string_types);
Py_XDECREF(self->binary_types);
pthread_mutex_destroy(&(self->lock));
Dprintf("connection_dealloc: deleted connection object at %p, refcnt = %d",
obj, obj->ob_refcnt);
Dprintf("connection_dealloc: deleted connection object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt
);
obj->ob_type->tp_free(obj);
}
@ -403,7 +412,7 @@ PyTypeObject connectionType = {
sizeof(connectionObject),
0,
connection_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
@ -421,7 +430,7 @@ PyTypeObject connectionType = {
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
connectionType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -438,11 +447,11 @@ PyTypeObject connectionType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
connection_init, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
connection_new, /*tp_new*/

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_CURSOR_H
#define PSYCOPG_CURSOR_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <libpq-fe.h>
@ -41,7 +42,7 @@ typedef struct {
int closed:1; /* 1 if the cursor is closed */
int notuples:1; /* 1 if the command was not a SELECT query */
int needsfetch:1; /* 1 if a call to pq_fetch is pending */
long int rowcount; /* number of rows affected by last execute */
long int columns; /* number of columns fetched from the db */
long int arraysize; /* how many rows should fetchmany() return */
@ -58,28 +59,28 @@ typedef struct {
PyObject *casts; /* an array (tuple) of typecast functions */
PyObject *caster; /* the current typecaster object */
PyObject *copyfile; /* file-like used during COPY TO/FROM ops */
long int copysize; /* size of the copy buffer during COPY TO/FROM ops */
Py_ssize_t copysize; /* size of the copy buffer during COPY TO/FROM ops */
#define DEFAULT_COPYSIZE 16384
PyObject *tuple_factory; /* factory for result tuples */
PyObject *tzinfo_factory; /* factory for tzinfo objects */
PyObject *query; /* last query executed */
char *qattr; /* quoting attr, used when quoting strings */
char *notice; /* a notice from the backend */
char *name; /* this cursor name */
PyObject *string_types; /* a set of typecasters for string types */
PyObject *binary_types; /* a set of typecasters for binary types */
} cursorObject;
/* C-callable functions in cursor_int.c and cursor_ext.c */
extern void curs_reset(cursorObject *self);
/* exception-raising macros */
#define EXC_IF_CURS_CLOSED(self) \
if ((self)->closed || ((self)->conn && (self)->conn->closed)) { \
@ -90,7 +91,7 @@ if ((self)->closed || ((self)->conn && (self)->conn->closed)) { \
if ((self)->notuples && (self)->name == NULL) { \
PyErr_SetString(ProgrammingError, "no results to fetch"); \
return NULL; }
#define EXC_IF_NO_MARK(self) \
if ((self)->mark != (self)->conn->mark) { \
PyErr_SetString(ProgrammingError, "named cursor isn't valid anymore"); \

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <string.h>

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <string.h>
@ -49,12 +50,12 @@ static PyObject *
psyco_curs_close(cursorObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "")) return NULL;
EXC_IF_CURS_CLOSED(self);
if (self->name != NULL) {
char buffer[128];
EXC_IF_NO_MARK(self);
PyOS_snprintf(buffer, 127, "CLOSE %s", self->name);
if (pq_execute(self, buffer, 0) == -1) return NULL;
@ -91,7 +92,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
if (c[0] == '%' && c[1] == '%') {
c+=2; force = 1;
}
/* if we find '%(' then this is a dictionary, we:
1/ find the matching ')' and extract the key name
2/ locate the value in the dictionary (or return an error)
@ -107,7 +108,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
key = PyString_FromStringAndSize(c+2, d-c-2);
value = PyObject_GetItem(var, key);
/* key has refcnt 1, value the original value + 1 */
/* if value is NULL we did not find the key (or this is not a
dictionary): let python raise a KeyError */
if (value == NULL) {
@ -116,12 +117,13 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
return -1;
}
Dprintf("_mogrify: value refcnt: %d (+1)", value->ob_refcnt);
Dprintf("_mogrify: value refcnt: "
FORMAT_CODE_PY_SSIZE_T " (+1)", value->ob_refcnt);
if (n == NULL) {
n = PyDict_New();
}
if ((item = PyObject_GetItem(n, key)) == NULL) {
PyObject *t = NULL;
@ -134,7 +136,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
t = PyString_FromString("NULL");
PyDict_SetItem(n, key, t);
/* t is a new object, refcnt = 1, key is at 2 */
/* if the value is None we need to substitute the
formatting char with 's' (FIXME: this should not be
necessary if we drop support for formats other than
@ -151,7 +153,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
}
else {
/* no adapter found, raise a BIG exception */
Py_XDECREF(value);
Py_XDECREF(value);
Py_DECREF(n);
return -1;
}
@ -160,26 +162,29 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
Py_XDECREF(t); /* t dies here */
/* after the DECREF value has the original refcnt plus 1
if it was added to the dictionary directly; good */
Py_XDECREF(value);
Py_XDECREF(value);
}
else {
/* we have an item with one extra refcnt here, zap! */
Py_DECREF(item);
}
Py_DECREF(key); /* key has the original refcnt now */
Dprintf("_mogrify: after value refcnt: %d",value->ob_refcnt);
Dprintf("_mogrify: after value refcnt: "
FORMAT_CODE_PY_SSIZE_T,
value->ob_refcnt
);
}
c = d;
}
else if (c[0] == '%' && c[1] != '(') {
/* this is a format that expects a tuple; it is much easier,
because we don't need to check the old/new dictionary for
keys */
value = PySequence_GetItem(var, index);
/* value has refcnt inc'ed by 1 here */
/* if value is NULL this is not a sequence or the index is wrong;
anyway we let python set its own exception */
if (value == NULL) {
@ -190,10 +195,10 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
if (n == NULL) {
n = PyTuple_New(PyObject_Length(var));
}
/* let's have d point just after the '%' */
d = c+1;
if (value == Py_None) {
PyTuple_SET_ITEM(n, index, PyString_FromString("NULL"));
while (*d && !isalpha(*d)) d++;
@ -224,10 +229,10 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
if (force && n == NULL)
n = PyTuple_New(0);
*new = n;
return 0;
}
#define psyco_curs_execute_doc \
"execute(query, vars=None, async=0) -- Execute query with bound vars."
@ -237,7 +242,7 @@ _psyco_curs_execute(cursorObject *self,
{
int res;
PyObject *fquery, *cvt = NULL, *uoperation = NULL;
pthread_mutex_lock(&(self->conn->lock));
if (self->conn->async_cursor != NULL
&& self->conn->async_cursor != (PyObject*)self) {
@ -247,18 +252,18 @@ _psyco_curs_execute(cursorObject *self,
return 0;
}
pthread_mutex_unlock(&(self->conn->lock));
if (!PyObject_IsTrue(operation)) {
psyco_set_error(ProgrammingError, (PyObject*)self,
"can't execute an empty query", NULL, NULL);
return 0;
return 0;
}
if (PyUnicode_Check(operation)) {
PyObject *enc = PyDict_GetItemString(psycoEncodings,
self->conn->encoding);
/* enc is a borrowed reference, we won't decref it */
if (enc) {
operation = PyUnicode_AsEncodedString(
operation, PyString_AsString(enc), NULL);
@ -267,7 +272,7 @@ _psyco_curs_execute(cursorObject *self,
target encoding we just let the exception propagate */
if (operation == NULL) return 0;
/* we clone operation in uoperation to be sure to free it later */
/* we clone operation in uoperation to be sure to free it later */
uoperation = operation;
}
else {
@ -282,20 +287,20 @@ _psyco_curs_execute(cursorObject *self,
"argument 1 must be a string or unicode object");
return 0;
}
IFCLEARPGRES(self->pgres);
if (self->query) {
Py_DECREF(self->query);
self->query = NULL;
}
Dprintf("psyco_curs_execute: starting execution of new query");
/* here we are, and we have a sequence or a dictionary filled with
objects to be substituted (bound variables). we try to be smart and do
the right thing (i.e., what the user expects) */
if (vars && vars != Py_None)
{
if(_mogrify(vars, operation, self->conn, &cvt) == -1) {
@ -315,13 +320,13 @@ _psyco_curs_execute(cursorObject *self,
and return the appropriate ProgrammingError. we do that by grabbing
the curren exception (we will later restore it if the type or the
strings do not match.) */
if (!(fquery = PyString_Format(operation, cvt))) {
PyObject *err, *arg, *trace;
int pe = 0;
PyErr_Fetch(&err, &arg, &trace);
if (err && PyErr_GivenExceptionMatches(err, PyExc_TypeError)) {
Dprintf("psyco_curs_execute: TypeError exception catched");
PyErr_NormalizeException(&err, &arg, &trace);
@ -356,7 +361,7 @@ _psyco_curs_execute(cursorObject *self,
Py_XDECREF(uoperation);
return 0;
}
if (self->name != NULL) {
self->query = PyString_FromFormat(
"DECLARE %s CURSOR WITHOUT HOLD FOR %s",
@ -366,8 +371,9 @@ _psyco_curs_execute(cursorObject *self,
else {
self->query = fquery;
}
Dprintf("psyco_curs_execute: cvt->refcnt = %d", cvt->ob_refcnt);
Dprintf("psyco_curs_execute: cvt->refcnt = " FORMAT_CODE_PY_SSIZE_T,
cvt->ob_refcnt);
Py_DECREF(cvt);
}
else {
@ -381,25 +387,25 @@ _psyco_curs_execute(cursorObject *self,
self->query = operation;
}
}
res = pq_execute(self, PyString_AS_STRING(self->query), async);
Dprintf("psyco_curs_execute: res = %d, pgres = %p", res, self->pgres);
Py_XDECREF(uoperation);
return res == -1 ? 0 : 1;
}
static PyObject *
psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs)
{
{
long int async = 0;
PyObject *vars = NULL, *operation = NULL;
static char *kwlist[] = {"query", "vars", "async", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi", kwlist,
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ol", kwlist,
&operation, &vars, &async)) {
return NULL;
}
@ -414,7 +420,7 @@ psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs)
if (self->conn->isolation_level == 0) {
psyco_set_error(ProgrammingError, (PyObject*)self,
"can't use a named cursor outside of transactions", NULL, NULL);
return NULL;
return NULL;
}
if (self->conn->mark != self->mark) {
psyco_set_error(ProgrammingError, (PyObject*)self,
@ -424,7 +430,7 @@ psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs)
}
EXC_IF_CURS_CLOSED(self);
if (_psyco_curs_execute(self, operation, vars, async)) {
Py_INCREF(Py_None);
return Py_None;
@ -442,7 +448,7 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
{
PyObject *operation = NULL, *vars = NULL;
PyObject *v, *iter = NULL;
static char *kwlist[] = {"query", "vars_list", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist,
@ -451,18 +457,18 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
}
EXC_IF_CURS_CLOSED(self);
if (self->name != NULL) {
psyco_set_error(ProgrammingError, (PyObject*)self,
"can't call .executemany() on named cursors", NULL, NULL);
return NULL;
}
}
if (!PyIter_Check(vars)) {
vars = iter = PyObject_GetIter(vars);
if (iter == NULL) return NULL;
}
while ((v = PyIter_Next(vars)) != NULL) {
if (_psyco_curs_execute(self, operation, v, 0) == 0) {
Py_DECREF(v);
@ -473,7 +479,7 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
}
}
Py_XDECREF(iter);
Py_INCREF(Py_None);
return Py_None;
}
@ -485,10 +491,10 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
static PyObject *
psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs)
{
{
PyObject *vars = NULL, *cvt = NULL, *operation = NULL;
PyObject *fquery;
static char *kwlist[] = {"query", "vars", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist,
@ -501,7 +507,7 @@ psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs)
"unicode queries not yet supported");
return NULL;
}
EXC_IF_CURS_CLOSED(self);
IFCLEARPGRES(self->pgres);
@ -516,13 +522,13 @@ psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs)
if(_mogrify(vars, operation, self->conn, &cvt) == -1) return NULL;
}
if (vars && cvt) {
if (vars && cvt) {
if (!(fquery = PyString_Format(operation, cvt))) {
PyObject *err, *arg, *trace;
int pe = 0;
PyErr_Fetch(&err, &arg, &trace);
if (err && PyErr_GivenExceptionMatches(err, PyExc_TypeError)) {
Dprintf("psyco_curs_execute: TypeError exception catched");
PyErr_NormalizeException(&err, &arg, &trace);
@ -557,8 +563,10 @@ psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs)
return NULL;
}
Dprintf("psyco_curs_execute: cvt->refcnt = %d, fquery->refcnt = %d",
cvt->ob_refcnt, fquery->ob_refcnt);
Dprintf("psyco_curs_execute: cvt->refcnt = " FORMAT_CODE_PY_SSIZE_T
", fquery->refcnt = " FORMAT_CODE_PY_SSIZE_T,
cvt->ob_refcnt, fquery->ob_refcnt
);
Py_DECREF(cvt);
}
else {
@ -583,7 +591,7 @@ static int
_psyco_curs_prefetch(cursorObject *self)
{
int i = 0;
/* check if the fetching cursor is the one that did the asynchronous query
and raise an exception if not */
pthread_mutex_lock(&(self->conn->lock));
@ -595,7 +603,7 @@ _psyco_curs_prefetch(cursorObject *self)
return -2;
}
pthread_mutex_unlock(&(self->conn->lock));
if (self->pgres == NULL || self->needsfetch) {
self->needsfetch = 0;
Dprintf("_psyco_curs_prefetch: trying to fetch data");
@ -616,7 +624,7 @@ _psyco_curs_buildrow_fill(cursorObject *self, PyObject *res,
int i, len;
unsigned char *str;
PyObject *val;
for (i=0; i < n; i++) {
if (PQgetisnull(self->pgres, row, i)) {
str = NULL;
@ -634,7 +642,10 @@ _psyco_curs_buildrow_fill(cursorObject *self, PyObject *res,
(PyObject*)self);
if (val) {
Dprintf("_psyco_curs_buildrow: val->refcnt = %d", val->ob_refcnt);
Dprintf("_psyco_curs_buildrow: val->refcnt = "
FORMAT_CODE_PY_SSIZE_T,
val->ob_refcnt
);
if (istuple) {
PyTuple_SET_ITEM(res, i, val);
}
@ -659,7 +670,7 @@ static PyObject *
_psyco_curs_buildrow(cursorObject *self, int row)
{
int n;
n = PQnfields(self->pgres);
return _psyco_curs_buildrow_fill(self, PyTuple_New(n), row, n, 1);
}
@ -681,24 +692,24 @@ PyObject *
psyco_curs_fetchone(cursorObject *self, PyObject *args)
{
PyObject *res;
if (args && !PyArg_ParseTuple(args, "")) return NULL;
EXC_IF_CURS_CLOSED(self)
if (_psyco_curs_prefetch(self) < 0) return NULL;
EXC_IF_NO_TUPLES(self);
if (self->name != NULL) {
char buffer[128];
EXC_IF_NO_MARK(self);
PyOS_snprintf(buffer, 127, "FETCH FORWARD 1 FROM %s", self->name);
if (pq_execute(self, buffer, 0) == -1) return NULL;
if (_psyco_curs_prefetch(self) < 0) return NULL;
}
Dprintf("psyco_curs_fetchone: fetching row %ld", self->row);
Dprintf("psyco_curs_fetchone: rowcount = %ld", self->rowcount);
Dprintf("psyco_curs_fetchone: rowcount = %ld", self->rowcount);
if (self->row >= self->rowcount) {
/* we exausted available data: return None */
@ -710,7 +721,7 @@ psyco_curs_fetchone(cursorObject *self, PyObject *args)
res = _psyco_curs_buildrow(self, self->row);
else
res = _psyco_curs_buildrow_with_factory(self, self->row);
self->row++; /* move the counter to next line */
/* if the query was async aggresively free pgres, to allow
@ -736,10 +747,10 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
{
int i;
PyObject *list, *res;
long int size = self->arraysize;
static char *kwlist[] = {"size", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwords, "|l", kwlist, &size)) {
return NULL;
}
@ -750,7 +761,7 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
if (self->name != NULL) {
char buffer[128];
EXC_IF_NO_MARK(self);
PyOS_snprintf(buffer, 127, "FETCH FORWARD %d FROM %s",
(int)size, self->name);
@ -764,19 +775,19 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
}
Dprintf("psyco_curs_fetchmany: size = %ld", size);
if (size <= 0) {
return PyList_New(0);
}
list = PyList_New(size);
for (i = 0; i < size; i++) {
if (self->tuple_factory == Py_None)
res = _psyco_curs_buildrow(self, self->row);
else
res = _psyco_curs_buildrow_with_factory(self, self->row);
self->row++;
if (res == NULL) {
@ -792,7 +803,7 @@ psyco_curs_fetchmany(cursorObject *self, PyObject *args, PyObject *kwords)
if (self->row >= self->rowcount
&& self->conn->async_cursor == (PyObject*)self)
IFCLEARPGRES(self->pgres);
return list;
}
@ -819,10 +830,10 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args)
EXC_IF_CURS_CLOSED(self);
if (_psyco_curs_prefetch(self) < 0) return NULL;
EXC_IF_NO_TUPLES(self);
if (self->name != NULL) {
char buffer[128];
EXC_IF_NO_MARK(self);
PyOS_snprintf(buffer, 127, "FETCH FORWARD ALL FROM %s", self->name);
if (pq_execute(self, buffer, 0) == -1) return NULL;
@ -830,19 +841,19 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args)
}
size = self->rowcount - self->row;
if (size <= 0) {
return PyList_New(0);
}
list = PyList_New(size);
for (i = 0; i < size; i++) {
if (self->tuple_factory == Py_None)
res = _psyco_curs_buildrow(self, self->row);
else
res = _psyco_curs_buildrow_with_factory(self, self->row);
self->row++;
if (res == NULL) {
@ -858,7 +869,7 @@ psyco_curs_fetchall(cursorObject *self, PyObject *args)
if (self->row >= self->rowcount
&& self->conn->async_cursor == (PyObject*)self)
IFCLEARPGRES(self->pgres);
return list;
}
@ -878,7 +889,7 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
PyObject *operation = NULL;
PyObject *res = NULL;
if (!PyArg_ParseTuple(args, "s|Oi", &procname, &parameters, &async)) {
if (!PyArg_ParseTuple(args, "s|Ol", &procname, &parameters, &async)) {
return NULL;
}
@ -888,28 +899,28 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
psyco_set_error(ProgrammingError, (PyObject*)self,
"can't call .callproc() on named cursors", NULL, NULL);
return NULL;
}
}
if(parameters && parameters != Py_None) {
nparameters = PyObject_Length(parameters);
if (nparameters < 0) nparameters = 0;
if (nparameters < 0) nparameters = 0;
}
/* allocate some memory, build the SQL and create a PyString from it */
sl = strlen(procname) + 17 + nparameters*3 - (nparameters ? 1 : 0);
sql = (char*)PyMem_Malloc(sl);
if (sql == NULL) return NULL;
sprintf(sql, "SELECT * FROM %s(", procname);
for(i=0; i<nparameters; i++) {
strcat(sql, "%s,");
}
sql[sl-2] = ')';
sql[sl-1] = '\0';
operation = PyString_FromString(sql);
PyMem_Free((void*)sql);
if (_psyco_curs_execute(self, operation, parameters, async)) {
Py_INCREF(Py_None);
res = Py_None;
@ -931,7 +942,7 @@ static PyObject *
psyco_curs_nextset(cursorObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "")) return NULL;
EXC_IF_CURS_CLOSED(self);
PyErr_SetString(NotSupportedError, "not supported by PostgreSQL");
@ -949,10 +960,10 @@ static PyObject *
psyco_curs_setinputsizes(cursorObject *self, PyObject *args)
{
PyObject *sizes;
if (!PyArg_ParseTuple(args, "O", &sizes))
return NULL;
EXC_IF_CURS_CLOSED(self);
Py_INCREF(Py_None);
@ -970,10 +981,10 @@ static PyObject *
psyco_curs_setoutputsize(cursorObject *self, PyObject *args)
{
long int size, column;
if (!PyArg_ParseTuple(args, "l|l", &size, &column))
return NULL;
EXC_IF_CURS_CLOSED(self);
Py_INCREF(Py_None);
@ -984,7 +995,7 @@ psyco_curs_setoutputsize(cursorObject *self, PyObject *args)
/* scroll - scroll position in result list */
#define psyco_curs_scroll_doc \
"scroll(value, mode='relative') -- Scroll to new position according to mode."
"scroll(value, mode='relative') -- Scroll to new position according to mode."
static PyObject *
psyco_curs_scroll(cursorObject *self, PyObject *args, PyObject *kwargs)
@ -997,7 +1008,7 @@ psyco_curs_scroll(cursorObject *self, PyObject *args, PyObject *kwargs)
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|s",
kwlist, &value, &mode))
return NULL;
EXC_IF_CURS_CLOSED(self);
/* if the cursor is not named we have the full result set and we can do
@ -1013,21 +1024,21 @@ psyco_curs_scroll(cursorObject *self, PyObject *args, PyObject *kwargs)
"scroll mode must be 'relative' or 'absolute'", NULL, NULL);
return NULL;
}
if (newpos < 0 || newpos >= self->rowcount ) {
psyco_set_error(ProgrammingError, (PyObject*)self,
"scroll destination out of bounds", NULL, NULL);
return NULL;
}
self->row = newpos;
}
else {
char buffer[128];
EXC_IF_NO_MARK(self);
if (strcmp(mode, "absolute") == 0) {
PyOS_snprintf(buffer, 127, "MOVE ABSOLUTE %d FROM %s",
value, self->name);
@ -1064,7 +1075,7 @@ _psyco_curs_has_read_check(PyObject* o, void* var)
PyErr_SetString(PyExc_TypeError,
"argument 1 must have both .read() and .readline() methods");
return 0;
}
}
}
static PyObject *
@ -1073,20 +1084,22 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
char query[1024];
char *table_name;
char *sep = "\t", *null = NULL;
long int bufsize = DEFAULT_COPYSIZE;
Py_ssize_t bufsize = DEFAULT_COPYSIZE;
PyObject *file, *columns = NULL, *res = NULL;
char columnlist[1024] = "";
static char *kwlist[] = {"file", "table", "sep", "null", "size",
static char *kwlist[] = {"file", "table", "sep", "null", "size",
"columns", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s|ssiO", kwlist,
_psyco_curs_has_read_check, &file,
&table_name, &sep, &null, &bufsize,
&columns)) {
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"O&s|ss" CONV_CODE_PY_SSIZE_T "O", kwlist,
_psyco_curs_has_read_check, &file, &table_name, &sep, &null, &bufsize,
&columns)
)
{
return NULL;
}
if (columns != NULL && columns != Py_None) {
PyObject* collistiter = PyObject_GetIter(columns);
PyObject* col;
@ -1102,7 +1115,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
Py_DECREF(col);
Py_DECREF(collistiter);
PyErr_SetString(PyExc_ValueError,
"Elements in column list must be strings");
"Elements in column list must be strings");
return NULL;
}
PyString_AsStringAndSize(col, &colname, &colitemlen);
@ -1152,7 +1165,7 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
}
self->copyfile =NULL;
return res;
}
@ -1171,7 +1184,7 @@ _psyco_curs_has_write_check(PyObject* o, void* var)
PyErr_SetString(PyExc_TypeError,
"argument 1 must have a .write() method");
return 0;
}
}
}
static PyObject *
@ -1189,7 +1202,7 @@ psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
&table_name, &sep, &null)) {
return NULL;
}
EXC_IF_CURS_CLOSED(self);
if (null) {
@ -1206,13 +1219,13 @@ psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
if (pq_execute(self, query, 0) == 1) {
res = Py_None;
Py_INCREF(Py_None);
Py_INCREF(Py_None);
}
self->copyfile = NULL;
return res;
}
}
/* extension: fileno - return the file descripor of the connection */
#define psyco_curs_fileno_doc \
@ -1222,7 +1235,7 @@ static PyObject *
psyco_curs_fileno(cursorObject *self, PyObject *args)
{
long int socket;
if (!PyArg_ParseTuple(args, "")) return NULL;
EXC_IF_CURS_CLOSED(self);
@ -1252,7 +1265,7 @@ psyco_curs_isready(cursorObject *self, PyObject *args)
/* pq_is_busy does its own locking, we don't need anything special but if
the cursor is ready we need to fetch the result and free the connection
for the next query. */
if (pq_is_busy(self->conn)) {
Py_INCREF(Py_False);
return Py_False;
@ -1351,7 +1364,7 @@ static struct PyMemberDef cursorObject_members[] = {
/* DBAPI-2.0 basics */
{"rowcount", T_LONG, OFFSETOF(rowcount), RO,
"Number of rows read from the backend in the last command."},
{"arraysize", T_LONG, OFFSETOF(arraysize), 0,
{"arraysize", T_LONG, OFFSETOF(arraysize), 0,
"Number of records `fetchmany()` must fetch if not explicitely " \
"specified."},
{"description", T_OBJECT, OFFSETOF(description), RO,
@ -1361,7 +1374,7 @@ static struct PyMemberDef cursorObject_members[] = {
/* DBAPI-2.0 extensions */
{"rownumber", T_LONG, OFFSETOF(row), RO,
"The current row position."},
{"connection", T_OBJECT, OFFSETOF(conn), RO,
{"connection", T_OBJECT, OFFSETOF(conn), RO,
"The connection where the cursor comes from."},
#ifdef PSYCOPG_EXTENSIONS
{"name", T_STRING, OFFSETOF(name), RO},
@ -1385,7 +1398,7 @@ cursor_setup(cursorObject *self, connectionObject *conn, char *name)
{
Dprintf("cursor_setup: init cursor object at %p", self);
Dprintf("cursor_setup: parameters: name = %s, conn = %p", name, conn);
if (name) {
self->name = PyMem_Malloc(strlen(name)+1);
if (self->name == NULL) return 1;
@ -1401,21 +1414,21 @@ cursor_setup(cursorObject *self, connectionObject *conn, char *name)
} */
self->conn = conn;
Py_INCREF((PyObject*)self->conn);
self->closed = 0;
self->mark = conn->mark;
self->pgres = NULL;
self->pgres = NULL;
self->notuples = 1;
self->arraysize = 1;
self->rowcount = -1;
self->lastoid = InvalidOid;
self->casts = NULL;
self->notice = NULL;
self->string_types = NULL;
self->binary_types = NULL;
self->description = Py_None;
Py_INCREF(Py_None);
self->pgstatus = Py_None;
@ -1424,13 +1437,15 @@ cursor_setup(cursorObject *self, connectionObject *conn, char *name)
Py_INCREF(Py_None);
self->query = Py_None;
Py_INCREF(Py_None);
/* default tzinfo factory */
self->tzinfo_factory = pyPsycopgTzFixedOffsetTimezone;
Py_INCREF(self->tzinfo_factory);
Dprintf("cursor_setup: good cursor object at %p, refcnt = %d",
self, ((PyObject *)self)->ob_refcnt);
Dprintf("cursor_setup: good cursor object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
self, ((PyObject *)self)->ob_refcnt
);
return 0;
}
@ -1440,7 +1455,7 @@ cursor_dealloc(PyObject* obj)
cursorObject *self = (cursorObject *)obj;
if (self->name) PyMem_Free(self->name);
Py_XDECREF((PyObject*)self->conn);
Py_XDECREF(self->casts);
Py_XDECREF(self->description);
@ -1450,11 +1465,13 @@ cursor_dealloc(PyObject* obj)
Py_XDECREF(self->query);
Py_XDECREF(self->string_types);
Py_XDECREF(self->binary_types);
IFCLEARPGRES(self->pgres);
Dprintf("cursor_dealloc: deleted cursor object at %p, refcnt = %d",
obj, obj->ob_refcnt);
Dprintf("cursor_dealloc: deleted cursor object at %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt
);
obj->ob_type->tp_free(obj);
}
@ -1464,7 +1481,7 @@ cursor_init(PyObject *obj, PyObject *args, PyObject *kwds)
{
char *name = NULL;
PyObject *conn;
if (!PyArg_ParseTuple(args, "O|s", &conn, &name))
return -1;
@ -1503,7 +1520,7 @@ PyTypeObject cursorType = {
sizeof(cursorObject),
0,
cursor_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
@ -1521,7 +1538,7 @@ PyTypeObject cursorType = {
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
cursorType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -1538,11 +1555,11 @@ PyTypeObject cursorType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
cursor_init, /*tp_init*/
0, /*tp_alloc Will be set to PyType_GenericAlloc in module init*/
cursor_new, /*tp_new*/

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
@ -44,10 +45,10 @@ microprotocols_init(PyObject *dict)
/* create adapters dictionary and put it in module namespace */
if ((psyco_adapters = PyDict_New()) == NULL) {
return -1;
}
}
PyDict_SetItemString(dict, "adapters", psyco_adapters);
return 0;
}
@ -79,7 +80,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
quotable object to be its instance */
Dprintf("microprotocols_adapt: trying to adapt %s", obj->ob_type->tp_name);
/* look for an adapter in the registry */
key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
adapter = PyDict_GetItem(psyco_adapters, key);
@ -98,7 +99,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
return NULL;
}
/* and finally try to have the object adapt itself */
/* and finally try to have the object adapt itself */
if (PyObject_HasAttrString(obj, "__conform__")) {
PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto);
if (adapted && adapted != Py_None) return adapted;
@ -106,7 +107,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
return NULL;
}
/* else set the right exception and return NULL */
psyco_set_error(ProgrammingError, NULL, "can't adapt", NULL, NULL);
return NULL;
@ -120,7 +121,7 @@ microprotocol_getquoted(PyObject *obj, connectionObject *conn)
PyObject *res = NULL;
PyObject *tmp = microprotocols_adapt(
obj, (PyObject*)&isqlquoteType, NULL);
if (tmp != NULL) {
Dprintf("microprotocol_getquoted: adapted to %s",
tmp->ob_type->tp_name);

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_MICROPROTOCOLS_H
#define PSYCOPG_MICROPROTOCOLS_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "psycopg/connection.h"
#include "psycopg/cursor.h"
@ -46,15 +47,15 @@ extern PyObject *psyco_adapters;
extern int microprotocols_init(PyObject *dict);
extern int microprotocols_add(
PyTypeObject *type, PyObject *proto, PyObject *cast);
extern PyObject *microprotocols_adapt(
PyObject *obj, PyObject *proto, PyObject *alt);
extern PyObject *microprotocol_getquoted(
PyObject *obj, connectionObject *conn);
extern PyObject *
psyco_microprotocols_adapt(cursorObject *self, PyObject *args);
psyco_microprotocols_adapt(cursorObject *self, PyObject *args);
#define psyco_microprotocols_adapt_doc \
"adapt(obj, protocol, alternate) -> object -- adapt obj to given protocol"
#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <stringobject.h>
@ -44,7 +45,7 @@ static PyObject *
psyco_isqlquote_getquoted(isqlquoteObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "")) return NULL;
Py_INCREF(Py_None);
return Py_None;
}
@ -58,7 +59,7 @@ static PyObject *
psyco_isqlquote_getbinary(isqlquoteObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "")) return NULL;
Py_INCREF(Py_None);
return Py_None;
}
@ -72,7 +73,7 @@ static PyObject *
psyco_isqlquote_getbuffer(isqlquoteObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "")) return NULL;
Py_INCREF(Py_None);
return Py_None;
}
@ -119,9 +120,9 @@ static void
isqlquote_dealloc(PyObject* obj)
{
isqlquoteObject *self = (isqlquoteObject *)obj;
Py_XDECREF(self->wrapped);
obj->ob_type->tp_free(obj);
}
@ -163,7 +164,7 @@ PyTypeObject isqlquoteType = {
sizeof(isqlquoteObject),
0,
isqlquote_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
@ -181,7 +182,7 @@ PyTypeObject isqlquoteType = {
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
isqlquoteType_doc, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -198,11 +199,11 @@ PyTypeObject isqlquoteType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
isqlquote_init, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
isqlquote_new, /*tp_new*/

View File

@ -22,22 +22,23 @@
#ifndef PSYCOPG_ISQLQUOTE_H
#define PSYCOPG_ISQLQUOTE_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <libpq-fe.h>
#ifdef __cplusplus
extern "C" {
#endif
extern PyTypeObject isqlquoteType;
typedef struct {
PyObject_HEAD
PyObject *wrapped;
} isqlquoteObject;
#ifdef __cplusplus
}
#endif

View File

@ -25,6 +25,7 @@
connection.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <string.h>
@ -47,17 +48,17 @@ void
pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
{
PyObject *pgc = (PyObject*)curs;
char *err = NULL;
char *err2 = NULL;
char *code = NULL;
char *buf = NULL;
if ((conn == NULL && curs == NULL) || (curs != NULL && conn == NULL)) {
PyErr_SetString(Error, "psycopg went psycotic and raised a null error");
return;
}
if (curs && curs->pgres) {
err = PQresultErrorMessage(curs->pgres);
#ifdef HAVE_PQPROTOCOL3
@ -76,7 +77,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
PyErr_SetString(Error, "psycopg went psycotic without error set");
return;
}
/* if exc is NULL, analyze the message and try to deduce the right
exception kind (only if we have a pgres, obviously) */
if (exc == NULL) {
@ -93,7 +94,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
}
}
}
/* if exc is still NULL psycopg was not built with HAVE_PQPROTOCOL3 or the
connection is using protocol 2: in both cases we default to comparing
error messages */
@ -105,7 +106,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
else
exc = ProgrammingError;
}
/* try to remove the initial "ERROR: " part from the postgresql error */
if (err && strlen(err) > 8) err2 = &(err[8]);
else err2 = err;
@ -126,9 +127,9 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
}
}
else {
psyco_set_error(exc, pgc, err2, err, code);
psyco_set_error(exc, pgc, err2, err, code);
}
if (buf != NULL) PyMem_Free(buf);
}
@ -144,7 +145,7 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
void
pq_set_critical(connectionObject *conn, const char *msg)
{
if (msg == NULL)
if (msg == NULL)
msg = PQerrorMessage(conn->pgconn);
if (conn->critical) free(conn->critical);
if (msg && msg[0] != '\0') conn->critical = strdup(msg);
@ -155,7 +156,7 @@ PyObject *
pq_resolve_critical(connectionObject *conn, int close)
{
Dprintf("pq_resolve_critical: resolving %s", conn->critical);
if (conn->critical) {
char *msg = &(conn->critical[6]);
Dprintf("pq_resolve_critical: error = %s", msg);
@ -163,7 +164,7 @@ pq_resolve_critical(connectionObject *conn, int close)
from the connection, so we just raise an OperationalError with the
critical message */
PyErr_SetString(OperationalError, msg);
/* we don't want to destroy this connection but just close it */
if (close == 1) conn_close(conn);
}
@ -175,7 +176,7 @@ pq_resolve_critical(connectionObject *conn, int close)
note that this function does block because it needs to wait for the full
result sets of the previous query to clear them.
this function does not call any Py_*_ALLOW_THREADS macros */
void
@ -201,7 +202,7 @@ pq_begin(connectionObject *conn)
NULL,
"BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED",
"BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"};
int pgstatus, retvalue = -1;
PGresult *pgres = NULL;
@ -324,7 +325,7 @@ pq_abort(connectionObject *conn)
}
/* pq_is_busy - consume input and return connection status
a status of 1 means that a call to pq_fetch will block, while a status of 0
means that there is data available to be collected. -1 means an error, the
exception will be set accordingly.
@ -336,7 +337,7 @@ int
pq_is_busy(connectionObject *conn)
{
PGnotify *pgn;
Dprintf("pq_is_busy: consuming input");
Py_BEGIN_ALLOW_THREADS;
@ -352,13 +353,13 @@ pq_is_busy(connectionObject *conn)
pthread_mutex_unlock(&(conn->lock));
Py_END_ALLOW_THREADS;
/* now check for notifies */
while ((pgn = PQnotifies(conn->pgconn)) != NULL) {
PyObject *notify;
Dprintf("curs_is_busy: got NOTIFY from pid %d, msg = %s",
pgn->be_pid, pgn->relname);
(int) pgn->be_pid, pgn->relname);
notify = PyTuple_New(2);
PyTuple_SET_ITEM(notify, 0, PyInt_FromLong((long)pgn->be_pid));
@ -366,7 +367,7 @@ pq_is_busy(connectionObject *conn)
PyList_Append(conn->notifies, notify);
free(pgn);
}
return PQisBusy(conn->pgconn);
}
@ -410,10 +411,10 @@ pq_execute(cursorObject *curs, const char *query, int async)
not what should we do? just block and discard data or execute
another query? */
pq_clear_async(curs->conn);
Dprintf("pq_execute: executing ASYNC query:");
Dprintf(" %-.200s", query);
/* then we can go on and send a new query without fear */
IFCLEARPGRES(curs->pgres);
if (PQsendQuery(curs->conn->pgconn, query) == 0) {
@ -425,10 +426,10 @@ pq_execute(cursorObject *curs, const char *query, int async)
}
Dprintf("pq_execute: async query sent to backend");
}
pthread_mutex_unlock(&(curs->conn->lock));
Py_END_ALLOW_THREADS;
/* if the execute was sync, we call pq_fetch() immediately,
to respect the old DBAPI-2.0 compatible behaviour */
if (async == 0) {
@ -438,7 +439,7 @@ pq_execute(cursorObject *curs, const char *query, int async)
else {
curs->conn->async_cursor = (PyObject*)curs;
}
return 1-async;
}
@ -470,7 +471,7 @@ _pq_fetch_tuples(cursorObject *curs)
curs->description = PyTuple_New(pgnfields);
curs->casts = PyTuple_New(pgnfields);
curs->columns = pgnfields;
/* calculate the display size for each column (cpu intensive, can be
switched off at configuration time) */
#ifdef PSYCOPG_DISPLAY_SIZE
@ -494,13 +495,13 @@ _pq_fetch_tuples(cursorObject *curs)
Oid ftype = PQftype(curs->pgres, i);
int fsize = PQfsize(curs->pgres, i);
int fmod = PQfmod(curs->pgres, i);
PyObject *dtitem = PyTuple_New(7);
PyObject *type = PyInt_FromLong(ftype);
PyObject *cast = NULL;
PyTuple_SET_ITEM(curs->description, i, dtitem);
/* fill the right cast function by accessing three different dictionaries:
- the per-cursor dictionary, if available (can be NULL or None)
- the per-connection dictionary (always exists but can be null)
@ -521,7 +522,7 @@ _pq_fetch_tuples(cursorObject *curs)
Dprintf("_pq_fetch_tuples: global dict: %p", cast);
}
if (cast == NULL) cast = psyco_default_cast;
/* else if we got binary tuples and if we got a field that
is binary use the default cast
FIXME: what the hell am I trying to do here? This just can't work..
@ -538,7 +539,7 @@ _pq_fetch_tuples(cursorObject *curs)
PQftype(curs->pgres,i));
Py_INCREF(cast);
PyTuple_SET_ITEM(curs->casts, i, cast);
/* 1/ fill the other fields */
PyTuple_SET_ITEM(dtitem, 0,
PyString_FromString(PQfname(curs->pgres, i)));
@ -584,7 +585,7 @@ _pq_fetch_tuples(cursorObject *curs)
Py_INCREF(Py_None);
PyTuple_SET_ITEM(dtitem, 6, Py_None);
}
if (dsize) PyMem_Free(dsize);
}
@ -598,14 +599,16 @@ _pq_copy_in_v3(cursorObject *curs)
PyObject *o;
Py_ssize_t length = 0;
int error = 0;
while (1) {
o = PyObject_CallMethod(curs->copyfile, "read", "i", curs->copysize);
o = PyObject_CallMethod(curs->copyfile, "read",
CONV_CODE_PY_SSIZE_T, curs->copysize
);
if (!o || !PyString_Check(o) || (length = PyString_Size(o)) == -1) {
error = 1;
}
if (length == 0 || error == 1) break;
Py_BEGIN_ALLOW_THREADS;
if (PQputCopyData(curs->conn->pgconn,
PyString_AS_STRING(o), length) == -1) {
@ -614,12 +617,12 @@ _pq_copy_in_v3(cursorObject *curs)
Py_END_ALLOW_THREADS;
if (error == 2) break;
Py_DECREF(o);
}
Py_XDECREF(o);
Dprintf("_pq_copy_in_v3: error = %d", error);
if (error == 0 || error == 2)
@ -682,13 +685,13 @@ _pq_copy_out_v3(cursorObject *curs)
PyObject *tmp = NULL;
char *buffer;
int len;
Py_ssize_t len;
while (1) {
Py_BEGIN_ALLOW_THREADS;
len = PQgetCopyData(curs->conn->pgconn, &buffer, 0);
Py_END_ALLOW_THREADS;
if (len > 0 && buffer) {
tmp = PyObject_CallMethod(curs->copyfile,
"write", "s#", buffer, len);
@ -703,7 +706,7 @@ _pq_copy_out_v3(cursorObject *curs)
postgresql authors :/) */
else if (len <= 0) break;
}
if (len == -2) {
pq_raise(curs->conn, NULL, NULL, NULL);
return -1;
@ -726,8 +729,9 @@ _pq_copy_out(cursorObject *curs)
PyObject *tmp = NULL;
char buffer[4096];
int status, len, ll=0;
int status, ll=0;
Py_ssize_t len;
while (1) {
Py_BEGIN_ALLOW_THREADS;
status = PQgetline(curs->conn->pgconn, buffer, 4096);
@ -735,7 +739,7 @@ _pq_copy_out(cursorObject *curs)
if (status == 0) {
if (!ll && buffer[0] == '\\' && buffer[1] == '.') break;
len = strlen(buffer);
len = (Py_ssize_t) strlen(buffer);
buffer[len++] = '\n';
ll = 0;
}
@ -746,7 +750,7 @@ _pq_copy_out(cursorObject *curs)
else {
return -1;
}
tmp = PyObject_CallMethod(curs->copyfile, "write", "s#", buffer, len);
if (tmp == NULL)
return -1;
@ -757,7 +761,7 @@ _pq_copy_out(cursorObject *curs)
status = 1;
if (PQendcopy(curs->conn->pgconn) != 0)
status = -1;
/* if for some reason we're using a protocol 3 libpq to connect to a
protocol 2 backend we still need to cycle on the result set */
IFCLEARPGRES(curs->pgres);
@ -777,14 +781,14 @@ pq_fetch(cursorObject *curs)
/* even if we fail, we remove any information about the previous query */
curs_reset(curs);
/* we check the result from the previous execute; if the result is not
already there, we need to consume some input and go to sleep until we
get something edible to eat */
if (!curs->pgres) {
Dprintf("pq_fetch: no data: entering polling loop");
while (pq_is_busy(curs->conn) > 0) {
fd_set rfds;
struct timeval tv;
@ -830,9 +834,9 @@ pq_fetch(cursorObject *curs)
}
}
*/
if (curs->pgres == NULL) return 0;
pgstatus = PQresultStatus(curs->pgres);
Dprintf("pq_fetch: pgstatus = %s", PQresStatus(pgstatus));
@ -863,11 +867,11 @@ pq_fetch(cursorObject *curs)
if (PyErr_Occurred()) ex = -1;
IFCLEARPGRES(curs->pgres);
break;
case PGRES_COPY_IN:
Dprintf("pq_fetch: data from a COPY FROM (no tuples)");
#ifdef HAVE_PQPROTOCOL3
if (curs->conn->protocol == 3)
if (curs->conn->protocol == 3)
ex = _pq_copy_in_v3(curs);
else
#endif
@ -877,14 +881,14 @@ pq_fetch(cursorObject *curs)
if (PyErr_Occurred()) ex = -1;
IFCLEARPGRES(curs->pgres);
break;
case PGRES_TUPLES_OK:
Dprintf("pq_fetch: data from a SELECT (got tuples)");
curs->rowcount = PQntuples(curs->pgres);
_pq_fetch_tuples(curs); ex = 0;
/* don't clear curs->pgres, because it contains the results! */
break;
default:
Dprintf("pq_fetch: uh-oh, something FAILED");
pq_raise(curs->conn, curs, NULL, NULL);
@ -894,7 +898,7 @@ pq_fetch(cursorObject *curs)
}
Dprintf("pq_fetch: fetching done; check for critical errors");
/* error checking, close the connection if necessary (some critical errors
are not really critical, like a COPY FROM error: if that's the case we
raise the exception but we avoid to close the connection) */
@ -907,6 +911,6 @@ pq_fetch(cursorObject *curs)
}
return -1;
}
return ex;
}

View File

@ -1,4 +1,4 @@
/* psycopg.h - definitions for the psycopg python module
/* psycopg.h - definitions for the psycopg python module
*
* Copyright (C) 2003 Federico Di Gregorio <fog@debian.org>
*
@ -22,35 +22,60 @@
#ifndef PSYCOPG_H
#define PSYCOPG_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Python 2.5 ssize_t compatibility */
#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
typedef int Py_ssize_t;
#define PY_SSIZE_T_MAX INT_MAX
#define PY_SSIZE_T_MIN INT_MIN
/* Python 2.5+ Py_ssize_t compatibility: */
#ifndef PY_FORMAT_SIZE_T
#define PY_FORMAT_SIZE_T ""
#endif
/* FORMAT_CODE_SIZE_T is for plain size_t, not for Py_ssize_t: */
#ifdef _MSC_VER
/* For MSVC: */
#define FORMAT_CODE_SIZE_T "%Iu"
#else
/* C99 standard format code: */
#define FORMAT_CODE_SIZE_T "%zu"
#endif
/* FORMAT_CODE_PY_SSIZE_T is for Py_ssize_t: */
#define FORMAT_CODE_PY_SSIZE_T "%" PY_FORMAT_SIZE_T "d"
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 5
#define CONV_CODE_PY_SSIZE_T "n"
#else
#define CONV_CODE_PY_SSIZE_T "d"
typedef int Py_ssize_t;
#define PY_SSIZE_T_MIN INT_MIN
#define PY_SSIZE_T_MAX INT_MAX
#define readbufferproc getreadbufferproc
#define writebufferproc getwritebufferproc
#define segcountproc getsegcountproc
#define charbufferproc getcharbufferproc
#endif
/* DBAPI compliance parameters */
#define APILEVEL "2.0"
#define THREADSAFETY 2
#define PARAMSTYLE "pyformat"
/* C API functions */
#define psyco_errors_fill_NUM 0
#define psyco_errors_fill_RETURN void
#define psyco_errors_fill_PROTO (PyObject *dict)
#define psyco_errors_fill_PROTO (PyObject *dict)
#define psyco_errors_set_NUM 1
#define psyco_errors_set_RETURN void
#define psyco_errors_set_PROTO (PyObject *type)
/* Total number of C API pointers */
#define PSYCOPG_API_pointers 2
#ifdef PSYCOPG_MODULE
/** This section is used when compiling psycopgmodule.c & co. **/
extern psyco_errors_fill_RETURN psyco_errors_fill psyco_errors_fill_PROTO;
@ -65,7 +90,7 @@ extern PyObject *Error, *Warning, *InterfaceError, *DatabaseError,
#ifndef PyMODINIT_FUNC
#define PyMODINIT_FUNC void
#endif
#else
/** This section is used in modules that use psycopg's C API **/
@ -77,7 +102,7 @@ static void **PSYCOPG_API;
#define psyco_errors_set \
(*(psyco_errors_set_RETURN (*)psyco_errors_set_PROTO) \
PSYCOPG_API[psyco_errors_set_NUM])
/* Return -1 and set exception on error, 0 on success. */
static int
import_psycopg(void)
@ -98,19 +123,19 @@ import_psycopg(void)
/* postgresql<->python encoding map */
extern PyObject *psycoEncodings;
typedef struct {
char *pgenc;
char *pyenc;
} encodingPair;
/* the Decimal type, used by the DECIMAL typecaster */
/* the Decimal type, used by the DECIMAL typecaster */
extern PyObject *decimalType;
/* some utility functions */
extern void psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
extern void psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
char *pgerror, char *pgcode);
/* Exceptions docstrings */
#define Error_doc \
"Base class for error exceptions."

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#define PSYCOPG_MODULE
@ -127,16 +128,16 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
{
PyObject *conn, *factory = NULL;
PyObject *pyport = NULL;
int idsn=-1, iport=-1;
char *dsn=NULL, *database=NULL, *user=NULL, *password=NULL;
char *host=NULL, *sslmode=NULL;
char port[16];
static char *kwlist[] = {"dsn", "database", "host", "port",
"user", "password", "sslmode",
"connection_factory", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssOsssO", kwlist,
&dsn, &database, &host, &pyport,
&user, &password, &sslmode, &factory)) {
@ -144,16 +145,16 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
}
if (pyport && PyString_Check(pyport)) {
PyObject *pyint = PyInt_FromString(PyString_AsString(pyport), NULL, 10);
if (!pyint) return NULL;
iport = PyInt_AsLong(pyint);
PyObject *pyint = PyInt_FromString(PyString_AsString(pyport), NULL, 10);
if (!pyint) return NULL;
iport = PyInt_AsLong(pyint);
}
else if (pyport && PyInt_Check(pyport)) {
iport = PyInt_AsLong(pyport);
iport = PyInt_AsLong(pyport);
}
else if (pyport != NULL) {
PyErr_SetString(PyExc_TypeError, "port must be a string or int");
return NULL;
PyErr_SetString(PyExc_TypeError, "port must be a string or int");
return NULL;
}
if (iport > 0)
@ -168,7 +169,7 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
if (user) l += strlen(user);
if (password) l += strlen(password);
if (sslmode) l += strlen(sslmode);
dsn = malloc(l*sizeof(char));
if (dsn == NULL) {
PyErr_SetString(InterfaceError, "dynamic dsn allocation failed");
@ -188,7 +189,7 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
idsn = _psyco_connect_fill_dsn(dsn, " password=", password, idsn);
if (sslmode)
idsn = _psyco_connect_fill_dsn(dsn, " sslmode=", sslmode, idsn);
if (idsn > 0) {
dsn[idsn] = '\0';
memmove(dsn, &dsn[1], idsn);
@ -206,7 +207,7 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
if (factory == NULL) factory = (PyObject *)&connectionType;
conn = PyObject_CallFunction(factory, "s", dsn);
if (conn) _psyco_connect_fill_exc((connectionObject*)conn);
return conn;
}
@ -239,7 +240,7 @@ _psyco_register_type_set(PyObject **dict, PyObject *type)
static PyObject *
psyco_register_type(PyObject *self, PyObject *args)
{
PyObject *type, *obj;
PyObject *type, *obj = NULL;
if (!PyArg_ParseTuple(args, "O!|O", &typecastType, &type, &obj)) {
return NULL;
@ -273,16 +274,16 @@ static void
psyco_adapters_init(PyObject *mod)
{
PyObject *call;
microprotocols_add(&PyFloat_Type, NULL, (PyObject*)&asisType);
microprotocols_add(&PyInt_Type, NULL, (PyObject*)&asisType);
microprotocols_add(&PyLong_Type, NULL, (PyObject*)&asisType);
microprotocols_add(&PyString_Type, NULL, (PyObject*)&qstringType);
microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType);
microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType);
microprotocols_add(&PyList_Type, NULL, (PyObject*)&listType);
#ifdef HAVE_MXDATETIME
/* the module has already been initialized, so we can obtain the callable
objects directly from its dictionary :) */
@ -303,7 +304,7 @@ psyco_adapters_init(PyObject *mod)
call = PyMapping_GetItemString(mod, "IntervalFromPy");
microprotocols_add((PyTypeObject*)pyDeltaTypeP, NULL, call);
#endif
#ifdef HAVE_PYBOOL
microprotocols_add(&PyBool_Type, NULL, (PyObject*)&pbooleanType);
#endif
@ -314,19 +315,19 @@ psyco_adapters_init(PyObject *mod)
}
/* psyco_encodings_fill
Fill the module's postgresql<->python encoding table */
static encodingPair encodings[] = {
{"SQL_ASCII", "ascii"},
{"LATIN1", "iso8859_1"},
{"LATIN2", "iso8859_2"},
{"LATIN3", "iso8859_3"},
{"LATIN4", "iso8859_4"},
{"LATIN5", "iso8859_9"},
{"LATIN6", "iso8859_10"},
{"LATIN7", "iso8859_13"},
{"LATIN8", "iso8859_14"},
{"LATIN2", "iso8859_2"},
{"LATIN3", "iso8859_3"},
{"LATIN4", "iso8859_4"},
{"LATIN5", "iso8859_9"},
{"LATIN6", "iso8859_10"},
{"LATIN7", "iso8859_13"},
{"LATIN8", "iso8859_14"},
{"LATIN9", "iso8859_15"},
{"ISO88591", "iso8859_1"},
{"ISO88592", "iso8859_2"},
@ -359,7 +360,7 @@ static encodingPair encodings[] = {
{"ShiftJIS", "cp932"},
{"WIN932", "cp932"},
{"Windows932", "cp932"},
{"UHC", "cp949"},
{"UHC", "cp949"},
{"WIN949", "cp949"},
{"Windows949", "cp949"},
{"WIN866", "cp866"},
@ -385,7 +386,7 @@ static encodingPair encodings[] = {
/* {"EUC_TW", "?"}, */
/* {"LATIN10", "?"}, */
/* {"ISO885916", "?"}, */
/* {"MULE_INTERNAL", "?"}, */
/* {"MULE_INTERNAL", "?"}, */
{NULL, NULL}
};
@ -421,14 +422,14 @@ static struct {
{ "psycopg2.InterfaceError", &InterfaceError, &Error, InterfaceError_doc },
{ "psycopg2.DatabaseError", &DatabaseError, &Error, DatabaseError_doc },
{ "psycopg2.InternalError", &InternalError, &DatabaseError, InternalError_doc },
{ "psycopg2.OperationalError", &OperationalError, &DatabaseError,
{ "psycopg2.OperationalError", &OperationalError, &DatabaseError,
OperationalError_doc },
{ "psycopg2.ProgrammingError", &ProgrammingError, &DatabaseError,
{ "psycopg2.ProgrammingError", &ProgrammingError, &DatabaseError,
ProgrammingError_doc },
{ "psycopg2.IntegrityError", &IntegrityError, &DatabaseError,
{ "psycopg2.IntegrityError", &IntegrityError, &DatabaseError,
IntegrityError_doc },
{ "psycopg2.DataError", &DataError, &DatabaseError, DataError_doc },
{ "psycopg2.NotSupportedError", &NotSupportedError, &DatabaseError,
{ "psycopg2.NotSupportedError", &NotSupportedError, &DatabaseError,
NotSupportedError_doc },
{NULL} /* Sentinel */
};
@ -439,7 +440,7 @@ psyco_errors_init(void)
/* the names of the exceptions here reflect the oranization of the
psycopg2 module and not the fact the the original error objects
live in _psycopg */
int i;
PyObject *dict;
PyObject *base;
@ -474,7 +475,7 @@ psyco_errors_fill(PyObject *dict)
PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
PyDict_SetItemString(dict, "DataError", DataError);
PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
}
void
@ -493,17 +494,17 @@ psyco_errors_set(PyObject *type)
}
/* psyco_error_new
Create a new error of the given type with extra attributes. */
void
psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
char *pgerror, char *pgcode)
{
PyObject *t;
PyObject *err = PyObject_CallFunction(exc, "s", msg);
if (err) {
if (pgerror) {
t = PyString_FromString(pgerror);
@ -522,16 +523,16 @@ psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
}
PyObject_SetAttrString(err, "pgcode", t);
Py_DECREF(t);
if (curs)
PyObject_SetAttrString(err, "cursor", curs);
else
PyObject_SetAttrString(err, "cursor", Py_None);
PyErr_SetObject(exc, err);
Py_DECREF(err);
Py_DECREF(err);
}
}
}
/* psyco_decimal_init
@ -589,7 +590,7 @@ static PyMethodDef psycopgMethods[] = {
METH_VARARGS, psyco_TimestampFromTicks_doc},
{"List", (PyCFunction)psyco_List,
METH_VARARGS, psyco_List_doc},
#ifdef HAVE_MXDATETIME
{"DateFromMx", (PyCFunction)psyco_DateFromMx,
METH_VARARGS, psyco_DateFromMx_doc},
@ -598,7 +599,7 @@ static PyMethodDef psycopgMethods[] = {
{"TimestampFromMx", (PyCFunction)psyco_TimestampFromMx,
METH_VARARGS, psyco_TimestampFromMx_doc},
{"IntervalFromMx", (PyCFunction)psyco_IntervalFromMx,
METH_VARARGS, psyco_IntervalFromMx_doc},
METH_VARARGS, psyco_IntervalFromMx_doc},
#endif
#ifdef HAVE_PYDATETIME
@ -609,7 +610,7 @@ static PyMethodDef psycopgMethods[] = {
{"TimestampFromPy", (PyCFunction)psyco_TimestampFromPy,
METH_VARARGS, psyco_TimestampFromPy_doc},
{"IntervalFromPy", (PyCFunction)psyco_IntervalFromPy,
METH_VARARGS, psyco_IntervalFromPy_doc},
METH_VARARGS, psyco_IntervalFromPy_doc},
#endif
{NULL, NULL, 0, NULL} /* Sentinel */
@ -619,7 +620,7 @@ PyMODINIT_FUNC
init_psycopg(void)
{
static void *PSYCOPG_API[PSYCOPG_API_pointers];
PyObject *module, *dict;
PyObject *c_api_object;
@ -635,7 +636,7 @@ init_psycopg(void)
asisType.ob_type = &PyType_Type;
listType.ob_type = &PyType_Type;
chunkType.ob_type = &PyType_Type;
if (PyType_Ready(&connectionType) == -1) return;
if (PyType_Ready(&cursorType) == -1) return;
if (PyType_Ready(&typecastType) == -1) return;
@ -645,18 +646,18 @@ init_psycopg(void)
if (PyType_Ready(&asisType) == -1) return;
if (PyType_Ready(&listType) == -1) return;
if (PyType_Ready(&chunkType) == -1) return;
#ifdef HAVE_PYBOOL
pbooleanType.ob_type = &PyType_Type;
if (PyType_Ready(&pbooleanType) == -1) return;
#endif
/* import mx.DateTime module, if necessary */
#ifdef HAVE_MXDATETIME
mxdatetimeType.ob_type = &PyType_Type;
if (PyType_Ready(&mxdatetimeType) == -1) return;
if (mxDateTime_ImportModuleAndAPI() != 0) {
Dprintf("initpsycopg: why marc hide mx.DateTime again?!");
Dprintf("initpsycopg: why marc hide mx.DateTime again?!");
PyErr_SetString(PyExc_ImportError, "can't import mx.DateTime module");
return;
}
@ -667,7 +668,7 @@ init_psycopg(void)
#ifdef HAVE_PYDATETIME
pyDateTimeModuleP = PyImport_ImportModule("datetime");
if (pyDateTimeModuleP == NULL) {
Dprintf("initpsycopg: can't import datetime module");
Dprintf("initpsycopg: can't import datetime module");
PyErr_SetString(PyExc_ImportError, "can't import datetime module");
return;
}
@ -680,20 +681,20 @@ init_psycopg(void)
pyTimeTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "time");
pyDateTimeTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "datetime");
pyDeltaTypeP = PyObject_GetAttrString(pyDateTimeModuleP, "timedelta");
#endif
#endif
/* import psycopg2.tz anyway (TODO: replace with C-level module?) */
pyPsycopgTzModule = PyImport_ImportModule("psycopg2.tz");
if (pyPsycopgTzModule == NULL) {
Dprintf("initpsycopg: can't import psycopg2.tz module");
Dprintf("initpsycopg: can't import psycopg2.tz module");
PyErr_SetString(PyExc_ImportError, "can't import psycopg2.tz module");
return;
return;
}
pyPsycopgTzLOCAL =
PyObject_GetAttrString(pyPsycopgTzModule, "LOCAL");
pyPsycopgTzFixedOffsetTimezone =
pyPsycopgTzLOCAL =
PyObject_GetAttrString(pyPsycopgTzModule, "LOCAL");
pyPsycopgTzFixedOffsetTimezone =
PyObject_GetAttrString(pyPsycopgTzModule, "FixedOffsetTimezone");
/* initialize the module and grab module's dictionary */
module = Py_InitModule("_psycopg", psycopgMethods);
dict = PyModule_GetDict(module);
@ -710,33 +711,33 @@ init_psycopg(void)
psycoEncodings = PyDict_New();
psyco_encodings_fill(psycoEncodings);
psyco_decimal_init();
/* set some module's parameters */
PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION);
PyModule_AddStringConstant(module, "__doc__", "psycopg PostgreSQL driver");
PyModule_AddObject(module, "apilevel", PyString_FromString(APILEVEL));
PyModule_AddObject(module, "threadsafety", PyInt_FromLong(THREADSAFETY));
PyModule_AddObject(module, "paramstyle", PyString_FromString(PARAMSTYLE));
/* put new types in module dictionary */
PyModule_AddObject(module, "connection", (PyObject*)&connectionType);
PyModule_AddObject(module, "cursor", (PyObject*)&cursorType);
PyModule_AddObject(module, "ISQLQuote", (PyObject*)&isqlquoteType);
/* encodings dictionary in module dictionary */
PyModule_AddObject(module, "encodings", psycoEncodings);
/* initialize default set of typecasters */
typecast_init(dict);
/* initialize microprotocols layer */
microprotocols_init(dict);
psyco_adapters_init(dict);
/* create a standard set of exceptions and add them to the module's dict */
psyco_errors_init();
psyco_errors_fill(dict);
/* Solve win32 build issue about non-constant initializer element */
cursorType.tp_alloc = PyType_GenericAlloc;
binaryType.tp_alloc = PyType_GenericAlloc;
@ -747,7 +748,7 @@ init_psycopg(void)
qstringType.tp_alloc = PyType_GenericAlloc;
listType.tp_alloc = PyType_GenericAlloc;
chunkType.tp_alloc = PyType_GenericAlloc;
#ifdef HAVE_PYDATETIME
pydatetimeType.tp_alloc = PyType_GenericAlloc;
#endif

View File

@ -22,12 +22,13 @@
#ifndef PSYCOPG_PYTHON_H
#define PSYCOPG_PYTHON_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
/* python < 2.2 does not have PyMemeberDef */
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2
#define PyMemberDef memberlist
#define PyMemberDef memberlist
#endif
/* PyObject_TypeCheck introduced in 2.2 */

View File

@ -19,6 +19,7 @@
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
@ -52,9 +53,9 @@ typecast_parse_date(char* s, char** t, int* len,
int* year, int* month, int* day)
{
int acc = -1, cz = 0;
Dprintf("typecast_parse_date: len = %d, s = %s", *len, s);
while (cz < 3 && *len > 0 && *s) {
switch (*s) {
case '-':
@ -67,7 +68,7 @@ typecast_parse_date(char* s, char** t, int* len,
break;
default:
acc = (acc == -1 ? 0 : acc*10) + ((int)*s - (int)'0');
break;
break;
}
s++; (*len)--;
@ -77,7 +78,7 @@ typecast_parse_date(char* s, char** t, int* len,
*day = acc;
cz += 1;
}
if (t != NULL) *t = s;
if (t != NULL) *t = s;
return cz;
}
@ -89,12 +90,12 @@ typecast_parse_time(char* s, char** t, int* len,
int acc = -1, cz = 0;
int tzs = 1, tzhh = 0, tzmm = 0;
int usd = 0;
/* sets microseconds and timezone to 0 because they may be missing */
*us = *tz = 0;
Dprintf("typecast_parse_time: len = %d, s = %s", *len, s);
while (cz < 6 && *len > 0 && *s) {
switch (*s) {
case ':':
@ -123,7 +124,7 @@ typecast_parse_time(char* s, char** t, int* len,
default:
acc = (acc == -1 ? 0 : acc*10) + ((int)*s - (int)'0');
if (cz == 3) usd += 1;
break;
break;
}
s++; (*len)--;
@ -136,13 +137,13 @@ typecast_parse_time(char* s, char** t, int* len,
else if (cz == 5) tzmm = acc;
}
if (t != NULL) *t = s;
*tz = tzs * tzhh*60 + tzmm;
if (*us != 0.0) {
while (usd++ < 6) *us *= 10.0;
}
return cz;
}
@ -168,7 +169,7 @@ typecastObject_initlist typecast_pydatetime[] = {
{"PYDATETIME", typecast_DATETIME_types, typecast_PYDATETIME_cast},
{"PYTIME", typecast_TIME_types, typecast_PYTIME_cast},
{"PYDATE", typecast_DATE_types, typecast_PYDATE_cast},
{"PYINTERVAL", typecast_INTERVAL_types, typecast_PYINTERVAL_cast},
{"PYINTERVAL", typecast_INTERVAL_types, typecast_PYINTERVAL_cast},
{NULL, NULL, NULL}
};
#endif
@ -179,7 +180,7 @@ typecastObject_initlist typecast_mxdatetime[] = {
{"MXDATETIME", typecast_DATETIME_types, typecast_MXDATE_cast},
{"MXTIME", typecast_TIME_types, typecast_MXTIME_cast},
{"MXDATE", typecast_DATE_types, typecast_MXDATE_cast},
{"MXINTERVAL", typecast_INTERVAL_types, typecast_MXINTERVAL_cast},
{"MXINTERVAL", typecast_INTERVAL_types, typecast_MXINTERVAL_cast},
{NULL, NULL, NULL}
};
#endif
@ -203,20 +204,20 @@ int
typecast_init(PyObject *dict)
{
int i;
/* create type dictionary and put it in module namespace */
psyco_types = PyDict_New();
psyco_binary_types = PyDict_New();
if (!psyco_types || !psyco_binary_types) {
Py_XDECREF(psyco_types);
Py_XDECREF(psyco_binary_types);
return -1;
}
}
PyDict_SetItemString(dict, "string_types", psyco_types);
PyDict_SetItemString(dict, "binary_types", psyco_binary_types);
/* insert the cast types into the 'types' dictionary and register them in
the module dictionary */
for (i = 0; typecast_builtins[i].name != NULL; i++) {
@ -235,7 +236,7 @@ typecast_init(PyObject *dict)
psyco_default_binary_cast = (PyObject *)t;
}
}
/* create and save a default cast object (but does not register it) */
psyco_default_cast = typecast_from_c(&typecast_default, dict);
@ -258,7 +259,7 @@ typecast_init(PyObject *dict)
PyDict_SetItem(dict, t->name, (PyObject *)t);
}
#endif
return 0;
}
@ -270,9 +271,11 @@ typecast_add(PyObject *obj, PyObject *dict, int binary)
Py_ssize_t len, i;
typecastObject *type = (typecastObject *)obj;
Dprintf("typecast_add: object at %p, values refcnt = %d",
obj, type->values->ob_refcnt);
Dprintf("typecast_add: object at %p, values refcnt = "
FORMAT_CODE_PY_SSIZE_T,
obj, type->values->ob_refcnt
);
if (dict == NULL)
dict = (binary ? psyco_binary_types : psyco_types);
@ -302,7 +305,7 @@ typecast_cmp(PyObject *obj1, PyObject* obj2)
PyObject *number = NULL;
Py_ssize_t i, j;
int res = -1;
if (PyObject_TypeCheck(obj2, &typecastType)) {
other = (typecastObject*)obj2;
}
@ -311,25 +314,25 @@ typecast_cmp(PyObject *obj1, PyObject* obj2)
}
Dprintf("typecast_cmp: other = %p, number = %p", other, number);
for (i=0; i < PyObject_Length(self->values) && res == -1; i++) {
long int val = PyInt_AsLong(PyTuple_GET_ITEM(self->values, i));
if (other != NULL) {
for (j=0; j < PyObject_Length(other->values); j++) {
if (PyInt_AsLong(PyTuple_GET_ITEM(other->values, j)) == val) {
res = 0; break;
res = 0; break;
}
}
}
else if (number != NULL) {
if (PyInt_AsLong(number) == val) {
res = 0; break;
}
}
}
Py_XDECREF(number);
return res;
}
@ -339,29 +342,29 @@ typecast_richcompare(PyObject *obj1, PyObject* obj2, int opid)
{
PyObject *result = NULL;
int res = typecast_cmp(obj1, obj2);
if (PyErr_Occurred()) return NULL;
if ((opid == Py_EQ && res == 0) || (opid != Py_EQ && res != 0))
result = Py_True;
else
result = Py_False;
Py_INCREF(result);
return result;
}
static struct PyMemberDef typecastObject_members[] = {
{"name", T_OBJECT, OFFSETOF(name), RO},
{"values", T_OBJECT, OFFSETOF(values), RO},
{NULL}
};
static void
typecast_dealloc(PyObject *obj)
{
typecastObject *self = (typecastObject*)obj;
Py_XDECREF(self->values);
Py_XDECREF(self->name);
Py_XDECREF(self->pcast);
@ -371,9 +374,9 @@ typecast_dealloc(PyObject *obj)
static PyObject *
typecast_call(PyObject *obj, PyObject *args, PyObject *kwargs)
{
{
PyObject *string, *cursor;
if (!PyArg_ParseTuple(args, "OO", &string, &cursor)) {
return NULL;
}
@ -389,9 +392,9 @@ PyTypeObject typecastType = {
"psycopg2._psycopg.type",
sizeof(typecastObject),
0,
typecast_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
typecast_cmp, /*tp_compare*/
@ -409,7 +412,7 @@ PyTypeObject typecastType = {
Py_TPFLAGS_HAVE_RICHCOMPARE, /*tp_flags*/
"psycopg type-casting object", /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
@ -426,11 +429,11 @@ PyTypeObject typecastType = {
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
0, /*tp_init*/
0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/
0, /*tp_new*/
@ -451,11 +454,12 @@ typecast_new(PyObject *name, PyObject *values, PyObject *cast, PyObject *base)
obj = PyObject_NEW(typecastObject, &typecastType);
if (obj == NULL) return NULL;
Dprintf("typecast_new: new type at = %p, refcnt = %d", obj, obj->ob_refcnt);
Dprintf("typecast_new: new type at = %p, refcnt = " FORMAT_CODE_PY_SSIZE_T,
obj, obj->ob_refcnt);
Py_INCREF(values);
obj->values = values;
if (name) {
Py_INCREF(name);
obj->name = name;
@ -476,26 +480,26 @@ typecast_new(PyObject *name, PyObject *values, PyObject *cast, PyObject *base)
Py_INCREF(cast);
obj->pcast = cast;
}
Dprintf("typecast_new: typecast object created at %p", obj);
return (PyObject *)obj;
}
PyObject *
typecast_from_python(PyObject *self, PyObject *args, PyObject *keywds)
{
PyObject *v, *name, *cast = NULL, *base = NULL;
PyObject *v, *name = NULL, *cast = NULL, *base = NULL;
static char *kwlist[] = {"values", "name", "castobj", "baseobj", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|O!OO", kwlist,
if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|O!OO", kwlist,
&PyTuple_Type, &v,
&PyString_Type, &name,
&cast, &base)) {
return NULL;
}
return typecast_new(name, v, cast, base);
}
@ -517,18 +521,18 @@ typecast_from_c(typecastObject_initlist *type, PyObject *dict)
}
while (type->values[len] != 0) len++;
tuple = PyTuple_New(len);
if (!tuple) return NULL;
for (i = 0; i < len ; i++) {
PyTuple_SET_ITEM(tuple, i, PyInt_FromLong(type->values[i]));
}
obj = (typecastObject *)
typecast_new(PyString_FromString(type->name), tuple, NULL, base);
if (obj) {
obj->ccast = type->cast;
obj->pcast = NULL;
@ -545,7 +549,7 @@ typecast_cast(PyObject *obj, char *str, Py_ssize_t len, PyObject *curs)
/* we don't incref, the caster *can't* die at this point */
old = ((cursorObject*)curs)->caster;
((cursorObject*)curs)->caster = obj;
if (self->ccast) {
res = self->ccast(str, len, curs);
}

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_TYPECAST_H
#define PSYCOPG_TYPECAST_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus
@ -60,7 +61,7 @@ typedef struct {
/* the type dictionary, much faster to access it globally */
extern PyObject *psyco_types;
extern PyObject *psyco_binary_types;
/* the default casting objects, used when no other objects are available */
extern PyObject *psyco_default_cast;
extern PyObject *psyco_default_binary_cast;
@ -81,5 +82,5 @@ extern PyObject *typecast_from_python(
/* the function used to dispatch typecasting calls */
extern PyObject *typecast_cast(
PyObject *self, char *str, Py_ssize_t len, PyObject *curs);
#endif /* !defined(PSYCOPG_TYPECAST_H) */

View File

@ -27,9 +27,9 @@ static int
typecast_array_cleanup(char **str, int *len)
{
int i, depth = 1;
if ((*str)[0] != '[') return -1;
for (i=1 ; depth > 0 && i < *len ; i++) {
if ((*str)[i] == '[')
depth += 1;
@ -37,7 +37,7 @@ typecast_array_cleanup(char **str, int *len)
depth -= 1;
}
if ((*str)[i] != '=') return -1;
*str = &((*str)[i+1]);
*len = *len - i - 1;
return 0;
@ -83,7 +83,7 @@ typecast_array_tokenize(char *str, int strlength,
q = 0; /* if q is odd we're inside quotes */
b = 0; /* if b is 1 we just encountered a backslash */
res = ASCAN_TOKEN;
for (i = *pos ; i < strlength ; i++) {
switch (str[i]) {
case '"':
@ -122,21 +122,21 @@ typecast_array_tokenize(char *str, int strlength,
if (str[*pos] == '"') {
*pos += 1;
l -= 2;
*quotes = 1;
*quotes = 1;
}
if (res == ASCAN_QUOTED) {
if (res == ASCAN_QUOTED) {
char *buffer = PyMem_Malloc(l+1);
if (buffer == NULL) return ASCAN_ERROR;
*token = buffer;
for (j = *pos; j < *pos+l; j++) {
if (str[j] != '\\'
|| (j > *pos && str[j-1] == '\\'))
*(buffer++) = str[j];
}
*buffer = '\0';
*length = buffer - *token;
}
@ -146,7 +146,7 @@ typecast_array_tokenize(char *str, int strlength,
}
*pos = i;
/* skip the comma and set position to the start of next token */
if (str[i] == ',') *pos += 1;
@ -162,22 +162,22 @@ typecast_array_scan(char *str, int strlength,
PyObject *stack[MAX_DIMENSIONS];
int stack_index = 0;
while (1) {
token = NULL;
state = typecast_array_tokenize(str, strlength,
&pos, &token, &length, &quotes);
state = typecast_array_tokenize(str, strlength,
&pos, &token, &length, &quotes);
Dprintf("typecast_array_scan: state = %d, length = %d, token = '%s'",
state, length, token);
if (state == ASCAN_TOKEN || state == ASCAN_QUOTED) {
PyObject *obj;
if (!quotes && length == 4
&& (token[0] == 'n' || token[0] == 'N')
&& (token[1] == 'u' || token[1] == 'U')
&& (token[2] == 'l' || token[2] == 'L')
&& (token[3] == 'l' || token[3] == 'L'))
obj = typecast_cast(base, NULL, 0, curs);
else
if (!quotes && length == 4
&& (token[0] == 'n' || token[0] == 'N')
&& (token[1] == 'u' || token[1] == 'U')
&& (token[2] == 'l' || token[2] == 'L')
&& (token[3] == 'l' || token[3] == 'L'))
obj = typecast_cast(base, NULL, 0, curs);
else
obj = typecast_cast(base, token, length, curs);
/* before anything else we free the memory */
@ -189,7 +189,7 @@ typecast_array_scan(char *str, int strlength,
}
else if (state == ASCAN_BEGIN) {
PyObject *sub = PyList_New(0);
PyObject *sub = PyList_New(0);
if (sub == NULL) return 0;
PyList_Append(array, sub);
@ -201,7 +201,7 @@ typecast_array_scan(char *str, int strlength,
stack[stack_index++] = array;
array = sub;
}
else if (state == ASCAN_ERROR) {
return 0;
}
@ -222,13 +222,13 @@ typecast_array_scan(char *str, int strlength,
/** GENERIC - a generic typecaster that can be used when no special actions
have to be taken on the single items **/
static PyObject *
typecast_GENERIC_ARRAY_cast(char *str, int len, PyObject *curs)
{
PyObject *obj = NULL;
PyObject *base = ((typecastObject*)((cursorObject*)curs)->caster)->bcast;
Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s', len = %d", str, len);
if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
@ -240,7 +240,7 @@ typecast_GENERIC_ARRAY_cast(char *str, int len, PyObject *curs)
}
Dprintf("typecast_GENERIC_ARRAY_cast: str = '%s', len = %d", str, len);
obj = PyList_New(0);
/* scan the array skipping the first level of {} */
@ -248,7 +248,7 @@ typecast_GENERIC_ARRAY_cast(char *str, int len, PyObject *curs)
Py_DECREF(obj);
obj = NULL;
}
return obj;
}

View File

@ -33,8 +33,10 @@
static void
chunk_dealloc(chunkObject *self)
{
Dprintf("chunk_dealloc: deallocating memory at %p, size %d",
self->base, self->len);
Dprintf("chunk_dealloc: deallocating memory at %p, size "
FORMAT_CODE_PY_SSIZE_T,
self->base, self->len
);
free(self->base);
self->ob_type->tp_free((PyObject *) self);
}
@ -42,12 +44,14 @@ chunk_dealloc(chunkObject *self)
static PyObject *
chunk_repr(chunkObject *self)
{
return PyString_FromFormat("<memory chunk at %p size %d>",
self->base, self->len);
return PyString_FromFormat(
"<memory chunk at %p size " FORMAT_CODE_PY_SSIZE_T ">",
self->base, self->len
);
}
static int
chunk_getreadbuffer(chunkObject *self, int segment, void **ptr)
static Py_ssize_t
chunk_getreadbuffer(chunkObject *self, Py_ssize_t segment, void **ptr)
{
if (segment != 0)
{
@ -59,8 +63,8 @@ chunk_getreadbuffer(chunkObject *self, int segment, void **ptr)
return self->len;
}
static int
chunk_getsegcount(chunkObject *self, int *lenp)
static Py_ssize_t
chunk_getsegcount(chunkObject *self, Py_ssize_t *lenp)
{
if (lenp != NULL)
*lenp = self->len;
@ -69,10 +73,10 @@ chunk_getsegcount(chunkObject *self, int *lenp)
static PyBufferProcs chunk_as_buffer =
{
(getreadbufferproc) chunk_getreadbuffer,
(getwritebufferproc) NULL,
(getsegcountproc) chunk_getsegcount,
(getcharbufferproc) NULL
(readbufferproc) chunk_getreadbuffer,
(writebufferproc) NULL,
(segcountproc) chunk_getsegcount,
(charbufferproc) NULL
};
#define chunk_doc "memory chunk"
@ -120,7 +124,7 @@ typecast_BINARY_cast_unescape(unsigned char *str, size_t *to_length)
if (dststr == NULL) return NULL;
Py_BEGIN_ALLOW_THREADS;
for (i = 0; i < len; i++) {
if (str[i] == '\\') {
if ( ++i < len) {
@ -140,17 +144,17 @@ typecast_BINARY_cast_unescape(unsigned char *str, size_t *to_length)
}
dstptr++;
}
Py_END_ALLOW_THREADS;
*to_length = (size_t)(dstptr-dststr);
return dststr;
}
#define PQunescapeBytea typecast_BINARY_cast_unescape
#endif
static PyObject *
typecast_BINARY_cast(char *s, int l, PyObject *curs)
{
@ -172,12 +176,13 @@ typecast_BINARY_cast(char *s, int l, PyObject *curs)
s = buffer;
}
str = (char*)PQunescapeBytea((unsigned char*)s, &len);
Dprintf("typecast_BINARY_cast: unescaped %d bytes", len);
Dprintf("typecast_BINARY_cast: unescaped " FORMAT_CODE_SIZE_T " bytes",
len);
if (buffer) PyMem_Free(buffer);
chunk = (chunkObject *) PyObject_New(chunkObject, &chunkType);
if (chunk == NULL) return NULL;
chunk->base = str;
chunk->len = len;
if ((res = PyBuffer_FromObject((PyObject *)chunk, 0, len)) == NULL)

View File

@ -22,6 +22,7 @@
#ifndef PSYCOPG_TYPECAST_BINARY_H
#define PSYCOPG_TYPECAST_BINARY_H 1
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef __cplusplus
@ -36,7 +37,7 @@ typedef struct {
PyObject_HEAD
void *base; /* Pointer to the memory chunk. */
int len; /* Size in bytes of the memory chunk. */
Py_ssize_t len; /* Size in bytes of the memory chunk. */
} chunkObject;

View File

@ -38,9 +38,9 @@ typecast_PYDATE_cast(char *str, int len, PyObject *curs)
{
PyObject* obj = NULL;
int n, y=0, m=0, d=0;
if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
if (!strcmp(str, "infinity") || !strcmp(str, "-infinity")) {
if (str[0] == '-') {
obj = PyObject_GetAttrString(pyDateTypeP, "min");
@ -59,7 +59,7 @@ typecast_PYDATE_cast(char *str, int len, PyObject *curs)
PyErr_SetString(DataError, "unable to parse date");
}
else {
if (y > 9999) y = 9999;
if (y > 9999) y = 9999;
obj = PyObject_CallFunction(pyDateTypeP, "iii", y, m, d);
}
}
@ -75,9 +75,9 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs)
int n, y=0, m=0, d=0;
int hh=0, mm=0, ss=0, us=0, tz=0;
char *tp = NULL;
if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
/* check for infinity */
if (!strcmp(str, "infinity") || !strcmp(str, "-infinity")) {
if (str[0] == '-') {
@ -93,11 +93,11 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs)
n = typecast_parse_date(str, &tp, &len, &y, &m, &d);
Dprintf("typecast_PYDATE_cast: tp = %p "
"n = %d, len = %d, y = %d, m = %d, d = %d",
tp, n, len, y, m, d);
tp, n, len, y, m, d);
if (n != 3) {
PyErr_SetString(DataError, "unable to parse date");
}
if (len > 0) {
n = typecast_parse_time(tp, NULL, &len, &hh, &mm, &ss, &us, &tz);
Dprintf("typecast_PYDATETIME_cast: n = %d, len = %d, "
@ -107,13 +107,13 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs)
PyErr_SetString(DataError, "unable to parse time");
}
}
if (ss > 59) {
mm += 1;
ss -= 60;
}
if (y > 9999)
y = 9999;
y = 9999;
if (n == 5 && ((cursorObject*)curs)->tzinfo_factory != Py_None) {
/* we have a time zone, calculate minutes and create
@ -124,8 +124,10 @@ typecast_PYDATETIME_cast(char *str, int len, PyObject *curs)
((cursorObject*)curs)->tzinfo_factory, "i", tz);
obj = PyObject_CallFunction(pyDateTimeTypeP, "iiiiiiiO",
y, m, d, hh, mm, ss, us, tzinfo);
Dprintf("typecast_PYDATETIME_cast: tzinfo: %p, refcnt = %d",
tzinfo, tzinfo->ob_refcnt);
Dprintf("typecast_PYDATETIME_cast: tzinfo: %p, refcnt = "
FORMAT_CODE_PY_SSIZE_T,
tzinfo, tzinfo->ob_refcnt
);
Py_XDECREF(tzinfo);
}
else {
@ -143,14 +145,14 @@ typecast_PYTIME_cast(char *str, int len, PyObject *curs)
{
PyObject* obj = NULL;
int n, hh=0, mm=0, ss=0, us=0, tz=0;
if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
n = typecast_parse_time(str, NULL, &len, &hh, &mm, &ss, &us, &tz);
Dprintf("typecast_PYTIME_cast: n = %d, len = %d, "
"hh = %d, mm = %d, ss = %d, us = %d, tz = %d",
n, len, hh, mm, ss, us, tz);
if (n < 3 || n > 5) {
PyErr_SetString(DataError, "unable to parse time");
}
@ -161,7 +163,7 @@ typecast_PYTIME_cast(char *str, int len, PyObject *curs)
}
obj = PyObject_CallFunction(pyTimeTypeP, "iiii", hh, mm, ss, us);
}
return obj;
return obj;
}
/** INTERVAL - parse an interval into a timedelta object **/
@ -178,7 +180,7 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs)
if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
Dprintf("typecast_PYINTERVAL_cast: s = %s", str);
while (len-- > 0 && *str) {
switch (*str) {
@ -234,12 +236,12 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs)
seconds = v;
v = 0.0; part = 6;
}
break;
break;
default:
break;
}
str++;
}
@ -254,7 +256,7 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs)
hundredths = v;
hundredths = hundredths/denominator;
}
/* calculates seconds */
if (sign < 0.0) {
seconds = - (hundredths + seconds + minutes*60 + hours*3600);
@ -263,7 +265,7 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs)
seconds += hundredths + minutes*60 + hours*3600;
}
/* calculates days */
/* calculates days */
days += years*365 + months*30;
micro = (seconds - floor(seconds)) * 1000000.0;
@ -274,7 +276,7 @@ typecast_PYINTERVAL_cast(char *str, int len, PyObject *curs)
/* psycopg defaults to using python datetime types */
#ifdef PSYCOPG_DEFAULT_PYDATETIME
#ifdef PSYCOPG_DEFAULT_PYDATETIME
#define typecast_DATE_cast typecast_PYDATE_cast
#define typecast_TIME_cast typecast_PYTIME_cast
#define typecast_INTERVAL_cast typecast_PYINTERVAL_cast