cassanity 0.6.0.beta5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/doc/Migrations.md +4 -15
  4. data/examples/collections.rb +82 -0
  5. data/lib/cassanity.rb +54 -0
  6. data/lib/cassanity/addition.rb +15 -0
  7. data/lib/cassanity/argument_generators/batch.rb +8 -1
  8. data/lib/cassanity/argument_generators/column_family_create.rb +11 -1
  9. data/lib/cassanity/argument_generators/column_family_delete.rb +19 -4
  10. data/lib/cassanity/argument_generators/keyspace_create.rb +5 -1
  11. data/lib/cassanity/argument_generators/set_clause.rb +4 -1
  12. data/lib/cassanity/collection_item.rb +39 -0
  13. data/lib/cassanity/removal.rb +15 -0
  14. data/lib/cassanity/schema.rb +5 -2
  15. data/lib/cassanity/set_addition.rb +16 -0
  16. data/lib/cassanity/set_removal.rb +16 -0
  17. data/lib/cassanity/statement.rb +4 -1
  18. data/lib/cassanity/version.rb +1 -1
  19. data/spec/unit/cassanity/addition_spec.rb +80 -0
  20. data/spec/unit/cassanity/argument_generators/batch_spec.rb +45 -0
  21. data/spec/unit/cassanity/argument_generators/column_family_create_spec.rb +20 -0
  22. data/spec/unit/cassanity/argument_generators/column_family_delete_spec.rb +42 -0
  23. data/spec/unit/cassanity/argument_generators/keyspace_create_spec.rb +11 -0
  24. data/spec/unit/cassanity/argument_generators/set_clause_spec.rb +35 -0
  25. data/spec/unit/cassanity/collection_item_spec.rb +84 -0
  26. data/spec/unit/cassanity/removal_spec.rb +80 -0
  27. data/spec/unit/cassanity/schema_spec.rb +49 -0
  28. data/spec/unit/cassanity/set_addition_spec.rb +80 -0
  29. data/spec/unit/cassanity/set_removal_spec.rb +80 -0
  30. data/spec/unit/cassanity/statement_spec.rb +9 -2
  31. data/spec/unit/cassanity_spec.rb +42 -0
  32. metadata +31 -15
@@ -1,5 +1,6 @@
1
1
  require 'bigdecimal'
2
2
  require 'date'
3
+ require 'set'
3
4
  require 'time'
4
5
 
5
6
  module Cassanity
@@ -19,7 +20,9 @@ module Cassanity
19
20
  private
20
21
  def quote(var)
21
22
  if Array === var
