believer 0.2.14 → 0.2.15
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/believer/base.rb +1 -1
- data/lib/believer/counter.rb +6 -0
- data/lib/believer/counting.rb +32 -0
- data/lib/believer/environment/base_env.rb +5 -0
- data/lib/believer/test/database.rb +2 -2
- data/lib/believer/test/test_run_life_cycle.rb +34 -11
- data/lib/believer/version.rb +1 -1
- data/spec/believer/columns_spec.rb +4 -2
- data/spec/believer/counting_spec.rb +40 -26
- data/spec/believer/update_spec.rb +20 -21
- data/spec/support/test_classes.rb +4 -3
- metadata +1 -1
data/lib/believer/base.rb
CHANGED
@@ -23,7 +23,6 @@ module Believer
|
|
23
23
|
attr_accessor :id
|
24
24
|
|
25
25
|
def initialize(attrs = {})
|
26
|
-
@attributes = {}
|
27
26
|
set_attributes(attrs)
|
28
27
|
yield self if block_given?
|
29
28
|
end
|
@@ -47,6 +46,7 @@ module Believer
|
|
47
46
|
end
|
48
47
|
|
49
48
|
def set_attributes(attrs)
|
49
|
+
@attributes = {}
|
50
50
|
attrs.each do |name, val|
|
51
51
|
send("#{name}=".to_sym, val)
|
52
52
|
end if attrs.present?
|
data/lib/believer/counter.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Believer
|
2
2
|
|
3
|
+
# The counter value
|
3
4
|
class Counter
|
4
5
|
|
5
6
|
def initialize(v = 0, initial_val = nil)
|
@@ -7,6 +8,11 @@ module Believer
|
|
7
8
|
@initial_value = initial_val.nil? ? @value : initial_val
|
8
9
|
end
|
9
10
|
|
11
|
+
def reconcile!
|
12
|
+
@initial_value = @value
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
10
16
|
def reset!
|
11
17
|
@value = 0
|
12
18
|
self
|
data/lib/believer/counting.rb
CHANGED
@@ -1,23 +1,29 @@
|
|
1
1
|
module Believer
|
2
|
+
# Model functionality for counter columns
|
2
3
|
module Counting
|
3
4
|
extend ::ActiveSupport::Concern
|
4
5
|
|
5
6
|
module ClassMethods
|
6
7
|
|
8
|
+
# Returns all the counter columns
|
9
|
+
# @return an array of Column
|
7
10
|
def counter_columns
|
8
11
|
columns_with_type(:counter)
|
9
12
|
end
|
10
13
|
|
14
|
+
# Is this a model class with counter columns?
|
11
15
|
def is_counter_table?
|
12
16
|
counter_columns.any?
|
13
17
|
end
|
14
18
|
|
15
19
|
end
|
16
20
|
|
21
|
+
# Is this a model with counters?
|
17
22
|
def is_counter_instance?
|
18
23
|
self.class.is_counter_table?
|
19
24
|
end
|
20
25
|
|
26
|
+
# Returns true if there are any counter increments or decrements
|
21
27
|
def has_counter_diffs?
|
22
28
|
self.class.counter_columns.any? do |col|
|
23
29
|
counter = self.send(col.name)
|
@@ -25,5 +31,31 @@ module Believer
|
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
34
|
+
# Reloads from DB, resets all counters and saves, which effectively resets all counters
|
35
|
+
def reset_counters!
|
36
|
+
reload!
|
37
|
+
self.class.counter_columns.each do |cc|
|
38
|
+
counter = self.send(cc.name)
|
39
|
+
counter.reset! unless counter.nil?
|
40
|
+
end
|
41
|
+
save
|
42
|
+
end
|
43
|
+
|
44
|
+
# Increments a counter and saves the receiver model
|
45
|
+
def incr_counter!(name, val = 1)
|
46
|
+
counter = self.send(name.to_sym)
|
47
|
+
counter.incr(val)
|
48
|
+
save
|
49
|
+
counter.reconcile!
|
50
|
+
end
|
51
|
+
|
52
|
+
# Increments a counter and saves the receiver model
|
53
|
+
def decr_counter!(name, decr = 1)
|
54
|
+
counter = self.send(name.to_sym)
|
55
|
+
counter.decr(val)
|
56
|
+
save
|
57
|
+
counter.reconcile!
|
58
|
+
end
|
59
|
+
|
28
60
|
end
|
29
61
|
end
|
@@ -14,7 +14,7 @@ module Believer
|
|
14
14
|
keyspace = ::Believer::KeySpace.new(env)
|
15
15
|
# First delete the existing keyspace
|
16
16
|
begin
|
17
|
-
|
17
|
+
#env.logger.debug "Dropping keyspace"
|
18
18
|
keyspace.drop
|
19
19
|
rescue Cql::QueryError
|
20
20
|
end
|
@@ -30,7 +30,7 @@ module Believer
|
|
30
30
|
clazz = cl
|
31
31
|
end
|
32
32
|
if clazz.ancestors.include?(Believer::Base)
|
33
|
-
puts "Creating table #{clazz.table_name}"
|
33
|
+
#puts "Creating table #{clazz.table_name}"
|
34
34
|
clazz.create_table()
|
35
35
|
end
|
36
36
|
|
@@ -5,7 +5,7 @@ module Believer
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
|
8
|
+
|
9
9
|
Believer::Base.after_save do |model|
|
10
10
|
Destructor.instance.after_save(model)
|
11
11
|
end
|
@@ -16,21 +16,44 @@ module Believer
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# Detroys all CqlRecord::Base instances created
|
19
|
-
class Destructor
|
19
|
+
class Destructor
|
20
20
|
include Singleton
|
21
|
-
|
21
|
+
|
22
|
+
def counters_action
|
23
|
+
if @counters_action.nil?
|
24
|
+
begin
|
25
|
+
@counters_action = Believer::Base.environment.believer_configuration[:test][:life_cycle][:counters].to_sym
|
26
|
+
rescue
|
27
|
+
@counters_action = :destroy
|
28
|
+
end
|
29
|
+
end
|
30
|
+
@counters_action
|
31
|
+
end
|
32
|
+
|
33
|
+
def should_destroy?(model)
|
34
|
+
#return false if model.is_counter_instance? && retain_counter_models?
|
35
|
+
true
|
36
|
+
end
|
22
37
|
|
23
38
|
def cleanup
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
39
|
+
@observed_models.each do |model|
|
40
|
+
begin
|
41
|
+
if model.is_counter_instance?
|
42
|
+
case counters_action
|
43
|
+
when :destroy
|
44
|
+
model.destroy if should_destroy?(model)
|
45
|
+
when :reset
|
46
|
+
model.reset_counters!
|
47
|
+
when :retain
|
48
|
+
end
|
49
|
+
else
|
50
|
+
model.destroy if should_destroy?(model)
|
30
51
|
end
|
52
|
+
rescue Exception => e
|
53
|
+
puts "Could not destroy model #{model}: #{e}\n#{e.backtrace.join("\n")}"
|
31
54
|
end
|
32
|
-
|
33
|
-
|
55
|
+
end unless @observed_models.nil? || @observed_models.empty?
|
56
|
+
@observed_models = nil
|
34
57
|
end
|
35
58
|
|
36
59
|
def observed_models
|
data/lib/believer/version.rb
CHANGED
@@ -14,8 +14,10 @@ describe Believer::Columns do
|
|
14
14
|
string_cols = Test::Song.columns_with_type(:string)
|
15
15
|
expect(string_cols.size).to eql 4
|
16
16
|
|
17
|
-
counter_cols = Test::
|
18
|
-
expect(counter_cols).to eql
|
17
|
+
counter_cols = Test::AlbumStatistics.columns_with_type(:counter)
|
18
|
+
expect(counter_cols.size).to eql 2
|
19
|
+
expect(counter_cols).to include Test::AlbumStatistics.columns[:sold]
|
20
|
+
expect(counter_cols).to include Test::AlbumStatistics.columns[:produced]
|
19
21
|
end
|
20
22
|
|
21
23
|
end
|
@@ -4,58 +4,72 @@ describe Believer::Counting do
|
|
4
4
|
|
5
5
|
it 'should detect a counter table' do
|
6
6
|
expect(Test::Artist.is_counter_table?).to eql false
|
7
|
-
expect(Test::
|
7
|
+
expect(Test::AlbumStatistics.is_counter_table?).to eql true
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'should detect a changed counter instance' do
|
11
|
-
album_sales = Test::
|
11
|
+
album_sales = Test::AlbumStatistics.new
|
12
12
|
expect(album_sales.has_counter_diffs?).to eql false
|
13
|
-
album_sales.
|
13
|
+
album_sales.sold.incr
|
14
14
|
expect(album_sales.has_counter_diffs?).to eql true
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'should be able to set a counter using a number' do
|
18
|
-
album_sales = Test::
|
19
|
-
album_sales.
|
20
|
-
expect(album_sales.
|
18
|
+
album_sales = Test::AlbumStatistics.new
|
19
|
+
album_sales.sold = 2
|
20
|
+
expect(album_sales.sold.to_i).to eql 2
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'should be able to undo changes in a counter' do
|
24
|
-
album_sales = Test::
|
25
|
-
album_sales.
|
24
|
+
album_sales = Test::AlbumStatistics.new
|
25
|
+
album_sales.sold.incr
|
26
26
|
expect(album_sales.has_counter_diffs?).to eql true
|
27
|
-
album_sales.
|
27
|
+
album_sales.sold.undo_changes!
|
28
28
|
expect(album_sales.has_counter_diffs?).to eql false
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'should be able to reset a counter' do
|
32
32
|
album_attrs = {:artist_name => 'CSNY', :name => 'Deja vu'}
|
33
|
-
album_sales = Test::
|
34
|
-
album_sales.
|
35
|
-
|
33
|
+
album_sales = Test::AlbumStatistics.new(album_attrs)
|
34
|
+
album_sales.incr_counter!(:sold, 4)
|
35
|
+
|
36
|
+
album_sales = Test::AlbumStatistics.where(album_attrs).first
|
37
|
+
expect(album_sales.sold.value).to eql 4
|
38
|
+
album_sales.sold.reset!
|
36
39
|
album_sales.save
|
37
40
|
|
38
|
-
album_sales = Test::
|
39
|
-
expect(album_sales.
|
40
|
-
|
41
|
+
album_sales = Test::AlbumStatistics.where(album_attrs).first
|
42
|
+
expect(album_sales.sold.value).to eql 0
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should be able to reset all counters in one go' do
|
46
|
+
album_attrs = {:artist_name => 'CSNY', :name => 'Deja vu'}
|
47
|
+
album_sales = Test::AlbumStatistics.new(album_attrs)
|
48
|
+
album_sales.sold.incr(4)
|
49
|
+
album_sales.produced.incr(7)
|
50
|
+
expect(album_sales.has_counter_diffs?).to eql true
|
41
51
|
album_sales.save
|
42
52
|
|
43
|
-
album_sales = Test::
|
44
|
-
expect(album_sales.
|
53
|
+
album_sales = Test::AlbumStatistics.where(album_attrs).first
|
54
|
+
expect(album_sales.sold.value).to eql 4
|
55
|
+
expect(album_sales.produced.value).to eql 7
|
56
|
+
album_sales.reset_counters!
|
57
|
+
|
58
|
+
album_sales = Test::AlbumStatistics.where(album_attrs).first
|
59
|
+
expect(album_sales.sold.value).to eql 0
|
60
|
+
expect(album_sales.produced.value).to eql 0
|
45
61
|
end
|
46
62
|
|
47
63
|
it 'should be able to persist a counter value' do
|
48
|
-
album_sales = Test::
|
49
|
-
album_sales.
|
50
|
-
album_sales.
|
51
|
-
expect(album_sales.sales.value).to eql 1
|
64
|
+
album_sales = Test::AlbumStatistics.new(:artist_name => 'CSNY', :name => 'Deja vu')
|
65
|
+
album_sales.incr_counter!(:sold)
|
66
|
+
expect(album_sales.sold.value).to eql 1
|
52
67
|
|
53
|
-
album_sales = Test::
|
54
|
-
album_sales.
|
55
|
-
album_sales.save
|
68
|
+
album_sales = Test::AlbumStatistics.where(:artist_name => 'CSNY', :name => 'Deja vu').first
|
69
|
+
album_sales.incr_counter!(:sold)
|
56
70
|
|
57
|
-
album_sales = Test::
|
58
|
-
expect(album_sales.
|
71
|
+
album_sales = Test::AlbumStatistics.where(:artist_name => 'CSNY', :name => 'Deja vu').first
|
72
|
+
expect(album_sales.sold.value).to eql 2
|
59
73
|
end
|
60
74
|
|
61
75
|
end
|
@@ -6,8 +6,8 @@ describe Believer::Update do
|
|
6
6
|
Test::Artist.create(:name => 'Beatles', :label => 'Apple')
|
7
7
|
end
|
8
8
|
|
9
|
-
let :
|
10
|
-
Test::
|
9
|
+
let :album_statistics do
|
10
|
+
Test::AlbumStatistics.create(:artist_name => 'Beatles', :name => 'Revolver')
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should create statement based on hash" do
|
@@ -21,37 +21,36 @@ describe Believer::Update do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should create create a correct statement for a counter increment" do
|
24
|
-
|
25
|
-
update = Believer::Update.create(
|
26
|
-
expect(update.to_cql).to eql "UPDATE
|
24
|
+
album_statistics.sold.incr(2)
|
25
|
+
update = Believer::Update.create(album_statistics)
|
26
|
+
expect(update.to_cql).to eql "UPDATE album_statistics SET sold = sold + 2 WHERE artist_name = '#{album_statistics.artist_name}' AND name = '#{album_statistics.name}'"
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should create create a correct statement for a counter decrement" do
|
30
|
-
|
31
|
-
update = Believer::Update.create(
|
32
|
-
expect(update.to_cql).to eql "UPDATE
|
30
|
+
album_statistics.sold.decr(2)
|
31
|
+
update = Believer::Update.create(album_statistics)
|
32
|
+
expect(update.to_cql).to eql "UPDATE album_statistics SET sold = sold - 2 WHERE artist_name = '#{album_statistics.artist_name}' AND name = '#{album_statistics.name}'"
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should execute a counter change" do
|
36
|
-
cur_val =
|
37
|
-
|
38
|
-
update = Believer::Update.create(
|
36
|
+
cur_val = album_statistics.sold.to_i
|
37
|
+
album_statistics.sold.incr(2)
|
38
|
+
update = Believer::Update.create(album_statistics)
|
39
39
|
update.execute
|
40
|
-
|
41
|
-
expect(
|
40
|
+
cur_album_statistics = Test::AlbumStatistics.where(album_statistics.key_values).first
|
41
|
+
expect(cur_album_statistics.sold.to_i).to eql (cur_val + 2)
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should not execute if no changes are detected in any counter" do
|
45
|
-
cur_val =
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
update = Believer::Update.create(album_sales)
|
45
|
+
cur_val = album_statistics.reload!.sold.to_i
|
46
|
+
album_statistics.sold.incr(2)
|
47
|
+
album_statistics.sold.decr(2)
|
48
|
+
expect(album_statistics.sold.to_i).to eql cur_val
|
49
|
+
update = Believer::Update.create(album_statistics)
|
51
50
|
expect(update.execute).to eql false
|
52
51
|
|
53
|
-
|
54
|
-
expect(
|
52
|
+
cur_album_statistics = Test::AlbumStatistics.where(album_statistics.key_values).first
|
53
|
+
expect(cur_album_statistics.sold.to_i).to eql cur_val
|
55
54
|
end
|
56
55
|
|
57
56
|
it "should update the values" do
|
@@ -34,11 +34,12 @@ module Test
|
|
34
34
|
has_single :album, :class => 'Test::Album', :key => [:artist_name, :album_name], :foreign_key => [:artist_name, :name]
|
35
35
|
end
|
36
36
|
|
37
|
-
class
|
37
|
+
class AlbumStatistics < Believer::Base
|
38
38
|
column :artist_name
|
39
39
|
column :name
|
40
40
|
|
41
|
-
column :
|
41
|
+
column :sold, :type => :counter
|
42
|
+
column :produced, :type => :counter
|
42
43
|
|
43
44
|
primary_key :artist_name, :name
|
44
45
|
end
|
@@ -93,7 +94,7 @@ module Test
|
|
93
94
|
end
|
94
95
|
|
95
96
|
Believer::Base.environment = test_environment
|
96
|
-
CLASSES = [Artist, Album, Song,
|
97
|
+
CLASSES = [Artist, Album, Song, AlbumStatistics, Event, Person, Child]
|
97
98
|
#CLASSES.each {|cl| cl.environment = test_environment}
|
98
99
|
|
99
100
|
def self.classes
|