import { DbLoadCallback , IDatabase } from './IDatabase' ; import { Game , GameId , GameOptions , Score } from '../Game' ; import { IGameData } from './IDatabase' ; import { SerializedGame } from '../SerializedGame' ; import { Dirent } from 'fs' ; const path = require ( 'path' ) ; const fs = require ( 'fs' ) ; const dbFolder = path . resolve ( process . cwd ( ) , './db/files' ) ; const historyFolder = path . resolve ( dbFolder , 'history' ) ; export class Localfilesystem implements IDatabase { constructor ( ) { console . log ( `Starting local database at ${ dbFolder }` ) ; if ( ! fs . existsSync ( dbFolder ) ) { fs . mkdirSync ( dbFolder ) ; } if ( ! fs . existsSync ( historyFolder ) ) { fs . mkdirSync ( historyFolder ) ; } } async initialize ( ) { } _filename ( gameId ) { return path . resolve ( dbFolder , `${ gameId }.json` ) ; } _historyFilename ( gameId , saveId ) { const saveIdString = saveId . toString ( ) . padStart ( 5 , '0' ) ; return path . resolve ( historyFolder , `${ gameId }-${ saveIdString }.json` ) ; } saveGame ( game ) { console . log ( `saving ${ game . id } at position ${ game . lastSaveId }` ) ; this . saveSerializedGame ( game . serialize ( ) ) ; game . lastSaveId ++ ; return Promise . resolve ( ) ; } saveSerializedGame ( serializedGame ) { const text = JSON . stringify ( serializedGame , null , 2 ) ; fs . writeFileSync ( this . _filename ( serializedGame . id ) , text ) ; fs . writeFileSync ( this . _historyFilename ( serializedGame . id , serializedGame . lastSaveId ) , text ) ; } getGame ( game_id , cb ) { try { console . log ( `Loading ${ game_id }` ) ; const text = fs . readFileSync ( this . _filename ( game_id ) ) ; const serializedGame = JSON . parse ( text ) ; cb ( undefined , serializedGame ) ; } catch ( e ) { const error = e instanceof Error ? e : new Error ( String ( e ) ) ; cb ( error , undefined ) ; } } getGameId ( _playerId , _cb ) { throw new Error ( 'Not implemented' ) ; } getGameVersion ( _game_id , _save_id , _cb ) { throw new Error ( 'Not implemented' ) ; } getClonableGames ( cb ) { this . getGames ( ( err , gameIds ) => { const filtered = gameIds . filter ( ( gameId ) => fs . existsSync ( this . _historyFilename ( gameId , 0 ) ) ) ; const gameData = filtered . map ( ( gameId ) => { const text = fs . readFileSync ( this . _historyFilename ( gameId , 0 ) ) ; const serializedGame = JSON . parse ( text ) as SerializedGame ; return { gameId : gameId , playerCount : serializedGame . players . length } ; } ) ; cb ( err , gameData ) ; } ) ; } loadCloneableGame ( game_id , cb ) { try { console . log ( `Loading ${ game_id } at save point 0` ) ; const text = fs . readFileSync ( this . _historyFilename ( game_id , 0 ) ) ; const serializedGame = JSON . parse ( text ) ; cb ( undefined , serializedGame ) ; } catch ( e ) { const error = e instanceof Error ? e : new Error ( String ( e ) ) ; cb ( error , undefined ) ; } } getGames ( cb ) { const gameIds = [ ] ; fs . readdirSync ( dbFolder , { withFileTypes : true } ) . forEach ( ( dirent ) => { if ( ! dirent . isFile ( ) ) { return ; } const re = /(.*).json/ ; const result = dirent . name . match ( re ) ; if ( result === null ) { return ; } gameIds . push ( result [ 1 ] ) ; } ) ; cb ( undefined , gameIds ) ; } restoreReferenceGame ( _gameId , cb ) { cb ( new Error ( 'Does not work' ) , undefined ) ; } saveGameResults ( _gameId , _players , _generations , _gameOptions , _scores ) { } cleanSaves ( _gameId , _save_id ) { } purgeUnfinishedGames ( ) { } restoreGame ( _gameId , _save_id , _cb ) { throw new Error ( 'Undo not yet implemented' ) ; } deleteGameNbrSaves ( _gameId , _rollbackCount ) { throw new Error ( 'Rollback not yet implemented' ) ; } }