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