Class: PgReports::Connection::Registry
- Inherits:
-
Object
- Object
- PgReports::Connection::Registry
- Defined in:
- lib/pg_reports/connection/registry.rb
Overview
Registry of named PostgreSQL targets.
In a Rails app the :primary target is auto-registered on first access from ActiveRecord::Base.connection_db_config — no configuration is required. Additional targets can be registered explicitly via Configuration#add_target for setups where the dashboard should reach databases the host app cannot.
Current target/database is tracked in a Thread.current slot, switched via PgReports.with_target / PgReports.with_database for block-scoped usage.
Defined Under Namespace
Classes: UnknownTarget
Constant Summary collapse
- THREAD_KEY_TARGET =
:pg_reports_current_target- THREAD_KEY_DATABASE =
:pg_reports_current_database
Instance Attribute Summary collapse
-
#default_name ⇒ Object
Returns the value of attribute default_name.
Instance Method Summary collapse
-
#current_connection ⇒ Object
Resolve the AR connection to use right now (current target + database).
- #current_database ⇒ Object
-
#current_database_name ⇒ Object
The database name in effect for the current target.
- #current_name ⇒ Object
-
#current_target ⇒ Object
Returns the target that current_connection would resolve to.
-
#ensure_default_registered! ⇒ Object
Auto-discover the :primary target from ActiveRecord on first need.
- #fetch(name = nil) ⇒ Object
-
#initialize ⇒ Registry
constructor
A new instance of Registry.
-
#register(name, spec) ⇒ Object
Register or overwrite a target.
-
#reset! ⇒ Object
For tests / reload scenarios.
- #target?(name) ⇒ Boolean
- #target_names ⇒ Object
-
#targets ⇒ Object
All known targets (auto-registers :primary if needed first).
-
#with_context(target: nil, database: nil) ⇒ Object
Switch target and/or database for the duration of the block.
Constructor Details
#initialize ⇒ Registry
Returns a new instance of Registry.
20 21 22 23 24 25 |
# File 'lib/pg_reports/connection/registry.rb', line 20 def initialize @targets = {} @default_name = :primary @auto_registered = false @mutex = Mutex.new end |
Instance Attribute Details
#default_name ⇒ Object
Returns the value of attribute default_name.
27 28 29 |
# File 'lib/pg_reports/connection/registry.rb', line 27 def default_name @default_name end |
Instance Method Details
#current_connection ⇒ Object
Resolve the AR connection to use right now (current target + database). Honors PgReports.with_target / with_database thread-local context.
60 61 62 63 |
# File 'lib/pg_reports/connection/registry.rb', line 60 def current_connection target = fetch(current_name) target.connection_for(current_database) end |
#current_database ⇒ Object
79 80 81 |
# File 'lib/pg_reports/connection/registry.rb', line 79 def current_database Thread.current[THREAD_KEY_DATABASE] end |
#current_database_name ⇒ Object
The database name in effect for the current target.
71 72 73 |
# File 'lib/pg_reports/connection/registry.rb', line 71 def current_database_name current_database || fetch(current_name).default_database end |
#current_name ⇒ Object
75 76 77 |
# File 'lib/pg_reports/connection/registry.rb', line 75 def current_name Thread.current[THREAD_KEY_TARGET] end |
#current_target ⇒ Object
Returns the target that current_connection would resolve to.
66 67 68 |
# File 'lib/pg_reports/connection/registry.rb', line 66 def current_target fetch(current_name) end |
#ensure_default_registered! ⇒ Object
Auto-discover the :primary target from ActiveRecord on first need. Idempotent and thread-safe.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/pg_reports/connection/registry.rb', line 122 def ensure_default_registered! return if @auto_registered return unless defined?(ActiveRecord::Base) @mutex.synchronize do return if @auto_registered unless @targets.key?(:primary) spec = primary_spec_from_active_record @targets[:primary] = Target.new(:primary, spec) if spec end @auto_registered = true end end |
#fetch(name = nil) ⇒ Object
52 53 54 55 56 |
# File 'lib/pg_reports/connection/registry.rb', line 52 def fetch(name = nil) ensure_default_registered! key = (name || current_name || @default_name).to_sym @targets.fetch(key) { raise UnknownTarget, "Unknown target #{key.inspect}. Known: #{@targets.keys.inspect}" } end |
#register(name, spec) ⇒ Object
Register or overwrite a target.
34 35 36 |
# File 'lib/pg_reports/connection/registry.rb', line 34 def register(name, spec) @targets[name.to_sym] = Target.new(name, spec) end |
#reset! ⇒ Object
For tests / reload scenarios. Restores the registry to a fresh state —closes all derived pools, drops all registered targets, resets default_name back to :primary, and re-arms auto-registration.
111 112 113 114 115 116 117 118 |
# File 'lib/pg_reports/connection/registry.rb', line 111 def reset! @mutex.synchronize do @targets.each_value(&:disconnect!) @targets.clear @default_name = :primary @auto_registered = false end end |
#target?(name) ⇒ Boolean
48 49 50 |
# File 'lib/pg_reports/connection/registry.rb', line 48 def target?(name) targets.any? { |t| t.name == name.to_sym } end |
#target_names ⇒ Object
44 45 46 |
# File 'lib/pg_reports/connection/registry.rb', line 44 def target_names targets.map(&:name) end |
#targets ⇒ Object
All known targets (auto-registers :primary if needed first).
39 40 41 42 |
# File 'lib/pg_reports/connection/registry.rb', line 39 def targets ensure_default_registered! @targets.values end |
#with_context(target: nil, database: nil) ⇒ Object
Switch target and/or database for the duration of the block. Semantics:
-
target given → switches target AND clears the database override
(the previous database belongs to the previous target's cluster and would not be valid on a new one). Pass `database:` explicitly to override on the new target. -
target nil → keeps the active target, switches only database.
-
database nil → uses the (possibly new) target’s default database.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/pg_reports/connection/registry.rb', line 91 def with_context(target: nil, database: nil) prev_target = Thread.current[THREAD_KEY_TARGET] prev_database = Thread.current[THREAD_KEY_DATABASE] if target Thread.current[THREAD_KEY_TARGET] = target.to_sym Thread.current[THREAD_KEY_DATABASE] = database&.to_s elsif database Thread.current[THREAD_KEY_DATABASE] = database.to_s end yield ensure Thread.current[THREAD_KEY_TARGET] = prev_target Thread.current[THREAD_KEY_DATABASE] = prev_database end |