Module: ActiveVersion
- Extended by:
- ActiveSupport::Autoload
- Defined in:
- lib/active_version.rb,
lib/active_version/query.rb,
lib/active_version/audits.rb,
lib/active_version/railtie.rb,
lib/active_version/runtime.rb,
lib/active_version/version.rb,
lib/active_version/adapters.rb,
lib/active_version/database.rb,
lib/active_version/sharding.rb,
lib/active_version/migrators.rb,
lib/active_version/revisions.rb,
lib/active_version/translations.rb,
lib/active_version/column_mapper.rb,
lib/active_version/configuration.rb,
lib/active_version/migrators/base.rb,
lib/active_version/adapters/sequel.rb,
lib/active_version/instrumentation.rb,
lib/active_version/version_registry.rb,
lib/active_version/audits/has_audits.rb,
lib/active_version/migrators/audited.rb,
lib/active_version/audits/sql_builder.rb,
lib/active_version/audits/audit_record.rb,
lib/active_version/revisions/sql_builder.rb,
lib/active_version/adapters/active_record.rb,
lib/active_version/revisions/has_revisions.rb,
lib/active_version/unique_version_collision.rb,
lib/active_version/revisions/revision_record.rb,
lib/active_version/adapters/sequel/versioning.rb,
lib/active_version/sharding/connection_router.rb,
lib/active_version/adapters/active_record/base.rb,
lib/active_version/database/triggers/postgresql.rb,
lib/active_version/adapters/active_record/audits.rb,
lib/active_version/audits/audit_record/callbacks.rb,
lib/active_version/translations/has_translations.rb,
lib/active_version/audits/has_audits/audit_writer.rb,
lib/active_version/audits/audit_record/serializers.rb,
lib/active_version/translations/translation_record.rb,
lib/active_version/adapters/active_record/revisions.rb,
lib/active_version/audits/has_audits/audit_combiner.rb,
lib/active_version/audits/has_audits/change_filters.rb,
lib/active_version/audits/has_audits/audit_callbacks.rb,
lib/generators/active_version/audits/audits_generator.rb,
lib/active_version/adapters/active_record/translations.rb,
lib/generators/active_version/install/install_generator.rb,
lib/generators/active_version/triggers/triggers_generator.rb,
lib/active_version/revisions/has_revisions/revision_queries.rb,
lib/generators/active_version/revisions/revisions_generator.rb,
lib/active_version/audits/has_audits/database_adapter_helper.rb,
lib/active_version/revisions/has_revisions/revision_manipulation.rb,
lib/generators/active_version/translations/translations_generator.rb,
sig/active_version.rbs,
sig/active_version/core.rbs,
sig/active_version/audits.rbs,
sig/active_version/runtime.rbs,
sig/active_version/advanced.rbs,
sig/active_version/revisions.rbs,
sig/active_version/translations.rbs,
sig/active_version/configuration.rbs,
sig/active_version/instrumentation.rbs,
sig/active_version/registry_and_mapping.rbs
Overview
Main entry point for ActiveVersion
Defined Under Namespace
Modules: Adapters, Audits, Database, Generators, Instrumentation, Migrators, Query, Revisions, Runtime, SchemaGuards, Sharding, Translations, UniqueVersionCollision
Classes: ColumnMapper, Configuration, ConfigurationError, DeletedColumnError, Error, FutureTimeError, Railtie, ReadonlyVersionError, RequestStore, VersionNotFoundError, VersionRegistry
Constant Summary
collapse
- VERSION =
"2.0.0"
Class Attribute Summary collapse
Class Method Summary
collapse
-
.adapter_for(model_class, version_type) ⇒ Object
-
.auditing_enabled ⇒ Boolean
Convenience methods for accessing configuration.
-
.auditing_enabled=(value) ⇒ Boolean
-
.clear_context! ⇒ nil
Clear persistent context.
-
.clear_scoped_keys!(pattern) ⇒ void
-
.column_mapper ⇒ ColumnMapper
-
.config ⇒ Configuration
-
.configure {|config| ... } ⇒ Configuration
-
.connection_for(model_class, version_type) ⇒ Object
Connection access is intentionally application-owned.
-
.context ⇒ Hash[untyped, untyped]
-
.context=(value) ⇒ Hash[untyped, untyped]
-
.default_logger ⇒ Object
-
.disable_auditing ⇒ Boolean
-
.enable_auditing ⇒ Boolean
-
.enter_context_block! ⇒ Object
-
.leave_context_block! ⇒ Object
-
.log_debug(message) ⇒ Object
-
.parse_time(time) ⇒ Time
Parse time from various formats Converts Numeric (Unix timestamp), String, Date, Time, or other objects to Time.
-
.parse_time_to_time(time) ⇒ Time
Parse time and return Time object (alias for clarity).
-
.registry ⇒ VersionRegistry
-
.reset_runtime_adapter! ⇒ Object
-
.runtime_adapter ⇒ Object
Runtime adapter access (ActiveRecord by default).
-
.runtime_adapter=(adapter) ⇒ Object
-
.store_delete(key) ⇒ Object
-
.store_get(key) ⇒ Object
-
.store_keys ⇒ Object
-
.store_set(key, value) ⇒ Object
-
.time_parser ⇒ Object
-
.transactional_context_supported? ⇒ Boolean
-
.with_connection(model_class, version_type) {|Runtime.adapter.connection_for(model_class, version_type)| ... } ⇒ Object
-
.with_context(context = nil, transactional: true, **kwargs) { ... } ⇒ Object
Transaction-aware context (uses PostgreSQL session variables) Accepts either a hash as first argument or keyword arguments.
-
.with_context!(context) ⇒ nil
Persistent context (connection-level, persists across operations).
-
.with_thread_local_context(context, &block) ⇒ Object
-
.with_transactional_context(context, &block) ⇒ Object
-
.without_auditing { ... } ⇒ Object
Disable versioning globally.
Class Attribute Details
.logger ⇒ Object
336
337
338
339
340
|
# File 'lib/active_version.rb', line 336
def logger
return @logger if defined?(@logger)
@logger = default_logger
end
|
Class Method Details
.adapter_for(model_class, version_type) ⇒ Object
324
325
326
|
# File 'lib/active_version.rb', line 324
def self.adapter_for(model_class, version_type)
Runtime.adapter.connection_for(model_class, version_type)
end
|
.auditing_enabled ⇒ Boolean
Convenience methods for accessing configuration
73
74
75
|
# File 'lib/active_version.rb', line 73
def self.auditing_enabled
config.auditing_enabled
end
|
.auditing_enabled=(value) ⇒ Boolean
77
78
79
|
# File 'lib/active_version.rb', line 77
def self.auditing_enabled=(value)
config.auditing_enabled = value
end
|
.clear_context! ⇒ nil
154
155
156
157
158
159
|
# File 'lib/active_version.rb', line 154
def self.clear_context!
store_delete(:active_version_persistent_context)
store_set(:active_version_context_depth, 0)
store_set(:active_version_in_block, false)
nil
end
|
.clear_scoped_keys!(pattern) ⇒ void
This method returns an undefined value.
200
201
202
|
# File 'lib/active_version.rb', line 200
def self.clear_scoped_keys!(pattern)
store_keys.grep(pattern).each { |key| store_delete(key) }
end
|
293
294
295
|
# File 'lib/active_version.rb', line 293
def self.column_mapper
@column_mapper ||= ColumnMapper.new
end
|
63
64
65
|
# File 'lib/active_version.rb', line 63
def self.config
@config ||= Configuration.new
end
|
67
68
69
70
|
# File 'lib/active_version.rb', line 67
def self.configure
yield config if block_given?
config
end
|
.connection_for(model_class, version_type) ⇒ Object
Connection access is intentionally application-owned.
ActiveVersion does not route between shards/connections.
These methods remain as pass-through helpers.
320
321
322
|
# File 'lib/active_version.rb', line 320
def self.connection_for(model_class, version_type)
:default
end
|
.context ⇒ Hash[untyped, untyped]
102
103
104
105
106
107
|
# File 'lib/active_version.rb', line 102
def self.context
persistent = store_get(:active_version_persistent_context) || {}
request_scoped = RequestStore.version_context || {}
persistent.merge(request_scoped)
end
|
.context=(value) ⇒ Hash[untyped, untyped]
.default_logger ⇒ Object
349
350
351
352
353
354
|
# File 'lib/active_version.rb', line 349
def default_logger
l = Logger.new($stderr)
l.level = Logger::WARN
l.formatter = proc { |_, _, _, msg| "#{msg}\n" }
l
end
|
.disable_auditing ⇒ Boolean
279
280
281
|
# File 'lib/active_version.rb', line 279
def self.disable_auditing
self.auditing_enabled = false
end
|
.enable_auditing ⇒ Boolean
283
284
285
|
# File 'lib/active_version.rb', line 283
def self.enable_auditing
self.auditing_enabled = true
end
|
.enter_context_block! ⇒ Object
205
206
207
208
209
|
# File 'lib/active_version.rb', line 205
def self.enter_context_block!
depth = store_get(:active_version_context_depth).to_i + 1
store_set(:active_version_context_depth, depth)
store_set(:active_version_in_block, depth.positive?)
end
|
.leave_context_block! ⇒ Object
211
212
213
214
215
216
|
# File 'lib/active_version.rb', line 211
def self.leave_context_block!
depth = store_get(:active_version_context_depth).to_i - 1
depth = 0 if depth.negative?
store_set(:active_version_context_depth, depth)
store_set(:active_version_in_block, depth.positive?)
end
|
.log_debug(message) ⇒ Object
342
343
344
345
346
347
|
# File 'lib/active_version.rb', line 342
def log_debug(message)
logger = self.logger
return if logger.nil?
logger.debug(message) if logger.respond_to?(:debug)
end
|
.parse_time(time) ⇒ Time
Parse time from various formats
Converts Numeric (Unix timestamp), String, Date, Time, or other objects to Time
301
302
303
304
305
306
307
308
309
310
|
# File 'lib/active_version.rb', line 301
def self.parse_time(time)
parser = time_parser
case time
when Numeric then parser.at(time)
when String then parser.parse(time)
when Date then time.to_time
when Time then time
else parser.parse(time.to_s)
end
end
|
.parse_time_to_time(time) ⇒ Time
Parse time and return Time object (alias for clarity)
313
314
315
|
# File 'lib/active_version.rb', line 313
def self.parse_time_to_time(time)
parse_time(time)
end
|
288
289
290
|
# File 'lib/active_version.rb', line 288
def self.registry
@registry ||= VersionRegistry.new
end
|
.reset_runtime_adapter! ⇒ Object
90
91
92
|
# File 'lib/active_version.rb', line 90
def self.reset_runtime_adapter!
Runtime.reset_adapter!
end
|
.runtime_adapter ⇒ Object
Runtime adapter access (ActiveRecord by default).
82
83
84
|
# File 'lib/active_version.rb', line 82
def self.runtime_adapter
Runtime.adapter
end
|
.runtime_adapter=(adapter) ⇒ Object
86
87
88
|
# File 'lib/active_version.rb', line 86
def self.runtime_adapter=(adapter)
Runtime.adapter = adapter
end
|
.store_delete(key) ⇒ Object
181
182
183
|
# File 'lib/active_version.rb', line 181
def self.store_delete(key)
store_set(key, nil)
end
|
.store_get(key) ⇒ Object
161
162
163
164
165
166
167
168
169
|
# File 'lib/active_version.rb', line 161
def self.store_get(key)
if config.execution_scope == :thread
Thread.current.thread_variable_get(key)
elsif Fiber.current.respond_to?(:[])
Fiber.current[key]
else
thread_current_for_fallback_store[key]
end
end
|
.store_keys ⇒ Object
185
186
187
188
189
190
191
192
193
|
# File 'lib/active_version.rb', line 185
def self.store_keys
if config.execution_scope == :thread
Thread.current.thread_variables
elsif thread_current_for_fallback_store.respond_to?(:keys)
thread_current_for_fallback_store.keys
else
[]
end
end
|
.store_set(key, value) ⇒ Object
171
172
173
174
175
176
177
178
179
|
# File 'lib/active_version.rb', line 171
def self.store_set(key, value)
if config.execution_scope == :thread
Thread.current.thread_variable_set(key, value)
elsif Fiber.current.respond_to?(:[]=)
Fiber.current[key] = value
else
thread_current_for_fallback_store[key] = value
end
end
|
.time_parser ⇒ Object
252
253
254
255
|
# File 'lib/active_version.rb', line 252
def self.time_parser
zone = Time.zone if Time.respond_to?(:zone)
zone || Time
end
|
.transactional_context_supported? ⇒ Boolean
.with_connection(model_class, version_type) {|Runtime.adapter.connection_for(model_class, version_type)| ... } ⇒ Object
328
329
330
|
# File 'lib/active_version.rb', line 328
def self.with_connection(model_class, version_type, &block)
yield(Runtime.adapter.connection_for(model_class, version_type))
end
|
.with_context(context = nil, transactional: true, **kwargs) { ... } ⇒ Object
Transaction-aware context (uses PostgreSQL session variables)
Accepts either a hash as first argument or keyword arguments
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
# File 'lib/active_version.rb', line 116
def self.with_context(context = nil, transactional: true, **kwargs, &block)
raise ArgumentError, "with_context requires a block" unless block_given?
context_hash = if context.nil? && kwargs.any?
kwargs
elsif context.is_a?(Hash)
context
elsif context.nil?
{}
else
raise ArgumentError, "context must be a hash or keyword arguments"
end
if transactional_context_supported?
with_transactional_context(context_hash, &block)
else
with_thread_local_context(context_hash, &block)
end
end
|
.with_context!(context) ⇒ nil
Persistent context (connection-level, persists across operations)
142
143
144
145
146
147
148
149
150
151
|
# File 'lib/active_version.rb', line 142
def self.with_context!(context)
raise ArgumentError, "context must be a hash" unless context.is_a?(Hash)
if store_get(:active_version_in_block)
raise Error, "with_context! cannot be called from within a with_context block"
end
store_set(:active_version_persistent_context, context)
nil
end
|
.with_thread_local_context(context, &block) ⇒ Object
257
258
259
260
261
262
263
264
265
266
267
268
|
# File 'lib/active_version.rb', line 257
def self.with_thread_local_context(context, &block)
old_context = self.context.dup
old_block_context = store_get(:active_version_block_context)
enter_context_block!
self.context = old_context.merge(context)
store_set(:active_version_block_context, context)
yield
ensure
self.context = old_context
store_set(:active_version_block_context, old_block_context)
leave_context_block!
end
|
.with_transactional_context(context, &block) ⇒ Object
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
# File 'lib/active_version.rb', line 218
def self.with_transactional_context(context, &block)
connection = Runtime.adapter.base_connection
old_context = self.context.dup
old_block_context = store_get(:active_version_block_context)
enter_context_block!
if connection.open_transactions.positive?
encoded_context = connection.quote(ActiveSupport::JSON.encode(context))
connection.execute("SET LOCAL active_version.context = #{encoded_context}")
end
self.context = old_context.merge(context)
store_set(:active_version_block_context, context)
yield
ensure
self.context = old_context
store_set(:active_version_block_context, old_block_context)
leave_context_block!
end
|
.without_auditing { ... } ⇒ Object
Disable versioning globally
271
272
273
274
275
276
277
|
# File 'lib/active_version.rb', line 271
def self.without_auditing
auditing_was_enabled = auditing_enabled
disable_auditing
yield
ensure
enable_auditing if auditing_was_enabled
end
|