parent
88018a0f16
commit
1fd98e04c6
@ -0,0 +1,18 @@ |
||||
export interface BattleType { |
||||
id: number, |
||||
name: string, |
||||
emoji: string, |
||||
color: string, |
||||
displayOrder: number, |
||||
immmunities: BattleTypeStub[] |
||||
resistances: BattleTypeStub[] |
||||
weaknesses: BattleTypeStub[] |
||||
} |
||||
|
||||
export interface BattleTypeStub { |
||||
id: number, |
||||
name: string, |
||||
emoji: string, |
||||
color: string, |
||||
displayOrder: number |
||||
} |
@ -0,0 +1,64 @@ |
||||
import {QueryType, Transactable} from "./database.js" |
||||
import {Snowflake} from "discord-api-types/globals.js" |
||||
import {Pronouns} from "./pronouns.js" |
||||
|
||||
export interface CharacterCreationState { |
||||
name: string | null |
||||
title: string | null |
||||
profile: string | null |
||||
gender: string | null |
||||
pronouns: Pronouns | null |
||||
difficulty: Difficulty | null |
||||
preference: Preference | null |
||||
type1: BattleType | null, |
||||
type2: BattleType | null, |
||||
baseConfidence: number | null, |
||||
baseHealth: number | null, |
||||
baseStamina: number | null, |
||||
baseBrawn: number | null, |
||||
baseDurability: number | null, |
||||
baseIntensity: number | null, |
||||
baseResilience: number | null, |
||||
baseSpeed: number | null, |
||||
} |
||||
|
||||
export interface CharacterCreationInput { |
||||
name?: string |
||||
title?: string |
||||
profile?: string |
||||
gender?: string |
||||
pronouns?: string |
||||
difficultyName?: string |
||||
preferenceName?: string |
||||
type1Name?: string |
||||
type2Name?: string |
||||
baseConfidence?: number |
||||
baseHealth?: number |
||||
baseStamina?: number |
||||
baseBrawn?: number |
||||
baseDurability?: number |
||||
baseIntensity?: number |
||||
baseResilience?: number |
||||
baseSpeed?: number |
||||
} |
||||
|
||||
export interface CharacterCreationTable { |
||||
startOrContinueCreatingCharacter(snowflake: Snowflake, |
||||
input: CharacterCreationInput): Promise<CharacterCreationState> |
||||
} |
||||
|
||||
export class CharacterCreationTableImpl implements CharacterCreationTable { |
||||
private readonly _query: QueryType |
||||
private readonly _transactable: Transactable |
||||
|
||||
constructor({query, transactable}: { query: QueryType, transactable: Transactable }) { |
||||
this._query = query |
||||
this._transactable = transactable |
||||
} |
||||
|
||||
async startOrContinueCreatingCharacter( |
||||
owner: Snowflake, |
||||
input: CharacterCreationInput): Promise<CharacterCreationState> { |
||||
|
||||
} |
||||
} |
@ -1,16 +1,71 @@ |
||||
import {Client} from "pg" |
||||
import {QueryResult, QueryResultRow} from "pg" |
||||
import {UsersTable, UsersTableImpl} from "./users.js" |
||||
import {CharacterCreationTable, CharacterCreationTableImpl} from "./character_creation.js" |
||||
|
||||
export interface PoolLike { |
||||
connect(): Promise<PoolClientLike> |
||||
} |
||||
|
||||
export interface PoolClientLike extends Queryable { |
||||
release(err?: boolean): void |
||||
} |
||||
|
||||
export function makeTransactable(p: PoolLike): Transactable { |
||||
return async function transactable(callback: (q: QueryType, attempts: number) => Promise<void>): Promise<void> { |
||||
const client = await p.connect() |
||||
const query = client.query.bind(client) |
||||
let committed = false |
||||
let attempts = 0 |
||||
while (!committed) { |
||||
try { |
||||
await client.query("BEGIN") |
||||
} catch (err) { |
||||
client.release() |
||||
throw err |
||||
} |
||||
try { |
||||
await callback(query, attempts) |
||||
} catch (err) { |
||||
try { |
||||
await client.query("ROLLBACK") |
||||
client.release() |
||||
} catch (err) { |
||||
client.release(true) |
||||
} |
||||
throw err |
||||
} |
||||
try { |
||||
await client.query("COMMIT") |
||||
committed = true |
||||
} catch (err) { |
||||
attempts += 1 |
||||
} |
||||
} |
||||
client.release() |
||||
} |
||||
} |
||||
|
||||
export interface Database { |
||||
readonly users: UsersTable |
||||
readonly characterCreation: CharacterCreationTable |
||||
} |
||||
|
||||
export interface Queryable { |
||||
query<RowT extends QueryResultRow>(queryText: string): Promise<QueryResult<RowT>> |
||||
|
||||
query<RowT extends QueryResultRow, ParamT extends any[]>(queryText: string, |
||||
params: ParamT): Promise<QueryResult<RowT>> |
||||
} |
||||
|
||||
export type QueryType = Queryable["query"] |
||||
export type Transactable = (transaction: (client: QueryType, attempts: number) => Promise<void>) => Promise<void> |
||||
|
||||
export class DatabaseImpl implements Database { |
||||
readonly users: UsersTableImpl |
||||
private readonly _query: Client["query"] |
||||
readonly characterCreation: CharacterCreationTableImpl |
||||
|
||||
constructor(query: Client["query"]) { |
||||
this._query = query |
||||
this.users = new UsersTableImpl(this._query) |
||||
constructor({query, transactable}: { query: QueryType, transactable: Transactable }) { |
||||
this.users = new UsersTableImpl({query}) |
||||
this.characterCreation = new CharacterCreationTableImpl({query, transactable}) |
||||
} |
||||
} |
@ -0,0 +1,22 @@ |
||||
export interface Pronouns { |
||||
id: number |
||||
defaultGender: string |
||||
pronouns: string |
||||
displayOrder: number |
||||
usePlural: boolean |
||||
subjective: string |
||||
adjective: string |
||||
possessive: string |
||||
reflexive: string |
||||
objective: string |
||||
} |
||||
|
||||
export interface PronounsAutocomplete { |
||||
pronouns: string |
||||
usePlural: boolean |
||||
subjective: string |
||||
adjective: string |
||||
possessive: string |
||||
reflexive: string |
||||
objective: string |
||||
} |
Loading…
Reference in new issue