cql-rb 2.0.5 → 2.1.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
@@ -66,6 +66,18 @@ module Cql
66
66
  end
67
67
  end
68
68
 
69
+ context 'when encoding user defined type values' do
70
+ it 'encodes a null value' do
71
+ converter.to_bytes(buffer, [:udt, {'name' => :string, 'shoe_size' => :int}], nil, 4).should eql_bytes("\xff\xff\xff\xff")
72
+ end
73
+ end
74
+
75
+ context 'when encoding custom values' do
76
+ it 'encodes a null value' do
77
+ converter.to_bytes(buffer, [:custom, 'com.example.CustomType'], nil, 4).should eql_bytes("\xff\xff\xff\xff")
78
+ end
79
+ end
80
+
69
81
  context 'when encoding and decoding negative numbers' do
70
82
  numeric_types.each do |type|
71
83
  it "encodes and decodes a -1 #{type.upcase}" do
@@ -19,7 +19,7 @@ describe 'A CQL client' do
19
19
  client.close rescue nil
20
20
  end
21
21
 
22
- def create_keyspace_and_table
22
+ def create_keyspace
23
23
  begin
24
24
  client.execute(%(DROP KEYSPACE cql_rb_client_spec))
25
25
  rescue Cql::QueryError => e
@@ -27,6 +27,10 @@ describe 'A CQL client' do
27
27
  end
28
28
  client.execute(%(CREATE KEYSPACE cql_rb_client_spec WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1}))
29
29
  client.use('cql_rb_client_spec')
30
+ end
31
+
32
+ def create_keyspace_and_table
33
+ create_keyspace
30
34
  client.execute(%(CREATE TABLE users (user_id VARCHAR PRIMARY KEY, first VARCHAR, last VARCHAR, age INT)))
31
35
  client.execute(%(CREATE TABLE counters (id VARCHAR PRIMARY KEY, count COUNTER)))
32
36
  end
@@ -108,13 +112,6 @@ describe 'A CQL client' do
108
112
  counters = result.each_with_object({}) { |row, acc| acc[row['id']] = row['count'] }
109
113
  counters.should eql('foo' => 11, 'bar' => 3)
110
114
  end
111
-
112
- it 'handles altered tables' do
113
- result1 = statement.execute('sue')
114
- client.execute('ALTER TABLE users ADD password VARCHAR')
115
- result2 = statement.execute('sue')
116
- result2.to_a.should eql(result1.to_a)
117
- end
118
115
  end
119
116
 
120
117
  context 'with multiple connections' do
@@ -445,6 +442,61 @@ describe 'A CQL client' do
445
442
  end
446
443
  end
447
444
 
445
+ context 'with user defined types' do
446
+ before do
447
+ release_version = client.execute('SELECT release_version FROM system.local').first['release_version']
448
+ pending 'User defined types are not available in C* before 2.1.0' unless release_version[0, 5] >= '2.1.0'
449
+ create_keyspace
450
+ client.execute(%(CREATE TYPE address (street TEXT, city TEXT, zip INT)))
451
+ client.execute(%(CREATE TYPE company (name TEXT, addresses LIST<address>)))
452
+ client.execute(%(CREATE TABLE users (id VARCHAR PRIMARY KEY, primary_address address, secondary_addresses MAP<TEXT, address>, employers SET<company>)))
453
+ end
454
+
455
+ it 'inserts records into a table with a user defined type' do
456
+ statement = client.prepare(%(INSERT INTO users (id, primary_address) VALUES (?, ?)))
457
+ statement.execute('sue', {'street' => '123 Some St.', 'city' => 'Frans Sanisco', 'zip' => 76543})
458
+ result = client.execute(%(SELECT primary_address.street AS street FROM users WHERE id = 'sue'))
459
+ result.first['street'].should == '123 Some St.'
460
+ end
461
+
462
+ it 'reads records from a table with a user defined type' do
463
+ client.execute(%(INSERT INTO users (id, primary_address) VALUES ('sue', {street: '123 Some St.', city: 'Frans Sanisco', zip: 76543})))
464
+ result = client.execute(%(SELECT primary_address FROM users WHERE id = 'sue'))
465
+ result.first['primary_address'].should eql('street' => '123 Some St.', 'city' => 'Frans Sanisco', 'zip' => 76543)
466
+ end
467
+
468
+ it 'reads records from a table with a user defined type in a collection' do
469
+ client.execute(<<-CQL)
470
+ INSERT INTO users (id, primary_address, secondary_addresses)
471
+ VALUES (
472
+ 'sue',
473
+ {street: '123 Some St.', city: 'Frans Sanisco', zip: 76543},
474
+ {'secret_lair': {street: '4 Some Other St.', city: 'Gos Latos', zip: 87654}}
475
+ )
476
+ CQL
477
+ result = client.execute(%(SELECT secondary_addresses FROM users WHERE id = 'sue'))
478
+ result.first['secondary_addresses'].should eql('secret_lair' => {'street' => '4 Some Other St.', 'city' => 'Gos Latos', 'zip' => 87654})
479
+ end
480
+
481
+ it 'reads records from a table with user defined types nested in other user defined types, and collections' do
482
+ client.execute(<<-CQL)
483
+ INSERT INTO users (id, employers)
484
+ VALUES (
485
+ 'sue',
486
+ {
487
+ {name: 'Acme Corp', addresses: [{street: '1 St.', city: '1 City', zip: 11111}, {street: '2 St.', city: '2 City', zip: 22222}]},
488
+ {name: 'Foo Inc.', addresses: [{street: '3 St.', city: '3 City', zip: 33333}]}
489
+ }
490
+ )
491
+ CQL
492
+ result = client.execute(%(SELECT employers FROM users WHERE id = 'sue'))
493
+ result.first['employers'].should eql(Set.new([
494
+ {'name' => 'Acme Corp', 'addresses' => [{'street' => '1 St.', 'city' => '1 City', 'zip' => 11111}, {'street' => '2 St.', 'city' => '2 City', 'zip' => 22222}]},
495
+ {'name' => 'Foo Inc.', 'addresses' => [{'street' => '3 St.', 'city' => '3 City', 'zip' => 33333}]}
496
+ ]))
497
+ end
498
+ end
499
+
448
500
  context 'with error conditions' do
