cassanity 0.6.0.beta5 → 0.6.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 (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