Continued progress on character creation

main
Mari 1 year ago
parent 8714891c2e
commit 0291c73e80
  1. 6
      src/commands/character/create.ts
  2. 6
      src/commands/character/index.ts
  3. 4
      src/commands/index.ts
  4. 4
      src/database/battle_types.ts
  5. 32
      src/database/characters.ts
  6. 4
      src/database/genders.ts
  7. 28
      src/database/index.ts
  8. 4
      src/database/users.ts
  9. 6
      src/managers/battle_types.ts
  10. 9
      src/managers/characters.ts
  11. 8
      src/managers/genders.ts
  12. 2
      src/managers/index.ts
  13. 6
      src/managers/users.ts

@ -1,6 +1,6 @@
import {ApplicationCommandOptionType, ApplicationCommandSubCommandData, ChatInputCommandInteraction} from "discord.js" import {ApplicationCommandOptionType, ApplicationCommandSubCommandData, ChatInputCommandInteraction} from "discord.js"
import {SubcommandData} from "../types" import {SubcommandData} from "../types"
import {UsersTable} from "../../database/users.js" import {UserTable} from "../../database/users.js"
export class CharacterCreateCommand extends SubcommandData { export class CharacterCreateCommand extends SubcommandData {
readonly definition: ApplicationCommandSubCommandData = { readonly definition: ApplicationCommandSubCommandData = {
@ -68,9 +68,9 @@ export class CharacterCreateCommand extends SubcommandData {
}, },
], ],
} }
private readonly _users: UsersTable private readonly _users: UserTable
constructor({users}: { users: UsersTable }) { constructor({users}: { users: UserTable }) {
super() super()
this._users = users this._users = users
} }

