cql-rb 1.0.0.pre6 → 1.0.0.pre7

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 (34) hide show
  1. data/bin/cqlexec +2 -2
  2. data/lib/cql/protocol.rb +26 -1
  3. data/lib/cql/protocol/decoding.rb +3 -0
  4. data/lib/cql/protocol/request_body.rb +15 -0
  5. data/lib/cql/protocol/request_frame.rb +1 -266
  6. data/lib/cql/protocol/requests/credentials_request.rb +31 -0
  7. data/lib/cql/protocol/requests/execute_request.rb +129 -0
  8. data/lib/cql/protocol/requests/options_request.rb +19 -0
  9. data/lib/cql/protocol/requests/prepare_request.rb +31 -0
  10. data/lib/cql/protocol/requests/query_request.rb +33 -0
  11. data/lib/cql/protocol/requests/register_request.rb +20 -0
  12. data/lib/cql/protocol/requests/startup_request.rb +27 -0
  13. data/lib/cql/protocol/response_body.rb +13 -0
  14. data/lib/cql/protocol/response_frame.rb +1 -533
  15. data/lib/cql/protocol/responses/authenticate_response.rb +21 -0
  16. data/lib/cql/protocol/responses/detailed_error_response.rb +44 -0
  17. data/lib/cql/protocol/responses/error_response.rb +28 -0
  18. data/lib/cql/protocol/responses/event_response.rb +21 -0
  19. data/lib/cql/protocol/responses/prepared_result_response.rb +23 -0
  20. data/lib/cql/protocol/responses/ready_response.rb +24 -0
  21. data/lib/cql/protocol/responses/result_response.rb +29 -0
  22. data/lib/cql/protocol/responses/rows_result_response.rb +100 -0
  23. data/lib/cql/protocol/responses/schema_change_event_result_response.rb +40 -0
  24. data/lib/cql/protocol/responses/schema_change_result_response.rb +21 -0
  25. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +21 -0
  26. data/lib/cql/protocol/responses/status_change_event_result_response.rb +24 -0
  27. data/lib/cql/protocol/responses/supported_response.rb +21 -0
  28. data/lib/cql/protocol/responses/topology_change_event_result_response.rb +14 -0
  29. data/lib/cql/protocol/responses/void_result_response.rb +19 -0
  30. data/lib/cql/protocol/type_converter.rb +165 -0
  31. data/lib/cql/version.rb +1 -1
  32. data/spec/cql/protocol/response_frame_spec.rb +31 -0
  33. data/spec/integration/regression_spec.rb +56 -9
  34. metadata +27 -2
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class VoidResultResponse < ResultResponse
6
+ def self.decode!(buffer)
7
+ new
8
+ end
9
+
10
+ def to_s
11
+ %(RESULT VOID)
12
+ end
13
+
14
+ def void?
15
+ true
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,165 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ipaddr'
4
+ require 'set'
5
+
6
+
7
+ module Cql
8
+ module Protocol
9
+ class TypeConverter
10
+ include Decoding
11
+
12
+ def initialize
13
+ @conversions = conversions
14
+ end
15
+
16
+ def convert_type(buffer, type, size_bytes=4)
17
+ return nil if buffer.empty?
18
+ case type
19
+ when Array
20
+ return nil unless read_size(buffer, size_bytes)
21
+ case type.first
22
+ when :list
23
+ convert_list(buffer, @conversions[type[1]])
24
+ when :map
25
+ convert_map(buffer, @conversions[type[1]], @conversions[type[2]])
26
+ when :set
27
+ convert_set(buffer, @conversions[type[1]])
28
+ end
29
+ else
30
+ @conversions[type].call(buffer, size_bytes)
31
+ end
32
+ end
33
+
34
+ def conversions
35
+ {
36
+ :ascii => method(:convert_ascii),
37
+ :bigint => method(:convert_bigint),
38
+ :blob => method(:convert_blob),
39
+ :boolean => method(:convert_boolean),
40
+ :counter => method(:convert_bigint),
41
+ :decimal => method(:convert_decimal),
42
+ :double => method(:convert_double),
43
+ :float => method(:convert_float),
44
+ :int => method(:convert_int),
45
+ :timestamp => method(:convert_timestamp),
46
+ :varchar => method(:convert_varchar),
47
+ :text => method(:convert_varchar),
48
+ :varint => method(:convert_varint),
49
+ :timeuuid => method(:convert_uuid),
50
+ :uuid => method(:convert_uuid),
51
+ :inet => method(:convert_inet),
52
+ }
53
+ end
54
+
55
+ def convert_ascii(buffer, size_bytes)
56
+ bytes = size_bytes == 4 ? read_bytes!(buffer) : read_short_bytes!(buffer)
57
+ bytes ? bytes.force_encoding(::Encoding::ASCII) : nil
58
+ end
59
+
60
+ def convert_bigint(buffer, size_bytes)
61
+ return nil unless read_size(buffer, size_bytes)
62
+ read_long!(buffer)
63
+ end
64
+
65
+ def convert_blob(buffer, size_bytes)
66
+ bytes = size_bytes == 4 ? read_bytes!(buffer) : read_short_bytes!(buffer)
67
+ bytes ? bytes : nil
68
+ end
69
+
70
+ def convert_boolean(buffer, size_bytes)
71
+ return nil unless read_size(buffer, size_bytes)
72
+ buffer.read(1) == Constants::TRUE_BYTE
73
+ end
74
+
75
+ def convert_decimal(buffer, size_bytes)
76
+ size = read_size(buffer, size_bytes)
77
+ return nil unless size
78
+ read_decimal!(buffer, size)
79
+ end
80
+
81
+ def convert_double(buffer, size_bytes)
82
+ return nil unless read_size(buffer, size_bytes)
83
+ read_double!(buffer)
84
+ end
85
+
86
+ def convert_float(buffer, size_bytes)
87
+ return nil unless read_size(buffer, size_bytes)
88
+ read_float!(buffer)
89
+ end
90
+
91
+ def convert_int(buffer, size_bytes)
92
+ return nil unless read_size(buffer, size_bytes)
93
+ read_int!(buffer)
94
+ end
95
+
96
+ def convert_timestamp(buffer, size_bytes)
97
+ return nil unless read_size(buffer, size_bytes)
98
+ timestamp = read_long!(buffer)
99
+ Time.at(timestamp/1000.0)
100
+ end
101
+
102
+ def convert_varchar(buffer, size_bytes)
103
+ bytes = size_bytes == 4 ? read_bytes!(buffer) : read_short_bytes!(buffer)
104
+ bytes ? bytes.force_encoding(::Encoding::UTF_8) : nil
105
+ end
106
+
107
+ def convert_varint(buffer, size_bytes)
108
+ size = read_size(buffer, size_bytes)
109
+ return nil unless size
110
+ read_varint!(buffer, size)
111
+ end
112
+
113
+ def convert_uuid(buffer, size_bytes)
114
+ return nil unless read_size(buffer, size_bytes)
115
+ read_uuid!(buffer)
116
+ end
117
+
118
+ def convert_inet(buffer, size_bytes)
119
+ size = read_size(buffer, size_bytes)
120
+ return nil unless size
121
+ IPAddr.new_ntoh(buffer.read(size))
122
+ end
123
+
124
+ def convert_list(buffer, value_converter)
125
+ list = []
126
+ size = buffer.read_short
127
+ size.times do
128
+ list << value_converter.call(buffer, 2)
129
+ end
130
+ list
131
+ end
132
+
133
+ def convert_map(buffer, key_converter, value_converter)
134
+ map = {}
135
+ size = buffer.read_short
136
+ size.times do
137
+ key = key_converter.call(buffer, 2)
138
+ value = value_converter.call(buffer, 2)
139
+ map[key] = value
140
+ end
141
+ map
142
+ end
143
+
144
+ def convert_set(buffer, value_converter)
145
+ set = Set.new
146
+ size = buffer.read_short
147
+ size.times do
148
+ set << value_converter.call(buffer, 2)
149
+ end
150
+ set
151
+ end
152
+
153
+ def read_size(buffer, size_bytes)
154
+ if size_bytes == 2
155
+ size = buffer.read_short
156
+ return nil if size & 0x8000 == 0x8000
157
+ else
158
+ size = buffer.read_int
159
+ return nil if size & 0x80000000 == 0x80000000
160
+ end
161
+ size
162
+ end
163
+ end
164
+ end
165
+ end
data/lib/cql/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cql
4
- VERSION = '1.0.0.pre6'.freeze
4
+ VERSION = '1.0.0.pre7'.freeze
5
5
  end
@@ -540,11 +540,42 @@ module Cql
540
540
  frame.body.rows.first['set_column'].should == Set.new(["\xab\x43\x21", "\xaf\xd8\x7e\xcd"].map { |s| s.force_encoding(::Encoding::BINARY) })
541
541
  end
542
542
 
543
+ it 'decodes nulls' do
544
+ frame = described_class.new(ByteBuffer.new("\x81\x00\x00\b\x00\x00\x01\xB6\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x13\x00\x12cql_rb_client_spec\x00\rlots_of_types\x00\x02id\x00\t\x00\fascii_column\x00\x01\x00\rbigint_column\x00\x02\x00\vblob_column\x00\x03\x00\x0Eboolean_column\x00\x04\x00\x0Edecimal_column\x00\x06\x00\rdouble_column\x00\a\x00\ffloat_column\x00\b\x00\vinet_column\x00\x10\x00\nint_column\x00\t\x00\vlist_column\x00 \x00\x01\x00\nmap_column\x00!\x00\r\x00\x04\x00\nset_column\x00\"\x00\x03\x00\vtext_column\x00\r\x00\x10timestamp_column\x00\v\x00\x0Ftimeuuid_column\x00\x0F\x00\vuuid_column\x00\f\x00\x0Evarchar_column\x00\r\x00\rvarint_column\x00\x0E\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"))
545
+ row = frame.body.rows.first
546
+ row.should eql(
547
+ 'id' => 3,
548
+ 'ascii_column' => nil,
549
+ 'bigint_column' => nil,
550
+ 'blob_column' => nil,
551
+ 'boolean_column' => nil,
552
+ 'decimal_column' => nil,
553
+ 'double_column' => nil,
554
+ 'float_column' => nil,
555
+ 'int_column' => nil,
556
+ 'text_column' => nil,
557
+ 'timestamp_column' => nil,
558
+ 'uuid_column' => nil,
559
+ 'varchar_column' => nil,
560
+ 'varint_column' => nil,
561
+ 'timeuuid_column' => nil,
562
+ 'inet_column' => nil,
563
+ 'list_column' => nil,
564
+ 'map_column' => nil,
565
+ 'set_column' => nil,
566
+ )
567
+ end
568
+
543
569
  it 'decodes COUNTER as a number' do
