This commit is contained in:
Chongyi Zheng 2024-05-01 09:51:01 -06:00 committed by GitHub
commit 8878b281fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 149 additions and 7 deletions

View File

@ -5,10 +5,11 @@ const { log } = require("../src/util");
* DO NOT ADD ANYTHING HERE!
* IF YOU NEED TO ADD FIELDS, ADD IT TO ./db/knex_migrations
* See ./db/knex_migrations/README.md for more information
* @param {"mariadb"|"postgres"} dbType database type, should be either "mariadb" or "postgres"
* @returns {Promise<void>}
*/
async function createTables() {
log.info("mariadb", "Creating basic tables for MariaDB");
async function createTables(dbType) {
log.info(dbType, "Creating basic tables");
const knex = R.knex;
// TODO: Should check later if it is really the final patch sql file.

90
package-lock.json generated
View File

@ -91,6 +91,7 @@
"@popperjs/core": "~2.10.2",
"@types/bootstrap": "~5.1.9",
"@types/node": "^20.8.6",
"@types/pg": "^8.10.2",
"@typescript-eslint/eslint-plugin": "^6.7.5",
"@typescript-eslint/parser": "^6.7.5",
"@vitejs/plugin-vue": "~5.0.1",
@ -4220,6 +4221,74 @@
"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
"dev": true
},
"node_modules/@types/pg": {
"version": "8.10.2",
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.2.tgz",
"integrity": "sha512-MKFs9P6nJ+LAeHLU3V0cODEOgyThJ3OAnmOlsZsxux6sfQs3HRXR5bBn7xG5DjckEFhTAxsXi7k7cd0pCMxpJw==",
"dev": true,
"dependencies": {
"@types/node": "*",
"pg-protocol": "*",
"pg-types": "^4.0.1"
}
},
"node_modules/@types/pg/node_modules/pg-types": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz",
"integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==",
"dev": true,
"dependencies": {
"pg-int8": "1.0.1",
"pg-numeric": "1.0.2",
"postgres-array": "~3.0.1",
"postgres-bytea": "~3.0.0",
"postgres-date": "~2.0.1",
"postgres-interval": "^3.0.0",
"postgres-range": "^1.1.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@types/pg/node_modules/postgres-array": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz",
"integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/@types/pg/node_modules/postgres-bytea": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz",
"integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==",
"dev": true,
"dependencies": {
"obuf": "~1.1.2"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/@types/pg/node_modules/postgres-date": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz",
"integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/@types/pg/node_modules/postgres-interval": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz",
"integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/@types/qs": {
"version": "6.9.14",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz",
@ -10695,6 +10764,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/obuf": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
"dev": true
},
"node_modules/oidc-token-hash": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz",
@ -11065,6 +11140,15 @@
"node": ">=4.0.0"
}
},
"node_modules/pg-numeric": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz",
"integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/pg-pool": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz",
@ -11341,6 +11425,12 @@
"node": ">=0.10.0"
}
},
"node_modules/postgres-range": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz",
"integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==",
"dev": true
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",

View File

@ -156,6 +156,7 @@
"@popperjs/core": "~2.10.2",
"@types/bootstrap": "~5.1.9",
"@types/node": "^20.8.6",
"@types/pg": "^8.10.2",
"@typescript-eslint/eslint-plugin": "^6.7.5",
"@typescript-eslint/parser": "^6.7.5",
"@vitejs/plugin-vue": "~5.0.1",

View File

@ -6,6 +6,7 @@ const knex = require("knex");
const path = require("path");
const { EmbeddedMariaDB } = require("./embedded-mariadb");
const mysql = require("mysql2/promise");
const pg = require("pg");
/**
* Database & App Data Folder
@ -186,6 +187,18 @@ class Database {
fs.writeFileSync(path.join(Database.dataDir, "db-config.json"), JSON.stringify(dbConfig, null, 4));
}
/**
* Validate a database name
* @param {string} dbName Database name to validate
* @throws {Error} If the database name is invalid
* @returns {void}
*/
static validateDBName(dbName) {
if (!/^\w+$/.test(dbName)) {
throw Error("Invalid database name. A database name can only consist of letters, numbers and underscores");
}
}
/**
* Connect to the database
* @param {boolean} testMode Should the connection be started in test mode?
@ -217,7 +230,6 @@ class Database {
log.info("db", `Database Type: ${dbConfig.type}`);
if (dbConfig.type === "sqlite") {
if (! fs.existsSync(Database.sqlitePath)) {
log.info("server", "Copying Database");
fs.copyFileSync(Database.templatePath, Database.sqlitePath);
@ -242,9 +254,7 @@ class Database {
}
};
} else if (dbConfig.type === "mariadb") {
if (!/^\w+$/.test(dbConfig.dbName)) {
throw Error("Invalid database name. A database name can only consist of letters, numbers and underscores");
}
this.validateDBName(dbConfig.dbName);
const connection = await mysql.createConnection({
host: dbConfig.hostname,
@ -296,6 +306,24 @@ class Database {
},
pool: mariadbPoolConfig,
};
} else if (dbConfig.type === "postgres") {
this.validateDBName(dbConfig.dbName);
const clientConfig = {
host: dbConfig.hostname,
port: dbConfig.port,
user: dbConfig.username,
password: dbConfig.password,
database: dbConfig.dbName,
};
const client = new pg.Client(clientConfig);
await client.execute("CREATE DATABASE IF NOT EXISTS " + dbConfig.dbName);
await client.end();
config = {
client: "pg",
connection: clientConfig,
};
} else {
throw new Error("Unknown Database type: " + dbConfig.type);
}
@ -328,6 +356,8 @@ class Database {
await this.initSQLite(testMode, noLog);
} else if (dbConfig.type.endsWith("mariadb")) {
await this.initMariaDB();
} else if (dbConfig.type === "postgres") {
await this.initPostgres();
}
}
@ -377,6 +407,22 @@ class Database {
}
}
/**
* Initialize PostgresDB
* @returns {Promise<void>}
*/
static async initPostgres() {
log.debug("db", "Checking if PostgresDB database exists...");
let hasTable = await R.hasTable("docker_host");
if (!hasTable) {
const { createTables } = require("../db/knex_init_db");
await createTables();
} else {
log.debug("db", "PostgresDB database already exists");
}
}
/**
* Patch the database
* @returns {Promise<void>}
@ -702,13 +748,17 @@ class Database {
/**
* @returns {string} Get the SQL for the current time plus a number of hours
* @throws {Error} If the database type is unknown
*/
static sqlHourOffset() {
if (Database.dbConfig.type === "sqlite") {
return "DATETIME('now', ? || ' hours')";
} else {
} else if (Database.dbConfig.type.endsWith("mariadb")) {
return "DATE_ADD(NOW(), INTERVAL ? HOUR)";
} else if (Database.dbConfig.type === "postgres") {
return "NOW() + INTERVAL '? HOUR'";
}
throw new Error("Unknown database type: " + Database.dbConfig.type);
}
}