[Python-checkins] cpython: Issue #13773: sqlite3.connect() gets a new `uri` parameter to pass the filename

antoine.pitrou python-checkins at python.org
Sun Feb 10 00:06:57 CET 2013


http://hg.python.org/cpython/rev/f13bb1e40fbc
changeset: 82113:f13bb1e40fbc
user: Antoine Pitrou <solipsis at pitrou.net>
date: Sun Feb 10 00:02:44 2013 +0100
summary:
 Issue #13773: sqlite3.connect() gets a new `uri` parameter to pass the filename as a URI, allowing to pass custom options.
files:
 Doc/library/sqlite3.rst | 14 +++++++++++++-
 Lib/sqlite3/test/dbapi.py | 18 ++++++++++++++++++
 Misc/NEWS | 3 +++
 Modules/_sqlite/connection.c | 24 +++++++++++++++++++++---
 Modules/_sqlite/module.c | 16 ++++++++++++----
 5 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst
--- a/Doc/library/sqlite3.rst
+++ b/Doc/library/sqlite3.rst
@@ -159,7 +159,7 @@
 first blank for the column name: the column name would simply be "x".
 
 
-.. function:: connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements])
+.. function:: connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri])
 
 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
@@ -195,6 +195,18 @@
 for the connection, you can set the *cached_statements* parameter. The currently
 implemented default is to cache 100 statements.
 
+ If *uri* is true, *database* is interpreted as a URI. This allows you
+ to specify options. For example, to open a database in read-only mode
+ you can use::
+
+ db = sqlite3.connect('file:path/to/database?mode=ro', uri=True)
+
+ More information about this feature, including a list of recognized options, can
+ be found in the `SQLite URI documentation <http://www.sqlite.org/uri.html>`_.
+
+ .. versionchanged:: 3.4
+ Added the *uri* parameter.
+
 
 .. function:: register_converter(typename, callable)
 
diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py
--- a/Lib/sqlite3/test/dbapi.py
+++ b/Lib/sqlite3/test/dbapi.py
@@ -28,6 +28,9 @@
 except ImportError:
 threading = None
 
+from test.support import TESTFN, unlink
+
+
 class ModuleTests(unittest.TestCase):
 def CheckAPILevel(self):
 self.assertEqual(sqlite.apilevel, "2.0",
@@ -163,6 +166,21 @@
 with self.assertRaises(AttributeError):
 self.cx.in_transaction = True
 
+ def CheckOpenUri(self):
+ if sqlite.sqlite_version_info < (3, 7, 7):
+ with self.assertRaises(sqlite.NotSupportedError):
+ sqlite.connect(':memory:', uri=True)
+ return
+ self.addCleanup(unlink, TESTFN)
+ with sqlite.connect(TESTFN) as cx:
+ cx.execute('create table test(id integer)')
+ with sqlite.connect('file:' + TESTFN, uri=True) as cx:
+ cx.execute('insert into test(id) values(0)')
+ with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
+ with self.assertRaises(sqlite.OperationalError):
+ cx.execute('insert into test(id) values(1)')
+
+
 class CursorTests(unittest.TestCase):
 def setUp(self):
 self.cx = sqlite.connect(":memory:")
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -244,6 +244,9 @@
 Library
 -------
 
+- Issue #13773: sqlite3.connect() gets a new `uri` parameter to pass the
+ filename as a URI, allowing to pass custom options.
+
 - Issue #17156: pygettext.py now uses an encoding of source file and correctly
 writes and escapes non-ascii characters.
 
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -60,7 +60,11 @@
 
 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", "uri",
+ NULL
+ };
 
 char* database;
 int detect_types = 0;
@@ -68,11 +72,14 @@
 PyObject* factory = NULL;
 int check_same_thread = 1;
 int cached_statements = 100;
+ int uri = 0;
 double timeout = 5.0;
 int rc;
 
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
- &database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOip", kwlist,
+ &database, &timeout, &detect_types,
+ &isolation_level, &check_same_thread,
+ &factory, &cached_statements, &uri))
 {
 return -1;
 }
@@ -91,8 +98,19 @@
 Py_INCREF(&PyUnicode_Type);
 self->text_factory = (PyObject*)&PyUnicode_Type;
 
+#ifdef SQLITE_OPEN_URI
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_open_v2(database, &self->db,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
+ (uri ? SQLITE_OPEN_URI : 0), NULL);
+#else
+ if (uri) {
+ PyErr_SetString(pysqlite_NotSupportedError, "URIs not supported");
+ return -1;
+ }
 Py_BEGIN_ALLOW_THREADS
 rc = sqlite3_open(database, &self->db);
+#endif
 Py_END_ALLOW_THREADS
 
 if (rc != SQLITE_OK) {
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c
--- a/Modules/_sqlite/module.c
+++ b/Modules/_sqlite/module.c
@@ -50,19 +50,26 @@
 * 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", "uri",
+ NULL
+ };
 char* database;
 int detect_types = 0;
 PyObject* isolation_level;
 PyObject* factory = NULL;
 int check_same_thread = 1;
 int cached_statements;
+ int uri = 0;
 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))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOip", kwlist,
+ &database, &timeout, &detect_types,
+ &isolation_level, &check_same_thread,
+ &factory, &cached_statements, &uri))
 {
 return NULL;
 }
@@ -77,7 +84,8 @@
 }
 
 PyDoc_STRVAR(module_connect_doc,
-"connect(database[, timeout, isolation_level, detect_types, factory])\n\
+"connect(database[, timeout, detect_types, isolation_level,\n\
+ check_same_thread, factory, cached_statements, uri])\n\
 \n\
 Opens a connection to the SQLite database file *database*. You can use\n\
 \":memory:\" to open a database connection to a database that resides in\n\
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /