atomically 1.0.4 → 1.0.5

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
  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: []