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: be864b7e40e4e6c504bf98b195a564bde6d076b4
4
- data.tar.gz: b79141c1dc5742385d9426f7a6fcf176844642ec
3
+ metadata.gz: 20a1c3b1bd4fce9f01962835c9820b238eb9fc44
4
+ data.tar.gz: 50f5192660e3f3abacf17cf8688f723b66a7d507
5
5
  SHA512:
6
- metadata.gz: b0a74962101fbff55ae9edc9a8203088fca7aaa078b3bbac3594a03d3d3c8bb122f545cb984c5ad5a897ffbe80c557d530180cd2b0a0af5e353ba0bb469adcdc
7
- data.tar.gz: 06c0780a190219771c06f27091774395eb682e126bf458dcb4cc1091a41b6ece5e3d104ed343684eae41e50259c6e7fc167e7ee40b9833b0460d16e036f7d2bb
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
- relation = self.class.unscoped.where(
32
- self.class.arel_table[pk].eq(substitute))
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
- attributes_with_values = arel_attributes_with_values_for_update(attribute_names)
71
- if attributes_with_values.empty?
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
- klass = self.class
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, selects)
119
- if !selects.empty?
120
- expanded_select = selects.map do |field|
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
- @using_configurators << UsingConfigurator.new(using_class, ancestor, ancestor::configurator_dsl) if ancestor::configurator_dsl
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
@@ -1,4 +1,4 @@
1
1
  module Partitioned
2
2
  # the current version of this gem
3
- VERSION = "2.0.0"
3
+ VERSION = "2.1.0"
4
4
  end
@@ -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-01'
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.0.4'
26
- s.add_development_dependency 'rails', '~> 4.0.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
- expect(subject.find(1).name).to eq("Kevin")
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.0.0
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-01 00:00:00.000000000 Z
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.0.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.0.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.0.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.0.4
98
+ version: 4.1.13
99
99
  - !ruby/object:Gem::Dependency
100
100
  name: rspec-rails
101
101
  requirement: !ruby/object:Gem::Requirement