You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

237 lines
6.1 KiB

/**
* 数据库工具脚本
* 用于创建迁移文件和种子数据文件
*/
import { writeFileSync, mkdirSync, existsSync } from 'fs'
import { resolve, dirname } from 'path'
import { fileURLToPath } from 'url'
// 获取当前文件目录
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const projectRoot = resolve(__dirname, '..')
// 配置路径
const MIGRATIONS_DIR = 'src/infrastructure/database/migrations'
const SEEDS_DIR = 'src/infrastructure/database/seeds'
/**
* 生成时间戳
* @returns {string} 格式: YYYYMMDDHHMMSS
*/
function generateTimestamp() {
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const day = String(now.getDate()).padStart(2, '0')
const hours = String(now.getHours()).padStart(2, '0')
const minutes = String(now.getMinutes()).padStart(2, '0')
const seconds = String(now.getSeconds()).padStart(2, '0')
return `${year}${month}${day}${hours}${minutes}${seconds}`
}
/**
* 创建迁移文件模板
* @param {string} migrationName 迁移名称
* @returns {string} 迁移文件内容
*/
function createMigrationTemplate(migrationName) {
return `/**
* ${migrationName} 迁移文件
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
export const up = async knex => {
// TODO: 在此处编写数据库结构变更逻辑
// 例如:创建表、添加列、创建索引等
/*
return knex.schema.createTable('table_name', table => {
table.increments('id').primary()
table.string('name').notNullable()
table.timestamps(true, true)
})
*/
}
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
export const down = async knex => {
// TODO: 在此处编写回滚逻辑
// 例如:删除表、删除列、删除索引等
/*
return knex.schema.dropTable('table_name')
*/
}
`
}
/**
* 创建种子数据文件模板
* @param {string} seedName 种子数据名称
* @returns {string} 种子数据文件内容
*/
function createSeedTemplate(seedName) {
return `/**
* ${seedName} 种子数据
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
export const seed = async knex => {
// 清空现有数据(可选)
// await knex('table_name').del()
// 插入种子数据
/*
await knex('table_name').insert([
{
name: '示例数据1',
created_at: knex.fn.now(),
updated_at: knex.fn.now()
},
{
name: '示例数据2',
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}
])
console.log('✅ ${seedName} seeded successfully!')
*/
}
`
}
/**
* 创建迁移文件
* @param {string} migrationName 迁移名称
*/
function createMigration(migrationName) {
if (!migrationName) {
console.error('❌ 请提供迁移名称')
console.log('用法: bun run scripts/db-tools.js migrate <migration_name>')
process.exit(1)
}
// 确保目录存在
const migrationsPath = resolve(projectRoot, MIGRATIONS_DIR)
if (!existsSync(migrationsPath)) {
mkdirSync(migrationsPath, { recursive: true })
}
// 生成文件名
const timestamp = generateTimestamp()
const fileName = `${timestamp}_${migrationName}.mjs`
const filePath = resolve(migrationsPath, fileName)
// 检查文件是否已存在
if (existsSync(filePath)) {
console.error(`❌ 迁移文件已存在: ${fileName}`)
process.exit(1)
}
// 创建文件
const content = createMigrationTemplate(migrationName)
writeFileSync(filePath, content, 'utf8')
console.log(`✅ 迁移文件创建成功: ${fileName}`)
console.log(`📁 路径: ${filePath}`)
console.log(`📝 请编辑文件并实现 up() 和 down() 方法`)
}
/**
* 创建种子数据文件
* @param {string} seedName 种子数据名称
*/
function createSeed(seedName) {
if (!seedName) {
console.error('❌ 请提供种子数据名称')
console.log('用法: bun run scripts/db-tools.js seed <seed_name>')
process.exit(1)
}
// 确保目录存在
const seedsPath = resolve(projectRoot, SEEDS_DIR)
if (!existsSync(seedsPath)) {
mkdirSync(seedsPath, { recursive: true })
}
// 生成文件名
const timestamp = generateTimestamp()
const fileName = `${timestamp}_${seedName}.mjs`
const filePath = resolve(seedsPath, fileName)
// 检查文件是否已存在
if (existsSync(filePath)) {
console.error(`❌ 种子数据文件已存在: ${fileName}`)
process.exit(1)
}
// 创建文件
const content = createSeedTemplate(seedName)
writeFileSync(filePath, content, 'utf8')
console.log(`✅ 种子数据文件创建成功: ${fileName}`)
console.log(`📁 路径: ${filePath}`)
console.log(`📝 请编辑文件并实现 seed() 方法`)
}
/**
* 显示帮助信息
*/
function showHelp() {
console.log(`
🗄️ 数据库工具 - 迁移和种子数据管理
用法:
bun run scripts/db-tools.js <command> [options]
命令:
migrate <name> 创建新的迁移文件
seed <name> 创建新的种子数据文件
help 显示帮助信息
示例:
bun run scripts/db-tools.js migrate create_posts_table
bun run scripts/db-tools.js seed posts_seed
💡 提示:
- 迁移文件用于管理数据库结构变更
- 种子数据文件用于插入测试或初始数据
- 文件名会自动添加时间戳前缀
- 所有文件使用 ES 模块格式 (.mjs)
`)
}
// 主函数
function main() {
const args = process.argv.slice(2)
const command = args[0]
const name = args[1]
switch (command) {
case 'migrate':
createMigration(name)
break
case 'seed':
createSeed(name)
break
case 'help':
case '--help':
case '-h':
showHelp()
break
default:
console.error(`❌ 未知命令: ${command}`)
showHelp()
process.exit(1)
}
}
// 运行主函数
main()