124 lines
2.6 KiB
JavaScript
124 lines
2.6 KiB
JavaScript
import { readdirSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
import { spawnSync } from 'node:child_process'
|
|
|
|
const rootDir = process.cwd()
|
|
const envFile = process.env.ENV_FILE || '.env.development'
|
|
const serviceName = process.env.DB_SERVICE || 'sori-studio-db'
|
|
const databaseName = process.env.POSTGRES_DB || 'sori_studio'
|
|
const databaseUser = process.env.POSTGRES_USER || 'sori_studio'
|
|
const migrationsDir = join(rootDir, 'db', 'migrations')
|
|
const containerMigrationsDir = '/docker-entrypoint-initdb.d'
|
|
|
|
/**
|
|
* 명령 실행 결과 확인
|
|
* @param {string} command - 실행할 명령
|
|
* @param {string[]} args - 명령 인자
|
|
* @param {Object} options - 실행 옵션
|
|
* @returns {void}
|
|
*/
|
|
const runCommand = (command, args, options = {}) => {
|
|
const result = spawnSync(command, args, {
|
|
cwd: rootDir,
|
|
env: {
|
|
...process.env,
|
|
ENV_FILE: envFile
|
|
},
|
|
stdio: 'inherit',
|
|
...options
|
|
})
|
|
|
|
if (result.status !== 0) {
|
|
process.exit(result.status || 1)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 마이그레이션 파일 목록 조회
|
|
* @returns {string[]} SQL 파일 목록
|
|
*/
|
|
const getMigrationFiles = () => readdirSync(migrationsDir)
|
|
.filter((fileName) => fileName.endsWith('.sql'))
|
|
.sort((firstFile, secondFile) => firstFile.localeCompare(secondFile))
|
|
|
|
/**
|
|
* 개발 DB 컨테이너 시작
|
|
* @returns {void}
|
|
*/
|
|
const startDatabase = () => {
|
|
runCommand('docker', [
|
|
'compose',
|
|
'--env-file',
|
|
envFile,
|
|
'up',
|
|
'-d',
|
|
serviceName
|
|
])
|
|
}
|
|
|
|
/**
|
|
* 개발 DB 준비 상태 확인
|
|
* @returns {void}
|
|
*/
|
|
const waitForDatabase = () => {
|
|
for (let attempt = 1; attempt <= 20; attempt += 1) {
|
|
const result = spawnSync('docker', [
|
|
'exec',
|
|
serviceName,
|
|
'pg_isready',
|
|
'-U',
|
|
databaseUser,
|
|
'-d',
|
|
databaseName
|
|
], {
|
|
cwd: rootDir,
|
|
stdio: 'ignore'
|
|
})
|
|
|
|
if (result.status === 0) {
|
|
return
|
|
}
|
|
|
|
spawnSync('sleep', ['1'])
|
|
}
|
|
|
|
console.error('개발 DB가 준비되지 않았습니다.')
|
|
process.exit(1)
|
|
}
|
|
|
|
/**
|
|
* SQL 마이그레이션 파일 실행
|
|
* @param {string} fileName - 실행할 SQL 파일명
|
|
* @returns {void}
|
|
*/
|
|
const runMigrationFile = (fileName) => {
|
|
runCommand('docker', [
|
|
'exec',
|
|
serviceName,
|
|
'psql',
|
|
'-v',
|
|
'ON_ERROR_STOP=1',
|
|
'-U',
|
|
databaseUser,
|
|
'-d',
|
|
databaseName,
|
|
'-f',
|
|
`${containerMigrationsDir}/${fileName}`
|
|
])
|
|
}
|
|
|
|
/**
|
|
* 개발 DB 마이그레이션 실행
|
|
* @returns {void}
|
|
*/
|
|
const migrateDevelopmentDatabase = () => {
|
|
startDatabase()
|
|
waitForDatabase()
|
|
|
|
for (const fileName of getMigrationFiles()) {
|
|
runMigrationFile(fileName)
|
|
}
|
|
}
|
|
|
|
migrateDevelopmentDatabase()
|