cassanity 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +11 -0
  5. data/Guardfile +17 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +99 -0
  8. data/Rakefile +16 -0
  9. data/cassanity.gemspec +21 -0
  10. data/examples/_shared.rb +8 -0
  11. data/examples/batch.rb +40 -0
  12. data/examples/column_families.rb +68 -0
  13. data/examples/keyspaces.rb +57 -0
  14. data/lib/cassanity/argument_generators/batch.rb +52 -0
  15. data/lib/cassanity/argument_generators/column_family_alter.rb +47 -0
  16. data/lib/cassanity/argument_generators/column_family_create.rb +44 -0
  17. data/lib/cassanity/argument_generators/column_family_delete.rb +65 -0
  18. data/lib/cassanity/argument_generators/column_family_drop.rb +18 -0
  19. data/lib/cassanity/argument_generators/column_family_insert.rb +53 -0
  20. data/lib/cassanity/argument_generators/column_family_select.rb +34 -0
  21. data/lib/cassanity/argument_generators/column_family_truncate.rb +18 -0
  22. data/lib/cassanity/argument_generators/column_family_update.rb +69 -0
  23. data/lib/cassanity/argument_generators/index_create.rb +22 -0
  24. data/lib/cassanity/argument_generators/index_drop.rb +13 -0
  25. data/lib/cassanity/argument_generators/keyspace_create.rb +51 -0
  26. data/lib/cassanity/argument_generators/keyspace_drop.rb +13 -0
  27. data/lib/cassanity/argument_generators/keyspace_use.rb +13 -0
  28. data/lib/cassanity/argument_generators/keyspaces.rb +12 -0
  29. data/lib/cassanity/argument_generators/set_clause.rb +30 -0
  30. data/lib/cassanity/argument_generators/using_clause.rb +24 -0
  31. data/lib/cassanity/argument_generators/where_clause.rb +29 -0
  32. data/lib/cassanity/argument_generators/with_clause.rb +32 -0
  33. data/lib/cassanity/column_family.rb +233 -0
  34. data/lib/cassanity/connection.rb +88 -0
  35. data/lib/cassanity/error.rb +28 -0
  36. data/lib/cassanity/executors/cassandra_cql.rb +120 -0
  37. data/lib/cassanity/keyspace.rb +118 -0
  38. data/lib/cassanity/result_transformers/column_family_select.rb +15 -0
  39. data/lib/cassanity/result_transformers/mirror.rb +12 -0
  40. data/lib/cassanity/schema.rb +26 -0
  41. data/lib/cassanity/version.rb +3 -0
  42. data/lib/cassanity.rb +5 -0
  43. data/spec/helper.rb +27 -0
  44. data/spec/integration/cassanity/column_family_spec.rb +243 -0
  45. data/spec/integration/cassanity/connection_spec.rb +87 -0
  46. data/spec/integration/cassanity/keyspace_spec.rb +64 -0
  47. data/spec/support/cassanity_helpers.rb +35 -0
  48. data/spec/unit/cassanity/argument_generators/batch_spec.rb +36 -0
  49. data/spec/unit/cassanity/argument_generators/column_family_alter_spec.rb +85 -0
  50. data/spec/unit/cassanity/argument_generators/column_family_create_spec.rb +107 -0
  51. data/spec/unit/cassanity/argument_generators/column_family_delete_spec.rb +92 -0
  52. data/spec/unit/cassanity/argument_generators/column_family_drop_spec.rb +25 -0
  53. data/spec/unit/cassanity/argument_generators/column_family_insert_spec.rb +70 -0
  54. data/spec/unit/cassanity/argument_generators/column_family_select_spec.rb +113 -0
  55. data/spec/unit/cassanity/argument_generators/column_family_truncate_spec.rb +25 -0
  56. data/spec/unit/cassanity/argument_generators/column_family_update_spec.rb +109 -0
  57. data/spec/unit/cassanity/argument_generators/index_create_spec.rb +39 -0
  58. data/spec/unit/cassanity/argument_generators/index_drop_spec.rb +14 -0
  59. data/spec/unit/cassanity/argument_generators/keyspace_create_spec.rb +53 -0
  60. data/spec/unit/cassanity/argument_generators/keyspace_drop_spec.rb +14 -0
  61. data/spec/unit/cassanity/argument_generators/keyspace_use_spec.rb +14 -0
  62. data/spec/unit/cassanity/argument_generators/keyspaces_spec.rb +12 -0
  63. data/spec/unit/cassanity/argument_generators/set_clause_spec.rb +85 -0
  64. data/spec/unit/cassanity/argument_generators/using_clause_spec.rb +44 -0
  65. data/spec/unit/cassanity/argument_generators/where_clause_spec.rb +57 -0
  66. data/spec/unit/cassanity/argument_generators/with_clause_spec.rb +63 -0
  67. data/spec/unit/cassanity/column_family_spec.rb +250 -0
  68. data/spec/unit/cassanity/connection_spec.rb +75 -0
  69. data/spec/unit/cassanity/error_spec.rb +35 -0
  70. data/spec/unit/cassanity/executors/cassandra_cql_spec.rb +178 -0
  71. data/spec/unit/cassanity/keyspace_spec.rb +137 -0
  72. data/spec/unit/cassanity/result_transformers/column_family_select_spec.rb +0 -0
  73. data/spec/unit/cassanity/result_transformers/mirror_spec.rb +12 -0
  74. data/spec/unit/cassanity/schema_spec.rb +23 -0
  75. data/spec/unit/cassanity_spec.rb +5 -0
  76. metadata +172 -0
