cql-rb 1.0.0.pre6 → 1.0.0.pre7

Sign up to get free protection for your applications and to get access to all the features.
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