From a80c3e32f1d4344c3a7a49d040601672d31bcb34 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 2 Mar 2025 19:39:06 +0200 Subject: [PATCH] fix(migration): JavaScript-based migrations not working --- ...bs.js => 0216__move_content_into_blobs.ts} | 27 +++++++++++++----- ...=> 0220__migrate_images_to_attachments.ts} | 12 ++++---- src/services/migration.spec.ts | 17 +++++++++++ src/services/migration.ts | 2 +- src/services/sql.ts | 12 +++++--- test/db/document_v214.db | Bin 1732608 -> 1732608 bytes 6 files changed, 52 insertions(+), 18 deletions(-) rename db/migrations/{0216__move_content_into_blobs.js => 0216__move_content_into_blobs.ts} (71%) rename db/migrations/{0220__migrate_images_to_attachments.js => 0220__migrate_images_to_attachments.ts} (66%) diff --git a/db/migrations/0216__move_content_into_blobs.js b/db/migrations/0216__move_content_into_blobs.ts similarity index 71% rename from db/migrations/0216__move_content_into_blobs.js rename to db/migrations/0216__move_content_into_blobs.ts index 53586d0e3..e43bd25e3 100644 --- a/db/migrations/0216__move_content_into_blobs.js +++ b/db/migrations/0216__move_content_into_blobs.ts @@ -1,11 +1,24 @@ -module.exports = () => { - const sql = require("../../src/services/sql"); - const utils = require("../../src/services/utils"); +interface NoteContentsRow { + noteId: string; + content: string | Buffer; + dateModified: string; + utcDateModified: string; +} + +interface NoteRevisionContents { + noteRevisionId: string; + content: string | Buffer; + utcDateModified: string; +} + +export default async () => { + const sql = (await import("../../src/services/sql")).default; + const utils = (await import("../../src/services/utils")).default; const existingBlobIds = new Set(); - for (const noteId of sql.getColumn(`SELECT noteId FROM note_contents`)) { - const row = sql.getRow(`SELECT noteId, content, dateModified, utcDateModified FROM note_contents WHERE noteId = ?`, [noteId]); + for (const noteId of sql.getColumn(`SELECT noteId FROM note_contents`)) { + const row = sql.getRow(`SELECT noteId, content, dateModified, utcDateModified FROM note_contents WHERE noteId = ?`, [noteId]); const blobId = utils.hashedBlobId(row.content); if (!existingBlobIds.has(blobId)) { @@ -28,7 +41,7 @@ module.exports = () => { } for (const noteRevisionId of sql.getColumn(`SELECT noteRevisionId FROM note_revision_contents`)) { - const row = sql.getRow(`SELECT noteRevisionId, content, utcDateModified FROM note_revision_contents WHERE noteRevisionId = ?`, [noteRevisionId]); + const row = sql.getRow(`SELECT noteRevisionId, content, utcDateModified FROM note_revision_contents WHERE noteRevisionId = ?`, [noteRevisionId]); const blobId = utils.hashedBlobId(row.content); if (!existingBlobIds.has(blobId)) { @@ -44,7 +57,7 @@ module.exports = () => { sql.execute("UPDATE entity_changes SET entityName = 'blobs', entityId = ? WHERE entityName = 'note_revision_contents' AND entityId = ?", [blobId, row.noteRevisionId]); } else { // duplicates - sql.execute("DELETE FROM entity_changes WHERE entityName = 'note_revision_contents' AND entityId = ?", [row.noteId]); + sql.execute("DELETE FROM entity_changes WHERE entityName = 'note_revision_contents' AND entityId = ?", [row.noteRevisionId]); } sql.execute("UPDATE note_revisions SET blobId = ? WHERE noteRevisionId = ?", [blobId, row.noteRevisionId]); diff --git a/db/migrations/0220__migrate_images_to_attachments.js b/db/migrations/0220__migrate_images_to_attachments.ts similarity index 66% rename from db/migrations/0220__migrate_images_to_attachments.js rename to db/migrations/0220__migrate_images_to_attachments.ts index a93e2028d..60cfd337f 100644 --- a/db/migrations/0220__migrate_images_to_attachments.js +++ b/db/migrations/0220__migrate_images_to_attachments.ts @@ -1,9 +1,9 @@ -module.exports = () => { - const beccaLoader = require("../../src/becca/becca_loader"); - const becca = require("../../src/becca/becca"); - const cls = require("../../src/services/cls"); - const log = require("../../src/services/log"); - const sql = require("../../src/services/sql"); +export default async () => { + const beccaLoader = (await import("../../src/becca/becca_loader")).default; + const becca = (await import("../../src/becca/becca")).default; + const cls = (await import("../../src/services/cls")).default; + const log = (await import("../../src/services/log")).default; + const sql = (await import("../../src/services/sql")).default; cls.init(() => { // emergency disabling of image compression since it appears to make problems in migration to 0.61 diff --git a/src/services/migration.spec.ts b/src/services/migration.spec.ts index e69de29bb..0cd6c2839 100644 --- a/src/services/migration.spec.ts +++ b/src/services/migration.spec.ts @@ -0,0 +1,17 @@ +import { describe, it } from "vitest"; +import becca from "../becca/becca.js"; +import sql from "./sql.js"; +import migration from "./migration.js"; +import cls from "./cls.js"; + +describe("Migration", () => { + it("migrates from v214", async () => { + return new Promise((resolve) => { + cls.init(async () => { + sql.rebuildIntegrationTestDatabase("test/db/document_v214.db"); + await migration.migrateIfNecessary(); + resolve(); + }); + }); + }); +}); diff --git a/src/services/migration.ts b/src/services/migration.ts index f8cbfbc22..e0fc2a6ed 100644 --- a/src/services/migration.ts +++ b/src/services/migration.ts @@ -106,7 +106,7 @@ async function executeMigration(mig: MigrationInfo) { console.log("Migration with JS module"); const migrationModule = await import(`${resourceDir.MIGRATIONS_DIR}/${mig.file}`); - migrationModule(); + await migrationModule.default(); } else { throw new Error(`Unknown migration type '${mig.type}'`); } diff --git a/src/services/sql.ts b/src/services/sql.ts index ab98d3a04..87d3df936 100644 --- a/src/services/sql.ts +++ b/src/services/sql.ts @@ -25,14 +25,18 @@ function buildDatabase() { return new Database(dataDir.DOCUMENT_PATH); } -function buildIntegrationTestDatabase() { - const dbBuffer = fs.readFileSync(dataDir.DOCUMENT_PATH); +function buildIntegrationTestDatabase(dbPath?: string) { + const dbBuffer = fs.readFileSync(dbPath ?? dataDir.DOCUMENT_PATH); return new Database(dbBuffer); } -function rebuildIntegrationTestDatabase() { +function rebuildIntegrationTestDatabase(dbPath: string) { + if (dbConnection) { + dbConnection.close(); + } + // This allows a database that is read normally but is kept in memory and discards all modifications. - dbConnection = buildIntegrationTestDatabase(); + dbConnection = buildIntegrationTestDatabase(dbPath); statementCache = {}; } diff --git a/test/db/document_v214.db b/test/db/document_v214.db index 482024b74512361812c218225b3a31bfdae39df3..928561d9d8939163849d5521255621a622dee342 100644 GIT binary patch delta 157 zcmZp8klFAcQzkgjC$l6~AuYcsH?c&)m_dMnk&(ecL4kpRfq9~gGb=NLUR6P3N^1(^ z))b~c=cZq578PqRJI@5f%s|Wn#H>Kf2E^<@%mKulK+FZi+(66&#JoVv2gLk9EC9rU cKr95r!aytn#G*h9GE*FgCAOEHm+V>q0PRgc3IG5A delta 157 zcmZp8klFAcQzkgjC$l6~AuYcsH?c&)m_dMniHX5ML4kpRfoYLW0Y#II?n{e%s|Wn#H>Kf2E^<@%mKulK+FZi+(66&#JoVv2gLk9EC9rU cKr95r!aytn#G*hf2E^h(EU~@nyky$~0Jpn8wEzGB