544
570
  frame = described_class.new(ByteBuffer.new("\x81\x00\x00\b\x00\x00\x00N\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\x00\x04test\x00\x04cnts\x00\x02id\x00\r\x00\x02c1\x00\x05\x00\x02c2\x00\x05\x00\x00\x00\x01\x00\x00\x00\x04theo\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x01"))
545
571
  frame.body.rows.first['c1'].should == 3
546
572
  end
547
573
 
574
+ it 'decodes a null COUNTER as nil' do
575
+ frame = described_class.new(ByteBuffer.new("\x81\x00\x00\b\x00\x00\x00V\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x12cql_rb_client_spec\x00\bcounters\x00\bcounter1\x00\x05\x00\bcounter2\x00\x05\x00\x00\x00\x01\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xFF\xFF"))
576
+ frame.body.rows.first['counter2'].should be_nil
577
+ end
578
+
548
579
  it 'raises an error when encountering an unknown column type' do
549
580
  frame = described_class.new
550
581
  frame << "\x81\x00\x00\b\x00\x00\x00E"
@@ -20,7 +20,7 @@ describe 'Regressions' do
20
20
  end
21
21
 
22
22
  after do
23
- client.execute('DROP KEYSPACE cql_rb_client_spec')
23
+ client.execute('DROP KEYSPACE cql_rb_client_spec') rescue nil
24
24
  client.close
25
25
  end
26
26
 
@@ -63,18 +63,65 @@ describe 'Regressions' do
63
63
  end
64
64
  end
65
65
 
