From 935380f0877d99d72da31deaac7a662ab0cbc395 Mon Sep 17 00:00:00 2001 From: Will Hunt <half-shot@molrams.com> Date: Sun, 26 Mar 2017 04:58:13 +0100 Subject: [PATCH] Update DiscordStore functions with v3 changes. --- config/config.sample.yaml | 2 ++ src/clientfactory.ts | 56 +++++++++++++++++---------------- src/dbschema/v3.ts | 10 +++--- src/store.ts | 65 ++++++++++++++++++++++++++------------- 4 files changed, 82 insertions(+), 51 deletions(-) diff --git a/config/config.sample.yaml b/config/config.sample.yaml index af22a18..16c4883 100644 --- a/config/config.sample.yaml +++ b/config/config.sample.yaml @@ -7,3 +7,5 @@ auth: botToken: "foobar" logging: level: "warn" #silly, verbose, info, http, warn, error +database: + filename: "discord.db" diff --git a/src/clientfactory.ts b/src/clientfactory.ts index 816dacb..6589a60 100644 --- a/src/clientfactory.ts +++ b/src/clientfactory.ts @@ -34,32 +34,36 @@ export class DiscordClientFactory { } public getClient(userId?: string): Promise<any> { - let client; - if (userId) { - if (this.clients.has(userId)) { - log.verbose("ClientFactory", "Returning cached user client."); - return Promise.resolve(this.clients.get(userId)); - } - return this.store.get_user_token(userId).then((token) => { - if (token === null) { - return Promise.resolve(this.botClient); - } - client = Bluebird.promisifyAll(new Client({ - fetchAllMembers: true, - sync: true, - messageCacheLifetime: 5, - })); - log.verbose("ClientFactory", "Got user token. Logging in..."); - return client.login(token).then(() => { - log.verbose("ClientFactory", "Logged in. Storing ", userId); - this.clients.set(userId, client); - return Promise.resolve(client); - }).catch((err) => { - log.warn("ClientFactory", `Could not log ${userId} in.`, err); - }); - }); - // Get from cache + if (userId == null) { + return Promise.resolve(this.botClient); + } + return Bluebird.coroutine(this._getClient.bind(this))(userId); + } + + private * _getClient(userId: string): any { + if (this.clients.has(userId)) { + log.verbose("ClientFactory", "Returning cached user client."); + return this.clients.get(userId); + } + const discordIds = yield this.store.get_user_discord_ids(userId); + if (discordIds.length === 0) { + return Promise.resolve(this.botClient); + } + // TODO: Select a profile based on preference, not the first one. + const token = yield this.store.get_token(discordIds[0]); + const client: any = Bluebird.promisifyAll(new Client({ + fetchAllMembers: true, + sync: true, + messageCacheLifetime: 5, + })); + log.verbose("ClientFactory", "Got user token. Logging in..."); + try { + yield client.login(token); + log.verbose("ClientFactory", "Logged in. Storing ", userId); + this.clients.set(userId, client); + return client; + } catch (err) { + log.warn("ClientFactory", `Could not log ${userId} in.`, err); } - return Promise.resolve(this.botClient); } } diff --git a/src/dbschema/v3.ts b/src/dbschema/v3.ts index 206d5d9..b7db4b9 100644 --- a/src/dbschema/v3.ts +++ b/src/dbschema/v3.ts @@ -11,13 +11,15 @@ export class Schema implements IDbSchema { public run(store: DiscordStore): Promise<null> { const promise = Promise.all([store.create_table(` CREATE TABLE user_id_discord_id ( - discord_id TEXT UNIQUE NOT NULL, - user_id TEXT UNIQUE NOT NULL + discord_id TEXT NOT NULL, + user_id TEXT NOT NULL, + PRIMARY KEY(discord_id, user_id) );`, "user_id_discord_id"), store.create_table(` CREATE TABLE discord_id_token ( discord_id TEXT UNIQUE NOT NULL, - token TEXT NOT NULL + token TEXT NOT NULL, + PRIMARY KEY(discord_id) );`, "discord_id_token", )]); return promise.then(() => { @@ -59,7 +61,7 @@ export class Schema implements IDbSchema { log.info("SchemaV3", "Dropping %s from database due to an invalid token."); return null; }).then((dId) => { - if(dId === null) { + if (dId === null) { return null; } discordId = dId; diff --git a/src/store.ts b/src/store.ts index 4b091ae..770a735 100644 --- a/src/store.ts +++ b/src/store.ts @@ -92,12 +92,16 @@ export class DiscordStore { this.db.close(); } - public set_user_token(userId: string, token: string) { + public add_user_token(userId: string, discordId: string, token: string) { log.silly("SQL", "set_user_token => %s", userId); return this.db.runAsync( - `REPLACE INTO user_tokens (userId,token) VALUES ($id,$token);` + ` + INSERT INTO user_id_discord_id (user_id,discord_id) VALUES ($userId,$discordId); + INSERT INTO discord_id_token (discord_id,token) VALUES ($discordId,$token); + ` , { - $id: userId, + $userId: userId, + $discordId: discordId, $token: token, }).catch( (err) => { log.error("TwitDB", "Error storing user token %s", err); @@ -105,32 +109,53 @@ export class DiscordStore { }); } - public delete_user_token(userId: string) { - log.silly("SQL", "delete_user_token => %s", userId); - return this.db.runAsync( - `DELETE FROM user_tokens WHERE userId = $id;` + public delete_user_token(discordId: string) { + log.silly("SQL", "delete_user_token => %s", discordId); + return this.db.execAsync( + ` + DELETE FROM user_id_discord_id WHERE discord_id = $id; + DELETE FROM discord_id_token WHERE discord_id = $id; + ` , { - $id: userId, + $id: discordId, }).catch( (err) => { log.error("TwitDB", "Error deleting user token %s", err); throw err; }); } - public get_user_token(userId: string): Promise<string> { - log.silly("SQL", "get_user_token => %s", userId); + public get_user_discord_ids(userId: string): Promise<string> { + log.silly("SQL", "get_user_discord_ids => %s", userId); return this.db.getAsync( ` - SELECT token - FROM user_tokens - WHERE user_tokens.userId = $id; + SELECT discord_id + FROM user_id_discord_id + WHERE user_id = $userId + `, { + $userId: userId, + }, + ).then( (rows) => { + return rows.map((row) => { return row.discord_id; }); + }).catch( (err) => { + log.error("TwitDB", "Error getting discord ids %s", err.Error); + throw err; + }); + } + + public get_token(discordId: string): Promise<string> { + log.silly("SQL", "discord_id_token => %s", discordId); + return this.db.getAsync( ` - , { - $id: userId, - }).then( (row) => { + SELECT token + FROM discord_id_token + WHERE discord_id = $discordId + `, { + $discordId: discordId, + }, + ).then( (row) => { return row !== undefined ? row.token : null; }).catch( (err) => { - log.error("TwitDB", "Error getting user token %s", err.Error); + log.error("TwitDB", "Error getting discord ids %s", err.Error); throw err; }); } @@ -166,20 +191,18 @@ export class DiscordStore { $discordId: discordId, $discordChannel: discordChannel, $roomId: roomId, - }).then( () => { - return }).catch( (err) => { log.error("TwitDB", "Error executing set_dm_room query %s", err.Error); throw err; }); } - public get_users_tokens(): Promise<any> { + public get_all_user_discord_ids(): Promise<any> { log.silly("SQL", "get_users_tokens"); return this.db.allAsync( ` SELECT * - FROM user_tokens + FROM get_user_discord_ids `, ).then( (rows) => { return rows; -- GitLab