@@ -0,0 +1,109 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/column_family_update'
3
+
4
+ describe Cassanity::ArgumentGenerators::ColumnFamilyUpdate do
5
+ let(:column_family_name) { 'apps' }
6
+
7
+ describe "#call" do
8
+ it "returns array of arguments" do
9
+ cql = "UPDATE #{column_family_name} SET name = ? WHERE id = ?"
10
+ expected = [cql, 'New Name', '1']
11
+ subject.call({
12
+ name: column_family_name,
13
+ set: {
14
+ name: 'New Name',
15
+ },
16
+ where: {
17
+ id: '1',
18
+ }
19
+ }).should eq(expected)
20
+ end
21
+
22
+ context "with :keyspace_name" do
23
+ it "returns array of arguments" do
24
+ cql = "UPDATE foo.#{column_family_name} SET name = ? WHERE id = ?"
25
+ expected = [cql, 'New Name', '1']
26
+ subject.call({
27
+ keyspace_name: :foo,
28
+ name: column_family_name,
29
+ set: {
30
+ name: 'New Name',
31
+ },
32
+ where: {
33
+ id: '1',
34
+ }
35
+ }).should eq(expected)
36
+ end
37
+ end
38
+
39
+ context "with :where key" do
40
+ subject {
41
+ described_class.new({
42
+ where_clause: lambda { |args|
43
+ [" WHERE id = ?", args.fetch(:where).fetch(:id)]
44
+ }
45
+ })
46
+ }
47
+
48
+ it "uses where clause to get additional cql and bound variables" do
49
+ cql = "UPDATE #{column_family_name} SET name = ? WHERE id = ?"
50
+ expected = [cql, 'New Name', '4']
51
+ subject.call({
52
+ name: column_family_name,
53
+ set: {
54
+ name: 'New Name',
55
+ },
56
+ where: {
57
+ id: '4',
58
+ }
59
+ }).should eq(expected)
60
+ end
61
+ end
62
+
63
+ context "with :set key" do
64
+ subject {
65
+ described_class.new({
66
+ set_clause: lambda { |args|
67
+ [" SET name = ?", args.fetch(:set).fetch(:name)]
68
+ }
69
+ })
70
+ }
71
+
72
+ it "uses set clause to get additional cql and bound variables" do
73
+ cql = "UPDATE #{column_family_name} SET name = ? WHERE id = ?"
74
+ expected = [cql, 'New Name', '4']
75
+ subject.call({
76
+ name: column_family_name,
77
+ set: {
78
+ name: 'New Name',
79
+ },
80
+ where: {
81
+ id: '4',
82
+ }
83
+ }).should eq(expected)
84
+ end
85
+ end
86
+
87
+ context "with :using key" do
88
+ it "returns array of arguments with cql including using" do
89
+ millis = (Time.mktime(2012, 11, 1, 14, 9, 9).to_f * 1000).to_i
90
+ cql = "UPDATE #{column_family_name} USING TTL 86400 AND TIMESTAMP #{millis} AND CONSISTENCY quorum SET name = ? WHERE id = ?"
91
+ expected = [cql, 'New Name', '1']
92
+ subject.call({
93
+ name: column_family_name,
94
+ using: {
95
+ ttl: 86400,
96
+ timestamp: millis,
97
+ consistency: 'quorum',
98
+ },
99
+ set: {
100
+ name: 'New Name',
101
+ },
102
+ where: {
103
+ id: '1',
104
+ },
105
+ }).should eq(expected)
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,39 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/index_create'
3
+
4
+ describe Cassanity::ArgumentGenerators::IndexCreate do
5
+ describe "#call" do
6
+ it "returns array of arguments" do
7
+ cql = "CREATE INDEX ON mutants (ability_id)"
8
+ expected = [cql]
9
+ subject.call({
10
+ column_family_name: :mutants,
11
+ column_name: :ability_id,
12
+ }).should eq(expected)
13
+ end
14
+
15
+ context "with :keyspace_name" do
16
+ it "returns array of arguments" do
17
+ cql = "CREATE INDEX ON app.mutants (ability_id)"
18
+ expected = [cql]
19
+ subject.call({
20
+ keyspace_name: :app,
21
+ column_family_name: :mutants,
22
+ column_name: :ability_id,
23
+ }).should eq(expected)
24
+ end
25
+ end
26
+
27
+ context "with :name" do
28
+ it "returns array of arguments with name in cql" do
29
+ cql = "CREATE INDEX ability_index ON mutants (ability_id)"
30
+ expected = [cql]
31
+ subject.call({
32
+ name: :ability_index,
33
+ column_family_name: :mutants,
34
+ column_name: :ability_id,
35
+ }).should eq(expected)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/index_drop'
3
+
4
+ describe Cassanity::ArgumentGenerators::IndexDrop do
5
+ describe "#call" do
6
+ it "returns array of arguments" do
7
+ cql = "DROP INDEX mutants_ability_id"
8
+ expected = [cql]
9
+ subject.call({
10
+ :name => :mutants_ability_id,
11
+ }).should eq(expected)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,53 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/keyspace_create'
3
+
4
+ describe Cassanity::ArgumentGenerators::KeyspaceCreate do
5
+ let(:keyspace_name) { 'analytics' }
6
+
7
+ describe "#call" do
8
+ context "only name" do
9
+ it "returns array of arguments" do
10
+ cql = "CREATE KEYSPACE #{keyspace_name} WITH strategy_class = ? AND strategy_options:replication_factor = ?"
11
+ expected = [cql, 'SimpleStrategy', 1]
12
+ subject.call(name: keyspace_name).should eq(expected)
13
+ end
14
+ end
15
+
16
+ context "overriding strategy_class" do
17
+ it "returns array of arguments" do
18
+ cql = "CREATE KEYSPACE #{keyspace_name} WITH strategy_class = ? AND strategy_options:replication_factor = ?"
19
+ expected = [cql, 'FooStrategy', 1]
20
+ subject.call({
21
+ name: keyspace_name,
22
+ strategy_class: 'FooStrategy',
23
+ }).should eq(expected)
24
+ end
25
+ end
26
+
27
+ context "overriding a default strategy_option" do
28
+ it "returns array of arguments" do
29
+ cql = "CREATE KEYSPACE #{keyspace_name} WITH strategy_class = ? AND strategy_options:replication_factor = ?"
30
+ expected = [cql, 'SimpleStrategy', 3]
31
+ subject.call({
32
+ name: keyspace_name,
33
+ strategy_options: {
34
+ replication_factor: 3,
35
+ }
36
+ }).should eq(expected)
37
+ end
38
+ end
39
+
40
+ context "adding new strategy_option" do
41
+ it "returns array of arguments" do
42
+ cql = "CREATE KEYSPACE #{keyspace_name} WITH strategy_class = ? AND strategy_options:replication_factor = ? AND strategy_options:batman = ?"
43
+ expected = [cql, 'SimpleStrategy', 1, 'robin']
44
+ subject.call({
45
+ name: keyspace_name,
46
+ strategy_options: {
47
+ batman: 'robin',
48
+ }
49
+ }).should eq(expected)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,14 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/keyspace_drop'
3
+
4
+ describe Cassanity::ArgumentGenerators::KeyspaceDrop do
5
+ let(:keyspace_name) { 'analytics' }
6
+
7
+ describe "#call" do
8
+ it "returns array of arguments" do
9
+ cql = "DROP KEYSPACE #{keyspace_name}"
10
+ expected = [cql]
11
+ subject.call(name: keyspace_name).should eq(expected)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/keyspace_use'
3
+
4
+ describe Cassanity::ArgumentGenerators::KeyspaceUse do
5
+ let(:keyspace_name) { 'analytics' }
6
+
7
+ describe "#call" do
8
+ it "returns array of arguments" do
9
+ cql = "USE #{keyspace_name}"
10
+ expected = [cql]
11
+ subject.call(name: keyspace_name).should eq(expected)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/keyspaces'
3
+
4
+ describe Cassanity::ArgumentGenerators::Keyspaces do
5
+ describe "#call" do
6
+ it "returns array of arguments" do
7
+ cql = "SELECT * FROM system.schema_keyspaces"
8
+ expected = [cql]
9
+ subject.call.should eq(expected)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,85 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/set_clause'
3
+
4
+ describe Cassanity::ArgumentGenerators::SetClause do
5
+ describe "#call" do
6
+ it "returns array of arguments" do
7
+ subject.call({
8
+ set: {
9
+ name: 'GitHub',
10
+ }
11
+ }).should eq([
12
+ " SET name = ?",
13
+ 'GitHub',
14
+ ])
15
+ end
16
+
17
+ context "with multiple :set keys/values" do
18
+ it "returns array of arguments where each SET is comma separated" do
19
+ time = Time.now
20
+
21
+ subject.call({
22
+ set: {
23
+ name: 'GitHub',
24
+ created_at: time,
25
+ }
26
+ }).should eq([
27
+ " SET name = ?, created_at = ?",
28
+ 'GitHub',
29
+ time,
30
+ ])
31
+ end
32
+ end
33
+
34
+ context "with counter update" do
35
+ it "returns array of arguments where counter SET is correct" do
36
+ subject.call(set: {views: 'views + 5'}).
37
+ should eq([" SET views = views + 5"])
38
+ end
39
+
40
+ it "works with no spaces" do
41
+ subject.call(set: {views: 'views+5'}).
42
+ should eq([" SET views = views+5"])
43
+ end
44
+
45
+ it "works with one or more spaces before the operator" do
46
+ subject.call(set: {views: 'views +5'}).
47
+ should eq([" SET views = views +5"])
48
+
49
+ subject.call(set: {views: 'views +5'}).
50
+ should eq([" SET views = views +5"])
51
+ end
52
+
53
+ it "works with one or more spaces after the operator" do
54
+ subject.call(set: {views: 'views+ 5'}).
55
+ should eq([" SET views = views+ 5"])
56
+
57
+ subject.call(set: {views: 'views+ 5'}).
58
+ should eq([" SET views = views+ 5"])
59
+ end
60
+
61
+ it "works with spaces after before the key" do
62
+ subject.call(set: {views: ' views + 5'}).
63
+ should eq([" SET views = views + 5"])
64
+ end
65
+
66
+ it "works with spaces after the number" do
67
+ subject.call(set: {views: 'views + 5 '}).
68
+ should eq([" SET views = views + 5 "])
69
+
70
+ subject.call(set: {views: 'views + 5 '}).
71
+ should eq([" SET views = views + 5 "])
72
+ end
73
+
74
+ it "works with negative operator" do
75
+ subject.call(set: {views: 'views - 5'}).
76
+ should eq([" SET views = views - 5"])
77
+ end
78
+
79
+ it "works with multiple digit numbers" do
80
+ subject.call(set: {views: 'views - 52737237'}).
81
+ should eq([" SET views = views - 52737237"])
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,44 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/using_clause'
3
+
4
+ describe Cassanity::ArgumentGenerators::UsingClause do
5
+ describe "#call" do
6
+ context "with single :using option" do
7
+ it "returns array of arguments" do
8
+ subject.call({
9
+ using: {
10
+ ttl: 500,
11
+ }
12
+ }).should eq([
13
+ " USING TTL 500",
14
+ ])
15
+ end
16
+ end
17
+
18
+ context "with multiple :using option" do
19
+ it "returns array of arguments" do
20
+ subject.call({
21
+ using: {
22
+ ttl: 500,
23
+ consistency: 'quorum',
24
+ timestamp: 1234,
25
+ }
26
+ }).should eq([
27
+ " USING TTL 500 AND CONSISTENCY quorum AND TIMESTAMP 1234",
28
+ ])
29
+ end
30
+ end
31
+
32
+ context "with no arguments" do
33
+ it "returns array of arguments where only item is empty string" do
34
+ subject.call.should eq([""])
35
+ end
36
+ end
37
+
38
+ context "with empty arguments" do
39
+ it "returns array of arguments where only item is empty string" do
40
+ subject.call({}).should eq([""])
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,57 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/where_clause'
3
+
4
+ describe Cassanity::ArgumentGenerators::WhereClause do
5
+ describe "#call" do
6
+ it "returns array of arguments" do
7
+ subject.call({
8
+ where: {
9
+ id: '1',
10
+ }
11
+ }).should eq([
12
+ " WHERE id = ?",
13
+ '1',
14
+ ])
15
+ end
16
+
17
+ context "with nil where" do
18
+ it "returns array with empty string" do
19
+ subject.call.should eq([""])
20
+ end
21
+ end
22
+
23
+ context "with empty where" do
24
+ it "returns array with empty string" do
25
+ subject.call(where: {}).should eq([""])
26
+ end
27
+ end
28
+
29
+ context "with array value for a where" do
30
+ it "returns array of arguments using IN for key with array value" do
31
+ subject.call({
32
+ where: {
33
+ id: ['1', '2', '3'],
34
+ }
35
+ }).should eq([
36
+ " WHERE id IN (?)",
37
+ ['1', '2', '3'],
38
+ ])
39
+ end
40
+ end
41
+
42
+ context "with multiple where values" do
43
+ it "returns array of arguments with AND separating where keys" do
44
+ subject.call({
45
+ where: {
46
+ bucket: '2012',
47
+ id: '1',
48
+ }
49
+ }).should eq([
50
+ " WHERE bucket = ? AND id = ?",
51
+ '2012',
52
+ '1',
53
+ ])
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,63 @@
1
+ require 'helper'
2
+ require 'cassanity/argument_generators/with_clause'
3
+
4
+ describe Cassanity::ArgumentGenerators::WithClause do
5
+ describe "#call" do
6
+ context "with single :with option" do
7
+ it "returns array of arguments" do
8
+ subject.call({
9
+ with: {
10
+ comment: 'Just testing',
11
+ }
12
+ }).should eq([
13
+ " WITH comment = ?",
14
+ 'Just testing',
15
+ ])
16
+ end
17
+ end
18
+
19
+ context "with multiple :with option" do
20
+ it "returns array of arguments" do
21
+ subject.call({
22
+ with: {
23
+ comment: 'Just testing',
24
+ read_repair_chance: 0.2,
25
+ }
26
+ }).should eq([
27
+ " WITH comment = ? AND read_repair_chance = ?",
28
+ 'Just testing',
29
+ 0.2,
30
+ ])
31
+ end
32
+ end
33
+
34
+ context "when using :with option that has sub options" do
35
+ it "returns array of arguments" do
36
+ subject.call({
37
+ with: {
38
+ compaction_strategy_options: {
39
+ min_compaction_threshold: 6,
40
+ max_compaction_threshold: 40,
41
+ },
42
+ }
43
+ }).should eq([
44
+ " WITH compaction_strategy_options:min_compaction_threshold = ? AND compaction_strategy_options:max_compaction_threshold = ?",
45
+ 6,
46
+ 40,
47
+ ])
48
+ end
49
+ end
50
+
51
+ context "with no arguments" do
52
+ it "returns array of arguments where only item is empty string" do
53
+ subject.call.should eq([""])
54
+ end
55
+ end
56
+
57
+ context "with empty arguments" do
58
+ it "returns array of arguments where only item is empty string" do
59
+ subject.call({}).should eq([""])
60
+ end
61
+ end
62
+ end
63
+ end