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 +4 -4
- data/.rubocop.yml +5 -3
- data/.travis.yml +5 -5
- data/CHANGELOG.md +8 -0
- data/README.md +54 -16
- data/atomically.gemspec +3 -3
- data/lib/atomically/query_service.rb +13 -0
- data/lib/atomically/version.rb +1 -1
- metadata +16 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4cd43d76a8ee02e70abdfe675dd3bf47047749d076f392ae117ceb28d52c270
|
4
|
+
data.tar.gz: 503c635e9e29701623b2a46615ac19b3da0b61e601f604e14f5ba9e498e5ebff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cecca409c00e5495b0d406795cb414a4a9eb57babf630c7dadd918119f92a3ea45cec32b916b224a4b48da4b1a92bb6464bf8782db39c24608c142451ef9506
|
7
|
+
data.tar.gz: 3b109442240656564ee4b10a699e180613c76ce9d6006e8667f57c42f811ab4c9e918601bd59bad80c042ef1830a8bb8cdede0db66bf1fe96f02166b64574249
|
data/.rubocop.yml
CHANGED
@@ -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
|
-
|
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:
|
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:
|
908
|
+
AllowInnerSlashes: false
|
907
909
|
Enabled: true
|
908
910
|
|
909
911
|
Layout/RescueEnsureAlignment:
|
data/.travis.yml
CHANGED
@@ -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
|
-
|
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
|
data/CHANGELOG.md
CHANGED
@@ -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
|
-
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
###
|
229
|
+
### decrement_unsigned_counters _(counters)_
|
199
230
|
|
200
|
-
|
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
|
-
- `
|
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
|
-
|
211
|
-
# =>
|
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
|
-
|
218
|
-
|
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
|
data/atomically.gemspec
CHANGED
@@ -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', '
|
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)}"
|
data/lib/atomically/version.rb
CHANGED
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
|
+
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:
|
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:
|
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:
|
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: []
|