Merge p3yk branch with the trunk up to revision 45595. This breaks a fair

number of tests, all because of the codecs/_multibytecodecs issue described
here (it's not a Py3K issue, just something Py3K discovers):
http://mail.python.org/pipermail/python-dev/2006-April/064051.html

Hye-Shik Chang promised to look for a fix, so no need to fix it here. The
tests that are expected to break are:

test_codecencodings_cn
test_codecencodings_hk
test_codecencodings_jp
test_codecencodings_kr
test_codecencodings_tw
test_codecs
test_multibytecodec

This merge fixes an actual test failure (test_weakref) in this branch,
though, so I believe merging is the right thing to do anyway.
This commit is contained in:
Thomas Wouters 2006-04-21 10:40:58 +00:00
parent 9ada3d6e29
commit 49fd7fa443
640 changed files with 52240 additions and 18408 deletions

View file

@ -0,0 +1,40 @@
/* adapters.c - default adapters
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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 "util.h"
#include "module.h"
#include "adapters.h"
/* dummy, will be implemented in a later version */
PyObject* adapt_date(PyObject* self, PyObject* args, PyObject* kwargs)
{
Py_INCREF(Py_None);
return Py_None;
}
PyObject* adapt_datetime(PyObject* self, PyObject* args, PyObject* kwargs)
{
Py_INCREF(Py_None);
return Py_None;
}

View file

@ -0,0 +1,33 @@
/* adapters.h - default adapters
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_ADAPTERS_H
#define PYSQLITE_ADAPTERS_H
#include "Python.h"
#include "pythread.h"
#include "sqlite3.h"
PyObject* adapt_date(PyObject* self, PyObject* args, PyObject* kwargs);
PyObject* adapt_datetime(PyObject* self, PyObject* args, PyObject* kwargs);
#endif

362
Modules/_sqlite/cache.c Normal file
View file

@ -0,0 +1,362 @@
/* cache .c - a LRU cache
*
* Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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 "cache.h"
/* only used internally */
Node* new_node(PyObject* key, PyObject* data)
{
Node* node;
node = (Node*) (NodeType.tp_alloc(&NodeType, 0));
if (!node) {
return NULL;
}
Py_INCREF(key);
node->key = key;
Py_INCREF(data);
node->data = data;
node->prev = NULL;
node->next = NULL;
return node;
}
void node_dealloc(Node* self)
{
Py_DECREF(self->key);
Py_DECREF(self->data);
self->ob_type->tp_free((PyObject*)self);
}
int cache_init(Cache* self, PyObject* args, PyObject* kwargs)
{
PyObject* factory;
int size = 10;
self->factory = NULL;
if (!PyArg_ParseTuple(args, "O|i", &factory, &size))
{
return -1;
}
if (size < 5) {
size = 5;
}
self->size = size;
self->first = NULL;
self->last = NULL;
self->mapping = PyDict_New();
if (!self->mapping) {
return -1;
}
Py_INCREF(factory);
self->factory = factory;
self->decref_factory = 1;
return 0;
}
void cache_dealloc(Cache* self)
{
Node* node;
Node* delete_node;
if (!self->factory) {
/* constructor failed, just get out of here */
return;
}
node = self->first;
while (node) {
delete_node = node;
node = node->next;
Py_DECREF(delete_node);
}
if (self->decref_factory) {
Py_DECREF(self->factory);
}
Py_DECREF(self->mapping);
self->ob_type->tp_free((PyObject*)self);
}
PyObject* cache_get(Cache* self, PyObject* args)
{
PyObject* key = args;
Node* node;
Node* ptr;
PyObject* data;
node = (Node*)PyDict_GetItem(self->mapping, key);
if (node) {
node->count++;
if (node->prev && node->count > node->prev->count) {
ptr = node->prev;
while (ptr->prev && node->count > ptr->prev->count) {
ptr = ptr->prev;
}
if (node->next) {
node->next->prev = node->prev;
} else {
self->last = node->prev;
}
if (node->prev) {
node->prev->next = node->next;
}
if (ptr->prev) {
ptr->prev->next = node;
} else {
self->first = node;
}
node->next = ptr;
node->prev = ptr->prev;
if (!node->prev) {
self->first = node;
}
ptr->prev = node;
}
} else {
if (PyDict_Size(self->mapping) == self->size) {
if (self->last) {
node = self->last;
if (PyDict_DelItem(self->mapping, self->last->key) != 0) {
return NULL;
}
if (node->prev) {
node->prev->next = NULL;
}
self->last = node->prev;
node->prev = NULL;
Py_DECREF(node);
}
}
data = PyObject_CallFunction(self->factory, "O", key);
if (!data) {
return NULL;
}
node = new_node(key, data);
if (!node) {
return NULL;
}
node->prev = self->last;
Py_DECREF(data);
if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) {
Py_DECREF(node);
return NULL;
}
if (self->last) {
self->last->next = node;
} else {
self->first = node;
}
self->last = node;
}
Py_INCREF(node->data);
return node->data;
}
PyObject* cache_display(Cache* self, PyObject* args)
{
Node* ptr;
PyObject* prevkey;
PyObject* nextkey;
PyObject* fmt_args;
PyObject* template;
PyObject* display_str;
ptr = self->first;
while (ptr) {
if (ptr->prev) {
prevkey = ptr->prev->key;
} else {
prevkey = Py_None;
}
Py_INCREF(prevkey);
if (ptr->next) {
nextkey = ptr->next->key;
} else {
nextkey = Py_None;
}
Py_INCREF(nextkey);
fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey);
if (!fmt_args) {
return NULL;
}
template = PyString_FromString("%s <- %s ->%s\n");
if (!template) {
return NULL;
}
display_str = PyString_Format(template, fmt_args);
Py_DECREF(template);
Py_DECREF(fmt_args);
if (!display_str) {
return NULL;
}
PyObject_Print(display_str, stdout, Py_PRINT_RAW);
Py_DECREF(display_str);
Py_DECREF(prevkey);
Py_DECREF(nextkey);
ptr = ptr->next;
}
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef cache_methods[] = {
{"get", (PyCFunction)cache_get, METH_O,
PyDoc_STR("Gets an entry from the cache.")},
{"display", (PyCFunction)cache_display, METH_NOARGS,
PyDoc_STR("For debugging only.")},
{NULL, NULL}
};
PyTypeObject NodeType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME "Node", /* tp_name */
sizeof(Node), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)node_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
PyTypeObject CacheType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME ".Cache", /* tp_name */
sizeof(Cache), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)cache_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
cache_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)cache_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
extern int cache_setup_types(void)
{
int rc;
NodeType.tp_new = PyType_GenericNew;
CacheType.tp_new = PyType_GenericNew;
rc = PyType_Ready(&NodeType);
if (rc < 0) {
return rc;
}
rc = PyType_Ready(&CacheType);
return rc;
}

