cql-rb 1.2.2 → 2.0.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -0
  3. data/README.md +139 -17
  4. data/lib/cql/client.rb +237 -8
  5. data/lib/cql/client/asynchronous_client.rb +138 -54
  6. data/lib/cql/client/asynchronous_prepared_statement.rb +41 -6
  7. data/lib/cql/client/authenticators.rb +46 -0
  8. data/lib/cql/client/batch.rb +115 -0
  9. data/lib/cql/client/connector.rb +255 -0
  10. data/lib/cql/client/execute_options_decoder.rb +25 -9
  11. data/lib/cql/client/keyspace_changer.rb +5 -5
  12. data/lib/cql/client/peer_discovery.rb +33 -0
  13. data/lib/cql/client/query_result.rb +124 -1
  14. data/lib/cql/client/request_runner.rb +4 -2
  15. data/lib/cql/client/synchronous_client.rb +14 -2
  16. data/lib/cql/client/synchronous_prepared_statement.rb +19 -1
  17. data/lib/cql/future.rb +97 -50
  18. data/lib/cql/io/connection.rb +0 -1
  19. data/lib/cql/io/io_reactor.rb +1 -1
  20. data/lib/cql/protocol.rb +8 -1
  21. data/lib/cql/protocol/cql_protocol_handler.rb +2 -2
  22. data/lib/cql/protocol/decoding.rb +10 -15
  23. data/lib/cql/protocol/frame_decoder.rb +2 -1
  24. data/lib/cql/protocol/frame_encoder.rb +5 -4
  25. data/lib/cql/protocol/requests/auth_response_request.rb +31 -0
  26. data/lib/cql/protocol/requests/batch_request.rb +59 -0
  27. data/lib/cql/protocol/requests/credentials_request.rb +1 -1
  28. data/lib/cql/protocol/requests/execute_request.rb +45 -17
  29. data/lib/cql/protocol/requests/options_request.rb +1 -1
  30. data/lib/cql/protocol/requests/prepare_request.rb +1 -1
  31. data/lib/cql/protocol/requests/query_request.rb +97 -5
  32. data/lib/cql/protocol/requests/register_request.rb +1 -1
  33. data/lib/cql/protocol/requests/startup_request.rb +4 -4
  34. data/lib/cql/protocol/response.rb +2 -2
  35. data/lib/cql/protocol/responses/auth_challenge_response.rb +25 -0
  36. data/lib/cql/protocol/responses/auth_success_response.rb +25 -0
  37. data/lib/cql/protocol/responses/authenticate_response.rb +1 -1
  38. data/lib/cql/protocol/responses/detailed_error_response.rb +1 -1
  39. data/lib/cql/protocol/responses/error_response.rb +3 -2
  40. data/lib/cql/protocol/responses/event_response.rb +3 -2
  41. data/lib/cql/protocol/responses/prepared_result_response.rb +10 -6
  42. data/lib/cql/protocol/responses/raw_rows_result_response.rb +27 -0
  43. data/lib/cql/protocol/responses/ready_response.rb +1 -1
  44. data/lib/cql/protocol/responses/result_response.rb +2 -2
  45. data/lib/cql/protocol/responses/rows_result_response.rb +43 -23
  46. data/lib/cql/protocol/responses/schema_change_event_response.rb +1 -1
  47. data/lib/cql/protocol/responses/schema_change_result_response.rb +1 -1
  48. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +1 -1
  49. data/lib/cql/protocol/responses/status_change_event_response.rb +1 -1
  50. data/lib/cql/protocol/responses/supported_response.rb +1 -1
  51. data/lib/cql/protocol/responses/void_result_response.rb +1 -1
  52. data/lib/cql/protocol/type_converter.rb +2 -2
  53. data/lib/cql/uuid.rb +2 -2
  54. data/lib/cql/version.rb +1 -1
  55. data/spec/cql/client/asynchronous_client_spec.rb +493 -50
  56. data/spec/cql/client/asynchronous_prepared_statement_spec.rb +193 -11
  57. data/spec/cql/client/authenticators_spec.rb +56 -0
  58. data/spec/cql/client/batch_spec.rb +277 -0
  59. data/spec/cql/client/connector_spec.rb +606 -0
  60. data/spec/cql/client/execute_options_decoder_spec.rb +95 -0
  61. data/spec/cql/client/keyspace_changer_spec.rb +8 -8
  62. data/spec/cql/client/peer_discovery_spec.rb +92 -0
  63. data/spec/cql/client/query_result_spec.rb +352 -0
  64. data/spec/cql/client/request_runner_spec.rb +31 -5
  65. data/spec/cql/client/synchronous_client_spec.rb +44 -1
  66. data/spec/cql/client/synchronous_prepared_statement_spec.rb +63 -1
  67. data/spec/cql/future_spec.rb +50 -2
  68. data/spec/cql/protocol/cql_protocol_handler_spec.rb +16 -5
  69. data/spec/cql/protocol/decoding_spec.rb +16 -6
  70. data/spec/cql/protocol/encoding_spec.rb +3 -1
  71. data/spec/cql/protocol/frame_encoder_spec.rb +99 -50
  72. data/spec/cql/protocol/requests/auth_response_request_spec.rb +62 -0
  73. data/spec/cql/protocol/requests/batch_request_spec.rb +155 -0
  74. data/spec/cql/protocol/requests/credentials_request_spec.rb +1 -1
  75. data/spec/cql/protocol/requests/execute_request_spec.rb +184 -71
  76. data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
  77. data/spec/cql/protocol/requests/prepare_request_spec.rb +1 -1
  78. data/spec/cql/protocol/requests/query_request_spec.rb +255 -32
  79. data/spec/cql/protocol/requests/register_request_spec.rb +1 -1
  80. data/spec/cql/protocol/requests/startup_request_spec.rb +12 -6
  81. data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +31 -0
  82. data/spec/cql/protocol/responses/auth_success_response_spec.rb +31 -0
  83. data/spec/cql/protocol/responses/authenticate_response_spec.rb +2 -1
  84. data/spec/cql/protocol/responses/detailed_error_response_spec.rb +14 -7
  85. data/spec/cql/protocol/responses/error_response_spec.rb +4 -2
  86. data/spec/cql/protocol/responses/event_response_spec.rb +7 -4
  87. data/spec/cql/protocol/responses/prepared_result_response_spec.rb +89 -34
  88. data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +66 -0
  89. data/spec/cql/protocol/responses/ready_response_spec.rb +1 -1
  90. data/spec/cql/protocol/responses/result_response_spec.rb +19 -7
  91. data/spec/cql/protocol/responses/rows_result_response_spec.rb +56 -11
  92. data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +2 -1
  93. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +2 -1
  94. data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +1 -1
  95. data/spec/cql/protocol/responses/status_change_event_response_spec.rb +2 -1
  96. data/spec/cql/protocol/responses/supported_response_spec.rb +2 -1
  97. data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +2 -1
  98. data/spec/cql/protocol/responses/void_result_response_spec.rb +1 -1
  99. data/spec/cql/protocol/type_converter_spec.rb +21 -4
  100. data/spec/cql/uuid_spec.rb +10 -3
  101. data/spec/integration/client_spec.rb +251 -28
  102. data/spec/integration/protocol_spec.rb +213 -62
  103. data/spec/integration/regression_spec.rb +4 -1
  104. data/spec/integration/uuid_spec.rb +4 -1
  105. data/spec/support/fake_io_reactor.rb +5 -5
  106. metadata +36 -7
  107. data/lib/cql/client/connection_helper.rb +0 -181
  108. data/spec/cql/client/connection_helper_spec.rb +0 -429
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class AuthResponseRequest < Request
6
+ attr_reader :token
7
+
8
+ def initialize(token)
9
+ super(0x0f)
10
+ @token = token
11
+ end
12
+
13
+ def write(protocol_version, io)
14
+ write_bytes(io, @token)
15
+ end
16
+
17
+ def to_s
18
+ %(AUTH_RESPONSE #{@token.bytesize})
19
+ end
20
+
21
+ def eql?(other)
22
+ self.token == other.token
23
+ end
24
+ alias_method :==, :eql?
25
+
26
+ def hash
27
+ @token.hash
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class BatchRequest < Request
6
+ LOGGED_TYPE = 0
7
+ UNLOGGED_TYPE = 1
8
+ COUNTER_TYPE = 2
9
+
10
+ attr_reader :type, :consistency, :part_count
11
+
12
+ def initialize(type, consistency, trace=false)
13
+ super(0x0D, trace)
14
+ @type = type
15
+ @part_count = 0
16
+ @encoded_queries = ByteBuffer.new
17
+ @consistency = consistency
18
+ end
19
+
20
+ def add_query(cql, values=nil, type_hints=nil)
21
+ @encoded_queries << QUERY_KIND
22
+ write_long_string(@encoded_queries, cql)
23
+ QueryRequest.encode_values(@encoded_queries, values, type_hints)
24
+ @part_count += 1
25
+ nil
26
+ end
27
+
28
+ def add_prepared(id, metadata, values)
29
+ @encoded_queries << PREPARED_KIND
30
+ write_short_bytes(@encoded_queries, id)
31
+ ExecuteRequest.encode_values(@encoded_queries, metadata, values)
32
+ @part_count += 1
33
+ nil
34
+ end
35
+
36
+ def write(protocol_version, io)
37
+ io << @type.chr
38
+ write_short(io, @part_count)
39
+ io << @encoded_queries
40
+ write_consistency(io, @consistency)
41
+ end
42
+
43
+ def to_s
44
+ type_str = case @type
45
+ when LOGGED_TYPE then 'LOGGED'
46
+ when UNLOGGED_TYPE then 'UNLOGGED'
47
+ when COUNTER_TYPE then 'COUNTER'
48
+ end
49
+ %(BATCH #{type_str} #{@part_count} #{@consistency.to_s.upcase})
50
+ end
51
+
52
+ private
53
+
54
+ TYPE_CONVERTER = TypeConverter.new
55
+ QUERY_KIND = "\x00".freeze
56
+ PREPARED_KIND = "\x01".freeze
57
+ end
58
+ end
59
+ end
@@ -10,7 +10,7 @@ module Cql
10
10
  @credentials = credentials.dup.freeze
11
11
  end
12
12
 
13
- def write(io)
13
+ def write(protocol_version, io)
14
14
  write_string_map(io, @credentials)
15
15
  end
16
16
 
@@ -3,20 +3,47 @@
3
3
  module Cql
4
4
  module Protocol
5
5
  class ExecuteRequest < Request
6
- attr_reader :id, :metadata, :values, :consistency
6
+ attr_reader :id, :metadata, :values, :request_metadata, :consistency, :serial_consistency, :page_size, :paging_state
7
7
 
8
- def initialize(id, metadata, values, consistency, trace=false)
8
+ def initialize(id, metadata, values, request_metadata, consistency, serial_consistency=nil, page_size=nil, paging_state=nil, trace=false)
9
9
  raise ArgumentError, "Metadata for #{metadata.size} columns, but #{values.size} values given" if metadata.size != values.size
10
+ raise ArgumentError, %(No such consistency: #{consistency.inspect}) if consistency.nil? || !CONSISTENCIES.include?(consistency)
11
+ raise ArgumentError, %(No such consistency: #{serial_consistency.inspect}) unless serial_consistency.nil? || CONSISTENCIES.include?(serial_consistency)
12
+ raise ArgumentError, %(Paging state given but no page size) if paging_state && !page_size
10
13
  super(10, trace)
11
14
  @id = id
12
15
  @metadata = metadata
13
16
  @values = values
17
+ @request_metadata = request_metadata
14
18
  @consistency = consistency
15
- @bytes = encode_body
19
+ @serial_consistency = serial_consistency
20
+ @page_size = page_size
21
+ @paging_state = paging_state
22
+ @encoded_values = self.class.encode_values('', @metadata, @values)
16
23
  end
17
24
 
18
- def write(io)
19
- io << @bytes
25
+ def write(protocol_version, io)
26
+ write_short_bytes(io, @id)
27
+ if protocol_version > 1
28
+ write_consistency(io, @consistency)
29
+ flags = 0
30
+ flags |= 0x01 if @values.size > 0
31
+ flags |= 0x02 unless @request_metadata
32
+ flags |= 0x04 if @page_size
33
+ flags |= 0x08 if @paging_state
34
+ flags |= 0x10 if @serial_consistency
35
+ io << flags.chr
36
+ if @values.size > 0
37
+ io << @encoded_values
38
+ end
39
+ write_int(io, @page_size) if @page_size
40
+ write_bytes(io, @paging_state) if @paging_state
41
+ write_consistency(io, @serial_consistency) if @serial_consistency
42
+ io
43
+ else
44
+ io << @encoded_values
45
+ write_consistency(io, @consistency)
46
+ end
20
47
  end
21
48
 
22
49
  def to_s
@@ -25,7 +52,7 @@ module Cql
25
52
  end
26
53
 
27
54
  def eql?(rq)
28
- self.class === rq && rq.id == self.id && rq.metadata == self.metadata && rq.values == self.values && rq.consistency == self.consistency
55
+ self.class === rq && rq.id == self.id && rq.metadata == self.metadata && rq.values == self.values && rq.consistency == self.consistency && rq.serial_consistency == self.serial_consistency && rq.page_size == self.page_size && rq.paging_state == self.paging_state
29
56
  end
30
57
  alias_method :==, :eql?
31
58
 
@@ -36,23 +63,24 @@ module Cql
36
63
  h = ((h & 33554431) * 31) ^ @metadata.hash
37
64
  h = ((h & 33554431) * 31) ^ @values.hash
38
65
  h = ((h & 33554431) * 31) ^ @consistency.hash
66
+ h = ((h & 33554431) * 31) ^ @serial_consistency.hash
67
+ h = ((h & 33554431) * 31) ^ @page_size.hash
68
+ h = ((h & 33554431) * 31) ^ @paging_state.hash
39
69
  h
40
70
  end
41
71
  end
42
72
 
43
- private
44
-
45
- def encode_body
46
- buffer = ByteBuffer.new
47
- type_converter = TypeConverter.new
48
- write_short_bytes(buffer, @id)
49
- write_short(buffer, @metadata.size)
50
- @metadata.each_with_index do |(_, _, _, type), index|
51
- type_converter.to_bytes(buffer, type, @values[index])
73
+ def self.encode_values(buffer, metadata, values)
74
+ Encoding.write_short(buffer, metadata.size)
75
+ metadata.each_with_index do |(_, _, _, type), index|
76
+ TYPE_CONVERTER.to_bytes(buffer, type, values[index])
52
77
  end
53
- write_consistency(buffer, @consistency)
54
- buffer.to_s
78
+ buffer
55
79
  end
80
+
81
+ private
82
+
83
+ TYPE_CONVERTER = TypeConverter.new
56
84
  end
57
85
  end
58
86
  end
@@ -11,7 +11,7 @@ module Cql
11
11
  false
12
12
  end
13
13
 
14
- def write(io)
14
+ def write(protocol_version, io)
15
15
  io
16
16
  end
17
17
 
@@ -11,7 +11,7 @@ module Cql
11
11
  @cql = cql
12
12
  end
13
13
 
14
- def write(io)
14
+ def write(protocol_version, io)
15
15
  write_long_string(io, @cql)
16
16
  end
17
17
 
@@ -3,19 +3,45 @@
3
3
  module Cql
4
4
  module Protocol
5
5
  class QueryRequest < Request
6
- attr_reader :cql, :consistency
6
+ attr_reader :cql, :values, :type_hints, :consistency, :serial_consistency, :page_size, :paging_state
7
7
 
8
- def initialize(cql, consistency, trace=false)
8
+ def initialize(cql, values, type_hints, consistency, serial_consistency=nil, page_size=nil, paging_state=nil, trace=false)
9
9
  raise ArgumentError, %(No CQL given!) unless cql
10
10
  raise ArgumentError, %(No such consistency: #{consistency.inspect}) if consistency.nil? || !CONSISTENCIES.include?(consistency)
11
+ raise ArgumentError, %(No such consistency: #{serial_consistency.inspect}) unless serial_consistency.nil? || CONSISTENCIES.include?(serial_consistency)
12
+ raise ArgumentError, %(Bound values and type hints must have the same number of elements (got #{values.size} values and #{type_hints.size} hints)) if values && type_hints && values.size != type_hints.size
13
+ raise ArgumentError, %(Paging state given but no page size) if paging_state && !page_size
11
14
  super(7, trace)
12
15
  @cql = cql
16
+ @values = values || EMPTY_LIST
17
+ @type_hints = type_hints || EMPTY_LIST
18
+ @encoded_values = self.class.encode_values('', @values, @type_hints)
13
19
  @consistency = consistency
20
+ @serial_consistency = serial_consistency
21
+ @page_size = page_size
22
+ @paging_state = paging_state
14
23
  end
15
24
 
16
- def write(io)
25
+ def write(protocol_version, io)
17
26
  write_long_string(io, @cql)
18
27
  write_consistency(io, @consistency)
28
+ if protocol_version > 1
29
+ flags = 0
30
+ flags |= 0x04 if @page_size
31
+ flags |= 0x08 if @paging_state
32
+ flags |= 0x10 if @serial_consistency
33
+ if @values && @values.size > 0
34
+ flags |= 0x01
35
+ io << flags.chr
36
+ io << @encoded_values
37
+ else
38
+ io << flags.chr
39
+ end
40
+ write_int(io, @page_size) if @page_size
41
+ write_bytes(io, @paging_state) if @paging_state
42
+ write_consistency(io, @serial_consistency) if @serial_consistency
43
+ end
44
+ io
19
45
  end
20
46
 
21
47
  def to_s
@@ -23,13 +49,79 @@ module Cql
23
49
  end
24
50
 
25
51
  def eql?(rq)
26
- self.class === rq && rq.cql.eql?(self.cql) && rq.consistency.eql?(self.consistency)
52
+ self.class === rq &&
53
+ rq.cql == self.cql &&
54
+ rq.values == self.values &&
55
+ rq.type_hints == self.type_hints &&
56
+ rq.consistency == self.consistency &&
57
+ rq.serial_consistency == self.serial_consistency &&
58
+ rq.page_size == self.page_size &&
59
+ rq.paging_state == self.paging_state
27
60
  end
28
61
  alias_method :==, :eql?
29
62
 
30
63
  def hash
31
- @h ||= (@cql.hash * 31) ^ consistency.hash
64
+ h = 0xcbf29ce484222325
65
+ h = 0xffffffffffffffff & (0x100000001b3 * (h ^ @cql.hash))
66
+ h = 0xffffffffffffffff & (0x100000001b3 * (h ^ @values.hash))
67
+ h = 0xffffffffffffffff & (0x100000001b3 * (h ^ @type_hints.hash))
68
+ h = 0xffffffffffffffff & (0x100000001b3 * (h ^ @consistency.hash))
69
+ h = 0xffffffffffffffff & (0x100000001b3 * (h ^ @serial_consistency.hash))
70
+ h = 0xffffffffffffffff & (0x100000001b3 * (h ^ @page_size.hash))
71
+ h = 0xffffffffffffffff & (0x100000001b3 * (h ^ @paging_state.hash))
72
+ h
32
73
  end
74
+
75
+ def self.encode_values(buffer, values, hints)
76
+ if values && values.size > 0
77
+ Encoding.write_short(buffer, values.size)
78
+ values.each_with_index do |value, index|
79
+ type = (hints && hints[index]) || guess_type(value)
80
+ raise EncodingError, "Could not guess a suitable type for #{value.inspect}" unless type
81
+ TYPE_CONVERTER.to_bytes(buffer, type, value)
82
+ end
83
+ buffer
84
+ else
85
+ Encoding.write_short(buffer, 0)
86
+ end
87
+ end
88
+
89
+ private
90
+
91
+ def self.guess_type(value)
92
+ type = TYPE_GUESSES[value.class]
93
+ if type == :map
94
+ pair = value.first
95
+ [type, guess_type(pair[0]), guess_type(pair[1])]
96
+ elsif type == :list
97
+ [type, guess_type(value.first)]
98
+ elsif type == :set
99
+ [type, guess_type(value.first)]
100
+ else
101
+ type
102
+ end
103
+ end
104
+
105
+ TYPE_GUESSES = {
106
+ String => :varchar,
107
+ Fixnum => :bigint,
108
+ Float => :double,
109
+ Bignum => :varint,
110
+ BigDecimal => :decimal,
111
+ TrueClass => :boolean,
112
+ FalseClass => :boolean,
113
+ NilClass => :bigint,
114
+ Uuid => :uuid,
115
+ TimeUuid => :uuid,
116
+ IPAddr => :inet,
117
+ Time => :timestamp,
118
+ Hash => :map,
119
+ Array => :list,
120
+ Set => :set,
121
+ }.freeze
122
+ TYPE_CONVERTER = TypeConverter.new
123
+ EMPTY_LIST = [].freeze
124
+ NO_FLAGS = "\x00".freeze
33
125
  end
34
126
  end
35
127
  end
@@ -10,7 +10,7 @@ module Cql
10
10
  @events = events
11
11
  end
12
12
 
13
- def write(io)
13
+ def write(protocol_version, io)
14
14
  write_string_list(io, @events)
15
15
  end
16
16
 
@@ -5,9 +5,10 @@ module Cql
5
5
  class StartupRequest < Request
6
6
  attr_reader :options
7
7
 
8
- def initialize(cql_version=nil, compression=nil)
8
+ def initialize(cql_version, compression=nil)
9
9
  super(1)
10
- @options = {CQL_VERSION => cql_version || DEFAULT_CQL_VERSION}
10
+ raise ArgumentError, "Invalid CQL version: #{cql_version.inspect}" unless cql_version
11
+ @options = {CQL_VERSION => cql_version}
11
12
  @options[COMPRESSION] = compression if compression
12
13
  end
13
14
 
@@ -15,7 +16,7 @@ module Cql
15
16
  false
16
17
  end
17
18
 
18
- def write(io)
19
+ def write(protocol_version, io)
19
20
  write_string_map(io, @options)
20
21
  end
21
22
 
@@ -25,7 +26,6 @@ module Cql
25
26
 
26
27
  private
27
28
 
28
- DEFAULT_CQL_VERSION = '3.0.0'.freeze
29
29
  CQL_VERSION = 'CQL_VERSION'.freeze
30
30
  COMPRESSION = 'COMPRESSION'.freeze
31
31
  end
@@ -5,10 +5,10 @@ module Cql
5
5
  class Response
6
6
  extend Decoding
7
7
 
8
- def self.decode!(opcode, buffer, trace_id)
8
+ def self.decode!(opcode, protocol_version, buffer, length, trace_id)
9
9
  response_class = RESPONSE_TYPES[opcode]
10
10
  if response_class
11
- response_class.decode!(buffer, trace_id)
11
+ response_class.decode!(protocol_version, buffer, length, trace_id)
12
12
  else
13
13
  raise UnsupportedOperationError, "The operation #{opcode} is not supported"
14
14
  end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class AuthChallengeResponse < Response
6
+ attr_reader :token
7
+
8
+ def self.decode!(protocol_version, buffer, length, trace_id=nil)
9
+ new(read_bytes!(buffer))
10
+ end
11
+
12
+ def initialize(token)
13
+ @token = token
14
+ end
15
+
16
+ def to_s
17
+ %(AUTH_CHALLENGE #{@token.bytesize})
18
+ end
19
+
20
+ private
21
+
22
+ RESPONSE_TYPES[0x0e] = self
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Cql
4
+ module Protocol
5
+ class AuthSuccessResponse < Response
6
+ attr_reader :token
7
+
8
+ def self.decode!(protocol_version, buffer, length, trace_id=nil)
9
+ new(read_bytes!(buffer))
10
+ end
11
+
12
+ def initialize(token)
13
+ @token = token
14
+ end
15
+
16
+ def to_s
17
+ %(AUTH_SUCCESS #{@token.bytesize})
18
+ end
19
+
20
+ private
21
+
22
+ RESPONSE_TYPES[0x10] = self
23
+ end
24
+ end
25
+ end