* Update formula column and handle dependencies * @param tableName Table name * @param tableColumnName Column name * @param property New property * @param fields All fields * @param db Database connection
(
tableName: string,
tableColumnName: string,
property: any,
fields: IField[],
db: BaseServerDatabase
)
| 342 | * @param db Database connection |
| 343 | */ |
| 344 | private async updateFormulaColumn( |
| 345 | tableName: string, |
| 346 | tableColumnName: string, |
| 347 | property: any, |
| 348 | fields: IField[], |
| 349 | db: BaseServerDatabase |
| 350 | ) { |
| 351 | // Find other generated columns that depend on the current column |
| 352 | const dependentFields = findDependentFormulaFields(tableColumnName, fields) |
| 353 | |
| 354 | if (dependentFields.length > 0) { |
| 355 | // If there are dependencies, we need to temporarily delete all dependent columns |
| 356 | const allColumnsToUpdate = [ |
| 357 | tableColumnName, |
| 358 | ...dependentFields.map((f) => f.columnName), |
| 359 | ] |
| 360 | |
| 361 | // Get the correct deletion order (delete columns that depend on others first) |
| 362 | const deletionOrder = getFormulaFieldDeletionOrder( |
| 363 | allColumnsToUpdate, |
| 364 | fields |
| 365 | ) |
| 366 | |
| 367 | // Save all column expressions for later recreation |
| 368 | const columnExpressions: Record<string, string> = {} |
| 369 | |
| 370 | // First delete all related columns (in dependency order) |
| 371 | for (const colName of deletionOrder) { |
| 372 | // Save expression for rebuilding |
| 373 | const expr = transformFormula2VirtualGeneratedField(colName, fields) |
| 374 | if (expr) { |
| 375 | columnExpressions[colName] = expr |
| 376 | } |
| 377 | |
| 378 | // Delete column |
| 379 | db.prepare(`ALTER TABLE ${tableName} DROP COLUMN ${colName};`).run() |
| 380 | } |
| 381 | |
| 382 | // Update the current column's expression |
| 383 | const updatedFields = fields.map((f) => |
| 384 | f.table_column_name === tableColumnName ? { ...f, property } : f |
| 385 | ) |
| 386 | |
| 387 | // Recalculate the current column's expression |
| 388 | columnExpressions[tableColumnName] = |
| 389 | transformFormula2VirtualGeneratedField( |
| 390 | tableColumnName, |
| 391 | updatedFields |
| 392 | ) || "" |
| 393 | |
| 394 | // Recreate all columns in reverse order (create dependent columns first) |
| 395 | for (const colName of deletionOrder.reverse()) { |
| 396 | if (columnExpressions[colName]) { |
| 397 | db.prepare( |
| 398 | `ALTER TABLE ${tableName} ADD COLUMN ${colName} GENERATED ALWAYS AS (${columnExpressions[colName]});` |
| 399 | ).run() |
| 400 | } |
| 401 | } |
no test coverage detected