diff --git a/sqlitedict.py b/sqlitedict.py index 29d39a3..3444a4e 100755 --- a/sqlitedict.py +++ b/sqlitedict.py @@ -168,10 +168,14 @@ def __init__(self, filename=None, tablename='unnamed', flag='c', self.decode = decode logger.info("opening Sqlite table %r in %r" % (tablename, filename)) - MAKE_TABLE = 'CREATE TABLE IF NOT EXISTS "%s" (key TEXT PRIMARY KEY, value BLOB)' % self.tablename self.conn = self._new_conn() - self.conn.execute(MAKE_TABLE) - self.conn.commit() + if self.flag == 'r': + if not self.tablename in SqliteDict.get_tablenames(self.filename): + raise RuntimeError('Refusing to create a new table "%s" in read-only DB mode' % tablename) + else: + MAKE_TABLE = 'CREATE TABLE IF NOT EXISTS "%s" (key TEXT PRIMARY KEY, value BLOB)' % self.tablename + self.conn.execute(MAKE_TABLE) + self.conn.commit() if flag == 'w': self.clear() diff --git a/tests/test_core.py b/tests/test_core.py index f6f3236..0d6c9fb 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -143,6 +143,26 @@ def attempt_terminate(): with self.assertRaises(RuntimeError): func() + def test_readonly_table(self): + """ + Read-only access on a non-existant tablename should raise RuntimeError, + and not create a new (empty) table. + """ + fname = norm_file('tests/db/sqlitedict-override-test.sqlite') + dummy_tablename = 'table404' + orig_db = SqliteDict(filename=fname) + orig_db['key'] = 'value' + orig_db['key_two'] = 2 + orig_db.commit() + orig_db.close() + + self.assertFalse(dummy_tablename in SqliteDict.get_tablenames(fname)) + + with self.assertRaises(RuntimeError): + SqliteDict(filename=fname, tablename=dummy_tablename, flag='r') + + self.assertFalse(dummy_tablename in SqliteDict.get_tablenames(fname)) + def test_irregular_tablenames(self): """Irregular table names need to be quoted""" def __test_irregular_tablenames(tablename):