ยปCore Development>Code coverage>Modules/_sqlite/microprotocols.c

Python code coverage for Modules/_sqlite/microprotocols.c

#countcontent
1n/a/* microprotocols.c - minimalist and non-validating protocols implementation
2n/a *
3n/a * Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
4n/a *
5n/a * This file is part of psycopg and was adapted for pysqlite. Federico Di
6n/a * Gregorio gave the permission to use it within pysqlite under the following
7n/a * license:
8n/a *
9n/a * This software is provided 'as-is', without any express or implied
10n/a * warranty. In no event will the authors be held liable for any damages
11n/a * arising from the use of this software.
12n/a *
13n/a * Permission is granted to anyone to use this software for any purpose,
14n/a * including commercial applications, and to alter it and redistribute it
15n/a * freely, subject to the following restrictions:
16n/a *
17n/a * 1. The origin of this software must not be misrepresented; you must not
18n/a * claim that you wrote the original software. If you use this software
19n/a * in a product, an acknowledgment in the product documentation would be
20n/a * appreciated but is not required.
21n/a * 2. Altered source versions must be plainly marked as such, and must not be
22n/a * misrepresented as being the original software.
23n/a * 3. This notice may not be removed or altered from any source distribution.
24n/a */
25n/a
26n/a#include <Python.h>
27n/a#include <structmember.h>
28n/a
29n/a#include "cursor.h"
30n/a#include "microprotocols.h"
31n/a#include "prepare_protocol.h"
32n/a
33n/a
34n/a/** the adapters registry **/
35n/a
36n/aPyObject *psyco_adapters;
37n/a
38n/a/* pysqlite_microprotocols_init - initialize the adapters dictionary */
39n/a
40n/aint
41n/apysqlite_microprotocols_init(PyObject *dict)
42n/a{
43n/a /* create adapters dictionary and put it in module namespace */
44n/a if ((psyco_adapters = PyDict_New()) == NULL) {
45n/a return -1;
46n/a }
47n/a
48n/a return PyDict_SetItemString(dict, "adapters", psyco_adapters);
49n/a}
50n/a
51n/a
52n/a/* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */
53n/a
54n/aint
55n/apysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
56n/a{
57n/a PyObject* key;
58n/a int rc;
59n/a
60n/a if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType;
61n/a
62n/a key = Py_BuildValue("(OO)", (PyObject*)type, proto);
63n/a if (!key) {
64n/a return -1;
65n/a }
66n/a
67n/a rc = PyDict_SetItem(psyco_adapters, key, cast);
68n/a Py_DECREF(key);
69n/a
70n/a return rc;
71n/a}
72n/a
73n/a/* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */
74n/a
75n/aPyObject *
76n/apysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
77n/a{
78n/a PyObject *adapter, *key;
79n/a
80n/a /* we don't check for exact type conformance as specified in PEP 246
81n/a because the pysqlite_PrepareProtocolType type is abstract and there is no
82n/a way to get a quotable object to be its instance */
83n/a
84n/a /* look for an adapter in the registry */
85n/a key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
86n/a if (!key) {
87n/a return NULL;
88n/a }
89n/a adapter = PyDict_GetItem(psyco_adapters, key);
90n/a Py_DECREF(key);
91n/a if (adapter) {
92n/a PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
93n/a return adapted;
94n/a }
95n/a
96n/a /* try to have the protocol adapt this object*/
97n/a if (PyObject_HasAttrString(proto, "__adapt__")) {
98n/a _Py_IDENTIFIER(__adapt__);
99n/a PyObject *adapted = _PyObject_CallMethodId(proto, &PyId___adapt__, "O", obj);
100n/a
101n/a if (adapted) {
102n/a if (adapted != Py_None) {
103n/a return adapted;
104n/a } else {
105n/a Py_DECREF(adapted);
106n/a }
107n/a }
108n/a
109n/a if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
110n/a return NULL;
111n/a }
112n/a
113n/a /* and finally try to have the object adapt itself */
114n/a if (PyObject_HasAttrString(obj, "__conform__")) {
115n/a _Py_IDENTIFIER(__conform__);
116n/a PyObject *adapted = _PyObject_CallMethodId(obj, &PyId___conform__,"O", proto);
117n/a
118n/a if (adapted) {
119n/a if (adapted != Py_None) {
120n/a return adapted;
121n/a } else {
122n/a Py_DECREF(adapted);
123n/a }
124n/a }
125n/a
126n/a if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
127n/a return NULL;
128n/a }
129n/a }
130n/a
131n/a /* else set the right exception and return NULL */
132n/a PyErr_SetString(pysqlite_ProgrammingError, "can't adapt");
133n/a return NULL;
134n/a}
135n/a
136n/a/** module-level functions **/
137n/a
138n/aPyObject *
139n/apysqlite_adapt(pysqlite_Cursor *self, PyObject *args)
140n/a{
141n/a PyObject *obj, *alt = NULL;
142n/a PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType;
143n/a
144n/a if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL;
145n/a return pysqlite_microprotocols_adapt(obj, proto, alt);
146n/a}