update_cardinals_by 0.0.1 → 0.1.0

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: b4c004461c19b5e0aefe58e948cfb03811159e6b
4
- data.tar.gz: cba4dafca4758e506b028221e8d54f7df3cf1643
2
+ SHA256:
3
+ metadata.gz: 0f0c9aa2f3667c4925560e59e838b79a294b918f48dda0f7092b01e476ad0c40
4
+ data.tar.gz: cdd625ca542d8d09e7d4ac17a03e48862f569d42a1694bfb94751780b4ed37c0
5
5
  SHA512:
6
- metadata.gz: f1d5c44273f2949c2406615f227df62eb212ee7f9ba4abbaaf66e189d21f28502da60e656b47542c7187caad5ce1627eec565f70d29dd8ab37c1d147b6fabdd7
7
- data.tar.gz: fcb907362971985e948276a6fd10d4081850acc69e538c81e09170c4c34a6c17c7b2863bfb49ec68163db290115cbb90ee27b5d18c087393101a56ba4f633b40
6
+ metadata.gz: 6ff4b4a4137503a08368116b1b0f213bb41fe08a0d3ca06c8ba44694ca3d00d62e0ee54072efb418737b15af9f987022e9427a0a418e498f2816c5692b83e258
7
+ data.tar.gz: 382d155ff8ddc7b3aae7bc9936ee6d6186ac1f55e27dc444249fb23fda69c52c7cf0aa6c28f4c5fed2ae762cc29d6dc85b9faee7f4d704b08b537b2c28cbcd4f
data/README.md CHANGED
@@ -1,22 +1,49 @@
1
- # Update Cardinals
1
+ # Update Cardinals By delta for Postgresql.
2
+
3
+ ## Function
2
4
 
3
5
  A gem to more safely update cardinal numbers like credits.
4
6
 
5
- It will start a transaction, make the change with a delta and call the given block. If any exceptions are thrown in the block, the change will be reverted.
7
+ It will
8
+ * start a transaction
9
+ * make the change with a delta `attr = attr + #{attributes[attr]}}`
10
+ * call the given block with an indifferent hash of the latest values in the db.
11
+ * update the given attributes on the instance to the latest values.
12
+ * end transaction.
13
+
14
+ If any exceptions are thrown in the block, the change will automatically be reverted.
6
15
 
7
- Sql will be like
16
+ Sql will be like:
8
17
 
9
18
  ```sql
10
- update accounts set credits = credit + -20 where id = 6
19
+ update accounts set credits = credit + -20 where id = 6 returning credits
11
20
  ```
12
21
 
22
+ ## Usage:
13
23
 
14
- Usage:
24
+ ```Gemfile
25
+ gem 'update_cardinals_by', '~> 0.1.0'
26
+ ```
15
27
 
16
28
  ```ruby
17
- change_counters_by!(credits: -20) do |res|
29
+ update_cardinals_by!(credits: -20) do |res|
18
30
  fail 'not enough credits' if res[:credits] < 0
19
31
  CreateWantedItems.run(..)
20
- CreditMutation.create(credits_new: res[:credits], credits_change: -20)
32
+ CreditMutation.create credits_new: res[:credits],
33
+ credits_old: credits,
34
+ credits_change: -20
21
35
  end
22
36
  ```
37
+
38
+ ## Changelog
39
+
40
+ 0.1.0 changed activerecord support from 4.2 to 5.0 and 5.1
41
+
42
+ ## Developing
43
+
44
+ ```
45
+ rake setup
46
+ rake db:setup
47
+ bundle exec appraisal install
48
+ bundle exec appraisal rspec
49
+ ```
data/Rakefile CHANGED
@@ -48,14 +48,16 @@ namespace :db do
48
48
  end
49
49
 
50
50
  task :drop => :load_db_settings do
