Module: Athar::Dashboard::ModelRegistry

Defined in:
lib/athar/dashboard/model_registry.rb

Defined Under Namespace

Classes: ModelInfo

Constant Summary collapse

DELETE_TRIGGER_SQL =
<<~SQL
  SELECT n.nspname AS schema_name, c.relname AS table_name,
         pg_get_triggerdef(t.oid) AS definition
  FROM pg_trigger t
  JOIN pg_proc p ON p.oid = t.tgfoid
  JOIN pg_class c ON c.oid = t.tgrelid
  JOIN pg_namespace n ON n.oid = c.relnamespace
  WHERE p.proname = 'athar_capture_delete' AND NOT t.tgisinternal
SQL
TRUNCATE_TRIGGER_SQL =
<<~SQL
  SELECT n.nspname AS schema_name, c.relname AS table_name
  FROM pg_trigger t
  JOIN pg_proc p ON p.oid = t.tgfoid
  JOIN pg_class c ON c.oid = t.tgrelid
  JOIN pg_namespace n ON n.oid = c.relnamespace
  WHERE p.proname = 'athar_capture_truncate' AND NOT t.tgisinternal
SQL
COUNTS_SQL =
<<~SQL.freeze
  SELECT schema_name, table_name, record_type, COUNT(*) AS n
  FROM #{Athar::DELETIONS_TABLE_NAME}
  GROUP BY schema_name, table_name, record_type
SQL
ARGS_RE =
/EXECUTE\s+(?:PROCEDURE|FUNCTION)\s+athar_capture_delete\((.*)\)/m
PG_ARRAY_QUOTED =
/"([^"]*)"/
PG_ARRAY_BARE =
/[^,]+/

Class Method Summary collapse

Class Method Details

.discoverObject

rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/athar/dashboard/model_registry.rb', line 40

def discover # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  connection = Athar.audit_connection
  triggers = parse_delete_triggers(connection)
  truncate_keys = truncate_trigger_keys(connection)
  counts = load_counts(connection)

  # One ModelInfo per (schema, table) trigger.
  primary = triggers.map do |trigger|
    key = [trigger[:schema], trigger[:table]]

    ModelInfo.new(
      schema: trigger[:schema],
      table: trigger[:table],
      record_type: trigger[:record_type] || trigger[:table].classify,
      capture_mode: trigger[:capture_mode],
      columns: trigger[:columns],
      masks: trigger[:masks],
      sti: trigger[:sti],
      truncate: truncate_keys.include?(key),
      count: counts.fetch(
        [trigger[:schema], trigger[:table], trigger[:record_type] || trigger[:table].classify],
        0
      )
    )
  end

  # STI children: any (schema, table, record_type) in counts that doesn't
  # match a primary's record_type but whose (schema, table) has STI on.
  children = counts.filter_map do |(schema, table, record_type), n|
    parent = primary.find { |entry| entry.schema == schema && entry.table == table }
    next unless parent&.sti && parent.record_type != record_type

    ModelInfo.new(
      schema:,
      table:,
      record_type:,
      capture_mode: parent.capture_mode,
      columns: parent.columns,
      masks: parent.masks,
      sti: true,
      truncate: parent.truncate,
      count: n
    )
  end

  primary + children
end