atomically 1.0.2 → 1.0.3
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/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
|

|
55
59
|
|
56
|
-
|
60
|
+
after
|
61
|
+
|
57
62
|

|
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
|