Showing 2 of 4 files from the diff.

@@ -336,18 +336,60 @@
Loading
336 336
337 337
        if tg_op == INSERT:
338 338
339 -
            if table == root_table and table in self.tree.nodes:
340 -
                for payload in payloads:
341 -
                    payload_data = self._payload_data(payload)
342 -
                    primary_values = [
343 -
                        payload_data[key] for key in primary_keys
344 -
                    ]
345 -
                    primary_fields = dict(
346 -
                        zip(primary_keys, primary_values)
347 -
                    )
348 -
                    filters[table].append({
349 -
                        key: value for key, value in primary_fields.items()
350 -
                    })
339 +
            if table in self.tree.nodes:
340 +
341 +
                if table == root_table:
342 +
                    for payload in payloads:
343 +
                        payload_data = self._payload_data(payload)
344 +
                        primary_values = [
345 +
                            payload_data[key] for key in primary_keys
346 +
                        ]
347 +
                        primary_fields = dict(
348 +
                            zip(primary_keys, primary_values)
349 +
                        )
350 +
                        filters[table].append({
351 +
                            key: value for key, value in primary_fields.items()
352 +
                        })
353 +
                else:
354 +
                    root = self.tree.build(nodes[0])
355 +
                    for node in traverse_post_order(root):
356 +
                        if table != node.table:
357 +
                            continue
358 +
359 +
                        if not node.parent:
360 +
                            logger.exception(
361 +
                                f'Could not get parent from node: '
362 +
                                f'{node.schema}.{node.table}'
363 +
                            )
364 +
                            raise
365 +
                        # set the parent as the new entity that has changed
366 +
                        filters[node.parent.table] = []
367 +
                        parent_model = self.model(
368 +
                            node.parent.table,
369 +
                            node.parent.schema,
370 +
                        )
371 +
                        foreign_keys = get_foreign_keys(
372 +
                            parent_model,
373 +
                            model,
374 +
                        )
375 +
376 +
                        _table = table
377 +
                        if not _table.startswith(f'{schema}.'):
378 +
                            _table = f'{schema}.{table}'
379 +
380 +
                        node_parent_table = node.parent.table
381 +
382 +
                        if not node_parent_table.startswith(f'{schema}.'):
383 +
                            node_parent_table = f'{schema}.{node_parent_table}'
384 +
385 +
                        for payload in payloads:
386 +
                            payload_data = self._payload_data(payload)
387 +
                            for i, key in enumerate(foreign_keys[_table]):
388 +
                                value = payload_data[key]
389 +
                                filters[node.parent.table].append({
390 +
                                    foreign_keys[node_parent_table][i]: value
391 +
                                })
392 +
351 393
            else:
352 394
353 395
                # handle case where we insert into a through table

@@ -15,8 +15,20 @@
Loading
15 15
      JOIN pg_attribute ON attrelid = indrelid AND attnum = ANY(indkey)
16 16
      WHERE indrelid = TG_RELID AND indisprimary
17 17
  );
18 +
  foreign_keys TEXT [] := (
19 +
      SELECT ARRAY_AGG(constraint_column_usage.column_name)
20 +
      FROM information_schema.table_constraints AS table_constraints
21 +
      JOIN information_schema.key_column_usage AS key_column_usage
22 +
      ON table_constraints.constraint_name = key_column_usage.constraint_name
23 +
      AND table_constraints.table_schema = key_column_usage.table_schema
24 +
      JOIN information_schema.constraint_column_usage AS constraint_column_usage
25 +
      ON constraint_column_usage.constraint_name = table_constraints.constraint_name
26 +
      AND constraint_column_usage.table_schema = table_constraints.table_schema
27 +
      WHERE table_constraints.constraint_type = 'FOREIGN KEY'
28 +
      AND table_constraints.table_name = TG_TABLE_NAME
29 +
  );
18 30
BEGIN
19 -
    -- database is also the channel name
31 +
    -- database is also the channel name.
20 32
    channel := CURRENT_DATABASE();
21 33
22 34
    IF TG_OP = 'DELETE' THEN
@@ -33,14 +45,14 @@
Loading
33 45
            new_row := (
34 46
                SELECT JSONB_OBJECT_AGG(key, value)
35 47
                FROM JSON_EACH(new_row)
36 -
                WHERE key = ANY(primary_keys)
48 +
                WHERE key = ANY(primary_keys) OR key = ANY(foreign_keys)
37 49
            );
38 50
            IF TG_OP = 'UPDATE' THEN
39 51
                old_row = ROW_TO_JSON(OLD);
40 52
                old_row := (
41 53
                    SELECT JSONB_OBJECT_AGG(key, value)
42 54
                    FROM JSON_EACH(old_row)
43 -
                    WHERE key = ANY(primary_keys)
55 +
                    WHERE key = ANY(primary_keys) OR key = ANY(foreign_keys)
44 56
                );
45 57
            END IF;
46 58
            xmin := NEW.xmin;
Files Coverage
pgsync 68.92%
tests/__init__.py 100.00%
Project Totals (10 files) 68.99%
codecov-umbrella
Build #361887110 -
unittests
codecov-umbrella
Build #361887110 -
unittests
codecov-umbrella
Build #361887110 -
unittests
codecov-umbrella
Build #361887110 -
unittests
codecov-umbrella
Build #361892550 -
unittests
codecov-umbrella
Build #361892550 -
unittests
codecov-umbrella
Build #361892550 -
unittests
codecov-umbrella
Build #361892550 -
unittests
1
coverage:
2
  status:
3
    project:
4
      default:
5
        threshold: 70%
6

7
codecov:
8
  archive: 
9
    uploads: false
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading