LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules/_sqlite - statement.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 216 0.0 %
Date: 2012-12-17 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* statement.c - the statement type
       2             :  *
       3             :  * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
       4             :  *
       5             :  * This file is part of pysqlite.
       6             :  *
       7             :  * This software is provided 'as-is', without any express or implied
       8             :  * warranty.  In no event will the authors be held liable for any damages
       9             :  * arising from the use of this software.
      10             :  *
      11             :  * Permission is granted to anyone to use this software for any purpose,
      12             :  * including commercial applications, and to alter it and redistribute it
      13             :  * freely, subject to the following restrictions:
      14             :  *
      15             :  * 1. The origin of this software must not be misrepresented; you must not
      16             :  *    claim that you wrote the original software. If you use this software
      17             :  *    in a product, an acknowledgment in the product documentation would be
      18             :  *    appreciated but is not required.
      19             :  * 2. Altered source versions must be plainly marked as such, and must not be
      20             :  *    misrepresented as being the original software.
      21             :  * 3. This notice may not be removed or altered from any source distribution.
      22             :  */
      23             : 
      24             : #include "statement.h"
      25             : #include "cursor.h"
      26             : #include "connection.h"
      27             : #include "microprotocols.h"
      28             : #include "prepare_protocol.h"
      29             : #include "sqlitecompat.h"
      30             : 
      31             : /* prototypes */
      32             : static int pysqlite_check_remaining_sql(const char* tail);
      33             : 
      34             : typedef enum {
      35             :     LINECOMMENT_1,
      36             :     IN_LINECOMMENT,
      37             :     COMMENTSTART_1,
      38             :     IN_COMMENT,
      39             :     COMMENTEND_1,
      40             :     NORMAL
      41             : } parse_remaining_sql_state;
      42             : 
      43             : typedef enum {
      44             :     TYPE_LONG,
      45             :     TYPE_FLOAT,
      46             :     TYPE_UNICODE,
      47             :     TYPE_BUFFER,
      48             :     TYPE_UNKNOWN
      49             : } parameter_type;
      50             : 
      51           0 : int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql)
      52             : {
      53             :     const char* tail;
      54             :     int rc;
      55             :     const char* sql_cstr;
      56             :     Py_ssize_t sql_cstr_len;
      57             : 
      58           0 :     self->st = NULL;
      59           0 :     self->in_use = 0;
      60             : 
      61           0 :     sql_cstr = _PyUnicode_AsStringAndSize(sql, &sql_cstr_len);
      62           0 :     if (sql_cstr == NULL) {
      63           0 :         rc = PYSQLITE_SQL_WRONG_TYPE;
      64           0 :         return rc;
      65             :     }
      66             : 
      67           0 :     self->in_weakreflist = NULL;
      68           0 :     Py_INCREF(sql);
      69           0 :     self->sql = sql;
      70             : 
      71           0 :     Py_BEGIN_ALLOW_THREADS
      72           0 :     rc = sqlite3_prepare(connection->db,
      73             :                          sql_cstr,
      74             :                          -1,
      75             :                          &self->st,
      76             :                          &tail);
      77           0 :     Py_END_ALLOW_THREADS
      78             : 
      79           0 :     self->db = connection->db;
      80             : 
      81           0 :     if (rc == SQLITE_OK && pysqlite_check_remaining_sql(tail)) {
      82           0 :         (void)sqlite3_finalize(self->st);
      83           0 :         self->st = NULL;
      84           0 :         rc = PYSQLITE_TOO_MUCH_SQL;
      85             :     }
      86             : 
      87           0 :     return rc;
      88             : }
      89             : 
      90           0 : int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter)
      91             : {
      92           0 :     int rc = SQLITE_OK;
      93             :     PY_LONG_LONG longlongval;
      94             :     const char* buffer;
      95             :     char* string;
      96             :     Py_ssize_t buflen;
      97             :     parameter_type paramtype;
      98             : 
      99           0 :     if (parameter == Py_None) {
     100           0 :         rc = sqlite3_bind_null(self->st, pos);
     101           0 :         goto final;
     102             :     }
     103             : 
     104           0 :     if (PyLong_CheckExact(parameter)) {
     105           0 :         paramtype = TYPE_LONG;
     106           0 :     } else if (PyFloat_CheckExact(parameter)) {
     107           0 :         paramtype = TYPE_FLOAT;
     108           0 :     } else if (PyUnicode_CheckExact(parameter)) {
     109           0 :         paramtype = TYPE_UNICODE;
     110           0 :     } else if (PyLong_Check(parameter)) {
     111           0 :         paramtype = TYPE_LONG;
     112           0 :     } else if (PyFloat_Check(parameter)) {
     113           0 :         paramtype = TYPE_FLOAT;
     114           0 :     } else if (PyUnicode_Check(parameter)) {
     115           0 :         paramtype = TYPE_UNICODE;
     116           0 :     } else if (PyObject_CheckBuffer(parameter)) {
     117           0 :         paramtype = TYPE_BUFFER;
     118             :     } else {
     119           0 :         paramtype = TYPE_UNKNOWN;
     120             :     }
     121             : 
     122           0 :     switch (paramtype) {
     123             :         case TYPE_LONG:
     124             :             /* in the overflow error case, longval/longlongval is -1, and an exception is set */
     125           0 :             longlongval = PyLong_AsLongLong(parameter);
     126           0 :             rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval);
     127           0 :             break;
     128             :         case TYPE_FLOAT:
     129           0 :             rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
     130           0 :             break;
     131             :         case TYPE_UNICODE:
     132           0 :             string = _PyUnicode_AsStringAndSize(parameter, &buflen);
     133           0 :             if (string != NULL)
     134           0 :                 rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT);
     135             :             else
     136           0 :                 rc = -1;
     137           0 :             break;
     138             :         case TYPE_BUFFER:
     139           0 :             if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) {
     140           0 :                 rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT);
     141             :             } else {
     142           0 :                 PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
     143           0 :                 rc = -1;
     144             :             }
     145           0 :             break;
     146             :         case TYPE_UNKNOWN:
     147           0 :             rc = -1;
     148             :     }
     149             : 
     150             : final:
     151           0 :     return rc;
     152             : }
     153             : 
     154             : /* returns 0 if the object is one of Python's internal ones that don't need to be adapted */
     155           0 : static int _need_adapt(PyObject* obj)
     156             : {
     157           0 :     if (pysqlite_BaseTypeAdapted) {
     158           0 :         return 1;
     159             :     }
     160             : 
     161           0 :     if (PyLong_CheckExact(obj) || PyFloat_CheckExact(obj)
     162           0 :           || PyUnicode_CheckExact(obj) || PyByteArray_CheckExact(obj)) {
     163           0 :         return 0;
     164             :     } else {
     165           0 :         return 1;
     166             :     }
     167             : }
     168             : 
     169           0 : void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters)
     170             : {
     171             :     PyObject* current_param;
     172             :     PyObject* adapted;
     173             :     const char* binding_name;
     174             :     int i;
     175             :     int rc;
     176             :     int num_params_needed;
     177             :     int num_params;
     178             : 
     179           0 :     Py_BEGIN_ALLOW_THREADS
     180           0 :     num_params_needed = sqlite3_bind_parameter_count(self->st);
     181           0 :     Py_END_ALLOW_THREADS
     182             : 
     183           0 :     if (PyTuple_CheckExact(parameters) || PyList_CheckExact(parameters) || (!PyDict_Check(parameters) && PySequence_Check(parameters))) {
     184             :         /* parameters passed as sequence */
     185           0 :         if (PyTuple_CheckExact(parameters)) {
     186           0 :             num_params = PyTuple_GET_SIZE(parameters);
     187           0 :         } else if (PyList_CheckExact(parameters)) {
     188           0 :             num_params = PyList_GET_SIZE(parameters);
     189             :         } else {
     190           0 :             num_params = PySequence_Size(parameters);
     191             :         }
     192           0 :         if (num_params != num_params_needed) {
     193           0 :             PyErr_Format(pysqlite_ProgrammingError, "Incorrect number of bindings supplied. The current statement uses %d, and there are %d supplied.",
     194             :                          num_params_needed, num_params);
     195           0 :             return;
     196             :         }
     197           0 :         for (i = 0; i < num_params; i++) {
     198           0 :             if (PyTuple_CheckExact(parameters)) {
     199           0 :                 current_param = PyTuple_GET_ITEM(parameters, i);
     200           0 :                 Py_XINCREF(current_param);
     201           0 :             } else if (PyList_CheckExact(parameters)) {
     202           0 :                 current_param = PyList_GET_ITEM(parameters, i);
     203           0 :                 Py_XINCREF(current_param);
     204             :             } else {
     205           0 :                 current_param = PySequence_GetItem(parameters, i);
     206             :             }
     207           0 :             if (!current_param) {
     208           0 :                 return;
     209             :             }
     210             : 
     211           0 :             if (!_need_adapt(current_param)) {
     212           0 :                 adapted = current_param;
     213             :             } else {
     214           0 :                 adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, NULL);
     215           0 :                 if (adapted) {
     216           0 :                     Py_DECREF(current_param);
     217             :                 } else {
     218           0 :                     PyErr_Clear();
     219           0 :                     adapted = current_param;
     220             :                 }
     221             :             }
     222             : 
     223           0 :             rc = pysqlite_statement_bind_parameter(self, i + 1, adapted);
     224           0 :             Py_DECREF(adapted);
     225             : 
     226           0 :             if (rc != SQLITE_OK) {
     227           0 :                 if (!PyErr_Occurred()) {
     228           0 :                     PyErr_Format(pysqlite_InterfaceError, "Error binding parameter %d - probably unsupported type.", i);
     229             :                 }
     230           0 :                 return;
     231             :             }
     232             :         }
     233           0 :     } else if (PyDict_Check(parameters)) {
     234             :         /* parameters passed as dictionary */
     235           0 :         for (i = 1; i <= num_params_needed; i++) {
     236           0 :             Py_BEGIN_ALLOW_THREADS
     237           0 :             binding_name = sqlite3_bind_parameter_name(self->st, i);
     238           0 :             Py_END_ALLOW_THREADS
     239           0 :             if (!binding_name) {
     240           0 :                 PyErr_Format(pysqlite_ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i);
     241           0 :                 return;
     242             :             }
     243             : 
     244           0 :             binding_name++; /* skip first char (the colon) */
     245           0 :             if (PyDict_CheckExact(parameters)) {
     246           0 :                 current_param = PyDict_GetItemString(parameters, binding_name);
     247           0 :                 Py_XINCREF(current_param);
     248             :             } else {
     249           0 :                 current_param = PyMapping_GetItemString(parameters, (char*)binding_name);
     250             :             }
     251           0 :             if (!current_param) {
     252           0 :                 PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i);
     253           0 :                 return;
     254             :             }
     255             : 
     256           0 :             if (!_need_adapt(current_param)) {
     257           0 :                 adapted = current_param;
     258             :             } else {
     259           0 :                 adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, NULL);
     260           0 :                 if (adapted) {
     261           0 :                     Py_DECREF(current_param);
     262             :                 } else {
     263           0 :                     PyErr_Clear();
     264           0 :                     adapted = current_param;
     265             :                 }
     266             :             }
     267             : 
     268           0 :             rc = pysqlite_statement_bind_parameter(self, i, adapted);
     269           0 :             Py_DECREF(adapted);
     270             : 
     271           0 :             if (rc != SQLITE_OK) {
     272           0 :                 if (!PyErr_Occurred()) {
     273           0 :                     PyErr_Format(pysqlite_InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name);
     274             :                 }
     275           0 :                 return;
     276             :            }
     277             :         }
     278             :     } else {
     279           0 :         PyErr_SetString(PyExc_ValueError, "parameters are of unsupported type");
     280             :     }
     281             : }
     282             : 
     283           0 : int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* params)
     284             : {
     285             :     const char* tail;
     286             :     int rc;
     287             :     const char* sql_cstr;
     288             :     Py_ssize_t sql_len;
     289             :     sqlite3_stmt* new_st;
     290             : 
     291           0 :     sql_cstr = _PyUnicode_AsStringAndSize(self->sql, &sql_len);
     292           0 :     if (sql_cstr == NULL) {
     293           0 :         rc = PYSQLITE_SQL_WRONG_TYPE;
     294           0 :         return rc;
     295             :     }
     296             : 
     297           0 :     Py_BEGIN_ALLOW_THREADS
     298           0 :     rc = sqlite3_prepare(self->db,
     299             :                          sql_cstr,
     300             :                          -1,
     301             :                          &new_st,
     302             :                          &tail);
     303           0 :     Py_END_ALLOW_THREADS
     304             : 
     305           0 :     if (rc == SQLITE_OK) {
     306             :         /* The efficient sqlite3_transfer_bindings is only available in SQLite
     307             :          * version 3.2.2 or later. For older SQLite releases, that might not
     308             :          * even define SQLITE_VERSION_NUMBER, we do it the manual way.
     309             :          */
     310             :         #ifdef SQLITE_VERSION_NUMBER
     311             :         #if SQLITE_VERSION_NUMBER >= 3002002
     312             :         /* The check for the number of parameters is necessary to not trigger a
     313             :          * bug in certain SQLite versions (experienced in 3.2.8 and 3.3.4). */
     314           0 :         if (sqlite3_bind_parameter_count(self->st) > 0) {
     315           0 :             (void)sqlite3_transfer_bindings(self->st, new_st);
     316             :         }
     317             :         #endif
     318             :         #else
     319             :         statement_bind_parameters(self, params);
     320             :         #endif
     321             : 
     322           0 :         (void)sqlite3_finalize(self->st);
     323           0 :         self->st = new_st;
     324             :     }
     325             : 
     326           0 :     return rc;
     327             : }
     328             : 
     329           0 : int pysqlite_statement_finalize(pysqlite_Statement* self)
     330             : {
     331             :     int rc;
     332             : 
     333           0 :     rc = SQLITE_OK;
     334           0 :     if (self->st) {
     335           0 :         Py_BEGIN_ALLOW_THREADS
     336           0 :         rc = sqlite3_finalize(self->st);
     337           0 :         Py_END_ALLOW_THREADS
     338           0 :         self->st = NULL;
     339             :     }
     340             : 
     341           0 :     self->in_use = 0;
     342             : 
     343           0 :     return rc;
     344             : }
     345             : 
     346           0 : int pysqlite_statement_reset(pysqlite_Statement* self)
     347             : {
     348             :     int rc;
     349             : 
     350           0 :     rc = SQLITE_OK;
     351             : 
     352           0 :     if (self->in_use && self->st) {
     353           0 :         Py_BEGIN_ALLOW_THREADS
     354           0 :         rc = sqlite3_reset(self->st);
     355           0 :         Py_END_ALLOW_THREADS
     356             : 
     357           0 :         if (rc == SQLITE_OK) {
     358           0 :             self->in_use = 0;
     359             :         }
     360             :     }
     361             : 
     362           0 :     return rc;
     363             : }
     364             : 
     365           0 : void pysqlite_statement_mark_dirty(pysqlite_Statement* self)
     366             : {
     367           0 :     self->in_use = 1;
     368           0 : }
     369             : 
     370           0 : void pysqlite_statement_dealloc(pysqlite_Statement* self)
     371             : {
     372           0 :     if (self->st) {
     373           0 :         Py_BEGIN_ALLOW_THREADS
     374           0 :         sqlite3_finalize(self->st);
     375           0 :         Py_END_ALLOW_THREADS
     376             :     }
     377             : 
     378           0 :     self->st = NULL;
     379             : 
     380           0 :     Py_XDECREF(self->sql);
     381             : 
     382           0 :     if (self->in_weakreflist != NULL) {
     383           0 :         PyObject_ClearWeakRefs((PyObject*)self);
     384             :     }
     385             : 
     386           0 :     Py_TYPE(self)->tp_free((PyObject*)self);
     387           0 : }
     388             : 
     389             : /*
     390             :  * Checks if there is anything left in an SQL string after SQLite compiled it.
     391             :  * This is used to check if somebody tried to execute more than one SQL command
     392             :  * with one execute()/executemany() command, which the DB-API and we don't
     393             :  * allow.
     394             :  *
     395             :  * Returns 1 if there is more left than should be. 0 if ok.
     396             :  */
     397           0 : static int pysqlite_check_remaining_sql(const char* tail)
     398             : {
     399           0 :     const char* pos = tail;
     400             : 
     401           0 :     parse_remaining_sql_state state = NORMAL;
     402             : 
     403             :     for (;;) {
     404           0 :         switch (*pos) {
     405             :             case 0:
     406           0 :                 return 0;
     407             :             case '-':
     408           0 :                 if (state == NORMAL) {
     409           0 :                     state  = LINECOMMENT_1;
     410           0 :                 } else if (state == LINECOMMENT_1) {
     411           0 :                     state = IN_LINECOMMENT;
     412             :                 }
     413           0 :                 break;
     414             :             case ' ':
     415             :             case '\t':
     416           0 :                 break;
     417             :             case '\n':
     418             :             case 13:
     419           0 :                 if (state == IN_LINECOMMENT) {
     420           0 :                     state = NORMAL;
     421             :                 }
     422           0 :                 break;
     423             :             case '/':
     424           0 :                 if (state == NORMAL) {
     425           0 :                     state = COMMENTSTART_1;
     426           0 :                 } else if (state == COMMENTEND_1) {
     427           0 :                     state = NORMAL;
     428           0 :                 } else if (state == COMMENTSTART_1) {
     429           0 :                     return 1;
     430             :                 }
     431           0 :                 break;
     432             :             case '*':
     433           0 :                 if (state == NORMAL) {
     434           0 :                     return 1;
     435           0 :                 } else if (state == LINECOMMENT_1) {
     436           0 :                     return 1;
     437           0 :                 } else if (state == COMMENTSTART_1) {
     438           0 :                     state = IN_COMMENT;
     439           0 :                 } else if (state == IN_COMMENT) {
     440           0 :                     state = COMMENTEND_1;
     441             :                 }
     442           0 :                 break;
     443             :             default:
     444           0 :                 if (state == COMMENTEND_1) {
     445           0 :                     state = IN_COMMENT;
     446           0 :                 } else if (state == IN_LINECOMMENT) {
     447           0 :                 } else if (state == IN_COMMENT) {
     448             :                 } else {
     449           0 :                     return 1;
     450             :                 }
     451             :         }
     452             : 
     453           0 :         pos++;
     454           0 :     }
     455             : 
     456             :     return 0;
     457             : }
     458             : 
     459             : PyTypeObject pysqlite_StatementType = {
     460             :         PyVarObject_HEAD_INIT(NULL, 0)
     461             :         MODULE_NAME ".Statement",                       /* tp_name */
     462             :         sizeof(pysqlite_Statement),                     /* tp_basicsize */
     463             :         0,                                              /* tp_itemsize */
     464             :         (destructor)pysqlite_statement_dealloc,         /* tp_dealloc */
     465             :         0,                                              /* tp_print */
     466             :         0,                                              /* tp_getattr */
     467             :         0,                                              /* tp_setattr */
     468             :         0,                                              /* tp_reserved */
     469             :         0,                                              /* tp_repr */
     470             :         0,                                              /* tp_as_number */
     471             :         0,                                              /* tp_as_sequence */
     472             :         0,                                              /* tp_as_mapping */
     473             :         0,                                              /* tp_hash */
     474             :         0,                                              /* tp_call */
     475             :         0,                                              /* tp_str */
     476             :         0,                                              /* tp_getattro */
     477             :         0,                                              /* tp_setattro */
     478             :         0,                                              /* tp_as_buffer */
     479             :         Py_TPFLAGS_DEFAULT,                             /* tp_flags */
     480             :         0,                                              /* tp_doc */
     481             :         0,                                              /* tp_traverse */
     482             :         0,                                              /* tp_clear */
     483             :         0,                                              /* tp_richcompare */
     484             :         offsetof(pysqlite_Statement, in_weakreflist),   /* tp_weaklistoffset */
     485             :         0,                                              /* tp_iter */
     486             :         0,                                              /* tp_iternext */
     487             :         0,                                              /* tp_methods */
     488             :         0,                                              /* tp_members */
     489             :         0,                                              /* tp_getset */
     490             :         0,                                              /* tp_base */
     491             :         0,                                              /* tp_dict */
     492             :         0,                                              /* tp_descr_get */
     493             :         0,                                              /* tp_descr_set */
     494             :         0,                                              /* tp_dictoffset */
     495             :         (initproc)0,                                    /* tp_init */
     496             :         0,                                              /* tp_alloc */
     497             :         0,                                              /* tp_new */
     498             :         0                                               /* tp_free */
     499             : };
     500             : 
     501           0 : extern int pysqlite_statement_setup_types(void)
     502             : {
     503           0 :     pysqlite_StatementType.tp_new = PyType_GenericNew;
     504           0 :     return PyType_Ready(&pysqlite_StatementType);
     505             : }

Generated by: LCOV version 1.10