after_migrate 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62f5a309584cee52788e0ea45c222648cc58c4db46bc08ce6188c6325f6c62dc
4
- data.tar.gz: e36efca18e936086cdace33a4fe422c2d34f63502ddf01c53090cf8048ed92c6
3
+ metadata.gz: b9d807edc34ee3c61bcda0ef4fd2319f80bac36c3bcd1cd1e2a46eb9f5e44f28
4
+ data.tar.gz: 16547159bf93c5a192a38a1e92d441bcd9690412b8d58ae163f59f8bc2da71bb
5
5
  SHA512:
6
- metadata.gz: 2590c965f71fc07b5171cea88869115516687331138b0a6a20b5c4bdd3008a13be1c7a7382dd8886112a02e076904d57f59e2f24db44bfa23d1c36dd30700b40
7
- data.tar.gz: 4a2f1dd2df2bb18e8f663b1ca150db22a6d4d5474b651ea0ee693129640926266ce77168e370921cab4ac214620a601fe02f6204a97829575ec7e417c944a7d4
6
+ metadata.gz: a7e76304080055fe4b9669d9895b9fb3709266c89e29deb2e39b3d408a29ba88ef1b99ebe951e693da446d2c97fda40ba416b71fae517234b65975e250b6635d
7
+ data.tar.gz: 14823ec925953300f85d28586a232111f945c2b9b8fb20bdaa4bf9d3057f8467dec2eb76defda50317a5811bbd6f7071bf71bb195f188950ab2a340030e0b2a5
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.2.3] - 2026-06-01
6
+
7
+ ### Added
8
+ - Redis-backed store via `config.store = :redis` for sharing collected migration tables across processes
9
+ - `config.redis` for passing a Redis client, connection pool, or callable client provider
10
+ - `config.redis_key_prefix` and `config.redis_ttl` for namespacing and expiring Redis store keys
11
+ - Redis store support for run isolation via `config.run_id`
12
+ - Redis store specs for persistence, merging, reset behavior, connection pools, `Redis.new` fallback, and missing-client errors
13
+
14
+ ### Changed
15
+ - Store cache keys now include Redis-specific configuration, so changing Redis store settings rebuilds the active store instance
16
+
5
17
  ## [0.2.2] - 2026-05-31
6
18
 
7
19
  ### Added
@@ -100,5 +100,94 @@ module AfterMigrate
100
100
  end
101
101
  end
102
102
  end
103
+
104
+ class RedisStore < Memory
105
+ attr_reader :key_prefix, :run_id, :ttl
106
+
107
+ def initialize(redis:, key_prefix: 'after_migrate', run_id: nil, ttl: 24 * 60 * 60)
108
+ super()
109
+ @redis = redis
110
+ @key_prefix = key_prefix.to_s
111
+ @run_id = run_id.to_s.presence || 'default'
112
+ @ttl = ttl.to_i
113
+ end
114
+
115
+ def affected_tables
116
+ load_into_memory
117
+ super
118
+ end
119
+
120
+ def merge_tables(schema, table_names)
121
+ return if table_names.blank?
122
+
123
+ with_redis do |redis|
124
+ redis.sadd(index_key, schema)
125
+ redis.sadd(schema_key(schema), table_names.to_a)
126
+ expire_keys(redis, schema)
127
+ end
128
+ merge_into_memory(schema => table_names)
129
+ end
130
+
131
+ def reset!
132
+ super
133
+ with_redis do |redis|
134
+ schemas = redis.smembers(index_key)
135
+ keys = schemas.map { |schema| schema_key(schema) }
136
+ redis.del(*(keys + [index_key])) if keys.any?
137
+ redis.del(index_key) if keys.empty?
138
+ end
139
+ end
140
+
141
+ private
142
+
143
+ def load_into_memory
144
+ with_redis do |redis|
145
+ redis.smembers(index_key).each do |schema|
146
+ merge_into_memory(schema => redis.smembers(schema_key(schema)))
147
+ end
148
+ end
149
+ end
150
+
151
+ def merge_into_memory(schemas)
152
+ schemas.each do |schema, table_names|
153
+ set = @affected_tables.compute_if_absent(schema) { Concurrent::Set.new }
154
+ set.merge(table_names)
155
+ end
156
+ end
157
+
158
+ def index_key
159
+ "#{base_key}:schemas"
160
+ end
161
+
162
+ def schema_key(schema)
163
+ "#{base_key}:schema:#{schema}"
164
+ end
165
+
166
+ def base_key
167
+ "#{key_prefix}:#{run_id}"
168
+ end
169
+
170
+ def expire_keys(redis, schema)
171
+ return unless ttl.positive?
172
+
173
+ redis.expire(index_key, ttl)
174
+ redis.expire(schema_key(schema), ttl)
175
+ end
176
+
177
+ def with_redis(&block)
178
+ redis = resolved_redis
179
+ return redis.with { |connection| block.call(connection) } if redis.respond_to?(:with)
180
+
181
+ block.call(redis)
182
+ end
183
+
184
+ def resolved_redis
185
+ client = @redis.respond_to?(:call) ? @redis.call : @redis
186
+ return client if client
187
+ return Redis.new if defined?(Redis)
188
+
189
+ raise 'AfterMigrate Redis store requires config.redis or the redis gem'
190
+ end
191
+ end
103
192
  end
