add basic test for database
This commit is contained in:
parent
f368638f6e
commit
8fa594159f
|
@ -9,6 +9,7 @@ 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 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 const int32 = z.number().lt(Math.pow(2, 31)).gte(-Math.pow(2, 32))
|
||||||
|
|
||||||
|
export namespace fun {
|
||||||
export function numberToBytes(num: number, bytesLength: number): Uint8Array {
|
export function numberToBytes(num: number, bytesLength: number): Uint8Array {
|
||||||
var array = new Uint8Array(bytesLength)
|
var array = new Uint8Array(bytesLength)
|
||||||
|
|
||||||
|
@ -22,4 +23,6 @@ export function numberToBytes(num: number, bytesLength: number): Uint8Array {
|
||||||
export function randomFromArray(array: Array<any>) {
|
export function randomFromArray(array: Array<any>) {
|
||||||
return array[_.random(0, array.length - 1, false)]
|
return array[_.random(0, array.length - 1, false)]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,39 +1,58 @@
|
||||||
import { test, expect } from "bun:test"
|
import { test, expect } from "bun:test"
|
||||||
import * as db from "./database.ts"
|
import * as db from "./database.ts"
|
||||||
import _ from "lodash"
|
import _ from "lodash"
|
||||||
import { randomFromArray } from "./common.ts"
|
import { None, Ok, Option, Some } from "ts-results-es"
|
||||||
import { None, Ok } from "ts-results-es"
|
|
||||||
|
|
||||||
test("DataBase", () => {
|
test("DataBase", () => {
|
||||||
const allTables = db.allTables()
|
const allTables = db.allTables()
|
||||||
expect(allTables).toBeArray()
|
expect(allTables).toBeArray()
|
||||||
expect(allTables).toEqual(["Users", "Boards"])
|
expect(allTables).toEqual(["Users", "Boards"])
|
||||||
expect(db.BoardTable.count()).toBe(0)
|
expect(db.BoardTable.countAll()).toBe(0)
|
||||||
expect(db.UserTable.count()).toBe(0)
|
expect(db.UserTable.countAll()).toBe(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("Board Table", () => {
|
test("Board Table", () => {
|
||||||
const boardsNumber = 10
|
const boardsNumber = 10
|
||||||
const rooms = ["A1", "A2"]
|
const rooms = ["A1", "A1", "A1", "A1", "A1", "A2", "A2", "A2", "A2", "A2"]
|
||||||
|
|
||||||
// Try to find something empty
|
// Try to find something empty
|
||||||
const findEmptyByID = db.BoardTable.find(_.random(0, boardsNumber))
|
const findEmptyByID = db.BoardTable.find(_.random(0, boardsNumber))
|
||||||
expect(findEmptyByID).toEqual(Ok(None))
|
expect(findEmptyByID).toEqual(Ok(None))
|
||||||
const findEmptyByName = db.BoardTable.find("Hello")
|
const findEmptyByName = db.BoardTable.find("Hello", "World")
|
||||||
expect(findEmptyByName).toEqual(Ok(None))
|
expect(findEmptyByName).toEqual(Ok(None))
|
||||||
|
|
||||||
|
|
||||||
const boardsArray: Array<db.Board> = []
|
const boardsArray: Array<db.Board> = []
|
||||||
for (let i = 0; i < boardsNumber; i++) {
|
for (let i = 0; i < boardsNumber; i++) {
|
||||||
boardsArray.push({
|
boardsArray.push({
|
||||||
id: _.random(0, 100),
|
id: i,
|
||||||
name: `Board ${i}`,
|
name: `Board ${i}`,
|
||||||
room: randomFromArray(rooms),
|
room: rooms[i],
|
||||||
ipv4: `192.168.172.${i}`,
|
ipv4: `192.168.172.${i}`,
|
||||||
port: _.random(0, 665535),
|
port: i,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
db.BoardTable.addFromArray(boardsArray)
|
||||||
|
|
||||||
|
// Test Find
|
||||||
|
expect(db.BoardTable.find(1)).toEqual(Ok(Some({
|
||||||
|
id: 1,
|
||||||
|
name: `Board ${1}`,
|
||||||
|
room: rooms[1],
|
||||||
|
ipv4: `192.168.172.${1}`,
|
||||||
|
port: 1,
|
||||||
|
} as db.Board)))
|
||||||
|
expect(db.BoardTable.find("Board 3", "A1")).toEqual(Ok(Some({
|
||||||
|
id: 3,
|
||||||
|
name: `Board ${3}`,
|
||||||
|
room: rooms[3],
|
||||||
|
ipv4: `192.168.172.${3}`,
|
||||||
|
port: 3,
|
||||||
|
} as db.Board)))
|
||||||
|
|
||||||
|
// Test Count
|
||||||
|
expect(db.BoardTable.countByName("Board 1")).toBe(1)
|
||||||
|
expect(db.BoardTable.countByRoom("A1")).toBe(5)
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -93,18 +93,35 @@ export function tableColumnName(table: string): Array<string> {
|
||||||
|
|
||||||
export namespace BoardTable {
|
export namespace BoardTable {
|
||||||
|
|
||||||
export function add(board: Board): Result<Changes, "Wrong type" | "ID conflict"> {
|
export function add(board: Board): Result<Changes, "Wrong type" | "ID conflict" | "Name conflict in one room"> {
|
||||||
if (!isBoard(board)) {
|
if (!isBoard(board)) {
|
||||||
return new Err("Wrong type")
|
return new Err("Wrong type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure no id conflict
|
||||||
if (board.id == 0) {
|
if (board.id == 0) {
|
||||||
const cnt = count()
|
const cnt = countAll()
|
||||||
board.id = cnt + 1
|
board.id = cnt + 1
|
||||||
} else if (includes(board.id)) {
|
} else {
|
||||||
return new Err("ID conflict")
|
const retID = includes(board.id)
|
||||||
|
if (retID.isOk()) {
|
||||||
|
if (retID.value) return new Err("ID conflict")
|
||||||
|
} else {
|
||||||
|
return new Err("Wrong type")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure no name conflict in the same room
|
||||||
|
{
|
||||||
|
const retName = includes(board.name, board.room)
|
||||||
|
if (retName.isOk()) {
|
||||||
|
if (retName.value) {
|
||||||
|
return new Err("Name conflict in one room")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return new Err("Wrong type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const query = db.query(`
|
const query = db.query(`
|
||||||
INSERT INTO Boards VALUES
|
INSERT INTO Boards VALUES
|
||||||
|
@ -112,53 +129,74 @@ export namespace BoardTable {
|
||||||
'${board.name},
|
'${board.name},
|
||||||
'${board.room}',
|
'${board.room}',
|
||||||
'${board.ipv4}',
|
'${board.ipv4}',
|
||||||
'${typeof board.ipv6 === "undefined" ? "NULL" : board.ipv6}',
|
'${_.isUndefined(board.ipv6) ? "NULL" : board.ipv6}',
|
||||||
${board.port});
|
${board.port});
|
||||||
`)
|
`)
|
||||||
|
|
||||||
return Ok(query.run())
|
return Ok(query.run())
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addFromArray(array: Array<Board>): Result<Board, "Wrong type"> {
|
export function addFromArray(array: Array<Board>): Result<Array<Changes>, "Wrong type"> {
|
||||||
|
let arrayChanges: Array<Changes> = []
|
||||||
for (const item of array) {
|
for (const item of array) {
|
||||||
const ret = add(item)
|
const ret = add(item)
|
||||||
if (ret.isErr()) {
|
if (ret.isErr()) {
|
||||||
return new Err("Wrong type")
|
return new Err("Wrong type")
|
||||||
|
} else {
|
||||||
|
arrayChanges.push(ret.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Ok()
|
return new Ok(arrayChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function count(): number {
|
export function all() {
|
||||||
|
const query = db.query(`SELECT * FROM Boards`)
|
||||||
|
const boards = query.all()
|
||||||
|
|
||||||
|
query.finalize()
|
||||||
|
return boards
|
||||||
|
}
|
||||||
|
|
||||||
|
export function countAll(): number {
|
||||||
const query = db.query(`SELECT COUNT(*) FROM Boards`)
|
const query = db.query(`SELECT COUNT(*) FROM Boards`)
|
||||||
return query.values()[0][0] as number
|
return query.values()[0][0] as number
|
||||||
}
|
}
|
||||||
|
|
||||||
export function remove(name?: string): Result<Board, "Wrong Type" | "No such Board">
|
export function countByName(name: string): number {
|
||||||
export function remove(id?: number): Result<Board, "Wrong Type" | "No such Board">
|
const query = db.query(`SELECT * FROM Boards WHERE name=${name}`)
|
||||||
export function remove(board?: Board): Result<Board, "Wrong Type" | "No such Board">
|
return query.values()[0][0] as number
|
||||||
export function remove(arg: any): Result<Board, "Wrong Type" | "No such Board"> {
|
}
|
||||||
|
|
||||||
|
export function countByRoom(room: string): number {
|
||||||
|
const query = db.query(`SELECT * FROM Boards WHERE room=${room}`)
|
||||||
|
return query.values()[0][0] as number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function remove(name: string, room: 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(arg1: any, arg2?: any): Result<Board, "Wrong Type" | "No such Board"> {
|
||||||
let retBoard
|
let retBoard
|
||||||
let condition: string
|
let condition: string
|
||||||
if (isBoard(arg)) {
|
if (isBoard(arg1)) {
|
||||||
retBoard = _.cloneDeep(arg)
|
retBoard = _.cloneDeep(arg1)
|
||||||
condition = `id=${arg.id}`
|
condition = `id=${arg1.id}`
|
||||||
|
|
||||||
} else if (_.isNumber(arg)) {
|
} else if (_.isNumber(arg1)) {
|
||||||
retBoard = find(arg)
|
retBoard = find(arg1)
|
||||||
if (retBoard.isOk() && retBoard.value.isSome()) {
|
if (retBoard.isOk() && retBoard.value.isSome()) {
|
||||||
retBoard = _.cloneDeep(retBoard.value.value)
|
retBoard = _.cloneDeep(retBoard.value.value)
|
||||||
condition = `id=${arg}`
|
condition = `id=${arg1}`
|
||||||
} else {
|
} else {
|
||||||
return new Err("No such Board")
|
return new Err("No such Board")
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (_.isString(arg)) {
|
} else if (_.isString(arg1) && _.isString(arg2)) {
|
||||||
retBoard = find(arg)
|
retBoard = find(arg1, arg2)
|
||||||
if (retBoard.isOk() && retBoard.value.isSome()) {
|
if (retBoard.isOk() && retBoard.value.isSome()) {
|
||||||
retBoard = _.cloneDeep(retBoard.value.value)
|
retBoard = _.cloneDeep(retBoard.value.value)
|
||||||
condition = `name=${arg}`
|
condition = `name=${arg1}`
|
||||||
} else {
|
} else {
|
||||||
return new Err("No such Board")
|
return new Err("No such Board")
|
||||||
}
|
}
|
||||||
|
@ -173,28 +211,18 @@ export namespace BoardTable {
|
||||||
return new Ok(retBoard)
|
return new Ok(retBoard)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function all() {
|
|
||||||
const query = db.query(`SELECT * FROM Boards`)
|
|
||||||
const boards = query.all()
|
|
||||||
|
|
||||||
query.finalize()
|
|
||||||
return boards
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function find(name: string, room: string): 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(id: number): Result<Option<Board>, "Wrong type">
|
||||||
export function find(arg1: any, arg2: any): Result<Option<Board>, "Wrong type"> {
|
export function find(arg1: any, arg2?: any): Result<Option<Board>, "Wrong type"> {
|
||||||
let condition: string
|
let condition: string
|
||||||
if (_.isNumber(arg1)) {
|
if (_.isNumber(arg1)) {
|
||||||
condition = `id=${arg1}`
|
condition = `id=${arg1}`
|
||||||
|
|
||||||
} else if (_.isString(arg1)) {
|
} else if (_.isString(arg1) && _.isString(arg2)) {
|
||||||
condition = `name='${arg1}'`
|
condition = `name='${arg1}' AND room='${arg2}'`
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return new Err("Wrong type")
|
return new Err("Wrong type")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = db.query(`SELECT * FROM Boards WHERE ${condition}`)
|
const query = db.query(`SELECT * FROM Boards WHERE ${condition}`)
|
||||||
|
@ -208,37 +236,39 @@ export namespace BoardTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function includes(name?: string): Result<boolean, "Wrong type">
|
export function includes(name: string, room?: string): Result<boolean, "Wrong type">
|
||||||
export function includes(id?: number): Result<boolean, "Wrong type">
|
export function includes(id: number): Result<boolean, "Wrong type">
|
||||||
export function includes(arg: any): Result<boolean, "Wrong type"> {
|
export function includes(arg1: any, arg2?: any): Result<boolean, "Wrong type"> {
|
||||||
let condition: string
|
let condition: string
|
||||||
if (_.isNumber(arg)) {
|
if (_.isUndefined(arg2)) {
|
||||||
condition = `id=${arg}`
|
if (_.isNumber(arg1)) {
|
||||||
|
condition = `id=${arg1}`
|
||||||
|
|
||||||
} else if (_.isString(arg)) {
|
} else if (_.isString(arg1)) {
|
||||||
condition = `name='${arg}'`
|
condition = `name='${arg1}'`
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return new Err("Wrong type")
|
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(true)
|
|
||||||
} else {
|
} else {
|
||||||
return new Ok(false)
|
if (_.isString(arg1) && _.isString(arg2)) {
|
||||||
|
condition = `name='${arg1} AND room=${arg2}'`
|
||||||
|
} else {
|
||||||
|
return new Err("Wrong type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const query = db.query(`SELECT COUNT(*) FROM Boards WHERE ${condition}`)
|
||||||
|
const num = query.values()[0][0] as number
|
||||||
|
|
||||||
|
return new Ok(num > 0 ? true : false)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace UserTable {
|
export namespace UserTable {
|
||||||
|
|
||||||
export function count(): number {
|
export function countAll(): number {
|
||||||
const query = db.query(`SELECT COUNT(*) FROM Users`)
|
const query = db.query(`SELECT COUNT(*) FROM Users`)
|
||||||
return query.values()[0][0] as number
|
return query.values()[0][0] as number
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue