| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- const mysql = require('mysql2/promise')
- const DB_CFG = {
- host: process.env.DB_HOST || 'cq-cdb-8fjmemkb.sql.tencentcdb.com',
- port: Number(process.env.DB_PORT || 27220),
- user: process.env.DB_USER || 'root',
- password: process.env.DB_PASSWORD || 'Ylrz_1q2w3e4r5t6y',
- multipleStatements: true
- }
- const MASTER_DB = process.env.MASTER_DB || 'ylrz_saas'
- const ALTER_SQL = `
- SET @col_exists := (SELECT COUNT(*) FROM information_schema.COLUMNS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lobster_execution_config' AND COLUMN_NAME = 'quality_gate_enabled');
- SET @ddl := IF(@col_exists = 0,
- 'ALTER TABLE lobster_execution_config ADD COLUMN quality_gate_enabled tinyint NOT NULL DEFAULT 1 COMMENT ''quality gate enabled'' AFTER auto_start_instance_on_tag',
- 'SELECT 1');
- PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
- SET @col_exists := (SELECT COUNT(*) FROM information_schema.COLUMNS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lobster_execution_config' AND COLUMN_NAME = 'quality_pass_score_percent');
- SET @ddl := IF(@col_exists = 0,
- 'ALTER TABLE lobster_execution_config ADD COLUMN quality_pass_score_percent int NOT NULL DEFAULT 75 COMMENT ''runtime pass score percent'' AFTER quality_gate_enabled',
- 'SELECT 1');
- PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
- SET @col_exists := (SELECT COUNT(*) FROM information_schema.COLUMNS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lobster_execution_config' AND COLUMN_NAME = 'quality_target_score_percent');
- SET @ddl := IF(@col_exists = 0,
- 'ALTER TABLE lobster_execution_config ADD COLUMN quality_target_score_percent int NOT NULL DEFAULT 75 COMMENT ''e2e target score percent'' AFTER quality_pass_score_percent',
- 'SELECT 1');
- PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
- SET @col_exists := (SELECT COUNT(*) FROM information_schema.COLUMNS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lobster_execution_config' AND COLUMN_NAME = 'quality_min_node_score_percent');
- SET @ddl := IF(@col_exists = 0,
- 'ALTER TABLE lobster_execution_config ADD COLUMN quality_min_node_score_percent int NOT NULL DEFAULT 60 COMMENT ''e2e min node score percent'' AFTER quality_target_score_percent',
- 'SELECT 1');
- PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
- SET @col_exists := (SELECT COUNT(*) FROM information_schema.COLUMNS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lobster_execution_config' AND COLUMN_NAME = 'quality_min_e2e_avg_score_percent');
- SET @ddl := IF(@col_exists = 0,
- 'ALTER TABLE lobster_execution_config ADD COLUMN quality_min_e2e_avg_score_percent int NOT NULL DEFAULT 75 COMMENT ''e2e min avg score percent'' AFTER quality_min_node_score_percent',
- 'SELECT 1');
- PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
- SET @col_exists := (SELECT COUNT(*) FROM information_schema.COLUMNS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lobster_execution_config' AND COLUMN_NAME = 'quality_multiturn_min_avg_score_percent');
- SET @ddl := IF(@col_exists = 0,
- 'ALTER TABLE lobster_execution_config ADD COLUMN quality_multiturn_min_avg_score_percent int NOT NULL DEFAULT 45 COMMENT ''multiturn min avg score percent'' AFTER quality_min_e2e_avg_score_percent',
- 'SELECT 1');
- PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
- `
- function dbNameFromUrl(url) {
- if (!url) return null
- const m = String(url).match(/\/([^/?]+)(?:\?|$)/)
- return m ? m[1] : null
- }
- async function columnExists(conn, column) {
- const [rows] = await conn.query(
- `SELECT COUNT(*) AS c FROM information_schema.COLUMNS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lobster_execution_config' AND COLUMN_NAME = ?`,
- [column]
- )
- return rows[0].c > 0
- }
- async function applyOnDb(conn, label) {
- const [tables] = await conn.query("SHOW TABLES LIKE 'lobster_execution_config'")
- if (!tables.length) {
- console.log(`${label}: skip (no lobster_execution_config table)`)
- return
- }
- await conn.query(ALTER_SQL)
- const ok = await columnExists(conn, 'quality_gate_enabled')
- console.log(`${label}: quality_gate_enabled=${ok ? 'OK' : 'MISSING'}`)
- }
- async function main() {
- const dbs = new Set(process.argv.slice(2))
- const masterConn = await mysql.createConnection({ ...DB_CFG, database: MASTER_DB })
- if (!dbs.size) {
- try {
- const [tenants] = await masterConn.query(
- 'SELECT db_url FROM tenant_info WHERE db_url IS NOT NULL AND db_url != \'\''
- )
- for (const t of tenants) {
- const name = dbNameFromUrl(t.db_url)
- if (name) dbs.add(name)
- }
- } catch (e) {
- console.warn('tenant_info skipped:', e.message)
- }
- }
- await masterConn.end()
- for (const db of dbs) {
- const conn = await mysql.createConnection({ ...DB_CFG, database: db })
- try {
- await applyOnDb(conn, db)
- } catch (e) {
- console.error(`${db}: ${e.message}`)
- } finally {
- await conn.end()
- }
- }
- }
- main().catch(err => {
- console.error(err)
- process.exit(1)
- })
|