Add migrations (#923)

* Fix typeorm migration cli and server migrations.
* Add `migrate-from-staging` script
This commit is contained in:
Madeline
2023-01-05 17:04:15 +11:00
committed by GitHub
parent 5ef4b80fc5
commit e42eaeee8d
10 changed files with 893 additions and 60 deletions
+2 -4
View File
@@ -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 {
+1 -1
View File
@@ -4,7 +4,7 @@ import {
ObjectIdColumn,
PrimaryGeneratedColumn,
} from "typeorm";
import { BaseClassWithoutId } from ".";
import { BaseClassWithoutId } from "./BaseClass";
export const PrimaryIdAutoGenerated = process.env.DATABASE?.startsWith(
"mongodb",
+7 -6
View File
@@ -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";
export * from "./ValidRegistrationTokens";
export * from "./VoiceState";
export * from "./Webhook";
+61 -6
View File
@@ -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();
}
-42
View File
@@ -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 };