449
501
  it 'raises an error for CQL syntax errors' do
450
502
  expect { client.execute('BAD cql') }.to raise_error(Cql::CqlError)
@@ -26,13 +26,13 @@ class FakeIoReactor
26
26
  @before_startup_handler = handler
27
27
  end
28
28
 
29
- def connect(host, port, timeout)
29
+ def connect(host, port, options)
30
30
  if host == '0.0.0.0'
31
31
  Cql::Future.failed(Cql::Io::ConnectionError.new('Can\'t connect to 0.0.0.0'))
32
32
  elsif @down_nodes.include?(host)
33
33
  Cql::Future.failed(Cql::Io::ConnectionError.new('Node down'))
34
34
  else
35
- connection = FakeConnection.new(host, port, timeout)
35
+ connection = FakeConnection.new(host, port, options)
36
36
  @connections << connection
37
37
  @connection_listeners.each do |listener|
38
38
  listener.call(connection)
@@ -71,12 +71,13 @@ class FakeIoReactor
71
71
  end
72
72
 
73
73
  class FakeConnection
74
- attr_reader :host, :port, :timeout, :requests, :keyspace
74
+ attr_reader :host, :port, :timeout, :options, :requests, :keyspace
75
75
 
76
- def initialize(host, port, timeout, data={})
76
+ def initialize(host, port, options={}, data={})
77
77
  @host = host
78
78
  @port = port
79
- @timeout = timeout
79
+ @options = options || {}
80
+ @timeout = @options[:timeout]
80
81
  @requests = []
81
82
  @responses = []
82
83
  @closed = false
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cql-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
4
+ version: 2.1.0.pre0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Theo Hultberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-15 00:00:00.000000000 Z
11
+ date: 2014-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ione
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: '1'
19
+ version: 1.2.0.pre3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: '1'
26
+ version: 1.2.0.pre3
27
27
  description: A pure Ruby CQL3 driver for Cassandra
28
28
  email:
29
29
  - theo@iconara.net
@@ -54,10 +54,10 @@ files:
54
54
  - lib/cql/compression.rb
55
55
  - lib/cql/compression/lz4_compressor.rb
56
56
  - lib/cql/compression/snappy_compressor.rb
57
- - lib/cql/error_codes.rb
58
57
  - lib/cql/protocol.rb
59
58
  - lib/cql/protocol/cql_byte_buffer.rb
60
59
  - lib/cql/protocol/cql_protocol_handler.rb
60
+ - lib/cql/protocol/custom_type_parser.rb
61
61
  - lib/cql/protocol/frame_decoder.rb
62
62
  - lib/cql/protocol/frame_encoder.rb
63
63
  - lib/cql/protocol/request.rb
@@ -111,6 +111,7 @@ files:
111
111
  - spec/cql/compression/snappy_compressor_spec.rb
112
112
  - spec/cql/protocol/cql_byte_buffer_spec.rb
113
113
  - spec/cql/protocol/cql_protocol_handler_spec.rb
114
+ - spec/cql/protocol/custom_type_parser_spec.rb
114
115
  - spec/cql/protocol/frame_decoder_spec.rb
115
116
  - spec/cql/protocol/frame_encoder_spec.rb
116
117
  - spec/cql/protocol/requests/auth_response_request_spec.rb
@@ -166,9 +167,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
167
  version: 1.9.3
167
168
  required_rubygems_version: !ruby/object:Gem::Requirement
168
169
  requirements:
169
- - - ">="
170
+ - - ">"
170
171
  - !ruby/object:Gem::Version
171
- version: '0'
172
+ version: 1.3.1
172
173
  requirements: []
