(table: TableDefinition)
| 895 | * cells, and those rows are NOT selected for deletion (NULL ≠ TRUE) — they must stay visible. |
| 896 | */ |
| 897 | export async function pendingDeleteMask(table: TableDefinition): Promise<SQL | undefined> { |
| 898 | const [job] = await db |
| 899 | .select({ payload: tableJobs.payload }) |
| 900 | .from(tableJobs) |
| 901 | .where( |
| 902 | and( |
| 903 | eq(tableJobs.tableId, table.id), |
| 904 | eq(tableJobs.status, 'running'), |
| 905 | eq(tableJobs.type, 'delete') |
| 906 | ) |
| 907 | ) |
| 908 | .limit(1) |
| 909 | if (!job?.payload) return undefined |
| 910 | const scope = job.payload as TableDeleteJobPayload |
| 911 | |
| 912 | // A bounded delete (explicit limit) deletes only the first `maxRows` matches, so the filter-based |
| 913 | // mask — which hides every match — would over-hide the rows beyond the cap this job never touches. |
| 914 | // Leave those reads unmasked; the bounded delete is eventually consistent like a bounded update. |
| 915 | if (scope.maxRows !== undefined) return undefined |
| 916 | |
| 917 | const doomedParts: SQL[] = [] |
| 918 | if (scope.filter && Object.keys(scope.filter).length > 0) { |
| 919 | try { |
| 920 | const clause = buildFilterClause(scope.filter, USER_TABLE_ROWS_SQL_NAME, table.schema.columns) |
| 921 | if (clause) doomedParts.push(clause) |
| 922 | } catch (error) { |
| 923 | // Schema drifted mid-job (column renamed/deleted). Showing doomed rows briefly beats |
| 924 | // failing every read; the worker resolves the same way on its next page. |
| 925 | logger.warn(`Skipping delete-job mask for table ${table.id}: stale filter`, { |
| 926 | error: toError(error).message, |
| 927 | }) |
| 928 | return undefined |
| 929 | } |
| 930 | } |
| 931 | if (scope.cutoff) doomedParts.push(lte(userTableRows.createdAt, new Date(scope.cutoff))) |
| 932 | if (scope.excludeRowIds && scope.excludeRowIds.length > 0) { |
| 933 | doomedParts.push(notInArray(userTableRows.id, scope.excludeRowIds)) |
| 934 | } |
| 935 | if (doomedParts.length === 0) return undefined |
| 936 | return sql`(${and(...doomedParts)}) IS NOT TRUE` |
| 937 | } |
| 938 | |
| 939 | /** |
| 940 | * `COUNT(*)` for a filtered view, kept inside the tenant's rows: measured |
no test coverage detected