def test_db_schemaUpgrade(self) -> None: """ A database with an old schema is automatically upgraded to the current version. """ def getSchemaInfo(db: Connection) -> str: out = StringIO() printSchema(db, out) return out.getvalue() currentVersion = DataStore._schemaVersion with createDB( None, DataStore._loadSchema(version=currentVersion) ) as db: currentSchemaInfo = getSchemaInfo(db) for version in range(1, currentVersion): path = Path(self.mktemp()) createDB(path, DataStore._loadSchema(version=version)) store = DataStore(dbPath=path) self.assertEqual(store._version(store._db), currentVersion) schemaInfo = getSchemaInfo(store._db) self.maxDiff = None self.assertEqual(schemaInfo, currentSchemaInfo)
def test_upgradeSchema(self) -> None: """ :meth:`DataStore.upgradeSchema` upgrades the data schema to the current version. """ def getSchemaInfo(db: Connection) -> str: out = StringIO() printSchema(db, out) return out.getvalue() currentVersion = DataStore.schemaVersion with createDB( None, DataStore.loadSchema(version=currentVersion) ) as db: currentSchemaInfo = getSchemaInfo(db) for version in range(1, currentVersion): path = Path(self.mktemp()) createDB(path, DataStore.loadSchema(version=version)) store = DataStore(dbPath=path) self.successResultOf(store.upgradeSchema()) self.assertEqual(store._dbSchemaVersion(store._db), currentVersion) schemaInfo = getSchemaInfo(store._db) self.maxDiff = None self.assertEqual(schemaInfo, currentSchemaInfo)
def printSchema(cls, out: TextIO = stdout) -> None: """ Print schema. """ with createDB(None, cls.loadSchema()) as db: version = cls._dbSchemaVersion(db) print(f"Version: {version}", file=out) printSchema(db, out=out)
def test_version(self) -> None: """ :meth:`DataStore._version` returns the schema version for the given database. """ for version in range(1, DataStore._schemaVersion + 1): db = createDB(None, DataStore._loadSchema(version=version)) self.assertEqual(DataStore._version(db), version)
def test_dbSchemaVersion(self) -> None: """ :meth:`DataStore._dbSchemaVersion` returns the schema version for the given database. """ for version in range(1, DataStore.schemaVersion + 1): db = createDB(None, DataStore.loadSchema(version=version)) self.assertEqual(DataStore._dbSchemaVersion(db), version)
def printQueries(cls, out: TextIO = stdout) -> None: """ Print a summary of queries. """ queries = ((getattr(cls.query, name).text, name) for name in sorted(vars(cls.query))) with createDB(None, cls.loadSchema()) as db: for line in explainQueryPlans(db, queries): print(line, file=out) print(file=out)
def printQueries(cls, out: TextIO = stdout) -> None: """ Print a summary of queries. """ queries = ( (getattr(cls.query, name).text, name) for name in sorted(vars(cls.query)) ) with createDB(None, cls.loadSchema()) as db: for line in explainQueryPlans(db, queries): print(line, file=out) print(file=out)
def test_upgradeSchema_noSchemaVersion(self) -> None: """ :meth:`DataStore.upgradeSchema` raises :exc:`StorageError` when the SCHEMA_INFO table has no rows. """ # Load valid schema, then delete SCHEMA_INFO rows. dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore.loadSchema()) as db: db.execute("delete from SCHEMA_INFO") store = TestDataStore(dbPath=dbPath) f = self.failureResultOf(store.upgradeSchema(), StorageError) self.assertEqual(f.getErrorMessage(), "Invalid schema: no version")
def test_upgradeSchema_noSchemaInfo(self) -> None: """ :meth:`DataStore.upgradeSchema` raises :exc:`StorageError` when the database has no SCHEMA_INFO table. """ # Load valid schema, then drop SCHEMA_INFO dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore.loadSchema()) as db: db.execute("drop table SCHEMA_INFO") store = TestDataStore(dbPath=dbPath) f = self.failureResultOf(store.upgradeSchema(), StorageError) self.assertStartsWith(f.getErrorMessage(), "Unable to apply schema: ")
def test_db_noSchemaVersion(self) -> None: """ :meth:`DataStore._db` raises :exc:`StorageError` when the SCHEMA_INFO table has no rows. """ # Load valid schema, then delete SCHEMA_INFO rows. dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore._loadSchema()) as db: db.execute("delete from SCHEMA_INFO") store = self.store(dbPath=dbPath) e = self.assertRaises(StorageError, lambda: store._db) self.assertEqual(str(e), "Invalid schema: no version")
def test_upgradeSchema_noSchemaVersion(self) -> None: """ :meth:`DataStore.upgradeSchema` raises :exc:`StorageError` when the SCHEMA_INFO table has no rows. """ # Load valid schema, then delete SCHEMA_INFO rows. dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore.loadSchema()) as db: db.execute("delete from SCHEMA_INFO") store = TestDataStore(self, dbPath=dbPath) f = self.failureResultOf(store.upgradeSchema(), StorageError) self.assertEqual(f.getErrorMessage(), "Invalid schema: no version")
def test_upgradeSchema_noSchemaInfo(self) -> None: """ :meth:`DataStore.upgradeSchema` raises :exc:`StorageError` when the database has no SCHEMA_INFO table. """ # Load valid schema, then drop SCHEMA_INFO dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore.loadSchema()) as db: db.execute("drop table SCHEMA_INFO") store = TestDataStore(self, dbPath=dbPath) f = self.failureResultOf(store.upgradeSchema(), StorageError) self.assertStartsWith(f.getErrorMessage(), "Unable to apply schema: ")
def test_db_noSchemaInfo(self) -> None: """ :meth:`DataStore._db` raises :exc:`StorageError` when the database has no SCHEMA_INFO table. """ # Load valid schema, then drop SCHEMA_INFO dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore._loadSchema()) as db: db.execute("drop table SCHEMA_INFO") store = self.store(dbPath=dbPath) e = self.assertRaises(StorageError, lambda: store._db) self.assertStartsWith(str(e), "Unable to look up schema version: ") self.assertIn("SCHEMA_INFO", str(e))
def _db(self) -> Connection: if self._state.db is None: try: if self.dbPath is None: self._state.db = createDB(None, schema="") else: self._state.db = openDB(self.dbPath, schema="") except SQLiteError as e: self._log.critical( "Unable to open SQLite database {dbPath}: {error}", dbPath=self.dbPath, error=e, ) raise StorageError( f"Unable to open SQLite database {self.dbPath}: {e}") return self._state.db
def test_db_fromVersionTooHigh(self, version: int) -> None: """ :meth:`DataStore._db` raises :exc:`StorageError` when the database has a schema version of greater than the current schema version. """ # Load valid schema, then set schema version dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore._loadSchema()) as db: db.execute( "update SCHEMA_INFO set VERSION = :version", dict(version=version) ) store = self.store(dbPath=dbPath) e = self.assertRaises(StorageError, lambda: store._db) self.assertEqual( str(e), f"Schema version {version} is too new" )
def test_db_fromVersionTooLow(self, version: int) -> None: """ :meth:`DataStore._db` raises :exc:`StorageError` when the database has a schema version of zero or less. (Version numbering started at 1.) """ # Load valid schema, then set schema version dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore._loadSchema()) as db: db.execute( "update SCHEMA_INFO set VERSION = :version", dict(version=version) ) store = self.store(dbPath=dbPath) e = self.assertRaises(StorageError, lambda: store._db) self.assertEqual( str(e), f"No upgrade path from schema version {version}" )
def test_upgradeSchema_fromVersionTooLow(self, version: int) -> None: """ :meth:`DataStore.upgradeSchema` raises :exc:`StorageError` when the database has a schema version less than 0. """ # Load valid schema, then set schema version dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore.loadSchema()) as db: db.execute( "update SCHEMA_INFO set VERSION = :version", dict(version=version) ) store = TestDataStore(dbPath=dbPath) f = self.failureResultOf(store.upgradeSchema(), StorageError) self.assertEqual( f.getErrorMessage(), f"No upgrade path from schema version {version}", )
def test_upgradeSchema_fromVersionTooLow(self, version: int) -> None: """ :meth:`DataStore.upgradeSchema` raises :exc:`StorageError` when the database has a schema version less than 0. """ # Load valid schema, then set schema version dbPath = Path(self.mktemp()) with createDB(dbPath, DataStore.loadSchema()) as db: db.execute( "update SCHEMA_INFO set VERSION = :version", dict(version=version) ) store = TestDataStore(self, dbPath=dbPath) f = self.failureResultOf(store.upgradeSchema(), StorageError) self.assertEqual( f.getErrorMessage(), f"No upgrade path from schema version {version}", )