mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-11 22:17:14 +03:00
migrate to typescript
This commit is contained in:
committed by
Dainius Dauksevicius
parent
c462323dd5
commit
08d27265fc
13
src/databases/IDatabase.ts
Normal file
13
src/databases/IDatabase.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface IDatabase {
|
||||
init(): void;
|
||||
|
||||
prepare(type: QueryType, query: string, params: any[]): any;
|
||||
|
||||
get<TModel>(query: string, params: any[]): TModel;
|
||||
getAll<TModel>(query: string, params: any[]): TModel[];
|
||||
run(query: string, params: any[]): void;
|
||||
|
||||
exec(query: string): any;
|
||||
}
|
||||
|
||||
export type QueryType = 'get' | 'all' | 'run';
|
||||
@@ -1,28 +0,0 @@
|
||||
var MysqlInterface = require('sync-mysql');
|
||||
const logger = require('../utils/logger.js');
|
||||
|
||||
class Mysql {
|
||||
constructor(msConfig) {
|
||||
this.connection = new MysqlInterface(msConfig);
|
||||
}
|
||||
|
||||
exec(query) {
|
||||
this.prepare('run', query, []);
|
||||
}
|
||||
|
||||
prepare (type, query, params) {
|
||||
logger.debug("prepare (mysql): type: " + type + ", query: " + query + ", params: " + params);
|
||||
if (type === 'get') {
|
||||
return this.connection.query(query, params)[0];
|
||||
} else if (type === 'run') {
|
||||
this.connection.query(query, params);
|
||||
} else if (type === 'all') {
|
||||
return this.connection.query(query, params);
|
||||
} else {
|
||||
logger.warn('returning undefined...');
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Mysql;
|
||||
49
src/databases/Mysql.ts
Normal file
49
src/databases/Mysql.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import {Logger} from '../utils/logger';
|
||||
import {IDatabase, QueryType} from './IDatabase';
|
||||
// @ts-ignore
|
||||
import MysqlInterface from 'sync-mysql';
|
||||
|
||||
export class Mysql implements IDatabase {
|
||||
private connection: any;
|
||||
|
||||
constructor(private config: any) {
|
||||
}
|
||||
|
||||
init() {
|
||||
this.connection = new MysqlInterface(this.config);
|
||||
}
|
||||
|
||||
exec(query: string) {
|
||||
this.prepare('run', query, []);
|
||||
}
|
||||
|
||||
prepare(type: QueryType, query: string, params: any[]) {
|
||||
Logger.debug(`prepare (mysql): type: ${type}, query: ${query}, params: ${params}`);
|
||||
const queryResult = this.connection.query(query, params);
|
||||
|
||||
switch (type) {
|
||||
case 'get': {
|
||||
return queryResult[0];
|
||||
}
|
||||
case 'all': {
|
||||
return queryResult;
|
||||
}
|
||||
case 'run': {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public get<TModel>(query: string, params: any[]): TModel {
|
||||
return this.prepare('get', query, params);
|
||||
}
|
||||
|
||||
public getAll<TModel>(query: string, params: any[]): TModel[] {
|
||||
return this.prepare('all', query, params);
|
||||
}
|
||||
|
||||
public run(query: string, params: any[]): void {
|
||||
this.prepare('run', query, params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
const { db } = require("./databases");
|
||||
var config = require('../config.js');
|
||||
const logger = require('../utils/logger.js');
|
||||
|
||||
class Sqlite {
|
||||
constructor(connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
getConnection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
prepare(type, query, params) {
|
||||
if (type === 'get') {
|
||||
return this.connection.prepare(query).get(...params);
|
||||
} else if (type === 'run') {
|
||||
this.connection.prepare(query).run(...params);
|
||||
} else if (type === 'all') {
|
||||
return this.connection.prepare(query).all(...params);
|
||||
} else {
|
||||
logger.debug('sqlite query: returning undefined')
|
||||
logger.debug("prepare: type: " + type + ", query: " + query + ", params: " + params);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
exec(query) {
|
||||
return this.connection.exec(query);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Sqlite;
|
||||
107
src/databases/Sqlite.ts
Normal file
107
src/databases/Sqlite.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import {IDatabase, QueryType} from './IDatabase';
|
||||
import Sqlite3, {Database, Database as SQLiteDatabase} from 'better-sqlite3';
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import {getHash} from '../utils/getHash';
|
||||
import {Logger} from '../utils/logger';
|
||||
|
||||
export class Sqlite implements IDatabase {
|
||||
private db: SQLiteDatabase;
|
||||
|
||||
constructor(private config: SqliteConfig)
|
||||
{
|
||||
}
|
||||
|
||||
prepare(type: QueryType, query: string, params: any[]) {
|
||||
const preparedQuery = this.db.prepare(query);
|
||||
|
||||
switch (type) {
|
||||
case 'get': {
|
||||
return preparedQuery.get(...params);
|
||||
}
|
||||
case 'all': {
|
||||
return preparedQuery.all(...params);
|
||||
}
|
||||
case 'run': {
|
||||
preparedQuery.run(...params);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get<TModel>(query: string, params: any[]): TModel {
|
||||
return this.prepare('get', query, params);
|
||||
}
|
||||
getAll<TModel>(query: string, params: any[]): TModel[] {
|
||||
return this.prepare('all', query, params);
|
||||
}
|
||||
run(query: string, params: any[]): void {
|
||||
this.prepare('run', query, params);
|
||||
}
|
||||
|
||||
exec(query: string) {
|
||||
return this.db.exec(query);
|
||||
}
|
||||
|
||||
init() {
|
||||
// Make dirs if required
|
||||
if (!fs.existsSync(path.join(this.config.dbPath, "../"))) {
|
||||
fs.mkdirSync(path.join(this.config.dbPath, "../"));
|
||||
}
|
||||
|
||||
this.db = new Sqlite3(this.config.dbPath, {readonly: this.config.readOnly, fileMustExist: !this.config.createDbIfNotExists});
|
||||
|
||||
if (this.config.createDbIfNotExists && !this.config.readOnly && fs.existsSync(this.config.dbSchemaFileName)) {
|
||||
this.db.exec(fs.readFileSync(this.config.dbSchemaFileName).toString());
|
||||
}
|
||||
|
||||
if (!this.config.readOnly) {
|
||||
this.db.function("sha256", (str: string) => {
|
||||
return getHash(str, 1);
|
||||
});
|
||||
|
||||
// Upgrade database if required
|
||||
Sqlite.upgradeDB(this.db, this.config.fileNamePrefix, this.config.dbSchemaFolder);
|
||||
}
|
||||
|
||||
// Enable WAL mode checkpoint number
|
||||
if (this.config.enableWalCheckpointNumber) {
|
||||
this.db.exec("PRAGMA journal_mode=WAL;");
|
||||
this.db.exec("PRAGMA wal_autocheckpoint=1;");
|
||||
}
|
||||
|
||||
// Enable Memory-Mapped IO
|
||||
this.db.exec("pragma mmap_size= 500000000;");
|
||||
}
|
||||
|
||||
attachDatabase(database: string, attachAs: string) {
|
||||
this.db.prepare(`ATTACH ? as ${attachAs}`).run(database);
|
||||
}
|
||||
|
||||
private static upgradeDB(db: Database, fileNamePrefix: string, schemaFolder: string) {
|
||||
const versionCodeInfo = db.prepare("SELECT value FROM config WHERE key = ?").get("version");
|
||||
let versionCode = versionCodeInfo ? versionCodeInfo.value : 0;
|
||||
|
||||
let path = schemaFolder + "/_upgrade_" + fileNamePrefix + "_" + (parseInt(versionCode) + 1) + ".sql";
|
||||
Logger.debug('db update: trying ' + path);
|
||||
while (fs.existsSync(path)) {
|
||||
Logger.debug('db update: updating ' + path);
|
||||
db.exec(fs.readFileSync(path).toString());
|
||||
|
||||
versionCode = db.prepare("SELECT value FROM config WHERE key = ?").get("version").value;
|
||||
path = schemaFolder + "/_upgrade_" + fileNamePrefix + "_" + (parseInt(versionCode) + 1) + ".sql";
|
||||
Logger.debug('db update: trying ' + path);
|
||||
}
|
||||
Logger.debug('db update: no file ' + path);
|
||||
}
|
||||
}
|
||||
|
||||
export interface SqliteConfig {
|
||||
dbPath: string;
|
||||
dbSchemaFileName: string;
|
||||
dbSchemaFolder: string;
|
||||
fileNamePrefix: string;
|
||||
readOnly: boolean;
|
||||
createDbIfNotExists: boolean;
|
||||
enableWalCheckpointNumber: boolean
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
var config = require('../config.js');
|
||||
var Sqlite3 = require('better-sqlite3');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var Sqlite = require('./Sqlite.js')
|
||||
var Mysql = require('./Mysql.js');
|
||||
const logger = require('../utils/logger.js');
|
||||
const getHash = require('../utils/getHash.js');
|
||||
|
||||
let options = {
|
||||
readonly: config.readOnly,
|
||||
fileMustExist: !config.createDatabaseIfNotExist
|
||||
};
|
||||
|
||||
if (config.mysql) {
|
||||
module.exports = {
|
||||
db: new Mysql(config.mysql),
|
||||
privateDB: new Mysql(config.privateMysql)
|
||||
};
|
||||
} else {
|
||||
// Make dirs if required
|
||||
if (!fs.existsSync(path.join(config.db, "../"))) {
|
||||
fs.mkdirSync(path.join(config.db, "../"));
|
||||
}
|
||||
if (!fs.existsSync(path.join(config.privateDB, "../"))) {
|
||||
fs.mkdirSync(path.join(config.privateDB, "../"));
|
||||
}
|
||||
|
||||
var db = new Sqlite3(config.db, options);
|
||||
var privateDB = new Sqlite3(config.privateDB, options);
|
||||
|
||||
if (config.createDatabaseIfNotExist && !config.readOnly) {
|
||||
if (fs.existsSync(config.dbSchema)) db.exec(fs.readFileSync(config.dbSchema).toString());
|
||||
if (fs.existsSync(config.privateDBSchema)) privateDB.exec(fs.readFileSync(config.privateDBSchema).toString());
|
||||
}
|
||||
|
||||
if (!config.readOnly) {
|
||||
db.function("sha256", (string) => {
|
||||
return getHash(string, 1);
|
||||
});
|
||||
|
||||
// Upgrade database if required
|
||||
ugradeDB(db, "sponsorTimes");
|
||||
ugradeDB(privateDB, "private")
|
||||
}
|
||||
|
||||
// Attach private db to main db
|
||||
db.prepare("ATTACH ? as privateDB").run(config.privateDB);
|
||||
|
||||
// Enable WAL mode checkpoint number
|
||||
if (!config.readOnly && config.mode === "production") {
|
||||
db.exec("PRAGMA journal_mode=WAL;");
|
||||
db.exec("PRAGMA wal_autocheckpoint=1;");
|
||||
}
|
||||
|
||||
// Enable Memory-Mapped IO
|
||||
db.exec("pragma mmap_size= 500000000;");
|
||||
privateDB.exec("pragma mmap_size= 500000000;");
|
||||
|
||||
module.exports = {
|
||||
db: new Sqlite(db),
|
||||
privateDB: new Sqlite(privateDB)
|
||||
};
|
||||
|
||||
function ugradeDB(db, prefix) {
|
||||
let versionCodeInfo = db.prepare("SELECT value FROM config WHERE key = ?").get("version");
|
||||
let versionCode = versionCodeInfo ? versionCodeInfo.value : 0;
|
||||
|
||||
let path = config.schemaFolder + "/_upgrade_" + prefix + "_" + (parseInt(versionCode) + 1) + ".sql";
|
||||
logger.debug('db update: trying ' + path);
|
||||
while (fs.existsSync(path)) {
|
||||
logger.debug('db update: updating ' + path);
|
||||
db.exec(fs.readFileSync(path).toString());
|
||||
|
||||
versionCode = db.prepare("SELECT value FROM config WHERE key = ?").get("version").value;
|
||||
path = config.schemaFolder + "/_upgrade_" + prefix + "_" + (parseInt(versionCode) + 1) + ".sql";
|
||||
logger.debug('db update: trying ' + path);
|
||||
}
|
||||
logger.debug('db update: no file ' + path);
|
||||
}
|
||||
}
|
||||
47
src/databases/databases.ts
Normal file
47
src/databases/databases.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import {config} from '../config';
|
||||
import {Sqlite} from './Sqlite';
|
||||
import {Mysql} from './Mysql';
|
||||
import {IDatabase} from './IDatabase';
|
||||
|
||||
|
||||
let db: IDatabase;
|
||||
let privateDB: IDatabase;
|
||||
if (config.mysql) {
|
||||
db = new Mysql(config.mysql);
|
||||
privateDB = new Mysql(config.privateMysql);
|
||||
}
|
||||
else {
|
||||
db = new Sqlite({
|
||||
dbPath: config.db,
|
||||
dbSchemaFileName: config.dbSchema,
|
||||
dbSchemaFolder: config.schemaFolder,
|
||||
fileNamePrefix: 'sponsorTimes',
|
||||
readOnly: config.readOnly,
|
||||
createDbIfNotExists: config.createDatabaseIfNotExist,
|
||||
enableWalCheckpointNumber: !config.readOnly && config.mode === "production"
|
||||
});
|
||||
privateDB = new Sqlite({
|
||||
dbPath: config.privateDB,
|
||||
dbSchemaFileName: config.privateDBSchema,
|
||||
dbSchemaFolder: config.schemaFolder,
|
||||
fileNamePrefix: 'private',
|
||||
readOnly: config.readOnly,
|
||||
createDbIfNotExists: config.createDatabaseIfNotExist,
|
||||
enableWalCheckpointNumber: false
|
||||
});
|
||||
}
|
||||
function initDb() {
|
||||
db.init();
|
||||
privateDB.init();
|
||||
|
||||
if (db instanceof Sqlite) {
|
||||
// Attach private db to main db
|
||||
(db as Sqlite).attachDatabase(config.privateDB, 'privateDB');
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
db,
|
||||
privateDB,
|
||||
initDb,
|
||||
}
|
||||
Reference in New Issue
Block a user