Bug 1968020 - Fix schema check of the semantic history database. r=cgopal
The healthy database schema check cannot use table_info as it is not supported by the sqlite-vec extension. Differential Revision: https://phabricator.services.mozilla.com/D250794
This commit is contained in:
committed by
mak77@bonardo.net
parent
9b2092feba
commit
fd60166ce8
@@ -97,7 +97,7 @@ export class PlacesSemanticHistoryDatabase {
|
|||||||
lazy.logger.info("Initializing schema");
|
lazy.logger.info("Initializing schema");
|
||||||
await this.#initializeSchema();
|
await this.#initializeSchema();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
lazy.logger.warn("Schema initialization failed");
|
lazy.logger.warn(`Schema initialization failed: ${e}`);
|
||||||
// If the schema cannot be initialized close the connection and create
|
// If the schema cannot be initialized close the connection and create
|
||||||
// a new database file.
|
// a new database file.
|
||||||
await this.closeConnection();
|
await this.closeConnection();
|
||||||
@@ -153,12 +153,15 @@ export class PlacesSemanticHistoryDatabase {
|
|||||||
*/
|
*/
|
||||||
async #initializeSchema() {
|
async #initializeSchema() {
|
||||||
let version = await this.#conn.getSchemaVersion();
|
let version = await this.#conn.getSchemaVersion();
|
||||||
|
lazy.logger.debug(`Database schema version: ${version}`);
|
||||||
if (version > CURRENT_SCHEMA_VERSION) {
|
if (version > CURRENT_SCHEMA_VERSION) {
|
||||||
|
lazy.logger.warn(`Database schema downgrade`);
|
||||||
throw new Error("Downgrade of the schema is not supported");
|
throw new Error("Downgrade of the schema is not supported");
|
||||||
}
|
}
|
||||||
if (version == CURRENT_SCHEMA_VERSION) {
|
if (version == CURRENT_SCHEMA_VERSION) {
|
||||||
let healthy = await this.#checkDatabaseEntities(this.#embeddingSize);
|
let healthy = await this.#checkDatabaseEntities(this.#embeddingSize);
|
||||||
if (!healthy) {
|
if (!healthy) {
|
||||||
|
lazy.logger.error(`Database schema is not healthy`);
|
||||||
throw new Error("Database schema is not healthy");
|
throw new Error("Database schema is not healthy");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -228,18 +231,21 @@ export class PlacesSemanticHistoryDatabase {
|
|||||||
!tableNames.includes("vec_history") ||
|
!tableNames.includes("vec_history") ||
|
||||||
!tableNames.includes("vec_history_mapping")
|
!tableNames.includes("vec_history_mapping")
|
||||||
) {
|
) {
|
||||||
|
lazy.logger.error(`Missing tables in the database`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the embedding size changed the database should be recreated. This
|
// If the embedding size changed the database should be recreated. This
|
||||||
// should be handled by a migration, but we check to be overly safe.
|
// should be handled by a migration, but we check to be overly safe.
|
||||||
let embeddingSizeCheck = await this.#conn.execute(
|
let embeddingSizeMatches = (
|
||||||
`PRAGMA table_info(vec_history)`
|
await this.#conn.execute(
|
||||||
);
|
`SELECT INSTR(sql, :needle) > 0
|
||||||
let embeddingSizeRow = embeddingSizeCheck.find(
|
FROM sqlite_master WHERE name = 'vec_history'`,
|
||||||
row => row.getResultByName("name") == "embedding"
|
{ needle: `FLOAT[${embeddingSize}]` }
|
||||||
);
|
)
|
||||||
if (embeddingSizeRow.getResultByName("type") != `FLOAT[${embeddingSize}]`) {
|
)[0].getResultByIndex(0);
|
||||||
|
if (!embeddingSizeMatches) {
|
||||||
|
lazy.logger.error(`Embeddings size doesn't match`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,3 +94,26 @@ add_task(async function test_corruptdb() {
|
|||||||
await db.closeConnection();
|
await db.closeConnection();
|
||||||
await db.removeDatabaseFiles();
|
await db.removeDatabaseFiles();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function test_healthydb() {
|
||||||
|
let db = new PlacesSemanticHistoryDatabase({
|
||||||
|
embeddingSize: 4,
|
||||||
|
fileName: "places_semantic.sqlite",
|
||||||
|
});
|
||||||
|
await db.getConnection();
|
||||||
|
await db.closeConnection();
|
||||||
|
// Check database creation time won't change when reopening, as that would
|
||||||
|
// indicate the database file was replaced.
|
||||||
|
let creationTime = (await IOUtils.stat(db.databaseFilePath)).creationTime;
|
||||||
|
db = new PlacesSemanticHistoryDatabase({
|
||||||
|
embeddingSize: 4,
|
||||||
|
fileName: "places_semantic.sqlite",
|
||||||
|
});
|
||||||
|
await db.getConnection();
|
||||||
|
await db.closeConnection();
|
||||||
|
Assert.equal(
|
||||||
|
creationTime,
|
||||||
|
(await IOUtils.stat(db.databaseFilePath)).creationTime,
|
||||||
|
"Database creation time should not change."
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user