新增競賽前台呈現、刪除競賽、修改競賽狀態
This commit is contained in:
@@ -157,6 +157,53 @@ export class DatabaseSyncFixed {
|
||||
}
|
||||
}
|
||||
|
||||
// 智能雙寫更新
|
||||
async smartDualUpdate(tableName: string, id: string, updates: Record<string, any>): Promise<WriteResult> {
|
||||
const result: WriteResult = {
|
||||
success: false,
|
||||
masterSuccess: false,
|
||||
slaveSuccess: false
|
||||
};
|
||||
|
||||
try {
|
||||
// 先獲取主機的記錄
|
||||
const masterRecord = await this.getMasterRecord(tableName, id);
|
||||
|
||||
if (!masterRecord) {
|
||||
throw new Error('主機記錄不存在');
|
||||
}
|
||||
|
||||
// 獲取備機的記錄 ID(通過名稱匹配)
|
||||
const slaveId = await this.getSlaveRecordIdByName(tableName, masterRecord.name);
|
||||
|
||||
if (!slaveId) {
|
||||
throw new Error('備機記錄不存在');
|
||||
}
|
||||
|
||||
// 同時更新主機和備機
|
||||
const masterPromise = this.updateMasterRecord(tableName, id, updates);
|
||||
const slavePromise = this.updateSlaveRecord(tableName, slaveId, updates);
|
||||
|
||||
const [masterResult, slaveResult] = await Promise.allSettled([masterPromise, slavePromise]);
|
||||
|
||||
result.masterSuccess = masterResult.status === 'fulfilled';
|
||||
result.slaveSuccess = slaveResult.status === 'fulfilled';
|
||||
result.success = result.masterSuccess || result.slaveSuccess;
|
||||
|
||||
if (masterResult.status === 'rejected') {
|
||||
result.masterError = masterResult.reason instanceof Error ? masterResult.reason.message : '主機更新失敗';
|
||||
}
|
||||
if (slaveResult.status === 'rejected') {
|
||||
result.slaveError = slaveResult.reason instanceof Error ? slaveResult.reason.message : '備機更新失敗';
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
result.masterError = error instanceof Error ? error.message : '雙寫更新執行失敗';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 智能雙寫關聯表 - 使用對應的競賽 ID
|
||||
async smartDualInsertRelation(
|
||||
relationTable: string,
|
||||
@@ -260,6 +307,71 @@ export class DatabaseSyncFixed {
|
||||
}
|
||||
}
|
||||
|
||||
// 獲取主機記錄
|
||||
private async getMasterRecord(tableName: string, id: string): Promise<any> {
|
||||
if (!this.masterPool) return null;
|
||||
|
||||
const connection = await this.masterPool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.execute(`SELECT * FROM ${tableName} WHERE id = ?`, [id]);
|
||||
return (rows as any[])[0] || null;
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 根據名稱獲取備機記錄 ID
|
||||
private async getSlaveRecordIdByName(tableName: string, name: string): Promise<string | null> {
|
||||
if (!this.slavePool) return null;
|
||||
|
||||
const connection = await this.slavePool.getConnection();
|
||||
try {
|
||||
const [rows] = await connection.execute(`SELECT id FROM ${tableName} WHERE name = ? ORDER BY created_at DESC LIMIT 1`, [name]);
|
||||
const result = (rows as any[])[0]?.id || null;
|
||||
return result && typeof result !== 'string' ? String(result) : result;
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新主機記錄
|
||||
private async updateMasterRecord(tableName: string, id: string, updates: Record<string, any>): Promise<void> {
|
||||
if (!this.masterPool) return;
|
||||
|
||||
const fields = Object.keys(updates).filter(key => key !== 'id' && key !== 'created_at');
|
||||
if (fields.length === 0) return;
|
||||
|
||||
const setClause = fields.map(field => `${field} = ?`).join(', ');
|
||||
const values = fields.map(field => updates[field]);
|
||||
|
||||
const connection = await this.masterPool.getConnection();
|
||||
try {
|
||||
const sql = `UPDATE ${tableName} SET ${setClause}, updated_at = CURRENT_TIMESTAMP WHERE id = ?`;
|
||||
await connection.execute(sql, [...values, id]);
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新備機記錄
|
||||
private async updateSlaveRecord(tableName: string, id: string, updates: Record<string, any>): Promise<void> {
|
||||
if (!this.slavePool) return;
|
||||
|
||||
const fields = Object.keys(updates).filter(key => key !== 'id' && key !== 'created_at');
|
||||
if (fields.length === 0) return;
|
||||
|
||||
const setClause = fields.map(field => `${field} = ?`).join(', ');
|
||||
const values = fields.map(field => updates[field]);
|
||||
|
||||
const connection = await this.slavePool.getConnection();
|
||||
try {
|
||||
const sql = `UPDATE ${tableName} SET ${setClause}, updated_at = CURRENT_TIMESTAMP WHERE id = ?`;
|
||||
await connection.execute(sql, [...values, id]);
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 根據名稱獲取備機競賽 ID
|
||||
private async getSlaveCompetitionIdByName(name: string): Promise<string | null> {
|
||||
if (!this.slavePool) return null;
|
||||
@@ -350,6 +462,135 @@ export class DatabaseSyncFixed {
|
||||
}
|
||||
}
|
||||
|
||||
// 清除所有競賽的當前狀態
|
||||
async clearAllCurrentCompetitions(): Promise<WriteResult> {
|
||||
const result: WriteResult = {
|
||||
success: false,
|
||||
masterSuccess: false,
|
||||
slaveSuccess: false
|
||||
};
|
||||
|
||||
try {
|
||||
// 同時清除主機和備機的所有當前競賽狀態
|
||||
const masterPromise = this.clearMasterCurrentCompetitions();
|
||||
const slavePromise = this.clearSlaveCurrentCompetitions();
|
||||
|
||||
const [masterResult, slaveResult] = await Promise.allSettled([masterPromise, slavePromise]);
|
||||
|
||||
result.masterSuccess = masterResult.status === 'fulfilled';
|
||||
result.slaveSuccess = slaveResult.status === 'fulfilled';
|
||||
result.success = result.masterSuccess || result.slaveSuccess;
|
||||
|
||||
if (masterResult.status === 'rejected') {
|
||||
result.masterError = masterResult.reason instanceof Error ? masterResult.reason.message : '主機清除失敗';
|
||||
}
|
||||
if (slaveResult.status === 'rejected') {
|
||||
result.slaveError = slaveResult.reason instanceof Error ? slaveResult.reason.message : '備機清除失敗';
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
result.masterError = error instanceof Error ? error.message : '清除所有當前競賽執行失敗';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 清除主機的所有當前競賽狀態
|
||||
private async clearMasterCurrentCompetitions(): Promise<void> {
|
||||
if (!this.masterPool) return;
|
||||
|
||||
const connection = await this.masterPool.getConnection();
|
||||
try {
|
||||
await connection.execute('UPDATE competitions SET is_current = FALSE');
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 清除備機的所有當前競賽狀態
|
||||
private async clearSlaveCurrentCompetitions(): Promise<void> {
|
||||
if (!this.slavePool) return;
|
||||
|
||||
const connection = await this.slavePool.getConnection();
|
||||
try {
|
||||
await connection.execute('UPDATE competitions SET is_current = FALSE');
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 智能雙寫刪除
|
||||
async smartDualDelete(tableName: string, id: string, idField: string = 'id'): Promise<WriteResult> {
|
||||
const result: WriteResult = {
|
||||
success: false,
|
||||
masterSuccess: false,
|
||||
slaveSuccess: false
|
||||
};
|
||||
|
||||
try {
|
||||
// 獲取備機對應的 ID
|
||||
let slaveId: string | null = null;
|
||||
if (tableName === 'competitions') {
|
||||
// 對於競賽表,先獲取競賽名稱
|
||||
const masterRecord = await this.getMasterRecord(tableName, id);
|
||||
if (masterRecord) {
|
||||
slaveId = await this.getSlaveRecordIdByName(tableName, masterRecord.name);
|
||||
}
|
||||
} else {
|
||||
// 對於關聯表,直接使用主機 ID
|
||||
slaveId = id;
|
||||
}
|
||||
|
||||
// 同時刪除主機和備機的記錄
|
||||
const masterPromise = this.deleteFromMaster(tableName, id, idField);
|
||||
const slavePromise = slaveId ? this.deleteFromSlave(tableName, slaveId, idField) : Promise.resolve();
|
||||
|
||||
const [masterResult, slaveResult] = await Promise.allSettled([masterPromise, slavePromise]);
|
||||
|
||||
result.masterSuccess = masterResult.status === 'fulfilled';
|
||||
result.slaveSuccess = slaveResult.status === 'fulfilled';
|
||||
result.success = result.masterSuccess || result.slaveSuccess;
|
||||
|
||||
if (masterResult.status === 'rejected') {
|
||||
result.masterError = masterResult.reason instanceof Error ? masterResult.reason.message : '主機刪除失敗';
|
||||
}
|
||||
if (slaveResult.status === 'rejected') {
|
||||
result.slaveError = slaveResult.reason instanceof Error ? slaveResult.reason.message : '備機刪除失敗';
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
result.masterError = error instanceof Error ? error.message : '雙寫刪除執行失敗';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 從主機刪除記錄
|
||||
private async deleteFromMaster(tableName: string, id: string, idField: string = 'id'): Promise<void> {
|
||||
if (!this.masterPool) return;
|
||||
|
||||
const connection = await this.masterPool.getConnection();
|
||||
try {
|
||||
const sql = `DELETE FROM ${tableName} WHERE ${idField} = ?`;
|
||||
await connection.execute(sql, [id]);
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 從備機刪除記錄
|
||||
private async deleteFromSlave(tableName: string, id: string, idField: string = 'id'): Promise<void> {
|
||||
if (!this.slavePool) return;
|
||||
|
||||
const connection = await this.slavePool.getConnection();
|
||||
try {
|
||||
const sql = `DELETE FROM ${tableName} WHERE ${idField} = ?`;
|
||||
await connection.execute(sql, [id]);
|
||||
} finally {
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 清理資源
|
||||
async close(): Promise<void> {
|
||||
if (this.masterPool) {
|
||||
|
Reference in New Issue
Block a user