From a7ff3a13cd07e6a9393752a0a4b81962518775e5 Mon Sep 17 00:00:00 2001 From: Will Hunt <will@half-shot.uk> Date: Sun, 27 Jan 2019 17:25:11 +0000 Subject: [PATCH] Migrate rooms in the schema --- src/db/schema/dbschema.ts | 1 + src/db/schema/v8.ts | 29 +++++++++- src/discordas.ts | 2 +- src/store.ts | 14 ++++- tools/moveRoomStoreToDb.ts | 106 ------------------------------------- 5 files changed, 42 insertions(+), 110 deletions(-) delete mode 100644 tools/moveRoomStoreToDb.ts diff --git a/src/db/schema/dbschema.ts b/src/db/schema/dbschema.ts index 9f215f1..132e7c0 100644 --- a/src/db/schema/dbschema.ts +++ b/src/db/schema/dbschema.ts @@ -15,6 +15,7 @@ limitations under the License. */ import { DiscordStore } from "../../store"; +import { DiscordBridgeConfigDatabase } from "../../config"; export interface IDbSchema { description: string; run(store: DiscordStore): Promise<null|void|Error|Error[]>; diff --git a/src/db/schema/v8.ts b/src/db/schema/v8.ts index 4e68102..b41650e 100644 --- a/src/db/schema/v8.ts +++ b/src/db/schema/v8.ts @@ -17,11 +17,19 @@ limitations under the License. import {IDbSchema} from "./dbschema"; import {DiscordStore} from "../../store"; import { Log } from "../../log"; - +import { + RoomStore, +} from "matrix-appservice-bridge"; +import { RemoteStoreRoom, MatrixStoreRoom } from "../roomstore"; const log = new Log("SchemaV8"); export class Schema implements IDbSchema { public description = "create room store tables"; + + constructor(private roomStore: RoomStore|null) { + + } + public async run(store: DiscordStore): Promise<void> { await store.create_table(` CREATE TABLE remote_room_data ( @@ -47,6 +55,25 @@ export class Schema implements IDbSchema { remote_id TEXT, PRIMARY KEY(id) );`, "room_entries"); + + if (this.roomStore === null) { + log.warn("Not migrating rooms from room store, room store is null"); + return; + } + log.warn("Migrating rooms from roomstore, this may take a while..."); + const rooms = await this.roomStore.select({}); + // Matrix room only entrys are useless. + const entrys = rooms.filter((r) => r.remote); + for (const e of entrys) { + const matrix = new MatrixStoreRoom(e.matrix_id); + try { + const remote = new RemoteStoreRoom(e.remote_id, e.remote); + await store.roomStore.linkRooms(matrix, remote); + log.info(`Migrated ${matrix.roomId}`); + } catch (ex) { + log.error(`Failed to link ${matrix.roomId}: `, ex); + } + } } public async rollBack(store: DiscordStore): Promise<void> { diff --git a/src/discordas.ts b/src/discordas.ts index 5e66cb7..841747a 100644 --- a/src/discordas.ts +++ b/src/discordas.ts @@ -136,7 +136,7 @@ async function run(port: number, fileConfig: DiscordBridgeConfig) { try { await bridge.run(port, config); log.info("Initing store."); - await discordstore.init(); + await discordstore.init(0, bridge.getRoomStore()); log.info("Initing bot."); provisioner.setStore(discordstore.roomStore); roomhandler.setBridge(bridge, discordstore.roomStore); diff --git a/src/store.ts b/src/store.ts index c18ef89..0a506a4 100644 --- a/src/store.ts +++ b/src/store.ts @@ -25,6 +25,9 @@ import { DiscordBridgeConfigDatabase } from "./config"; import { Postgres } from "./db/postgres"; import { IDatabaseConnector } from "./db/connector"; import { DbRoomStore } from "./db/roomstore"; +import { + RoomStore, +} from "matrix-appservice-bridge"; const log = new Log("DiscordStore"); /** * Stores data for specific users and data not specific to rooms. @@ -83,7 +86,8 @@ export class DiscordStore { /** * Checks the database has all the tables needed. */ - public async init(overrideSchema: number = 0): Promise<void> { + public async init(overrideSchema: number = 0, roomStore: RoomStore = null): Promise<void> { + const SCHEMA_ROOM_STORE_REQUIRED = 8; log.info("Starting DB Init"); await this.open_database(); let version = await this.getSchemaVersion(); @@ -91,7 +95,13 @@ export class DiscordStore { while (version < targetSchema) { version++; const schemaClass = require(`./db/schema/v${version}.js`).Schema; - const schema = (new schemaClass() as IDbSchema); + let schema: IDbSchema; + if (version === SCHEMA_ROOM_STORE_REQUIRED) { // 8 requires access to the roomstore. + console.log(roomStore); + schema = (new schemaClass(roomStore) as IDbSchema); + } else { + schema = (new schemaClass() as IDbSchema); + } log.info(`Updating database to v${version}, "${schema.description}"`); try { await schema.run(this); diff --git a/tools/moveRoomStoreToDb.ts b/tools/moveRoomStoreToDb.ts deleted file mode 100644 index 80edb1b..0000000 --- a/tools/moveRoomStoreToDb.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright 2018 matrix-appservice-discord - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* tslint:disable:no-console */ -/** - * Allows you to become an admin for a room the bot is in control of. - */ - -import { ClientFactory, Bridge } from "matrix-appservice-bridge"; -import * as yaml from "js-yaml"; -import * as fs from "fs"; -import * as args from "command-line-args"; -import * as usage from "command-line-usage"; -import { DiscordBridgeConfig } from "../src/config"; -import { Log } from "../src/log"; -import { Util } from "../src/util"; -import { RemoteStoreRoom, MatrixStoreRoom } from "../src/db/roomstore"; -import { DiscordStore } from "../src/store"; -const log = new Log("MoveRoomStoreToDb"); - -const optionDefinitions = [ - { - alias: "h", - description: "Display this usage guide.", - name: "help", - type: Boolean, - }, - { - alias: "c", - defaultValue: "config.yaml", - description: "The AS config file.", - name: "config", - type: String, - typeLabel: "<config.yaml>", - }, - { - alias: "s", - defaultValue: "room-store.db", - description: "The location of the room store.", - name: "store", - type: String, - }, -]; - -const options = args(optionDefinitions); - -if (options.help) { - /* tslint:disable:no-console */ - console.log(usage([ - { - content: "A tool to move all room store entries to the database.", - header: "Add rooms to directory", - }, - { - header: "Options", - optionList: optionDefinitions, - }, - ])); - process.exit(0); -} -const config: DiscordBridgeConfig = yaml.safeLoad(fs.readFileSync(options.config, "utf8")) as DiscordBridgeConfig; - -const bridge = new Bridge({ - controller: { - onEvent: () => { }, - }, - domain: "rubbish", - homeserverUrl: true, - registration: true, - roomStore: options.store, -}); - -async function run() { - await bridge.loadDatabases(); - const store = new DiscordStore(config.database); - await store.init(); - const rooms = await bridge.getRoomStore().select({}); - // Matrix room only entrys are useless. - const entrys = rooms.filter((r) => r.remote); - entrys.forEach((e) => { - const remote = new RemoteStoreRoom(e.remote_id, e.remote); - const matrix = new MatrixStoreRoom(e.matrix_id); - store.roomStore.linkRooms(matrix, remote).then(() => { - log.info(`Migrated ${matrix.roomId}`); - }).catch((err) => { - log.error(`Failed to link ${matrix.roomId}: `, err); - }); - }); -} - -run().catch((e) => { - log.error(`Failed to run script`, e); -}); -- GitLab