believer 0.2.5 → 0.2.6

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.
Files changed (42) hide show
  1. data/README.md +29 -2
  2. data/lib/believer.rb +5 -0
  3. data/lib/believer/base.rb +16 -4
  4. data/lib/believer/column.rb +74 -9
  5. data/lib/believer/columns.rb +18 -1
  6. data/lib/believer/command.rb +12 -1
  7. data/lib/believer/counter.rb +60 -0
  8. data/lib/believer/counting.rb +29 -0
  9. data/lib/believer/cql_helper.rb +22 -0
  10. data/lib/believer/create_table.rb +24 -0
  11. data/lib/believer/ddl.rb +2 -31
  12. data/lib/believer/drop_table.rb +9 -0
  13. data/lib/believer/environment/base_env.rb +5 -0
  14. data/lib/believer/insert.rb +3 -1
  15. data/lib/believer/persistence.rb +18 -2
  16. data/lib/believer/update.rb +52 -0
  17. data/lib/believer/values.rb +67 -0
  18. data/lib/believer/version.rb +1 -1
  19. data/spec/believer/base_spec.rb +9 -2
  20. data/spec/believer/callback_spec.rb +1 -1
  21. data/spec/believer/collection_columns_spec.rb +95 -0
  22. data/spec/believer/columns_spec.rb +21 -0
  23. data/spec/believer/counter_spec.rb +46 -0
  24. data/spec/believer/counting_spec.rb +31 -0
  25. data/spec/believer/delete_spec.rb +1 -1
  26. data/spec/believer/environment_spec.rb +4 -4
  27. data/spec/believer/finder_methods_spec.rb +9 -9
  28. data/spec/believer/insert_spec.rb +1 -1
  29. data/spec/believer/limit_spec.rb +1 -1
  30. data/spec/believer/order_by_spec.rb +2 -2
  31. data/spec/believer/query_spec.rb +2 -2
  32. data/spec/believer/querying_spec.rb +1 -1
  33. data/spec/believer/relation_spec.rb +6 -6
  34. data/spec/believer/test_run_life_cycle_spec.rb +2 -2
  35. data/spec/believer/time_series_spec.rb +23 -3
  36. data/spec/believer/update_spec.rb +71 -0
  37. data/spec/believer/where_spec.rb +4 -4
  38. data/spec/spec_helper.rb +6 -2
  39. data/spec/support/setup_database.rb +8 -8
  40. data/spec/support/test_classes.rb +22 -5
  41. metadata +17 -19
  42. data/lib/believer/extensions/will_paginate.rb +0 -173
@@ -6,42 +6,13 @@ module Believer
6
6
  module ClassMethods
7
7
 
8
8
  def drop_table
9
- connection_pool.with do |connection|
10
- cql = "DROP TABLE #{table_name}"
11
- ActiveSupport::Notifications.instrument('ddl.believer', :class => self, :cql => cql, :method => :drop) do
12
- connection.execute(cql)
13
- end
14
- end
9
+ ::Believer::DropTable.new(:record_class => self).execute
15
10
  end
16
11
 
17
12
  def create_table
18
- connection_pool.with do |connection|
19
- cql = create_table_cql
20
- ActiveSupport::Notifications.instrument('ddl.believer', :class => self, :cql => cql, :method => :create) do
21
- connection.execute(cql)
22
- end
23
- end
13
+ ::Believer::CreateTable.new(:record_class => self).execute
24
14
  end
25
15
 
26
- def create_table_cql
27
-
28
- keys = []
29
- get_primary_key.each do |key_part|
30
- if key_part.is_a?(Enumerable)
31
- keys << "(#{key_part.join(',')})"
32
- else
33
- keys << key_part
34
- end
35
- end
36
-
37
- s = "CREATE TABLE #{table_name} (\n"
38
- col_statement_parts = columns.keys.map {|col| "#{col} #{columns[col].cql_type}"}
39
- s << col_statement_parts.join(",\n")
40
- s << ",\n"
41
- s << "PRIMARY KEY (#{keys.join(',')})"
42
- s << "\n)"
43
- s
44
- end
45
16
  end
46
17
 
47
18
  end
@@ -0,0 +1,9 @@
1
+ module Believer
2
+ class DropTable < Command
3
+
4
+ def to_cql
5
+ "DROP TABLE #{record_class.table_name}"
6
+ end
7
+
8
+ end
9
+ end
@@ -77,6 +77,11 @@ module Believer
77
77
  connection
78
78
  end
79
79
 
80
+ def drop_keyspace
81
+ conn = create_connection(:connect_to_keyspace => false)
82
+ conn.execute("DROP KEYSPACE #{connection_configuration[:keyspace]}")
83
+ end
84
+
80
85
  def create_keyspace(properties = {}, connection = nil)
