Class: Apartment::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/apartment/config.rb

Overview

Configuration object for Apartment v4. Created via Apartment.configure block; validated after the block yields.

Constant Summary collapse

VALID_STRATEGIES =
%i[schema database_name shard database_config].freeze
VALID_ENVIRONMENTIFY_STRATEGIES =
[nil, :prepend, :append].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfig

rubocop:disable Metrics/AbcSize



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/apartment/config.rb', line 27

def initialize # rubocop:disable Metrics/AbcSize
  @tenant_strategy = nil
  @tenants_provider = nil
  @default_tenant = nil
  @excluded_models = []
  @tenant_pool_size = 5
  @pool_idle_timeout = 300
  @max_total_connections = nil
  @seed_after_create = false
  @seed_data_file = nil
  @schema_load_strategy = nil
  @schema_file = nil
  @parallel_migration_threads = 0
  @environmentify_strategy = nil
  @elevator = nil
  @elevator_options = {}
  @tenant_not_found_handler = nil
  @active_record_log = false
  @sql_query_tags = false
  @postgres_config = nil
  @mysql_config = nil
  @shard_key_prefix = 'apartment'
  @migration_role = nil
  @app_role = nil
  @schema_cache_per_tenant = false
  @check_pending_migrations = true
end

Instance Attribute Details

#active_record_logObject

Returns the value of attribute active_record_log.



17
18
19
# File 'lib/apartment/config.rb', line 17

def active_record_log
  @active_record_log
end

#app_roleObject

Returns the value of attribute app_role.



17
18
19
# File 'lib/apartment/config.rb', line 17

def app_role
  @app_role
end

#check_pending_migrationsObject

Returns the value of attribute check_pending_migrations.



17
18
19
# File 'lib/apartment/config.rb', line 17

def check_pending_migrations
  @check_pending_migrations
end

#default_tenantObject

Returns the value of attribute default_tenant.



17
18
19
# File 'lib/apartment/config.rb', line 17

def default_tenant
  @default_tenant
end

#elevatorObject

Returns the value of attribute elevator.



17
18
19
# File 'lib/apartment/config.rb', line 17

def elevator
  @elevator
end

#elevator_optionsObject

Returns the value of attribute elevator_options.



17
18
19
# File 'lib/apartment/config.rb', line 17

def elevator_options
  @elevator_options
end

#environmentify_strategyObject

Returns the value of attribute environmentify_strategy.



14
15
16
# File 'lib/apartment/config.rb', line 14

def environmentify_strategy
  @environmentify_strategy
end

#excluded_modelsObject

Returns the value of attribute excluded_models.



14
15
16
# File 'lib/apartment/config.rb', line 14

def excluded_models
  @excluded_models
end

#max_total_connectionsObject

Returns the value of attribute max_total_connections.



17
18
19
# File 'lib/apartment/config.rb', line 17

def max_total_connections
  @max_total_connections
end

#migration_roleObject

Returns the value of attribute migration_role.



17
18
19
# File 'lib/apartment/config.rb', line 17

def migration_role
  @migration_role
end

#mysql_configObject (readonly)

Returns the value of attribute mysql_config.



14
15
16
# File 'lib/apartment/config.rb', line 14

def mysql_config
  @mysql_config
end

#parallel_migration_threadsObject

Returns the value of attribute parallel_migration_threads.



17
18
19
# File 'lib/apartment/config.rb', line 17

def parallel_migration_threads
  @parallel_migration_threads
end

#pool_idle_timeoutObject

Returns the value of attribute pool_idle_timeout.



17
18
19
# File 'lib/apartment/config.rb', line 17

def pool_idle_timeout
  @pool_idle_timeout
end

#postgres_configObject (readonly)

Returns the value of attribute postgres_config.



14
15
16
# File 'lib/apartment/config.rb', line 14

def postgres_config
  @postgres_config
end

#schema_cache_per_tenantObject

Returns the value of attribute schema_cache_per_tenant.



17
18
19
# File 'lib/apartment/config.rb', line 17

def schema_cache_per_tenant
  @schema_cache_per_tenant
end

#schema_fileObject

Returns the value of attribute schema_file.



17
18
19
# File 'lib/apartment/config.rb', line 17

def schema_file
  @schema_file
end

#schema_load_strategyObject

Returns the value of attribute schema_load_strategy.



17
18
19
# File 'lib/apartment/config.rb', line 17

def schema_load_strategy
  @schema_load_strategy
end

#seed_after_createObject

Returns the value of attribute seed_after_create.



17
18
19
# File 'lib/apartment/config.rb', line 17

def seed_after_create
  @seed_after_create
end

#seed_data_fileObject

Returns the value of attribute seed_data_file.



17
18
19
# File 'lib/apartment/config.rb', line 17

def seed_data_file
  @seed_data_file
end

#shard_key_prefixObject

Returns the value of attribute shard_key_prefix.



17
18
19
# File 'lib/apartment/config.rb', line 17

def shard_key_prefix
  @shard_key_prefix
end

#sql_query_tagsObject

Returns the value of attribute sql_query_tags.



