pg_party 1.2.1 → 1.3.0
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 +4 -4
- data/README.md +27 -1
- data/lib/pg_party.rb +0 -6
- data/lib/pg_party/adapter/postgresql_methods.rb +9 -8
- data/lib/pg_party/adapter_decorator.rb +1 -1
- data/lib/pg_party/model/list_methods.rb +3 -2
- data/lib/pg_party/model/methods.rb +4 -4
- data/lib/pg_party/model/range_methods.rb +3 -2
- data/lib/pg_party/model_decorator.rb +25 -4
- data/lib/pg_party/model_injector.rb +11 -5
- data/lib/pg_party/version.rb +1 -1
- metadata +22 -9
- data/lib/pg_party/hacks/schema_cache.rb +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ee226c4523ca2b7099761ad517be99938078f7977281d88920beff47396f0c51
|
|
4
|
+
data.tar.gz: 2843ee1eb9fbe92e9998d8da0a3a20dfa989fa6c6dfcf3a261b80bac0caa47da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6cb4e5e42f08dcca3ec065c5d73656b6075e5a647d60722607cb4a9ff3cfeee24a94f4048544f3442284c816e7e37fe196579b9037e1ddacaaf1136e440efd4a
|
|
7
|
+
data.tar.gz: fdb593463dace1bdcfd844cac214cb6e6489dc7cd533226b90d11e506955ff48ad959fa80320423f3485637f89e3f6dbaeec5812ec0c1f640eb2d620e91de6dc
|
data/README.md
CHANGED
|
@@ -351,9 +351,35 @@ SomeRangeRecord.in_partition(:some_range_records_partition_name)
|
|
|
351
351
|
SomeListRecord.in_partition(:some_list_records_partition_name)
|
|
352
352
|
```
|
|
353
353
|
|
|
354
|
+
To create _range_ partitions by month for previous, current and next months it's possible to use this example. To automate creation of partitions, run `Log.maintenance` every day with cron:
|
|
355
|
+
|
|
356
|
+
```ruby
|
|
357
|
+
class Log < ApplicationRecord
|
|
358
|
+
range_partition_by { '(created_at::date)' }
|
|
359
|
+
|
|
360
|
+
def self.maintenance
|
|
361
|
+
partitions = [Date.today.prev_month, Date.today, Date.today.next_month]
|
|
362
|
+
|
|
363
|
+
partitions.each do |day|
|
|
364
|
+
name = Log.partition_name_for(day)
|
|
365
|
+
next if ActiveRecord::Base.connection.table_exists?(name)
|
|
366
|
+
Log.create_partition(
|
|
367
|
+
name: name,
|
|
368
|
+
start_range: day.beginning_of_month,
|
|
369
|
+
end_range: day.next_month.beginning_of_month
|
|
370
|
+
)
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def self.partition_name_for(day)
|
|
375
|
+
"logs_y#{day.year}_m#{day.month}"
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
```
|
|
379
|
+
|
|
354
380
|
For more examples, take a look at the model integration specs:
|
|
355
381
|
|
|
356
|
-
- https://github.com/rkrage/pg_party/tree/
|
|
382
|
+
- https://github.com/rkrage/pg_party/tree/master/spec/integration/model
|
|
357
383
|
|
|
358
384
|
## Development
|
|
359
385
|
|
data/lib/pg_party.rb
CHANGED
|
@@ -34,12 +34,6 @@ ActiveSupport.on_load(:active_record) do
|
|
|
34
34
|
PgParty::Adapter::AbstractMethods
|
|
35
35
|
)
|
|
36
36
|
|
|
37
|
-
require "pg_party/hacks/schema_cache"
|
|
38
|
-
|
|
39
|
-
ActiveRecord::ConnectionAdapters::SchemaCache.include(
|
|
40
|
-
PgParty::Hacks::SchemaCache
|
|
41
|
-
)
|
|
42
|
-
|
|
43
37
|
require "active_record/tasks/postgresql_database_tasks"
|
|
44
38
|
require "pg_party/hacks/postgresql_database_tasks"
|
|
45
39
|
|
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "pg_party/adapter_decorator"
|
|
4
|
+
require "ruby2_keywords"
|
|
4
5
|
|
|
5
6
|
module PgParty
|
|
6
7
|
module Adapter
|
|
7
8
|
module PostgreSQLMethods
|
|
8
|
-
def create_range_partition(*args, &blk)
|
|
9
|
+
ruby2_keywords def create_range_partition(*args, &blk)
|
|
9
10
|
PgParty::AdapterDecorator.new(self).create_range_partition(*args, &blk)
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def create_list_partition(*args, &blk)
|
|
13
|
+
ruby2_keywords def create_list_partition(*args, &blk)
|
|
13
14
|
PgParty::AdapterDecorator.new(self).create_list_partition(*args, &blk)
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
def create_range_partition_of(*args)
|
|
17
|
+
ruby2_keywords def create_range_partition_of(*args)
|
|
17
18
|
PgParty::AdapterDecorator.new(self).create_range_partition_of(*args)
|
|
18
19
|
end
|
|
19
20
|
|
|
20
|
-
def create_list_partition_of(*args)
|
|
21
|
+
ruby2_keywords def create_list_partition_of(*args)
|
|
21
22
|
PgParty::AdapterDecorator.new(self).create_list_partition_of(*args)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
def create_table_like(*args)
|
|
25
|
+
ruby2_keywords def create_table_like(*args)
|
|
25
26
|
PgParty::AdapterDecorator.new(self).create_table_like(*args)
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
def attach_range_partition(*args)
|
|
29
|
+
ruby2_keywords def attach_range_partition(*args)
|
|
29
30
|
PgParty::AdapterDecorator.new(self).attach_range_partition(*args)
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
def attach_list_partition(*args)
|
|
33
|
+
ruby2_keywords def attach_list_partition(*args)
|
|
33
34
|
PgParty::AdapterDecorator.new(self).attach_list_partition(*args)
|
|
34
35
|
end
|
|
35
36
|
|
|
36
|
-
def detach_partition(*args)
|
|
37
|
+
ruby2_keywords def detach_partition(*args)
|
|
37
38
|
PgParty::AdapterDecorator.new(self).detach_partition(*args)
|
|
38
39
|
end
|
|
39
40
|
end
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "pg_party/model_decorator"
|
|
4
|
+
require "ruby2_keywords"
|
|
4
5
|
|
|
5
6
|
module PgParty
|
|
6
7
|
module Model
|
|
7
8
|
module ListMethods
|
|
8
|
-
def create_partition(*args)
|
|
9
|
+
ruby2_keywords def create_partition(*args)
|
|
9
10
|
PgParty::ModelDecorator.new(self).create_list_partition(*args)
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def partition_key_in(*args)
|
|
13
|
+
ruby2_keywords def partition_key_in(*args)
|
|
13
14
|
PgParty::ModelDecorator.new(self).list_partition_key_in(*args)
|
|
14
15
|
end
|
|
15
16
|
end
|
|
@@ -5,12 +5,12 @@ require "pg_party/model_injector"
|
|
|
5
5
|
module PgParty
|
|
6
6
|
module Model
|
|
7
7
|
module Methods
|
|
8
|
-
def range_partition_by(key
|
|
9
|
-
PgParty::ModelInjector.new(self, key
|
|
8
|
+
def range_partition_by(*key, &blk)
|
|
9
|
+
PgParty::ModelInjector.new(self, *key, &blk).inject_range_methods
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def list_partition_by(key
|
|
13
|
-
PgParty::ModelInjector.new(self, key
|
|
12
|
+
def list_partition_by(*key, &blk)
|
|
13
|
+
PgParty::ModelInjector.new(self, *key, &blk).inject_list_methods
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def partitioned?
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "pg_party/model_decorator"
|
|
4
|
+
require "ruby2_keywords"
|
|
4
5
|
|
|
5
6
|
module PgParty
|
|
6
7
|
module Model
|
|
7
8
|
module RangeMethods
|
|
8
|
-
def create_partition(*args)
|
|
9
|
+
ruby2_keywords def create_partition(*args)
|
|
9
10
|
PgParty::ModelDecorator.new(self).create_range_partition(*args)
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def partition_key_in(*args)
|
|
13
|
+
ruby2_keywords def partition_key_in(*args)
|
|
13
14
|
PgParty::ModelDecorator.new(self).range_partition_key_in(*args)
|
|
14
15
|
end
|
|
15
16
|
end
|
|
@@ -36,7 +36,7 @@ module PgParty
|
|
|
36
36
|
if complex_partition_key
|
|
37
37
|
complex_partition_key_query("(#{partition_key}) = (?)", value)
|
|
38
38
|
else
|
|
39
|
-
|
|
39
|
+
where_partition_key(:eq, value)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
|
|
@@ -48,9 +48,9 @@ module PgParty
|
|
|
48
48
|
end_range
|
|
49
49
|
)
|
|
50
50
|
else
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
where_partition_key(:gteq, start_range).merge(
|
|
52
|
+
where_partition_key(:lt, end_range)
|
|
53
|
+
)
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -132,5 +132,26 @@ module PgParty
|
|
|
132
132
|
|
|
133
133
|
from(subquery, current_alias)
|
|
134
134
|
end
|
|
135
|
+
|
|
136
|
+
def where_partition_key(meth, values)
|
|
137
|
+
partition_key_array = Array.wrap(partition_key)
|
|
138
|
+
values = Array.wrap(values)
|
|
139
|
+
|
|
140
|
+
if partition_key_array.size != values.size
|
|
141
|
+
raise "number of provided values does not match the number of partition key columns"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
arel_query = partition_key_array.zip(values).inject(nil) do |obj, (column, value)|
|
|
145
|
+
node = current_arel_table[column].send(meth, value)
|
|
146
|
+
|
|
147
|
+
if obj.nil?
|
|
148
|
+
node
|
|
149
|
+
else
|
|
150
|
+
obj.and(node)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
where(arel_query)
|
|
155
|
+
end
|
|
135
156
|
end
|
|
136
157
|
end
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module PgParty
|
|
4
4
|
class ModelInjector
|
|
5
|
-
def initialize(model, key)
|
|
5
|
+
def initialize(model, *key, &blk)
|
|
6
6
|
@model = model
|
|
7
|
-
@key = key
|
|
7
|
+
@key = key.flatten.compact
|
|
8
|
+
@key_blk = blk
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
def inject_range_methods
|
|
@@ -38,11 +39,16 @@ module PgParty
|
|
|
38
39
|
instance_predicate: false
|
|
39
40
|
)
|
|
40
41
|
|
|
41
|
-
if @
|
|
42
|
-
@model.partition_key = @
|
|
42
|
+
if @key_blk
|
|
43
|
+
@model.partition_key = @key_blk.call
|
|
43
44
|
@model.complex_partition_key = true
|
|
44
45
|
else
|
|
45
|
-
@
|
|
46
|
+
if @key.size == 1
|
|
47
|
+
@model.partition_key = @key.first
|
|
48
|
+
else
|
|
49
|
+
@model.partition_key = @key
|
|
50
|
+
end
|
|
51
|
+
|
|
46
52
|
@model.complex_partition_key = false
|
|
47
53
|
end
|
|
48
54
|
end
|
data/lib/pg_party/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pg_party
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Krage
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-06-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -16,7 +16,7 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '5.0'
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
22
|
version: '6.1'
|
|
@@ -26,10 +26,24 @@ dependencies:
|
|
|
26
26
|
requirements:
|
|
27
27
|
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '
|
|
29
|
+
version: '5.0'
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: '6.1'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: ruby2_keywords
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.0.2
|
|
40
|
+
type: :runtime
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 0.0.2
|
|
33
47
|
- !ruby/object:Gem::Dependency
|
|
34
48
|
name: appraisal
|
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -182,14 +196,14 @@ dependencies:
|
|
|
182
196
|
requirements:
|
|
183
197
|
- - "~>"
|
|
184
198
|
- !ruby/object:Gem::Version
|
|
185
|
-
version:
|
|
199
|
+
version: 0.17.0
|
|
186
200
|
type: :development
|
|
187
201
|
prerelease: false
|
|
188
202
|
version_requirements: !ruby/object:Gem::Requirement
|
|
189
203
|
requirements:
|
|
190
204
|
- - "~>"
|
|
191
205
|
- !ruby/object:Gem::Version
|
|
192
|
-
version:
|
|
206
|
+
version: 0.17.0
|
|
193
207
|
- !ruby/object:Gem::Dependency
|
|
194
208
|
name: timecop
|
|
195
209
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -221,7 +235,6 @@ files:
|
|
|
221
235
|
- lib/pg_party/cache.rb
|
|
222
236
|
- lib/pg_party/config.rb
|
|
223
237
|
- lib/pg_party/hacks/postgresql_database_tasks.rb
|
|
224
|
-
- lib/pg_party/hacks/schema_cache.rb
|
|
225
238
|
- lib/pg_party/model/list_methods.rb
|
|
226
239
|
- lib/pg_party/model/methods.rb
|
|
227
240
|
- lib/pg_party/model/range_methods.rb
|
|
@@ -241,14 +254,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
241
254
|
requirements:
|
|
242
255
|
- - ">="
|
|
243
256
|
- !ruby/object:Gem::Version
|
|
244
|
-
version: 2.
|
|
257
|
+
version: 2.5.0
|
|
245
258
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
246
259
|
requirements:
|
|
247
260
|
- - ">="
|
|
248
261
|
- !ruby/object:Gem::Version
|
|
249
262
|
version: '0'
|
|
250
263
|
requirements: []
|
|
251
|
-
rubygems_version: 3.
|
|
264
|
+
rubygems_version: 3.1.4
|
|
252
265
|
signing_key:
|
|
253
266
|
specification_version: 4
|
|
254
267
|
summary: ActiveRecord PostgreSQL Partitioning
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module PgParty
|
|
4
|
-
module Hacks
|
|
5
|
-
module SchemaCache
|
|
6
|
-
def self.included(base)
|
|
7
|
-
return if base.method_defined?(:data_source_exists?)
|
|
8
|
-
|
|
9
|
-
base.send(:alias_method, :data_source_exists?, :table_exists?)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|