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,21 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class AuthenticateResponse < ResponseBody
6
+ attr_reader :authentication_class
7
+
8
+ def self.decode!(buffer)
9
+ new(read_string!(buffer))
10
+ end
11
+
12
+ def initialize(authentication_class)
13
+ @authentication_class = authentication_class
14
+ end
15
+
16
+ def to_s
17
+ %(AUTHENTICATE #{authentication_class})
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class DetailedErrorResponse < ErrorResponse
6
+ attr_reader :details
7
+
8
+ def initialize(code, message, details)
9
+ super(code, message)
10
+ @details = details
11
+ end
12
+
13
+ def self.decode!(code, message, buffer)
14
+ details = {}
15
+ case code
16
+ when 0x1000 # unavailable
17
+ details[:cl] = read_consistency!(buffer)
18
+ details[:required] = read_int!(buffer)
19
+ details[:alive] = read_int!(buffer)
20
+ when 0x1100 # write_timeout
21
+ details[:cl] = read_consistency!(buffer)
22
+ details[:received] = read_int!(buffer)
23
+ details[:blockfor] = read_int!(buffer)
24
+ details[:write_type] = read_string!(buffer)
25
+ when 0x1200 # read_timeout
26
+ details[:cl] = read_consistency!(buffer)
27
+ details[:received] = read_int!(buffer)
28
+ details[:blockfor] = read_int!(buffer)
29
+ details[:data_present] = read_byte!(buffer) != 0
30
+ when 0x2400 # already_exists
31
+ details[:ks] = read_string!(buffer)
32
+ details[:table] = read_string!(buffer)
33
+ when 0x2500
34
+ details[:id] = read_short_bytes!(buffer)
35
+ end
36
+ new(code, message, details)
37
+ end
38
+
39
+ def to_s
40
+ %(ERROR #@code "#@message" #@details)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class ErrorResponse < ResponseBody
6
+ attr_reader :code, :message
7
+
8
+ def initialize(*args)
9
+ @code, @message = args
10
+ end
11
+
12
+ def self.decode!(buffer)
13
+ code = read_int!(buffer)
14
+ message = read_string!(buffer)
15
+ case code
16
+ when 0x1000, 0x1100, 0x1200, 0x2400, 0x2500
17
+ DetailedErrorResponse.decode!(code, message, buffer)
18
+ else
19
+ new(code, message)
20
+ end
21
+ end
22
+
23
+ def to_s
24
+ %(ERROR #@code "#@message")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class EventResponse < ResultResponse
6
+ def self.decode!(buffer)
7
+ type = read_string!(buffer)
8
+ case type
9
+ when SchemaChangeEventResponse::TYPE
10
+ SchemaChangeEventResponse.decode!(buffer)
11
+ when StatusChangeEventResponse::TYPE
12
+ StatusChangeEventResponse.decode!(buffer)
13
+ when TopologyChangeEventResponse::TYPE
14
+ TopologyChangeEventResponse.decode!(buffer)
15
+ else
16
+ raise UnsupportedEventTypeError, %(Unsupported event type: "#{type}")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class PreparedResultResponse < ResultResponse
6
+ attr_reader :id, :metadata
7
+
8
+ def initialize(*args)
9
+ @id, @metadata = args
10
+ end
11
+
12
+ def self.decode!(buffer)
13
+ id = read_short_bytes!(buffer)
14
+ metadata = RowsResultResponse.read_metadata!(buffer)
15
+ new(id, metadata)
16
+ end
17
+
18
+ def to_s
19
+ %(RESULT PREPARED #{id.each_byte.map { |x| x.to_s(16) }.join('')} #@metadata)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class ReadyResponse < ResponseBody
6
+ def self.decode!(buffer)
7
+ new
8
+ end
9
+
10
+ def eql?(rs)
11
+ self.class === rs
12
+ end
13
+ alias_method :==, :eql?
14
+
15
+ def hash
16
+ @h ||= to_s.hash ^ 0xbadc0de
17
+ end
18
+
19
+ def to_s
20
+ 'READY'
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class ResultResponse < ResponseBody
6
+ def self.decode!(buffer)
7
+ kind = read_int!(buffer)
8
+ case kind
9
+ when 0x01
10
+ VoidResultResponse.decode!(buffer)
11
+ when 0x02
12
+ RowsResultResponse.decode!(buffer)
13
+ when 0x03
14
+ SetKeyspaceResultResponse.decode!(buffer)
15
+ when 0x04
16
+ PreparedResultResponse.decode!(buffer)
17
+ when 0x05
18
+ SchemaChangeResultResponse.decode!(buffer)
19
+ else
20
+ raise UnsupportedResultKindError, %(Unsupported result kind: #{kind})
21
+ end
22
+ end
23
+
24
+ def void?
25
+ false
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,100 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class RowsResultResponse < ResultResponse
6
+ attr_reader :rows, :metadata
7
+
8
+ def initialize(*args)
9
+ @rows, @metadata = args
10
+ end
11
+
12
+ def self.decode!(buffer)
13
+ column_specs = read_metadata!(buffer)
14
+ new(read_rows!(buffer, column_specs), column_specs)
15
+ end
16
+
17
+ def to_s
18
+ %(RESULT ROWS #@metadata #@rows)
19
+ end
20
+
21
+ private
22
+
23
+ COLUMN_TYPES = [
24
+ nil,
25
+ :ascii,
26
+ :bigint,
27
+ :blob,
28
+ :boolean,
29
+ :counter,
30
+ :decimal,
31
+ :double,
32
+ :float,
33
+ :int,
34
+ :text,
35
+ :timestamp,
36
+ :uuid,
37
+ :varchar,
38
+ :varint,
39
+ :timeuuid,
40
+ :inet,
41
+ ].freeze
42
+
43
+ def self.read_column_type!(buffer)
44
+ id, type = read_option!(buffer) do |id, b|
45
+ if id > 0 && id <= 0x10
46
+ COLUMN_TYPES[id]
47
+ elsif id == 0x20
48
+ sub_type = read_column_type!(buffer)
49
+ [:list, sub_type]
50
+ elsif id == 0x21
51
+ key_type = read_column_type!(buffer)
52
+ value_type = read_column_type!(buffer)
53
+ [:map, key_type, value_type]
54
+ elsif id == 0x22
55
+ sub_type = read_column_type!(buffer)
56
+ [:set, sub_type]
57
+ else
58
+ raise UnsupportedColumnTypeError, %(Unsupported column type: #{id})
59
+ end
60
+ end
61
+ type
62
+ end
63
+
64
+ def self.read_metadata!(buffer)
65
+ flags = read_int!(buffer)
66
+ columns_count = read_int!(buffer)
67
+ if flags & 0x01 == 0x01
68
+ global_keyspace_name = read_string!(buffer)
69
+ global_table_name = read_string!(buffer)
70
+ end
71
+ column_specs = columns_count.times.map do
72
+ if global_keyspace_name
73
+ keyspace_name = global_keyspace_name
74
+ table_name = global_table_name
75
+ else
76
+ keyspace_name = read_string!(buffer)
77
+ table_name = read_string!(buffer)
78
+ end
79
+ column_name = read_string!(buffer)
80
+ type = read_column_type!(buffer)
81
+ [keyspace_name, table_name, column_name, type]
82
+ end
83
+ end
84
+
85
+ def self.read_rows!(buffer, column_specs)
86
+ type_converter = TypeConverter.new
87
+ rows_count = read_int!(buffer)
88
+ rows = []
89
+ rows_count.times do |row_index|
90
+ row = {}
91
+ column_specs.each do |column_spec|
92
+ row[column_spec[2]] = type_converter.convert_type(buffer, column_spec[3])
93
+ end
94
+ rows << row
95
+ end
96
+ rows
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class SchemaChangeEventResponse < EventResponse
6
+ TYPE = 'SCHEMA_CHANGE'.freeze
7
+
8
+ attr_reader :type, :change, :keyspace, :table
9
+
10
+ def initialize(*args)
11
+ @change, @keyspace, @table = args
12
+ @type = TYPE
13
+ end
14
+
15
+ def self.decode!(buffer)
16
+ new(read_string!(buffer), read_string!(buffer), read_string!(buffer))
17
+ end
18
+
19
+ def eql?(rs)
20
+ rs.type == self.type && rs.change == self.change && rs.keyspace == self.keyspace && rs.table == self.table
21
+ end
22
+ alias_method :==, :eql?
23
+
24
+ def hash
25
+ @h ||= begin
26
+ h = 0
27
+ h = ((h & 33554431) * 31) ^ @type.hash
28
+ h = ((h & 33554431) * 31) ^ @change.hash
29
+ h = ((h & 33554431) * 31) ^ @keyspace.hash
30
+ h = ((h & 33554431) * 31) ^ @table.hash
31
+ h
32
+ end
33
+ end
34
+
35
+ def to_s
36
+ %(EVENT #@type #@change "#@keyspace" "#@table")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class SchemaChangeResultResponse < ResultResponse
6
+ attr_reader :change, :keyspace, :table
7
+
8
+ def initialize(*args)
9
+ @change, @keyspace, @table = args
10
+ end
11
+
12
+ def self.decode!(buffer)
13
+ new(read_string!(buffer), read_string!(buffer), read_string!(buffer))
14
+ end
15
+
16
+ def to_s
17
+ %(RESULT SCHEMA_CHANGE #@change "#@keyspace" "#@table")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class SetKeyspaceResultResponse < ResultResponse
6
+ attr_reader :keyspace
7
+
8
+ def initialize(keyspace)
9
+ @keyspace = keyspace
10
+ end
11
+
12
+ def self.decode!(buffer)
13
+ new(read_string!(buffer))
14
+ end
15
+
16
+ def to_s
17
+ %(RESULT SET_KEYSPACE "#@keyspace")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class StatusChangeEventResponse < EventResponse
6
+ TYPE = 'STATUS_CHANGE'.freeze
7
+
8
+ attr_reader :type, :change, :address, :port
9
+
10
+ def initialize(*args)
11
+ @change, @address, @port = args
12
+ @type = TYPE
13
+ end
14
+
15
+ def self.decode!(buffer)
16
+ new(read_string!(buffer), *read_inet!(buffer))
17
+ end
18
+
19
+ def to_s
20
+ %(EVENT #@type #@change #@address:#@port)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class SupportedResponse < ResponseBody
6
+ attr_reader :options
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+
12
+ def self.decode!(buffer)
13
+ new(read_string_multimap!(buffer))
14
+ end
15
+
16
+ def to_s
17
+ %(SUPPORTED #{options})
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class TopologyChangeEventResponse < StatusChangeEventResponse
6
+ TYPE = 'TOPOLOGY_CHANGE'.freeze
7
+
8
+ def initialize(*args)
9
+ super
10
+ @type = TYPE
11
+ end
12
+ end
13
+ end
14
+ end