mirror of
https://github.com/aljazceru/bakery.git
synced 2025-12-17 20:55:02 +01:00
fix database migrations missing
This commit is contained in:
@@ -21,7 +21,8 @@
|
|||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"nostrudel/dist"
|
"nostrudel/dist",
|
||||||
|
"drizzle"
|
||||||
],
|
],
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"nostr",
|
"nostr",
|
||||||
|
|||||||
@@ -223,8 +223,8 @@ export default class App extends EventEmitter<EventMap> {
|
|||||||
this.gossip.interval = config.gossipInterval;
|
this.gossip.interval = config.gossipInterval;
|
||||||
this.gossip.broadcastRelays = config.gossipBroadcastRelays;
|
this.gossip.broadcastRelays = config.gossipBroadcastRelays;
|
||||||
|
|
||||||
if (config.gossipEnabled) this.gossip.start();
|
if (config.gossipEnabled && !this.gossip.running) this.gossip.start();
|
||||||
else this.gossip.stop();
|
else if (!config.gossipEnabled && this.gossip.running) this.gossip.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
// setup PROXY switchboard
|
// setup PROXY switchboard
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { dirname, resolve } from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||||
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
||||||
import Database from "better-sqlite3";
|
import Database from "better-sqlite3";
|
||||||
@@ -12,8 +14,11 @@ const bakeryDatabase = drizzle(sqlite, { schema });
|
|||||||
|
|
||||||
export type BakeryDatabase = typeof bakeryDatabase;
|
export type BakeryDatabase = typeof bakeryDatabase;
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
// Run migrations first
|
// Run migrations first
|
||||||
migrate(bakeryDatabase, { migrationsFolder: "./drizzle" });
|
migrate(bakeryDatabase, { migrationsFolder: resolve(__dirname, "../../drizzle") });
|
||||||
|
|
||||||
// Setup search tables after migrations
|
// Setup search tables after migrations
|
||||||
setupEventFts(sqlite);
|
setupEventFts(sqlite);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { kinds } from "nostr-tools";
|
|||||||
import z from "zod";
|
import z from "zod";
|
||||||
|
|
||||||
import mcpServer from "../server.js";
|
import mcpServer from "../server.js";
|
||||||
import { ownerFactory, ownerPublish } from "../../owner.js";
|
import { ownerFactory, ownerPublish } from "../../owner-signer.js";
|
||||||
import { requestLoader } from "../../loaders.js";
|
import { requestLoader } from "../../loaders.js";
|
||||||
import bakeryConfig from "../../config.js";
|
import bakeryConfig from "../../config.js";
|
||||||
import eventCache from "../../event-cache.js";
|
import eventCache from "../../event-cache.js";
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import z from "zod";
|
|||||||
import { FollowUser, PinNote, UnfollowUser, UnpinNote } from "applesauce-actions/actions";
|
import { FollowUser, PinNote, UnfollowUser, UnpinNote } from "applesauce-actions/actions";
|
||||||
|
|
||||||
import mcpServer from "../server.js";
|
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 { normalizeToHexPubkey } from "../../../helpers/nip19.js";
|
||||||
import eventCache from "../../event-cache.js";
|
import eventCache from "../../event-cache.js";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { UpdateProfile } from "applesauce-actions/actions";
|
import { UpdateProfile } from "applesauce-actions/actions";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { ownerPublish } from "../../owner.js";
|
import { ownerPublish } from "../../owner-signer.js";
|
||||||
import mcpServer from "../server.js";
|
import mcpServer from "../server.js";
|
||||||
import { ownerActions } from "../../owner.js";
|
import { ownerActions } from "../../owner-signer.js";
|
||||||
|
|
||||||
mcpServer.tool(
|
mcpServer.tool(
|
||||||
"update_profile",
|
"update_profile",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import qrcode from "qrcode-terminal";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import mcpServer from "../server.js";
|
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 { DEFAULT_NOSTR_CONNECT_RELAYS } from "../../../const.js";
|
||||||
import { normalizeToHexPubkey } from "../../../helpers/nip19.js";
|
import { normalizeToHexPubkey } from "../../../helpers/nip19.js";
|
||||||
import bakeryConfig from "../../config.js";
|
import bakeryConfig from "../../config.js";
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { simpleTimeout } from "applesauce-core/observable";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import mcpServer from "../server.js";
|
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 eventCache from "../../event-cache.js";
|
||||||
import { requestLoader, singleEventLoader } from "../../loaders.js";
|
import { requestLoader, singleEventLoader } from "../../loaders.js";
|
||||||
import { eventStore } from "../../stores.js";
|
import { eventStore } from "../../stores.js";
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ import { unixNow } from "applesauce-core/helpers";
|
|||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
// import { logger } from "../logger.js";
|
|
||||||
// const log = logger.extend("rx-nostr");
|
|
||||||
|
|
||||||
export const rxNostr = createRxNostr({
|
export const rxNostr = createRxNostr({
|
||||||
skipVerify: true,
|
skipVerify: true,
|
||||||
verifier: noopVerifier,
|
verifier: noopVerifier,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ISyncEventStore } from "applesauce-core";
|
import { ISyncEventStore } from "applesauce-core";
|
||||||
import { Filter, NostrEvent, kinds } from "nostr-tools";
|
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 EventEmitter from "events";
|
||||||
|
|
||||||
import { logger } from "../logger.js";
|
import { logger } from "../logger.js";
|
||||||
@@ -113,7 +113,7 @@ export class SQLiteEventStore extends EventEmitter<EventMap> implements ISyncEve
|
|||||||
|
|
||||||
private insertEventTags(event: NostrEvent) {
|
private insertEventTags(event: NostrEvent) {
|
||||||
for (let tag of event.tags) {
|
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();
|
this.database.insert(schema.tags).values({ event: event.id, tag: tag[0], value: tag[1] }).run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
import { unixNow } from "applesauce-core/helpers";
|
|
||||||
import { Database } from "better-sqlite3";
|
|
||||||
|
|
||||||
type ScriptFunction = (database: Database, log: (message: string) => void) => Promise<void>;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user