atomically 1.0.0 → 1.0.1

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
- SHA1:
3
- metadata.gz: 053a70728eaf97d497e01c5eb97d28b8606a13f6
4
- data.tar.gz: d19a6e6f011e0fa73f8ed40a6f48fc514d426c16
2
+ SHA256:
3
+ metadata.gz: d38cf83ab4f1e792cfefbb2c01ac897377fb7af2a81da6f09f932df4d5fa76f2
4
+ data.tar.gz: 88640837b4c69ef162d036b2a3e6ad61087e94a6baa79cde026fb748f09b58f1
5
5
  SHA512:
6
- metadata.gz: 642a937243e5e133294cfc5d97be7201cad09041717ff13ec512f8f23d4fc128d18dfd78d25d4130d0c0526655ccd232b25ada2decf284b1e55ece0c990b2dea
7
- data.tar.gz: 247cbb367d404627ab799af68f35de8dd2294e0a7b1d585c061e8b5d4a25ae5691af646577a51dd8a9b1e696304b1cd784ddc45773c7ec55acb74529d1e7fd77
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, :count]
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 = [:count]
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.
@@ -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
@@ -3,7 +3,7 @@ require 'atomically/query_service'
3
3
 
4
4
  class ActiveRecord::Relation
5
5
  def atomically
6
- Atomically::QueryService.new(klass)
6
+ Atomically::QueryService.new(klass, relation: self)
7
7
  end
8
8
  end
9
9
 
@@ -0,0 +1,8 @@
1
+ require 'active_record'
2
+
3
+ class << ActiveRecord::Base
4
+ def from(value) # For Rails 3
5
+ value = "(#{value.to_sql}) subquery" if value.is_a?( ActiveRecord::Relation )
6
+ return super
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ require 'active_record'
2
+
3
+ class << ActiveRecord::Base
4
+ def none # For Rails 3
5
+ where('1=0')
6
+ end
7
+ 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
- .map(&@klass.connection.method(:quote_column_name))
17
- .map{|s| "#{s} = #{s} + VALUES(#{s})" }
18
- .force
19
- .join(', ')
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
@@ -1,3 +1,3 @@
1
1
  module Atomically
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  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.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-21 00:00:00.000000000 Z
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: activerecord
126
+ name: rails_or
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
116
130
  - !ruby/object:Gem::Version
117
- version: '3'
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: '3'
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.13
190
+ rubygems_version: 2.7.6
175
191
  signing_key:
176
192
  specification_version: 4
177
193
  summary: ''