import { Database } from "bun:sqlite"; import _ from "lodash"; import { Ok, Err, Result, None, Some, Option } from "ts-results-es"; import { z } from "zod"; const db = new Database("lab.sqlite", { strict: true }) initDB(); const boardSchema = z.object({ id: z.number().nonnegative(), name: z.string(), room: z.string(), ipv4: z.string().ip({ version: "v4" }), ipv6: z.string().ip({ version: "v6" }), port: z.number().nonnegative(), cmdID: z.number().nonnegative() }).partial({ ipv6: true, cmdID: true }) export type Board = z.infer export function isBoard(obj: any): obj is Board { return boardSchema.safeParse(obj).success } const userSchema = z.object({ id: z.number().nonnegative(), name: z.string(), password: z.string(), boardID: z.number(), }).partial({ boardID: true, }) export type User = z.infer export function isUser(obj: any): obj is User { return userSchema.safeParse(obj).success } function initDB() { const tables = allTables() if (!tables.includes("Users")) { db.query(` CREATE TABLE Users( id INT PRIMARY KEY NOT NULL, name TEXT NOT NULL, password TEXT NOT NULL ); `).run(); } if (!tables.includes("Boards")) db.query(` CREATE TABLE Boards( id INT PRIMARY KEY NOT NULL, name TEXT NOT NULL, room TEXT NOT NULL, ipv4 CHAR(16) NOT NULL, ipv6 CHAR(46) , port INT NOT NULL ) `).run(); } export function allTables(): Array { const query = db.query(`SELECT name FROM sqlite_master WHERE type='table'`) var tables = new Array() // Flaten array for (const item of query.values()) { tables.push(item[0]) } query.finalize() return tables } export function tableColumnName(table: string): Array { const query = db.query(`PRAGMA table_info(${table})`) var columnName = new Array() for (const column of query.values()) { columnName.push(column[1]) } return columnName } export function addBoard(board: Board): Result { if (!isBoard(board)) { return new Err("Wrong params type") } if (board.id == 0) { const idNum = boardsNum() board.id = idNum } else { } const query = db.query(` INSERT INTO Boards VALUES (${board.id}, '${board.name}, '${board.room}', '${board.ipv4}', '${typeof board.ipv6 === "undefined" ? "NULL" : board.ipv6}', ${board.port}); `) query.run() return Ok(board) } export function boardsNum(): number { const query = db.query(`SELECT COUNT(*) FROM Boards`) return query.values()[0][0] as number } export function deleteBoard(name?: string): Result export function deleteBoard(id?: number): Result export function deleteBoard(board?: Board): Result export function deleteBoard(arg: any): Result { let retBoard let condition: string if (isBoard(arg)) { retBoard = arg } else if (_.isNumber(arg)) { retBoard = findBoard(arg) } else if (_.isString(arg)) { retBoard = findBoard(arg) } else { return new Err("Wrong Type") } const query = db.query(`DELETE FROM Boards WHERE id=${arg.id}`) return new Ok(retBoard) } export function allBoards() { const query = db.query(`SELECT * FROM Boards`) const boards = query.all() query.finalize() return boards } export function findBoard(name?: string): Result, "Wrong type"> export function findBoard(id?: number): Result, "Wrong type"> export function findBoard(arg: any): Result, "Wrong type"> { let condition: string if (_.isNumber(arg)) { condition = `arg=${arg}` } else if (_.isString(arg)) { condition = `name='${arg}'` } else { return new Err("Wrong type") } const query = db.query(`SELECT * FROM Boards WHERE ${condition}`) const spRet = boardSchema.safeParse(query.get()) if (spRet.success) { return new Ok(Some(spRet.data)) } else { return new Ok(None) } } export function findUser(name: string): User { const query = db.query(`SELECT * FROM Users WHERE name='${name}'`) const spRet = userSchema.safeParse(query.get()) if (spRet.success) { return spRet.data } else { throw new Error(`Failure: Not found ${name} User`) } }