diff options
author | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:24:06 +0300 |
---|---|---|
committer | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:41:34 +0300 |
commit | e0e3e1717e3d33762ce61950504f9637a6e669ed (patch) | |
tree | bca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/tools/python3/src/Modules/_sqlite/microprotocols.c | |
parent | 38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff) | |
download | ydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz |
add ydb deps
Diffstat (limited to 'contrib/tools/python3/src/Modules/_sqlite/microprotocols.c')
-rw-r--r-- | contrib/tools/python3/src/Modules/_sqlite/microprotocols.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c new file mode 100644 index 0000000000..a79f0067b1 --- /dev/null +++ b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c @@ -0,0 +1,144 @@ +/* microprotocols.c - minimalist and non-validating protocols implementation + * + * Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org> + * + * This file is part of psycopg and was adapted for pysqlite. Federico Di + * Gregorio gave the permission to use it within pysqlite under the following + * license: + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include <Python.h> + +#include "cursor.h" +#include "microprotocols.h" +#include "prepare_protocol.h" + + +/* pysqlite_microprotocols_init - initialize the adapters dictionary */ + +int +pysqlite_microprotocols_init(PyObject *module) +{ + /* create adapters dictionary and put it in module namespace */ + pysqlite_state *state = pysqlite_get_state(module); + state->psyco_adapters = PyDict_New(); + if (state->psyco_adapters == NULL) { + return -1; + } + + return PyModule_AddObjectRef(module, "adapters", state->psyco_adapters); +} + + +/* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */ + +int +pysqlite_microprotocols_add(pysqlite_state *state, PyTypeObject *type, + PyObject *proto, PyObject *cast) +{ + PyObject* key; + int rc; + + assert(type != NULL); + assert(proto != NULL); + key = Py_BuildValue("(OO)", (PyObject*)type, proto); + if (!key) { + return -1; + } + + rc = PyDict_SetItem(state->psyco_adapters, key, cast); + Py_DECREF(key); + + return rc; +} + +/* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */ + +PyObject * +pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, + PyObject *proto, PyObject *alt) +{ + PyObject *adapter, *key, *adapted; + + /* we don't check for exact type conformance as specified in PEP 246 + because the PrepareProtocolType type is abstract and there is no + way to get a quotable object to be its instance */ + + /* look for an adapter in the registry */ + key = Py_BuildValue("(OO)", (PyObject*)Py_TYPE(obj), proto); + if (!key) { + return NULL; + } + adapter = PyDict_GetItemWithError(state->psyco_adapters, key); + Py_DECREF(key); + if (adapter) { + Py_INCREF(adapter); + adapted = PyObject_CallOneArg(adapter, obj); + Py_DECREF(adapter); + return adapted; + } + if (PyErr_Occurred()) { + return NULL; + } + + /* try to have the protocol adapt this object */ + if (_PyObject_LookupAttr(proto, state->str___adapt__, &adapter) < 0) { + return NULL; + } + if (adapter) { + adapted = PyObject_CallOneArg(adapter, obj); + Py_DECREF(adapter); + + if (adapted == Py_None) { + Py_DECREF(adapted); + } + else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) { + return adapted; + } + else { + PyErr_Clear(); + } + } + + /* and finally try to have the object adapt itself */ + if (_PyObject_LookupAttr(obj, state->str___conform__, &adapter) < 0) { + return NULL; + } + if (adapter) { + adapted = PyObject_CallOneArg(adapter, proto); + Py_DECREF(adapter); + + if (adapted == Py_None) { + Py_DECREF(adapted); + } + else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) { + return adapted; + } + else { + PyErr_Clear(); + } + } + + if (alt) { + return Py_NewRef(alt); + } + /* else set the right exception and return NULL */ + PyErr_SetString(state->ProgrammingError, "can't adapt"); + return NULL; +} |