81
86
  conn = connection || create_connection(:connect_to_keyspace => false)
82
87
 
@@ -11,7 +11,9 @@ module Believer
11
11
 
12
12
  def to_cql
13
13
  attrs = @values.keys
14
- "INSERT INTO #{@record_class.table_name} (#{attrs.join(', ')}) VALUES (#{attrs.map {|a| to_cql_literal(@values[a]) }.join(', ')})"
14
+ cols_def = "#{attrs.join(', ')}"
15
+ vals_defs = attrs.map { |a| to_cql_literal(@values[a]) }.join(', ')
16
+ "INSERT INTO #{@record_class.table_name} (#{cols_def}) VALUES (#{vals_defs})"
15
17
  end
16
18
  end
17
19
 
@@ -24,12 +24,28 @@ module Believer
24
24
 
25
25
  # Saves the model.
26
26
  def save
27
- Insert.new(:record_class => self.class, :values => self).execute
27
+ if persisted? || is_counter_instance?
28
+ Update.create(self).execute
29
+ else
30
+ Insert.new(:record_class => self.class, :values => self).execute
31
+ end
32
+ persisted!
33
+ self
28
34
  end
29
35
 
30
36
  # Destroys the model.
31
37
  def destroy
32
- Delete.new(:record_class => self.class).where(key_values).execute
38
+ res = Delete.new(:record_class => self.class).where(key_values).execute
39
+ @persisted = false
40
+ res
41
+ end
42
+
43
+ def persisted!
44
+ @persisted = true
45
+ end
46
+
47
+ def persisted?
48
+ @persisted == true
33
49
  end
34
50
 
35
51
  end
@@ -0,0 +1,52 @@
1
+ module Believer
2
+ class Update < FilterCommand
3
+ include CqlHelper
4
+
5
+ attr_accessor :values
6
+
7
+ def self.create(object)
8
+ pk_cols = object.class.primary_key_columns
9
+ pk_values = object.attributes.delete_if {|k, v| !pk_cols.include?(k)}
10
+
11
+ update = new(:record_class => object.class, :values => object.attributes)
12
+ update.where(pk_values)
13
+ end
14
+
15
+ def query_attributes
16
+ attrs = super
17
+ attrs.merge(:values => (values.dup))
18
+ end
19
+
20
+ def values=(v)
21
+ pk_cols = record_class.primary_key_columns
22
+ vals = v.is_a?(Base) ? v.attributes : v.to_hash
23
+ @values = vals.dup.delete_if {|k, v| pk_cols.include?(k)}
24
+ end
25
+
26
+ def can_execute?
27
+ if record_class.is_counter_table?
28
+ mock_instance = record_class.new(values)
29
+ return mock_instance.has_counter_diffs?
30
+ end
31
+ true
32
+ end
33
+
34
+ def to_cql
35
+ cql = "UPDATE #{record_class.table_name} SET "
36
+ cql << values.keys.map {|col| assign_statement(col, values[col]) }.flatten.join(', ')
37
+ cql << " WHERE #{wheres.map { |wc| "#{wc.to_cql}" }.join(' AND ')}" if wheres.any?
38
+ cql
39
+ end
40
+
41
+ def assign_statement(col_name, val)
42
+ column = record_class.columns[col_name]
43
+ if column.ruby_type == :counter
44
+ return nil if val.nil?
45
+ operator = val.incremented? ? '+' : '-'
46
+ return "#{col_name} = #{col_name} #{operator} #{val.diff}"
47
+ end
48
+ "#{col_name} = #{to_cql_literal(val)}"
49
+ end
50
+
51
+ end
52
+ end
@@ -1,7 +1,28 @@
1
+ require 'set'
2
+
1
3
  module Believer
2
4
 
3
5
  module Values
4
6
 
7
+ # Converts the value to a one that conforms to the type of this column
8
+ # @param v [Object] the value
9
+ # @param value_type [Symbol] value type
10
+ def convert_value_to_type(v, value_type)
11
+ meth = convert_method(value_type)
12
+ return send(meth, v) if respond_to?(meth)
13
+ v
14
+ end
15
+
16
+ def convert_method(value_type)
17
+ return nil if value_type.nil?
18
+ "convert_to_#{value_type}".to_sym
19
+ end
20
+
21
+ def convert_to_string(v)
22
+ return v.to_s unless v.nil?
23
+ nil
24
+ end
25
+
5
26
  def convert_to_integer(v)
6
27
  return v.to_i unless v.nil?
7
28
  nil
@@ -26,6 +47,52 @@ module Believer
26
47
  Time.at(v.to_i)
