Files
alla-tms/scripts/reset-db.js
2026-07-16 09:53:14 +07:00

120 lines
3.3 KiB
JavaScript

const crypto = require('node:crypto');
const fs = require('node:fs');
const path = require('node:path');
const postgres = require('postgres');
function readEnvFile(filePath) {
if (!fs.existsSync(filePath)) {
return {};
}
const content = fs.readFileSync(filePath, 'utf8');
return Object.fromEntries(
content
.split(/\r?\n/)
.map((line) => line.trim())
.filter((line) => line && !line.startsWith('#') && line.includes('='))
.map((line) => {
const index = line.indexOf('=');
const key = line.slice(0, index).trim();
const value = line.slice(index + 1).trim();
return [key, value];
})
);
}
function resolveDatabaseUrl() {
if (process.env.DATABASE_URL) {
return process.env.DATABASE_URL;
}
const rootDir = process.cwd();
const envLocal = readEnvFile(path.join(rootDir, '.env.local'));
if (envLocal.DATABASE_URL) {
return envLocal.DATABASE_URL;
}
const env = readEnvFile(path.join(rootDir, '.env'));
if (env.DATABASE_URL) {
return env.DATABASE_URL;
}
throw new Error('DATABASE_URL was not found in process.env, .env.local, or .env');
}
function getMigrationFiles(rootDir) {
return fs
.readdirSync(path.join(rootDir, 'drizzle'))
.filter((file) => file.endsWith('.sql'))
.sort((left, right) => left.localeCompare(right));
}
async function main() {
const databaseUrl = resolveDatabaseUrl();
const databaseName = new URL(databaseUrl).pathname.replace(/^\//, '');
const rootDir = process.cwd();
const migrationFiles = getMigrationFiles(rootDir);
if (!databaseName) {
throw new Error('DATABASE_URL must include a database name');
}
const sql = postgres(databaseUrl, {
max: 1,
prepare: false
});
console.log(`Resetting database "${databaseName}"...`);
try {
await sql`
select pg_terminate_backend(pid)
from pg_stat_activity
where datname = current_database()
and pid <> pg_backend_pid()
`;
await sql.unsafe('drop schema if exists drizzle cascade');
await sql.unsafe('drop schema if exists public cascade');
await sql.unsafe('create schema public');
await sql.unsafe('grant all on schema public to public');
await sql.unsafe('grant all on schema public to postgres');
await sql.unsafe('create schema drizzle');
await sql.unsafe(`
create table drizzle.__drizzle_migrations (
id serial primary key,
hash text not null,
created_at bigint not null
)
`);
for (const fileName of migrationFiles) {
const filePath = path.join(rootDir, 'drizzle', fileName);
const sqlContent = fs.readFileSync(filePath, 'utf8');
const statements = sqlContent
.split('--> statement-breakpoint')
.map((statement) => statement.trim())
.filter(Boolean);
for (const statement of statements) {
await sql.unsafe(statement);
}
const hash = crypto.createHash('sha256').update(sqlContent).digest('hex');
await sql`
insert into drizzle.__drizzle_migrations (hash, created_at)
values (${hash}, ${String(Date.now())})
`;
}
} finally {
await sql.end();
}
console.log('Database reset completed.');
}
main().catch((error) => {
console.error('Failed to reset database.');
console.error(error);
process.exit(1);
});