61
Modules/_sqlite/cache.h Normal file
View file

@ -0,0 +1,61 @@
/* cache.h - definitions for the LRU cache
*
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_CACHE_H
#define PYSQLITE_CACHE_H
#include "Python.h"
typedef struct _Node
{
PyObject_HEAD
PyObject* key;
PyObject* data;
long count;
struct _Node* prev;
struct _Node* next;
} Node;
typedef struct
{
PyObject_HEAD
int size;
PyObject* mapping;
PyObject* factory;
Node* first;
Node* last;
int decref_factory;
} Cache;
extern PyTypeObject NodeType;
extern PyTypeObject CacheType;
int node_init(Node* self, PyObject* args, PyObject* kwargs);
void node_dealloc(Node* self);
int cache_init(Cache* self, PyObject* args, PyObject* kwargs);
void cache_dealloc(Cache* self);
PyObject* cache_get(Cache* self, PyObject* args);
int cache_setup_types(void);
#endif

1082
Modules/_sqlite/connection.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,106 @@
/* connection.h - definitions for the connection type
*
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_CONNECTION_H
#define PYSQLITE_CONNECTION_H
#include "Python.h"
#include "pythread.h"
#include "structmember.h"
#include "cache.h"
#include "module.h"
#include "sqlite3.h"
typedef struct
{
PyObject_HEAD
sqlite3* db;
int inTransaction;
int detect_types;
/* the timeout value in seconds for database locks */
double timeout;
/* for internal use in the timeout handler: when did the timeout handler
* first get called with count=0? */
double timeout_started;
/* None for autocommit, otherwise a PyString with the isolation level */
PyObject* isolation_level;
/* NULL for autocommit, otherwise a string with the BEGIN statment; will be
* freed in connection destructor */
char* begin_statement;
int check_same_thread;
long thread_ident;
Cache* statement_cache;
PyObject* row_factory;
PyObject* text_factory;
/* remember references to functions/classes used in
* create_function/create/aggregate, use these as dictionary keys, so we
* can keep the total system refcount constant by clearing that dictionary
* in connection_dealloc */
PyObject* function_pinboard;
/* a dictionary of registered collation name => collation callable mappings */
PyObject* collations;
/* Exception objects */
PyObject* Warning;
PyObject* Error;
PyObject* InterfaceError;
PyObject* DatabaseError;
PyObject* DataError;
PyObject* OperationalError;
PyObject* IntegrityError;
PyObject* InternalError;
PyObject* ProgrammingError;
PyObject* NotSupportedError;
} Connection;
extern PyTypeObject ConnectionType;
PyObject* connection_alloc(PyTypeObject* type, int aware);
void connection_dealloc(Connection* self);
PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs);
PyObject* connection_close(Connection* self, PyObject* args);
PyObject* _connection_begin(Connection* self);
PyObject* connection_begin(Connection* self, PyObject* args);
PyObject* connection_commit(Connection* self, PyObject* args);
PyObject* connection_rollback(Connection* self, PyObject* args);
PyObject* connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
int connection_init(Connection* self, PyObject* args, PyObject* kwargs);
int check_thread(Connection* self);
int check_connection(Connection* con);
int connection_setup_types(void);
#endif

View file

@ -0,0 +1,40 @@
/* converters.c - default converters
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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 "util.h"
#include "module.h"
#include "adapters.h"
/* dummy, will be implemented in a later version */
PyObject* convert_date(PyObject* self, PyObject* args, PyObject* kwargs)
{
Py_INCREF(Py_None);
return Py_None;
}
PyObject* convert_timestamp(PyObject* self, PyObject* args, PyObject* kwargs)
{
Py_INCREF(Py_None);
return Py_None;
}