27
48
  end
28
49
 
50
+ def convert_to_symbol(v)
51
+ return nil if v.nil?
52
+ return v.to_sym
53
+ end
54
+
55
+ def convert_to_counter(v)
56
+ return nil if v.nil?
57
+ return v if v.is_a?(Counter)
58
+ Counter.new(v.to_i)
59
+ end
60
+
61
+ def convert_to_array(v, element_type = nil)
62
+ return nil if v.nil?
63
+ arr = v.is_a?(Array) ? v : Array.new(v)
64
+ convert_collection_elements(arr, element_type)
65
+ end
66
+
67
+ def convert_to_set(v, element_type = nil)
68
+ return nil if v.nil?
69
+ s = v.is_a?(Set) ? v : Set.new(v)
70
+ Set.new(convert_collection_elements(s, element_type))
71
+ end
72
+
73
+ def convert_collection_elements(col, element_type = nil)
74
+ return col if element_type.nil?
75
+ meth = convert_method(element_type)
76
+ col.map {|el| send(meth, el)}
77
+ end
78
+
79
+ def convert_to_hash(v, key_type = nil, value_type = nil)
80
+ return nil if v.nil?
81
+ hash = v.is_a?(Hash) ? v : Hash.new(v)
82
+ unless key_type.nil? && value_type.nil?
83
+ key_conv_meth = convert_method(key_type)
84
+ val_conv_meth = convert_method(value_type)
85
+ hash_conv = {}
86
+ hash.each do |key, value|
87
+ key_conv = key_conv_meth.nil? ? key : send(key_conv_meth, key)
88
+ value_conv = val_conv_meth.nil? ? value : send(val_conv_meth, value)
89
+ hash_conv[key_conv] = value_conv
90
+ end
91
+ return hash_conv
92
+ end
93
+ hash
94
+ end
95
+
29
96
  end
30
97
 
31
98
  end
@@ -1,5 +1,5 @@
1
1
  module Believer
2
2
  module Version
3
- VERSION = '0.2.5'
3
+ VERSION = '0.2.6'
4
4
  end
5
5
  end
@@ -2,9 +2,16 @@ require 'spec_helper'
2
2
 
3
3
  describe Believer::Base do
4
4
 
5
- it 'equality' do
5
+ it 'should implement equality' do
6
6
  a1 = Test::Artist.new(:name => 'Level 42')
7
7
  a2 = Test::Artist.new(:name => 'Level 42', :label => 'Epic')
8
- a1.should == a2
8
+ expect(a1).to eql(a2)
9
9
  end
10
+
11
+ it 'should be able to reload itself' do
12
+ artist = Test::Artist.create(:name => 'Level 42', :label => 'Epic')
13
+ artist.label = 'Apple'
14
+ expect(artist.reload!.label).to eql('Epic')
15
+ end
16
+
10
17
  end
@@ -17,7 +17,7 @@ describe Believer::Callbacks do
17
17
  })
18
18
  object.send(method)
19
19
 
20
- called.should == true
20
+ expect(called).to eql(true)
21
21
  end
22
22
  end
23
23
  end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Collection columns' do
