virsandra 0.5.0

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 (43) hide show
  1. data/LICENSE.txt +22 -0
  2. data/README.md +93 -0
  3. data/Rakefile +18 -0
  4. data/lib/virsandra.rb +89 -0
  5. data/lib/virsandra/configuration.rb +61 -0
  6. data/lib/virsandra/connection.rb +39 -0
  7. data/lib/virsandra/cql_value.rb +38 -0
  8. data/lib/virsandra/errors.rb +3 -0
  9. data/lib/virsandra/model.rb +86 -0
  10. data/lib/virsandra/model_query.rb +52 -0
  11. data/lib/virsandra/queries/add_query.rb +25 -0
  12. data/lib/virsandra/queries/alter_query.rb +34 -0
  13. data/lib/virsandra/queries/delete_query.rb +25 -0
  14. data/lib/virsandra/queries/insert_query.rb +34 -0
  15. data/lib/virsandra/queries/limit_query.rb +17 -0
  16. data/lib/virsandra/queries/order_query.rb +36 -0
  17. data/lib/virsandra/queries/select_query.rb +72 -0
  18. data/lib/virsandra/queries/table_query.rb +13 -0
  19. data/lib/virsandra/queries/values_query.rb +41 -0
  20. data/lib/virsandra/queries/where_query.rb +69 -0
  21. data/lib/virsandra/query.rb +87 -0
  22. data/lib/virsandra/version.rb +3 -0
  23. data/spec/feature_helper.rb +62 -0
  24. data/spec/integration/virsandra_spec.rb +13 -0
  25. data/spec/lib/virsandra/configuration_spec.rb +66 -0
  26. data/spec/lib/virsandra/connection_spec.rb +47 -0
  27. data/spec/lib/virsandra/cql_value_spec.rb +25 -0
  28. data/spec/lib/virsandra/model_query_spec.rb +58 -0
  29. data/spec/lib/virsandra/model_spec.rb +173 -0
  30. data/spec/lib/virsandra/queries/add_query_spec.rb +26 -0
  31. data/spec/lib/virsandra/queries/alter_query_spec.rb +35 -0
  32. data/spec/lib/virsandra/queries/delete_query_spec.rb +34 -0
  33. data/spec/lib/virsandra/queries/insert_query_spec.rb +36 -0
  34. data/spec/lib/virsandra/queries/limit_query_spec.rb +20 -0
  35. data/spec/lib/virsandra/queries/order_query_spec.rb +33 -0
  36. data/spec/lib/virsandra/queries/select_query_spec.rb +108 -0
  37. data/spec/lib/virsandra/queries/table_query_spec.rb +13 -0
  38. data/spec/lib/virsandra/queries/values_query_spec.rb +41 -0
  39. data/spec/lib/virsandra/queries/where_query_spec.rb +76 -0
  40. data/spec/lib/virsandra/query_spec.rb +117 -0
  41. data/spec/lib/virsandra_spec.rb +108 -0
  42. data/spec/spec_helper.rb +19 -0
  43. metadata +207 -0
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::AddQuery do
4
+ let(:column_name){ "new_column" }
5
+ let(:column_type){ nil }
6
+ subject(:query){ described_class.new(column_name, column_type) }
7
+
8
+ describe "#to_s" do
9
+ subject{ super().to_s }
10
+
11
+ it{ should eq("ADD new_column varchar") }
12
+
13
+ context "column type specified" do
14
+ let(:column_type){ "int" }
15
+
16
+ it{ should eq("ADD new_column int") }
17
+ end
18
+
19
+ context "column name not specified" do
20
+ let(:column_name){ nil }
21
+ it "should raise error" do
22
+ expect{ subject }.to raise_error(Virsandra::InvalidQuery, "You must specify column name")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::AlterQuery do
4
+ let(:skip_validation){ true }
5
+ subject(:query){ described_class.new(skip_validation) }
6
+
7
+ describe "#to_s" do
8
+ subject{ super().to_s }
9
+
10
+ it{ should eq("ALTER") }
11
+
12
+ end
13
+
14
+ describe "#table" do
15
+ subject{ super().table("foo").to_s }
16
+
17
+ it{ should eq("ALTER TABLE foo")}
18
+
19
+ context "with validation" do
20
+ let(:skip_validation){ false }
21
+
22
+ it "should raise error when table not specified" do
23
+ expect{ query.to_s }.to raise_error(Virsandra::InvalidQuery, "You must set the table")
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "#add" do
29
+ context "without column type" do
30
+ subject{ super().table("foo").add(:new_column).to_s }
31
+
32
+ it{ should eq("ALTER TABLE foo ADD new_column varchar")}
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::DeleteQuery do
4
+ subject(:query){ described_class.new }
5
+
6
+ its(:to_s){ should eq("DELETE") }
7
+
8
+ describe "#from" do
9
+ it "deletes from given table" do
10
+ query.from("foo")
11
+ query.to_s.should eq("DELETE FROM foo")
12
+ end
13
+
14
+ it "allows to use table as alias method" do
15
+ query.table("foo")
16
+ query.to_s.should eq("DELETE FROM foo")
17
+ end
18
+ end
19
+
20
+ describe "#where" do
21
+ it "adds given criteria to query" do
22
+ query.from("foo").where(id: "123")
23
+ query.to_s.should eq("DELETE FROM foo WHERE id = '123'")
24
+ end
25
+
26
+ context "called more than once" do
27
+ it "should join all wheres together" do
28
+ query.from("foo").where(id: 1)
29
+ query.where(count: {gt: 4})
30
+ query.to_s.should eq("DELETE FROM foo WHERE id = 1 AND count > 4")
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::InsertQuery do
4
+ subject(:query){ described_class.new }
5
+
6
+ describe "#into" do
7
+ subject{ super().into("foo") }
8
+
9
+ it "should raise error when values are missing" do
10
+ expect{ subject.to_s }.to raise_error(Virsandra::InvalidQuery, "You must set values")
11
+ end
12
+ end
13
+
14
+ describe "#values" do
15
+ subject{ super().values(column_name: "name") }
16
+
17
+ it "should raise error when into is missing" do
18
+ expect{ subject.to_s }.to raise_error(Virsandra::InvalidQuery, "You must set into")
19
+ end
20
+ end
21
+
22
+ describe "#to_s" do
23
+ context "when into is missing" do
24
+ it "should raise error when into is missing" do
25
+ expect{ query.to_s }.to raise_error(Virsandra::InvalidQuery, "You must set into")
26
+ end
27
+ end
28
+
29
+ context "when into and values are set" do
30
+ subject{ super().into("foo").values(id: 1, date: '2011-11-11').to_s }
31
+
32
+ it{ should eq("INSERT INTO foo (id, date) VALUES (1, '2011-11-11')") }
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::LimitQuery do
4
+ let(:number){ 4 }
5
+ subject{ described_class.new(number) }
6
+
7
+ describe "#to_s" do
8
+ subject{ super().to_s }
9
+
10
+ it{ should eq("LIMIT 4")}
11
+
12
+ context "when number is less than 1" do
13
+ let(:number){ 0 }
14
+
15
+ it "should raise error" do
16
+ expect{ subject }.to raise_error(Virsandra::InvalidQuery, "Limit must be positive number")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::OrderQuery do
4
+ let(:columns){ nil }
5
+ subject{ described_class.new(columns) }
6
+
7
+ describe "#to_s" do
8
+ subject{ super().to_s }
9
+
10
+ it{ should eq("") }
11
+
12
+ context "when columns given as string" do
13
+ let(:columns){ "date DESC" }
14
+
15
+ it{ should eq("ORDER BY date DESC")}
16
+ end
17
+
18
+ context "when columns given as hash" do
19
+ let(:columns){ {date: :asc, user_id: :asc} }
20
+
21
+ it{ should eq("ORDER BY date ASC, user_id ASC")}
22
+ end
23
+
24
+ context "when unknown order given" do
25
+ let(:columns){ {data: :bzz} }
26
+
27
+ it "raises an error" do
28
+ expect{ subject }.to raise_error(Virsandra::InvalidQuery, "Unknown order bzz")
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::SelectQuery do
4
+ let(:columns){ nil }
5
+ let(:skip_validation){ true }
6
+ let(:query){ described_class.new(columns, skip_validation) }
7
+ subject{ query }
8
+
9
+ it "uses * as default columns" do
10
+ subject.to_s.should eq("SELECT *")
11
+ end
12
+
13
+ context "empty array given as columns" do
14
+ let(:columns){ [] }
15
+ it "uses * as default columns" do
16
+ subject.to_s.should eq("SELECT *")
17
+ end
18
+ end
19
+
20
+ context "when columns are given" do
21
+ subject{ super().to_s }
22
+
23
+ let(:columns){ "id, date" }
24
+
25
+ it{ should eq("SELECT id, date")}
26
+
27
+ context "when columns are array" do
28
+ let(:columns){ ['id', 'date'] }
29
+
30
+ it{ should eq("SELECT id, date")}
31
+ end
32
+ end
33
+
34
+ describe "#from" do
35
+ subject{ super().from("foo").to_s }
36
+
37
+ it{ should eq("SELECT * FROM foo")}
38
+ end
39
+
40
+ describe "#where" do
41
+ subject{ super().from("foo").where(id: 1).to_s }
42
+
43
+ it{ should eq("SELECT * FROM foo WHERE id = 1")}
44
+
45
+ context "called more than once" do
46
+ it "should join all wheres together" do
47
+ query.from("foo").where(id: 1)
48
+ query.where(count: {gt: 4})
49
+ query.to_s.should eq("SELECT * FROM foo WHERE id = 1 AND count > 4")
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "#order" do
55
+ subject{ super().from("foo").order(date: "asc").to_s }
56
+
57
+ it{ should eq("SELECT * FROM foo ORDER BY date ASC")}
58
+ end
59
+
60
+ describe "#limit" do
61
+ subject{ super().from("foo").limit(3).to_s }
62
+
63
+ it{ should eq("SELECT * FROM foo LIMIT 3")}
64
+
65
+ context "when called more than once" do
66
+ it "uses only last one" do
67
+ query.from("foo").limit(1)
68
+ query.limit(4)
69
+ query.to_s.should eq("SELECT * FROM foo LIMIT 4")
70
+ end
71
+ end
72
+ end
73
+
74
+ describe "#reset" do
75
+ subject{ super().from("foo").where(id: 1) }
76
+
77
+ it "should reset query" do
78
+ subject.to_s.should eq("SELECT * FROM foo WHERE id = 1")
79
+ subject.reset
80
+ subject.where(date: "2011-11-11")
81
+ subject.to_s.should eq("SELECT * FROM foo WHERE date = '2011-11-11'")
82
+ end
83
+ end
84
+
85
+ describe "#to_s" do
86
+ let(:skip_validation){ false }
87
+ it "should validate from existence" do
88
+ expect{ query.to_s }.to raise_error(Virsandra::InvalidQuery, "You must set from")
89
+ end
90
+ end
91
+
92
+ describe "#allow_filtering!" do
93
+ subject{ super().from("foo").where(id: 1).allow_filtering!.to_s }
94
+
95
+ it{ should eq("SELECT * FROM foo WHERE id = 1 ALLOW FILTERING")}
96
+ end
97
+
98
+ describe "#deny_filtering!" do
99
+ subject{ super().from("foo").where(id: 1) }
100
+
101
+ it "should remove allow filtering clause" do
102
+ subject.allow_filtering!
103
+ subject.to_s.should eq("SELECT * FROM foo WHERE id = 1 ALLOW FILTERING")
104
+ subject.deny_filtering!
105
+ subject.to_s.should eq("SELECT * FROM foo WHERE id = 1")
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::TableQuery do
4
+ describe "#to_s" do
5
+ it "return given table name" do
6
+ described_class.new("FROM", "foo").to_s.should eq("FROM foo")
7
+ end
8
+
9
+ it "return empty string when nil given" do
10
+ described_class.new("FROM",nil).to_s.should eq("")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::ValuesQuery do
4
+ let(:values){ {} }
5
+ subject(:query){ described_class.new(values) }
6
+
7
+ describe "#to_s" do
8
+ subject{ super().to_s }
9
+
10
+ it{ should eq("") }
11
+
12
+ context "when values given" do
13
+ let(:values){ {id: 1, date: '2011-11-11'} }
14
+
15
+ it{ should eq("(id, date) VALUES (1, '2011-11-11')")}
16
+
17
+ it "should convert each value" do
18
+ Virsandra::CQLValue.should_receive(:convert).twice
19
+ subject
20
+ end
21
+ end
22
+
23
+ context "when any value is nil" do
24
+ let(:values){ {id: 1, date: nil} }
25
+
26
+ it{ should eq("(id) VALUES (1)")}
27
+ end
28
+
29
+ context "when all values are nil" do
30
+ let(:values){ {id: nil, date: nil} }
31
+
32
+ it{ should eq("")}
33
+ end
34
+
35
+ context "when values is something else than hash" do
36
+ let(:values){ [] }
37
+
38
+ it{ should eq("") }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::WhereQuery do
4
+ subject(:query){ described_class.new(clause) }
5
+
6
+ describe "#+" do
7
+ let(:clause){ {id: [1,2]} }
8
+ let(:other_query){ described_class.new(other_clause) }
9
+ let(:other_clause){ {count: {lt_or_eq: 4}} }
10
+
11
+ it "merge both where clauses with AND" do
12
+ (query + other_query).should eq("WHERE id IN (1, 2) AND count <= 4")
13
+ end
14
+
15
+ it "should raise error when something else than WhereQuery is given" do
16
+ expect{ query + 1}.to raise_error(Virsandra::InvalidQuery, "WhereQuery can be mereged only with other WhereQuery")
17
+ end
18
+ end
19
+
20
+ describe "#to_s" do
21
+ subject{ super().to_s }
22
+
23
+ context "when clause given as string" do
24
+ let(:clause){ "id='1' AND count=6" }
25
+
26
+ it{ should eq("WHERE id='1' AND count=6")}
27
+ end
28
+
29
+ context "when clause given as hash" do
30
+ let(:clause){ {id: '1', count: 6} }
31
+
32
+ it{ should eq("WHERE id = '1' AND count = 6")}
33
+
34
+ it "should convert each value" do
35
+ Virsandra::CQLValue.should_receive(:convert).twice
36
+ subject
37
+ end
38
+ end
39
+
40
+
41
+ described_class::OPERATOR_MAPPING.reject{|key,value| key == :in}.each do |operator_name, operator|
42
+ context "when any clause value given as hash" do
43
+ let(:clause){ {id: '1', count: Hash[operator_name, 6]} }
44
+
45
+ it{ should eq("WHERE id = '1' AND count #{operator} 6") }
46
+
47
+ it "should convert each value" do
48
+ Virsandra::CQLValue.should_receive(:convert).twice
49
+ subject
50
+ end
51
+ end
52
+ end
53
+
54
+ context "when any clause value given as hash and hash key is :in" do
55
+ let(:clause){ {id: '1', count: {:in => 6}} }
56
+
57
+ it{ should eq("WHERE id = '1' AND count IN (6)")}
58
+
59
+ it "should convert each value" do
60
+ Virsandra::CQLValue.should_receive(:convert).twice
61
+ subject
62
+ end
63
+ end
64
+
65
+ context "when any clause value given as array" do
66
+ let(:clause){ {id: '1', count: [2,3]} }
67
+
68
+ it{ should eq("WHERE id = '1' AND count IN (2, 3)") }
69
+
70
+ it "should convert each value" do
71
+ Virsandra::CQLValue.should_receive(:convert).exactly(3).times
72
+ subject
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virsandra::Query do
4
+
5
+ [:from, :table, :into, :where, :order, :limit, :add, :values].each do |method_name|
6
+ it "should raise error when #{method_name} called" do
7
+ expect{ described_class.new.send(method_name) }.to raise_error(Virsandra::InvalidQuery )
8
+ end
9
+ end
10
+
11
+ it "should return empty hash when can't fetch hash from results" do
12
+ Virsandra.stub(:execute => double("row", :first => nil))
13
+ described_class.new.fetch.should eq({})
14
+ end
15
+
16
+ it "should return empty hash when results are not available" do
17
+ Virsandra.stub(:execute => nil )
18
+ described_class.new.fetch.should eq({})
19
+ end
20
+
21
+ it "adds a from method" do
22
+ q = Virsandra::Query.select.from(:foo)
23
+ q.to_s.should == "SELECT * FROM foo"
24
+
25
+ q = Virsandra::Query.insert.into(:foo).values(id: 1)
26
+ q.to_s.should == "INSERT INTO foo (id) VALUES (1)"
27
+
28
+ q = Virsandra::Query.delete.from(:foo)
29
+ q.to_s.should == "DELETE FROM foo"
30
+
31
+ q = Virsandra::Query.alter.table(:foo)
32
+ q.to_s.should == "ALTER TABLE foo"
33
+ end
34
+
35
+ it "can change the table" do
36
+ q = Virsandra::Query.insert.into(:foo).values(id: 1)
37
+
38
+ q.into(:bar)
39
+ q.to_s.should == "INSERT INTO bar (id) VALUES (1)"
40
+ end
41
+
42
+ it "adds a where clause when appropriate" do
43
+ q = Virsandra::Query.select.from(:foo).where(id: 'Funky', location: 'town')
44
+ q.to_s.should == "SELECT * FROM foo WHERE id = 'Funky' AND location = 'town'"
45
+
46
+ q.reset
47
+ q.where(can: "change options")
48
+ q.to_s.should == "SELECT * FROM foo WHERE can = 'change options'"
49
+
50
+ uuid = SimpleUUID::UUID.new
51
+ uuid.stub(to_guid: 'i-am-a-guid')
52
+
53
+ q.reset
54
+ q.where(cid: uuid, nummer: 123)
55
+ q.to_s.should == "SELECT * FROM foo WHERE cid = i-am-a-guid AND nummer = 123"
56
+
57
+ expect {
58
+ Virsandra::Query.insert.into(:foo).where(id: 1)
59
+ }.to raise_error(Virsandra::InvalidQuery)
60
+ end
61
+
62
+ it "can add values to an insert statement" do
63
+ q = Virsandra::Query.insert.into(:foo).values(id: 93, comment: "Stuff!")
64
+ q.to_s.should == "INSERT INTO foo (id, comment) VALUES (93, 'Stuff!')"
65
+
66
+ uuid = SimpleUUID::UUID.new
67
+ uuid.stub(to_guid: 'i-am-a-guid')
68
+
69
+ q.values(fun: 'time', lol: 'who', uuidz: uuid)
70
+ q.to_s.should == "INSERT INTO foo (fun, lol, uuidz) VALUES ('time', 'who', i-am-a-guid)"
71
+
72
+ expect {
73
+ Virsandra::Query.select.from(:foo).values(id: 1)
74
+ }.to raise_error(Virsandra::InvalidQuery)
75
+ end
76
+
77
+ it "alters the table" do
78
+ query = Virsandra::Query.alter.table(:foo).add(:name)
79
+ query.to_s.should == "ALTER TABLE foo ADD name varchar"
80
+
81
+ query.add(:patents, :integer)
82
+ query.to_s.should == "ALTER TABLE foo ADD patents integer"
83
+
84
+ expect {
85
+ Virsandra::Query.select.from(:foo).add(:funky)
86
+ }.to raise_error(Virsandra::InvalidQuery)
87
+
88
+ end
89
+
90
+ it "executes the query" do
91
+ q = Virsandra::Query.select.from(:foo).where({:id => 123, :name => "Funky"})
92
+
93
+ Virsandra.should_receive(:execute).
94
+ with("SELECT * FROM foo WHERE id = 123 AND name = 'Funky'")
95
+
96
+ q.execute
97
+ end
98
+
99
+ it "can fetch the row with symbolized keys" do
100
+ query = Virsandra::Query.select.from(:foo).where({:id => "0123", :name => "Funky"})
101
+
102
+ query.should_receive(:execute)
103
+ query.should_receive(:fetch_with_symbolized_keys)
104
+ query.fetch
105
+ end
106
+
107
+
108
+ it "can fetch a raw query" do
109
+ cql = "SELECT * FROM cities WHERE town = 'funky'"
110
+ query = Virsandra::Query.new
111
+
112
+ Virsandra.should_receive(:execute).with(cql)
113
+
114
+ query.fetch(cql)
115
+ end
116
+
117
+ end