66
- context 'wat' do
67
- it 'finds all things' do
68
- client.execute('CREATE TABLE t_b (a BIGINT, b BOOLEAN, c SET<BIGINT>, PRIMARY KEY (a, b))')
69
- client.execute('INSERT INTO t_b (a, b, c) VALUES (271, false, {429512359, 22140083129, 154124373, 7133790052, 3263802876, 7306375341, 1086106894, 18819871958, 2754233688, 11353254728, 9045041985, 17997058330, 12443485304, 8549364896, 731630293, 21159857519, 1111535777, 3180792037, 9563930655, 7144898604, 12770338502, 22740775138, 18618244615, 22214143018, 6934152431, 18762976055, 17285647286, 20125813811, 9133629150, 15424700007, 118980476, 14741258930, 18779991792, 8324600546, 11637140295, 9991399356, 19199483004, 21445636099, 16558957905, 15918629196, 18233976642, 11046492659, 6935319727, 10159850783, 4663807554, 7355805674, 7635043414, 21675092442, 13600103335, 22306919328, 9217523096, 12529064948, 8776455938, 2245602097, 15670128881, 18058001691, 21092222111, 17277710588, 14115070523, 9070732951, 2812255943, 9349962400, 3159466851, 16008470639, 19953811077, 21577742012, 22095236133, 14644601174, 8617764033, 16140330747, 6430474270, 8193684764, 18867977174, 19652105799, 17553107189, 18499057047, 15047410679, 14622689532, 116299629, 7516765793, 8115675759, 16051975041, 16430971219, 10443592529, 7029456978, 4636255483, 10311426631, 18607907259, 13049692716, 20594963153, 11747270720, 8552608868, 13807260864, 18374272405, 19847587719, 12573496801, 2860931462, 16578852692, 22804253685, 2720329280})')
70
- result = client.execute('SELECT * FROM t_b')
71
- raise unless result.first['c'] == Set.new([429512359, 22140083129, 154124373, 7133790052, 3263802876, 7306375341, 1086106894, 18819871958, 2754233688, 11353254728, 9045041985, 17997058330, 12443485304, 8549364896, 731630293, 21159857519, 1111535777, 3180792037, 9563930655, 7144898604, 12770338502, 22740775138, 18618244615, 22214143018, 6934152431, 18762976055, 17285647286, 20125813811, 9133629150, 15424700007, 118980476, 14741258930, 18779991792, 8324600546, 11637140295, 9991399356, 19199483004, 21445636099, 16558957905, 15918629196, 18233976642, 11046492659, 6935319727, 10159850783, 4663807554, 7355805674, 7635043414, 21675092442, 13600103335, 22306919328, 9217523096, 12529064948, 8776455938, 2245602097, 15670128881, 18058001691, 21092222111, 17277710588, 14115070523, 9070732951, 2812255943, 9349962400, 3159466851, 16008470639, 19953811077, 21577742012, 22095236133, 14644601174, 8617764033, 16140330747, 6430474270, 8193684764, 18867977174, 19652105799, 17553107189, 18499057047, 15047410679, 14622689532, 116299629, 7516765793, 8115675759, 16051975041, 16430971219, 10443592529, 7029456978, 4636255483, 10311426631, 18607907259, 13049692716, 20594963153, 11747270720, 8552608868, 13807260864, 18374272405, 19847587719, 12573496801, 2860931462, 16578852692, 22804253685, 2720329280])
66
+ context 'frame decoding' do
67
+ it 'decodes null counters' do
68
+ client.execute(%<CREATE TABLE counters (id ASCII, counter1 COUNTER, counter2 COUNTER, PRIMARY KEY (id))>)
69
+ client.execute(%<UPDATE counters SET counter1 = counter1 + 1 WHERE id = 'foo'>)
70
+ result = client.execute(%<SELECT counter1, counter2 FROM counters WHERE id = 'foo'>)
71
+ result.first['counter1'].should == 1
72
+ result.first['counter2'].should be_nil
72
73
  end
73
74
 