173
174
  rubyforge_project:
174
175
  rubygems_version: 2.2.2
@@ -194,6 +195,7 @@ test_files:
194
195
  - spec/cql/compression/snappy_compressor_spec.rb
195
196
  - spec/cql/protocol/cql_byte_buffer_spec.rb
196
197
  - spec/cql/protocol/cql_protocol_handler_spec.rb
198
+ - spec/cql/protocol/custom_type_parser_spec.rb
197
199
  - spec/cql/protocol/frame_decoder_spec.rb
198
200
  - spec/cql/protocol/frame_encoder_spec.rb
199
201
  - spec/cql/protocol/requests/auth_response_request_spec.rb
@@ -1,96 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Cql
4
- module ErrorCodes
5
- # Something unexpected happened. This indicates a server-side bug.
6
- SERVER_ERROR = 0x0000
7
-
8
- # Some client message triggered a protocol violation (for instance a QUERY
9
- # message is sent before a STARTUP one has been sent).
10
- PROTOCOL_ERROR = 0x000A
11
-
12
- # CREDENTIALS request failed because Cassandra did not accept the provided credentials.
13
- BAD_CREDENTIALS = 0x0100
14
-
15
- # Unavailable exception.
16
- #
17
- # Details:
18
- #
19
- # * `:cl` - The consistency level of the query having triggered the exception.
20
- # * `:required` - An int representing the number of nodes that should be alive to respect `:cl`.
21
- # * `:alive` - An int representing the number of replica that were known to be
22
- # alive when the request has been processed (since an unavailable
23
- # exception has been triggered, there will be `:alive` < `:required`.
24
- UNAVAILABLE = 0x1000
25
-
26
- # The request cannot be processed because the coordinator node is overloaded.
27
- OVERLOADED = 0x1001
28
-
29
- # The request was a read request but the coordinator node is bootstrapping.
30
- IS_BOOTSTRAPPING = 0x1002
31
-
32
- # Error during a truncation error.
33
- TRUNCATE_ERROR = 0x1003
34
-
35
- # Timeout exception during a write request.
36
- #
37
- # Details:
38
- #
39
- # * `:cl` - The consistency level of the query having triggered the exception.
40
- # * `:received` - An int representing the number of nodes having acknowledged the request.
41
- # * `:blockfor` - The number of replica whose acknowledgement is required to achieve `:cl`.
42
- # * `:write_type` - A string that describe the type of the write that timeouted. The value of that string can be one of:
43
- # - `"SIMPLE"`: the write was a non-batched non-counter write.
44
- # - `"BATCH"`: the write was a (logged) batch write. If this type is received, it means the batch log
45
- # has been successfully written (otherwise a `"BATCH_LOG"` type would have been send instead).
46
- # - `"UNLOGGED_BATCH"`: the write was an unlogged batch. Not batch log write has been attempted.
47
- # - `"COUNTER"`: the write was a counter write (batched or not).
48
- # - `"BATCH_LOG"`: the timeout occured during the write to the batch log when a (logged) batch write was requested.
49
- WRITE_TIMEOUT = 0x1100
50
-
51
- # Timeout exception during a read request.
52
- #
53
- # Details:
54
- #
55
- # * `:cl` - The consistency level of the query having triggered the exception
56
- # * `:received` - An int representing the number of nodes having answered the request.
57
- # * `:blockfor` - The number of replica whose response is required to achieve `:cl`.
58
- # Please note that it is possible to have `:received` >= `:blockfor` if
59
- # `:data_present` is false. And also in the (unlikely) case were `:cl` is
60
- # achieved but the coordinator node timeout while waiting for read-repair
61
- # acknowledgement.
62
- # * `:data_present` - If `true`, it means the replica that was asked for data has not responded.
63
- READ_TIMEOUT = 0x1200
64
-
65
- # The submitted query has a syntax error.
66
- SYNTAX_ERROR = 0x2000
67
-
68
- # The logged user doesn't have the right to perform the query.
69
- UNAUTHORIZED = 0x2100
70
-
71
- # The query is syntactically correct but invalid.
72
- INVALID = 0x2200
73
-
74
- # The query is invalid because of some configuration issue.
75
- CONFIG_ERROR = 0x2300
76
-
77
- # The query attempted to create a keyspace or a table that was already existing.
78
- #
79
- # Details:
80
- #
81
- # * `:ks` - A string representing either the keyspace that already exists, or the
82
- # keyspace in which the table that already exists is.
83
- # * `:table` - A string representing the name of the table that already exists. If the
84
- # query was attempting to create a keyspace, `:table` will be present but
85
- # will be the empty string.
86
- ALREADY_EXISTS = 0x2400
87
-
88
- # Can be thrown while a prepared statement tries to be executed if the
89
- # provide prepared statement ID is not known by this host.
90
- #
91
- # Details:
92
- #
93
- # * `:id` - The unknown ID.
94
- UNPREPARED = 0x2500
95
- end
96
- end