@ -1,14 +1,14 @@
import {ApplicationCommandOptionType, ApplicationCommandSubCommandData, ApplicationCommandType} from "discord.js" import {ApplicationCommandOptionType, ApplicationCommandSubCommandData, ApplicationCommandType} from "discord.js"
import {BaseChatInputCommandData, CommandWithSubcommandsData, SubcommandData} from "../types" import {BaseChatInputCommandData, CommandWithSubcommandsData, SubcommandData} from "../types"
import {UsersTable} from "../../database/users.js" import {UserTable} from "../../database/users.js"
import {CharacterCreateCommand} from "./create.js" import {CharacterCreateCommand} from "./create.js"
export class CharacterCommand extends CommandWithSubcommandsData { export class CharacterCommand extends CommandWithSubcommandsData {
readonly create: CharacterCreateCommand readonly create: CharacterCreateCommand
readonly subcommands: SubcommandData[] readonly subcommands: SubcommandData[]
private readonly _users: UsersTable private readonly _users: UserTable
constructor({users}: { users: UsersTable }) { constructor({users}: { users: UserTable }) {
super() super()
this._users = users this._users = users
this.create = new CharacterCreateCommand({users}) this.create = new CharacterCreateCommand({users})

@ -10,7 +10,7 @@ import {
import {CharacterCommand} from "./character/index" import {CharacterCommand} from "./character/index"
import {autocompleteNotImplementedError, CommandData} from "./types" import {autocompleteNotImplementedError, CommandData} from "./types"
import {BotCommand} from "./bot/index" import {BotCommand} from "./bot/index"
import {UsersTable} from "../database/users.js" import {UserTable} from "../database/users.js"
export const invalidCommandError = "No command by that name exists." export const invalidCommandError = "No command by that name exists."
@ -21,7 +21,7 @@ export class Commands {
readonly definitions: ApplicationCommandDataResolvable[] readonly definitions: ApplicationCommandDataResolvable[]
private readonly _nameCache: Record<string, CommandData> private readonly _nameCache: Record<string, CommandData>
constructor({users, cleanUp}: { users: UsersTable, cleanUp: () => Promise<void> }) { constructor({users, cleanUp}: { users: UserTable, cleanUp: () => Promise<void> }) {
this.character = new CharacterCommand({users}) this.character = new CharacterCommand({users})
this.bot = new BotCommand({users, cleanUp}) this.bot = new BotCommand({users, cleanUp})
this.all = [ this.all = [

@ -18,11 +18,11 @@ export interface BattleTypeTablesData {
relationships: BattleTypeRelationshipData[] relationships: BattleTypeRelationshipData[]
} }
export interface BattleTypeTables { export interface BattleTypeTable {
getTypesAndRelationships(): Promise<BattleTypeTablesData> getTypesAndRelationships(): Promise<BattleTypeTablesData>
} }
export class BattleTypeTablesImpl implements BattleTypeTables { export class BattleTypeTableImpl implements BattleTypeTable {
private readonly _transact: TransactType private readonly _transact: TransactType
constructor({transact}: { transact: TransactType }) { constructor({transact}: { transact: TransactType }) {

@ -0,0 +1,32 @@
import {TransactType} from "./index";
export interface CharacterTable {
clearOrCreateCharacterEditor(options: {userId: string, deleteFirst: boolean}): Promise<{inserted: number, deleted: number}>
}
export class CharacterTableImpl implements CharacterTable {
private readonly _transact: TransactType
constructor({transact}: { transact: TransactType }) {
this._transact = transact
}
async clearOrCreateCharacterEditor(
{userId, deleteFirst}: { userId: string; deleteFirst: boolean }): Promise<{ inserted: number, deleted: number }> {
const result = {
inserted: 0,
deleted: 0,
}
await this._transact({
readonly: false,
async transaction(query) {
result.deleted = deleteFirst
? (await query("DELETE FROM character_creation WHERE id = $1", [userId])).rowCount
: 0
result.inserted =
(await query("INSERT INTO character_creation (id) VALUES ($1) ON CONFLICT (id) DO NOTHING")).rowCount
}
})
return result
}
}

@ -24,11 +24,11 @@ export interface GenderTablesData {
markers: GenderMarkerData[] markers: GenderMarkerData[]
} }
export interface GenderTables { export interface GenderTable {
getPronounsAndMarkers(): Promise<GenderTablesData> getPronounsAndMarkers(): Promise<GenderTablesData>
} }
export class GenderTablesImpl implements GenderTables { export class GenderTablesImpl implements GenderTable {
private readonly _transact: TransactType private readonly _transact: TransactType
constructor({transact}: { transact: TransactType }) { constructor({transact}: { transact: TransactType }) {

@ -1,7 +1,8 @@
import {QueryResult, QueryResultRow} from "pg" import {QueryResult, QueryResultRow} from "pg"
import {UsersTable, UsersTableImpl} from "./users.js" import {UserTable, UserTableImpl} from "./users.js"
import {BattleTypeTables, BattleTypeTablesImpl} from "./battle_types"; import {BattleTypeTable, BattleTypeTableImpl} from "./battle_types";
import {GenderTables, GenderTablesImpl} from "./gender"; import {GenderTable, GenderTablesImpl} from "./genders";
import {CharacterTable, CharacterTableImpl} from "./characters";
export interface PoolLike { export interface PoolLike {
connect(): Promise<PoolClientLike> connect(): Promise<PoolClientLike>
@ -47,9 +48,10 @@ export function makeTransact(p: PoolLike): TransactType {
} }
export interface Database { export interface Database {
readonly users: UsersTable readonly characters: CharacterTable
readonly gender: GenderTables readonly users: UserTable
readonly battleTypes: BattleTypeTables readonly genders: GenderTable
readonly battleTypes: BattleTypeTable
} }
export interface Queryable { export interface Queryable {
@ -63,13 +65,15 @@ export type QueryType = Queryable["query"]
export type TransactType = (config: {readonly?: boolean, transaction: (client: QueryType, attempts: number) => Promise<void>}) => Promise<void> export type TransactType = (config: {readonly?: boolean, transaction: (client: QueryType, attempts: number) => Promise<void>}) => Promise<void>
export class DatabaseImpl implements Database { export class DatabaseImpl implements Database {
readonly users: UsersTableImpl readonly characters: CharacterTableImpl
readonly gender: GenderTables readonly users: UserTableImpl
readonly battleTypes: BattleTypeTablesImpl readonly genders: GenderTable
readonly battleTypes: BattleTypeTableImpl
constructor({query, transact}: { query: QueryType, transact: TransactType }) { constructor({query, transact}: { query: QueryType, transact: TransactType }) {
this.users = new UsersTableImpl({query}) this.characters = new CharacterTableImpl({transact})
this.gender = new GenderTablesImpl({transact}) this.users = new UserTableImpl({query})
this.battleTypes = new BattleTypeTablesImpl({transact}) this.genders = new GenderTablesImpl({transact})
this.battleTypes = new BattleTypeTableImpl({transact})
} }
} }

@ -1,6 +1,6 @@
import {QueryType} from "./index.js" import {QueryType} from "./index.js"
export interface UsersTable { export interface UserTable {
createUserOrUpdateActiveTime(id: string): Promise<void> createUserOrUpdateActiveTime(id: string): Promise<void>
getUserExistsAndIsAdmin(id: string): Promise<boolean> getUserExistsAndIsAdmin(id: string): Promise<boolean>
@ -8,7 +8,7 @@ export interface UsersTable {
createOrSetUserAsAdmin(id: string): Promise<void> createOrSetUserAsAdmin(id: string): Promise<void>
} }
export class UsersTableImpl implements UsersTable { export class UserTableImpl implements UserTable {
private readonly _query: QueryType private readonly _query: QueryType
constructor({query}: { query: QueryType }) { constructor({query}: { query: QueryType }) {

@ -1,4 +1,4 @@
import {BattleTypeTables} from "../database/battle_types"; import {BattleTypeTable} from "../database/battle_types";
export interface BattleType { export interface BattleType {
id: string, id: string,
@ -14,9 +14,9 @@ export class BattleTypeManager {
private cachedTypeList: BattleType[] = [] private cachedTypeList: BattleType[] = []
private refreshPromise: Promise<void>|null = null private refreshPromise: Promise<void>|null = null
private readonly _table: BattleTypeTables private readonly _table: BattleTypeTable
constructor({battleTypes}: { battleTypes: BattleTypeTables }) { constructor({battleTypes}: { battleTypes: BattleTypeTable }) {
this._table = battleTypes this._table = battleTypes
} }

@ -1,7 +1,14 @@
import {Snowflake} from "discord-api-types/globals"; import {Snowflake} from "discord-api-types/globals";
import {CharacterTable} from "../database/characters";
export class CharacterManager { export class CharacterManager {
async startNewCharacter(user: Snowflake, forceErase: boolean): Promise<{alreadyEditing: boolean}> { private
constructor({characters}: {characters: CharacterTable}) {
}
async startNewCharacter(user: Snowflake, overwrite: boolean): Promise<{alreadyEditing: boolean, created: boolean}> {
} }
async abandonEditedCharacter(user: Snowflake): Promise<{abandoned: boolean}> { async abandonEditedCharacter(user: Snowflake): Promise<{abandoned: boolean}> {

@ -1,4 +1,4 @@
import {GenderTables} from "../database/gender"; import {GenderTable} from "../database/genders";
export interface Pronouns { export interface Pronouns {
id: string id: string
@ -27,10 +27,10 @@ export class GenderManager {
private cachedMarkerList: GenderMarker[] = [] private cachedMarkerList: GenderMarker[] = []
private refreshPromise: Promise<void>|null = null private refreshPromise: Promise<void>|null = null
private readonly _table: GenderTables private readonly _table: GenderTable
constructor({gender}: { gender: GenderTables }) { constructor({genders}: { genders: GenderTable }) {
this._table = gender this._table = genders
} }
async refreshCache(): Promise<void> { async refreshCache(): Promise<void> {

@ -1,6 +1,6 @@
import {BattleTypeManager} from "./battle_types"; import {BattleTypeManager} from "./battle_types";
import {UsersManager} from "./users"; import {UsersManager} from "./users";
import {GenderManager} from "./gender"; import {GenderManager} from "./genders";
import {Database} from "../database"; import {Database} from "../database";
export class Managers { export class Managers {

@ -2,12 +2,12 @@ import {Snowflake} from "discord-api-types/globals";
import {parse as uuidParse, v1 as uuidV1, validate as uuidValidate, version as uuidVersion} from "uuid"; import {parse as uuidParse, v1 as uuidV1, validate as uuidValidate, version as uuidVersion} from "uuid";
import {SnowflakeUtil} from "discord.js"; import {SnowflakeUtil} from "discord.js";
import {fast1a52 as fnvFast1a52} from "fnv-plus"; import {fast1a52 as fnvFast1a52} from "fnv-plus";
import {UsersTable} from "../database/users"; import {UserTable} from "../database/users";
export class UsersManager { export class UsersManager {
private readonly _table: UsersTable private readonly _table: UserTable
constructor({users}: { users: UsersTable }) { constructor({users}: { users: UserTable }) {
this._table = users this._table = users
} }

Loading…
Cancel
Save