From 8290e5a82131b752dba72399a87489a669be1113 Mon Sep 17 00:00:00 2001 From: Tau Date: Sun, 28 Apr 2019 20:59:37 -0400 Subject: [PATCH] aimedb: Add Postgres backend --- src/aimedb/db.ts | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/aimedb/db.ts diff --git a/src/aimedb/db.ts b/src/aimedb/db.ts new file mode 100644 index 0000000..dc5f71b --- /dev/null +++ b/src/aimedb/db.ts @@ -0,0 +1,94 @@ +import { PoolClient } from "pg"; +import * as sql from "sql-bricks"; + +import { AimeId } from "./model"; +import { CardRepository, Transaction } from "./repo"; +import { connect, generateId, generateExtId } from "../db"; + +class CardRepositoryImpl implements CardRepository { + constructor(private readonly _conn: PoolClient) {} + + async lookup(luid: string, now: Date): Promise { + const fetchSql = sql + .select("c.id", "p.ext_id") + .from("aime.card c") + .join("aime.player p", { "c.player_id": "p.id" }) + .where("c.nfc_id", luid) + .toParams(); + + const { rows } = await this._conn.query(fetchSql); + + if (rows.length === 0) { + return undefined; + } + + const id = rows[0].id; + const extId = rows[0].ext_id; + + const touchSql = sql + .update("aime.card") + .set({ access_time: now }) + .where("id", id) + .toParams(); + + await this._conn.query(touchSql); + + return extId; + } + + async register(luid: string, now: Date): Promise { + const playerId = generateId(); + const cardId = generateId(); + const aimeId = generateExtId() as AimeId; + + const playerSql = sql + .insert("aime.player", { + id: playerId, + ext_id: aimeId, + register_time: now, + }) + .toParams(); + + await this._conn.query(playerSql); + + const cardSql = sql + .insert("aime.card", { + id: cardId, + player_id: playerId, + nfc_id: luid, + register_time: now, + access_time: now, + }) + .toParams(); + + await this._conn.query(cardSql); + + return aimeId; + } +} + +class TransactionImpl implements Transaction { + constructor(private readonly _conn: PoolClient) {} + + cards(): CardRepository { + return new CardRepositoryImpl(this._conn); + } + + async commit(): Promise { + await this._conn.query("commit"); + await this._conn.release(); + } + + async rollback(): Promise { + await this._conn.query("rollback"); + await this._conn.release(); + } +} + +export async function beginDbSession(): Promise { + const conn = await connect(); + + await conn.query("begin"); + + return new TransactionImpl(conn); +}