mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-25 10:23:43 +03:00
Adaptation fixes (a lot.)
This commit is contained in:
parent
1ec3c83720
commit
cd672525e1
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
2005-03-01 Federico Di Gregorio <fog@debian.org>
|
||||||
|
|
||||||
|
* psycopg/microprotocols.c (microprotocols_adapt): fixed small
|
||||||
|
typo that made adaptation using __conform__ impossible.
|
||||||
|
|
||||||
|
2005-02-28 Federico Di Gregorio <fog@debian.org>
|
||||||
|
|
||||||
|
* lib/extras.py: removed AsIs adapter (now a built-in); also
|
||||||
|
removed prepare() method from the adapters that don't use it to
|
||||||
|
avoid an extra method call at mogrification time.
|
||||||
|
|
||||||
|
* psycopg/psycopgmodule.c (psyco_adapters_init): added
|
||||||
|
initialization of the AsIs adapter (adapts int, long, float and
|
||||||
|
*wonder* None!)
|
||||||
|
|
||||||
|
* psycopg/cursor_type.c (_mogrify_getquoted): reorganized the code
|
||||||
|
to adapt and then call .getquoted() to obtain the quoted data into
|
||||||
|
this new function.
|
||||||
|
|
||||||
2005-2-27 Federico Di Gregorio <fog@initd.org>
|
2005-2-27 Federico Di Gregorio <fog@initd.org>
|
||||||
|
|
||||||
* examples/myfirstrecipe.py: fixed adapter registration.
|
* examples/myfirstrecipe.py: fixed adapter registration.
|
||||||
|
|
2
NEWS
2
NEWS
|
@ -11,6 +11,8 @@ What's new in psycopg 1.99.12
|
||||||
connect to an old protocol 2 database and will detect it and use the
|
connect to an old protocol 2 database and will detect it and use the
|
||||||
right code.
|
right code.
|
||||||
|
|
||||||
|
* getquoted() called for real by the mogrification code.
|
||||||
|
|
||||||
What's new in psycopg 1.99.11
|
What's new in psycopg 1.99.11
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,12 @@ import sys, psycopg
|
||||||
import psycopg.extensions
|
import psycopg.extensions
|
||||||
import whrandom
|
import whrandom
|
||||||
|
|
||||||
|
# importing psycopg.extras will give us a nice tuple adapter: this is wrong
|
||||||
|
# because the adapter is meant to be used in SQL IN clauses while we use
|
||||||
|
# tuples to represent points but it works and the example is about Rect, not
|
||||||
|
# "Point"
|
||||||
|
import psycopg.extras
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
DSN = sys.argv[1]
|
DSN = sys.argv[1]
|
||||||
|
|
||||||
|
@ -43,7 +49,7 @@ conn.commit()
|
||||||
# usually a function, but we use a class, just to demonstrate the
|
# usually a function, but we use a class, just to demonstrate the
|
||||||
# flexibility of the psycopg casting system
|
# flexibility of the psycopg casting system
|
||||||
|
|
||||||
class Rect:
|
class Rect(object):
|
||||||
"""Very simple rectangle.
|
"""Very simple rectangle.
|
||||||
|
|
||||||
Note that we use this type as a data holder, as an adapter of itself for
|
Note that we use this type as a data holder, as an adapter of itself for
|
||||||
|
@ -59,7 +65,6 @@ class Rect:
|
||||||
|
|
||||||
def __conform__(self, proto):
|
def __conform__(self, proto):
|
||||||
"""This is a terrible hack, just ignore proto and return self."""
|
"""This is a terrible hack, just ignore proto and return self."""
|
||||||
print "CONFORMIG!"
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def from_points(self, x0, y0, x1, y1):
|
def from_points(self, x0, y0, x1, y1):
|
||||||
|
@ -82,11 +87,6 @@ class Rect:
|
||||||
self.x, self.y, self.x + self.width, self.y + self.height)
|
self.x, self.y, self.x + self.width, self.y + self.height)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
__str__ = getquoted
|
|
||||||
|
|
||||||
def prepare(self, conn):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
"""Format a description of the box."""
|
"""Format a description of the box."""
|
||||||
s = "X: %d\tY: %d\tWidth: %d\tHeight: %d" % (
|
s = "X: %d\tY: %d\tWidth: %d\tHeight: %d" % (
|
||||||
|
|
|
@ -71,40 +71,19 @@ class DictRow(list):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AsIs(object):
|
|
||||||
"""An adapter that just return the object 'as is'.
|
|
||||||
|
|
||||||
psycopg 1.99.9 has some optimizations that make impossible to call adapt()
|
|
||||||
without adding some basic adapters externally. This limitation will be
|
|
||||||
lifted in a future release. In the meantime you can use the AsIs adapter.
|
|
||||||
"""
|
|
||||||
def __init__(self, obj):
|
|
||||||
self.__obj = obj
|
|
||||||
def getquoted(self):
|
|
||||||
return str(self.__obj)
|
|
||||||
def prepare(self, conn):
|
|
||||||
pass
|
|
||||||
__str__ = getquoted
|
|
||||||
|
|
||||||
class SQL_IN(object):
|
class SQL_IN(object):
|
||||||
"""Adapt any iterable to an SQL quotable object."""
|
"""Adapt any iterable to an SQL quotable object."""
|
||||||
|
|
||||||
def __init__(self, seq):
|
def __init__(self, seq):
|
||||||
self._seq = seq
|
self._seq = seq
|
||||||
|
|
||||||
def prepare(self, conn):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def getquoted(self):
|
def getquoted(self):
|
||||||
# this is the important line: note how every object in the
|
# this is the important line: note how every object in the
|
||||||
# list is adapted and then how getquoted() is called on it
|
# list is adapted and then how getquoted() is called on it
|
||||||
qobjs = [str(_A(o).getquoted()) for o in self._seq]
|
qobjs = [str(_A(o).getquoted()) for o in self._seq]
|
||||||
|
|
||||||
return '(' + ', '.join(qobjs) + ')'
|
return '(' + ', '.join(qobjs) + ')'
|
||||||
|
|
||||||
__str__ = getquoted
|
__str__ = getquoted
|
||||||
|
|
||||||
|
|
||||||
_RA(tuple, SQL_IN)
|
_RA(tuple, SQL_IN)
|
||||||
_RA(int, AsIs)
|
|
||||||
_RA(float, AsIs)
|
|
||||||
|
|
223
psycopg/adapter_asis.c
Normal file
223
psycopg/adapter_asis.c
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
/* adapter_asis.c - adapt types as they are
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
|
||||||
|
*
|
||||||
|
* This file is part of psycopg.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2,
|
||||||
|
* or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
#include <structmember.h>
|
||||||
|
#include <stringobject.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define PSYCOPG_MODULE
|
||||||
|
#include "psycopg/config.h"
|
||||||
|
#include "psycopg/python.h"
|
||||||
|
#include "psycopg/psycopg.h"
|
||||||
|
#include "psycopg/adapter_asis.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** the AsIs object **/
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
asis_str(asisObject *self)
|
||||||
|
{
|
||||||
|
if (self->wrapped == Py_None) {
|
||||||
|
return PyString_FromString("NULL");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return PyObject_Repr(self->wrapped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
asis_getquoted(asisObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
if (!PyArg_ParseTuple(args, "")) return NULL;
|
||||||
|
return asis_str(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
asis_prepare(asisObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *fake;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O", &fake)) return NULL;
|
||||||
|
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** the AsIs object */
|
||||||
|
|
||||||
|
/* object member list */
|
||||||
|
|
||||||
|
static struct PyMemberDef asisObject_members[] = {
|
||||||
|
{"adapted", T_OBJECT, offsetof(asisObject, wrapped), RO},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* object method table */
|
||||||
|
|
||||||
|
static PyMethodDef asisObject_methods[] = {
|
||||||
|
{"getquoted", (PyCFunction)asis_getquoted, METH_VARARGS,
|
||||||
|
"getquoted() -> wrapped object value as SQL-quoted string"},
|
||||||
|
/* {"prepare", (PyCFunction)asis_prepare, METH_VARARGS,
|
||||||
|
"prepare(conn) -> currently does nothing"}, */
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* initialization and finalization methods */
|
||||||
|
|
||||||
|
static int
|
||||||
|
asis_setup(asisObject *self, PyObject *obj)
|
||||||
|
{
|
||||||
|
Dprintf("asis_setup: init asis object at %p, refcnt = %d",
|
||||||
|
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);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
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);
|
||||||
|
|
||||||
|
obj->ob_type->tp_free(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
asis_init(PyObject *obj, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
PyObject *o;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O", &o))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return asis_setup((asisObject *)obj, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
asis_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
return type->tp_alloc(type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
asis_del(PyObject* self)
|
||||||
|
{
|
||||||
|
PyObject_Del(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
asis_repr(asisObject *self)
|
||||||
|
{
|
||||||
|
return PyString_FromFormat("<psycopg.AsIs object at %p>", self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* object type */
|
||||||
|
|
||||||
|
#define asisType_doc \
|
||||||
|
"psycopg.AsIs(str) -> new AsIs adapter object"
|
||||||
|
|
||||||
|
PyTypeObject asisType = {
|
||||||
|
PyObject_HEAD_INIT(NULL)
|
||||||
|
0,
|
||||||
|
"psycopg._psycopg.AsIs",
|
||||||
|
sizeof(asisObject),
|
||||||
|
0,
|
||||||
|
asis_dealloc, /*tp_dealloc*/
|
||||||
|
0, /*tp_print*/
|
||||||
|
|
||||||
|
0, /*tp_getattr*/
|
||||||
|
0, /*tp_setattr*/
|
||||||
|
|
||||||
|
0, /*tp_compare*/
|
||||||
|
|
||||||
|
(reprfunc)asis_repr, /*tp_repr*/
|
||||||
|
0, /*tp_as_number*/
|
||||||
|
0, /*tp_as_sequence*/
|
||||||
|
0, /*tp_as_mapping*/
|
||||||
|
0, /*tp_hash */
|
||||||
|
|
||||||
|
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*/
|
||||||
|
|
||||||
|
0, /*tp_richcompare*/
|
||||||
|
0, /*tp_weaklistoffset*/
|
||||||
|
|
||||||
|
0, /*tp_iter*/
|
||||||
|
0, /*tp_iternext*/
|
||||||
|
|
||||||
|
/* Attribute descriptor and subclassing stuff */
|
||||||
|
|
||||||
|
asisObject_methods, /*tp_methods*/
|
||||||
|
asisObject_members, /*tp_members*/
|
||||||
|
0, /*tp_getset*/
|
||||||
|
0, /*tp_base*/
|
||||||
|
0, /*tp_dict*/
|
||||||
|
|
||||||
|
0, /*tp_descr_get*/
|
||||||
|
0, /*tp_descr_set*/
|
||||||
|
0, /*tp_dictoffset*/
|
||||||
|
|
||||||
|
asis_init, /*tp_init*/
|
||||||
|
PyType_GenericAlloc, /*tp_alloc*/
|
||||||
|
asis_new, /*tp_new*/
|
||||||
|
(freefunc)asis_del, /*tp_free Low-level free-memory routine */
|
||||||
|
0, /*tp_is_gc For PyObject_IS_GC */
|
||||||
|
0, /*tp_bases*/
|
||||||
|
0, /*tp_mro method resolution order */
|
||||||
|
0, /*tp_cache*/
|
||||||
|
0, /*tp_subclasses*/
|
||||||
|
0 /*tp_weaklist*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** module-level functions **/
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
psyco_AsIs(PyObject *module, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *obj;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O", &obj))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return PyObject_CallFunction((PyObject *)&asisType, "O", obj);
|
||||||
|
}
|
51
psycopg/adapter_asis.h
Normal file
51
psycopg/adapter_asis.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/* adapter_asis.h - definition for the psycopg AsIs type wrapper
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003-2005 Federico Di Gregorio <fog@debian.org>
|
||||||
|
*
|
||||||
|
* This file is part of psycopg.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2,
|
||||||
|
* or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PSYCOPG_ASIS_H
|
||||||
|
#define PSYCOPG_ASIS_H 1
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern PyTypeObject asisType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject HEAD;
|
||||||
|
|
||||||
|
/* this is the real object we wrap */
|
||||||
|
PyObject *wrapped;
|
||||||
|
|
||||||
|
} asisObject;
|
||||||
|
|
||||||
|
/* functions exported to psycopgmodule.c */
|
||||||
|
|
||||||
|
extern PyObject *psyco_AsIs(PyObject *module, PyObject *args);
|
||||||
|
#define psyco_AsIs_doc \
|
||||||
|
"psycopg.AsIs(obj) -> new AsIs wrapper object"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !defined(PSYCOPG_ASIS_H) */
|
|
@ -190,8 +190,8 @@ static struct PyMemberDef binaryObject_members[] = {
|
||||||
static PyMethodDef binaryObject_methods[] = {
|
static PyMethodDef binaryObject_methods[] = {
|
||||||
{"getquoted", (PyCFunction)binary_getquoted, METH_VARARGS,
|
{"getquoted", (PyCFunction)binary_getquoted, METH_VARARGS,
|
||||||
"getquoted() -> wrapped object value as SQL-quoted binary string"},
|
"getquoted() -> wrapped object value as SQL-quoted binary string"},
|
||||||
{"prepare", (PyCFunction)binary_prepare, METH_VARARGS,
|
/* {"prepare", (PyCFunction)binary_prepare, METH_VARARGS,
|
||||||
"prepare(conn) -> currently does nothing"},
|
"prepare(conn) -> currently does nothing"},*/
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -108,8 +108,8 @@ static struct PyMemberDef pydatetimeObject_members[] = {
|
||||||
static PyMethodDef pydatetimeObject_methods[] = {
|
static PyMethodDef pydatetimeObject_methods[] = {
|
||||||
{"getquoted", (PyCFunction)pydatetime_getquoted, METH_VARARGS,
|
{"getquoted", (PyCFunction)pydatetime_getquoted, METH_VARARGS,
|
||||||
"getquoted() -> wrapped object value as SQL date/time"},
|
"getquoted() -> wrapped object value as SQL date/time"},
|
||||||
{"prepare", (PyCFunction)pydatetime_prepare, METH_VARARGS,
|
/* {"prepare", (PyCFunction)pydatetime_prepare, METH_VARARGS,
|
||||||
"prepare(conn) -> currently does nothing"},
|
"prepare(conn) -> currently does nothing"}, */
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,8 @@ static struct PyMemberDef mxdatetimeObject_members[] = {
|
||||||
static PyMethodDef mxdatetimeObject_methods[] = {
|
static PyMethodDef mxdatetimeObject_methods[] = {
|
||||||
{"getquoted", (PyCFunction)mxdatetime_getquoted, METH_VARARGS,
|
{"getquoted", (PyCFunction)mxdatetime_getquoted, METH_VARARGS,
|
||||||
"getquoted() -> wrapped object value as SQL date/time"},
|
"getquoted() -> wrapped object value as SQL date/time"},
|
||||||
{"prepare", (PyCFunction)mxdatetime_prepare, METH_VARARGS,
|
/* {"prepare", (PyCFunction)mxdatetime_prepare, METH_VARARGS,
|
||||||
"prepare(conn) -> currently does nothing"},
|
"prepare(conn) -> currently does nothing"}, */
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,8 @@ static struct PyMemberDef pbooleanObject_members[] = {
|
||||||
static PyMethodDef pbooleanObject_methods[] = {
|
static PyMethodDef pbooleanObject_methods[] = {
|
||||||
{"getquoted", (PyCFunction)pboolean_getquoted, METH_VARARGS,
|
{"getquoted", (PyCFunction)pboolean_getquoted, METH_VARARGS,
|
||||||
"getquoted() -> wrapped object value as SQL-quoted string"},
|
"getquoted() -> wrapped object value as SQL-quoted string"},
|
||||||
{"prepare", (PyCFunction)pboolean_prepare, METH_VARARGS,
|
/* {"prepare", (PyCFunction)pboolean_prepare, METH_VARARGS,
|
||||||
"prepare(conn) -> currently does nothing"},
|
"prepare(conn) -> currently does nothing"}, */
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,38 @@ psyco_curs_close(cursorObject *self, PyObject *args)
|
||||||
|
|
||||||
/* mogrify a query string and build argument array or dict */
|
/* mogrify a query string and build argument array or dict */
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
_mogrify_getquoted(PyObject *obj, connectionObject *conn)
|
||||||
|
{
|
||||||
|
PyObject *res = NULL;
|
||||||
|
PyObject *tmp = microprotocols_adapt(
|
||||||
|
obj, (PyObject*)&isqlquoteType, NULL);
|
||||||
|
|
||||||
|
if (tmp != NULL) {
|
||||||
|
Dprintf("_mogrify: adapted to %s", tmp->ob_type->tp_name);
|
||||||
|
|
||||||
|
/* if requested prepare the object passing it the connection */
|
||||||
|
if (PyObject_HasAttrString(tmp, "prepare")) {
|
||||||
|
res = PyObject_CallMethod(tmp, "prepare", "O", (PyObject*)conn);
|
||||||
|
if (res == NULL) {
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Py_DECREF(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call the getquoted method on tmp (that should exist because we
|
||||||
|
adapted to the right protocol) */
|
||||||
|
res = PyObject_CallMethod(tmp, "getquoted", NULL);
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we return res with one extra reference, the caller shall free it */
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
|
_mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
|
||||||
{
|
{
|
||||||
|
@ -131,28 +163,17 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
|
||||||
if (*d) *d = 's';
|
if (*d) *d = 's';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
t = microprotocols_adapt(value,
|
t = _mogrify_getquoted(value, conn);
|
||||||
(PyObject*)&isqlquoteType,
|
|
||||||
NULL);
|
|
||||||
if (t != NULL) {
|
if (t != NULL) {
|
||||||
/* t is a new object, refcnt = 1 */
|
|
||||||
Dprintf("_mogrify: adapted to %s",
|
|
||||||
t->ob_type->tp_name);
|
|
||||||
|
|
||||||
/* prepare the object passing it the connection */
|
|
||||||
PyObject_CallMethod(t, "prepare", "O",
|
|
||||||
(PyObject*)conn);
|
|
||||||
|
|
||||||
PyDict_SetItem(n, key, t);
|
PyDict_SetItem(n, key, t);
|
||||||
/* both key and t refcnt +1, key is at 2 now */
|
/* both key and t refcnt +1, key is at 2 now */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* we did not found an adapter but we don't raise
|
/* no adapter found, raise a BIG exception */
|
||||||
an exception; just pass the original value */
|
Py_XDECREF(value);
|
||||||
PyErr_Clear();
|
Py_DECREF(n);
|
||||||
PyDict_SetItem(n, key, value);
|
return -1;
|
||||||
Dprintf("_mogrify: set value refcnt: %d",
|
|
||||||
value->ob_refcnt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,20 +221,16 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject *t = microprotocols_adapt(value,
|
PyObject *t = _mogrify_getquoted(value, conn);
|
||||||
(PyObject*)&isqlquoteType,
|
|
||||||
NULL);
|
|
||||||
if (t != NULL) {
|
|
||||||
/* prepare the object passing it the connection */
|
|
||||||
PyObject_CallMethod(t, "prepare", "O", (PyObject*)conn);
|
|
||||||
|
|
||||||
|
if (t != NULL) {
|
||||||
PyTuple_SET_ITEM(n, index, t);
|
PyTuple_SET_ITEM(n, index, t);
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyErr_Clear();
|
Py_DECREF(n);
|
||||||
PyTuple_SET_ITEM(n, index, value);
|
Py_DECREF(value);
|
||||||
/* here we steal value ref, no need to DECREF */
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = d;
|
c = d;
|
||||||
|
@ -228,7 +245,7 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
|
||||||
n = PyTuple_New(0);
|
n = PyTuple_New(0);
|
||||||
*new = n;
|
*new = n;
|
||||||
|
|
||||||
return 0;;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define psyco_curs_execute_doc \
|
#define psyco_curs_execute_doc \
|
||||||
|
|
|
@ -58,8 +58,7 @@ microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
|
||||||
{
|
{
|
||||||
if (proto == NULL) proto = (PyObject*)&isqlquoteType;
|
if (proto == NULL) proto = (PyObject*)&isqlquoteType;
|
||||||
|
|
||||||
Dprintf("microprotocols_add: cast %p for (%s, ?)",
|
Dprintf("microprotocols_add: cast %p for (%s, ?)", cast, type->tp_name);
|
||||||
cast, type->tp_name);
|
|
||||||
|
|
||||||
PyDict_SetItem(psyco_adapters,
|
PyDict_SetItem(psyco_adapters,
|
||||||
Py_BuildValue("(OO)", (PyObject*)type, proto),
|
Py_BuildValue("(OO)", (PyObject*)type, proto),
|
||||||
|
@ -78,6 +77,8 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
because the ISQLQuote type is abstract and there is no way to get a
|
because the ISQLQuote type is abstract and there is no way to get a
|
||||||
quotable object to be its instance */
|
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 */
|
/* look for an adapter in the registry */
|
||||||
key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
|
key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
|
||||||
adapter = PyDict_GetItem(psyco_adapters, key);
|
adapter = PyDict_GetItem(psyco_adapters, key);
|
||||||
|
@ -95,14 +96,14 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
return NULL;
|
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__")) {
|
if (PyObject_HasAttrString(obj, "__conform__")) {
|
||||||
PyObject *adapted = PyObject_CallMethod(proto, "__conform__","O", obj);
|
PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto);
|
||||||
if (adapted && adapted != Py_None) return adapted;
|
if (adapted && adapted != Py_None) return adapted;
|
||||||
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
|
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* else set the right exception and return NULL */
|
/* else set the right exception and return NULL */
|
||||||
PyErr_SetString(ProgrammingError, "can't adapt");
|
PyErr_SetString(ProgrammingError, "can't adapt");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -106,8 +106,8 @@ static struct PyMethodDef isqlquoteObject_methods[] = {
|
||||||
METH_VARARGS, psyco_isqlquote_getbinary_doc},
|
METH_VARARGS, psyco_isqlquote_getbinary_doc},
|
||||||
{"getbuffer", (PyCFunction)psyco_isqlquote_getbuffer,
|
{"getbuffer", (PyCFunction)psyco_isqlquote_getbuffer,
|
||||||
METH_VARARGS, psyco_isqlquote_getbuffer_doc},
|
METH_VARARGS, psyco_isqlquote_getbuffer_doc},
|
||||||
{"prepare", (PyCFunction)psyco_isqlquote_prepare,
|
/* {"prepare", (PyCFunction)psyco_isqlquote_prepare,
|
||||||
METH_VARARGS, psyco_isqlquote_prepare_doc},
|
METH_VARARGS, psyco_isqlquote_prepare_doc}, */
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "psycopg/adapter_qstring.h"
|
#include "psycopg/adapter_qstring.h"
|
||||||
#include "psycopg/adapter_binary.h"
|
#include "psycopg/adapter_binary.h"
|
||||||
#include "psycopg/adapter_pboolean.h"
|
#include "psycopg/adapter_pboolean.h"
|
||||||
|
#include "psycopg/adapter_asis.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_MXDATETIME
|
#ifdef HAVE_MXDATETIME
|
||||||
|
@ -187,6 +188,10 @@ psyco_adapters_init(PyObject *mod)
|
||||||
{
|
{
|
||||||
PyObject *call;
|
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(&PyString_Type, NULL, (PyObject*)&qstringType);
|
||||||
microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType);
|
microprotocols_add(&PyUnicode_Type, NULL, (PyObject*)&qstringType);
|
||||||
microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType);
|
microprotocols_add(&PyBuffer_Type, NULL, (PyObject*)&binaryType);
|
||||||
|
@ -225,6 +230,9 @@ static encodingPair encodings[] = {
|
||||||
{"SQL_ASCII", "ascii"},
|
{"SQL_ASCII", "ascii"},
|
||||||
{"LATIN1", "latin_1"},
|
{"LATIN1", "latin_1"},
|
||||||
{"UNICODE", "utf_8"},
|
{"UNICODE", "utf_8"},
|
||||||
|
/* some compatibility stuff */
|
||||||
|
{"latin-1", "latin_1"},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
static void psyco_encodings_fill(PyObject *dict)
|
static void psyco_encodings_fill(PyObject *dict)
|
||||||
|
@ -328,7 +336,9 @@ static PyMethodDef psycopgMethods[] = {
|
||||||
METH_VARARGS, psyco_register_type_doc},
|
METH_VARARGS, psyco_register_type_doc},
|
||||||
{"new_type", (PyCFunction)typecast_from_python,
|
{"new_type", (PyCFunction)typecast_from_python,
|
||||||
METH_VARARGS|METH_KEYWORDS},
|
METH_VARARGS|METH_KEYWORDS},
|
||||||
|
|
||||||
|
{"AsIs", (PyCFunction)psyco_AsIs,
|
||||||
|
METH_VARARGS, psyco_AsIs_doc},
|
||||||
{"QuotedString", (PyCFunction)psyco_QuotedString,
|
{"QuotedString", (PyCFunction)psyco_QuotedString,
|
||||||
METH_VARARGS, psyco_QuotedString_doc},
|
METH_VARARGS, psyco_QuotedString_doc},
|
||||||
{"Boolean", (PyCFunction)psyco_Boolean,
|
{"Boolean", (PyCFunction)psyco_Boolean,
|
||||||
|
@ -388,8 +398,9 @@ init_psycopg(void)
|
||||||
cursorType.ob_type = &PyType_Type;
|
cursorType.ob_type = &PyType_Type;
|
||||||
typecastType.ob_type = &PyType_Type;
|
typecastType.ob_type = &PyType_Type;
|
||||||
qstringType.ob_type = &PyType_Type;
|
qstringType.ob_type = &PyType_Type;
|
||||||
binaryType.ob_type = &PyType_Type;
|
binaryType.ob_type = &PyType_Type;
|
||||||
isqlquoteType.ob_type = &PyType_Type;
|
isqlquoteType.ob_type = &PyType_Type;
|
||||||
|
asisType.ob_type = &PyType_Type;
|
||||||
|
|
||||||
if (PyType_Ready(&connectionType) == -1) return;
|
if (PyType_Ready(&connectionType) == -1) return;
|
||||||
if (PyType_Ready(&cursorType) == -1) return;
|
if (PyType_Ready(&cursorType) == -1) return;
|
||||||
|
@ -397,6 +408,7 @@ init_psycopg(void)
|
||||||
if (PyType_Ready(&qstringType) == -1) return;
|
if (PyType_Ready(&qstringType) == -1) return;
|
||||||
if (PyType_Ready(&binaryType) == -1) return;
|
if (PyType_Ready(&binaryType) == -1) return;
|
||||||
if (PyType_Ready(&isqlquoteType) == -1) return;
|
if (PyType_Ready(&isqlquoteType) == -1) return;
|
||||||
|
if (PyType_Ready(&asisType) == -1) return;
|
||||||
|
|
||||||
#ifdef HAVE_PYBOOL
|
#ifdef HAVE_PYBOOL
|
||||||
pbooleanType.ob_type = &PyType_Type;
|
pbooleanType.ob_type = &PyType_Type;
|
||||||
|
|
5
setup.py
5
setup.py
|
@ -47,7 +47,7 @@ from distutils.core import setup, Extension
|
||||||
from distutils.sysconfig import get_python_inc
|
from distutils.sysconfig import get_python_inc
|
||||||
import distutils.ccompiler
|
import distutils.ccompiler
|
||||||
|
|
||||||
PSYCOPG_VERSION = '1.99.11'
|
PSYCOPG_VERSION = '1.99.11/devel'
|
||||||
|
|
||||||
have_pydatetime = False
|
have_pydatetime = False
|
||||||
have_mxdatetime = False
|
have_mxdatetime = False
|
||||||
|
@ -114,7 +114,8 @@ sources = [
|
||||||
'psycopgmodule.c', 'pqpath.c', 'typecast.c',
|
'psycopgmodule.c', 'pqpath.c', 'typecast.c',
|
||||||
'microprotocols.c', 'microprotocols_proto.c',
|
'microprotocols.c', 'microprotocols_proto.c',
|
||||||
'connection_type.c', 'connection_int.c', 'cursor_type.c', 'cursor_int.c',
|
'connection_type.c', 'connection_int.c', 'cursor_type.c', 'cursor_int.c',
|
||||||
'adapter_qstring.c', 'adapter_pboolean.c', 'adapter_binary.c']
|
'adapter_qstring.c', 'adapter_pboolean.c', 'adapter_binary.c',
|
||||||
|
'adapter_asis.c']
|
||||||
|
|
||||||
# check for mx package
|
# check for mx package
|
||||||
mxincludedir = os.path.join(get_python_inc(plat_specific=1), "mx")
|
mxincludedir = os.path.join(get_python_inc(plat_specific=1), "mx")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user