add some test files
This commit is contained in:
		
							
								
								
									
										3
									
								
								bun.lock
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								bun.lock
									
									
									
									
									
								
							@@ -7,6 +7,7 @@
 | 
			
		||||
        "@trpc/client": "^10.45.2",
 | 
			
		||||
        "@trpc/server": "^10.45.2",
 | 
			
		||||
        "@types/lodash": "^4.17.16",
 | 
			
		||||
        "lodash": "^4.17.21",
 | 
			
		||||
        "log-symbols": "^7.0.0",
 | 
			
		||||
        "pinia": "^3.0.1",
 | 
			
		||||
        "trpc-bun-adapter": "^1.2.2",
 | 
			
		||||
@@ -434,6 +435,8 @@
 | 
			
		||||
 | 
			
		||||
    "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.29.2", "", { "os": "win32", "cpu": "x64" }, "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA=="],
 | 
			
		||||
 | 
			
		||||
    "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
 | 
			
		||||
 | 
			
		||||
    "log-symbols": ["log-symbols@7.0.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0", "yoctocolors": "^2.1.1" } }, "sha512-zrc91EDk2M+2AXo/9BTvK91pqb7qrPg2nX/Hy+u8a5qQlbaOflCKO+6SqgZ+M+xUFxGdKTgwnGiL96b1W3ikRA=="],
 | 
			
		||||
 | 
			
		||||
    "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
    "@trpc/client": "^10.45.2",
 | 
			
		||||
    "@trpc/server": "^10.45.2",
 | 
			
		||||
    "@types/lodash": "^4.17.16",
 | 
			
		||||
    "lodash": "^4.17.21",
 | 
			
		||||
    "log-symbols": "^7.0.0",
 | 
			
		||||
    "pinia": "^3.0.1",
 | 
			
		||||
    "trpc-bun-adapter": "^1.2.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,25 @@
 | 
			
		||||
import _ from "lodash"
 | 
			
		||||
import { z } from "zod";
 | 
			
		||||
 | 
			
		||||
export const uint8 = z.number().nonnegative().lt(Math.pow(2, 8))
 | 
			
		||||
export const uint16 = z.number().nonnegative().lt(Math.pow(2, 16))
 | 
			
		||||
export const uint32 = z.number().nonnegative().lt(Math.pow(2, 32))
 | 
			
		||||
 | 
			
		||||
export const int8 = z.number().lt(Math.pow(2, 7)).gte(-Math.pow(2, 8))
 | 
			
		||||
export const int16 = z.number().lt(Math.pow(2, 15)).gte(-Math.pow(2, 16))
 | 
			
		||||
export const int32 = z.number().lt(Math.pow(2, 31)).gte(-Math.pow(2, 32))
 | 
			
		||||
 | 
			
		||||
