junk_drawer 1.4.0 → 1.6.3

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
- SHA1:
3
- metadata.gz: 238eb68d411dc0c6089296530a43a2465975d417
4
- data.tar.gz: 655fec097bfbdf9aa9ad42d1b3ebb95b96f5e6de
2
+ SHA256:
3
+ metadata.gz: c19a96b9707d53151fb3edf626ce443ad60cb4503ac75b108bd46eb6d7694f54
4
+ data.tar.gz: a4e87efeacae9353c7784dbad2a47294292b088c39fb50f5ad387dec2a8dcaa9
5
5
  SHA512:
6
- metadata.gz: 97e29c483b957b9de82874825ec57a185f4b44ec4bfb00db45cdc7666fba99bc1466a0cbec786428efcbeec02843919373e1fd5177bfb4413b9e4b8b7fb5069b
7
- data.tar.gz: 361c72c75c5263153d8ca6b0bcdd1fcc0cc2a158710492ba30de723f4ef1bfdc866a9745d7ab712f78a47b7769a5a7bc4297ed068a67213a3bc3f7a792582331
6
+ metadata.gz: 19a935285fd80b81d4d7c432f1775196032f766bdc78df61967b504d433566be1a36e04992c6266466fc5c480ff69aaef4edf21705ef48e6d9fbd4d9cfa0fffa
7
+ data.tar.gz: 2ad821ea7cc213f62c55bd07e96394fe1ea3618684bc13dea806cf83bb94cae883dc8bc392dd988e6ee1f6d80dfdf8e91459fb1907a58666ebca919fe50daa75
@@ -20,7 +20,7 @@ Metrics/MethodLength:
20
20
  Metrics/BlockLength:
21
21
  Exclude:
22
22
  - junk_drawer.gemspec
23
- - spec/**/*_spec.rb
23
+ - spec/**/*
24
24
 
25
25
  RSpec/ExampleLength:
26
26
  Enabled: false
@@ -1,10 +1,14 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.3
4
+ - 2.3
5
+ - 2.4
6
+ - 2.5
7
+ - 2.6
8
+ - 2.7
5
9
  addons:
6
10
  postgresql: '9.4'
7
- before_install: gem install bundler -v 1.13.6
11
+ before_install: gem install bundler -v 2.0.2
8
12
  before_script:
9
13
  - createdb junk_drawer_test -U postgres
10
14
  script:
data/Gemfile CHANGED
@@ -6,3 +6,5 @@ gemspec
6
6
 
7
7
  gem 'activerecord', '~> 5.1.0'
8
8
  gem 'activesupport', '~> 5.1.0'
9
+ gem 'hstore_accessor', '~> 1.1.1'
10
+ gem 'jsonb_accessor', '~> 1.0.0'
data/README.md CHANGED
@@ -220,6 +220,13 @@ release a new version, update the version number in `version.rb`, and then run
220
220
  `bundle exec rake release`, which will create a git tag for the version, push
221
221
  git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
222
222
 
223
+ In order to run tests against different Rails versions, you can use
224
+ `BUNDLE_GEMFILE`:
225
+
226
+ ```sh
227
+ $ BUNDLE_GEMFILE=gemfiles/rails_4.2.gems rake spec
228
+ ```
229
+
223
230
  ## Contributing
224
231
 
225
232
  Bug reports and pull requests are welcome on GitHub at
@@ -6,3 +6,5 @@ gemspec path: '../'
6
6
 
7
7
  gem 'activerecord', '~> 4.2.0'
8
8
  gem 'activesupport', '~> 4.2.0'
9
+ gem 'hstore_accessor', '~> 1.1.1'
10
+ gem 'jsonb_accessor', '~> 0.3.3'
@@ -6,3 +6,5 @@ gemspec path: '../'
6
6
 
7
7
  gem 'activerecord', '~> 5.0.0'
8
8
  gem 'activesupport', '~> 5.0.0'
9
+ gem 'hstore_accessor', '~> 1.1.1'
10
+ gem 'jsonb_accessor', '~> 1.0.0'
@@ -21,12 +21,13 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.required_ruby_version = '>= 2.1'
23
23
 
24
- spec.add_development_dependency 'bundler', '~> 1.13'
24
+ spec.add_runtime_dependency 'ruby2_keywords', '~> 0.0.2'
25
25
  spec.add_development_dependency 'guard', '~> 2.14'
26
26
  spec.add_development_dependency 'guard-rspec', '~> 4.7'
27
27
  spec.add_development_dependency 'guard-rubocop', '~> 1.2'
28
28
  spec.add_development_dependency 'pg', '~> 0.20'
29
29
  spec.add_development_dependency 'pry', '~> 0.10'
30
+ spec.add_development_dependency 'pry-byebug', '~> 3.6.0'
30
31
  spec.add_development_dependency 'rake', '~> 12.0'
31
32
  spec.add_development_dependency 'rspec', '~> 3.0'
32
33
  spec.add_development_dependency 'rubocop', '~> 0.48.1'
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ruby2_keywords'
4
+
3
5
  module JunkDrawer
4
6
  # error to be thrown by Callable
5
7
  class CallableError < StandardError
@@ -19,8 +21,8 @@ module JunkDrawer
19
21
  # an instance. It also causes an error to be raised if a public instance
20
22
  # method is defined with a name other than `call`
21
23
  module ClassMethods
22
- def call(*args)
23
- new.(*args)
24
+ ruby2_keywords def call(*args, &block)
25
+ new.(*args, &block)
24
26
  end
25
27
 
26
28
  def to_proc
@@ -7,34 +7,45 @@ require 'active_record/connection_adapters/postgresql_adapter'
7
7
  module JunkDrawer
