From 4ea9888a3d89c7821551dc2515ffba0d7d829fa7 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Sat, 29 Mar 2025 13:01:37 +0000 Subject: [PATCH] fix database migrations missing --- package.json | 3 +- src/app/index.ts | 4 +- src/db/database.ts | 7 +- src/services/mcp/tools/events.ts | 2 +- src/services/mcp/tools/lists.ts | 2 +- src/services/mcp/tools/profile.ts | 4 +- src/services/mcp/tools/signer.ts | 2 +- src/services/mcp/tools/social.ts | 2 +- src/services/{owner.ts => owner-signer.ts} | 0 src/services/rx-nostr.ts | 3 - src/sqlite/event-store.ts | 4 +- src/sqlite/migrations.ts | 94 ---------------------- 12 files changed, 18 insertions(+), 109 deletions(-) rename src/services/{owner.ts => owner-signer.ts} (100%) delete mode 100644 src/sqlite/migrations.ts diff --git a/package.json b/package.json index 28f219a..9a7a99b 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ }, "files": [ "dist", - "nostrudel/dist" + "nostrudel/dist", + "drizzle" ], "keywords": [ "nostr", diff --git a/src/app/index.ts b/src/app/index.ts index 5208a48..da06e01 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -223,8 +223,8 @@ export default class App extends EventEmitter { this.gossip.interval = config.gossipInterval; this.gossip.broadcastRelays = config.gossipBroadcastRelays; - if (config.gossipEnabled) this.gossip.start(); - else this.gossip.stop(); + if (config.gossipEnabled && !this.gossip.running) this.gossip.start(); + else if (!config.gossipEnabled && this.gossip.running) this.gossip.stop(); }); // setup PROXY switchboard diff --git a/src/db/database.ts b/src/db/database.ts index e2d4370..3387ff2 100644 --- a/src/db/database.ts +++ b/src/db/database.ts @@ -1,3 +1,5 @@ +import { dirname, resolve } from "path"; +import { fileURLToPath } from "url"; import { drizzle } from "drizzle-orm/better-sqlite3"; import { migrate } from "drizzle-orm/better-sqlite3/migrator"; import Database from "better-sqlite3"; @@ -12,8 +14,11 @@ const bakeryDatabase = drizzle(sqlite, { schema }); export type BakeryDatabase = typeof bakeryDatabase; +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + // Run migrations first -migrate(bakeryDatabase, { migrationsFolder: "./drizzle" }); +migrate(bakeryDatabase, { migrationsFolder: resolve(__dirname, "../../drizzle") }); // Setup search tables after migrations setupEventFts(sqlite); diff --git a/src/services/mcp/tools/events.ts b/src/services/mcp/tools/events.ts index f73187f..93cbd75 100644 --- a/src/services/mcp/tools/events.ts +++ b/src/services/mcp/tools/events.ts @@ -4,7 +4,7 @@ import { kinds } from "nostr-tools"; import z from "zod"; import mcpServer from "../server.js"; -import { ownerFactory, ownerPublish } from "../../owner.js"; +import { ownerFactory, ownerPublish } from "../../owner-signer.js"; import { requestLoader } from "../../loaders.js"; import bakeryConfig from "../../config.js"; import eventCache from "../../event-cache.js"; diff --git a/src/services/mcp/tools/lists.ts b/src/services/mcp/tools/lists.ts index 249d546..0152d46 100644 --- a/src/services/mcp/tools/lists.ts +++ b/src/services/mcp/tools/lists.ts @@ -2,7 +2,7 @@ import z from "zod"; import { FollowUser, PinNote, UnfollowUser, UnpinNote } from "applesauce-actions/actions"; import mcpServer from "../server.js"; -import { ownerActions, ownerPublish } from "../../owner.js"; +import { ownerActions, ownerPublish } from "../../owner-signer.js"; import { normalizeToHexPubkey } from "../../../helpers/nip19.js"; import eventCache from "../../event-cache.js"; diff --git a/src/services/mcp/tools/profile.ts b/src/services/mcp/tools/profile.ts index 37a5612..a0828f1 100644 --- a/src/services/mcp/tools/profile.ts +++ b/src/services/mcp/tools/profile.ts @@ -1,9 +1,9 @@ import { UpdateProfile } from "applesauce-actions/actions"; import { z } from "zod"; -import { ownerPublish } from "../../owner.js"; +import { ownerPublish } from "../../owner-signer.js"; import mcpServer from "../server.js"; -import { ownerActions } from "../../owner.js"; +import { ownerActions } from "../../owner-signer.js"; mcpServer.tool( "update_profile", diff --git a/src/services/mcp/tools/signer.ts b/src/services/mcp/tools/signer.ts index 7ccd1df..c801236 100644 --- a/src/services/mcp/tools/signer.ts +++ b/src/services/mcp/tools/signer.ts @@ -4,7 +4,7 @@ import qrcode from "qrcode-terminal"; import { z } from "zod"; import mcpServer from "../server.js"; -import { ownerAccount$, setupSigner$, startSignerSetup, stopSignerSetup } from "../../owner.js"; +import { ownerAccount$, setupSigner$, startSignerSetup, stopSignerSetup } from "../../owner-signer.js"; import { DEFAULT_NOSTR_CONNECT_RELAYS } from "../../../const.js"; import { normalizeToHexPubkey } from "../../../helpers/nip19.js"; import bakeryConfig from "../../config.js"; diff --git a/src/services/mcp/tools/social.ts b/src/services/mcp/tools/social.ts index 3811d5c..9db9124 100644 --- a/src/services/mcp/tools/social.ts +++ b/src/services/mcp/tools/social.ts @@ -7,7 +7,7 @@ import { simpleTimeout } from "applesauce-core/observable"; import { z } from "zod"; import mcpServer from "../server.js"; -import { ownerFactory, ownerPublish } from "../../owner.js"; +import { ownerFactory, ownerPublish } from "../../owner-signer.js"; import eventCache from "../../event-cache.js"; import { requestLoader, singleEventLoader } from "../../loaders.js"; import { eventStore } from "../../stores.js"; diff --git a/src/services/owner.ts b/src/services/owner-signer.ts similarity index 100% rename from src/services/owner.ts rename to src/services/owner-signer.ts diff --git a/src/services/rx-nostr.ts b/src/services/rx-nostr.ts index 6b9e5cc..07da8ee 100644 --- a/src/services/rx-nostr.ts +++ b/src/services/rx-nostr.ts @@ -3,9 +3,6 @@ import { unixNow } from "applesauce-core/helpers"; import { BehaviorSubject } from "rxjs"; import { nanoid } from "nanoid"; -// import { logger } from "../logger.js"; -// const log = logger.extend("rx-nostr"); - export const rxNostr = createRxNostr({ skipVerify: true, verifier: noopVerifier, diff --git a/src/sqlite/event-store.ts b/src/sqlite/event-store.ts index 9a0dbc8..3ce8eb6 100644 --- a/src/sqlite/event-store.ts +++ b/src/sqlite/event-store.ts @@ -1,6 +1,6 @@ import { ISyncEventStore } from "applesauce-core"; import { Filter, NostrEvent, kinds } from "nostr-tools"; -import { and, eq, inArray, isNull } from "drizzle-orm"; +import { eq, inArray } from "drizzle-orm"; import EventEmitter from "events"; import { logger } from "../logger.js"; @@ -113,7 +113,7 @@ export class SQLiteEventStore extends EventEmitter implements ISyncEve private insertEventTags(event: NostrEvent) { for (let tag of event.tags) { - if (tag[0].length === 1) { + if (tag[0].length === 1 && tag[1]) { this.database.insert(schema.tags).values({ event: event.id, tag: tag[0], value: tag[1] }).run(); } } diff --git a/src/sqlite/migrations.ts b/src/sqlite/migrations.ts deleted file mode 100644 index 9acf550..0000000 --- a/src/sqlite/migrations.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { unixNow } from "applesauce-core/helpers"; -import { Database } from "better-sqlite3"; - -type ScriptFunction = (database: Database, log: (message: string) => void) => Promise; -type MigrationScript = { version: number; migrate: ScriptFunction }; - -export class MigrationSet { - scripts: MigrationScript[] = []; - - name: string; - database?: Database; - setupMigrationTables = true; - - constructor(name: string, database?: Database) { - this.database = database; - this.name = name; - } - - private ensureMigrations(database: Database | undefined = this.database) { - if (!database) throw new Error("database required"); - - database - .prepare( - ` - CREATE TABLE IF NOT EXISTS "migrations" ( - "id" INTEGER NOT NULL, - "name" TEXT NOT NULL, - "version" INTEGER NOT NULL, - "date" INTEGER NOT NULL, - PRIMARY KEY("id" AUTOINCREMENT) - ); - `, - ) - .run(); - database - .prepare( - ` - CREATE TABLE IF NOT EXISTS "migration_logs" ( - "id" INTEGER NOT NULL, - "migration" INTEGER NOT NULL, - "message" TEXT NOT NULL, - FOREIGN KEY("migration") REFERENCES "migrations", - PRIMARY KEY("id" AUTOINCREMENT) - ); - `, - ) - .run(); - } - - addScript(version: number, migrate: ScriptFunction) { - this.scripts.push({ version, migrate }); - } - - async run(database: Database | undefined = this.database) { - if (!database) throw new Error("database required"); - - // ensure migration tables are setup - await this.ensureMigrations(database); - - const prev = database - .prepare<[string], { name: string; version: number }>(`SELECT * FROM migrations WHERE name=?`) - .all(this.name); - const lastVersion = prev.reduce((v, m) => Math.max(m.version, v), 0); - - const sorted = Array.from(this.scripts).sort((a, b) => a.version - b.version); - - let version = lastVersion; - for (const script of sorted) { - if (version < script.version) { - let logs: string[] = []; - await database.transaction(() => { - return script.migrate(database, (message) => logs.push(message)); - })(); - - version = script.version; - - // save the migration - database.transaction(() => { - const result = database - .prepare<[string, number, number]>(`INSERT INTO migrations (name, version, date) VALUES (?, ?, ?)`) - .run(this.name, script.version, unixNow()); - - const insertLog = database.prepare<[number | bigint, string]>( - `INSERT INTO migration_logs (migration, message) VALUES (?, ?)`, - ); - - for (const message of logs) { - insertLog.run(result.lastInsertRowid, message); - } - })(); - } - } - } -}