summaryrefslogtreecommitdiff
path: root/src/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/connection.c')
-rw-r--r--src/connection.c90
1 files changed, 88 insertions, 2 deletions
diff --git a/src/connection.c b/src/connection.c
index 7e4e96c..115d15a 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -30,6 +30,8 @@
#include "util.h"
#include "sqlitecompat.h"
+#include "blob.h"
+
#ifdef PYSQLITE_EXPERIMENTAL
#include "backup.h"
#endif
@@ -91,6 +93,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
self->statement_cache = NULL;
self->statements = NULL;
self->cursors = NULL;
+ self->blobs = NULL;
Py_INCREF(Py_None);
self->row_factory = Py_None;
@@ -167,10 +170,12 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
self->created_statements = 0;
self->created_cursors = 0;
- /* Create lists of weak references to statements/cursors */
+ /* Create lists of weak references to statements/cursors/blobs */
self->statements = PyList_New(0);
self->cursors = PyList_New(0);
- if (!self->statements || !self->cursors) {
+ self->blobs = PyList_New(0);
+
+ if (!self->statements || !self->cursors || !self->blobs) {
return -1;
}
@@ -293,6 +298,7 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self)
Py_XDECREF(self->collations);
Py_XDECREF(self->statements);
Py_XDECREF(self->cursors);
+ Py_XDECREF(self->blobs);
self->ob_type->tp_free((PyObject*)self);
}
@@ -390,6 +396,82 @@ PyObject* pysqlite_connection_backup(pysqlite_Connection* self, PyObject* args,
}
#endif
+PyObject* pysqlite_connection_blob(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
+{
+ static char *kwlist[] = {"table", "column", "row", "flags", "dbname", NULL, NULL};
+ int rc;
+ const char *dbname = "main", *table, *column;
+ sqlite3_int64 row;
+ int flags = 0;
+ sqlite3_blob* blob;
+ pysqlite_Blob *pyblob=0;
+ PyObject *weakref;
+
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssL|is", kwlist,
+ &table, &column, &row, &flags, &dbname)) {
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_blob_open(self->db, dbname, table, column, row, flags, &blob);
+ Py_END_ALLOW_THREADS
+
+ if (rc != SQLITE_OK) {
+ _pysqlite_seterror(self->db, NULL);
+ return NULL;
+ }
+
+ pyblob = PyObject_New(pysqlite_Blob, &pysqlite_BlobType);
+ if (!pyblob){
+ goto error;
+ }
+
+ rc = pysqlite_blob_init(pyblob, self, blob);
+ if (rc) {
+ Py_CLEAR(pyblob);
+ goto error;
+ }
+
+ // Add our blob to connection blobs list
+ weakref=PyWeakref_NewRef((PyObject*)pyblob, NULL);
+ if (!weakref){
+ Py_CLEAR(pyblob);
+ goto error;
+ }
+ if (PyList_Append(self->blobs, weakref) != 0) {
+ Py_CLEAR(pyblob);
+ Py_CLEAR(weakref);
+ goto error;
+ }
+ Py_DECREF(weakref);
+
+ return (PyObject*)pyblob;
+
+error:
+ Py_BEGIN_ALLOW_THREADS
+ sqlite3_blob_close(blob);
+ Py_END_ALLOW_THREADS
+ return NULL;
+}
+
+
+void pysqlite_close_all_blobs(pysqlite_Connection* self)
+{
+ int i;
+ PyObject* weakref;
+ PyObject* blob;
+
+ for (i = 0; i < PyList_Size(self->blobs); i++) {
+ weakref = PyList_GetItem(self->blobs, i);
+ blob = PyWeakref_GetObject(weakref);
+ if (blob != Py_None) {
+ pysqlite_blob_close((pysqlite_Blob*)blob);
+ }
+ }
+}
+
+
PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args)
{
PyObject* ret;
@@ -401,6 +483,8 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args)
pysqlite_do_all_statements(self, ACTION_FINALIZE, 1);
+ pysqlite_close_all_blobs(self);
+
if (self->db) {
if (self->apsw_connection) {
ret = PyObject_CallMethod(self->apsw_connection, "close", "");
@@ -1597,6 +1681,8 @@ static PyMethodDef connection_methods[] = {
{"backup", (PyCFunction)pysqlite_connection_backup, METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("Backup database.")},
#endif
+ {"blob", (PyCFunction)pysqlite_connection_blob, METH_VARARGS|METH_KEYWORDS,
+ PyDoc_STR("return a blob object")},
{"cursor", (PyCFunction)pysqlite_connection_cursor, METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("Return a cursor for the connection.")},
{"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS,