1 /* microprotocols.c - minimalist and non-validating protocols implementation
3 * Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
5 * This file is part of psycopg and was adapted for pysqlite. Federico Di
6 * Gregorio gave the permission to use it within pysqlite under the following
9 * This software is provided 'as-is', without any express or implied
10 * warranty. In no event will the authors be held liable for any damages
11 * arising from the use of this software.
13 * Permission is granted to anyone to use this software for any purpose,
14 * including commercial applications, and to alter it and redistribute it
15 * freely, subject to the following restrictions:
17 * 1. The origin of this software must not be misrepresented; you must not
18 * claim that you wrote the original software. If you use this software
19 * in a product, an acknowledgment in the product documentation would be
20 * appreciated but is not required.
21 * 2. Altered source versions must be plainly marked as such, and must not be
22 * misrepresented as being the original software.
23 * 3. This notice may not be removed or altered from any source distribution.
27 #include <structmember.h>
30 #include "microprotocols.h"
31 #include "prepare_protocol.h"
34 /** the adapters registry **/
36 PyObject
*psyco_adapters
;
38 /* microprotocols_init - initialize the adapters dictionary */
41 microprotocols_init(PyObject
*dict
)
43 /* create adapters dictionary and put it in module namespace */
44 if ((psyco_adapters
= PyDict_New()) == NULL
) {
48 return PyDict_SetItemString(dict
, "adapters", psyco_adapters
);
52 /* microprotocols_add - add a reverse type-caster to the dictionary */
55 microprotocols_add(PyTypeObject
*type
, PyObject
*proto
, PyObject
*cast
)
60 if (proto
== NULL
) proto
= (PyObject
*)&pysqlite_PrepareProtocolType
;
62 key
= Py_BuildValue("(OO)", (PyObject
*)type
, proto
);
67 rc
= PyDict_SetItem(psyco_adapters
, key
, cast
);
73 /* microprotocols_adapt - adapt an object to the built-in protocol */
76 microprotocols_adapt(PyObject
*obj
, PyObject
*proto
, PyObject
*alt
)
78 PyObject
*adapter
, *key
;
80 /* we don't check for exact type conformance as specified in PEP 246
81 because the pysqlite_PrepareProtocolType type is abstract and there is no
82 way to get a quotable object to be its instance */
84 /* look for an adapter in the registry */
85 key
= Py_BuildValue("(OO)", (PyObject
*)obj
->ob_type
, proto
);
89 adapter
= PyDict_GetItem(psyco_adapters
, key
);
92 PyObject
*adapted
= PyObject_CallFunctionObjArgs(adapter
, obj
, NULL
);
96 /* try to have the protocol adapt this object*/
97 if (PyObject_HasAttrString(proto
, "__adapt__")) {
98 PyObject
*adapted
= PyObject_CallMethod(proto
, "__adapt__", "O", obj
);
100 if (adapted
!= Py_None
) {
107 if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError
))
111 /* and finally try to have the object adapt itself */
112 if (PyObject_HasAttrString(obj
, "__conform__")) {
113 PyObject
*adapted
= PyObject_CallMethod(obj
, "__conform__","O", proto
);
115 if (adapted
!= Py_None
) {
122 if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError
)) {
127 /* else set the right exception and return NULL */
128 PyErr_SetString(pysqlite_ProgrammingError
, "can't adapt");
132 /** module-level functions **/
135 psyco_microprotocols_adapt(pysqlite_Cursor
*self
, PyObject
*args
)
137 PyObject
*obj
, *alt
= NULL
;
138 PyObject
*proto
= (PyObject
*)&pysqlite_PrepareProtocolType
;
140 if (!PyArg_ParseTuple(args
, "O|OO", &obj
, &proto
, &alt
)) return NULL
;
141 return microprotocols_adapt(obj
, proto
, alt
);