atomically 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +65 -9
- data/lib/atomically/query_service.rb +9 -2
- data/lib/atomically/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 215319d576e714905af55fcb2ec48b1924c5971bf0e0bdaf3c61f75be3862a13
|
4
|
+
data.tar.gz: 6171664742f2758011c79058fc2fd13850e11bb61c28604f24625e4ed107026f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 117f29a0644c694a25bef5ebd0d5bf8219e1a9e2521e0fad95f8ee5180ebad418d2651b10d3259a06735b495d23ceb4de1a75d3e928fe4dc725203aece924306
|
7
|
+
data.tar.gz: 62482706f8a98ad1bc71041c323596a117e810330921b90e9395134c7d495c9c7e2b7f01378151178abd20b11dffad42678e9b2fdd0e851776d2de81537c10be
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
## Change Log
|
2
|
+
|
3
|
+
### [v1.0.2](https://github.com/khiav223577/atomically/compare/v1.0.1...v1.0.2) 2018/11/27
|
4
|
+
- [#3](https://github.com/khiav223577/atomically/pull/3) Implement `update` (@khiav223577)
|
5
|
+
|
6
|
+
### v1.0.1 2018/11/22
|
7
|
+
- [#2](https://github.com/khiav223577/atomically/pull/2) Implement `pay_all` (@khiav223577)
|
8
|
+
- [#1](https://github.com/khiav223577/atomically/pull/1) Implement `create_or_plus` (@khiav223577)
|
data/README.md
CHANGED
@@ -28,14 +28,17 @@ Or install it yourself as:
|
|
28
28
|
|
29
29
|
## Usage
|
30
30
|
|
31
|
-
### create_or_plus
|
31
|
+
### create_or_plus _(columns, values, on_duplicate_update_columns)_
|
32
32
|
|
33
33
|
Import an array of records. When key is duplicate, plus the old value with new value.
|
34
34
|
It is useful to add `items` to `user` when `user_items` may not exist.
|
35
35
|
|
36
|
-
|
36
|
+
#### Parameters
|
37
37
|
|
38
|
-
|
38
|
+
- First two args (`columns`, `values`) are the same with the [import](https://github.com/zdennis/activerecord-import#columns-and-arrays) method.
|
39
|
+
- `on_duplicate_update_columns` - The column that will be updated on duplicate.
|
40
|
+
|
41
|
+
#### Example
|
39
42
|
```rb
|
40
43
|
user = User.find(2)
|
41
44
|
item1 = Item.find(1)
|
@@ -50,28 +53,81 @@ on_duplicate_update_columns = [:quantity]
|
|
50
53
|
UserItem.atomically.create_or_plus(columns, values, on_duplicate_update_columns)
|
51
54
|
```
|
52
55
|
|
53
|
-
|
56
|
+
before
|
57
|
+
|
54
58
|
![before](https://user-images.githubusercontent.com/4011729/48998921-ff430600-f18f-11e8-8eeb-e8a71bbf5802.png)
|
55
59
|
|
56
|
-
|
60
|
+
after
|
61
|
+
|
57
62
|
![image](https://user-images.githubusercontent.com/4011729/48999092-8d1ef100-f190-11e8-8372-86e2e99cbe08.png)
|
58
63
|
|
59
64
|
|
60
|
-
### pay_all
|
65
|
+
### pay_all _(hash, update_columns, primary_key: :id)_
|
61
66
|
|
62
67
|
Reduce the quantity of items and return how many rows and updated if all of them is enough.
|
63
68
|
Do nothing and return zero if any of them is not enough.
|
64
69
|
|
65
|
-
|
70
|
+
#### Parameters
|
71
|
+
|
72
|
+
- `hash` - A hash contains the id of the models as keys and the amount to update the field by as values.
|
73
|
+
- `update_columns` - The column that will be updated.
|
74
|
+
- `primary_key` - Specify the column that `id`(the key of hash) refer to.
|
75
|
+
|
76
|
+
#### Example
|
77
|
+
|
66
78
|
```rb
|
67
79
|
user.user_items.atomically.pay_all({ item1.id => 4, item2.id => 3 }, [:quantity], primary_key: :item_id)
|
68
80
|
```
|
69
81
|
|
70
|
-
|
82
|
+
```sql
|
83
|
+
# generated sql
|
84
|
+
UPDATE `user_items` SET `quantity` = `quantity` + (@change :=
|
85
|
+
CASE `item_id`
|
86
|
+
WHEN 1 THEN -4
|
87
|
+
WHEN 2 THEN -3
|
88
|
+
END)
|
89
|
+
WHERE `user_items`.`user_id` = 1 AND (
|
90
|
+
`user_items`.`item_id` = 1 AND (`quantity` >= 4) OR `user_items`.`item_id` = -2 AND (`quantity` >= 3)
|
91
|
+
) AND (
|
92
|
+
(
|
93
|
+
SELECT COUNT(*) FROM (
|
94
|
+
SELECT `user_items`.* FROM `user_items`
|
95
|
+
WHERE `user_items`.`user_id` = 1 AND (
|
96
|
+
`user_items`.`item_id` = 1 AND (`quantity` >= 4) OR `user_items`.`item_id` = 2 AND (`quantity` >= 3)
|
97
|
+
)
|
98
|
+
) subquery
|
99
|
+
) = 2
|
100
|
+
)
|
101
|
+
```
|
102
|
+
|
103
|
+
### update_all _(expected_number, updates)_
|
104
|
+
|
105
|
+
Behaves like [ActiveRecord::Relation#update_all](https://apidock.com/rails/ActiveRecord/Relation/update_all) but add an additional constrain that the number of affected rows equals to what you specify.
|
106
|
+
|
107
|
+
#### Parameters
|
108
|
+
|
109
|
+
- `expected_number` - The number of rows that you expect to be updated.
|
110
|
+
- `updates` - A string, array, or hash representing the SET part of an SQL statement.
|
111
|
+
|
112
|
+
#### Examples
|
113
|
+
```rb
|
114
|
+
User.where(id: [1, 2]).atomically.update_all(2, name: '')
|
115
|
+
# => 2
|
116
|
+
|
117
|
+
User.where(id: [1, 2, 3]).atomically.update_all(2, name: '')
|
118
|
+
# => 0
|
119
|
+
```
|
120
|
+
|
121
|
+
### update _(attrs, from: :not_set)_
|
71
122
|
|
72
123
|
Updates the attributes of the model from the passed-in hash and saves the record. The difference between this method and [ActiveRecord#update](https://apidock.com/rails/ActiveRecord/Persistence/update) is that it will add extra WHERE conditions to prevent race condition.
|
73
124
|
|
74
|
-
|
125
|
+
#### Parameters
|
126
|
+
|
127
|
+
- `attrs` - Same with the first parameter of [ActiveRecord#update](https://apidock.com/rails/ActiveRecord/Persistence/update)
|
128
|
+
- `from` - The value before update. If not set, use the attriutes of the model.
|
129
|
+
|
130
|
+
#### Example
|
75
131
|
```rb
|
76
132
|
class Arena < ApplicationRecord
|
77
133
|
def atomically_close!
|
@@ -35,8 +35,11 @@ class Atomically::QueryService
|
|
35
35
|
next "#{column} = #{column} + #{value}"
|
36
36
|
end
|
37
37
|
|
38
|
-
return query.
|
39
|
-
|
38
|
+
return where_all_can_be_updated(query, hash.size).update_all(update_sqls.join(', '))
|
39
|
+
end
|
40
|
+
|
41
|
+
def update_all(expected_size, *args)
|
42
|
+
where_all_can_be_updated(@relation, expected_size).update_all(*args)
|
40
43
|
end
|
41
44
|
|
42
45
|
def update(attrs, from: :not_set)
|
@@ -59,6 +62,10 @@ class Atomically::QueryService
|
|
59
62
|
@klass.connection.quote(value)
|
60
63
|
end
|
61
64
|
|
65
|
+
def where_all_can_be_updated(query, expected_size)
|
66
|
+
query.where("(#{@klass.from(query.where('')).select('COUNT(*)').to_sql}) = ?", expected_size)
|
67
|
+
end
|
68
|
+
|
62
69
|
def update_and_return_number_of_updated_rows(attrs, from)
|
63
70
|
model = @model
|
64
71
|
return open_update_all_scope do
|
data/lib/atomically/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.3
|
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-11-
|
11
|
+
date: 2018-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|