junk_drawer 1.3.0 → 1.6.2

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: fa1bc248af13f000203f8c72364c382c44de203a
4
- data.tar.gz: 05ad7bf2b95cb6630eab0129811dcb68cd8e1e6b
2
+ SHA256:
3
+ metadata.gz: 4f24671eaa9add85408c8966382db1f81bd41c401bf08bc9fa367507d48a5024
4
+ data.tar.gz: 586334b2252f4e4b19d6338686b4c4b53435a6144f12cc5b642e85509bca8e2a
5
5
  SHA512:
6
- metadata.gz: 99d8ee5d88bc1bcd7d3253fc4dbac3be7be6418ede9a772bc4963233b0785344429ee40a2f8b2078e8d51e678aead1701eeba99ed4227ade2206b79e7af1912b
7
- data.tar.gz: 108ff56c6ed5bbe24e81edcfa099e0ae7a55cada04469a0e9900d76b4b3623b64f334f39eaa52ed048b18811bf7fd8e907b83e95f7169d9f745de2ee93f4673b
6
+ metadata.gz: 68798dd630e0f3508d5fcd30480c9f7eb04e3d12a1035bf4bdd39003d976e1a3eed76bd717fd8671985b4f33924dde6eeabaa37ab2d154d2b4aa42df13b8f7a0
7
+ data.tar.gz: 67bd7ba05df3c718c79c37dffffb3936894a541253b17d382809af1805c36cc330b465016f7ca7f1886a4496128817d8cd3621a4bf2c7a724c6fdad8aadc7a9d
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
3
  /Gemfile.lock
4
+ *gems.lock
4
5
  /_yardoc/
5
6
  /coverage/
6
7
  /doc/
@@ -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,13 +1,21 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.1
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:
11
15
  - bundle exec rubocop
12
16
  - bundle exec rake
13
17
  - bundle exec rake build
18
+ gemfile:
19
+ - Gemfile
20
+ - gemfiles/rails_5.0.gems
21
+ - gemfiles/rails_4.2.gems
data/Gemfile CHANGED
@@ -3,3 +3,8 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
+
7
+ gem 'activerecord', '~> 5.1.0'
8
+ gem 'activesupport', '~> 5.1.0'
9
+ gem 'hstore_accessor', '~> 1.1.1'
10
+ gem 'jsonb_accessor', '~> 1.0.0'
data/README.md CHANGED
@@ -211,7 +211,8 @@ database.
211
211
  ## Development
212
212
 
213
213
  After checking out the repo, run `bin/setup` to install dependencies. Then, run
214
- `rake spec` to run the tests. You can also run `bin/console` for an interactive
214
+ `rake spec` to run the tests, or `bin/test` to run tests for all supported
215
+ ActiveRecord versions. You can also run `bin/console` for an interactive
215
216
  prompt that will allow you to experiment.
216
217
 
217
218
  To install this gem onto your local machine, run `bundle exec rake install`. To
@@ -219,10 +220,17 @@ release a new version, update the version number in `version.rb`, and then run
219
220
  `bundle exec rake release`, which will create a git tag for the version, push
220
221
  git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
221
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
+
222
230
  ## Contributing
223
231
 
224
232
  Bug reports and pull requests are welcome on GitHub at
225
- https://github.com/mockdeep/junk_drawer. This project is intended to be a
233
+ https://github.com/thread-pond/junk_drawer. This project is intended to be a
226
234
  safe, welcoming space for collaboration, and contributors are expected to
227
235
  adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
228
236
 
data/bin/setup CHANGED
@@ -3,6 +3,9 @@ set -euo pipefail
3
3
  IFS=$'\n\t'
4
4
  set -vx
5
5
 
6
+ createuser -s -r postgres
7
+ createdb junk_drawer_test -U postgres
8
+
6
9
  bundle install
7
10
 
8
11
  # Do any other automated setup that you need to do here
@@ -0,0 +1,3 @@
1
+ (export BUNDLE_GEMFILE=Gemfile; bundle && bundle exec rake)
2
+ (export BUNDLE_GEMFILE=gemfiles/rails_5.0.gems; bundle && bundle exec rake spec)
3
+ (export BUNDLE_GEMFILE=gemfiles/rails_4.2.gems; bundle && bundle exec rake spec)
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec path: '../'
6
+
7
+ gem 'activerecord', '~> 4.2.0'
8
+ gem 'activesupport', '~> 4.2.0'
9
+ gem 'hstore_accessor', '~> 1.1.1'
10
+ gem 'jsonb_accessor', '~> 0.3.3'
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec path: '../'
6
+
7
+ gem 'activerecord', '~> 5.0.0'
8
+ gem 'activesupport', '~> 5.0.0'
9
+ gem 'hstore_accessor', '~> 1.1.1'
10
+ gem 'jsonb_accessor', '~> 1.0.0'
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ['lobatifricha@gmail.com']
10
10
 
