summary refs log tree commit diff
path: root/src/util
diff options
context:
space:
mode:
authorMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2023-01-05 17:04:15 +1100
committerGitHub <noreply@github.com>2023-01-05 17:04:15 +1100
commitf67375bf37f3a299e1ea7da890040e9de546eb80 (patch)
treebd0ec98942d1115593d9cb03fdf1187cf31783ff /src/util
parentMerge pull request #922 from MaddyUnderStars/maddy/bodyParserPatch (diff)
downloadserver-f67375bf37f3a299e1ea7da890040e9de546eb80.tar.xz
Add migrations (#923)
* Fix typeorm migration cli and server migrations.
* Add `migrate-from-staging` script
Diffstat (limited to 'src/util')
-rw-r--r--src/util/entities/BaseClass.ts6
-rw-r--r--src/util/entities/Migration.ts2
-rw-r--r--src/util/entities/index.ts13
-rw-r--r--src/util/util/Database.ts67
-rw-r--r--src/util/util/Datasource.ts42
5 files changed, 71 insertions, 59 deletions
diff --git a/src/util/entities/BaseClass.ts b/src/util/entities/BaseClass.ts
index 025c747b..790aee33 100644
--- a/src/util/entities/BaseClass.ts
+++ b/src/util/entities/BaseClass.ts
@@ -1,4 +1,3 @@
-import "reflect-metadata";
 import {
 	BaseEntity,
 	BeforeInsert,
@@ -8,9 +7,8 @@ import {
 	PrimaryColumn,
 } from "typeorm";
 import { Snowflake } from "../util/Snowflake";
-import "missing-native-js-functions";
-import { getDatabase } from "..";
-import { OrmUtils } from "@fosscord/util";
+import { getDatabase } from "../util/Database";
+import { OrmUtils } from "../imports/OrmUtils";
 
 export class BaseClassWithoutId extends BaseEntity {
 	private get construct(): any {
diff --git a/src/util/entities/Migration.ts b/src/util/entities/Migration.ts
index f4e54eae..072014de 100644
--- a/src/util/entities/Migration.ts
+++ b/src/util/entities/Migration.ts
@@ -4,7 +4,7 @@ import {
 	ObjectIdColumn,
 	PrimaryGeneratedColumn,
 } from "typeorm";
-import { BaseClassWithoutId } from ".";
+import { BaseClassWithoutId } from "./BaseClass";
 
 export const PrimaryIdAutoGenerated = process.env.DATABASE?.startsWith(
 	"mongodb",
diff --git a/src/util/entities/index.ts b/src/util/entities/index.ts
index 40260ba4..dc509250 100644
--- a/src/util/entities/index.ts
+++ b/src/util/entities/index.ts
@@ -1,19 +1,23 @@
 export * from "./Application";
 export * from "./Attachment";
 export * from "./AuditLog";
+export * from "./BackupCodes";
 export * from "./Ban";
 export * from "./BaseClass";
 export * from "./Categories";
+export * from "./ClientRelease";
 export * from "./Channel";
 export * from "./Config";
 export * from "./ConnectedAccount";
 export * from "./EmbedCache";
 export * from "./Emoji";
+export * from "./Encryption";
 export * from "./Guild";
 export * from "./Invite";
 export * from "./Member";
 export * from "./Message";
 export * from "./Migration";
+export * from "./Note";
 export * from "./RateLimit";
 export * from "./ReadState";
 export * from "./Recipient";
@@ -26,10 +30,7 @@ export * from "./Team";
 export * from "./TeamMember";
 export * from "./Template";
 export * from "./User";
-export * from "./VoiceState";
-export * from "./Webhook";
-export * from "./ClientRelease";
-export * from "./BackupCodes";
-export * from "./Note";
 export * from "./UserSettings";
-export * from "./ValidRegistrationTokens";
\ No newline at end of file
+export * from "./ValidRegistrationTokens";
+export * from "./VoiceState";
+export * from "./Webhook";
\ No newline at end of file
diff --git a/src/util/util/Database.ts b/src/util/util/Database.ts
index 2f1cd290..da0909ab 100644
--- a/src/util/util/Database.ts
+++ b/src/util/util/Database.ts
@@ -1,13 +1,42 @@
-import "reflect-metadata";
 import { DataSource } from "typeorm";
 import { yellow, green, red } from "picocolors";
-import { DataSourceOptions, DatabaseType } from "./Datasource";
+import { ConfigEntity } from "../entities/Config";
+import { config } from "dotenv";
+import path from "path";
 
 // UUID extension option is only supported with postgres
 // We want to generate all id's with Snowflakes that's why we have our own BaseEntity class
 
 var dbConnection: DataSource | undefined;
 
+// For typeorm cli
+if (!process.env) {
+	config();
+}
+
+let dbConnectionString =
+	process.env.DATABASE || path.join(process.cwd(), "database.db");
+
+const DatabaseType = dbConnectionString.includes("://")
+	? dbConnectionString.split(":")[0]?.replace("+srv", "")
+	: "sqlite";
+const isSqlite = DatabaseType.includes("sqlite");
+
+const DataSourceOptions = new DataSource({
+	//@ts-ignore type 'string' is not 'mysql' | 'sqlite' | 'mariadb' | etc etc
+	type: DatabaseType,
+	charset: "utf8mb4",
+	url: isSqlite ? undefined : dbConnectionString,
+	database: isSqlite ? dbConnectionString : undefined,
+	entities: ["dist/util/entities/*.js"],
+	synchronize: !!process.env.DB_SYNC,
+	logging: false,
+	bigNumberStrings: false,
+	supportBigNumbers: true,
+	name: "default",
+	migrations: [path.join(__dirname, "..", "migration", DatabaseType, "*.js")],
+});
+
 
 // Gets the existing database connection
 export function getDatabase(): DataSource | null {
@@ -20,18 +49,44 @@ export function getDatabase(): DataSource | null {
 export async function initDatabase(): Promise<DataSource> {
 	if (dbConnection) return dbConnection;
 
+	if (isSqlite) {
+		console.log(
+			`[Database] ${red(
+				`You are running sqlite! Please keep in mind that we recommend setting up a dedicated database!`,
+			)}`,
+		);
+	}
+
+	if (!process.env.DB_SYNC) {
+		const supported = ["mysql", "mariadb", "postgres", "sqlite"];
+		if (!supported.includes(DatabaseType)) {
+			console.log("[Database]" + red(` We don't have migrations for DB type '${DatabaseType}'` +
+				` To ignore, set DB_SYNC=true in your env. https://docs.fosscord.com/setup/server/configuration/env/`));
+			process.exit();
+		}
+	}
+
 	console.log(`[Database] ${yellow(`connecting to ${DatabaseType} db`)}`);
 
 	dbConnection = await DataSourceOptions.initialize();
 
-	await dbConnection.runMigrations();
+	// Crude way of detecting if the migrations table exists.
+	const dbExists = async () => { try { await ConfigEntity.count(); return true; } catch (e) { return false; } };
+	if (!await dbExists()) {
+		console.log("[Database] This appears to be a fresh database. Synchronising.");
+		await dbConnection.synchronize();
+	}
+	else {
+		await dbConnection.runMigrations();
+	}
+
 	console.log(`[Database] ${green("connected")}`);
 
 	return dbConnection;
 }
 
-export { dbConnection };
+export { dbConnection, DataSourceOptions, DatabaseType };
 
-export function closeDatabase() {
-	dbConnection?.destroy();
+export async function closeDatabase() {
+	await dbConnection?.destroy();
 }
diff --git a/src/util/util/Datasource.ts b/src/util/util/Datasource.ts
deleted file mode 100644
index 1495faaa..00000000
--- a/src/util/util/Datasource.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { config } from "dotenv"
-import path from "path";
-import { DataSource } from "typeorm";
-import { red } from "picocolors";
-
-// For typeorm cli
-if (!process.env) {
-	config();
-}
-
-let dbConnectionString =
-	process.env.DATABASE || path.join(process.cwd(), "database.db");
-
-const type = dbConnectionString.includes("://")
-	? dbConnectionString.split(":")[0]?.replace("+srv", "")
-	: "sqlite";
-const isSqlite = type.includes("sqlite");
-
-if (isSqlite) {
-	console.log(
-		`[Database] ${red(
-			`You are running sqlite! Please keep in mind that we recommend setting up a dedicated database!`,
-		)}`,
-	);
-}
-
-const dataSource = new DataSource({
-	//@ts-ignore type 'string' is not 'mysql' | 'sqlite' | 'mariadb' | etc etc
-	type,
-	charset: "utf8mb4",
-	url: isSqlite ? undefined : dbConnectionString,
-	database: isSqlite ? dbConnectionString : undefined,
-	entities: ["dist/util/entities/*.js"],
-	synchronize: false,
-	logging: false,
-	bigNumberStrings: false,
-	supportBigNumbers: true,
-	name: "default",
-	migrations: ["dist/util/migrations/*.js"],
-});
-
-export { dataSource as DataSourceOptions, type as DatabaseType };
\ No newline at end of file