import createDebug from "debug" ; import { Store } from "keyv" ; import { Pg } from "../util/q" ; export interface CacheStore < T > extends Store < T > { get ( id ) : Promise < T | undefined > ; set ( id , data ) : Promise < void > ; delete ( id ) : Promise < boolean > ; clear ( ) : Promise < void > ; } export interface CacheService { draw : CacheStore < Buffer > ; http : CacheStore < string > ; } const debug = createDebug ( "chess:cache" ) ; export default async ( { pg } ) : Promise < CacheService > => { const createStore = < T > ( name ) : CacheStore < T > => ( { async get ( id ) { const { rows } = await pg . query ( { name : `get ${ name }` , text : `
          select data from ${ name }
          where id = $1
        ` , values : [ id ] , } ) ; if ( rows . length !== 0 ) { debug ( `HIT ${ name }: ${ id }` ) ; return rows [ 0 ] . data ; } else { debug ( `MISS ${ name }: ${ id }` ) ; return undefined ; } } , async set ( id , data ) { debug ( `SET ${ name }: ${ id }` ) ; await pg . query ( { name : `set ${ name }` , text : `
          insert into ${ name } (id, data)
            values ($1, $2)
          on conflict (id) do update
            set data = $2
        ` , values : [ id , data ] , } ) ; } , async delete ( id ) { debug ( `DEL ${ name }: ${ id }` ) ; const { rowCount } = await pg . query ( { name : `delete ${ name }` , text : `
          delete from ${ name }
          where id = $1
        ` , values : [ id ] , } ) ; return rowCount !== 0 ; } , async clear ( ) { debug ( `CLEAR ${ name }` ) ; await pg . query ( { name : `clear ${ name }` , text : `
          truncate table ${ name }
        ` , } ) ; } , } ) ; return { draw : createStore < Buffer > ( "draw_cache" ) , http : createStore < string > ( "http_cache" ) , } ; } ;