View file

@ -0,0 +1,33 @@
/* converters.h - default converters
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_CONVERTERS_H
#define PYSQLITE_CONVERTERS_H
#include "Python.h"
#include "pythread.h"
#include "sqlite3.h"
PyObject* convert_date(PyObject* self, PyObject* args, PyObject* kwargs);
PyObject* convert_timestamp(PyObject* self, PyObject* args, PyObject* kwargs);
#endif

1027
Modules/_sqlite/cursor.c Normal file

File diff suppressed because it is too large Load diff

71
Modules/_sqlite/cursor.h Normal file
View file

@ -0,0 +1,71 @@
/* cursor.h - definitions for the cursor type
*
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_CURSOR_H
#define PYSQLITE_CURSOR_H
#include "Python.h"
#include "statement.h"
#include "connection.h"
#include "module.h"
typedef struct
{
PyObject_HEAD
Connection* connection;
PyObject* description;
PyObject* row_cast_map;
int arraysize;
PyObject* lastrowid;
PyObject* rowcount;
PyObject* row_factory;
Statement* statement;
/* the next row to be returned, NULL if no next row available */
PyObject* next_row;
} Cursor;
typedef enum {
STATEMENT_INVALID, STATEMENT_INSERT, STATEMENT_DELETE,
STATEMENT_UPDATE, STATEMENT_REPLACE, STATEMENT_SELECT,
STATEMENT_OTHER
} StatementKind;
extern PyTypeObject CursorType;
int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs);
void cursor_dealloc(Cursor* self);
PyObject* cursor_execute(Cursor* self, PyObject* args);
PyObject* cursor_executemany(Cursor* self, PyObject* args);
PyObject* cursor_getiter(Cursor *self);
PyObject* cursor_iternext(Cursor *self);
PyObject* cursor_fetchone(Cursor* self, PyObject* args);
PyObject* cursor_fetchmany(Cursor* self, PyObject* args);
PyObject* cursor_fetchall(Cursor* self, PyObject* args);
PyObject* pysqlite_noop(Connection* self, PyObject* args);
PyObject* cursor_close(Cursor* self, PyObject* args);
int cursor_setup_types(void);
#define UNKNOWN (-1)
#endif

View file

@ -0,0 +1,142 @@
/* 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 <structmember.h>
#include "cursor.h"
#include "microprotocols.h"
#include "prepare_protocol.h"
/** the adapters registry **/
PyObject *psyco_adapters;
/* microprotocols_init - initialize the adapters dictionary */
int
microprotocols_init(PyObject *dict)
{
/* create adapters dictionary and put it in module namespace */
if ((psyco_adapters = PyDict_New()) == NULL) {
return -1;
}
return PyDict_SetItemString(dict, "adapters", psyco_adapters);
}
/* microprotocols_add - add a reverse type-caster to the dictionary */
int
microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
{
PyObject* key;
int rc;
if (proto == NULL) proto = (PyObject*)&SQLitePrepareProtocolType;
key = Py_BuildValue("(OO)", (PyObject*)type, proto);
if (!key) {
return -1;
}
rc = PyDict_SetItem(psyco_adapters, key, cast);
Py_DECREF(key);
return rc;
}
/* microprotocols_adapt - adapt an object to the built-in protocol */
PyObject *
microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
{
PyObject *adapter, *key;
/* we don't check for exact type conformance as specified in PEP 246
because the SQLitePrepareProtocolType 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*)obj->ob_type, proto);
if (!key) {
return NULL;
}
adapter = PyDict_GetItem(psyco_adapters, key);
Py_DECREF(key);
if (adapter) {
PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
return adapted;
}
/* try to have the protocol adapt this object*/
if (PyObject_HasAttrString(proto, "__adapt__")) {
PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj);
if (adapted) {
if (adapted != Py_None) {
return adapted;
} else {
Py_DECREF(adapted);
}
}
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
return NULL;
}
/* and finally try to have the object adapt itself */
if (PyObject_HasAttrString(obj, "__conform__")) {
PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto);
if (adapted) {
if (adapted != Py_None) {
return adapted;
} else {
Py_DECREF(adapted);
}
}
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
return NULL;
}
}
/* else set the right exception and return NULL */
PyErr_SetString(ProgrammingError, "can't adapt");
return NULL;
}
/** module-level functions **/
PyObject *
psyco_microprotocols_adapt(Cursor *self, PyObject *args)
{
PyObject *obj, *alt = NULL;
PyObject *proto = (PyObject*)&SQLitePrepareProtocolType;
if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL;
return microprotocols_adapt(obj, proto, alt);
}

View file

