|
| 1 | +import { QueryExecutor } from '@crowd/data-access-layer/src/queryExecutor' |
| 2 | + |
| 3 | +import { RepoWellKnownFilesUpdate } from './types' |
| 4 | + |
| 5 | +export async function bulkUpsertRepoWellKnownFiles( |
| 6 | + qx: QueryExecutor, |
| 7 | + updates: RepoWellKnownFilesUpdate[], |
| 8 | +): Promise<void> { |
| 9 | + if (updates.length === 0) return |
| 10 | + |
| 11 | + // dedupe by repoId: ON CONFLICT DO UPDATE cannot affect the same row twice in one statement |
| 12 | + const byRepo = new Map(updates.map((u) => [u.repoId, u])) |
| 13 | + const batch = [...byRepo.values()] |
| 14 | + |
| 15 | + await qx.result( |
| 16 | + ` |
| 17 | + WITH input AS ( |
| 18 | + SELECT |
| 19 | + (j->>'repoId')::bigint AS repo_id, |
| 20 | + (j->>'checkedAt')::timestamptz AS checked_at, |
| 21 | + j->'files' AS files |
| 22 | + FROM jsonb_array_elements($1::jsonb) j |
| 23 | + ), |
| 24 | + found AS ( |
| 25 | + SELECT |
| 26 | + i.repo_id, |
| 27 | + f->>'fileType' AS file_type, |
| 28 | + f->>'directory' AS directory, |
| 29 | + f->>'path' AS path, |
| 30 | + f->>'blobOid' AS blob_oid, |
| 31 | + i.checked_at |
| 32 | + FROM input i, jsonb_array_elements(i.files) f |
| 33 | + ), |
| 34 | + soft_deleted AS ( |
| 35 | + UPDATE repo_well_known_files w |
| 36 | + SET deleted_at = i.checked_at, |
| 37 | + change_detected_at = i.checked_at |
| 38 | + FROM input i |
| 39 | + WHERE w.repo_id = i.repo_id |
| 40 | + AND w.deleted_at IS NULL |
| 41 | + AND NOT EXISTS ( |
| 42 | + SELECT 1 FROM found f WHERE f.repo_id = w.repo_id AND f.path = w.path |
| 43 | + ) |
| 44 | + ) |
| 45 | + INSERT INTO repo_well_known_files (repo_id, file_type, directory, path, blob_oid, checked_at, change_detected_at) |
| 46 | + SELECT repo_id, file_type, directory, path, blob_oid, checked_at, checked_at |
| 47 | + FROM found |
| 48 | + ON CONFLICT (repo_id, path) DO UPDATE SET |
| 49 | + blob_oid = EXCLUDED.blob_oid, |
| 50 | + file_type = EXCLUDED.file_type, |
| 51 | + directory = EXCLUDED.directory, |
| 52 | + checked_at = EXCLUDED.checked_at, |
| 53 | + deleted_at = NULL, |
| 54 | + change_detected_at = CASE |
| 55 | + WHEN repo_well_known_files.blob_oid <> EXCLUDED.blob_oid |
| 56 | + OR repo_well_known_files.deleted_at IS NOT NULL |
| 57 | + THEN EXCLUDED.checked_at |
| 58 | + ELSE repo_well_known_files.change_detected_at |
| 59 | + END |
| 60 | + `, |
| 61 | + [JSON.stringify(batch)], |
| 62 | + ) |
| 63 | +} |
0 commit comments