believer 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
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