104
193
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AfterMigrate
4
- VERSION = '0.2.2'
4
+ VERSION = '0.2.3'
5
5
  end
data/lib/after_migrate.rb CHANGED
@@ -8,7 +8,8 @@ require 'after_migrate/railtie'
8
8
 
9
9
  module AfterMigrate
10
10
  class Configuration
11
- attr_accessor :enabled, :verbose, :vacuum, :analyze, :rake_tasks_enhanced, :defer, :store, :store_path, :run_id
11
+ attr_accessor :enabled, :verbose, :vacuum, :analyze, :rake_tasks_enhanced, :defer,
12
+ :store, :store_path, :run_id, :redis, :redis_key_prefix, :redis_ttl
12
13
 
13
14
  def initialize
14
15
  @enabled = true
@@ -20,6 +21,9 @@ module AfterMigrate
20
21
  @store = :memory
21
22
  @store_path = 'tmp/after_migrate/affected_tables.json'
22
23
  @run_id = nil
24
+ @redis = nil
25
+ @redis_key_prefix = 'after_migrate'
26
+ @redis_ttl = 24 * 60 * 60
23
27
  end
24
28
  end
25
29
 
@@ -58,21 +62,41 @@ module AfterMigrate
58
62
  end
59
63
 
60
64
  def store
61
- key = [configuration.store.to_s, configuration.store_path.to_s, configuration.run_id.to_s]
62
- @store = nil if @store_key != key
63
- @store_key = key
65
+ @store = nil if @store_key != store_key
66
+ @store_key = store_key
64
67
  @store ||= build_store
65
68
  end
66
69
 
67
70
  private
68
71
 
72
+ def store_key
73
+ [
74
+ configuration.store.to_s,
75
+ configuration.store_path.to_s,
76
+ configuration.run_id.to_s,
77
+ configuration.redis_key_prefix.to_s,
78
+ configuration.redis_ttl.to_s
79
+ ]
80
+ end
81
+
69
82
  def build_store
70
83
  case configuration.store.to_s
71
84
  when 'file'
72
85
  Stores::FileStore.new(path: configuration.store_path, run_id: configuration.run_id)
86
+ when 'redis'
87
+ redis_store
73
88
  else
74
89
  Stores::Memory.new
75
90
  end
76
91
  end
92
+
93
+ def redis_store
94
+ Stores::RedisStore.new(
95
+ redis: configuration.redis,
96
+ key_prefix: configuration.redis_key_prefix,
97
+ run_id: configuration.run_id,
98
+ ttl: configuration.redis_ttl
99
+ )
100
+ end
77
101
  end
78
102
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: after_migrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikolay Moskvin