Adds ICS
This commit is contained in:
parent
441715675c
commit
a79898b2e9
48 changed files with 2062 additions and 1503 deletions
|
|
@ -5,38 +5,39 @@ import {Container} from "../Container/Container";
|
|||
import {Logger} from "log4js";
|
||||
|
||||
export class DatabaseConnection {
|
||||
private database: Sqlite3.Database;
|
||||
|
||||
constructor(env: DatabaseEnvironment) {
|
||||
this.database = new Database(env.path, {
|
||||
nativeBinding: "node_modules/better-sqlite3/build/Release/better_sqlite3.node",
|
||||
})
|
||||
this.database.pragma('journal_mode = WAL');
|
||||
}
|
||||
|
||||
public execute(query: string, ...args: unknown[]): Sqlite3.RunResult {
|
||||
try {
|
||||
const preparedQuery = this.database.prepare(query);
|
||||
return preparedQuery.run(args);
|
||||
} catch (error) {
|
||||
Container.get<Logger>("logger").error("Failed to execute database connection", error, query, args);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
private database: Sqlite3.Database;
|
||||
|
||||
public fetch<BindParameters extends unknown[] | {} = unknown[], Result = unknown>(query: string, ...args: unknown[]): Result|undefined {
|
||||
const preparedQuery = this.database.prepare<BindParameters, Result>(query);
|
||||
return preparedQuery.get(args);
|
||||
}
|
||||
public fetchAll<BindParameters extends unknown[] | {} = unknown[], Result = unknown>(query: string, ...args: unknown[]): Result[] {
|
||||
const preparedQuery = this.database.prepare<BindParameters, Result>(query);
|
||||
return preparedQuery.all(args);
|
||||
}
|
||||
|
||||
public hasTable(tableName: string): boolean {
|
||||
const sql = "SELECT COUNT(*) as tableCount FROM sqlite_master WHERE type='table' AND name=? LIMIT 1;";
|
||||
|
||||
const result = this.fetch<string[], {tableCount: number}>(sql, tableName);
|
||||
return result != undefined && result.tableCount > 0;
|
||||
constructor(env: DatabaseEnvironment) {
|
||||
this.database = new Database(env.path, {
|
||||
nativeBinding: "node_modules/better-sqlite3/build/Release/better_sqlite3.node",
|
||||
})
|
||||
this.database.pragma('journal_mode = WAL');
|
||||
}
|
||||
|
||||
public execute(query: string, ...args: unknown[]): Sqlite3.RunResult {
|
||||
try {
|
||||
const preparedQuery = this.database.prepare(query);
|
||||
return preparedQuery.run(args);
|
||||
} catch (error) {
|
||||
Container.get<Logger>("logger").error("Failed to execute database connection", error, query, args);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public fetch<BindParameters extends unknown[] | {} = unknown[], Result = unknown>(query: string, ...args: unknown[]): Result | undefined {
|
||||
const preparedQuery = this.database.prepare<BindParameters, Result>(query);
|
||||
return preparedQuery.get(args);
|
||||
}
|
||||
|
||||
public fetchAll<BindParameters extends unknown[] | {} = unknown[], Result = unknown>(query: string, ...args: unknown[]): Result[] {
|
||||
const preparedQuery = this.database.prepare<BindParameters, Result>(query);
|
||||
return preparedQuery.all(args);
|
||||
}
|
||||
|
||||
public hasTable(tableName: string): boolean {
|
||||
const sql = "SELECT COUNT(*) as tableCount FROM sqlite_master WHERE type='table' AND name=? LIMIT 1;";
|
||||
|
||||
const result = this.fetch<string[], { tableCount: number }>(sql, tableName);
|
||||
return result != undefined && result.tableCount > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
export type DatabaseColumnDefinition = {
|
||||
name: string;
|
||||
type: string;
|
||||
primaryKey?: boolean;
|
||||
autoIncrement?: boolean;
|
||||
notNull?: boolean;
|
||||
options?: string;
|
||||
name: string;
|
||||
type: string;
|
||||
primaryKey?: boolean;
|
||||
autoIncrement?: boolean;
|
||||
notNull?: boolean;
|
||||
options?: string;
|
||||
}
|
||||
|
||||
export type DatabaseDefinition = {
|
||||
name: string;
|
||||
columns: DatabaseColumnDefinition[];
|
||||
name: string;
|
||||
columns: DatabaseColumnDefinition[];
|
||||
}
|
||||
|
|
@ -4,78 +4,82 @@ import {Container} from "../Container/Container";
|
|||
import {Logger} from "log4js";
|
||||
|
||||
export class DatabaseUpdater {
|
||||
constructor(private readonly database: DatabaseConnection) {}
|
||||
|
||||
public ensureAvaliablity(definitions: Iterable<DatabaseDefinition>) {
|
||||
for (const definition of definitions) {
|
||||
this.ensureDefinition(definition);
|
||||
}
|
||||
}
|
||||
|
||||
private ensureDefinition(definition: DatabaseDefinition) {
|
||||
if (this.database.hasTable(definition.name)) {
|
||||
this.ensureTableColumns(definition);
|
||||
return;
|
||||
}
|
||||
|
||||
this.createTable(definition);
|
||||
}
|
||||
|
||||
private ensureTableColumns(definition: DatabaseDefinition) {
|
||||
const DBSQLColumns = this.database.fetchAll<object, {name: string, type: string}>(
|
||||
`PRAGMA table_info("${definition.name}")`
|
||||
);
|
||||
|
||||
if (!DBSQLColumns) {
|
||||
Container.get<Logger>("logger").log("Request failed...");
|
||||
return;
|
||||
}
|
||||
|
||||
const missingColumns = definition.columns.filter(
|
||||
(column: DatabaseColumnDefinition) => {
|
||||
return !DBSQLColumns.some((dbColumn: DatabaseColumnDefinition) => {
|
||||
return column.name === dbColumn.name
|
||||
});
|
||||
}
|
||||
)
|
||||
|
||||
if (missingColumns.length < 1) {
|
||||
Container.get<Logger>("logger").log(`No new columns found for ${definition.name}`)
|
||||
return;
|
||||
}
|
||||
|
||||
const columnsSQL = missingColumns.map((column: DatabaseColumnDefinition) => {
|
||||
const values = [
|
||||
"ADD",
|
||||
column.name,
|
||||
column.type,
|
||||
column.primaryKey ? `PRIMARY KEY` : '',
|
||||
column.notNull ? 'NOT NULL' : '',
|
||||
column.autoIncrement ? 'AUTOINCREMENT' : '',
|
||||
]
|
||||
constructor(private readonly database: DatabaseConnection) {
|
||||
}
|
||||
|
||||
return values.join(' ');
|
||||
}).join(', ');
|
||||
|
||||
const sql = `ALTER TABLE ${definition.name} ${columnsSQL}`;
|
||||
this.database.execute(sql);
|
||||
public ensureAvaliablity(definitions: Iterable<DatabaseDefinition>) {
|
||||
for (const definition of definitions) {
|
||||
this.ensureDefinition(definition);
|
||||
}
|
||||
}
|
||||
|
||||
private ensureDefinition(definition: DatabaseDefinition) {
|
||||
if (this.database.hasTable(definition.name)) {
|
||||
this.ensureTableColumns(definition);
|
||||
return;
|
||||
}
|
||||
|
||||
this.createTable(definition);
|
||||
}
|
||||
|
||||
private createTable(definition: DatabaseDefinition) {
|
||||
const columnsSQL = definition.columns.map((column: DatabaseColumnDefinition) => {
|
||||
const values = [
|
||||
column.name,
|
||||
column.type,
|
||||
column.primaryKey ? `PRIMARY KEY` : '',
|
||||
column.notNull ? 'NOT NULL' : '',
|
||||
column.autoIncrement ? 'AUTOINCREMENT' : '',
|
||||
]
|
||||
|
||||
return values.join(' ');
|
||||
}).join(', ');
|
||||
|
||||
const sql = `CREATE TABLE IF NOT EXISTS ${definition.name} (${columnsSQL})`;
|
||||
this.database.execute(sql);
|
||||
private ensureTableColumns(definition: DatabaseDefinition) {
|
||||
const DBSQLColumns = this.database.fetchAll<object, { name: string, type: string }>(
|
||||
`PRAGMA table_info("${definition.name}")`
|
||||
);
|
||||
|
||||
if (!DBSQLColumns) {
|
||||
Container.get<Logger>("logger").log("Request failed...");
|
||||
return;
|
||||
}
|
||||
|
||||
const missingColumns = definition.columns.filter(
|
||||
(column: DatabaseColumnDefinition) => {
|
||||
return !DBSQLColumns.some((dbColumn: DatabaseColumnDefinition) => {
|
||||
return column.name === dbColumn.name
|
||||
});
|
||||
}
|
||||
)
|
||||
|
||||
if (missingColumns.length < 1) {
|
||||
Container.get<Logger>("logger").log(`No new columns found for ${definition.name}`)
|
||||
return;
|
||||
}
|
||||
|
||||
const columnsSQL = missingColumns.map((column: DatabaseColumnDefinition) => {
|
||||
const values = [
|
||||
"ADD",
|
||||
column.name,
|
||||
column.type,
|
||||
column.primaryKey ? `PRIMARY KEY` : '',
|
||||
column.notNull ? 'NOT NULL' : '',
|
||||
column.autoIncrement ? 'AUTOINCREMENT' : '',
|
||||
]
|
||||
|
||||
return values.join(' ');
|
||||
}).join(', ');
|
||||
|
||||
const sql = `ALTER TABLE ${definition.name} ${columnsSQL}`;
|
||||
this.database.execute(sql);
|
||||
}
|
||||
|
||||
|
||||
private createTable(definition: DatabaseDefinition) {
|
||||
const columnsSQL = definition.columns.map((column: DatabaseColumnDefinition) => {
|
||||
const values = [
|
||||
column.name,
|
||||
column.type,
|
||||
column.primaryKey ? `PRIMARY KEY` : '',
|
||||
column.notNull ? 'NOT NULL' : '',
|
||||
column.autoIncrement ? 'AUTOINCREMENT' : '',
|
||||
]
|
||||
|
||||
return values.join(' ');
|
||||
}).join(', ');
|
||||
|
||||
const sql = `CREATE TABLE IF NOT EXISTS ${definition.name}
|
||||
(
|
||||
${columnsSQL}
|
||||
)`;
|
||||
this.database.execute(sql);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,9 @@ import Playdate from "./tables/Playdate";
|
|||
import GroupConfiguration from "./tables/GroupConfiguration";
|
||||
|
||||
const definitions = new Set<DatabaseDefinition>([
|
||||
Groups,
|
||||
Playdate,
|
||||
GroupConfiguration
|
||||
Groups,
|
||||
Playdate,
|
||||
GroupConfiguration
|
||||
]);
|
||||
|
||||
export default definitions;
|
||||
|
|
@ -1,34 +1,34 @@
|
|||
import {DatabaseDefinition} from "../DatabaseDefinition";
|
||||
|
||||
export type DBGroupConfiguration = {
|
||||
id: number;
|
||||
groupid: number;
|
||||
key: string;
|
||||
value: string;
|
||||
id: number;
|
||||
groupid: number;
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const dbDefinition: DatabaseDefinition = {
|
||||
name: "groupConfiguration",
|
||||
columns: [
|
||||
{
|
||||
name: "id",
|
||||
type: "INTEGER",
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
{
|
||||
name: "groupid",
|
||||
type: "VARCHAR(32)",
|
||||
},
|
||||
{
|
||||
name: "key",
|
||||
type: "VARCHAR(32)",
|
||||
},
|
||||
{
|
||||
name: "value",
|
||||
type: "VARCHAR(128)",
|
||||
}
|
||||
]
|
||||
name: "groupConfiguration",
|
||||
columns: [
|
||||
{
|
||||
name: "id",
|
||||
type: "INTEGER",
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
{
|
||||
name: "groupid",
|
||||
type: "VARCHAR(32)",
|
||||
},
|
||||
{
|
||||
name: "key",
|
||||
type: "VARCHAR(32)",
|
||||
},
|
||||
{
|
||||
name: "value",
|
||||
type: "VARCHAR(128)",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default dbDefinition;
|
||||
|
|
@ -1,39 +1,39 @@
|
|||
import {DatabaseDefinition} from "../DatabaseDefinition";
|
||||
|
||||
export type DBGroup = {
|
||||
id: number;
|
||||
name: string;
|
||||
server: string;
|
||||
leader: string;
|
||||
role: string;
|
||||
id: number;
|
||||
name: string;
|
||||
server: string;
|
||||
leader: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
const dbDefinition: DatabaseDefinition = {
|
||||
name: "groups",
|
||||
columns: [
|
||||
{
|
||||
name: "id",
|
||||
type: "INTEGER",
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
{
|
||||
name: "server",
|
||||
type: "VARCHAR(32)"
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
type: "VARCHAR(32)",
|
||||
},
|
||||
{
|
||||
name: "leader",
|
||||
type: "VARCHAR(32)",
|
||||
},
|
||||
{
|
||||
name: "role",
|
||||
type: "VARCHAR(32)",
|
||||
}
|
||||
]
|
||||
name: "groups",
|
||||
columns: [
|
||||
{
|
||||
name: "id",
|
||||
type: "INTEGER",
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
{
|
||||
name: "server",
|
||||
type: "VARCHAR(32)"
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
type: "VARCHAR(32)",
|
||||
},
|
||||
{
|
||||
name: "leader",
|
||||
type: "VARCHAR(32)",
|
||||
},
|
||||
{
|
||||
name: "role",
|
||||
type: "VARCHAR(32)",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default dbDefinition;
|
||||
|
|
@ -1,35 +1,35 @@
|
|||
import {DatabaseDefinition} from "../DatabaseDefinition";
|
||||
|
||||
export type DBPlaydate = {
|
||||
id: number;
|
||||
groupid: number;
|
||||
id: number;
|
||||
groupid: number;
|
||||
|
||||
time_from: number;
|
||||
time_to: number;
|
||||
time_from: number;
|
||||
time_to: number;
|
||||
}
|
||||
|
||||
const dbDefinition: DatabaseDefinition = {
|
||||
name: "playdates",
|
||||
columns: [
|
||||
{
|
||||
name: "id",
|
||||
type: "INTEGER",
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
{
|
||||
name: "groupid",
|
||||
type: "INTEGER",
|
||||
},
|
||||
{
|
||||
name: "time_from",
|
||||
type: "TIMESTAMP",
|
||||
},
|
||||
{
|
||||
name: "time_to",
|
||||
type: "TIMESTAMP",
|
||||
}
|
||||
]
|
||||
name: "playdates",
|
||||
columns: [
|
||||
{
|
||||
name: "id",
|
||||
type: "INTEGER",
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
{
|
||||
name: "groupid",
|
||||
type: "INTEGER",
|
||||
},
|
||||
{
|
||||
name: "time_from",
|
||||
type: "TIMESTAMP",
|
||||
},
|
||||
{
|
||||
name: "time_to",
|
||||
type: "TIMESTAMP",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default dbDefinition;
|
||||
Loading…
Add table
Add a link
Reference in a new issue