11
11
  spec.summary = 'random useful Ruby utilities'
12
- spec.homepage = 'https://github.com/mockdeep/junk_drawer'
12
+ spec.homepage = 'https://github.com/thread-pond/junk_drawer'
13
13
  spec.license = 'MIT'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
@@ -21,14 +21,12 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.required_ruby_version = '>= 2.1'
23
23
 
24
- spec.add_development_dependency 'activerecord', '~> 4.2'
25
- spec.add_development_dependency 'activesupport', '~> 4.2'
26
- spec.add_development_dependency 'bundler', '~> 1.13'
27
24
  spec.add_development_dependency 'guard', '~> 2.14'
28
25
  spec.add_development_dependency 'guard-rspec', '~> 4.7'
29
26
  spec.add_development_dependency 'guard-rubocop', '~> 1.2'
30
27
  spec.add_development_dependency 'pg', '~> 0.20'
31
28
  spec.add_development_dependency 'pry', '~> 0.10'
29
+ spec.add_development_dependency 'pry-byebug', '~> 3.6.0'
32
30
  spec.add_development_dependency 'rake', '~> 12.0'
33
31
  spec.add_development_dependency 'rspec', '~> 3.0'
34
32
  spec.add_development_dependency 'rubocop', '~> 0.48.1'
@@ -19,8 +19,8 @@ module JunkDrawer
19
19
  # an instance. It also causes an error to be raised if a public instance
20
20
  # method is defined with a name other than `call`
21
21
  module ClassMethods
22
- def call(*args)
23
- new.(*args)
22
+ def call(*args, **kwargs, &block)
23
+ new.(*args, **kwargs, &block)
24
24
  end
25
25
 
26
26
  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,31 +58,37 @@ 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 ? caster.type_cast_for_database(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(', ')})"
84
+ end
85
+
86
+ def serialized_value(type, value)
87
+ if ::ActiveRecord::VERSION::MAJOR >= 5
88
+ type.serialize(value)
89
+ else
90
+ type.type_cast_for_database(value)
91
+ end
75
92
  end
76
93
  end
77
94
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JunkDrawer
4
- VERSION = '1.3.0'
4
+ VERSION = '1.6.2'
5
5
  end
metadata CHANGED
@@ -1,57 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: junk_drawer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.6.2
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-07-21 00:00:00.000000000 Z
11
+ date: 2020-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activerecord
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '4.2'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '4.2'
27
- - !ruby/object:Gem::Dependency
28
- name: activesupport
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '4.2'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '4.2'
41
- - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.13'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.13'
55
13
  - !ruby/object:Gem::Dependency
56
14
  name: guard
57
15
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +80,20 @@ dependencies:
122
80
  - - "~>"
123
81
  - !ruby/object:Gem::Version
124
82
  version: '0.10'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 3.6.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 3.6.0
125
97
  - !ruby/object:Gem::Dependency
126
98
  name: rake
127
99
  requirement: !ruby/object:Gem::Requirement
@@ -225,6 +197,9 @@ files:
225
197
  - Rakefile
226
198
  - bin/console
227
199
  - bin/setup
200
+ - bin/test
201
+ - gemfiles/rails_4.2.gems
202
+ - gemfiles/rails_5.0.gems
228
203
  - junk_drawer.gemspec
229
204
  - lib/junk_drawer.rb
230
205
  - lib/junk_drawer/callable.rb
@@ -235,7 +210,7 @@ files:
235
210
  - lib/junk_drawer/rails.rb
236
211
  - lib/junk_drawer/rails/bulk_updatable.rb
237
212
  - lib/junk_drawer/version.rb
238
- homepage: https://github.com/mockdeep/junk_drawer
213
+ homepage: https://github.com/thread-pond/junk_drawer
239
214
  licenses:
240
215
  - MIT
241
216
  metadata: {}
@@ -254,8 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
229
  - !ruby/object:Gem::Version
255
230
  version: '0'
256
231
  requirements: []
257
- rubyforge_project:
258
- rubygems_version: 2.6.11
232
+ rubygems_version: 3.1.4
259
233
  signing_key:
260
234
  specification_version: 4
261
235
  summary: random useful Ruby utilities