74
- it 'inet' do
75
- client.execute('select inet_column from test_types.lots_of_types')
75
+ it 'decodes null values' do
76
+ client.execute(<<-CQL)
77
+ CREATE TABLE lots_of_types (
78
+ id INT,
79
+ ascii_column ASCII,
80
+ bigint_column BIGINT,
81
+ blob_column BLOB,
82
+ boolean_column BOOLEAN,
83
+ decimal_column DECIMAL,
84
+ double_column DOUBLE,
85
+ float_column FLOAT,
86
+ int_column INT,
87
+ text_column TEXT,
88
+ timestamp_column TIMESTAMP,
89
+ uuid_column UUID,
90
+ varchar_column VARCHAR,
91
+ varint_column VARINT,
92
+ timeuuid_column TIMEUUID,
93
+ inet_column INET,
94
+ list_column LIST<ASCII>,
95
+ map_column MAP<TEXT, BOOLEAN>,
96
+ set_column SET<BLOB>,
97
+ PRIMARY KEY (id)
98
+ )
99
+ CQL
100
+ client.execute(%<INSERT INTO lots_of_types (id) VALUES (3)>)
101
+ result = client.execute(%<SELECT * FROM lots_of_types WHERE id = 3>)
102
+ row = result.first
103
+ row['ascii_column'].should be_nil
104
+ row['bigint_column'].should be_nil
105
+ row['blob_column'].should be_nil
106
+ row['boolean_column'].should be_nil
107
+ row['decimal_column'].should be_nil
108
+ row['double_column'].should be_nil
109
+ row['float_column'].should be_nil
110
+ row['int_column'].should be_nil
111
+ row['text_column'].should be_nil
112
+ row['timestamp_column'].should be_nil
113
+ row['uuid_column'].should be_nil
114
+ row['varchar_column'].should be_nil
115
+ row['varint_column'].should be_nil
116
+ row['timeuuid_column'].should be_nil
117
+ row['inet_column'].should be_nil
118
+ row['list_column'].should be_nil
119
+ row['map_column'].should be_nil
120
+ row['set_column'].should be_nil
76
121
  end
122
+ end
77
123
 
124
+ context 'wat' do
78
125
  it 'null values' do
79
126
  client.execute('CREATE TABLE null_value (a BIGINT, b BOOLEAN, c INT, PRIMARY KEY ((a, b), c))')
80
127
  client.execute('INSERT INTO null_value (a, b, c) VALUES (123123123123, true, 3234)')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cql-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre6
4
+ version: 1.0.0.pre7
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-13 00:00:00.000000000 Z
12
+ date: 2013-05-15 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A pure Ruby CQL3 driver for Cassandra
15
15
  email:
@@ -26,8 +26,33 @@ files:
26
26
  - lib/cql/io.rb
27
27
  - lib/cql/protocol/decoding.rb
28
28
  - lib/cql/protocol/encoding.rb
29
+ - lib/cql/protocol/request_body.rb
29
30
  - lib/cql/protocol/request_frame.rb
31
+ - lib/cql/protocol/requests/credentials_request.rb
32
+ - lib/cql/protocol/requests/execute_request.rb
33
+ - lib/cql/protocol/requests/options_request.rb
34
+ - lib/cql/protocol/requests/prepare_request.rb
35
+ - lib/cql/protocol/requests/query_request.rb
36
+ - lib/cql/protocol/requests/register_request.rb
37
+ - lib/cql/protocol/requests/startup_request.rb
38
+ - lib/cql/protocol/response_body.rb
30
39
  - lib/cql/protocol/response_frame.rb
40
+ - lib/cql/protocol/responses/authenticate_response.rb
41
+ - lib/cql/protocol/responses/detailed_error_response.rb
42
+ - lib/cql/protocol/responses/error_response.rb
43
+ - lib/cql/protocol/responses/event_response.rb
44
+ - lib/cql/protocol/responses/prepared_result_response.rb
45
+ - lib/cql/protocol/responses/ready_response.rb
46
+ - lib/cql/protocol/responses/result_response.rb
47
+ - lib/cql/protocol/responses/rows_result_response.rb
48
+ - lib/cql/protocol/responses/schema_change_event_result_response.rb
49
+ - lib/cql/protocol/responses/schema_change_result_response.rb
50
+ - lib/cql/protocol/responses/set_keyspace_result_response.rb
51
+ - lib/cql/protocol/responses/status_change_event_result_response.rb
52
+ - lib/cql/protocol/responses/supported_response.rb
53
+ - lib/cql/protocol/responses/topology_change_event_result_response.rb
54
+ - lib/cql/protocol/responses/void_result_response.rb
55
+ - lib/cql/protocol/type_converter.rb
31
56
  - lib/cql/protocol.rb
32
57
  - lib/cql/uuid.rb
33
58
  - lib/cql/version.rb