partitioned 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20a1c3b1bd4fce9f01962835c9820b238eb9fc44
|
4
|
+
data.tar.gz: 50f5192660e3f3abacf17cf8688f723b66a7d507
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cdc1610b1a093a31146412e73438c315ff85081a8680f1143c9fa39e19ff8a7c35a67752f35b0fe924daef87b705a729c8246f88c1137e77dd4157d6092586d
|
7
|
+
data.tar.gz: 58f04692b45d14116d77da96b2144478ad8466cd29d0dfb88ee6107377dd215d3b2154020a9b828c951b82b26a143982e7948aa34d034d929ab4f7cfb7b930e9
|
@@ -28,8 +28,9 @@ module ActiveRecord
|
|
28
28
|
where(using_arel_table[pk].eq(substitute))
|
29
29
|
else
|
30
30
|
# ****** END PARTITIONED PATCH ******
|
31
|
-
|
32
|
-
|
31
|
+
|
32
|
+
relation = self.class.unscoped.where(self.class.arel_table[pk].eq(substitute))
|
33
|
+
|
33
34
|
# ****** BEGIN PARTITIONED PATCH ******
|
34
35
|
end
|
35
36
|
# ****** END PARTITIONED PATCH ******
|
@@ -64,48 +65,22 @@ module ActiveRecord
|
|
64
65
|
|
65
66
|
# Updates the associated record with values matching those of the instance attributes.
|
66
67
|
# Returns the number of affected rows.
|
67
|
-
# NOTE(hofer): This monkeypatch intended for activerecord 4.0. Based on this code:
|
68
|
-
# https://github.com/rails/rails/blob/4-0-stable/activerecord/lib/active_record/persistence.rb#L487
|
69
68
|
def _update_record(attribute_names = @attributes.keys)
|
70
|
-
|
71
|
-
|
69
|
+
# ****** BEGIN PARTITIONED PATCH ******
|
70
|
+
# NOTE(hofer): This patch ensures the columns the table is
|
71
|
+
# partitioned on are passed along to the update code so that the
|
72
|
+
# update statement runs against a child partition, not the
|
73
|
+
# parent table, to help with performance.
|
74
|
+
if self.class.respond_to?(:partition_keys)
|
75
|
+
attribute_names.concat self.class.partition_keys.map(&:to_s)
|
76
|
+
attribute_names.uniq!
|
77
|
+
end
|
78
|
+
# ****** END PARTITIONED PATCH ******
|
79
|
+
attributes_values = arel_attributes_with_values_for_update(attribute_names)
|
80
|
+
if attributes_values.empty?
|
72
81
|
0
|
73
82
|
else
|
74
|
-
|
75
|
-
column_hash = klass.connection.schema_cache.columns_hash klass.table_name
|
76
|
-
db_columns_with_values = attributes_with_values.map { |attr,value|
|
77
|
-
real_column = column_hash[attr.name]
|
78
|
-
[real_column, value]
|
79
|
-
}
|
80
|
-
bind_attrs = attributes_with_values.dup
|
81
|
-
bind_attrs.keys.each_with_index do |column, i|
|
82
|
-
real_column = db_columns_with_values[i].first
|
83
|
-
bind_attrs[column] = klass.connection.substitute_at(real_column, i)
|
84
|
-
end
|
85
|
-
|
86
|
-
# ****** BEGIN PARTITIONED PATCH ******
|
87
|
-
if self.respond_to?(:dynamic_arel_table)
|
88
|
-
using_arel_table = dynamic_arel_table()
|
89
|
-
stmt = klass.unscoped.where(using_arel_table[klass.primary_key].eq(id_was || id)).arel.compile_update(bind_attrs)
|
90
|
-
|
91
|
-
# NOTE(hofer): The stmt variable got set up using
|
92
|
-
# klass.arel_table as its arel value. So arel_table.name is
|
93
|
-
# what gets used to construct the update statement. Here we
|
94
|
-
# set it to the specific partition name for this record so
|
95
|
-
# that the update gets run just on that partition, not on
|
96
|
-
# the parent one (which can cause performance issues).
|
97
|
-
begin
|
98
|
-
klass.arel_table.name = partition_table_name()
|
99
|
-
klass.connection.update stmt, 'SQL', db_columns_with_values
|
100
|
-
ensure
|
101
|
-
klass.arel_table.name = klass.table_name
|
102
|
-
end
|
103
|
-
else
|
104
|
-
# Original lines:
|
105
|
-
stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id_was || id)).arel.compile_update(bind_attrs)
|
106
|
-
klass.connection.update stmt, 'SQL', db_columns_with_values
|
107
|
-
end
|
108
|
-
# ****** END PARTITIONED PATCH ******
|
83
|
+
self.class.unscoped._update_record attributes_values, id, id_was
|
109
84
|
end
|
110
85
|
end
|
111
86
|
|
@@ -115,9 +90,9 @@ module ActiveRecord
|
|
115
90
|
|
116
91
|
# This method is patched to change the default behavior of select
|
117
92
|
# to use the Relation's Arel::Table
|
118
|
-
def build_select(arel
|
119
|
-
if !
|
120
|
-
expanded_select =
|
93
|
+
def build_select(arel)
|
94
|
+
if !select_values.empty?
|
95
|
+
expanded_select = select_values.map do |field|
|
121
96
|
columns_hash.key?(field.to_s) ? arel_table[field] : field
|
122
97
|
end
|
123
98
|
arel.project(*expanded_select)
|
@@ -186,5 +161,48 @@ module ActiveRecord
|
|
186
161
|
binds)
|
187
162
|
end
|
188
163
|
|
164
|
+
# NOTE(hofer): This monkeypatch intended for activerecord 4.1. Based on this code:
|
165
|
+
# https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/relation.rb#L73-L88
|
166
|
+
# TODO(hofer): Update this for rails 4.2, looks like the monkeypatched method changes a bit.
|
167
|
+
def _update_record(values, id, id_was) # :nodoc:
|
168
|
+
substitutes, binds = substitute_values values
|
169
|
+
|
170
|
+
scope = @klass.unscoped
|
171
|
+
|
172
|
+
if @klass.finder_needs_type_condition?
|
173
|
+
scope.unscope!(where: @klass.inheritance_column)
|
174
|
+
end
|
175
|
+
|
176
|
+
# ****** BEGIN PARTITIONED PATCH ******
|
177
|
+
if @klass.respond_to?(:dynamic_arel_table)
|
178
|
+
using_arel_table = @klass.dynamic_arel_table(Hash[*values.map { |k,v| [k.name,v] }.flatten])
|
179
|
+
um = scope.where(using_arel_table[@klass.primary_key].eq(id_was || id)).arel.compile_update(substitutes, @klass.primary_key)
|
180
|
+
|
181
|
+
# NOTE(hofer): The um variable got set up using
|
182
|
+
# klass.arel_table as its arel value. So arel_table.name is
|
183
|
+
# what gets used to construct the update statement. Here we
|
184
|
+
# set it to the specific partition name for this record so
|
185
|
+
# that the update gets run just on that partition, not on the
|
186
|
+
# parent one (which can cause performance issues).
|
187
|
+
begin
|
188
|
+
@klass.arel_table.name = using_arel_table.name
|
189
|
+
@klass.connection.update(
|
190
|
+
um,
|
191
|
+
'SQL',
|
192
|
+
binds)
|
193
|
+
ensure
|
194
|
+
@klass.arel_table.name = @klass.table_name
|
195
|
+
end
|
196
|
+
else
|
197
|
+
# Original lines:
|
198
|
+
um = scope.where(@klass.arel_table[@klass.primary_key].eq(id_was || id)).arel.compile_update(substitutes, @klass.primary_key)
|
199
|
+
|
200
|
+
@klass.connection.update(
|
201
|
+
um,
|
202
|
+
'SQL',
|
203
|
+
binds)
|
204
|
+
end
|
205
|
+
# ****** END PARTITIONED PATCH ******
|
206
|
+
end
|
189
207
|
end # class Relation
|
190
208
|
end # module ActiveRecord
|
@@ -5,10 +5,10 @@ module Partitioned
|
|
5
5
|
# {PartitionManager} to request partitioning information froma
|
6
6
|
# centralized source from multi level partitioned models
|
7
7
|
class Reader < Partitioned::PartitionedBase::Configurator::Reader
|
8
|
-
|
8
|
+
|
9
9
|
alias :base_collect_from_collection :collect_from_collection
|
10
10
|
alias :base_collect :collect
|
11
|
-
|
11
|
+
|
12
12
|
# configurator for a specific class level
|
13
13
|
UsingConfigurator = Struct.new(:model, :sliced_class, :dsl)
|
14
14
|
|
@@ -81,7 +81,7 @@ module Partitioned
|
|
81
81
|
bag
|
82
82
|
end
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
#
|
86
86
|
# Foreign keys to create on each leaf partition.
|
87
87
|
#
|
@@ -140,7 +140,11 @@ module Partitioned
|
|
140
140
|
using_classes.each do |using_class|
|
141
141
|
using_class.ancestors.each do |ancestor|
|
142
142
|
next if ancestor.class == Module
|
143
|
-
|
143
|
+
|
144
|
+
if ancestor.respond_to?(:configurator_dsl) && ancestor::configurator_dsl
|
145
|
+
@using_configurators << UsingConfigurator.new(using_class, ancestor, ancestor::configurator_dsl)
|
146
|
+
end
|
147
|
+
|
144
148
|
break if ancestor == Partitioned::PartitionedBase
|
145
149
|
end
|
146
150
|
end
|
data/lib/partitioned/version.rb
CHANGED
data/partitioned.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.name = 'partitioned'
|
8
8
|
s.version = Partitioned::VERSION
|
9
9
|
s.license = 'New BSD License'
|
10
|
-
s.date = '2015-10-
|
10
|
+
s.date = '2015-10-02'
|
11
11
|
s.summary = "Postgres table partitioning support for ActiveRecord."
|
12
12
|
s.description = "A gem providing support for table partitioning in ActiveRecord. Support is available for postgres and AWS RedShift databases. Other features include child table management (creation and deletion) and bulk data creating and updating."
|
13
13
|
s.authors = ["Keith Gabryelski", "Aleksandr Dembskiy", "Edward Slavich"]
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency 'pg'
|
23
23
|
s.add_dependency 'bulk_data_methods'
|
24
24
|
s.add_dependency 'activerecord-redshift-adapter'
|
25
|
-
s.add_dependency 'activerecord', '~> 4.
|
26
|
-
s.add_development_dependency 'rails', '~> 4.
|
25
|
+
s.add_dependency 'activerecord', '~> 4.1.13'
|
26
|
+
s.add_development_dependency 'rails', '~> 4.1.13'
|
27
27
|
s.add_development_dependency 'rspec-rails'
|
28
28
|
end
|
@@ -73,8 +73,12 @@ shared_examples_for "check that basic operations with postgres works correctly f
|
|
73
73
|
context "when try to update a record with id = 1" do
|
74
74
|
|
75
75
|
it "returns updated employee name" do
|
76
|
+
record = subject.find(1)
|
77
|
+
original_created_at = record.created_at
|
76
78
|
subject.update(1, :name => 'Kevin')
|
77
|
-
|
79
|
+
result = subject.find(1)
|
80
|
+
expect(result.name).to eq "Kevin"
|
81
|
+
expect(result.created_at).to eq original_created_at
|
78
82
|
end
|
79
83
|
|
80
84
|
end # when try to update a record with id = 1
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: partitioned
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keith Gabryelski
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-10-
|
13
|
+
date: 2015-10-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: jquery-rails
|
@@ -74,28 +74,28 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - "~>"
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 4.
|
77
|
+
version: 4.1.13
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
80
|
version_requirements: !ruby/object:Gem::Requirement
|
81
81
|
requirements:
|
82
82
|
- - "~>"
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: 4.
|
84
|
+
version: 4.1.13
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
name: rails
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
89
|
- - "~>"
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version: 4.
|
91
|
+
version: 4.1.13
|
92
92
|
type: :development
|
93
93
|
prerelease: false
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
96
|
- - "~>"
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: 4.
|
98
|
+
version: 4.1.13
|
99
99
|
- !ruby/object:Gem::Dependency
|
100
100
|
name: rspec-rails
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|