17
18
19
# File 'lib/apartment/config.rb', line 17

def sql_query_tags
  @sql_query_tags
end

#tenant_not_found_handlerObject

Returns the value of attribute tenant_not_found_handler.



17
18
19
# File 'lib/apartment/config.rb', line 17

def tenant_not_found_handler
  @tenant_not_found_handler
end

#tenant_pool_sizeObject

Returns the value of attribute tenant_pool_size.



17
18
19
# File 'lib/apartment/config.rb', line 17

def tenant_pool_size
  @tenant_pool_size
end

#tenant_strategyObject

Returns the value of attribute tenant_strategy.



14
15
16
# File 'lib/apartment/config.rb', line 14

def tenant_strategy
  @tenant_strategy
end

#tenants_providerObject

Returns the value of attribute tenants_provider.



17
18
19
# File 'lib/apartment/config.rb', line 17

def tenants_provider
  @tenants_provider
end

Instance Method Details

#configure_mysql {|@mysql_config| ... } ⇒ Object

Configure MySQL-specific options via block.

Yields:



90
91
92
93
94
# File 'lib/apartment/config.rb', line 90

def configure_mysql
  @mysql_config = Configs::MysqlConfig.new
  yield(@mysql_config) if block_given?
  @mysql_config
end

#configure_postgres {|@postgres_config| ... } ⇒ Object

Configure PostgreSQL-specific options via block.

Yields:



83
84
85
86
87
# File 'lib/apartment/config.rb', line 83

def configure_postgres
  @postgres_config = Configs::PostgresqlConfig.new
  yield(@postgres_config) if block_given?
  @postgres_config
end

#freeze!Object

Deep-freeze the config after validation to prevent post-boot mutation. Freezes mutable collections and sub-configs, then freezes self.



98
99
100
101
102
103
104
105
106
# File 'lib/apartment/config.rb', line 98

def freeze!
  @excluded_models.freeze
  @elevator_options.freeze
  @postgres_config&.freeze!
  @mysql_config&.freeze!
  # schema_file is a simple string, no deep freeze needed
  @app_role.freeze if @app_role.is_a?(String)
  freeze
end

#rails_env_nameObject

Returns the current Rails environment name, falling back to env vars and a safe default.



165
166
167
# File 'lib/apartment/config.rb', line 165

def rails_env_name
  (Rails.env if defined?(Rails.env)) || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'default_env'
end

#validate!Object

Validate configuration completeness and consistency. Raises ConfigurationError on invalid state.

Raises:



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/apartment/config.rb', line 110

def validate! # rubocop:disable Metrics/AbcSize
  raise(ConfigurationError, 'tenant_strategy is required') unless @tenant_strategy

  unless @tenants_provider.respond_to?(:call)
    raise(ConfigurationError, 'tenants_provider must be a callable (e.g., -> { Tenant.pluck(:name) })')
  end

  if @postgres_config && @mysql_config
    raise(ConfigurationError, 'Cannot configure both Postgres and MySQL at the same time')
  end

  unless @tenant_pool_size.is_a?(Integer) && @tenant_pool_size.positive?
    raise(ConfigurationError, "tenant_pool_size must be a positive integer, got: #{@tenant_pool_size.inspect}")
  end

  unless @pool_idle_timeout.is_a?(Numeric) && @pool_idle_timeout.positive?
    raise(ConfigurationError, "pool_idle_timeout must be a positive number, got: #{@pool_idle_timeout.inspect}")
  end

  if @max_total_connections && (!@max_total_connections.is_a?(Integer) || @max_total_connections < 1)
    raise(ConfigurationError,
          "max_total_connections must be a positive integer or nil, got: #{@max_total_connections.inspect}")
  end

  unless [nil, :schema_rb, :sql].include?(@schema_load_strategy)
    raise(ConfigurationError, "Invalid schema_load_strategy: #{@schema_load_strategy.inspect}. " \
                              'Must be nil, :schema_rb, or :sql')
  end

  if @migration_role && !@migration_role.is_a?(Symbol)
    raise(ConfigurationError, "migration_role must be nil or a Symbol, got: #{@migration_role.inspect}")
  end

  if @app_role && !@app_role.is_a?(String) && !@app_role.respond_to?(:call)
    raise(ConfigurationError, "app_role must be nil, a String, or a callable, got: #{@app_role.inspect}")
  end

  unless [true, false].include?(@schema_cache_per_tenant)
    raise(ConfigurationError,
          "schema_cache_per_tenant must be true or false, got: #{@schema_cache_per_tenant.inspect}")
  end

  unless [true, false].include?(@check_pending_migrations)
    raise(ConfigurationError,
          "check_pending_migrations must be true or false, got: #{@check_pending_migrations.inspect}")
  end

  return if @shard_key_prefix.is_a?(String) && @shard_key_prefix.match?(/\A[a-z_][a-z0-9_]*\z/)

  raise(ConfigurationError,
        'shard_key_prefix must be a lowercase string matching /[a-z_][a-z0-9_]*/, ' \
        "got: #{@shard_key_prefix.inspect}")
end