cassanity 0.4.0 → 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.
- data/.gitignore +2 -1
- data/.travis.yml +1 -0
- data/Gemfile +3 -0
- data/Guardfile +0 -2
- data/README.md +11 -0
- data/doc/Instrumentation.md +40 -0
- data/doc/Migrations.md +132 -0
- data/examples/keyspaces.rb +11 -7
- data/lib/cassanity/argument_generators/column_family_delete.rb +1 -1
- data/lib/cassanity/argument_generators/columns.rb +33 -0
- data/lib/cassanity/argument_generators/where_clause.rb +1 -1
- data/lib/cassanity/client.rb +3 -1
- data/lib/cassanity/column.rb +48 -0
- data/lib/cassanity/column_family.rb +21 -2
- data/lib/cassanity/connection.rb +4 -8
- data/lib/cassanity/error.rb +18 -11
- data/lib/cassanity/executors/cassandra_cql.rb +79 -50
- data/lib/cassanity/instrumentation/log_subscriber.rb +4 -5
- data/lib/cassanity/instrumentation/metriks.rb +6 -0
- data/lib/cassanity/instrumentation/metriks_subscriber.rb +16 -0
- data/lib/cassanity/instrumentation/statsd.rb +6 -0
- data/lib/cassanity/instrumentation/statsd_subscriber.rb +22 -0
- data/lib/cassanity/instrumentation/subscriber.rb +58 -0
- data/lib/cassanity/instrumenters/memory.rb +0 -1
- data/lib/cassanity/keyspace.rb +10 -8
- data/lib/cassanity/migration.rb +125 -0
- data/lib/cassanity/migration_proxy.rb +76 -0
- data/lib/cassanity/migrator.rb +154 -0
- data/lib/cassanity/result_transformers/column_families.rb +20 -0
- data/lib/cassanity/result_transformers/columns.rb +21 -0
- data/lib/cassanity/result_transformers/keyspaces.rb +21 -0
- data/lib/cassanity/result_transformers/mirror.rb +1 -1
- data/lib/cassanity/result_transformers/result_to_array.rb +1 -1
- data/lib/cassanity/retry_strategies/exponential_backoff.rb +43 -0
- data/lib/cassanity/retry_strategies/retry_n_times.rb +29 -0
- data/lib/cassanity/retry_strategies/retry_strategy.rb +35 -0
- data/lib/cassanity/version.rb +1 -1
- data/spec/helper.rb +8 -0
- data/spec/integration/cassanity/column_family_spec.rb +36 -25
- data/spec/integration/cassanity/connection_spec.rb +11 -11
- data/spec/integration/cassanity/fixtures/migrations/20130224135000_create_users.rb +17 -0
- data/spec/integration/cassanity/fixtures/migrations/20130225135002_create_apps.rb +15 -0
- data/spec/integration/cassanity/fixtures/migrations/20130226135004_add_username_to_users.rb +9 -0
- data/spec/integration/cassanity/instrumentation/log_subscriber_spec.rb +71 -0
- data/spec/integration/cassanity/instrumentation/metriks_subscriber_spec.rb +48 -0
- data/spec/integration/cassanity/instrumentation/statsd_subscriber_spec.rb +58 -0
- data/spec/integration/cassanity/keyspace_spec.rb +21 -21
- data/spec/integration/cassanity/migration_spec.rb +157 -0
- data/spec/integration/cassanity/migrator_spec.rb +212 -0
- data/spec/support/cassanity_helpers.rb +21 -17
- data/spec/support/fake_udp_socket.rb +27 -0
- data/spec/unit/cassanity/argument_generators/batch_spec.rb +5 -5
- data/spec/unit/cassanity/argument_generators/column_family_delete_spec.rb +20 -6
- data/spec/unit/cassanity/argument_generators/column_family_update_spec.rb +6 -6
- data/spec/unit/cassanity/argument_generators/columns_spec.rb +45 -0
- data/spec/unit/cassanity/argument_generators/keyspace_create_spec.rb +1 -1
- data/spec/unit/cassanity/argument_generators/keyspace_drop_spec.rb +1 -1
- data/spec/unit/cassanity/argument_generators/keyspace_use_spec.rb +1 -1
- data/spec/unit/cassanity/argument_generators/where_clause_spec.rb +2 -2
- data/spec/unit/cassanity/client_spec.rb +10 -3
- data/spec/unit/cassanity/column_family_spec.rb +20 -3
- data/spec/unit/cassanity/column_spec.rb +76 -0
- data/spec/unit/cassanity/connection_spec.rb +1 -1
- data/spec/unit/cassanity/error_spec.rb +7 -2
- data/spec/unit/cassanity/executors/cassandra_cql_spec.rb +76 -23
- data/spec/unit/cassanity/keyspace_spec.rb +38 -13
- data/spec/unit/cassanity/migration_proxy_spec.rb +81 -0
- data/spec/unit/cassanity/migration_spec.rb +12 -0
- data/spec/unit/cassanity/migrator_spec.rb +20 -0
- data/spec/unit/cassanity/retry_strategies/exponential_backoff_spec.rb +37 -0
- data/spec/unit/cassanity/retry_strategies/retry_n_times_spec.rb +47 -0
- data/spec/unit/cassanity/retry_strategies/retry_strategy_spec.rb +27 -0
- metadata +56 -4
@@ -1,35 +1,39 @@
|
|
1
1
|
module CassanityHelpers
|
2
|
-
def
|
3
|
-
|
2
|
+
def driver_keyspace?(driver, name)
|
3
|
+
driver.keyspaces.map(&:name).include?(name.to_s)
|
4
4
|
end
|
5
5
|
|
6
|
-
def
|
7
|
-
unless
|
8
|
-
|
6
|
+
def driver_create_keyspace(driver, name)
|
7
|
+
unless driver_keyspace?(driver, name)
|
8
|
+
driver.execute("CREATE KEYSPACE #{name} WITH strategy_class = 'SimpleStrategy' AND strategy_options:replication_factor = 1")
|
9
9
|
end
|
10
|
-
|
10
|
+
driver.execute("USE #{name}")
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
if
|
15
|
-
|
13
|
+
def driver_drop_keyspace(driver, name)
|
14
|
+
if driver_keyspace?(driver, name)
|
15
|
+
driver.execute("DROP KEYSPACE #{name}")
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
|
19
|
+
def driver_column_family?(driver, name)
|
20
|
+
driver.schema.column_family_names.include?(name.to_s)
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def driver_create_column_family(driver, name, columns = nil)
|
24
24
|
columns ||= "id text PRIMARY KEY, name text"
|
25
|
-
unless
|
26
|
-
|
25
|
+
unless driver_column_family?(driver, name)
|
26
|
+
driver.execute("CREATE COLUMNFAMILY #{name} (#{columns})")
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
31
|
-
if
|
32
|
-
|
30
|
+
def driver_drop_column_family(driver, name)
|
31
|
+
if driver_column_family?(driver, name)
|
32
|
+
driver.execute("DROP COLUMNFAMILY #{name}")
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
def cassandra_error(err)
|
37
|
+
CassandraCQL::Error::InvalidRequestException.new(err)
|
38
|
+
end
|
35
39
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class FakeUDPSocket
|
2
|
+
attr_reader :buffer
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@buffer = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def send(message, *rest)
|
9
|
+
@buffer.push [message]
|
10
|
+
end
|
11
|
+
|
12
|
+
def recv
|
13
|
+
@buffer.shift
|
14
|
+
end
|
15
|
+
|
16
|
+
def clear
|
17
|
+
@buffer = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
inspect
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
"<FakeUDPSocket: #{@buffer.inspect}>"
|
26
|
+
end
|
27
|
+
end
|
@@ -4,7 +4,7 @@ require 'cassanity/argument_generators/batch'
|
|
4
4
|
describe Cassanity::ArgumentGenerators::Batch do
|
5
5
|
describe "#call" do
|
6
6
|
it "returns array of arguments" do
|
7
|
-
cql = "BEGIN BATCH INSERT INTO users (id) VALUES (?) UPDATE users SET name = ? WHERE id = ? DELETE FROM users WHERE id = ? APPLY BATCH"
|
7
|
+
cql = "BEGIN BATCH INSERT INTO users (id) VALUES (?) UPDATE users SET name = ? WHERE \"id\" = ? DELETE FROM users WHERE \"id\" = ? APPLY BATCH"
|
8
8
|
subject.call({
|
9
9
|
modifications: [
|
10
10
|
[:insert, column_family_name: :users, data: {id: '1'}],
|
@@ -16,7 +16,7 @@ describe Cassanity::ArgumentGenerators::Batch do
|
|
16
16
|
|
17
17
|
context "with :column_family_name" do
|
18
18
|
it "merges column_family_name with each set of modifications" do
|
19
|
-
cql = "BEGIN BATCH INSERT INTO users (id) VALUES (?) UPDATE users SET name = ? WHERE id = ? APPLY BATCH"
|
19
|
+
cql = "BEGIN BATCH INSERT INTO users (id) VALUES (?) UPDATE users SET name = ? WHERE \"id\" = ? APPLY BATCH"
|
20
20
|
subject.call({
|
21
21
|
column_family_name: :users,
|
22
22
|
modifications: [
|
@@ -27,7 +27,7 @@ describe Cassanity::ArgumentGenerators::Batch do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it "does not override command argument name" do
|
30
|
-
cql = "BEGIN BATCH INSERT INTO users (id) VALUES (?) UPDATE other_column_family SET name = ? WHERE id = ? APPLY BATCH"
|
30
|
+
cql = "BEGIN BATCH INSERT INTO users (id) VALUES (?) UPDATE other_column_family SET name = ? WHERE \"id\" = ? APPLY BATCH"
|
31
31
|
subject.call({
|
32
32
|
column_family_name: :users,
|
33
33
|
modifications: [
|
@@ -40,7 +40,7 @@ describe Cassanity::ArgumentGenerators::Batch do
|
|
40
40
|
|
41
41
|
context "with :keyspace_name" do
|
42
42
|
it "merges column_family_name with each set of modifications" do
|
43
|
-
cql = "BEGIN BATCH INSERT INTO analytics.users (id) VALUES (?) UPDATE analytics.users SET name = ? WHERE id = ? APPLY BATCH"
|
43
|
+
cql = "BEGIN BATCH INSERT INTO analytics.users (id) VALUES (?) UPDATE analytics.users SET name = ? WHERE \"id\" = ? APPLY BATCH"
|
44
44
|
subject.call({
|
45
45
|
keyspace_name: :analytics,
|
46
46
|
modifications: [
|
@@ -51,7 +51,7 @@ describe Cassanity::ArgumentGenerators::Batch do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it "does not override command argument keyspace_name" do
|
54
|
-
cql = "BEGIN BATCH INSERT INTO other_keyspace_name.users (id) VALUES (?) UPDATE analytics.users SET name = ? WHERE id = ? APPLY BATCH"
|
54
|
+
cql = "BEGIN BATCH INSERT INTO other_keyspace_name.users (id) VALUES (?) UPDATE analytics.users SET name = ? WHERE \"id\" = ? APPLY BATCH"
|
55
55
|
subject.call({
|
56
56
|
keyspace_name: :analytics,
|
57
57
|
modifications: [
|
@@ -6,7 +6,7 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyDelete do
|
|
6
6
|
|
7
7
|
describe "#call" do
|
8
8
|
it "returns array of arguments" do
|
9
|
-
cql = "DELETE FROM #{column_family_name} WHERE id = ?"
|
9
|
+
cql = "DELETE FROM #{column_family_name} WHERE \"id\" = ?"
|
10
10
|
expected = [cql, '1']
|
11
11
|
subject.call({
|
12
12
|
column_family_name: column_family_name,
|
@@ -18,7 +18,7 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyDelete do
|
|
18
18
|
|
19
19
|
context "with :keyspace_name" do
|
20
20
|
it "returns array of arguments" do
|
21
|
-
cql = "DELETE FROM foo.#{column_family_name} WHERE id = ?"
|
21
|
+
cql = "DELETE FROM foo.#{column_family_name} WHERE \"id\" = ?"
|
22
22
|
expected = [cql, '1']
|
23
23
|
subject.call({
|
24
24
|
keyspace_name: :foo,
|
@@ -30,9 +30,23 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyDelete do
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
context "with single column" do
|
34
|
+
it "returns array of arguments only deleting specific column" do
|
35
|
+
cql = "DELETE foo FROM #{column_family_name} WHERE \"id\" = ?"
|
36
|
+
expected = [cql, '1']
|
37
|
+
subject.call({
|
38
|
+
column_family_name: column_family_name,
|
39
|
+
columns: :foo,
|
40
|
+
where: {
|
41
|
+
id: '1',
|
42
|
+
}
|
43
|
+
}).should eq(expected)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
33
47
|
context "with specific columns" do
|
34
48
|
it "returns array of arguments only deleting specific columns" do
|
35
|
-
cql = "DELETE foo, bar FROM #{column_family_name} WHERE id = ?"
|
49
|
+
cql = "DELETE foo, bar FROM #{column_family_name} WHERE \"id\" = ?"
|
36
50
|
expected = [cql, '1']
|
37
51
|
subject.call({
|
38
52
|
column_family_name: column_family_name,
|
@@ -48,13 +62,13 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyDelete do
|
|
48
62
|
subject {
|
49
63
|
described_class.new({
|
50
64
|
where_clause: lambda { |args|
|
51
|
-
[" WHERE id = ?", args.fetch(:where).fetch(:id)]
|
65
|
+
[" WHERE \"id\" = ?", args.fetch(:where).fetch(:id)]
|
52
66
|
}
|
53
67
|
})
|
54
68
|
}
|
55
69
|
|
56
70
|
it "uses where clause to get additional cql and bound variables" do
|
57
|
-
cql = "DELETE FROM #{column_family_name} WHERE id = ?"
|
71
|
+
cql = "DELETE FROM #{column_family_name} WHERE \"id\" = ?"
|
58
72
|
expected = [cql, '4']
|
59
73
|
subject.call({
|
60
74
|
column_family_name: column_family_name,
|
@@ -75,7 +89,7 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyDelete do
|
|
75
89
|
}
|
76
90
|
|
77
91
|
it "uses using clause to get additional cql and bound variables" do
|
78
|
-
cql = "DELETE FROM #{column_family_name} USING TTL = 500 WHERE id = ?"
|
92
|
+
cql = "DELETE FROM #{column_family_name} USING TTL = 500 WHERE \"id\" = ?"
|
79
93
|
expected = [cql, '4']
|
80
94
|
subject.call({
|
81
95
|
column_family_name: column_family_name,
|
@@ -6,7 +6,7 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyUpdate do
|
|
6
6
|
|
7
7
|
describe "#call" do
|
8
8
|
it "returns array of arguments" do
|
9
|
-
cql = "UPDATE #{column_family_name} SET name = ? WHERE id = ?"
|
9
|
+
cql = "UPDATE #{column_family_name} SET name = ? WHERE \"id\" = ?"
|
10
10
|
expected = [cql, 'New Name', '1']
|
11
11
|
subject.call({
|
12
12
|
column_family_name: column_family_name,
|
@@ -21,7 +21,7 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyUpdate do
|
|
21
21
|
|
22
22
|
context "with :keyspace_name" do
|
23
23
|
it "returns array of arguments" do
|
24
|
-
cql = "UPDATE foo.#{column_family_name} SET name = ? WHERE id = ?"
|
24
|
+
cql = "UPDATE foo.#{column_family_name} SET name = ? WHERE \"id\" = ?"
|
25
25
|
expected = [cql, 'New Name', '1']
|
26
26
|
subject.call({
|
27
27
|
keyspace_name: :foo,
|
@@ -40,13 +40,13 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyUpdate do
|
|
40
40
|
subject {
|
41
41
|
described_class.new({
|
42
42
|
where_clause: lambda { |args|
|
43
|
-
[" WHERE id = ?", args.fetch(:where).fetch(:id)]
|
43
|
+
[" WHERE \"id\" = ?", args.fetch(:where).fetch(:id)]
|
44
44
|
}
|
45
45
|
})
|
46
46
|
}
|
47
47
|
|
48
48
|
it "uses where clause to get additional cql and bound variables" do
|
49
|
-
cql = "UPDATE #{column_family_name} SET name = ? WHERE id = ?"
|
49
|
+
cql = "UPDATE #{column_family_name} SET name = ? WHERE \"id\" = ?"
|
50
50
|
expected = [cql, 'New Name', '4']
|
51
51
|
subject.call({
|
52
52
|
column_family_name: column_family_name,
|
@@ -70,7 +70,7 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyUpdate do
|
|
70
70
|
}
|
71
71
|
|
72
72
|
it "uses set clause to get additional cql and bound variables" do
|
73
|
-
cql = "UPDATE #{column_family_name} SET name = ? WHERE id = ?"
|
73
|
+
cql = "UPDATE #{column_family_name} SET name = ? WHERE \"id\" = ?"
|
74
74
|
expected = [cql, 'New Name', '4']
|
75
75
|
subject.call({
|
76
76
|
column_family_name: column_family_name,
|
@@ -87,7 +87,7 @@ describe Cassanity::ArgumentGenerators::ColumnFamilyUpdate do
|
|
87
87
|
context "with :using key" do
|
88
88
|
it "returns array of arguments with cql including using" do
|
89
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 = ?"
|
90
|
+
cql = "UPDATE #{column_family_name} USING TTL 86400 AND TIMESTAMP #{millis} AND CONSISTENCY quorum SET name = ? WHERE \"id\" = ?"
|
91
91
|
expected = [cql, 'New Name', '1']
|
92
92
|
subject.call({
|
93
93
|
column_family_name: column_family_name,
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'cassanity/argument_generators/columns'
|
3
|
+
|
4
|
+
describe Cassanity::ArgumentGenerators::Columns do
|
5
|
+
describe "#call" do
|
6
|
+
context "with no args" do
|
7
|
+
it "returns array of arguments for selecting all columns" do
|
8
|
+
cql = 'SELECT * FROM system.schema_columns'
|
9
|
+
expected = [cql]
|
10
|
+
subject.call.should eq(expected)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "with keyspace" do
|
15
|
+
it "returns array of arguments for selecting all columns for keyspace" do
|
16
|
+
cql = 'SELECT * FROM system.schema_columns WHERE "keyspace" = ?'
|
17
|
+
expected = [cql, 'foo']
|
18
|
+
subject.call({
|
19
|
+
keyspace_name: 'foo',
|
20
|
+
}).should eq(expected)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "with column family" do
|
25
|
+
it "returns array of arguments for selecting all columns for column family" do
|
26
|
+
cql = 'SELECT * FROM system.schema_columns WHERE "columnfamily" = ?'
|
27
|
+
expected = [cql, 'foo']
|
28
|
+
subject.call({
|
29
|
+
column_family_name: 'foo',
|
30
|
+
}).should eq(expected)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with keyspace and column family" do
|
35
|
+
it "returns array of arguments for selecting all columns for a column family in a keyspace" do
|
36
|
+
cql = 'SELECT * FROM system.schema_columns WHERE "keyspace" = ? AND "columnfamily" = ?'
|
37
|
+
expected = [cql, 'foo', 'bar']
|
38
|
+
subject.call({
|
39
|
+
keyspace_name: 'foo',
|
40
|
+
column_family_name: 'bar',
|
41
|
+
}).should eq(expected)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -2,7 +2,7 @@ require 'helper'
|
|
2
2
|
require 'cassanity/argument_generators/keyspace_drop'
|
3
3
|
|
4
4
|
describe Cassanity::ArgumentGenerators::KeyspaceDrop do
|
5
|
-
let(:keyspace_name) {
|
5
|
+
let(:keyspace_name) { :analytics }
|
6
6
|
|
7
7
|
describe "#call" do
|
8
8
|
it "returns array of arguments" do
|
@@ -9,7 +9,7 @@ describe Cassanity::ArgumentGenerators::WhereClause do
|
|
9
9
|
id: '1',
|
10
10
|
}
|
11
11
|
}).should eq([
|
12
|
-
|
12
|
+
' WHERE "id" = ?',
|
13
13
|
'1',
|
14
14
|
])
|
15
15
|
end
|
@@ -34,7 +34,7 @@ describe Cassanity::ArgumentGenerators::WhereClause do
|
|
34
34
|
id: '1',
|
35
35
|
}
|
36
36
|
}).should eq([
|
37
|
-
|
37
|
+
' WHERE "bucket" = ? AND "id" = ?',
|
38
38
|
'2012',
|
39
39
|
'1',
|
40
40
|
])
|
@@ -2,6 +2,13 @@ require 'helper'
|
|
2
2
|
require 'cassanity/client'
|
3
3
|
|
4
4
|
describe Cassanity::Client do
|
5
|
+
let(:driver) { double('Driver') }
|
6
|
+
|
7
|
+
before do
|
8
|
+
# Ensure that we never hit cassandra for real here.
|
9
|
+
CassandraCQL::Database.stub(:new => driver)
|
10
|
+
end
|
11
|
+
|
5
12
|
describe "#initialize" do
|
6
13
|
it "passes arguments to cassandra cql database instance" do
|
7
14
|
CassandraCQL::Database.should_receive(:new).
|
@@ -72,7 +79,7 @@ describe Cassanity::Client do
|
|
72
79
|
and_return(driver)
|
73
80
|
|
74
81
|
Cassanity::Executors::CassandraCql.should_receive(:new).
|
75
|
-
with(
|
82
|
+
with(hash_including(driver: driver, instrumenter: instrumenter)).
|
76
83
|
and_return(executor)
|
77
84
|
|
78
85
|
described_class.new('localhost:1234', instrumenter: instrumenter)
|
@@ -80,7 +87,7 @@ describe Cassanity::Client do
|
|
80
87
|
|
81
88
|
it "sets cassandra cql database instance as driver" do
|
82
89
|
client = described_class.new
|
83
|
-
client.driver.should be_instance_of(
|
90
|
+
client.driver.should be_instance_of(driver.class)
|
84
91
|
end
|
85
92
|
|
86
93
|
it "builds driver, executor and connection" do
|
@@ -91,7 +98,7 @@ describe Cassanity::Client do
|
|
91
98
|
CassandraCQL::Database.should_receive(:new).and_return(driver)
|
92
99
|
|
93
100
|
Cassanity::Executors::CassandraCql.should_receive(:new).
|
94
|
-
with(hash_including(
|
101
|
+
with(hash_including(driver: driver)).
|
95
102
|
and_return(executor)
|
96
103
|
|
97
104
|
Cassanity::Connection.should_receive(:new).
|
@@ -2,7 +2,7 @@ require 'helper'
|
|
2
2
|
require 'cassanity/column_family'
|
3
3
|
|
4
4
|
describe Cassanity::ColumnFamily do
|
5
|
-
let(:column_family_name) {
|
5
|
+
let(:column_family_name) { :analytics }
|
6
6
|
let(:keyspace_name) { 'foo' }
|
7
7
|
|
8
8
|
let(:keyspace) {
|
@@ -81,6 +81,15 @@ describe Cassanity::ColumnFamily do
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
context "with string name" do
|
85
|
+
it "converts name to symbol" do
|
86
|
+
column_family = described_class.new(required_arguments.merge({
|
87
|
+
name: 'foo',
|
88
|
+
}))
|
89
|
+
column_family.name.should be(:foo)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
84
93
|
describe "#schema" do
|
85
94
|
it "returns schema if set" do
|
86
95
|
described_class.new(required_arguments.merge({
|
@@ -100,8 +109,12 @@ describe Cassanity::ColumnFamily do
|
|
100
109
|
executor.should_receive(:call).with({
|
101
110
|
command: :column_families,
|
102
111
|
arguments: {keyspace_name: keyspace.name},
|
112
|
+
transformer_arguments: {keyspace: keyspace},
|
103
113
|
}).and_return([
|
104
|
-
{
|
114
|
+
Cassanity::ColumnFamily.new({
|
115
|
+
name: column_family_name,
|
116
|
+
keyspace: keyspace,
|
117
|
+
})
|
105
118
|
])
|
106
119
|
|
107
120
|
subject.send(method_name).should be_true
|
@@ -111,8 +124,12 @@ describe Cassanity::ColumnFamily do
|
|
111
124
|
executor.should_receive(:call).with({
|
112
125
|
command: :column_families,
|
113
126
|
arguments: {keyspace_name: keyspace.name},
|
127
|
+
transformer_arguments: {keyspace: keyspace},
|
114
128
|
}).and_return([
|
115
|
-
{
|
129
|
+
Cassanity::ColumnFamily.new({
|
130
|
+
name: 'boo',
|
131
|
+
keyspace: keyspace,
|
132
|
+
})
|
116
133
|
])
|
117
134
|
|
118
135
|
subject.send(method_name).should be_false
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'cassanity/column_family'
|
3
|
+
|
4
|
+
describe Cassanity::Column do
|
5
|
+
let(:name) { :age }
|
6
|
+
let(:type) { :int }
|
7
|
+
let(:column_family) { double('Column Family') }
|
8
|
+
|
9
|
+
let(:required_arguments) {
|
10
|
+
{
|
11
|
+
name: name,
|
12
|
+
type: type,
|
13
|
+
column_family: column_family,
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
subject { described_class.new(required_arguments) }
|
18
|
+
|
19
|
+
it { should respond_to(:name) }
|
20
|
+
it { should respond_to(:type) }
|
21
|
+
it { should respond_to(:column_family) }
|
22
|
+
|
23
|
+
describe "#initialize" do
|
24
|
+
it "sets name" do
|
25
|
+
subject.name.should eq(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "sets type" do
|
29
|
+
subject.type.should eq(type)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "sets column_family" do
|
33
|
+
subject.column_family.should eq(column_family)
|
34
|
+
end
|
35
|
+
|
36
|
+
[:name, :type, :column_family].each do |key|
|
37
|
+
it "raises error without :#{key} key" do
|
38
|
+
args = required_arguments.reject { |k, v| k == key }
|
39
|
+
expect { described_class.new(args) }.to raise_error(KeyError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "initializing with string name" do
|
45
|
+
it "sets name to symbol" do
|
46
|
+
instance = described_class.new(required_arguments.merge(name: 'foo'))
|
47
|
+
instance.name.should be(:foo)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "initializing with long cassandra type" do
|
52
|
+
described_class::Types.each do |long, short|
|
53
|
+
it "converts #{long} to #{short}" do
|
54
|
+
instance = described_class.new(required_arguments.merge(type: long))
|
55
|
+
instance.type.should eq(short)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "initializing with some unknown long type" do
|
61
|
+
it "sets does not change type" do
|
62
|
+
instance = described_class.new(required_arguments.merge(type: 'foo.bar.String'))
|
63
|
+
instance.type.should eq('foo.bar.String')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#inspect" do
|
68
|
+
it "return representation" do
|
69
|
+
result = subject.inspect
|
70
|
+
result.should match(/#{described_class}/)
|
71
|
+
result.should match(/name=/)
|
72
|
+
result.should match(/type=/)
|
73
|
+
result.should match(/column_family=/)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|