cassanity 0.5.1 → 0.6.0.beta1

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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +1 -1
  3. data/README.md +3 -16
  4. data/cassanity.gemspec +3 -1
  5. data/examples/keyspaces.rb +2 -2
  6. data/lib/cassanity/argument_generators/column_families.rb +1 -1
  7. data/lib/cassanity/argument_generators/columns.rb +2 -2
  8. data/lib/cassanity/argument_generators/keyspace_create.rb +4 -21
  9. data/lib/cassanity/argument_generators/with_clause.rb +2 -9
  10. data/lib/cassanity/client.rb +16 -13
  11. data/lib/cassanity/executors/{cassandra_cql.rb → cql_rb.rb} +28 -11
  12. data/lib/cassanity/keyspace.rb +7 -22
  13. data/lib/cassanity/migrator.rb +2 -2
  14. data/lib/cassanity/result_transformers/column_families.rb +1 -1
  15. data/lib/cassanity/result_transformers/columns.rb +2 -2
  16. data/lib/cassanity/result_transformers/keyspaces.rb +1 -1
  17. data/lib/cassanity/result_transformers/result_to_array.rb +1 -5
  18. data/lib/cassanity/retry_strategies/retry_strategy.rb +3 -3
  19. data/lib/cassanity/statement.rb +58 -0
  20. data/lib/cassanity/version.rb +1 -1
  21. data/spec/helper.rb +2 -4
  22. data/spec/integration/cassanity/column_family_spec.rb +62 -64
  23. data/spec/integration/cassanity/connection_spec.rb +2 -8
  24. data/spec/integration/cassanity/instrumentation/log_subscriber_spec.rb +4 -1
  25. data/spec/integration/cassanity/instrumentation/metriks_subscriber_spec.rb +2 -1
  26. data/spec/integration/cassanity/instrumentation/statsd_subscriber_spec.rb +2 -1
  27. data/spec/integration/cassanity/keyspace_spec.rb +1 -1
  28. data/spec/integration/cassanity/migration_spec.rb +5 -5
  29. data/spec/integration/cassanity/migrator_spec.rb +4 -4
  30. data/spec/support/cassanity_helpers.rb +7 -5
  31. data/spec/unit/cassanity/argument_generators/column_families_spec.rb +1 -1
  32. data/spec/unit/cassanity/argument_generators/columns_spec.rb +3 -3
  33. data/spec/unit/cassanity/argument_generators/keyspace_create_spec.rb +12 -16
  34. data/spec/unit/cassanity/argument_generators/with_clause_spec.rb +5 -6
  35. data/spec/unit/cassanity/client_spec.rb +15 -53
  36. data/spec/unit/cassanity/connection_spec.rb +6 -6
  37. data/spec/unit/cassanity/keyspace_spec.rb +12 -14
  38. data/spec/unit/cassanity/result_transformers/result_to_array_spec.rb +3 -16
  39. data/spec/unit/cassanity/statement_spec.rb +100 -0
  40. metadata +35 -24
  41. data/spec/unit/cassanity/executors/cassandra_cql_spec.rb +0 -286
@@ -6,83 +6,45 @@ describe Cassanity::Client do
6
6
 
7
7
  before do
8
8
  # Ensure that we never hit cassandra for real here.
9
- CassandraCQL::Database.stub(:new => driver)
9
+ Cql::Client.stub(:connect => driver)
10
10
  end
11
11
 
12
12
  describe "#initialize" do
13
13
  it "passes arguments to cassandra cql database instance" do
14
- CassandraCQL::Database.should_receive(:new).
15
- with(
16
- 'localhost:1234',
17
- hash_including(some: 'option'),
18
- instance_of(Hash)
19
- )
20
-
21
- described_class.new('localhost:1234', some: 'option')
14
+ Cql::Client.should_receive(:connect).
15
+ with(hash_including(hosts: ['localhost'], port: 1234, some: 'option'))
16
+
17
+ described_class.new(['localhost'], 1234, some: 'option')
22
18
  end
23
19
 
24
20
  it "defaults servers if not present" do
25
- CassandraCQL::Database.should_receive(:new).
26
- with(
27
- '127.0.0.1:9160',
28
- instance_of(Hash),
29
- instance_of(Hash)
30
- )
21
+ Cql::Client.should_receive(:connect).
22
+ with(hash_including(hosts: ['127.0.0.1'], port: 9042))
31
23
 
32
24
  described_class.new
33
25
  end
34
26
 
35
27
  it "defaults servers if nil" do
36
- CassandraCQL::Database.should_receive(:new).
37
- with(
38
- '127.0.0.1:9160',
39
- instance_of(Hash),
40
- instance_of(Hash)
41
- )
28
+ Cql::Client.should_receive(:connect).
29
+ with(hash_including(hosts: ['127.0.0.1'], port: 9042))
42
30
 
43
31
  described_class.new(nil)
44
32
  end
45
33
 
46
- it "defaults cql version in options to 3" do
47
- CassandraCQL::Database.should_receive(:new).
48
- with(
49
- anything,
50
- hash_including(cql_version: '3.0.0'),
51
- instance_of(Hash)
52
- )
53
-
54
- described_class.new
55
- end
56
-
57
- it "does not override cql version option if other options are provided" do
58
- CassandraCQL::Database.should_receive(:new).
59
- with(
60
- anything,
61
- hash_including(cql_version: '3.0.0', some: 'thing'),
62
- instance_of(Hash)
63
- )
64
-
65
- described_class.new('localhost:1234', some: 'thing')
66
- end
67
-
68
34
  it "allows passing instrumenter to executor, but does not pass it to driver instance" do
69
35
  instrumenter = double('Instrumenter')
70
36
  driver = double('Driver')
71
37
  executor = double('Executor')
72
38
 
73
- CassandraCQL::Database.should_receive(:new).
74
- with(
75
- anything,
76
- hash_not_including(instrumenter: instrumenter),
77
- instance_of(Hash)
78
- ).
39
+ Cql::Client.should_receive(:connect).
40
+ with(hash_not_including(instrumenter: instrumenter)).
79
41
  and_return(driver)
80
42
 
81
- Cassanity::Executors::CassandraCql.should_receive(:new).
43
+ Cassanity::Executors::CqlRb.should_receive(:new).
82
44
  with(hash_including(driver: driver, instrumenter: instrumenter)).
83
45
  and_return(executor)
84
46
 
85
- described_class.new('localhost:1234', instrumenter: instrumenter)
47
+ described_class.new(['localhost'], 1234, instrumenter: instrumenter)
86
48
  end
87
49
 
88
50
  it "sets cassandra cql database instance as driver" do
@@ -95,9 +57,9 @@ describe Cassanity::Client do
95
57
  executor = double('Executor')
96
58
  connection = double('Connection')
97
59
 
98
- CassandraCQL::Database.should_receive(:new).and_return(driver)
60
+ Cql::Client.should_receive(:connect).and_return(driver)
99
61
 
100
- Cassanity::Executors::CassandraCql.should_receive(:new).
62
+ Cassanity::Executors::CqlRb.should_receive(:new).
101
63
  with(hash_including(driver: driver)).
102
64
  and_return(executor)
103
65
 
@@ -55,7 +55,7 @@ describe Cassanity::Connection do
55
55
  context "with name and args" do
56
56
  before do
57
57
  @return_value = subject.keyspace(keyspace_name, {
58
- strategy_class: 'NetworkTopologyStrategy',
58
+ replication: {class: 'NetworkTopologyStrategy'},
59
59
  })
60
60
  end
61
61
 
@@ -64,7 +64,7 @@ describe Cassanity::Connection do
64
64
  end
65
65
 
66
66
  it "passes args to initialization" do
67
- @return_value.strategy_class.should eq('NetworkTopologyStrategy')
67
+ @return_value.replication.should eq(class: 'NetworkTopologyStrategy')
68
68
  end
69
69
 
70
70
  it "returns instance of keyspace" do
@@ -76,7 +76,7 @@ describe Cassanity::Connection do
76
76
  before do
77
77
  @return_value = subject.keyspace({
78
78
  name: keyspace_name,
79
- strategy_class: 'NetworkTopologyStrategy',
79
+ replication: {class: 'NetworkTopologyStrategy'},
80
80
  })
81
81
  end
82
82
 
@@ -89,7 +89,7 @@ describe Cassanity::Connection do
89
89
  end
90
90
 
91
91
  it "passes args to initialization" do
92
- @return_value.strategy_class.should eq('NetworkTopologyStrategy')
92
+ @return_value.replication.should eq(class: 'NetworkTopologyStrategy')
93
93
  end
94
94
  end
95
95
 
@@ -98,7 +98,7 @@ describe Cassanity::Connection do
98
98
  @return_value = subject.keyspace({
99
99
  name: keyspace_name,
100
100
  }, {
101
- strategy_class: 'NetworkTopologyStrategy',
101
+ replication: {class: 'NetworkTopologyStrategy'},
102
102
  })
103
103
  end
104
104
 
@@ -111,7 +111,7 @@ describe Cassanity::Connection do
111
111
  end
112
112
 
113
113
  it "passes args to initialization" do
114
- @return_value.strategy_class.should eq('NetworkTopologyStrategy')
114
+ @return_value.replication.should eq(class: 'NetworkTopologyStrategy')
115
115
  end
116
116
  end
117
117
  end
@@ -36,23 +36,23 @@ describe Cassanity::Keyspace do
36
36
  end
37
37
  end
38
38
 
39
- it "sets strategy_class if provided" do
39
+ it "sets class if provided" do
40
40
  instance = described_class.new(required_arguments.merge({
41
- strategy_class: 'NetworkTopologyStrategy',
41
+ replication: {class: 'NetworkTopologyStrategy'},
42
42
  }))
43
43
 
44
- instance.strategy_class.should eq('NetworkTopologyStrategy')
44
+ instance.replication.should eq(class: 'NetworkTopologyStrategy')
45
45
  end
46
46
 
47
- it "sets strategy_options if provided" do
47
+ it "sets strategy options if provided" do
48
48
  instance = described_class.new(required_arguments.merge({
49
- strategy_options: {
49
+ replication: {
50
50
  dc1: 3,
51
51
  dc2: 5,
52
52
  },
53
53
  }))
54
54
 
55
- instance.strategy_options.should eq({
55
+ instance.replication.should eq({
56
56
  dc1: 3,
57
57
  dc2: 5,
58
58
  })
@@ -236,7 +236,7 @@ describe Cassanity::Keyspace do
236
236
  args = {something: 'else'}
237
237
  executor.should_receive(:call).with({
238
238
  command: :keyspace_create,
239
- arguments: args.merge(keyspace_name: keyspace_name),
239
+ arguments: args.merge(keyspace_name: keyspace_name, replication: {}),
240
240
  })
241
241
  subject.create(args)
242
242
  end
@@ -248,32 +248,30 @@ describe Cassanity::Keyspace do
248
248
  command: :keyspace_create,
249
249
  arguments: args.merge({
250
250
  keyspace_name: keyspace_name,
251
- strategy_class: 'NetworkTopologyStrategy',
252
- strategy_options: {replication_factory: 3},
251
+ replication: {class: 'NetworkTopologyStrategy', replication_factory: 3},
253
252
  }),
254
253
  })
255
254
 
256
255
  instance = described_class.new(required_arguments.merge({
257
- strategy_class: 'NetworkTopologyStrategy',
258
- strategy_options: {replication_factory: 3},
256
+ replication: {class: 'NetworkTopologyStrategy', replication_factory: 3},
259
257
  }))
260
258
 
261
259
  instance.create(args)
262
260
  end
263
261
 
264
262
  it "merges strategy options in args with initialized strategy options" do
265
- args = {strategy_options: {dc1: 1}}
263
+ args = {replication: {dc1: 1}}
266
264
 
267
265
  executor.should_receive(:call).with({
268
266
  command: :keyspace_create,
269
267
  arguments: {
270
268
  keyspace_name: keyspace_name,
271
- strategy_options: {dc1: 1, dc2: 2},
269
+ replication: {dc1: 1, dc2: 2},
272
270
  },
273
271
  })
274
272
 
275
273
  instance = described_class.new(required_arguments.merge({
276
- strategy_options: {dc2: 2},
274
+ replication: {dc2: 2},
277
275
  }))
278
276
 
279
277
  instance.create(args)
@@ -6,23 +6,10 @@ describe Cassanity::ResultTransformers::ResultToArray do
6
6
  [{one: 1}, {two: 2}, {three: 3}]
7
7
  }
8
8
 
9
- let(:result) {
10
- Class.new do
11
- def initialize(array)
12
- @array = array
13
- end
14
-
15
- def fetch_hash
16
- @array.each do |row|
17
- yield row
18
- end
19
- end
20
- end.new(result_array)
21
- }
22
-
23
9
  describe "#call" do
24
- it "it iterates fetch_hash and returns array" do
25
- subject.call(result).should eq(result_array)
10
+ it "returns a copy of the array" do
11
+ subject.call(result_array).should eq(result_array)
12
+ subject.call(result_array).should_not equal(result_array)
26
13
  end
27
14
  end
28
15
  end
@@ -0,0 +1,100 @@
1
+ # encoding: utf-8
2
+ require 'helper'
3
+ require 'ostruct'
4
+ require 'cassanity/statement'
5
+
6
+ describe Cassanity::Statement do
7
+ describe 'variable interpolation' do
8
+ it 'interpolates strings' do
9
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?)')
10
+ expect(stmt.interpolate(["str"])).to eq(
11
+ "INSERT INTO foo VALUES ('str')"
12
+ )
13
+ end
14
+
15
+ it 'interpolates strings, escaping single quotes' do
16
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?)')
17
+ expect(stmt.interpolate(["testing'123"])).to eq(
18
+ "INSERT INTO foo VALUES ('testing''123')"
19
+ )
20
+ end
21
+
22
+ it 'interpolates strings containing binary data'
23
+
24
+ it 'interpolates numerics' do
25
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?,?)')
26
+ expect(stmt.interpolate([123, 456.78])).to eq(
27
+ "INSERT INTO foo VALUES (123,456.78)"
28
+ )
29
+ end
30
+
31
+ it 'interpolates big decimals' do
32
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?)')
33
+ expect(stmt.interpolate([BigDecimal.new("1234.56")])).to eq(
34
+ "INSERT INTO foo VALUES (0.123456E4)"
35
+ )
36
+ end
37
+
38
+ it 'interpolates booleans' do
39
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?,?)')
40
+ expect(stmt.interpolate([true, false])).to eq(
41
+ "INSERT INTO foo VALUES (true,false)"
42
+ )
43
+ end
44
+
45
+ it 'interpolates dates and times' do
46
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?,?)')
47
+ expect(stmt.interpolate([Date.new(2013, 5, 1), Time.utc(2013, 5, 1)])).to eq(
48
+ "INSERT INTO foo VALUES ('2013-05-01',1367366400000)"
49
+ )
50
+ end
51
+
52
+ it 'interpolates guids' do
53
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?)')
54
+ expect(stmt.interpolate([OpenStruct.new(to_guid: 'abc-123-def')])).to eq(
55
+ "INSERT INTO foo VALUES (abc-123-def)"
56
+ )
57
+ end
58
+
59
+ it 'interpolates arrays, recursively escaping each value' do
60
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?)')
61
+ expect(stmt.interpolate([["str", 123]])).to eq(
62
+ "INSERT INTO foo VALUES ('str',123)"
63
+ )
64
+ end
65
+
66
+ it 'interpolates hashes, recursively escaping each key/value' do
67
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?)')
68
+ expect(stmt.interpolate([{"foo" => 123}])).to eq(
69
+ "INSERT INTO foo VALUES ({'foo':123})"
70
+ )
71
+ end
72
+
73
+ it 'interpolates other items that can be converted to strings' do
74
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?)')
75
+
76
+ o = Object.new
77
+ def o.to_s; "string value"; end
78
+
79
+ expect(stmt.interpolate([o])).to eq(
80
+ "INSERT INTO foo VALUES ('string value')"
81
+ )
82
+ end
83
+
84
+ context 'cql version 2' do
85
+ it 'quotes big decimals values' do
86
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?)', cql_version: '2.0.0')
87
+ expect(stmt.interpolate([BigDecimal.new("1234.56")])).to eq(
88
+ "INSERT INTO foo VALUES ('0.123456E4')"
89
+ )
90
+ end
91
+
92
+ it 'quotes boolean values' do
93
+ stmt = Cassanity::Statement.new('INSERT INTO foo VALUES (?,?)', cql_version: '2.0.0')
94
+ expect(stmt.interpolate([true, false])).to eq(
95
+ "INSERT INTO foo VALUES ('true','false')"
96
+ )
97
+ end
98
+ end
99
+ end
100
+ end
metadata CHANGED
@@ -1,32 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cassanity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
5
- prerelease:
4
+ version: 0.6.0.beta1
6
5
  platform: ruby
7
6
  authors:
8
7
  - John Nunemaker
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-24 00:00:00.000000000 Z
11
+ date: 2013-12-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: cassandra-cql
14
+ name: cql-rb
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
21
- version: 1.1.3
19
+ version: '1.1'
20
+ - - '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.1
22
23
  type: :runtime
23
24
  prerelease: false
24
25
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 1.1.3
29
+ version: '1.1'
30
+ - - '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.1.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: simple_uuid
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: '0.4'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: '0.4'
30
47
  description: Layer of goodness on top of cassandra-cql so you do not have to write
31
48
  CQL strings all over the place.
32
49
  email:
@@ -83,7 +100,7 @@ files:
83
100
  - lib/cassanity/connection.rb
84
101
  - lib/cassanity/decrement.rb
85
102
  - lib/cassanity/error.rb
86
- - lib/cassanity/executors/cassandra_cql.rb
103
+ - lib/cassanity/executors/cql_rb.rb
87
104
  - lib/cassanity/increment.rb
88
105
  - lib/cassanity/instrumentation/log_subscriber.rb
89
106
  - lib/cassanity/instrumentation/metriks.rb
@@ -113,6 +130,7 @@ files:
113
130
  - lib/cassanity/retry_strategies/retry_n_times.rb
114
131
  - lib/cassanity/retry_strategies/retry_strategy.rb
115
132
  - lib/cassanity/schema.rb
133
+ - lib/cassanity/statement.rb
116
134
  - lib/cassanity/version.rb
117
135
  - spec/helper.rb
118
136
  - spec/integration/cassanity/column_family_spec.rb
@@ -157,7 +175,6 @@ files:
157
175
  - spec/unit/cassanity/connection_spec.rb
158
176
  - spec/unit/cassanity/decrement_spec.rb
159
177
  - spec/unit/cassanity/error_spec.rb
160
- - spec/unit/cassanity/executors/cassandra_cql_spec.rb
161
178
  - spec/unit/cassanity/increment_spec.rb
162
179
  - spec/unit/cassanity/instrumentors/memory_spec.rb
163
180
  - spec/unit/cassanity/instrumentors/noop_spec.rb
@@ -177,36 +194,30 @@ files:
177
194
  - spec/unit/cassanity/retry_strategies/retry_n_times_spec.rb
178
195
  - spec/unit/cassanity/retry_strategies/retry_strategy_spec.rb
179
196
  - spec/unit/cassanity/schema_spec.rb
197
+ - spec/unit/cassanity/statement_spec.rb
180
198
  - spec/unit/cassanity_spec.rb
181
199
  homepage: http://johnnunemaker.com/cassanity/
182
200
  licenses: []
201
+ metadata: {}
183
202
  post_install_message:
184
203
  rdoc_options: []
185
204
  require_paths:
186
205
  - lib
187
206
  required_ruby_version: !ruby/object:Gem::Requirement
188
- none: false
189
207
  requirements:
190
- - - ! '>='
208
+ - - '>='
191
209
  - !ruby/object:Gem::Version
192
210
  version: '0'
193
- segments:
194
- - 0
195
- hash: -90461320440382772
196
211
  required_rubygems_version: !ruby/object:Gem::Requirement
197
- none: false
198
212
  requirements:
199
- - - ! '>='
213
+ - - '>'
200
214
  - !ruby/object:Gem::Version
201
- version: '0'
202
- segments:
203
- - 0
204
- hash: -90461320440382772
215
+ version: 1.3.1
205
216
  requirements: []
206
217
  rubyforge_project:
207
- rubygems_version: 1.8.23
218
+ rubygems_version: 2.0.3
208
219
  signing_key:
209
- specification_version: 3
220
+ specification_version: 4
210
221
  summary: Layer of goodness on top of cassandra-cql so you do not have to write CQL
211
222
  strings all over the place.
212
223
  test_files:
@@ -253,7 +264,6 @@ test_files:
253
264
  - spec/unit/cassanity/connection_spec.rb
254
265
  - spec/unit/cassanity/decrement_spec.rb
255
266
  - spec/unit/cassanity/error_spec.rb
256
- - spec/unit/cassanity/executors/cassandra_cql_spec.rb
257
267
  - spec/unit/cassanity/increment_spec.rb
258
268
  - spec/unit/cassanity/instrumentors/memory_spec.rb
259
269
  - spec/unit/cassanity/instrumentors/noop_spec.rb
@@ -273,4 +283,5 @@ test_files:
273
283
  - spec/unit/cassanity/retry_strategies/retry_n_times_spec.rb
274
284
  - spec/unit/cassanity/retry_strategies/retry_strategy_spec.rb
275
285
  - spec/unit/cassanity/schema_spec.rb
286
+ - spec/unit/cassanity/statement_spec.rb
276
287
  - spec/unit/cassanity_spec.rb