22
- var.map { |v| quote(v) }.join(',')
23
+ %([#{var.map { |v| "#{quote(v)}" }.join(',')}])
24
+ elsif Set === var
25
+ %({#{var.map { |v| "#{quote(v)}" }.join(',')}})
23
26
  elsif Hash === var
24
27
  %({#{var.map { |k, v| "#{quote(k)}:#{quote(v)}" }.join(',')}})
25
28
  elsif String === var
@@ -1,3 +1,3 @@
1
1
  module Cassanity
2
- VERSION = "0.6.0.beta5"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -0,0 +1,80 @@
1
+ require 'helper'
2
+ require 'cassanity/addition'
3
+
4
+ describe Cassanity::Addition do
5
+ describe "self named helper method" do
6
+ it "returns instance" do
7
+ Cassanity::Addition('foo').should eq(described_class.new('foo'))
8
+ end
9
+ end
10
+
11
+ describe "#initialize" do
12
+ context "with value" do
13
+ before do
14
+ @instance = described_class.new('foo')
15
+ end
16
+
17
+ it "sets value" do
18
+ @instance.value.should eq(['foo'])
19
+ end
20
+
21
+ it "sets symbol" do
22
+ @instance.symbol.should be(:+)
23
+ end
24
+ end
25
+
26
+ context "with multiples values" do
27
+ before do
28
+ @instance = described_class.new('foo', 'bar')
29
+ end
30
+
31
+ it "sets values" do
32
+ @instance.value.should eq(['foo', 'bar'])
33
+ end
34
+ end
35
+
36
+ context "without value" do
37
+ it "raises error" do
38
+ expect {
39
+ subject.value
40
+ }.to raise_error(ArgumentError, "value cannot be nil")
41
+ end
42
+ end
43
+
44
+ context "with nil" do
45
+ it "raises error" do
46
+ expect {
47
+ described_class.new(nil)
48
+ }.to raise_error(ArgumentError, "value cannot be nil")
49
+ end
50
+ end
51
+ end
52
+
53
+ shared_examples_for "addition equality" do |method_name|
54
+ it "returns true for same class and value" do
55
+ instance = described_class.new('foo')
56
+ other = described_class.new('foo')
57
+ instance.send(method_name, other).should be_true
58
+ end
59
+
60
+ it "returns false for same class and different value" do
61
+ instance = described_class.new('foo')
62
+ other = described_class.new('bar')
63
+ instance.send(method_name, other).should be_false
64
+ end
65
+
66
+ it "returns false for different class" do
67
+ instance = described_class.new('foo')
68
+ other = Object.new
69
+ instance.send(method_name, other).should be_false
70
+ end
71
+ end
72
+
73
+ describe "#eql?" do
74
+ include_examples "addition equality", :eql?
75
+ end
76
+
77
+ describe "#==" do
78
+ include_examples "addition equality", :==
79
+ end
80
+ end
@@ -80,5 +80,50 @@ describe Cassanity::ArgumentGenerators::Batch do
80
80
  }).should eq([cql])
81
81
  end
82
82
  end
83
+
84
+ context "with :type key" do
85
+ it "supports counter batch" do
86
+ cql = "BEGIN COUNTER BATCH APPLY BATCH"
87
+ subject.call({
88
+ type: 'counter',
89
+ }).should eq([cql])
90
+ end
91
+
92
+ it "supports unlogged batch" do
93
+ cql = "BEGIN UNLOGGED BATCH APPLY BATCH"
94
+ subject.call({
95
+ type: 'unlogged',
96
+ }).should eq([cql])
97
+ end
98
+
99
+ it "supports default logged batch" do
100
+ cql = "BEGIN BATCH APPLY BATCH"
101
+ subject.call({
102
+ type: 'logged',
103
+ }).should eq([cql])
104
+ end
105
+
106
+ it "defaults to logged when type is nil" do
107
+ cql = "BEGIN BATCH APPLY BATCH"
108
+ subject.call({
109
+ type: nil,
110
+ }).should eq([cql])
111
+ end
112
+
113
+ it "defaults to logged when type an empty string" do
114
+ cql = "BEGIN BATCH APPLY BATCH"
115
+ subject.call({
116
+ type: '',
117
+ }).should eq([cql])
118
+ end
119
+
120
+ it "raises error when type is invalid" do
121
+ expect {
122
+ subject.call({
123
+ type: 'anothertype',
124
+ })
125
+ }.to raise_error(ArgumentError, "invalid batch type")
126
+ end
127
+ end
83
128
  end
84
129
  end
@@ -73,6 +73,26 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyCreate do
73
73
  end
74
74
  end
75
75
 
76
+ context "when using composite partition key" do
77
+ it "returns array of arguments" do
78
+ schema = Cassanity::Schema.new({
79
+ primary_key: [[:segment, :line], :track_id],
80
+ columns: {
81
+ segment: :text,
82
+ line: :int,
83
+ track_id: :timeuuid,
84
+ page: :text,
85
+ },
86
+ })
87
+ cql = "CREATE COLUMNFAMILY #{column_family_name} (segment text, line int, track_id timeuuid, page text, PRIMARY KEY ((segment, line), track_id))"
88
+ expected = [cql]
89
+ subject.call({
90
+ column_family_name: column_family_name,
91
+ schema: schema,
92
+ }).should eq(expected)
93
+ end
94
+ end
95
+
76
96
  context "when using WITH options" do
77
97
  let(:with_clause) {
78
98
  lambda { |args| [" WITH comment = ?", 'Testing']}
@@ -58,6 +58,48 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyDelete do
58
58
  end
59
59
  end
60
60
 
61
+ context "with one collection item" do
62
+ it "returns array of arguments only deleting the collection item" do
63
+ cql = "DELETE foo[?] FROM #{column_family_name} WHERE \"id\" = ?"
64
+ expected = [cql, 0, '1']
65
+ subject.call({
66
+ column_family_name: column_family_name,
67
+ columns: Cassanity.item(0, :foo),
68
+ where: {
69
+ id: '1',
70
+ }
71
+ }).should eq(expected)
72
+ end
73
+ end
74
+
75
+ context "with multiple collection items" do
76
+ it "returns array of arguments only deleting the collection items" do
77
+ cql = "DELETE foo[?], foo[?] FROM #{column_family_name} WHERE \"id\" = ?"
78
+ expected = [cql, 0, 3, '1']
79
+ subject.call({
80
+ column_family_name: column_family_name,
81
+ columns: [Cassanity.item(0, :foo), Cassanity.item(3, :foo)],
82
+ where: {
83
+ id: '1',
84
+ }
85
+ }).should eq(expected)
86
+ end
87
+ end
88
+
89
+ context "with standard columns and collection items" do
90
+ it "returns array of arguments only deleting given columns" do
91
+ cql = "DELETE bar, foo[?] FROM #{column_family_name} WHERE \"id\" = ?"
92
+ expected = [cql, 0, '1']
93
+ subject.call({
94
+ column_family_name: column_family_name,
95
+ columns: [:bar, Cassanity.item(0, :foo)],
96
+ where: {
97
+ id: '1',
98
+ }
99
+ }).should eq(expected)
100
+ end
101
+ end
102
+
61
103
  context "with :where key" do
62
104
  subject {
63
105
  described_class.new({
@@ -24,6 +24,17 @@ describe Cassanity::ArgumentGenerators::KeyspaceCreate do
24
24
  end
25
25
  end
26
26
 
27
+ context "overriding replication class with NetworkTopologyStrategy" do
28
+ it "doesn't merge in replication_factor" do
29
+ cql = "CREATE KEYSPACE #{keyspace_name} WITH replication = ?"
30
+ expected = [cql, {class: 'NetworkTopologyStrategy', datacenter1: 1}]
31
+ subject.call({
32
+ keyspace_name: keyspace_name,
33
+ replication: {class: 'NetworkTopologyStrategy', datacenter1: 1},
34
+ }).should eq(expected)
35
+ end
36
+ end
37
+
27
38
  context "overriding a default strategy_option" do
28
39
  it "returns array of arguments" do
29
40
  cql = "CREATE KEYSPACE #{keyspace_name} WITH replication = ?"
@@ -44,5 +44,40 @@ describe Cassanity::ArgumentGenerators::SetClause do
44
44
  should eq([" SET views = views - ?", 3])
45
45
  end
46
46
  end
47
+
48
+ context "with addition" do
49
+ it "returns array of arguments with SET including list value" do
50
+ subject.call(set: {places: Cassanity::Addition.new('mordor')}).
51
+ should eq([" SET places = places + ?", ['mordor']])
52
+ end
53
+ end
54
+
55
+ context "with removal" do
56
+ it "returns array of arguments with SET including list value" do
57
+ subject.call(set: {places: Cassanity::Removal.new('mordor')}).
58
+ should eq([" SET places = places - ?", ['mordor']])
59
+ end
60
+ end
61
+
62
+ context "with set_addition" do
63
+ it "returns array of arguments with SET including set value" do
64
+ subject.call(set: {places: Cassanity::SetAddition.new('mordor')}).
65
+ should eq([" SET places = places + ?", Set['mordor']])
66
+ end
67
+ end
68
+
69
+ context "with set_removal" do
70
+ it "returns array of arguments with SET including set value" do
71
+ subject.call(set: {places: Cassanity::SetRemoval.new('mordor')}).
72
+ should eq([" SET places = places - ?", Set['mordor']])
73
+ end
74
+ end
75
+
76
+ context "with collection_item" do
77
+ it "returns array of arguments with SET including collection item" do
78
+ subject.call(set: {tags: Cassanity::CollectionItem.new(3,'ruby')}).
79
+ should eq([" SET tags[?] = ?", 3, 'ruby'])
80
+ end
81
+ end
47
82
  end
48
83
  end
@@ -0,0 +1,84 @@
1
+ require 'helper'
2
+ require 'cassanity/collection_item'
3
+
4
+ describe Cassanity::CollectionItem do
5
+ subject {
6
+ described_class.new(1, 'ruby')
7
+ }
8
+
9
+ describe "self named helper method" do
10
+ it "returns instance" do
11
+ Cassanity::CollectionItem(0, 'ruby').should eq(described_class.new(0, 'ruby'))
12
+ end
13
+ end
14
+
15
+ describe "#initialize" do
16
+ before do
17
+ @instance = described_class.new(1, 'ruby')
18
+ end
19
+
20
+ it "sets key" do
21
+ @instance.key.should eq(1)
22
+ end
23
+
24
+ it "sets value" do
25
+ @instance.value.should eq('ruby')
26
+ end
27
+
28
+ context "with key nil" do
29
+ it "raises error" do
30
+ expect {
31
+ described_class.new(nil, 3)
32
+ }.to raise_error(ArgumentError, "key cannot be nil")
33
+ end
34
+ end
35
+
36
+ context "with value nil" do
37
+ it "raises error" do
38
+ expect {
39
+ described_class.new(3, nil)
40
+ }.to raise_error(ArgumentError, "value cannot be nil")
41
+ end
42
+ end
43
+ end
44
+
45
+ shared_examples_for "operator equality" do |method_name|
46
+ it "returns true for same class, key and value" do
47
+ instance = described_class.new(0, 'ruby')
48
+ other = described_class.new(0, 'ruby')
49
+ instance.send(method_name, other).should be_true
50
+ end
51
+
52
+ it "returns false for same class/value and different key" do
53
+ instance = described_class.new(0, 'ruby')
54
+ other = described_class.new(1, 'ruby')
55
+ instance.send(method_name, other).should be_false
56
+ end
57
+
58
+ it "returns false for same class/key and different value" do
59
+ instance = described_class.new(0, 'ruby')
60
+ other = described_class.new(0, 'go')
61
+ instance.send(method_name, other).should be_false
62
+ end
63
+
64
+ it "returns false for different class" do
65
+ instance = described_class.new(1, 'ruby')
66
+ other = Object.new
67
+ instance.send(method_name, other).should be_false
68
+ end
69
+ end
70
+
71
+ describe "#eql?" do
72
+ include_examples "operator equality", :eql?
73
+ end
74
+
75
+ describe "#==" do
76
+ include_examples "operator equality", :==
77
+ end
78
+
79
+ describe "#inspect" do
80
+ it "return representation" do
81
+ subject.inspect.should eq("#<Cassanity::CollectionItem:#{subject.object_id} key=1, value=\"ruby\">")
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,80 @@
1
+ require 'helper'
2
+ require 'cassanity/removal'
3
+
4
+ describe Cassanity::Removal do
5
+ describe "self named helper method" do
6
+ it "returns instance" do
7
+ Cassanity::Removal('foo').should eq(described_class.new('foo'))
8
+ end
9
+ end
10
+
11
+ describe "#initialize" do
12
+ context "with value" do
13
+ before do
14
+ @instance = described_class.new('foo')
15
+ end
16
+
17
+ it "sets value" do
18
+ @instance.value.should eq(['foo'])
19
+ end
20
+
21
+ it "sets symbol" do
22
+ @instance.symbol.should be(:-)
23
+ end
24
+ end
25
+
26
+ context "with multiples values" do
27
+ before do
28
+ @instance = described_class.new('foo', 'bar')
29
+ end
30
+
31
+ it "sets values" do
32
+ @instance.value.should eq(['foo', 'bar'])
33
+ end
34
+ end
35
+
36
+ context "without value" do
37
+ it "raises error" do
38
+ expect {
39
+ subject.value
40
+ }.to raise_error(ArgumentError, "value cannot be nil")
41
+ end
42
+ end
43
+
44
+ context "with nil" do
45
+ it "raises error" do
46
+ expect {
47
+ described_class.new(nil)
48
+ }.to raise_error(ArgumentError, "value cannot be nil")
49
+ end
50
+ end
51
+ end
52
+
53
+ shared_examples_for "removal equality" do |method_name|
54
+ it "returns true for same class and value" do
55
+ instance = described_class.new('foo')
56
+ other = described_class.new('foo')
57
+ instance.send(method_name, other).should be_true
58
+ end
59
+
60
+ it "returns false for same class and different value" do
61
+ instance = described_class.new('foo')
62
+ other = described_class.new('bar')
63
+ instance.send(method_name, other).should be_false
64
+ end
65
+
66
+ it "returns false for different class" do
67
+ instance = described_class.new('foo')
68
+ other = Object.new
69
+ instance.send(method_name, other).should be_false
70
+ end
71
+ end
72
+
73
+ describe "#eql?" do
74
+ include_examples "removal equality", :eql?
75
+ end
76
+
77
+ describe "#==" do
78
+ include_examples "removal equality", :==
79
+ end
80
+ end