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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94187458ce758fe40e71ba068f03dad4e2d8cebb0757099b8cecad1f1a8da017
4
- data.tar.gz: c79301b92a0436536feb4f850ba7e1b5f8fb8d589c17e50b9b6c20a38022826c
3
+ metadata.gz: 215319d576e714905af55fcb2ec48b1924c5971bf0e0bdaf3c61f75be3862a13
4
+ data.tar.gz: 6171664742f2758011c79058fc2fd13850e11bb61c28604f24625e4ed107026f
5
5
  SHA512:
6
- metadata.gz: 5163ddf343c94d028e7ea2b6fadd62baccf65e49a9d57ef08ff0894a1a3113c14048af6a410c7129604292c5d9d39d3c81ff94a8293f24b0eb08c170039beb59
7
- data.tar.gz: 5d02fedd2c17837517874714a23ffedd0a801a93cb12adf1217ed59cf8af483fd1793320f6fb7bbbf3aa35257ba9efda034245b194728949b8c526eaf07c07e2
6
+ metadata.gz: 117f29a0644c694a25bef5ebd0d5bf8219e1a9e2521e0fad95f8ee5180ebad418d2651b10d3259a06735b495d23ceb4de1a75d3e928fe4dc725203aece924306
7
+ data.tar.gz: 62482706f8a98ad1bc71041c323596a117e810330921b90e9395134c7d495c9c7e2b7f01378151178abd20b11dffad42678e9b2fdd0e851776d2de81537c10be
@@ -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
- First two args (columns, values) are the same with the [import](https://github.com/zdennis/activerecord-import#columns-and-arrays) method.
36
+ #### Parameters
37
37
 
38
- Example:
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
- #### before
56
+ before
57
+
54
58
  ![before](https://user-images.githubusercontent.com/4011729/48998921-ff430600-f18f-11e8-8eeb-e8a71bbf5802.png)
55
59
 
56
- #### after
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
- Example:
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
- ### update
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
- Example:
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.where("(#{@klass.from(query).select('COUNT(*)').to_sql}) = ?", hash.size)
39
- .update_all(update_sqls.join(', '))
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Atomically
4
- VERSION = '1.0.2'
4
+ VERSION = '1.0.3'
5
5
  end
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.2
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-27 00:00:00.000000000 Z
11
+ date: 2018-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler