Add development command to reset the database and rerun migrations
This commit is contained in:
27
develop
Executable file
27
develop
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This file belongs to the framework. You are not expected to modify it.
|
||||||
|
|
||||||
|
# Development command runner - parallel to ./mgmt for development tasks
|
||||||
|
# Usage: ./develop <command> [args...]
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
echo "Usage: ./develop <command> [args...]"
|
||||||
|
echo ""
|
||||||
|
echo "Available commands:"
|
||||||
|
for cmd in "$DIR"/framework/develop.d/*; do
|
||||||
|
if [ -x "$cmd" ]; then
|
||||||
|
basename "$cmd"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
subcmd="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
exec "$DIR"/framework/develop.d/"$subcmd" "$@"
|
||||||
@@ -137,6 +137,8 @@ async function runMigration(filename: string): Promise<void> {
|
|||||||
const filepath = path.join(MIGRATIONS_DIR, filename);
|
const filepath = path.join(MIGRATIONS_DIR, filename);
|
||||||
const content = fs.readFileSync(filepath, "utf-8");
|
const content = fs.readFileSync(filepath, "utf-8");
|
||||||
|
|
||||||
|
process.stdout.write(` Migration: ${filename}...`);
|
||||||
|
|
||||||
// Run migration in a transaction
|
// Run migration in a transaction
|
||||||
const client = await pool.connect();
|
const client = await pool.connect();
|
||||||
try {
|
try {
|
||||||
@@ -147,8 +149,11 @@ async function runMigration(filename: string): Promise<void> {
|
|||||||
[filename],
|
[filename],
|
||||||
);
|
);
|
||||||
await client.query("COMMIT");
|
await client.query("COMMIT");
|
||||||
console.log(`Applied migration: ${filename}`);
|
console.log(" ✓");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.log(" ✗");
|
||||||
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
|
console.error(` Error: ${message}`);
|
||||||
await client.query("ROLLBACK");
|
await client.query("ROLLBACK");
|
||||||
throw err;
|
throw err;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -169,11 +174,10 @@ async function migrate(): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Running ${pending.length} migration(s)...`);
|
console.log(`Applying ${pending.length} migration(s):`);
|
||||||
for (const file of pending) {
|
for (const file of pending) {
|
||||||
await runMigration(file);
|
await runMigration(file);
|
||||||
}
|
}
|
||||||
console.log("Migrations complete");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List migration status
|
// List migration status
|
||||||
|
|||||||
50
express/develop/reset-db.ts
Normal file
50
express/develop/reset-db.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
// reset-db.ts
|
||||||
|
// Development command to wipe the database and apply all migrations from scratch
|
||||||
|
|
||||||
|
import { migrate, pool, connectionConfig } from "../database";
|
||||||
|
|
||||||
|
async function main(): Promise<void> {
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
|
||||||
|
// Require explicit confirmation unless --force is passed
|
||||||
|
if (!args.includes("--force")) {
|
||||||
|
console.error("This will DROP ALL TABLES in the database!");
|
||||||
|
console.error(` Database: ${connectionConfig.database}`);
|
||||||
|
console.error(` Host: ${connectionConfig.host}:${connectionConfig.port}`);
|
||||||
|
console.error("");
|
||||||
|
console.error("Run with --force to proceed.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log("Dropping all tables...");
|
||||||
|
|
||||||
|
// Get all table names in the public schema
|
||||||
|
const result = await pool.query<{ tablename: string }>(`
|
||||||
|
SELECT tablename FROM pg_tables
|
||||||
|
WHERE schemaname = 'public'
|
||||||
|
`);
|
||||||
|
|
||||||
|
if (result.rows.length > 0) {
|
||||||
|
// Drop all tables with CASCADE to handle foreign key constraints
|
||||||
|
const tableNames = result.rows.map((r) => `"${r.tablename}"`).join(", ");
|
||||||
|
await pool.query(`DROP TABLE IF EXISTS ${tableNames} CASCADE`);
|
||||||
|
console.log(`Dropped ${result.rows.length} table(s)`);
|
||||||
|
} else {
|
||||||
|
console.log("No tables to drop");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("");
|
||||||
|
await migrate();
|
||||||
|
|
||||||
|
console.log("");
|
||||||
|
console.log("Database reset complete.");
|
||||||
|
} finally {
|
||||||
|
await pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((err) => {
|
||||||
|
console.error("Failed to reset database:", err.message);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
9
framework/develop.d/reset-db
Executable file
9
framework/develop.d/reset-db
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT="$DIR/../.."
|
||||||
|
|
||||||
|
cd "$ROOT/express"
|
||||||
|
"$DIR"/../cmd.d/tsx develop/reset-db.ts "$@"
|
||||||
Reference in New Issue
Block a user