LCOV - code coverage report
Current view: top level - dashql-app/src/connections/catalog - catalog_update_state.tsx Coverage Total Hit
Test: DashQL 915828b Lines: 100.0 % 136 136
Test Date: 2026-11-06 19:30:32

            Line data    Source code
       1              : import {
       2              :     CATALOG_UPDATE_CANCELLED,
       3              :     CATALOG_UPDATE_FAILED,
       4              :     CATALOG_UPDATE_SCHEMA_SCRIPT,
       5              :     CATALOG_UPDATE_REGISTER_QUERY,
       6              :     CATALOG_UPDATE_PARTIALLY_SUCCEEDED,
       7              :     CATALOG_UPDATE_SUCCEEDED,
       8              :     CatalogAction,
       9              :     ConnectionState,
      10              :     SET_CATALOG_SCRIPT,
      11              :     UPDATE_CATALOG,
      12              : } from '../connection_state.js';
      13              : 
      14              : 
      15            1 : export enum CatalogUpdateVariant {
      16            1 :     FULL_CATALOG_REFRESH
      17            1 : }
      18              : 
      19            1 : export enum CatalogUpdateTaskStatus {
      20            1 :     STARTED = 0,
      21            1 :     SUCCEEDED = 1,
      22            1 :     FAILED = 2,
      23            1 :     CANCELLED = 3,
      24            1 :     PARTIALLY_SUCCEEDED = 4,
      25            1 : }
      26              : export const CATALOG_UPDATE_TASK_STATUS_NAMES: string[] = [
      27              :     "Started",
      28              :     "Succeeded",
      29              :     "Failed",
      30              :     "Cancelled",
      31              :     "Partially Succeeded",
      32              : ];
      33              : 
      34              : export interface CatalogUpdateTaskState {
      35              :     /// The task key
      36              :     taskId: number;
      37              :     /// The catalog update variant
      38              :     taskVariant: CatalogUpdateVariant;
      39              :     /// The status
      40              :     status: CatalogUpdateTaskStatus;
      41              :     /// The cancellation signal
      42              :     cancellation: AbortController;
      43              :     /// The queries
      44              :     queries: number[];
      45              :     /// The loading error (if any)
      46              :     error: Error | null;
      47              :     /// The time at which the loading started (if any)
      48              :     startedAt: Date | null;
      49              :     /// The time at which the loading finishe (if any)
      50              :     finishedAt: Date | null;
      51              :     /// The time at which the task was last updated
      52              :     lastUpdateAt: Date | null;
      53              : }
      54              : 
      55            1 : export function isCatalogRefreshRunning(connection: ConnectionState | null): boolean {
      56            1 :     if (connection == null) return false;
      57            1 :     const refreshId = connection.catalogUpdates.currentFullRefresh;
      58            1 :     return refreshId != null && connection.catalogUpdates.tasksRunning.has(refreshId);
      59            1 : }
      60              : 
      61            1 : export function reduceCatalogAction(state: ConnectionState, action: CatalogAction): ConnectionState {
      62            1 :     const now = new Date();
      63              : 
      64            1 :     if (action.type == UPDATE_CATALOG) {
      65            1 :         const [updateId, update] = action.value;
      66            1 :         state.catalogUpdates.tasksRunning.set(updateId, update);
      67            1 :         return {
      68            1 :             ...state,
      69            1 :             catalogUpdates: {
      70            1 :                 ...state.catalogUpdates,
      71            1 :                 tasksRunning: state.catalogUpdates.tasksRunning,
      72            1 :                 currentFullRefresh: update.taskVariant == CatalogUpdateVariant.FULL_CATALOG_REFRESH
      73            1 :                     ? updateId
      74            1 :                     : state.catalogUpdates.currentFullRefresh
      75            1 :             },
      76            1 :         };
      77            1 :     }
      78              : 
      79              :     // SET_CATALOG_SCRIPT doesn't involve catalog updates
      80            1 :     if (action.type == SET_CATALOG_SCRIPT) {
      81            1 :         return state;
      82              :     }
      83              : 
      84            1 :     const updateId = (action.value as [number, ...any])[0];
      85            1 :     let update = state.catalogUpdates.tasksRunning.get(updateId);
      86            1 :     if (!update) {
      87            1 :         return state;
      88              :     }
      89            1 :     switch (action.type) {
      90            1 :         case CATALOG_UPDATE_REGISTER_QUERY: {
      91            1 :             update = {
      92            1 :                 ...update,
      93            1 :                 queries: [...update.queries, action.value[1]],
      94            1 :                 lastUpdateAt: now,
      95            1 :             };
      96            1 :             state.catalogUpdates.tasksRunning.set(updateId, update);
      97            1 :             return {
      98            1 :                 ...state,
      99            1 :                 catalogUpdates: {
     100            1 :                     ...state.catalogUpdates,
     101            1 :                     tasksRunning: state.catalogUpdates.tasksRunning,
     102            1 :                 }
     103            1 :             };
     104              :         }
     105            1 :         case CATALOG_UPDATE_SCHEMA_SCRIPT: {
     106            1 :             update = {
     107            1 :                 ...update,
     108            1 :                 lastUpdateAt: now,
     109            1 :             };
     110            1 :             state.catalogUpdates.tasksRunning.set(updateId, update);
     111            1 :             return {
     112            1 :                 ...state,
     113            1 :                 catalogUpdates: {
     114            1 :                     ...state.catalogUpdates,
     115            1 :                     tasksRunning: state.catalogUpdates.tasksRunning,
     116            1 :                 }
     117            1 :             };
     118              :         }
     119            1 :         case CATALOG_UPDATE_CANCELLED:
     120            1 :             update = {
     121            1 :                 ...update,
     122            1 :                 status: CatalogUpdateTaskStatus.CANCELLED,
     123            1 :                 error: action.value[1],
     124            1 :                 finishedAt: now,
     125            1 :                 lastUpdateAt: now,
     126            1 :             };
     127            1 :             state.catalogUpdates.tasksRunning.delete(updateId);
     128            1 :             state.catalogUpdates.tasksFinished.set(updateId, update);
     129            1 :             return {
     130            1 :                 ...state,
     131            1 :                 catalogUpdates: {
     132            1 :                     tasksRunning: state.catalogUpdates.tasksRunning,
     133            1 :                     tasksFinished: state.catalogUpdates.tasksFinished,
     134            1 :                     restoredAt: state.catalogUpdates.restoredAt,
     135            1 :                     currentFullRefresh: state.catalogUpdates.currentFullRefresh,
     136            1 :                     lastFullRefresh: state.catalogUpdates.currentFullRefresh === updateId
     137            1 :                         ? updateId : state.catalogUpdates.lastFullRefresh,
     138            1 :                 }
     139            1 :             };
     140            1 :         case CATALOG_UPDATE_FAILED:
     141            1 :             update = {
     142            1 :                 ...update,
     143            1 :                 status: CatalogUpdateTaskStatus.FAILED,
     144            1 :                 error: action.value[1],
     145            1 :                 finishedAt: now,
     146            1 :                 lastUpdateAt: now,
     147            1 :             };
     148            1 :             state.catalogUpdates.tasksRunning.delete(updateId);
     149            1 :             state.catalogUpdates.tasksFinished.set(updateId, update);
     150            1 :             return {
     151            1 :                 ...state,
     152            1 :                 catalogUpdates: {
     153            1 :                     tasksRunning: state.catalogUpdates.tasksRunning,
     154            1 :                     tasksFinished: state.catalogUpdates.tasksFinished,
     155            1 :                     restoredAt: state.catalogUpdates.restoredAt,
     156            1 :                     currentFullRefresh: state.catalogUpdates.currentFullRefresh,
     157            1 :                     lastFullRefresh: state.catalogUpdates.currentFullRefresh === updateId
     158            1 :                         ? updateId : state.catalogUpdates.lastFullRefresh,
     159            1 :                 }
     160            1 :             };
     161            1 :         case CATALOG_UPDATE_SUCCEEDED:
     162            1 :         case CATALOG_UPDATE_PARTIALLY_SUCCEEDED:
     163            1 :             update = {
     164            1 :                 ...update,
     165            1 :                 status: action.type === CATALOG_UPDATE_SUCCEEDED
     166            1 :                     ? CatalogUpdateTaskStatus.SUCCEEDED
     167            1 :                     : CatalogUpdateTaskStatus.PARTIALLY_SUCCEEDED,
     168            1 :                 error: action.type === CATALOG_UPDATE_PARTIALLY_SUCCEEDED ? action.value[1] : null,
     169            1 :                 finishedAt: now,
     170            1 :                 lastUpdateAt: now,
     171            1 :             };
     172            1 :             state.catalogUpdates.tasksRunning.delete(updateId);
     173            1 :             state.catalogUpdates.tasksFinished.set(updateId, update);
     174              :             // The refreshed relation script describes the catalog, the changes of earlier statements are part of it
     175            1 :             return {
     176            1 :                 ...state,
     177            1 :                 catalogChangesSql: '',
     178            1 :                 catalogUpdates: {
     179            1 :                     tasksRunning: state.catalogUpdates.tasksRunning,
     180            1 :                     tasksFinished: state.catalogUpdates.tasksFinished,
     181            1 :                     restoredAt: state.catalogUpdates.restoredAt,
     182            1 :                     currentFullRefresh: state.catalogUpdates.currentFullRefresh,
     183            1 :                     lastFullRefresh: state.catalogUpdates.currentFullRefresh === updateId
     184            1 :                         ? updateId : state.catalogUpdates.lastFullRefresh,
     185            1 :                 }
     186            1 :             };
     187            1 :         default:
     188            1 :             return state;
     189            1 :     }
     190            1 : }
        

Generated by: LCOV version 2.0-1