Skip to content

Commit

Permalink
Closes #81. Switch to sqlite3_open_v2. The flags parameter is now
Browse files Browse the repository at this point in the history
exposed. You can use it to modify the behaviour of the opened database
connection, for example opening a database file in read-only mode or
enable URI mode.
  • Loading branch information
ghaering committed Aug 23, 2015
1 parent da38987 commit 46d999e
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 8 deletions.
8 changes: 7 additions & 1 deletion doc/sphinx/sqlite3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ Module functions and constants
first blank for the column name: the column name would simply be "x".


.. function:: connect(database[, timeout, isolation_level, detect_types, factory])
.. function:: connect(database[, timeout, isolation_level, detect_types, factory, flags])

Opens a connection to the SQLite database file *database*. You can use
``":memory:"`` to open a database connection to a database that resides in RAM
Expand Down Expand Up @@ -172,6 +172,12 @@ Module functions and constants
for the connection, you can set the *cached_statements* parameter. The currently
implemented default is to cache 100 statements.

The *flags* parameter can be set to change the behaviour of the wrapped
sqlite3_open_v2 call. It defaults to *SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE*. Please consult the SQLite documentation for the
possible values: https://www.sqlite.org/c3ref/open.html



.. function:: register_converter(typename, callable)

Expand Down
5 changes: 5 additions & 0 deletions lib/test/dbapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ def CheckExceptions(self):
self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)

def CheckOpenFlags(self):
con = sqlite.connect(":memory:", flags=sqlite.SQLITE_OPEN_READONLY)
# exception will be raised because of readonly database
self.assertRaises(sqlite.OperationalError, con.execute, "create table test(foo)")

class CursorTests(unittest.TestCase):
def setUp(self):
self.cx = sqlite.connect(":memory:")
Expand Down
9 changes: 5 additions & 4 deletions src/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self);

int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
{
static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "flags", NULL, NULL};

PyObject* database;
int detect_types = 0;
Expand All @@ -59,11 +59,12 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
int check_same_thread = 1;
int cached_statements = 100;
double timeout = 5.0;
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
int rc;
PyObject* database_utf8;

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist,
&database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOii", kwlist,
&database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements, &flags))
{
return -1;
}
Expand Down Expand Up @@ -94,7 +95,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
}

Py_BEGIN_ALLOW_THREADS
rc = sqlite3_open(PyString_AsString(database_utf8), &self->db);
rc = sqlite3_open_v2(PyString_AsString(database_utf8), &self->db, flags, NULL);
Py_END_ALLOW_THREADS

Py_DECREF(database_utf8);
Expand Down
7 changes: 4 additions & 3 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,20 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
* 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};
static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "flags", NULL, NULL};
PyObject* database;
int detect_types = 0;
PyObject* isolation_level;
PyObject* factory = NULL;
int check_same_thread = 1;
int cached_statements;
double timeout = 5.0;
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;

PyObject* result;

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOi", kwlist,
&database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOii", kwlist,
&database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements, &flags))
{
return NULL;
}
Expand Down

0 comments on commit 46d999e

Please sign in to comment.