195 lines
4.5 KiB
TypeScript
195 lines
4.5 KiB
TypeScript
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<typeof boardSchema>
|
|
|
|
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<typeof userSchema>
|
|
|
|
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<string> {
|
|
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<string> {
|
|
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<Board, "Wrong params type"> {
|
|
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<Board, "Wrong Type" | "No such Board">
|
|
export function deleteBoard(id?: number): Result<Board, "Wrong Type" | "No such Board">
|
|
export function deleteBoard(board?: Board): Result<Board, "Wrong Type" | "No such Board">
|
|
export function deleteBoard(arg: any): Result<Board, "Wrong Type" | "No such Board"> {
|
|
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<Option<Board>, "Wrong type">
|
|
export function findBoard(id?: number): Result<Option<Board>, "Wrong type">
|
|
export function findBoard(arg: any): Result<Option<Board>, "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`)
|
|
}
|
|
}
|
|
|