1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-06-06 23:36:23 +02:00
pigallery2/src/backend/model/database/sql/SQLConnection.ts

243 lines
8.3 KiB
TypeScript
Raw Normal View History

2018-03-30 15:30:30 -04:00
import 'reflect-metadata';
import {Connection, ConnectionOptions, createConnection, getConnection} from 'typeorm';
import {UserEntity} from './enitites/UserEntity';
import {UserRoles} from '../../../../common/entities/UserDTO';
2018-03-30 15:30:30 -04:00
import {PhotoEntity} from './enitites/PhotoEntity';
import {DirectoryEntity} from './enitites/DirectoryEntity';
import {Config} from '../../../../common/config/private/Config';
2018-03-30 15:30:30 -04:00
import {SharingEntity} from './enitites/SharingEntity';
import {PasswordHelper} from '../../PasswordHelper';
import {ProjectPath} from '../../../ProjectPath';
2018-03-30 15:30:30 -04:00
import {VersionEntity} from './enitites/VersionEntity';
import {Logger} from '../../../Logger';
import {MediaEntity} from './enitites/MediaEntity';
import {VideoEntity} from './enitites/VideoEntity';
import {DataStructureVersion} from '../../../../common/DataStructureVersion';
2018-11-26 00:26:29 +01:00
import {FileEntity} from './enitites/FileEntity';
2019-01-12 16:41:45 +01:00
import {FaceRegionEntry} from './enitites/FaceRegionEntry';
import {PersonEntry} from './enitites/PersonEntry';
import {Utils} from '../../../../common/Utils';
2019-12-29 00:35:41 +01:00
import * as path from 'path';
import {DatabaseType, ServerDataBaseConfig, SQLLogLevel} from '../../../../common/config/private/PrivateConfig';
import {AlbumBaseEntity} from './enitites/album/AlbumBaseEntity';
import {SavedSearchEntity} from './enitites/album/SavedSearchEntity';
import {NotificationManager} from '../../NotifocationManager';
2022-02-22 14:06:52 +01:00
import {ActiveExperiments, Experiments} from '../../../../../benchmark/Experiments';
2016-12-27 16:09:47 +01:00
const LOG_TAG = '[SQLConnection]';
2016-12-27 16:09:47 +01:00
export class SQLConnection {
2016-12-27 16:09:47 +01:00
private static connection: Connection = null;
constructor() {
2017-07-03 19:17:49 +02:00
}
2016-12-27 16:09:47 +01:00
2017-07-03 19:17:49 +02:00
public static async getConnection(): Promise<Connection> {
2022-02-22 14:06:52 +01:00
if (ActiveExperiments[Experiments.db.name] === Experiments.db.groups.sqlite3) {
Config.Server.Database.type = DatabaseType.sqlite;
}
if (ActiveExperiments[Experiments.db.name] === Experiments.db.groups.betterSqlite) {
Config.Server.Database.type = DatabaseType.better_sqlite3;
}
2017-07-03 19:17:49 +02:00
if (this.connection == null) {
const options: any = this.getDriver(Config.Server.Database);
2018-12-22 11:49:56 +01:00
// options.name = 'main';
2017-10-19 12:08:07 -04:00
options.entities = [
UserEntity,
2018-11-26 00:26:29 +01:00
FileEntity,
2019-01-12 16:41:45 +01:00
FaceRegionEntry,
PersonEntry,
MediaEntity,
2017-10-19 12:08:07 -04:00
PhotoEntity,
VideoEntity,
DirectoryEntity,
SharingEntity,
AlbumBaseEntity,
SavedSearchEntity,
VersionEntity
2017-10-19 12:08:07 -04:00
];
options.synchronize = false;
if (Config.Server.Log.sqlLevel !== SQLLogLevel.none) {
options.logging = SQLLogLevel[Config.Server.Log.sqlLevel];
}
Logger.debug(LOG_TAG, 'Creating connection: ' + DatabaseType[Config.Server.Database.type]);
this.connection = await this.createConnection(options);
2018-01-30 20:01:16 -05:00
await SQLConnection.schemeSync(this.connection);
2016-12-27 16:09:47 +01:00
}
2017-07-03 19:17:49 +02:00
return this.connection;
}
2016-12-27 16:09:47 +01:00
public static async tryConnection(config: ServerDataBaseConfig): Promise<boolean> {
2017-07-12 18:31:19 +02:00
try {
2018-03-30 15:30:30 -04:00
await getConnection('test').close();
2017-07-12 18:31:19 +02:00
} catch (err) {
}
const options: any = this.getDriver(config);
2018-03-30 15:30:30 -04:00
options.name = 'test';
options.entities = [
UserEntity,
2018-11-26 00:26:29 +01:00
FileEntity,
2019-01-12 16:41:45 +01:00
FaceRegionEntry,
PersonEntry,
MediaEntity,
PhotoEntity,
VideoEntity,
DirectoryEntity,
SharingEntity,
AlbumBaseEntity,
SavedSearchEntity,
VersionEntity
];
options.synchronize = false;
if (Config.Server.Log.sqlLevel !== SQLLogLevel.none) {
options.logging = SQLLogLevel[Config.Server.Log.sqlLevel];
}
const conn = await this.createConnection(options);
2018-01-30 20:01:16 -05:00
await SQLConnection.schemeSync(conn);
await conn.close();
return true;
}
2018-03-30 15:30:30 -04:00
public static async init(): Promise<void> {
const connection = await this.getConnection();
2021-01-04 10:32:19 +01:00
// Adding enforced users to the db
const userRepository = connection.getRepository(UserEntity);
2022-01-15 14:39:30 +01:00
if (Array.isArray(Config.Server.Database.enforcedUsers) &&
Config.Server.Database.enforcedUsers.length > 0) {
for (const uc of Config.Server.Database.enforcedUsers) {
const user = await userRepository.findOne({name: uc.name});
if (!user) {
Logger.info(LOG_TAG, 'Saving enforced user: ' + uc.name);
const a = new UserEntity();
a.name = uc.name;
// encrypt password and save back to the db
if (!uc.encryptedPassword) {
uc.encryptedPassword = PasswordHelper.cryptPassword(uc.password);
uc.password = '';
await Config.save();
}
a.password = uc.encryptedPassword;
a.role = uc.role;
await userRepository.save(a);
}
}
}
// Add dummy Admin to the db
const admins = await userRepository.find({role: UserRoles.Admin});
if (admins.length === 0) {
const a = new UserEntity();
a.name = 'admin';
a.password = PasswordHelper.cryptPassword('admin');
a.role = UserRoles.Admin;
await userRepository.save(a);
}
const defAdmin = await userRepository.findOne({name: 'admin', role: UserRoles.Admin});
if (defAdmin && PasswordHelper.comparePassword('admin', defAdmin.password)) {
NotificationManager.error('Using default admin user!', 'You are using the default admin/admin user/password, please change or remove it.');
}
2018-03-30 15:30:30 -04:00
}
public static async close(): Promise<void> {
try {
if (this.connection != null) {
await this.connection.close();
this.connection = null;
}
} catch (err) {
2020-12-30 21:13:19 +01:00
console.error('Error during closing sql db:');
console.error(err);
}
}
public static getSQLiteDB(config: ServerDataBaseConfig): any {
2020-01-28 18:36:52 +01:00
return path.join(ProjectPath.getAbsolutePath(config.dbFolder), 'sqlite.db');
}
private static async createConnection(options: ConnectionOptions): Promise<Connection> {
if (options.type === 'sqlite') {
return await createConnection(options);
}
try {
return await createConnection(options);
} catch (e) {
if (e.sqlMessage === 'Unknown database \'' + options.database + '\'') {
Logger.debug(LOG_TAG, 'creating database: ' + options.database);
const tmpOption = Utils.clone(options);
// @ts-ignore
delete tmpOption.database;
const tmpConn = await createConnection(tmpOption);
await tmpConn.query('CREATE DATABASE IF NOT EXISTS ' + options.database);
await tmpConn.close();
return await createConnection(options);
}
throw e;
}
}
private static async schemeSync(connection: Connection): Promise<void> {
let version = null;
try {
version = await connection.getRepository(VersionEntity).findOne();
} catch (ex) {
}
if (version && version.version === DataStructureVersion) {
return;
}
Logger.info(LOG_TAG, 'Updating database scheme');
if (!version) {
version = new VersionEntity();
}
version.version = DataStructureVersion;
2018-12-23 16:50:20 +01:00
let users: UserEntity[] = [];
try {
users = await connection.getRepository(UserEntity).createQueryBuilder('user').getMany();
} catch (ex) {
}
await connection.dropDatabase();
await connection.synchronize();
await connection.getRepository(VersionEntity).save(version);
2018-12-22 11:49:56 +01:00
try {
await connection.getRepository(UserEntity).save(users);
} catch (e) {
await connection.dropDatabase();
await connection.synchronize();
await connection.getRepository(VersionEntity).save(version);
Logger.warn(LOG_TAG, 'Could not move users to the new db scheme, deleting them. Details:' + e.toString());
2018-12-22 11:49:56 +01:00
}
}
private static getDriver(config: ServerDataBaseConfig): ConnectionOptions {
2017-10-19 12:08:07 -04:00
let driver: ConnectionOptions = null;
if (config.type === DatabaseType.mysql) {
driver = {
2018-03-30 15:30:30 -04:00
type: 'mysql',
2017-07-08 12:43:42 +02:00
host: config.mysql.host,
2020-01-29 16:15:00 +01:00
port: config.mysql.port,
2017-07-08 12:43:42 +02:00
username: config.mysql.username,
password: config.mysql.password,
database: config.mysql.database,
charset: 'utf8mb4'
};
} else if (config.type === DatabaseType.sqlite) {
driver = {
2018-03-30 15:30:30 -04:00
type: 'sqlite',
2020-12-28 22:08:57 +01:00
database: path.join(ProjectPath.getAbsolutePath(config.dbFolder), config.sqlite.DBFileName)
};
2022-02-22 14:06:52 +01:00
} else if (config.type === DatabaseType.better_sqlite3) {
driver = {
type: 'better-sqlite3',
database: path.join(ProjectPath.getAbsolutePath(config.dbFolder), 'better_', config.sqlite.DBFileName)
};
}
return driver;
2017-07-08 12:43:42 +02:00
}
2016-12-27 16:09:47 +01:00
2017-07-03 19:17:49 +02:00
}