cql-rb 2.0.5 → 2.1.0.pre0

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.
@@ -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