Class: PgSqlTriggers::Registry::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/pg_sql_triggers/registry/manager.rb

Class Method Summary collapse

Class Method Details

._clear_registry_cacheObject



17
18
19
# File 'lib/pg_sql_triggers/registry/manager.rb', line 17

def _clear_registry_cache
  REGISTRY_CACHE_MUTEX.synchronize { @_registry_cache = {} }
end

._registry_cacheObject

Request-level cache to avoid N+1 queries when loading multiple trigger files. Access to @_registry_cache is guarded by REGISTRY_CACHE_MUTEX so that concurrent threads cannot observe a partially-initialised hash.



13
14
15
# File 'lib/pg_sql_triggers/registry/manager.rb', line 13

def _registry_cache
  REGISTRY_CACHE_MUTEX.synchronize { @_registry_cache ||= {} }
end

.diff(trigger_name = nil) ⇒ Object



100
101
102
# File 'lib/pg_sql_triggers/registry/manager.rb', line 100

def diff(trigger_name = nil)
  PgSqlTriggers::Drift.detect(trigger_name)
end

.driftedObject



104
105
106
107
108
# File 'lib/pg_sql_triggers/registry/manager.rb', line 104

def drifted
  PgSqlTriggers::Drift::Detector.detect_all.select do |r|
    r[:state] == PgSqlTriggers::DRIFT_STATE_DRIFTED
  end
end

.droppedObject



122
123
124
125
126
# File 'lib/pg_sql_triggers/registry/manager.rb', line 122

def dropped
  PgSqlTriggers::Drift::Detector.detect_all.select do |r|
    r[:state] == PgSqlTriggers::DRIFT_STATE_DROPPED
  end
end

.in_syncObject



110
111
112
113
114
# File 'lib/pg_sql_triggers/registry/manager.rb', line 110

def in_sync
  PgSqlTriggers::Drift::Detector.detect_all.select do |r|
    r[:state] == PgSqlTriggers::DRIFT_STATE_IN_SYNC
  end
end

.listObject



90
91
92
# File 'lib/pg_sql_triggers/registry/manager.rb', line 90

def list
  PgSqlTriggers::TriggerRegistry.all
end

.preload_triggers(trigger_names) ⇒ Object

Batch load existing triggers into cache to avoid N+1 queries Call this before registering multiple triggers for better performance



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/pg_sql_triggers/registry/manager.rb', line 23

def preload_triggers(trigger_names)
  return if trigger_names.empty?

  # Find all triggers that aren't already cached
  uncached_names = trigger_names - _registry_cache.keys
  return if uncached_names.empty?

  # Batch load all uncached triggers in a single query
  PgSqlTriggers::TriggerRegistry.where(trigger_name: uncached_names).find_each do |trigger|
    _registry_cache[trigger.trigger_name] = trigger
  end
end

.register(definition) ⇒ Object



36
37
38
39
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
87
88
# File 'lib/pg_sql_triggers/registry/manager.rb', line 36

def register(definition)
  trigger_name = definition.name

  # Use cached lookup if available to avoid N+1 queries during trigger file loading
  # Explicitly check cache first to avoid query in some Ruby versions where ||= may evaluate RHS
  existing = if _registry_cache.key?(trigger_name)
               _registry_cache[trigger_name]
             else
               _registry_cache[trigger_name] =
                 PgSqlTriggers::TriggerRegistry.find_by(trigger_name: trigger_name)
             end

  # Calculate checksum using field-concatenation (consistent with TriggerRegistry model)
  checksum = calculate_checksum(definition)
  attributes = registration_attributes(definition, checksum)

  if existing
    # Check if attributes have actually changed to avoid unnecessary queries
    attributes_changed = attributes.any? do |key, value|
      existing.send(key) != value
    end
    enabled_changed = existing.enabled != definition.enabled

    if attributes_changed
      begin
        existing.update!(attributes)
        # Update cache with the modified record (reload to get fresh data)
        reloaded = existing.reload
        _registry_cache[trigger_name] = reloaded
        if enabled_changed
          sync_postgresql_enabled_state(existing.trigger_name, existing.table_name, definition.enabled)
        end
        reloaded
      rescue ActiveRecord::RecordNotFound
        # Cached record was deleted, create a new one
        new_record = PgSqlTriggers::TriggerRegistry.create!(attributes)
        _registry_cache[trigger_name] = new_record
        new_record
      end
    else
      # No changes, return cached record without any queries
      existing
    end
  else
    new_record = PgSqlTriggers::TriggerRegistry.create!(attributes)
    # Cache the newly created record
    _registry_cache[trigger_name] = new_record
    unless definition.enabled
      sync_postgresql_enabled_state(new_record.trigger_name, new_record.table_name, definition.enabled)
    end
    new_record
  end
end

.unknown_triggersObject



116
117
118
119
120
# File 'lib/pg_sql_triggers/registry/manager.rb', line 116

def unknown_triggers
  PgSqlTriggers::Drift::Detector.detect_all.select do |r|
    r[:state] == PgSqlTriggers::DRIFT_STATE_UNKNOWN
  end
end