feat: migrations.
This commit is contained in:
1015
package-lock.json
generated
1015
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,12 @@
|
||||
import { Database } from "./types"; // this is the Database interface we defined earlier
|
||||
import { createPool } from "mysql2"; // do not use 'mysql2/promises'!
|
||||
import { Kysely, MysqlDialect } from "kysely";
|
||||
import {
|
||||
Kysely,
|
||||
Migration,
|
||||
MigrationProvider,
|
||||
Migrator,
|
||||
MysqlDialect,
|
||||
} from "kysely";
|
||||
import { env } from "process";
|
||||
|
||||
const dialect = new MysqlDialect({
|
||||
@@ -9,7 +15,7 @@ const dialect = new MysqlDialect({
|
||||
host: env.DATABASE_HOST || "",
|
||||
user: env.DATABASE_USER || "",
|
||||
password: env.DATABASE_PASSWORD || "",
|
||||
port: parseInt(env.DATABASE_PORT || "3308", 10),
|
||||
port: parseInt(env.DATABASE_PORT || "3306", 10),
|
||||
connectionLimit: parseInt(
|
||||
env.CONDATABASE_CONNECTIONLIMITNECTIONLIMIT || "10",
|
||||
10
|
||||
@@ -37,3 +43,32 @@ export const db = new Kysely<Database>({
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
import * as migrations from "./migrations";
|
||||
|
||||
class InnerMigrationProvider implements MigrationProvider {
|
||||
getMigrations(): Promise<Record<string, Migration>> {
|
||||
return Promise.resolve(migrations);
|
||||
}
|
||||
}
|
||||
|
||||
export async function migrateToLatest() {
|
||||
const migrator = new Migrator({
|
||||
db,
|
||||
provider: new InnerMigrationProvider(),
|
||||
});
|
||||
|
||||
const { error, results } = await migrator.migrateToLatest();
|
||||
|
||||
results?.forEach((it) => {
|
||||
if (it.status === "Success") {
|
||||
console.log(`migration "${it.migrationName}" was executed successfully`);
|
||||
} else if (it.status === "Error") {
|
||||
console.error(`failed to execute migration "${it.migrationName}"`);
|
||||
}
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw new Error(JSON.stringify(error));
|
||||
}
|
||||
}
|
||||
|
||||
64
src/server/db/migrations/2025-01-07T10-45-43.020Z.ts
Normal file
64
src/server/db/migrations/2025-01-07T10-45-43.020Z.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Kysely } from "kysely";
|
||||
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await db.schema
|
||||
.createTable("session_info")
|
||||
.addColumn("id", "char(36)", (col) => col.primaryKey())
|
||||
.addColumn("game_name", "varchar(255)", (col) => col.notNull())
|
||||
.addColumn("version", "varchar(255)", (col) => col.notNull())
|
||||
.addColumn("save_id", "char(255)", (col) => col.notNull())
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable("log_entries")
|
||||
.addColumn("id", "int4", (col) => col.primaryKey().autoIncrement())
|
||||
.addColumn("session_info_id", "char(36)", (col) =>
|
||||
col
|
||||
.notNull()
|
||||
.references("session_info.id")
|
||||
.onDelete("cascade")
|
||||
.onUpdate("cascade")
|
||||
)
|
||||
.addColumn("message", "varchar(255)", (col) => col.notNull())
|
||||
.addColumn("timestamp", "datetime", (col) => col.notNull())
|
||||
.addColumn("category", "varchar(255)", (col) => col.defaultTo(null))
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("log_entries_session_info_id")
|
||||
.on("log_entries")
|
||||
.column("session_info_id")
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("log_entries_category")
|
||||
.on("log_entries")
|
||||
.column("category")
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable("log_metadata")
|
||||
.addColumn("id", "int4", (col) => col.primaryKey().autoIncrement())
|
||||
.addColumn("log_entry_id", "int4", (col) =>
|
||||
col
|
||||
.notNull()
|
||||
.references("log_entries.id")
|
||||
.onDelete("cascade")
|
||||
.onUpdate("cascade")
|
||||
)
|
||||
.addColumn("key", "varchar(50)", (col) => col.notNull())
|
||||
.addColumn("value", "varchar(255)", (col) => col.notNull())
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("log_metadata_log_entry_id")
|
||||
.on("log_metadata")
|
||||
.column("log_entry_id")
|
||||
.execute();
|
||||
}
|
||||
|
||||
export async function down(db: Kysely<any>): Promise<void> {
|
||||
await db.schema.dropTable("log_metadata").execute();
|
||||
await db.schema.dropTable("log_entries").execute();
|
||||
await db.schema.dropTable("session_info").execute();
|
||||
}
|
||||
1
src/server/db/migrations/index.ts
Normal file
1
src/server/db/migrations/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * as migration20250107T104543020Z from "./2025-01-07T10-45-43.020Z";
|
||||
@@ -6,36 +6,44 @@ import path from "path";
|
||||
import { installCors } from "./install-cors";
|
||||
import { installMeta } from "./install-meta";
|
||||
import { OpenAPIObject } from "openapi3-ts/oas31";
|
||||
import { migrateToLatest } from "./db/init";
|
||||
|
||||
const app = express();
|
||||
migrateToLatest()
|
||||
.then(() => {
|
||||
const app = express();
|
||||
|
||||
// enable cors
|
||||
installCors(app);
|
||||
// enable cors
|
||||
installCors(app);
|
||||
|
||||
// serve che client files
|
||||
app.use(express.static("./dist/client"));
|
||||
// serve che client files
|
||||
app.use(express.static("./dist/client"));
|
||||
|
||||
// enable body parser to parse json and urlencoded data
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(bodyParser.json());
|
||||
// enable body parser to parse json and urlencoded data
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(bodyParser.json());
|
||||
|
||||
// install the openapi/swagger/etc... metadata about the api
|
||||
const openAPIObject = installMeta(app);
|
||||
// install the openapi/swagger/etc... metadata about the api
|
||||
const openAPIObject = installMeta(app);
|
||||
|
||||
// install the ts-rest router
|
||||
installRouter(app, openAPIObject as unknown as OpenAPIObject /* required because of mixups in versioning betwee @ts-rest/open-api, @anatine/zop-openapi and openapi3-ts */);
|
||||
// install the ts-rest router
|
||||
installRouter(
|
||||
app,
|
||||
openAPIObject as unknown as OpenAPIObject /* required because of mixups in versioning betwee @ts-rest/open-api, @anatine/zop-openapi and openapi3-ts */
|
||||
);
|
||||
|
||||
// handle every other GET route with index.html
|
||||
app.get("*", function (_req, res, next) {
|
||||
if (_req.method === "GET") {
|
||||
res.sendFile(path.join(__dirname, "../client/index.html"));
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
// handle every other GET route with index.html
|
||||
app.get("*", function (_req, res, next) {
|
||||
if (_req.method === "GET") {
|
||||
res.sendFile(path.join(__dirname, "../client/index.html"));
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
const port = parseInt(process.env.HTTP_PORT || "1111", 10);
|
||||
const host = process.env.HTTP_HOST || "localhost";
|
||||
app.listen(port, host, () => {
|
||||
console.log(`Listening on http://${host}:${port}`);
|
||||
});
|
||||
const port = parseInt(process.env.HTTP_PORT || "1111", 10);
|
||||
const host = process.env.HTTP_HOST || "localhost";
|
||||
app.listen(port, host, () => {
|
||||
console.log(`Listening on http://${host}:${port}`);
|
||||
});
|
||||
})
|
||||
.catch(console.error);
|
||||
|
||||
Reference in New Issue
Block a user