@ -0,0 +1,59 @@
/* microprotocols.c - definitions for minimalist and non-validating protocols
*
* 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.
*/
#ifndef PSYCOPG_MICROPROTOCOLS_H
#define PSYCOPG_MICROPROTOCOLS_H 1
#include <Python.h>
#ifdef __cplusplus
extern "C" {
#endif
/** adapters registry **/
extern PyObject *psyco_adapters;
/** the names of the three mandatory methods **/
#define MICROPROTOCOLS_GETQUOTED_NAME "getquoted"
#define MICROPROTOCOLS_GETSTRING_NAME "getstring"
#define MICROPROTOCOLS_GETBINARY_NAME "getbinary"
/** exported functions **/
/* used by module.c to init the microprotocols system */
extern int microprotocols_init(PyObject *dict);
extern int microprotocols_add(
PyTypeObject *type, PyObject *proto, PyObject *cast);
extern PyObject *microprotocols_adapt(
PyObject *obj, PyObject *proto, PyObject *alt);
extern PyObject *
psyco_microprotocols_adapt(Cursor* self, PyObject *args);
#define psyco_microprotocols_adapt_doc \
"adapt(obj, protocol, alternate) -> adapt obj to given protocol"
#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */

325
Modules/_sqlite/module.c Normal file
View file

@ -0,0 +1,325 @@
/* module.c - the module itself
*
* Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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 "connection.h"
#include "statement.h"
#include "cursor.h"
#include "cache.h"
#include "prepare_protocol.h"
#include "microprotocols.h"
#include "row.h"
#if SQLITE_VERSION_NUMBER >= 3003003
#define HAVE_SHARED_CACHE
#endif
/* static objects at module-level */
PyObject* Error, *Warning, *InterfaceError, *DatabaseError, *InternalError,
*OperationalError, *ProgrammingError, *IntegrityError, *DataError,
*NotSupportedError, *OptimizedUnicode;
PyObject* converters;
static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
kwargs)
{
/* Python seems to have no way of extracting a single keyword-arg at
* C-level, so this code is redundant with the one in connection_init in
* connection.c and must always be copied from there ... */
static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
char* database;
int detect_types = 0;
PyObject* isolation_level;
PyObject* factory = NULL;
int check_same_thread = 1;
int cached_statements;
double timeout = 5.0;
PyObject* result;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
&database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
{
return NULL;
}
if (factory == NULL) {
factory = (PyObject*)&ConnectionType;
}
result = PyObject_Call(factory, args, kwargs);
return result;
}
static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
kwargs)
{
static char *kwlist[] = {"statement", NULL, NULL};
char* statement;
PyObject* result;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement))
{
return NULL;
}
if (sqlite3_complete(statement)) {
result = Py_True;
} else {
result = Py_False;
}
Py_INCREF(result);
return result;
}
#ifdef HAVE_SHARED_CACHE
static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
kwargs)
{
static char *kwlist[] = {"do_enable", NULL, NULL};
int do_enable;
int rc;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable))
{
return NULL;
}
rc = sqlite3_enable_shared_cache(do_enable);
if (rc != SQLITE_OK) {
PyErr_SetString(OperationalError, "Changing the shared_cache flag failed");
return NULL;
} else {
Py_INCREF(Py_None);
return Py_None;
}
}
#endif /* HAVE_SHARED_CACHE */
static PyObject* module_register_adapter(PyObject* self, PyObject* args, PyObject* kwargs)
{
PyTypeObject* type;
PyObject* caster;
if (!PyArg_ParseTuple(args, "OO", &type, &caster)) {
return NULL;
}
microprotocols_add(type, (PyObject*)&SQLitePrepareProtocolType, caster);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObject* kwargs)
{
PyObject* name;
PyObject* callable;
if (!PyArg_ParseTuple(args, "OO", &name, &callable)) {
return NULL;
}
if (PyDict_SetItem(converters, name, callable) != 0) {
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
void converters_init(PyObject* dict)
{
converters = PyDict_New();
if (!converters) {
return;
}
PyDict_SetItemString(dict, "converters", converters);
}
static PyMethodDef module_methods[] = {
{"connect", (PyCFunction)module_connect, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a connection.")},
{"complete_statement", (PyCFunction)module_complete, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement.")},
#ifdef HAVE_SHARED_CACHE
{"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread.")},
#endif
{"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with sqlite's adapter registry.")},
{"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with sqlite.")},
{"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
{NULL, NULL}
};
PyMODINIT_FUNC init_sqlite3(void)
{
PyObject *module, *dict;
PyObject *tmp_obj;
module = Py_InitModule("_sqlite3", module_methods);
if (!module ||
(row_setup_types() < 0) ||
(cursor_setup_types() < 0) ||
(connection_setup_types() < 0) ||
(cache_setup_types() < 0) ||
(statement_setup_types() < 0) ||
(prepare_protocol_setup_types() < 0)
) {
return;
}
Py_INCREF(&ConnectionType);
PyModule_AddObject(module, "Connection", (PyObject*) &ConnectionType);
Py_INCREF(&CursorType);
PyModule_AddObject(module, "Cursor", (PyObject*) &CursorType);
Py_INCREF(&CacheType);
PyModule_AddObject(module, "Statement", (PyObject*)&StatementType);
Py_INCREF(&StatementType);
PyModule_AddObject(module, "Cache", (PyObject*) &CacheType);
Py_INCREF(&SQLitePrepareProtocolType);
PyModule_AddObject(module, "PrepareProtocol", (PyObject*) &SQLitePrepareProtocolType);
Py_INCREF(&RowType);
PyModule_AddObject(module, "Row", (PyObject*) &RowType);
if (!(dict = PyModule_GetDict(module))) {
goto error;
}
/*** Create DB-API Exception hierarchy */
if (!(Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_StandardError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "Error", Error);
if (!(Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_StandardError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "Warning", Warning);
/* Error subclasses */
if (!(InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", Error, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
if (!(DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", Error, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
/* DatabaseError subclasses */
if (!(InternalError = PyErr_NewException(MODULE_NAME ".InternalError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "InternalError", InternalError);
if (!(OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "OperationalError", OperationalError);
if (!(ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
if (!(IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", DatabaseError,NULL))) {
goto error;
}
PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
if (!(DataError = PyErr_NewException(MODULE_NAME ".DataError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "DataError", DataError);
if (!(NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
/* We just need "something" unique for OptimizedUnicode. It does not really
* need to be a string subclass. Just anything that can act as a special
* marker for us. So I pulled PyCell_Type out of my magic hat.
*/
Py_INCREF((PyObject*)&PyCell_Type);
OptimizedUnicode = (PyObject*)&PyCell_Type;
PyDict_SetItemString(dict, "OptimizedUnicode", OptimizedUnicode);
if (!(tmp_obj = PyInt_FromLong(PARSE_DECLTYPES))) {
goto error;
}
PyDict_SetItemString(dict, "PARSE_DECLTYPES", tmp_obj);
if (!(tmp_obj = PyInt_FromLong(PARSE_COLNAMES))) {
goto error;
}
PyDict_SetItemString(dict, "PARSE_COLNAMES", tmp_obj);
if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) {
goto error;
}
PyDict_SetItemString(dict, "version", tmp_obj);
if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) {
goto error;
}
PyDict_SetItemString(dict, "sqlite_version", tmp_obj);
/* initialize microprotocols layer */
microprotocols_init(dict);
/* initialize the default converters */
converters_init(dict);
/* Original comment form _bsddb.c in the Python core. This is also still
* needed nowadays for Python 2.3/2.4.
*
* PyEval_InitThreads is called here due to a quirk in python 1.5
* - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
* The global interepreter lock is not initialized until the first
* thread is created using thread.start_new_thread() or fork() is
* called. that would cause the ALLOW_THREADS here to segfault due
* to a null pointer reference if no threads or child processes
* have been created. This works around that and is a no-op if
* threads have already been initialized.
* (see pybsddb-users mailing list post on 2002-08-07)
*/
PyEval_InitThreads();
error:
if (PyErr_Occurred())
{
PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed");
}
}

55
Modules/_sqlite/module.h Normal file
View file

@ -0,0 +1,55 @@
/* module.h - definitions for the module
*
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_MODULE_H
#define PYSQLITE_MODULE_H
#include "Python.h"
#define PYSQLITE_VERSION "2.2.0"
extern PyObject* Error;
extern PyObject* Warning;
extern PyObject* InterfaceError;
extern PyObject* DatabaseError;
extern PyObject* InternalError;
extern PyObject* OperationalError;
extern PyObject* ProgrammingError;
extern PyObject* IntegrityError;
extern PyObject* DataError;
extern PyObject* NotSupportedError;
extern PyObject* OptimizedUnicode;
/* the functions time.time() and time.sleep() */
extern PyObject* time_time;
extern PyObject* time_sleep;
/* A dictionary, mapping colum types (INTEGER, VARCHAR, etc.) to converter
* functions, that convert the SQL value to the appropriate Python value.
* The key is uppercase.
*/
extern PyObject* converters;
#define PARSE_DECLTYPES 1
#define PARSE_COLNAMES 2
#endif

View file

@ -0,0 +1,84 @@
/* prepare_protocol.c - the protocol for preparing values for SQLite
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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 "prepare_protocol.h"
int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs)
{
return 0;
}
void prepare_protocol_dealloc(SQLitePrepareProtocol* self)
{
self->ob_type->tp_free((PyObject*)self);
}
PyTypeObject SQLitePrepareProtocolType= {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME ".PrepareProtocol", /* tp_name */
sizeof(SQLitePrepareProtocol), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)prepare_protocol_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)prepare_protocol_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
extern int prepare_protocol_setup_types(void)
{
SQLitePrepareProtocolType.tp_new = PyType_GenericNew;
SQLitePrepareProtocolType.ob_type= &PyType_Type;
return PyType_Ready(&SQLitePrepareProtocolType);
}

View file

@ -0,0 +1,41 @@
/* prepare_protocol.h - the protocol for preparing values for SQLite
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_PREPARE_PROTOCOL_H
#define PYSQLITE_PREPARE_PROTOCOL_H
#include "Python.h"
typedef struct
{
PyObject_HEAD
} SQLitePrepareProtocol;
extern PyTypeObject SQLitePrepareProtocolType;
int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs);
void prepare_protocol_dealloc(SQLitePrepareProtocol* self);
int prepare_protocol_setup_types(void);
#define UNKNOWN (-1)
#endif

202
Modules/_sqlite/row.c Normal file
View file

@ -0,0 +1,202 @@
/* row.c - an enhanced tuple for database rows
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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 "row.h"
#include "cursor.h"
#include "sqlitecompat.h"
void row_dealloc(Row* self)
{
Py_XDECREF(self->data);
Py_XDECREF(self->description);
self->ob_type->tp_free((PyObject*)self);
}
int row_init(Row* self, PyObject* args, PyObject* kwargs)
{
PyObject* data;
Cursor* cursor;
self->data = 0;
self->description = 0;
if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) {
return -1;
}
if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&CursorType)) {
PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
return -1;
}
if (!PyTuple_Check(data)) {
PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
return -1;
}
Py_INCREF(data);
self->data = data;
Py_INCREF(cursor->description);
self->description = cursor->description;
return 0;
}
PyObject* row_subscript(Row* self, PyObject* idx)
{
long _idx;
char* key;
int nitems, i;
char* compare_key;
char* p1;
char* p2;
PyObject* item;
if (PyInt_Check(idx)) {
_idx = PyInt_AsLong(idx);
item = PyTuple_GetItem(self->data, _idx);
Py_XINCREF(item);
return item;
} else if (PyLong_Check(idx)) {
_idx = PyLong_AsLong(idx);
item = PyTuple_GetItem(self->data, _idx);
Py_XINCREF(item);
return item;
} else if (PyString_Check(idx)) {
key = PyString_AsString(idx);
nitems = PyTuple_Size(self->description);
for (i = 0; i < nitems; i++) {
compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0));
if (!compare_key) {
return NULL;
}
p1 = key;
p2 = compare_key;
while (1) {
if ((*p1 == (char)0) || (*p2 == (char)0)) {
break;
}
if ((*p1 | 0x20) != (*p2 | 0x20)) {
break;
}
p1++;
p2++;
}
if ((*p1 == (char)0) && (*p2 == (char)0)) {
/* found item */
item = PyTuple_GetItem(self->data, i);
Py_INCREF(item);
return item;
}
}
PyErr_SetString(PyExc_IndexError, "No item with that key");
return NULL;
} else if (PySlice_Check(idx)) {
PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");
return NULL;
} else {
PyErr_SetString(PyExc_IndexError, "Index must be int or string");
return NULL;
}
}
Py_ssize_t row_length(Row* self, PyObject* args, PyObject* kwargs)
{
return PyTuple_GET_SIZE(self->data);
}
static int row_print(Row* self, FILE *fp, int flags)
{
return (&PyTuple_Type)->tp_print(self->data, fp, flags);
}
PyMappingMethods row_as_mapping = {
/* mp_length */ (lenfunc)row_length,
/* mp_subscript */ (binaryfunc)row_subscript,
/* mp_ass_subscript */ (objobjargproc)0,
};
PyTypeObject RowType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME ".Row", /* tp_name */
sizeof(Row), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)row_dealloc, /* tp_dealloc */
(printfunc)row_print, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)row_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
extern int row_setup_types(void)
{
RowType.tp_new = PyType_GenericNew;
RowType.tp_as_mapping = &row_as_mapping;
return PyType_Ready(&RowType);
}

39
Modules/_sqlite/row.h Normal file
View file

@ -0,0 +1,39 @@
/* row.h - an enhanced tuple for database rows
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_ROW_H
#define PYSQLITE_ROW_H
#include "Python.h"
typedef struct _Row
{
PyObject_HEAD
PyObject* data;
PyObject* description;
} Row;
extern PyTypeObject RowType;
int row_setup_types(void);
#endif

View file

@ -0,0 +1,34 @@
/* sqlitecompat.h - compatibility macros
*
* Copyright (C) 2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_COMPAT_H
#define PYSQLITE_COMPAT_H
/* define Py_ssize_t for pre-2.5 versions of Python */
#if PY_VERSION_HEX < 0x02050000
typedef int Py_ssize_t;
typedef int (*lenfunc)(PyObject*);
#endif
#endif

427
Modules/_sqlite/statement.c Normal file
View file

@ -0,0 +1,427 @@
/* statement.c - the statement type
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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 "statement.h"
#include "cursor.h"
#include "connection.h"
#include "microprotocols.h"
#include "prepare_protocol.h"
#include "sqlitecompat.h"
/* prototypes */
int check_remaining_sql(const char* tail);
typedef enum {
LINECOMMENT_1,
IN_LINECOMMENT,
COMMENTSTART_1,
IN_COMMENT,
COMMENTEND_1,
NORMAL
} parse_remaining_sql_state;
int statement_create(Statement* self, Connection* connection, PyObject* sql)
{
const char* tail;
int rc;
PyObject* sql_str;
char* sql_cstr;
self->st = NULL;
self->in_use = 0;
if (PyString_Check(sql)) {
sql_str = sql;
Py_INCREF(sql_str);
} else if (PyUnicode_Check(sql)) {
sql_str = PyUnicode_AsUTF8String(sql);
if (!sql_str) {
rc = PYSQLITE_SQL_WRONG_TYPE;
return rc;
}
} else {
rc = PYSQLITE_SQL_WRONG_TYPE;
return rc;
}
self->sql = sql_str;
sql_cstr = PyString_AsString(sql_str);
rc = sqlite3_prepare(connection->db,
sql_cstr,
-1,
&self->st,
&tail);
self->db = connection->db;
if (rc == SQLITE_OK && check_remaining_sql(tail)) {
(void)sqlite3_finalize(self->st);
self->st = NULL;
rc = PYSQLITE_TOO_MUCH_SQL;
}
return rc;
}
int statement_bind_parameter(Statement* self, int pos, PyObject* parameter)
{
int rc = SQLITE_OK;
long longval;
#ifdef HAVE_LONG_LONG
PY_LONG_LONG longlongval;
#endif
const char* buffer;
char* string;
Py_ssize_t buflen;
PyObject* stringval;
if (parameter == Py_None) {
rc = sqlite3_bind_null(self->st, pos);
} else if (PyInt_Check(parameter)) {
longval = PyInt_AsLong(parameter);
rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval);
#ifdef HAVE_LONG_LONG
} else if (PyLong_Check(parameter)) {
longlongval = PyLong_AsLongLong(parameter);
/* in the overflow error case, longlongval is -1, and an exception is set */
rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval);
#endif
} else if (PyFloat_Check(parameter)) {
rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
} else if (PyBuffer_Check(parameter)) {
if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) {
rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT);
} else {
PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
rc = -1;
}
} else if PyString_Check(parameter) {
string = PyString_AsString(parameter);
rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
} else if PyUnicode_Check(parameter) {
stringval = PyUnicode_AsUTF8String(parameter);
string = PyString_AsString(stringval);
rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
Py_DECREF(stringval);
} else {
rc = -1;
}
return rc;
}
void statement_bind_parameters(Statement* self, PyObject* parameters)
{
PyObject* current_param;
PyObject* adapted;
const char* binding_name;
int i;
int rc;
int num_params_needed;
int num_params;
Py_BEGIN_ALLOW_THREADS
num_params_needed = sqlite3_bind_parameter_count(self->st);
Py_END_ALLOW_THREADS
if (PyDict_Check(parameters)) {
/* parameters passed as dictionary */
for (i = 1; i <= num_params_needed; i++) {
Py_BEGIN_ALLOW_THREADS
binding_name = sqlite3_bind_parameter_name(self->st, i);
Py_END_ALLOW_THREADS
if (!binding_name) {
PyErr_Format(ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i);
return;
}
binding_name++; /* skip first char (the colon) */
current_param = PyDict_GetItemString(parameters, binding_name);
if (!current_param) {
PyErr_Format(ProgrammingError, "You did not supply a value for binding %d.", i);
return;
}
Py_INCREF(current_param);
adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
if (adapted) {
Py_DECREF(current_param);
} else {
PyErr_Clear();
adapted = current_param;
}
rc = statement_bind_parameter(self, i, adapted);
Py_DECREF(adapted);
if (rc != SQLITE_OK) {
PyErr_Format(InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name);
return;
}
}
} else {
/* parameters passed as sequence */
num_params = PySequence_Length(parameters);
if (num_params != num_params_needed) {
PyErr_Format(ProgrammingError, "Incorrect number of bindings supplied. The current statement uses %d, and there are %d supplied.",
num_params_needed, num_params);
return;
}
for (i = 0; i < num_params; i++) {
current_param = PySequence_GetItem(parameters, i);
if (!current_param) {
return;
}
adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
if (adapted) {
Py_DECREF(current_param);
} else {
PyErr_Clear();
adapted = current_param;
}
rc = statement_bind_parameter(self, i + 1, adapted);
Py_DECREF(adapted);
if (rc != SQLITE_OK) {
PyErr_Format(InterfaceError, "Error binding parameter %d - probably unsupported type.", i);
return;
}
}
}
}
int statement_recompile(Statement* self, PyObject* params)
{
const char* tail;
int rc;
char* sql_cstr;
sqlite3_stmt* new_st;
sql_cstr = PyString_AsString(self->sql);
rc = sqlite3_prepare(self->db,
sql_cstr,
-1,
&new_st,
&tail);
if (rc == SQLITE_OK) {
/* The efficient sqlite3_transfer_bindings is only available in SQLite
* version 3.2.2 or later. For older SQLite releases, that might not
* even define SQLITE_VERSION_NUMBER, we do it the manual way.
*/
#ifdef SQLITE_VERSION_NUMBER
#if SQLITE_VERSION_NUMBER >= 3002002
(void)sqlite3_transfer_bindings(self->st, new_st);
#endif
#else
statement_bind_parameters(self, params);
#endif
(void)sqlite3_finalize(self->st);
self->st = new_st;
}
return rc;
}
int statement_finalize(Statement* self)
{
int rc;
rc = SQLITE_OK;
if (self->st) {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_finalize(self->st);
Py_END_ALLOW_THREADS
self->st = NULL;
}
self->in_use = 0;
return rc;
}
int statement_reset(Statement* self)
{
int rc;
rc = SQLITE_OK;
if (self->in_use && self->st) {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_reset(self->st);
Py_END_ALLOW_THREADS
if (rc == SQLITE_OK) {
self->in_use = 0;
}
}
return rc;
}
void statement_mark_dirty(Statement* self)
{
self->in_use = 1;
}
void statement_dealloc(Statement* self)
{
int rc;
if (self->st) {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_finalize(self->st);
Py_END_ALLOW_THREADS
}
self->st = NULL;
Py_XDECREF(self->sql);
self->ob_type->tp_free((PyObject*)self);
}
/*
* Checks if there is anything left in an SQL string after SQLite compiled it.
* This is used to check if somebody tried to execute more than one SQL command
* with one execute()/executemany() command, which the DB-API and we don't
* allow.
*
* Returns 1 if there is more left than should be. 0 if ok.
*/
int check_remaining_sql(const char* tail)
{
const char* pos = tail;
parse_remaining_sql_state state = NORMAL;
for (;;) {
switch (*pos) {
case 0:
return 0;
case '-':
if (state == NORMAL) {
state = LINECOMMENT_1;
} else if (state == LINECOMMENT_1) {
state = IN_LINECOMMENT;
}
break;
case ' ':
case '\t':
break;
case '\n':
case 13:
if (state == IN_LINECOMMENT) {
state = NORMAL;
}
break;
case '/':
if (state == NORMAL) {
state = COMMENTSTART_1;
} else if (state == COMMENTEND_1) {
state = NORMAL;
} else if (state == COMMENTSTART_1) {
return 1;
}
break;
case '*':
if (state == NORMAL) {
return 1;
} else if (state == LINECOMMENT_1) {
return 1;
} else if (state == COMMENTSTART_1) {
state = IN_COMMENT;
} else if (state == IN_COMMENT) {
state = COMMENTEND_1;
}
break;
default:
if (state == COMMENTEND_1) {
state = IN_COMMENT;
} else if (state == IN_LINECOMMENT) {
} else if (state == IN_COMMENT) {
} else {
return 1;
}
}
pos++;
}
return 0;
}
PyTypeObject StatementType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME ".Statement", /* tp_name */
sizeof(Statement), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)statement_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
extern int statement_setup_types(void)
{
StatementType.tp_new = PyType_GenericNew;
return PyType_Ready(&StatementType);
}

View file

@ -0,0 +1,58 @@
/* statement.h - definitions for the statement type
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_STATEMENT_H
#define PYSQLITE_STATEMENT_H
#include "Python.h"
#include "connection.h"
#include "sqlite3.h"
#define PYSQLITE_TOO_MUCH_SQL (-100)
#define PYSQLITE_SQL_WRONG_TYPE (-101)
typedef struct
{
PyObject_HEAD
sqlite3* db;
sqlite3_stmt* st;
PyObject* sql;
int in_use;
} Statement;
extern PyTypeObject StatementType;
int statement_create(Statement* self, Connection* connection, PyObject* sql);
void statement_dealloc(Statement* self);
int statement_bind_parameter(Statement* self, int pos, PyObject* parameter);
void statement_bind_parameters(Statement* self, PyObject* parameters);
int statement_recompile(Statement* self, PyObject* parameters);
int statement_finalize(Statement* self);
int statement_reset(Statement* self);
void statement_mark_dirty(Statement* self);
int statement_setup_types(void);
#endif

96
Modules/_sqlite/util.c Normal file
View file

@ -0,0 +1,96 @@
/* util.c - various utility functions
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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 "module.h"
#include "connection.h"
int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection
)
{
int rc;
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_step(statement);
Py_END_ALLOW_THREADS
return rc;
}
/**
* Checks the SQLite error code and sets the appropriate DB-API exception.
* Returns the error code (0 means no error occured).
*/
int _seterror(sqlite3* db)
{
int errorcode;
errorcode = sqlite3_errcode(db);
switch (errorcode)
{
case SQLITE_OK:
PyErr_Clear();
break;
case SQLITE_INTERNAL:
case SQLITE_NOTFOUND:
PyErr_SetString(InternalError, sqlite3_errmsg(db));
break;
case SQLITE_NOMEM:
(void)PyErr_NoMemory();
break;
case SQLITE_ERROR:
case SQLITE_PERM:
case SQLITE_ABORT:
case SQLITE_BUSY:
case SQLITE_LOCKED:
case SQLITE_READONLY:
case SQLITE_INTERRUPT:
case SQLITE_IOERR:
case SQLITE_FULL:
case SQLITE_CANTOPEN:
case SQLITE_PROTOCOL:
case SQLITE_EMPTY:
case SQLITE_SCHEMA:
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
break;
case SQLITE_CORRUPT:
PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
break;
case SQLITE_TOOBIG:
PyErr_SetString(DataError, sqlite3_errmsg(db));
break;
case SQLITE_CONSTRAINT:
case SQLITE_MISMATCH:
PyErr_SetString(IntegrityError, sqlite3_errmsg(db));
break;
case SQLITE_MISUSE:
PyErr_SetString(ProgrammingError, sqlite3_errmsg(db));
break;
default:
PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
break;
}
return errorcode;
}

38
Modules/_sqlite/util.h Normal file
View file

@ -0,0 +1,38 @@
/* util.h - various utility functions
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* 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.
*/
#ifndef PYSQLITE_UTIL_H
#define PYSQLITE_UTIL_H
#include "Python.h"
#include "pythread.h"
#include "sqlite3.h"
#include "connection.h"
int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection);
/**
* Checks the SQLite error code and sets the appropriate DB-API exception.
* Returns the error code (0 means no error occured).
*/
int _seterror(sqlite3* db);
#endif