export function numberToBytes(num: number, bytesLength: number): Uint8Array {
 | 
			
		||||
  var array = new Uint8Array(bytesLength)
 | 
			
		||||
 | 
			
		||||
  var i;
 | 
			
		||||
  for (i = 0; i < bytesLength; i++) {
 | 
			
		||||
  for (let i = 0; i < bytesLength; i++) {
 | 
			
		||||
    array[i] = num & (0xFF << (i << 3))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return array
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function randomFromArray(array: Array<any>) {
 | 
			
		||||
  return array[_.random(0, array.length - 1, false)]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,39 @@
 | 
			
		||||
import { test, expect } from "bun:test"
 | 
			
		||||
import * as db from "./database.ts"
 | 
			
		||||
import _ from "lodash"
 | 
			
		||||
import { randomFromArray } from "./common.ts"
 | 
			
		||||
import { None, Ok } from "ts-results-es"
 | 
			
		||||
 | 
			
		||||
test("DataBase", () => {
 | 
			
		||||
  const allTables = db.allTables()
 | 
			
		||||
  expect(allTables).toBeArray()
 | 
			
		||||
  expect(allTables).toEqual(["Users", "Boards"])
 | 
			
		||||
  expect(db.boardsNum()).toBe(0)
 | 
			
		||||
  expect(db.BoardTable.count()).toBe(0)
 | 
			
		||||
  expect(db.UserTable.count()).toBe(0)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("Board Table", () => {
 | 
			
		||||
  const boardsNumber = 10
 | 
			
		||||
  const rooms = ["A1", "A2"]
 | 
			
		||||
 | 
			
		||||
  // Try to find something empty
 | 
			
		||||
  const findEmptyByID = db.BoardTable.find(_.random(0, boardsNumber))
 | 
			
		||||
  expect(findEmptyByID).toEqual(Ok(None))
 | 
			
		||||
  const findEmptyByName = db.BoardTable.find("Hello")
 | 
			
		||||
  expect(findEmptyByName).toEqual(Ok(None))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  const boardsArray: Array<db.Board> = []
 | 
			
		||||
  for (let i = 0; i < boardsNumber; i++) {
 | 
			
		||||
    boardsArray.push({
 | 
			
		||||
      id: _.random(0, 100),
 | 
			
		||||
      name: `Board ${i}`,
 | 
			
		||||
      room: randomFromArray(rooms),
 | 
			
		||||
      ipv4: `192.168.172.${i}`,
 | 
			
		||||
      port: _.random(0, 665535),
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
import { Database } from "bun:sqlite";
 | 
			
		||||
import { Database, type Changes } 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();
 | 
			
		||||
initDB(db);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const boardSchema = z.object({
 | 
			
		||||
@@ -13,7 +13,7 @@ const boardSchema = z.object({
 | 
			
		||||
  room: z.string(),
 | 
			
		||||
  ipv4: z.string().ip({ version: "v4" }),
 | 
			
		||||
  ipv6: z.string().ip({ version: "v6" }),
 | 
			
		||||
  port: z.number().nonnegative(),
 | 
			
		||||
  port: z.number().nonnegative().lte(65535),
 | 
			
		||||
  cmdID: z.number().nonnegative()
 | 
			
		||||
}).partial({
 | 
			
		||||
  ipv6: true,
 | 
			
		||||
@@ -42,7 +42,7 @@ export function isUser(obj: any): obj is User {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function initDB() {
 | 
			
		||||
function initDB(db: Database) {
 | 
			
		||||
  const tables = allTables()
 | 
			
		||||
 | 
			
		||||
  if (!tables.includes("Users")) {
 | 
			
		||||
@@ -91,18 +91,21 @@ export function tableColumnName(table: string): Array<string> {
 | 
			
		||||
  return columnName
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function addBoard(board: Board): Result<Board, "Wrong params type"> {
 | 
			
		||||
export namespace BoardTable {
 | 
			
		||||
 | 
			
		||||
  export function add(board: Board): Result<Changes, "Wrong type" | "ID conflict"> {
 | 
			
		||||
    if (!isBoard(board)) {
 | 
			
		||||
    return new Err("Wrong params type")
 | 
			
		||||
      return new Err("Wrong type")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (board.id == 0) {
 | 
			
		||||
    const idNum = boardsNum()
 | 
			
		||||
    board.id = idNum
 | 
			
		||||
  } else {
 | 
			
		||||
 | 
			
		||||
      const cnt = count()
 | 
			
		||||
      board.id = cnt + 1
 | 
			
		||||
    } else if (includes(board.id)) {
 | 
			
		||||
      return new Err("ID conflict")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const query = db.query(`
 | 
			
		||||
    INSERT INTO Boards VALUES 
 | 
			
		||||
    (${board.id},
 | 
			
		||||
@@ -112,41 +115,65 @@ export function addBoard(board: Board): Result<Board, "Wrong params type"> {
 | 
			
		||||
    '${typeof board.ipv6 === "undefined" ? "NULL" : board.ipv6}',
 | 
			
		||||
    ${board.port});
 | 
			
		||||
  `)
 | 
			
		||||
  query.run()
 | 
			
		||||
 | 
			
		||||
  return Ok(board)
 | 
			
		||||
    return Ok(query.run())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
export function boardsNum(): number {
 | 
			
		||||
  export function addFromArray(array: Array<Board>): Result<Board, "Wrong type"> {
 | 
			
		||||
    for (const item of array) {
 | 
			
		||||
      const ret = add(item)
 | 
			
		||||
      if (ret.isErr()) {
 | 
			
		||||
        return new Err("Wrong type")
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return new Ok()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  export function count(): 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"> {
 | 
			
		||||
  export function remove(name?: string): Result<Board, "Wrong Type" | "No such Board">
 | 
			
		||||
  export function remove(id?: number): Result<Board, "Wrong Type" | "No such Board">
 | 
			
		||||
  export function remove(board?: Board): Result<Board, "Wrong Type" | "No such Board">
 | 
			
		||||
  export function remove(arg: any): Result<Board, "Wrong Type" | "No such Board"> {
 | 
			
		||||
    let retBoard
 | 
			
		||||
    let condition: string
 | 
			
		||||
    if (isBoard(arg)) {
 | 
			
		||||
    retBoard = arg
 | 
			
		||||
      retBoard = _.cloneDeep(arg)
 | 
			
		||||
      condition = `id=${arg.id}`
 | 
			
		||||
 | 
			
		||||
    } else if (_.isNumber(arg)) {
 | 
			
		||||
    retBoard = findBoard(arg)
 | 
			
		||||
      retBoard = find(arg)
 | 
			
		||||
      if (retBoard.isOk() && retBoard.value.isSome()) {
 | 
			
		||||
        retBoard = _.cloneDeep(retBoard.value.value)
 | 
			
		||||
        condition = `id=${arg}`
 | 
			
		||||
      } else {
 | 
			
		||||
        return new Err("No such Board")
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    } else if (_.isString(arg)) {
 | 
			
		||||
    retBoard = findBoard(arg)
 | 
			
		||||
      retBoard = find(arg)
 | 
			
		||||
      if (retBoard.isOk() && retBoard.value.isSome()) {
 | 
			
		||||
        retBoard = _.cloneDeep(retBoard.value.value)
 | 
			
		||||
        condition = `name=${arg}`
 | 
			
		||||
      } else {
 | 
			
		||||
        return new Err("No such Board")
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      return new Err("Wrong Type")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  const query = db.query(`DELETE FROM Boards WHERE id=${arg.id}`)
 | 
			
		||||
    const query = db.query(`DELETE FROM Boards WHERE ${condition}`)
 | 
			
		||||
    query.run()
 | 
			
		||||
 | 
			
		||||
    return new Ok(retBoard)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
export function allBoards() {
 | 
			
		||||
  export function all() {
 | 
			
		||||
    const query = db.query(`SELECT * FROM Boards`)
 | 
			
		||||
    const boards = query.all()
 | 
			
		||||
 | 
			
		||||
@@ -155,12 +182,38 @@ export function allBoards() {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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"> {
 | 
			
		||||
  export function find(name: string, room: string): Result<Option<Board>, "Wrong type">
 | 
			
		||||
  export function find(id: number): Result<Option<Board>, "Wrong type">
 | 
			
		||||
  export function find(arg1: any, arg2: any): Result<Option<Board>, "Wrong type"> {
 | 
			
		||||
    let condition: string
 | 
			
		||||
    if (_.isNumber(arg1)) {
 | 
			
		||||
      condition = `id=${arg1}`
 | 
			
		||||
 | 
			
		||||
    } else if (_.isString(arg1)) {
 | 
			
		||||
      condition = `name='${arg1}'`
 | 
			
		||||
 | 
			
		||||
    } 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 includes(name?: string): Result<boolean, "Wrong type">
 | 
			
		||||
  export function includes(id?: number): Result<boolean, "Wrong type">
 | 
			
		||||
  export function includes(arg: any): Result<boolean, "Wrong type"> {
 | 
			
		||||
    let condition: string
 | 
			
		||||
    if (_.isNumber(arg)) {
 | 
			
		||||
    condition = `arg=${arg}`
 | 
			
		||||
      condition = `id=${arg}`
 | 
			
		||||
 | 
			
		||||
    } else if (_.isString(arg)) {
 | 
			
		||||
      condition = `name='${arg}'`
 | 
			
		||||
@@ -173,6 +226,40 @@ export function findBoard(arg: any): Result<Option<Board>, "Wrong type"> {
 | 
			
		||||
    const query = db.query(`SELECT * FROM Boards WHERE ${condition}`)
 | 
			
		||||
 | 
			
		||||
    const spRet = boardSchema.safeParse(query.get())
 | 
			
		||||
 | 
			
		||||
    if (spRet.success) {
 | 
			
		||||
      return new Ok(true)
 | 
			
		||||
    } else {
 | 
			
		||||
      return new Ok(false)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export namespace UserTable {
 | 
			
		||||
 | 
			
		||||
  export function count(): number {
 | 
			
		||||
    const query = db.query(`SELECT COUNT(*) FROM Users`)
 | 
			
		||||
    return query.values()[0][0] as number
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  export function find(id: number): Result<Option<User>, "Wrong Type">
 | 
			
		||||
  export function find(name: string): Result<Option<User>, "Wrong Type">
 | 
			
		||||
  export function find(arg: any): Result<Option<User>, "Wrong Type"> {
 | 
			
		||||
    let condition: string
 | 
			
		||||
    if (_.isNumber(arg)) {
 | 
			
		||||
      condition = `id=${arg}`
 | 
			
		||||
    } else if (_.isString(arg)) {
 | 
			
		||||
      condition = `name=${arg}`
 | 
			
		||||
    } else {
 | 
			
		||||
      return new Err("Wrong Type")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const query = db.query(`SELECT * FROM Users WHERE name='${arg}'`)
 | 
			
		||||
 | 
			
		||||
    const spRet = userSchema.safeParse(query.get())
 | 
			
		||||
 | 
			
		||||
    if (spRet.success) {
 | 
			
		||||
      return new Ok(Some(spRet.data))
 | 
			
		||||
    } else {
 | 
			
		||||
@@ -180,15 +267,6 @@ export function findBoard(arg: any): Result<Option<Board>, "Wrong type"> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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`)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user