51
- %x{ dropdb #{ENV['DATABASE_NAME']} }
51
+ %x{ dropdb #{ENV['DATABASE_NAME']} --if-exists }
52
+ puts 'Database dropped'
52
53
  end
53
54
 
54
55
  task :create => :load_db_settings do
55
56
  %x{ createdb #{ENV['DATABASE_NAME']} }
57
+ puts 'Database created'
56
58
  end
57
59
 
58
- task :migrate => :load_db_settings do
60
+ task :setup => [:drop, :create] do
59
61
  ActiveRecord::Base.establish_connection
60
62
 
61
63
  ActiveRecord::Base.connection.enable_extension 'hstore'
@@ -65,6 +67,6 @@ namespace :db do
65
67
  t.decimal "money"
66
68
  end
67
69
 
68
- puts 'Database migrated'
70
+ puts 'Database tables created'
69
71
  end
70
72
  end
@@ -1,3 +1,3 @@
1
1
  module UpdateCardinalsBy
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -3,12 +3,15 @@ require 'active_support/concern'
3
3
  module UpdateCardinalsBy
4
4
  extend ActiveSupport::Concern
5
5
 
6
- #
7
- # returns indifferent hash of new values.
6
+ # Changes given attributes by delta.
7
+ # @param attributes, hash from attribute to delta
8
+ # @param &block Block to execute after making update.
9
+ # Will receive indifferent hash from attribute to latest value in db.
10
+ # @returns indifferent hash from attribute to latest value in db.
8
11
  def update_cardinals_by!(attributes, &block)
9
12
  db_attributes = attributes.map { |k, v| [self.class.connection.quote_column_name(k), v] }
10
13
  updates = db_attributes.map.with_index { |(k, v), i| "#{k} = #{k} + $#{i+1}" }
11
- binds = db_attributes.map { |k, v| [column_for_attribute(k), v] }
14
+ binds = attributes.map { |k, v| [column_for_attribute(k), v] }
12
15
 
13
16
  transaction do
14
17
  res = self.class.connection.exec_query(
@@ -18,7 +21,7 @@ module UpdateCardinalsBy
18
21
  "returning #{db_attributes.map(&:first).join(', ')}",
19
22
  'SQL', binds
20
23
  ).first
21
- .map { |k, v| [k, column_for_attribute(k).type_cast_from_database(v)] }
24
+ .map { |k, v| [k, type_for_attribute(k).cast(v)] }
22
25
  res = HashWithIndifferentAccess[ res ]
23
26
 
24
27
  yield res if block_given?
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ class Account < ActiveRecord::Base
4
+ include UpdateCardinalsBy
5
+
6
+ def update_by!(attributes)
7
+ update_cardinals_by!(attributes) do |res|
8
+ if res[:credits] && res[:credits] < 0
9
+ fail 'Credits dropped below 0'
10
+ end
11
+ end
12
+ rescue => e
13
+ e
14
+ end
15
+ end
16
+
17
+ describe UpdateCardinalsBy do
18
+ let(:account) { Account.create credits: 100, money: BigDecimal(12, 34) }
19
+
20
+ describe 'update_cardinals_by!' do
21
+ it 'accepts positive change' do
22
+ account.update_by!(credits: 20, money: BigDecimal(3, 16))
23
+ expect(account.credits).to eq 120
24
+ expect(account.money).to eq BigDecimal(15, 50)
25
+ end
26
+
27
+ it 'accepts negative change' do
28
+ account.update_by!(credits: -20, money: -BigDecimal(1, 24))
29
+ expect(account.credits).to eq 80
30
+ expect(account.money).to eq BigDecimal(11, 10)
31
+ end
32
+
33
+ it 'leaves leaves the instance in a saved state' do
34
+ account.update_by!(credits: 20, money: BigDecimal(3, 16))
35
+ expect(account.changed?).to be_falsy
36
+ end
37
+
38
+ it 'reverts the value when the block throws an error' do
39
+ account.update_by!(credits: -200)
40
+ expect(account.credits).to eq 100
41
+ expect(account.reload.credits).to eq 100
42
+ end
43
+
44
+ it 'passes the right types to the block' do
45
+ account.update_cardinals_by!(credits: 20, money: BigDecimal(3, 16)) do |res|
46
+ expect(res[:credits]).to be_a Integer
47
+ expect(res[:money]).to be_a BigDecimal
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'active_record'
4
+ Bundler.require(:default, :development)
5
+
6
+ require 'update_cardinals_by'
7
+
8
+ Dotenv.load
9
+
10
+ ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
11
+
12
+ RSpec.configure do |config|
13
+ config.before(:suite) do
14
+ DatabaseCleaner.clean_with(:truncation)
15
+ end
16
+ config.before(:each) do
17
+ DatabaseCleaner.start
18
+ end
19
+ config.after(:each) do
20
+ DatabaseCleaner.clean
21
+ end
22
+ end
23
+
24
+
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: update_cardinals_by
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hampei
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-24 00:00:00.000000000 Z
11
+ date: 2019-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: 4.2.7
22
+ version: '5.2'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">"
28
+ - !ruby/object:Gem::Version
29
+ version: '5.0'
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: 4.2.7
32
+ version: '5.2'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: pg
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -56,32 +62,46 @@ dependencies:
56
62
  name: rspec
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - ">="
65
+ - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '0'
67
+ version: '3.0'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
- - - ">="
72
+ - - "~>"
67
73
  - !ruby/object:Gem::Version
68
- version: '0'
74
+ version: '3.0'
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: dotenv
71
77
  requirement: !ruby/object:Gem::Requirement
72
78
  requirements:
73
- - - ">="
79
+ - - "~>"
74
80
  - !ruby/object:Gem::Version
75
- version: '0'
81
+ version: '2.0'
76
82
  type: :development
77
83
  prerelease: false
78
84
  version_requirements: !ruby/object:Gem::Requirement
79
85
  requirements:
80
- - - ">="
86
+ - - "~>"
81
87
  - !ruby/object:Gem::Version
82
- version: '0'
88
+ version: '2.0'
83
89
  - !ruby/object:Gem::Dependency
84
90
  name: database_cleaner
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: appraisal
85
105
  requirement: !ruby/object:Gem::Requirement
86
106
  requirements:
87
107
  - - ">="
@@ -106,6 +126,8 @@ files:
106
126
  - Rakefile
107
127
  - lib/update_cardinals_by.rb
108
128
  - lib/update_cardinals_by/version.rb
129
+ - spec/concerns/update_cardinals_by_spec.rb
130
+ - spec/spec_helper.rb
109
131
  homepage: https://github.com/hampei/update_cardinals_by
110
132
  licenses:
111
133
  - MIT
@@ -118,17 +140,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
140
  requirements:
119
141
  - - ">="
120
142
  - !ruby/object:Gem::Version
121
- version: '0'
143
+ version: '2.1'
122
144
  required_rubygems_version: !ruby/object:Gem::Requirement
123
145
  requirements:
124
146
  - - ">="
125
147
  - !ruby/object:Gem::Version
126
148
  version: '0'
127
149
  requirements: []
128
- rubyforge_project:
129
- rubygems_version: 2.5.1
150
+ rubygems_version: 3.0.2
130
151
  signing_key:
131
152
  specification_version: 4
132
153
  summary: postgres database extension to increment/decrement values safely and get
133
154
  back result.
134
- test_files: []
155
+ test_files:
156
+ - spec/spec_helper.rb
157
+ - spec/concerns/update_cardinals_by_spec.rb