commit
This commit is contained in:
119
scripts/reset-db.js
Normal file
119
scripts/reset-db.js
Normal file
@@ -0,0 +1,119 @@
|
||||
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);
|
||||
});
|
||||
Reference in New Issue
Block a user