4
+
5
+ before :each do
6
+ @marbles = Set.new [:red, :green, :red]
7
+ @soccer_cards = ['Messi', 'Ronaldo', 'Pele']
8
+ @family = {:father => 'Fred', :mother => 'Tina', :sister => 'Emily'}
9
+ @children = Test::Child.create(:name => 'Johnny', :marbles => @marbles, :family => @family, :soccer_cards => @soccer_cards)
10
+ end
11
+
12
+ it 'should load a set' do
13
+ johnny = Test::Child.where(:name => 'Johnny').first
14
+ expect(johnny.marbles.size).to eql(@marbles.size)
15
+ @marbles.each do |m|
16
+ expect(johnny.marbles).to include(m)
17
+ end
18
+ end
19
+
20
+ it 'should be able to add to a set' do
21
+ johnny = Test::Child.where(:name => 'Johnny').first
22
+ johnny.marbles << :yellow
23
+ johnny.save
24
+
25
+ johnny = Test::Child.where(:name => 'Johnny').first
26
+ expect(johnny.marbles.size).to eql(@marbles.size + 1)
27
+ expect(johnny.marbles).to include(:yellow)
28
+ end
29
+
30
+ it 'should be able to remove from a set' do
31
+ johnny = Test::Child.where(:name => 'Johnny').first
32
+ johnny.marbles.delete(:red)
33
+ johnny.save
34
+
35
+ johnny = Test::Child.where(:name => 'Johnny').first
36
+ expect(johnny.marbles.size).to eql(@marbles.size - 1)
37
+ expect(johnny.marbles).not_to include(:red)
38
+ end
39
+
40
+ it 'should load a list' do
41
+ johnny = Test::Child.where(:name => 'Johnny').first
42
+ expect(johnny.soccer_cards.size).to eql(@soccer_cards.size)
43
+ @soccer_cards.each do |m|
44
+ expect(johnny.soccer_cards).to include(m)
45
+ end
46
+ end
47
+
48
+ it 'should be able to add to a list' do
49
+ johnny = Test::Child.where(:name => 'Johnny').first
50
+ johnny.soccer_cards << 'Neymar'
51
+ johnny.save
52
+
53
+ johnny = Test::Child.where(:name => 'Johnny').first
54
+ expect(johnny.soccer_cards.size).to eql(@soccer_cards.size + 1)
55
+ expect(johnny.soccer_cards).to include('Neymar')
56
+ end
57
+
58
+ it 'should be able to remove from a set' do
59
+ johnny = Test::Child.where(:name => 'Johnny').first
60
+ johnny.soccer_cards.delete('Messi')
61
+ johnny.save
62
+
63
+ johnny = Test::Child.where(:name => 'Johnny').first
64
+ expect(johnny.soccer_cards.size).to eql(@soccer_cards.size - 1)
65
+ expect(johnny.soccer_cards).not_to include('Messi')
66
+ end
67
+
68
+ it 'should load a map' do
69
+ johnny = Test::Child.where(:name => 'Johnny').first
70
+ expect(johnny.family.size).to eql(@family.size)
71
+ @family.each do |k, v|
72
+ expect(johnny.family.keys).to include(k)
73
+ expect(johnny.family[k]).to eql(v)
74
+ end
75
+ end
76
+
77
+ it 'should be able to add to a map' do
78
+ johnny = Test::Child.where(:name => 'Johnny').first
79
+ johnny.family[:brother] = 'Brad'
80
+ johnny.save
81
+
82
+ johnny = Test::Child.where(:name => 'Johnny').first
83
+ expect(johnny.family[:brother]).to eql('Brad')
84
+ end
85
+
86
+ it 'should be able to remove from a map' do
87
+ johnny = Test::Child.where(:name => 'Johnny').first
88
+ johnny.family.delete(:sister)
89
+ johnny.save
90
+
91
+ johnny = Test::Child.where(:name => 'Johnny').first
92
+ expect(johnny.family.has_key?(:sister)).to eql(false)
93
+ end
94
+
95
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Believer::Columns do
4
+
5
+ it 'should be able to find columns with type' do
6
+ cols = Test::Song.columns
7
+ expect(cols.size).to eql 5
8
+ end
9
+
10
+ it 'should be able to find columns with type' do
11
+ int_cols = Test::Song.columns_with_type(:integer)
12
+ expect(int_cols).to eql [Test::Song.columns[:track_number]]
13
+
14
+ string_cols = Test::Song.columns_with_type(:string)
15
+ expect(string_cols.size).to eql 4
16
+
17
+ counter_cols = Test::AlbumSales.columns_with_type(:counter)
18
+ expect(counter_cols).to eql [Test::AlbumSales.columns[:sales]]
19
+ end
20
+
21
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Believer::Counter do
4
+
5
+ it 'should have a default initial value' do
6
+ c = Believer::Counter.new(3)
7
+ expect(c.initial_value).to eql 3
8
+ end
9
+
10
+ it 'should increment' do
11
+ c = Believer::Counter.new(3)
12
+ c.incr
13
+ expect(c.initial_value).to eql 3
14
+ expect(c.to_i).to eql 4
15
+ end
16
+
17
+ it 'should decrement' do
18
+ c = Believer::Counter.new(3)
19
+ c.decr
20
+ expect(c.initial_value).to eql 3
21
+ expect(c.to_i).to eql 2
22
+ end
23
+
24
+ it 'should adopt a number value' do
25
+ c = Believer::Counter.new(3)
26
+ c.adopt_value(4)
27
+ expect(c.initial_value).to eql 3
28
+ expect(c.to_i).to eql 4
29
+ end
30
+
31
+ it 'should adopt a counter value' do
32
+ c = Believer::Counter.new(3)
33
+ c.adopt_value(Believer::Counter.new(4))
34
+ expect(c.initial_value).to eql 3
35
+ expect(c.to_i).to eql 4
36
+ end
37
+
38
+ it 'should adopt a nil value' do
39
+ c = Believer::Counter.new(3)
40
+ c.adopt_value(nil)
41
+ expect(c.initial_value).to eql 3
42
+ expect(c.to_i).to eql 0
43
+ end
44
+
45
+
46
+ end