mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-22 08:56:34 +03:00
Fixed both Python 2.5 and 64 bit problems.
This commit is contained in:
parent
fadd1a6938
commit
e5829292cd
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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" \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef PSYCOPG_LIST_H
|
||||
#define PSYCOPG_LIST_H 1
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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"); \
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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, ¶meters, &async)) {
|
||||
if (!PyArg_ParseTuple(args, "s|Ol", &procname, ¶meters, &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*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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
|
||||
|
|
118
psycopg/pqpath.c
118
psycopg/pqpath.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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, "es);
|
||||
state = typecast_array_tokenize(str, strlength,
|
||||
&pos, &token, &length, "es);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user