fix: use relations instead of references to deduce what to reprocess

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2023-04-13 23:30:38 +02:00
parent 4e018f01cf
commit 87082cf42e
2 changed files with 41 additions and 21 deletions
@@ -22,6 +22,7 @@ import {
DbFinalEntitiesRow,
DbRefreshStateReferencesRow,
DbRefreshStateRow,
DbRelationsRow,
} from '../../tables';
import { deleteOrphanedEntities } from './deleteOrphanedEntities';
@@ -55,15 +56,6 @@ describe('deleteOrphanedEntities', () => {
return result!;
}
async function insertReference(
knex: Knex,
...refs: DbRefreshStateReferencesRow[]
) {
return knex<DbRefreshStateReferencesRow>('refresh_state_references').insert(
refs,
);
}
async function insertEntity(knex: Knex, ...entityRefs: string[]) {
for (const ref of entityRefs) {
const entityId = uuid.v4();
@@ -85,6 +77,28 @@ describe('deleteOrphanedEntities', () => {
}
}
async function insertReference(
knex: Knex,
...refs: DbRefreshStateReferencesRow[]
) {
await knex<DbRefreshStateReferencesRow>('refresh_state_references').insert(
refs,
);
}
async function insertRelation(knex: Knex, fromRef: string, toRef: string) {
const orig = await knex
.select('entity_id')
.from('refresh_state')
.where('entity_ref', fromRef);
await knex<DbRelationsRow>('relations').insert({
originating_entity_id: orig[0].entity_id,
type: 'fake',
source_entity_ref: fromRef,
target_entity_ref: toRef,
});
}
async function refreshState(knex: Knex) {
return await knex<DbRefreshStateRow>('refresh_state')
.orderBy('entity_ref')
@@ -109,6 +123,8 @@ describe('deleteOrphanedEntities', () => {
'works for some mixed paths, %p',
async databaseId => {
/*
In this graph, edges represent refresh state references, not entity relations:
P1 - E1 -- E2
/
E3
@@ -127,7 +143,8 @@ describe('deleteOrphanedEntities', () => {
E10
Result: E3, E4, E5, E6, and E10 deleted; others remain; children of deleted orphans marked for reprocessing
Result: E3, E4, E5, E6, and E10 deleted; others remain
Entities that had relations pointing at orphans are marked for reprocessing
*/
const knex = await createDatabase(databaseId);
await insertEntity(
@@ -156,18 +173,21 @@ describe('deleteOrphanedEntities', () => {
{ source_entity_ref: 'E8', target_entity_ref: 'E7' },
{ source_key: 'P3', target_entity_ref: 'E9' },
);
await insertRelation(knex, 'E1', 'E2');
await insertRelation(knex, 'E2', 'E3');
await insertRelation(knex, 'E10', 'E6');
await expect(run(knex)).resolves.toEqual(5);
await expect(refreshState(knex)).resolves.toEqual([
{ entity_ref: 'E1', result_hash: 'original' },
{ entity_ref: 'E2', result_hash: 'orphan-parent-deleted' },
{ entity_ref: 'E7', result_hash: 'orphan-parent-deleted' },
{ entity_ref: 'E2', result_hash: 'orphan-relation-deleted' },
{ entity_ref: 'E7', result_hash: 'original' },
{ entity_ref: 'E8', result_hash: 'original' },
{ entity_ref: 'E9', result_hash: 'original' },
]);
await expect(finalEntities(knex)).resolves.toEqual([
{ entity_ref: 'E1', hash: 'original' },
{ entity_ref: 'E2', hash: 'orphan-parent-deleted' },
{ entity_ref: 'E7', hash: 'orphan-parent-deleted' },
{ entity_ref: 'E2', hash: 'orphan-relation-deleted' },
{ entity_ref: 'E7', hash: 'original' },
{ entity_ref: 'E8', hash: 'original' },
{ entity_ref: 'E9', hash: 'original' },
]);
@@ -43,18 +43,18 @@ export async function deleteOrphanedEntities(options: {
)
.select({
entityId: 'orphans.entity_id',
relationTargetId: 'refresh_state.entity_id',
relationSourceId: 'refresh_state.entity_id',
})
.from('orphans')
.leftOuterJoin(
'refresh_state_references',
'refresh_state_references.source_entity_ref',
'relations',
'relations.target_entity_ref',
'orphans.entity_ref',
)
.leftOuterJoin(
'refresh_state',
'refresh_state.entity_ref',
'refresh_state_references.target_entity_ref',
'relations.source_entity_ref',
);
if (!candidates.length) {
@@ -63,7 +63,7 @@ export async function deleteOrphanedEntities(options: {
const orphanIds: string[] = uniq(candidates.map(r => r.entityId));
const orphanRelationIds: string[] = uniq(
candidates.map(r => r.relationTargetId).filter(Boolean),
candidates.map(r => r.relationSourceId).filter(Boolean),
);
total += orphanIds.length;
@@ -79,13 +79,13 @@ export async function deleteOrphanedEntities(options: {
await tx
.table<DbFinalEntitiesRow>('final_entities')
.update({
hash: 'orphan-parent-deleted',
hash: 'orphan-relation-deleted',
})
.whereIn('entity_id', orphanRelationIds);
await tx
.table<DbRefreshStateRow>('refresh_state')
.update({
result_hash: 'orphan-parent-deleted',
result_hash: 'orphan-relation-deleted',
next_update_at: tx.fn.now(),
})
.whereIn('entity_id', orphanRelationIds);