8
8
  # module to allow bulk updates for `ActiveRecord` models
9
9
  module BulkUpdatable
10
- ATTRIBUTE_TYPE_TO_POSTGRES_CAST = {
11
- datetime: '::timestamp',
12
- hstore: '::hstore',
13
- boolean: '::boolean',
14
- jsonb: '::jsonb',
15
- }.freeze
16
-
17
- POSTGRES_VALUE_CASTERS = {
18
- hstore: ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Hstore.new,
19
- jsonb: ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb.new,
20
- }.freeze
21
-
22
10
  def bulk_update(objects)
23
11
  objects = objects.select(&:changed?)
24
12
  return unless objects.any?
25
13
 
26
- changed_attributes = extract_changed_attributes(objects)
27
- query = build_query_for(objects, changed_attributes)
14
+ unique_objects = uniquify_and_merge(objects)
15
+ changed_attributes = extract_changed_attributes(unique_objects)
16
+ query = build_query_for(unique_objects, changed_attributes)
28
17
  connection.execute(query)
18
+ objects.each(&:clear_changes_information)
29
19
  end
30
20
 
31
21
  private
32
22
 
23
+ def uniquify_and_merge(objects)
24
+ grouped_objects = objects.group_by(&:id).values
25
+ grouped_objects.each do |group|
26
+ next if group.length == 1
27
+
28
+ attrs = group.each_with_object({}) do |object, changes|
29
+ object.changed.each do |changed_attribute|
30
+ changes[changed_attribute] = object[changed_attribute]
31
+ end
32
+ end
33
+ group.each { |object| object.attributes = attrs }
34
+ end
35
+ grouped_objects.map(&:first)
36
+ end
37
+
33
38
  def extract_changed_attributes(objects)
34
39
  now = Time.zone.now
35
40
  objects.each { |object| object.updated_at = now }
36
41
 
37
- objects.flat_map(&:changed).uniq
42
+ changed_attributes = objects.flat_map(&:changed).uniq
43
+ if ::ActiveRecord::VERSION::MAJOR >= 5
44
+ column_names & changed_attributes
45
+ else
46
+ # to remove virtual columns from jsonb_accessor 0.3.3
47
+ columns.select(&:sql_type).map(&:name) & changed_attributes
48
+ end
38
49
  end
39
50
 
40
51
  def build_query_for(objects, attributes)
@@ -47,38 +58,36 @@ module JunkDrawer
47
58
  "#{quoted_column_name} = tmp_table.#{quoted_column_name}"
48
59
  end.join(', ')
49
60
 
50
- <<-SQL
51
- UPDATE #{table_name}
52
- SET #{assignment_query}
53
- FROM (VALUES #{object_values}) AS tmp_table(id, #{attributes.join(', ')})
54
- WHERE #{table_name}.id = tmp_table.id
55
- SQL
61
+ "UPDATE #{table_name} " \
62
+ "SET #{assignment_query} " \
63
+ "FROM (VALUES #{object_values}) " \
64
+ "AS tmp_table(id, #{attributes.join(', ')}) " \
65
+ "WHERE #{table_name}.id = tmp_table.id"
56
66
  end
57
67
 
58
68
  def sanitized_values(object, attributes)
59
- postgres_types = attributes.map do |attribute|
60
- attribute_type = columns_hash[attribute.to_s].type
61
- "?#{ATTRIBUTE_TYPE_TO_POSTGRES_CAST[attribute_type]}"
62
- end
63
-
64
69
  postgres_values = attributes.map do |attribute|
65
70
  value = object[attribute]
66
- attribute_type = columns_hash[attribute.to_s].type
67
- caster = POSTGRES_VALUE_CASTERS[attribute_type]
68
71
 
69
- caster ? serialized_value(caster, value) : value
72
+ # AR internal `columns_hash`
73
+ column = columns_hash[attribute.to_s]
74
+
75
+ # AR internal `type_for_attribute`
76
+ type = type_for_attribute(column.name)
77
+ type_cast = "::#{column.sql_type}"
78
+ type_cast = "#{type_cast}[]" if column.array
79
+
80
+ "#{connection.quote(serialized_value(type, value))}#{type_cast}"
70
81
  end
71
82
 
72
- sanitize_sql_array(
73
- ["(?, #{postgres_types.join(', ')})", object.id, *postgres_values],
74
- )
83
+ "(#{[object.id, *postgres_values].join(', ')})"
75
84
  end
76
85
 
77
- def serialized_value(caster, value)
86
+ def serialized_value(type, value)
78
87
  if ::ActiveRecord::VERSION::MAJOR >= 5
79
- caster.serialize(value)
88
+ type.serialize(value)
80
89
  else
81
- caster.type_cast_for_database(value)
90
+ type.type_cast_for_database(value)
82
91
  end
83
92
  end
84
93
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JunkDrawer
4
- VERSION = '1.4.0'
4
+ VERSION = '1.6.3'
5
5
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: junk_drawer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Fletcher
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-14 00:00:00.000000000 Z
11
+ date: 2020-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: ruby2_keywords
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.13'
20
- type: :development
19
+ version: 0.0.2
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.13'
26
+ version: 0.0.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: guard
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.10'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-byebug
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.6.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.6.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rake
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -229,8 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
229
243
  - !ruby/object:Gem::Version
230
244
  version: '0'
231
245
  requirements: []
232
- rubyforge_project:
233
- rubygems_version: 2.6.13
246
+ rubygems_version: 3.1.4
234
247
  signing_key:
235
248
  specification_version: 4
236
249
  summary: random useful Ruby utilities