symbian-qemu-0.9.1-12/python-2.6.1/Modules/_sqlite/microprotocols.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /* microprotocols.c - minimalist and non-validating protocols implementation
       
     2  *
       
     3  * Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
       
     4  *
       
     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
       
     7  * license:
       
     8  *
       
     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.
       
    12  *
       
    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:
       
    16  *
       
    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.
       
    24  */
       
    25 
       
    26 #include <Python.h>
       
    27 #include <structmember.h>
       
    28 
       
    29 #include "cursor.h"
       
    30 #include "microprotocols.h"
       
    31 #include "prepare_protocol.h"
       
    32 
       
    33 
       
    34 /** the adapters registry **/
       
    35 
       
    36 PyObject *psyco_adapters;
       
    37 
       
    38 /* pysqlite_microprotocols_init - initialize the adapters dictionary */
       
    39 
       
    40 int
       
    41 pysqlite_microprotocols_init(PyObject *dict)
       
    42 {
       
    43     /* create adapters dictionary and put it in module namespace */
       
    44     if ((psyco_adapters = PyDict_New()) == NULL) {
       
    45         return -1;
       
    46     }
       
    47 
       
    48     return PyDict_SetItemString(dict, "adapters", psyco_adapters);
       
    49 }
       
    50 
       
    51 
       
    52 /* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */
       
    53 
       
    54 int
       
    55 pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
       
    56 {
       
    57     PyObject* key;
       
    58     int rc;
       
    59 
       
    60     if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType;
       
    61 
       
    62     key = Py_BuildValue("(OO)", (PyObject*)type, proto);
       
    63     if (!key) {
       
    64         return -1;
       
    65     }
       
    66 
       
    67     rc = PyDict_SetItem(psyco_adapters, key, cast);
       
    68     Py_DECREF(key);
       
    69 
       
    70     return rc;
       
    71 }
       
    72 
       
    73 /* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */
       
    74 
       
    75 PyObject *
       
    76 pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
       
    77 {
       
    78     PyObject *adapter, *key;
       
    79 
       
    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 */
       
    83 
       
    84     /* look for an adapter in the registry */
       
    85     key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
       
    86     if (!key) {
       
    87         return NULL;
       
    88     }
       
    89     adapter = PyDict_GetItem(psyco_adapters, key);
       
    90     Py_DECREF(key);
       
    91     if (adapter) {
       
    92         PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
       
    93         return adapted;
       
    94     }
       
    95 
       
    96     /* try to have the protocol adapt this object*/
       
    97     if (PyObject_HasAttrString(proto, "__adapt__")) {
       
    98         PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj);
       
    99         if (adapted) {
       
   100             if (adapted != Py_None) {
       
   101                 return adapted;
       
   102             } else {
       
   103                 Py_DECREF(adapted);
       
   104             }
       
   105         }
       
   106 
       
   107         if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
       
   108             return NULL;
       
   109     }
       
   110 
       
   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);
       
   114         if (adapted) {
       
   115             if (adapted != Py_None) {
       
   116                 return adapted;
       
   117             } else {
       
   118                 Py_DECREF(adapted);
       
   119             }
       
   120         }
       
   121 
       
   122         if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
       
   123             return NULL;
       
   124         }
       
   125     }
       
   126 
       
   127     /* else set the right exception and return NULL */
       
   128     PyErr_SetString(pysqlite_ProgrammingError, "can't adapt");
       
   129     return NULL;
       
   130 }
       
   131 
       
   132 /** module-level functions **/
       
   133 
       
   134 PyObject *
       
   135 pysqlite_adapt(pysqlite_Cursor *self, PyObject *args)
       
   136 {
       
   137     PyObject *obj, *alt = NULL;
       
   138     PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType;
       
   139 
       
   140     if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL;
       
   141     return pysqlite_microprotocols_adapt(obj, proto, alt);
       
   142 }