atomically 1.0.0 → 1.0.1
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 +5 -5
- data/README.md +12 -4
- data/atomically.gemspec +2 -1
- data/lib/atomically/active_record/extension.rb +1 -1
- data/lib/atomically/patches/from.rb +8 -0
- data/lib/atomically/patches/none.rb +7 -0
- data/lib/atomically/query_service.rb +37 -6
- data/lib/atomically/version.rb +1 -1
- metadata +22 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d38cf83ab4f1e792cfefbb2c01ac897377fb7af2a81da6f09f932df4d5fa76f2
|
4
|
+
data.tar.gz: 88640837b4c69ef162d036b2a3e6ad61087e94a6baa79cde026fb748f09b58f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd968dcc060705bc3d0174daf532fa4c80b8dfadc5845a7406bcf68d930744c6ce78e2f04b97091eb4cea27818ed44df1e4b3c47eefac5e0643ab492b9bed21b
|
7
|
+
data.tar.gz: 7577dd5ef6f32a4d3753c71637d218358d48aeac8b7c675c9b780d906af56f08bd9cf5cb14d7b98fd12a9275d28f6d45ec8a5baaccb3b177257e300a04c0c890
|
data/README.md
CHANGED
@@ -31,20 +31,28 @@ Or install it yourself as:
|
|
31
31
|
### create_or_plus
|
32
32
|
|
33
33
|
Import an array of records. When key is duplicate, plus the old value with new value.
|
34
|
-
It is useful to add `items` to user when `user_items` may not exist.
|
34
|
+
It is useful to add `items` to `user` when `user_items` may not exist.
|
35
35
|
|
36
36
|
First two args (columns, values) are the same with the [import](https://github.com/zdennis/activerecord-import#columns-and-arrays) method.
|
37
37
|
|
38
38
|
Example:
|
39
|
-
|
40
39
|
```rb
|
41
|
-
columns = [:user_id, :item_id, :
|
40
|
+
columns = [:user_id, :item_id, :quantity]
|
42
41
|
values = [[user.id, item1.id, 3], [user.id, item2.id, 2]]
|
43
|
-
on_duplicate_update_columns = [:
|
42
|
+
on_duplicate_update_columns = [:quantity]
|
44
43
|
|
45
44
|
UserItem.atomically.create_or_plus(columns, values, on_duplicate_update_columns)
|
46
45
|
```
|
47
46
|
|
47
|
+
### pay_all
|
48
|
+
Reduce the quantity of items and return how many rows and updated if all of them is enough.
|
49
|
+
Do nothing and return zero if any of them is not enough.
|
50
|
+
|
51
|
+
Example:
|
52
|
+
```rb
|
53
|
+
user.user_items.atomically.pay_all({ item1.id => 4, item2.id => 3 }, [:quantity], primary_key: :item_id)
|
54
|
+
```
|
55
|
+
|
48
56
|
## Development
|
49
57
|
|
50
58
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test DB=mysql` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/atomically.gemspec
CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_development_dependency "mysql2", ">= 0.3"
|
35
35
|
spec.add_development_dependency "pluck_all", ">= 2.0.3"
|
36
36
|
|
37
|
-
spec.add_dependency "activerecord-import", ">= 0.27.0"
|
38
37
|
spec.add_dependency "activerecord", ">= 3"
|
38
|
+
spec.add_dependency "activerecord-import", ">= 0.27.0"
|
39
|
+
spec.add_dependency "rails_or", ">= 1.1.8"
|
39
40
|
end
|
@@ -1,21 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'activerecord-import'
|
4
|
+
require 'rails_or'
|
5
|
+
require 'atomically/patches/none' if not ActiveRecord::Base.respond_to?(:none)
|
6
|
+
require 'atomically/patches/from' if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.0.0')
|
2
7
|
|
3
8
|
class Atomically::QueryService
|
4
|
-
def initialize(klass)
|
9
|
+
def initialize(klass, relation: nil)
|
5
10
|
@klass = klass
|
11
|
+
@relation = relation || @klass
|
6
12
|
end
|
7
13
|
|
8
14
|
def create_or_plus(columns, data, update_columns)
|
9
15
|
@klass.import(columns, data, on_duplicate_key_update: on_duplicate_key_plus_sql(update_columns))
|
10
16
|
end
|
11
17
|
|
18
|
+
def pay_all(hash, update_columns, primary_key: :id) # { id => pay_count }
|
19
|
+
return 0 if hash.blank?
|
20
|
+
|
21
|
+
update_columns = update_columns.map(&method(:quote_column))
|
22
|
+
|
23
|
+
query = hash.inject(@klass.none) do |relation, (id, pay_count)|
|
24
|
+
condition = @relation.where(primary_key => id)
|
25
|
+
update_columns.each{|s| condition = condition.where("#{s} >= ?", pay_count) }
|
26
|
+
next relation.or(condition)
|
27
|
+
end
|
28
|
+
|
29
|
+
raw_when_sql = hash.map{|id, pay_count| "WHEN #{sanitize(id)} THEN #{sanitize(-pay_count)}" }.join("\n")
|
30
|
+
update_sqls = update_columns.map.with_index do |column, idx|
|
31
|
+
value = idx == 0 ? "(@change := \nCASE #{quote_column(primary_key)}\n#{raw_when_sql}\nEND)" : '@change'
|
32
|
+
next "#{column} = #{column} + #{value}"
|
33
|
+
end
|
34
|
+
|
35
|
+
return query.where("(#{@klass.from(query).select('COUNT(*)').to_sql}) = ?", hash.size)
|
36
|
+
.update_all(update_sqls.join(', '))
|
37
|
+
end
|
38
|
+
|
12
39
|
private
|
13
40
|
|
14
41
|
def on_duplicate_key_plus_sql( columns)
|
15
|
-
columns.lazy
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
42
|
+
columns.lazy.map(&method(:quote_column)).map{|s| "#{s} = #{s} + VALUES(#{s})" }.force.join(', ')
|
43
|
+
end
|
44
|
+
|
45
|
+
def quote_column(column)
|
46
|
+
@klass.connection.quote_column_name(column)
|
47
|
+
end
|
48
|
+
|
49
|
+
def sanitize(value)
|
50
|
+
@klass.connection.quote(value)
|
20
51
|
end
|
21
52
|
end
|
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.1
|
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-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 2.0.3
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activerecord
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: activerecord-import
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,19 +123,19 @@ dependencies:
|
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: 0.27.0
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: rails_or
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
131
|
+
version: 1.1.8
|
118
132
|
type: :runtime
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
136
|
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
138
|
+
version: 1.1.8
|
125
139
|
description: ''
|
126
140
|
email:
|
127
141
|
- mrtmrt15xn@yahoo.com.tw
|
@@ -149,6 +163,8 @@ files:
|
|
149
163
|
- gemfiles/5.2.gemfile
|
150
164
|
- lib/atomically.rb
|
151
165
|
- lib/atomically/active_record/extension.rb
|
166
|
+
- lib/atomically/patches/from.rb
|
167
|
+
- lib/atomically/patches/none.rb
|
152
168
|
- lib/atomically/query_service.rb
|
153
169
|
- lib/atomically/version.rb
|
154
170
|
homepage: https://github.com/khiav223577/atomically
|
@@ -171,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
187
|
version: '0'
|
172
188
|
requirements: []
|
173
189
|
rubyforge_project:
|
174
|
-
rubygems_version: 2.6
|
190
|
+
rubygems_version: 2.7.6
|
175
191
|
signing_key:
|
176
192
|
specification_version: 4
|
177
193
|
summary: ''
|