atomically 1.0.4 → 1.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec69d82cbee452fb2b61bd973aa1a885e5cffd5cdd8c5b5e6bb96ea066c8f7b1
4
- data.tar.gz: be3720c0644d7c8228ea3b8ae88fd05c1850c66f629819977cc4758b8ec0d3d9
3
+ metadata.gz: b4cd43d76a8ee02e70abdfe675dd3bf47047749d076f392ae117ceb28d52c270
4
+ data.tar.gz: 503c635e9e29701623b2a46615ac19b3da0b61e601f604e14f5ba9e498e5ebff
5
5
  SHA512:
6
- metadata.gz: 1b88cc95978a5c3cf4913d812e99e32aa4ef6b2bee12572e7e9eccea51edeadae8c78cdd42ad2f436ea9f3749832c1cacec0dd380a64900b0caa1936446b9a7a
7
- data.tar.gz: ea519708c2c2d24b7876f810095adf0a9b599d713b3e7cb4091981d567886ce9c28644d42bca688790ada4d0e9e5b153bc3f9c6149fc060818768ec12493d437
6
+ metadata.gz: 8cecca409c00e5495b0d406795cb414a4a9eb57babf630c7dadd918119f92a3ea45cec32b916b224a4b48da4b1a92bb6464bf8782db39c24608c142451ef9506
7
+ data.tar.gz: 3b109442240656564ee4b10a699e180613c76ce9d6006e8667f57c42f811ab4c9e918601bd59bad80c042ef1830a8bb8cdede0db66bf1fe96f02166b64574249
@@ -386,6 +386,7 @@ Layout/AlignHash:
386
386
  Description: >-
387
387
  Align the elements of a hash literal if they span more than
388
388
  one line.
389
+ EnforcedHashRocketStyle: table
389
390
  Enabled: true
390
391
 
391
392
  Layout/AlignParameters:
@@ -787,7 +788,8 @@ Style/Next:
787
788
  Style/NilComparison:
788
789
  Description: 'Prefer x.nil? to x == nil.'
789
790
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods'
790
- Enabled: false
791
+ EnforcedStyle: comparison
792
+ Enabled: true
791
793
 
792
794
  Style/NonNilCheck:
793
795
  # With `IncludeSemanticChanges` set to `true`, this cop reports offenses for
@@ -799,7 +801,7 @@ Style/NonNilCheck:
799
801
  Description: 'Checks for redundant nil checks.'
800
802
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-non-nil-checks'
801
803
  IncludeSemanticChanges: true
802
- Enabled: true
804
+ Enabled: false
803
805
 
804
806
  Style/Not:
805
807
  Description: 'Use ! instead of not.'
@@ -903,7 +905,7 @@ Style/RegexpLiteral:
903
905
  Description: 'Use / or %r around regular expressions.'
904
906
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-r'
905
907
  EnforcedStyle: slashes
906
- AllowInnerSlashes: true
908
+ AllowInnerSlashes: false
907
909
  Enabled: true
908
910
 
909
911
  Layout/RescueEnsureAlignment:
@@ -1,13 +1,13 @@
1
1
  sudo: false
2
- env:
3
- global:
4
- - CC_TEST_REPORTER_ID=12e1facab2e8910c9b9d6b9e6870c5544a5c44a1bef25cc6638fd132aa4af6b4
5
2
  language: ruby
6
3
  rvm:
7
4
  - 2.2
8
5
  - 2.5
9
6
  env:
10
- - DB=mysql
7
+ global:
8
+ - CC_TEST_REPORTER_ID=12e1facab2e8910c9b9d6b9e6870c5544a5c44a1bef25cc6638fd132aa4af6b4
9
+ matrix:
10
+ - DB=mysql
11
11
  gemfile:
12
12
  - gemfiles/3.2.gemfile
13
13
  - gemfiles/4.2.gemfile
@@ -20,7 +20,7 @@ matrix:
20
20
  rvm: 2.5
21
21
  before_install:
22
22
  - gem i rubygems-update -v '<3' && update_rubygems
23
- - gem install bundler
23
+ - gem install bundler -v 1.17.3
24
24
  - gem --version
25
25
  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
26
26
  - chmod +x ./cc-test-reporter
@@ -1,5 +1,13 @@
1
1
  ## Change Log
2
2
 
3
+ ### [v1.0.4](https://github.com/khiav223577/atomically/compare/v1.0.3...v1.0.4) 2018/12/21
4
+ - [#7](https://github.com/khiav223577/atomically/pull/7) Implement `update_all_and_get_ids` (@khiav223577)
5
+ - [#6](https://github.com/khiav223577/atomically/pull/6) Add warning (@kakas)
6
+ - [#5](https://github.com/khiav223577/atomically/pull/5) fix README `pay_all` description (@kakas)
7
+
8
+ ### [v1.0.3](https://github.com/khiav223577/atomically/compare/v1.0.2...v1.0.3) 2018/11/28
9
+ - [#4](https://github.com/khiav223577/atomically/pull/4) Implement `update_all` (@khiav223577)
10
+
3
11
  ### [v1.0.2](https://github.com/khiav223577/atomically/compare/v1.0.1...v1.0.2) 2018/11/27
4
12
  - [#3](https://github.com/khiav223577/atomically/pull/3) Implement `update` (@khiav223577)
5
13
 
data/README.md CHANGED
@@ -14,11 +14,14 @@ Supports Rails 3.2, 4.2, 5.0, 5.1, 5.2.
14
14
 
15
15
  1. [Installation](#installation)
16
16
  2. [Methods](#methods)
17
- - [create_or_plus](#create_or_plus-columns-values-on_duplicate_update_columns)
18
- - [pay_all](#pay_all-hash-update_columns-primary_key-id)
19
- - [update_all](#update_all-expected_number-updates)
20
- - [update](#update-attrs-from-not_set)
21
- - [update_all_and_get_ids](#update_all_and_get_ids-updates)
17
+ - Relation Methods
18
+ - [create_or_plus](#create_or_plus-columns-values-on_duplicate_update_columns)
19
+ - [pay_all](#pay_all-hash-update_columns-primary_key-id)
20
+ - [update_all](#update_all-expected_number-updates)
21
+ - [update_all_and_get_ids](#update_all_and_get_ids-updates)
22
+ - Model Methods
23
+ - [update](#update-attrs-from-not_set)
24
+ - [decrement_unsigned_counters](#decrement_unsigned_counters-counters)
22
25
  3. [Development](#development)
23
26
  4. [Contributing](#contributing)
24
27
  5. [License](#license)
@@ -158,6 +161,33 @@ UPDATE `users` SET `users`.`name` = '' WHERE `users`.`id` IN (1, 2, 3) AND (
158
161
  )
159
162
  ```
160
163
 
164
+ ---
165
+ ### update_all_and_get_ids _(updates)_
166
+
167
+ Behaves like [ActiveRecord::Relation#update_all](https://apidock.com/rails/ActiveRecord/Relation/update_all), but return the ids array of updated records instead of the number of updated records.
168
+
169
+
170
+ #### Parameters
171
+
172
+ - `updates` - A string, array, or hash representing the SET part of an SQL statement.
173
+
174
+ #### Example
175
+
176
+ ```rb
177
+ User.where(account: ['moon', 'wolf']).atomically.update_all_and_get_ids('money = money + 1')
178
+ # => [254, 371]
179
+ ```
180
+
181
+ #### SQL queries
182
+
183
+ ```sql
184
+ BEGIN
185
+ SET @ids := NULL
186
+ UPDATE `users` SET money = money + 1 WHERE `users`.`account` IN ('moon', 'wolf') AND ((SELECT @ids := CONCAT_WS(',', `users`.`id`, @ids)))
187
+ SELECT @ids FROM DUAL
188
+ COMMIT
189
+ ```
190
+
161
191
  ---
162
192
  ### update _(attrs, from: :not_set)_
163
193
 
@@ -166,7 +196,7 @@ Updates the attributes of the model from the passed-in hash and saves the record
166
196
  #### Parameters
167
197
 
168
198
  - `attrs` - Same with the first parameter of [ActiveRecord#update](https://apidock.com/rails/ActiveRecord/Persistence/update)
169
- - `from` - The value before update. If not set, use the attriutes of the model.
199
+ - `from` - The value before update. If not set, use the current attriutes of the model.
170
200
 
171
201
  #### Example
172
202
 
@@ -186,6 +216,7 @@ end
186
216
 
187
217
  ```sql
188
218
  # arena.atomically_close!
219
+ # (let arena.closed_at to be nil)
189
220
  UPDATE `arenas` SET `arenas`.`closed_at` = '2018-11-27 03:44:25', `updated_at` = '2018-11-27 03:44:25'
190
221
  WHERE `arenas`.`id` = 1752 AND `arenas`.`closed_at` IS NULL
191
222
 
@@ -195,30 +226,37 @@ WHERE `arenas`.`id` = 1752
195
226
  ```
196
227
 
197
228
  ---
198
- ### update_all_and_get_ids _(updates)_
229
+ ### decrement_unsigned_counters _(counters)_
199
230
 
200
- Behaves like [ActiveRecord::Relation#update_all](https://apidock.com/rails/ActiveRecord/Relation/update_all), but return the ids array of updated records instead of the number of updated records.
231
+ Decrement numeric fields via a direct SQL update, and make sure that it will not become negative.
201
232
 
202
233
 
203
234
  #### Parameters
204
235
 
205
- - `updates` - A string, array, or hash representing the SET part of an SQL statement.
236
+ - `counters` - A Hash containing the names of the fields to update as keys and the amount to update the field by as values.
206
237
 
207
238
  #### Example
208
239
 
209
240
  ```rb
210
- User.where(account: ['moon', 'wolf']).atomically.update_all_and_get_ids('money = money + 1')
211
- # => [254, 371]
241
+ user.money
242
+ # => 100
243
+
244
+ user.atomically.decrement_unsigned_counters(money: 10)
245
+ # => true
246
+ user.reload.money
247
+ # => 90
248
+
249
+ user.atomically.decrement_unsigned_counters(money: 999)
250
+ # => false
251
+ user.reload.money
252
+ # => 90
212
253
  ```
213
254
 
214
255
  #### SQL queries
215
256
 
216
257
  ```sql
217
- BEGIN
218
- SET @ids := NULL
219
- UPDATE `users` SET money = money + 1 WHERE `users`.`account` IN ('moon', 'wolf') AND ((SELECT @ids := CONCAT_WS(',', `users`.`id`, @ids)))
220
- SELECT @ids FROM DUAL
221
- COMMIT
258
+ # user.atomically.decrement_unsigned_counters(money: 140)
259
+ UPDATE `users` SET money = money - 140 WHERE `users`.`id` = 1 AND (money > 140)
222
260
  ```
223
261
 
224
262
  ## Development
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['khiav reoy']
10
10
  spec.email = ['mrtmrt15xn@yahoo.com.tw']
11
11
 
12
- spec.summary = ''
13
- spec.description = ''
12
+ spec.summary = 'Adds commonly useful atomic SQL statements to ActiveRecord to avoid race condition.'
13
+ spec.description = 'Adds commonly useful atomic SQL statements to ActiveRecord to avoid race condition.'
14
14
  spec.homepage = 'https://github.com/khiav223577/atomically'
15
15
  spec.license = 'MIT'
16
16
 
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}){|f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
- spec.add_development_dependency 'bundler', '~> 1.11'
30
+ spec.add_development_dependency 'bundler', '>= 1.17', '< 3.x'
31
31
  spec.add_development_dependency 'rake', '~> 12.0'
32
32
  spec.add_development_dependency 'sqlite3', '~> 1.3'
33
33
  spec.add_development_dependency 'minitest', '~> 5.0'
@@ -48,6 +48,19 @@ class Atomically::QueryService
48
48
  return success
49
49
  end
50
50
 
51
+ # ==== Parameters
52
+ #
53
+ # * +counters+ - A Hash containing the names of the fields
54
+ # to update as keys and the amount to update the field by as values.
55
+ def decrement_unsigned_counters(counters)
56
+ result = open_update_all_scope do
57
+ counters.each do |field, amount|
58
+ where("#{field} > ?", amount).update("#{field} = #{field} - ?", amount) if amount > 0
59
+ end
60
+ end
61
+ return (result == 1)
62
+ end
63
+
51
64
  def update_all_and_get_ids(*args)
52
65
  ids = nil
53
66
  id_column = "#{@klass.quoted_table_name}.#{quote_column(:id)}"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Atomically
4
- VERSION = '1.0.4'
4
+ VERSION = '1.0.5'
5
5
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atomically
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - khiav reoy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-21 00:00:00.000000000 Z
11
+ date: 2019-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '1.11'
22
+ version: 3.x
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.17'
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '1.11'
32
+ version: 3.x
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -150,7 +156,8 @@ dependencies:
150
156
  - - ">="
151
157
  - !ruby/object:Gem::Version
152
158
  version: 1.1.8
153
- description: ''
159
+ description: Adds commonly useful atomic SQL statements to ActiveRecord to avoid race
160
+ condition.
154
161
  email:
155
162
  - mrtmrt15xn@yahoo.com.tw
156
163
  executables: []
@@ -206,5 +213,6 @@ rubyforge_project:
206
213
  rubygems_version: 2.7.6
207
214
  signing_key:
208
215
  specification_version: 4
209
- summary: ''
216
+ summary: Adds commonly useful atomic SQL statements to ActiveRecord to avoid race
217
+ condition.
210
218
  test_files: []