switch-database.ts•3.95 kB
/// <reference types="node" />
/**
* Database provider switching script
*
* This script allows switching between database providers:
* - sqlite: Default lightweight database (good for development)
* - postgresql: Production-ready database with advanced features
* - mongodb: NoSQL database (through Prisma's MongoDB connector)
*/
import * as childProcess from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import { resolve } from 'path';
// Use execSync from child_process
const { execSync } = childProcess;
// Possible database providers
const PROVIDERS = {
SQLITE: 'sqlite',
POSTGRESQL: 'postgresql',
MONGODB: 'mongodb',
};
// Get command line arguments
const provider = process.argv[2]?.toLowerCase();
// Database connection strings
const CONNECTION_STRINGS = {
[PROVIDERS.SQLITE]: 'file:./dev.db',
[PROVIDERS.POSTGRESQL]: 'postgresql://postgres:postgres@localhost:5432/news_aggregator?schema=public',
[PROVIDERS.MONGODB]: 'mongodb://localhost:27017/news_aggregator',
};
// Prisma schema path
const schemaPath = path.resolve(__dirname, '../prisma/schema.prisma');
const envExamplePath = path.resolve(__dirname, '../.env.example');
const migrationLockPath = path.resolve(__dirname, '../prisma/migrations/migration_lock.toml');
/**
* Update the Prisma schema to use the specified provider
*/
function updateSchema(targetProvider: string): void {
if (!Object.values(PROVIDERS).includes(targetProvider)) {
console.error(`Invalid provider: ${targetProvider}`);
console.log(`Available providers: ${Object.values(PROVIDERS).join(', ')}`);
process.exit(1);
}
try {
// Read the schema file
let schema = fs.readFileSync(schemaPath, 'utf8');
// Update the provider in the schema
schema = schema.replace(
/provider\s*=\s*"[^"]+"/,
`provider = "${targetProvider}"`
);
// Update the url in the schema
schema = schema.replace(
/url\s*=\s*env\("DATABASE_URL"\)/,
`url = env("DATABASE_URL")`
);
// Write the updated schema
fs.writeFileSync(schemaPath, schema);
console.log(`Schema updated to use ${targetProvider} provider`);
// Update migration lock file
const lockContent = `# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "${targetProvider}"
`;
fs.writeFileSync(migrationLockPath, lockContent);
console.log(`Migration lock updated to use ${targetProvider} provider`);
// Update .env.example with the correct connection string
let envExample = fs.readFileSync(envExamplePath, 'utf8');
const connectionString = CONNECTION_STRINGS[targetProvider];
envExample = envExample.replace(
/DATABASE_URL=.*/,
`DATABASE_URL="${connectionString}"`
);
fs.writeFileSync(envExamplePath, envExample);
console.log(`.env.example updated with ${targetProvider} connection string`);
console.log('\nDatabase provider switch complete!');
console.log(`\nTo complete the transition to ${targetProvider}:`);
console.log('1. Update your .env file with the correct DATABASE_URL');
console.log('2. Run the migrations for the new database:');
console.log(' npm run migrate:reset');
console.log('3. Generate the Prisma client:');
console.log(' npm run db:generate');
} catch (error) {
console.error('Error updating schema:', error);
process.exit(1);
}
}
/**
* Show usage instructions
*/
function showUsage(): void {
console.log('Usage: npm run db:switch <provider>');
console.log('\nAvailable providers:');
console.log(` ${PROVIDERS.SQLITE} SQLite database (default, good for development)`);
console.log(` ${PROVIDERS.POSTGRESQL} PostgreSQL database (recommended for production)`);
console.log(` ${PROVIDERS.MONGODB} MongoDB database (NoSQL option)`);
}
// Main execution
if (!provider) {
showUsage();
} else {
updateSchema(provider);
}