yugabyte-ycql-driver 3.2.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +13 -0
  3. data/README.md +242 -0
  4. data/ext/cassandra_murmur3/cassandra_murmur3.c +178 -0
  5. data/ext/cassandra_murmur3/extconf.rb +2 -0
  6. data/lib/cassandra/address_resolution.rb +36 -0
  7. data/lib/cassandra/address_resolution/policies.rb +2 -0
  8. data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +56 -0
  9. data/lib/cassandra/address_resolution/policies/none.rb +35 -0
  10. data/lib/cassandra/aggregate.rb +123 -0
  11. data/lib/cassandra/argument.rb +51 -0
  12. data/lib/cassandra/attr_boolean.rb +33 -0
  13. data/lib/cassandra/auth.rb +100 -0
  14. data/lib/cassandra/auth/providers.rb +17 -0
  15. data/lib/cassandra/auth/providers/password.rb +65 -0
  16. data/lib/cassandra/cassandra_logger.rb +80 -0
  17. data/lib/cassandra/cluster.rb +331 -0
  18. data/lib/cassandra/cluster/client.rb +1612 -0
  19. data/lib/cassandra/cluster/connection_pool.rb +78 -0
  20. data/lib/cassandra/cluster/connector.rb +372 -0
  21. data/lib/cassandra/cluster/control_connection.rb +962 -0
  22. data/lib/cassandra/cluster/failed_connection.rb +35 -0
  23. data/lib/cassandra/cluster/metadata.rb +142 -0
  24. data/lib/cassandra/cluster/options.rb +145 -0
  25. data/lib/cassandra/cluster/registry.rb +284 -0
  26. data/lib/cassandra/cluster/schema.rb +405 -0
  27. data/lib/cassandra/cluster/schema/cql_type_parser.rb +112 -0
  28. data/lib/cassandra/cluster/schema/fetchers.rb +1627 -0
  29. data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +175 -0
  30. data/lib/cassandra/cluster/schema/partitioners.rb +21 -0
  31. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +45 -0
  32. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +37 -0
  33. data/lib/cassandra/cluster/schema/partitioners/random.rb +37 -0
  34. data/lib/cassandra/cluster/schema/replication_strategies.rb +21 -0
  35. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +102 -0
  36. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +39 -0
  37. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +44 -0
  38. data/lib/cassandra/column.rb +66 -0
  39. data/lib/cassandra/column_container.rb +326 -0
  40. data/lib/cassandra/compression.rb +69 -0
  41. data/lib/cassandra/compression/compressors/lz4.rb +73 -0
  42. data/lib/cassandra/compression/compressors/snappy.rb +69 -0
  43. data/lib/cassandra/custom_data.rb +53 -0
  44. data/lib/cassandra/driver.rb +260 -0
  45. data/lib/cassandra/errors.rb +784 -0
  46. data/lib/cassandra/execution/info.rb +69 -0
  47. data/lib/cassandra/execution/options.rb +267 -0
  48. data/lib/cassandra/execution/profile.rb +153 -0
  49. data/lib/cassandra/execution/profile_manager.rb +71 -0
  50. data/lib/cassandra/execution/trace.rb +192 -0
  51. data/lib/cassandra/executors.rb +113 -0
  52. data/lib/cassandra/function.rb +156 -0
  53. data/lib/cassandra/function_collection.rb +85 -0
  54. data/lib/cassandra/future.rb +794 -0
  55. data/lib/cassandra/host.rb +102 -0
  56. data/lib/cassandra/index.rb +118 -0
  57. data/lib/cassandra/keyspace.rb +473 -0
  58. data/lib/cassandra/listener.rb +87 -0
  59. data/lib/cassandra/load_balancing.rb +121 -0
  60. data/lib/cassandra/load_balancing/policies.rb +20 -0
  61. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +172 -0
  62. data/lib/cassandra/load_balancing/policies/round_robin.rb +141 -0
  63. data/lib/cassandra/load_balancing/policies/token_aware.rb +149 -0
  64. data/lib/cassandra/load_balancing/policies/white_list.rb +100 -0
  65. data/lib/cassandra/materialized_view.rb +92 -0
  66. data/lib/cassandra/null_logger.rb +56 -0
  67. data/lib/cassandra/protocol.rb +102 -0
  68. data/lib/cassandra/protocol/coder.rb +1085 -0
  69. data/lib/cassandra/protocol/cql_byte_buffer.rb +418 -0
  70. data/lib/cassandra/protocol/cql_protocol_handler.rb +448 -0
  71. data/lib/cassandra/protocol/request.rb +41 -0
  72. data/lib/cassandra/protocol/requests/auth_response_request.rb +51 -0
  73. data/lib/cassandra/protocol/requests/batch_request.rb +117 -0
  74. data/lib/cassandra/protocol/requests/credentials_request.rb +51 -0
  75. data/lib/cassandra/protocol/requests/execute_request.rb +122 -0
  76. data/lib/cassandra/protocol/requests/options_request.rb +39 -0
  77. data/lib/cassandra/protocol/requests/prepare_request.rb +59 -0
  78. data/lib/cassandra/protocol/requests/query_request.rb +112 -0
  79. data/lib/cassandra/protocol/requests/register_request.rb +38 -0
  80. data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
  81. data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
  82. data/lib/cassandra/protocol/response.rb +28 -0
  83. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +50 -0
  84. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +36 -0
  85. data/lib/cassandra/protocol/responses/auth_success_response.rb +36 -0
  86. data/lib/cassandra/protocol/responses/authenticate_response.rb +36 -0
  87. data/lib/cassandra/protocol/responses/error_response.rb +142 -0
  88. data/lib/cassandra/protocol/responses/event_response.rb +30 -0
  89. data/lib/cassandra/protocol/responses/function_failure_error_response.rb +52 -0
  90. data/lib/cassandra/protocol/responses/prepared_result_response.rb +62 -0
  91. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +59 -0
  92. data/lib/cassandra/protocol/responses/read_failure_error_response.rb +71 -0
  93. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +61 -0
  94. data/lib/cassandra/protocol/responses/ready_response.rb +43 -0
  95. data/lib/cassandra/protocol/responses/result_response.rb +42 -0
  96. data/lib/cassandra/protocol/responses/rows_result_response.rb +39 -0
  97. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +73 -0
  98. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +70 -0
  99. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +37 -0
  100. data/lib/cassandra/protocol/responses/status_change_event_response.rb +39 -0
  101. data/lib/cassandra/protocol/responses/supported_response.rb +36 -0
  102. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +33 -0
  103. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +58 -0
  104. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +48 -0
  105. data/lib/cassandra/protocol/responses/void_result_response.rb +34 -0
  106. data/lib/cassandra/protocol/responses/write_failure_error_response.rb +73 -0
  107. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +63 -0
  108. data/lib/cassandra/protocol/v1.rb +326 -0
  109. data/lib/cassandra/protocol/v3.rb +358 -0
  110. data/lib/cassandra/protocol/v4.rb +478 -0
  111. data/lib/cassandra/reconnection.rb +49 -0
  112. data/lib/cassandra/reconnection/policies.rb +20 -0
  113. data/lib/cassandra/reconnection/policies/constant.rb +46 -0
  114. data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
  115. data/lib/cassandra/result.rb +276 -0
  116. data/lib/cassandra/retry.rb +154 -0
  117. data/lib/cassandra/retry/policies.rb +21 -0
  118. data/lib/cassandra/retry/policies/default.rb +53 -0
  119. data/lib/cassandra/retry/policies/downgrading_consistency.rb +73 -0
  120. data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
  121. data/lib/cassandra/session.rb +270 -0
  122. data/lib/cassandra/statement.rb +32 -0
  123. data/lib/cassandra/statements.rb +23 -0
  124. data/lib/cassandra/statements/batch.rb +146 -0
  125. data/lib/cassandra/statements/bound.rb +65 -0
  126. data/lib/cassandra/statements/prepared.rb +235 -0
  127. data/lib/cassandra/statements/simple.rb +118 -0
  128. data/lib/cassandra/statements/void.rb +38 -0
  129. data/lib/cassandra/table.rb +240 -0
  130. data/lib/cassandra/time.rb +103 -0
  131. data/lib/cassandra/time_uuid.rb +78 -0
  132. data/lib/cassandra/timestamp_generator.rb +37 -0
  133. data/lib/cassandra/timestamp_generator/simple.rb +38 -0
  134. data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
  135. data/lib/cassandra/trigger.rb +67 -0
  136. data/lib/cassandra/tuple.rb +131 -0
  137. data/lib/cassandra/types.rb +1704 -0
  138. data/lib/cassandra/udt.rb +443 -0
  139. data/lib/cassandra/util.rb +464 -0
  140. data/lib/cassandra/uuid.rb +110 -0
  141. data/lib/cassandra/uuid/generator.rb +212 -0
  142. data/lib/cassandra/version.rb +21 -0
  143. data/lib/datastax/cassandra.rb +47 -0
  144. data/lib/ycql.rb +842 -0
  145. metadata +243 -0
@@ -0,0 +1,1085 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright DataStax, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #++
18
+
19
+ module Cassandra
20
+ module Protocol
21
+ module Coder
22
+ module_function
23
+
24
+ GLOBAL_TABLES_SPEC_FLAG = 0x01
25
+ HAS_MORE_PAGES_FLAG = 0x02
26
+ NO_METADATA_FLAG = 0x04
27
+
28
+ def write_values_v4(buffer, values, types, names = EMPTY_LIST)
29
+ if values && !values.empty?
30
+ buffer.append_short(values.size)
31
+ values.zip(types, names) do |(value, type, name)|
32
+ buffer.append_string(name) if name
33
+ write_value_v4(buffer, value, type)
34
+ end
35
+ buffer
36
+ else
37
+ buffer.append_short(0)
38
+ end
39
+ end
40
+
41
+ def write_list_v4(buffer, list, type)
42
+ raw = CqlByteBuffer.new
43
+
44
+ raw.append_int(list.size)
45
+ list.each do |element|
46
+ write_value_v4(raw, element, type)
47
+ end
48
+
49
+ buffer.append_bytes(raw)
50
+ end
51
+
52
+ def write_map_v4(buffer, map, key_type, value_type)
53
+ raw = CqlByteBuffer.new
54
+
55
+ raw.append_int(map.size)
56
+ map.each do |key, value|
57
+ write_value_v4(raw, key, key_type)
58
+ write_value_v4(raw, value, value_type)
59
+ end
60
+
61
+ buffer.append_bytes(raw)
62
+ end
63
+
64
+ def write_udt_v4(buffer, value, fields)
65
+ raw = CqlByteBuffer.new
66
+
67
+ fields.each do |field|
68
+ write_value_v4(raw, value[field.name], field.type)
69
+ end
70
+
71
+ buffer.append_bytes(raw)
72
+ end
73
+
74
+ def write_tuple_v4(buffer, value, members)
75
+ raw = CqlByteBuffer.new
76
+
77
+ members.each_with_index do |type, i|
78
+ write_value_v4(raw, value[i], type)
79
+ end
80
+
81
+ buffer.append_bytes(raw)
82
+ end
83
+
84
+ def write_value_v4(buffer, value, type)
85
+ if value.nil?
86
+ buffer.append_int(-1)
87
+ return
88
+ end
89
+
90
+ if NOT_SET.eql?(value)
91
+ buffer.append_int(-2)
92
+ return
93
+ end
94
+
95
+ case type.kind
96
+ when :ascii then write_ascii(buffer, value)
97
+ when :bigint, :counter then write_bigint(buffer, value)
98
+ when :blob then write_blob(buffer, value)
99
+ when :boolean then write_boolean(buffer, value)
100
+ when :custom then write_custom(buffer, value, type)
101
+ when :decimal then write_decimal(buffer, value)
102
+ when :double then write_double(buffer, value)
103
+ when :float then write_float(buffer, value)
104
+ when :int then write_int(buffer, value)
105
+ when :inet then write_inet(buffer, value)
106
+ when :timestamp then write_timestamp(buffer, value)
107
+ when :uuid, :timeuuid then write_uuid(buffer, value)
108
+ when :text then write_text(buffer, value)
109
+ when :varint then write_varint(buffer, value)
110
+ when :tinyint then write_tinyint(buffer, value)
111
+ when :smallint then write_smallint(buffer, value)
112
+ when :time then write_time(buffer, value)
113
+ when :date then write_date(buffer, value)
114
+ when :list, :set then write_list_v4(buffer, value, type.value_type)
115
+ when :map then write_map_v4(buffer, value,
116
+ type.key_type,
117
+ type.value_type)
118
+ when :udt then write_udt_v4(buffer, value, type.fields)
119
+ when :tuple then write_tuple_v4(buffer, value, type.members)
120
+ else
121
+ raise Errors::EncodingError, %(Unsupported value type: #{type})
122
+ end
123
+ end
124
+
125
+ def read_prepared_metadata_v4(buffer)
126
+ flags = buffer.read_int
127
+ columns_count = buffer.read_int
128
+ pk_count = buffer.read_int
129
+ pk_specs = ::Array.new(pk_count) {|_i| buffer.read_short}
130
+
131
+ if flags & GLOBAL_TABLES_SPEC_FLAG == GLOBAL_TABLES_SPEC_FLAG
132
+ keyspace_name = buffer.read_string
133
+ table_name = buffer.read_string
134
+
135
+ column_specs = ::Array.new(columns_count) do |_i|
136
+ [keyspace_name, table_name, buffer.read_string, read_type_v4(buffer)]
137
+ end
138
+ else
139
+ column_specs = ::Array.new(columns_count) do |_i|
140
+ [
141
+ buffer.read_string,
142
+ buffer.read_string,
143
+ buffer.read_string,
144
+ read_type_v4(buffer)
145
+ ]
146
+ end
147
+ end
148
+
149
+ [pk_specs, column_specs]
150
+ end
151
+
152
+ def read_metadata_v4(buffer)
153
+ flags = buffer.read_int
154
+ count = buffer.read_int
155
+
156
+ paging_state = nil
157
+ paging_state = buffer.read_bytes if flags & HAS_MORE_PAGES_FLAG != 0
158
+ column_specs = nil
159
+
160
+ if flags & NO_METADATA_FLAG == 0
161
+ if flags & GLOBAL_TABLES_SPEC_FLAG != 0
162
+ keyspace_name = buffer.read_string
163
+ table_name = buffer.read_string
164
+
165
+ column_specs = ::Array.new(count) do |_i|
166
+ [keyspace_name, table_name, buffer.read_string, read_type_v4(buffer)]
167
+ end
168
+ else
169
+ column_specs = ::Array.new(count) do |_i|
170
+ [
171
+ buffer.read_string,
172
+ buffer.read_string,
173
+ buffer.read_string,
174
+ read_type_v4(buffer)
175
+ ]
176
+ end
177
+ end
178
+ end
179
+
180
+ [column_specs, paging_state]
181
+ end
182
+
183
+ def read_type_v4(buffer)
184
+ id = buffer.read_unsigned_short
185
+ case id
186
+ when 0x0000 then Types.custom(buffer.read_string)
187
+ when 0x0001 then Types.ascii
188
+ when 0x0002 then Types.bigint
189
+ when 0x0003 then Types.blob
190
+ when 0x0004 then Types.boolean
191
+ when 0x0005 then Types.counter
192
+ when 0x0006 then Types.decimal
193
+ when 0x0007 then Types.double
194
+ when 0x0008 then Types.float
195
+ when 0x0009 then Types.int
196
+ when 0x000B then Types.timestamp
197
+ when 0x000C then Types.uuid
198
+ when 0x000D then Types.text
199
+ when 0x000E then Types.varint
200
+ when 0x000F then Types.timeuuid
201
+ when 0x0010 then Types.inet
202
+ when 0x0011 then Types.date
203
+ when 0x0012 then Types.time
204
+ when 0x0013 then Types.smallint
205
+ when 0x0014 then Types.tinyint
206
+ when 0x0020 then Types.list(read_type_v4(buffer))
207
+ when 0x0021 then Types.map(read_type_v4(buffer), read_type_v4(buffer))
208
+ when 0x0022 then Types.set(read_type_v4(buffer))
209
+ when 0x0030
210
+ keyspace = buffer.read_string
211
+ name = buffer.read_string
212
+ fields = ::Array.new(buffer.read_short) do
213
+ [buffer.read_string, read_type_v4(buffer)]
214
+ end
215
+
216
+ Types.udt(keyspace, name, fields)
217
+ when 0x0031 then Types.tuple(
218
+ *::Array.new(buffer.read_short) { read_type_v4(buffer) }
219
+ )
220
+ else
221
+ raise Errors::DecodingError, %(Unsupported column type: #{id})
222
+ end
223
+ end
224
+
225
+ def read_values_v4(buffer, column_metadata, custom_type_handlers)
226
+ ::Array.new(buffer.read_int) do |_i|
227
+ row = ::Hash.new
228
+
229
+ column_metadata.each do |(_, _, column, type)|
230
+ row[column] = read_value_v4(buffer, type, custom_type_handlers)
231
+ end
232
+
233
+ row
234
+ end
235
+ end
236
+
237
+ def read_value_v4(buffer, type, custom_type_handlers)
238
+ case type.kind
239
+ when :ascii then read_ascii(buffer)
240
+ when :bigint, :counter then read_bigint(buffer)
241
+ when :blob then buffer.read_bytes
242
+ when :boolean then read_boolean(buffer)
243
+ when :decimal then read_decimal(buffer)
244
+ when :double then read_double(buffer)
245
+ when :float then read_float(buffer)
246
+ when :int then read_int(buffer)
247
+ when :timestamp then read_timestamp(buffer)
248
+ when :uuid then read_uuid(buffer)
249
+ when :timeuuid then read_uuid(buffer, TimeUuid)
250
+ when :text then read_text(buffer)
251
+ when :varint then read_varint(buffer)
252
+ when :inet then read_inet(buffer)
253
+ when :tinyint then read_tinyint(buffer)
254
+ when :smallint then read_smallint(buffer)
255
+ when :time then read_time(buffer)
256
+ when :date then read_date(buffer)
257
+ when :custom then read_custom(buffer, type, custom_type_handlers)
258
+ when :list
259
+ return nil unless read_size(buffer)
260
+
261
+ value_type = type.value_type
262
+ ::Array.new(buffer.read_signed_int) { read_value_v4(buffer, value_type, custom_type_handlers) }
263
+ when :map
264
+ return nil unless read_size(buffer)
265
+
266
+ key_type = type.key_type
267
+ value_type = type.value_type
268
+ value = ::Hash.new
269
+
270
+ buffer.read_signed_int.times do
271
+ value[read_value_v4(buffer, key_type, custom_type_handlers)] =
272
+ read_value_v4(buffer, value_type, custom_type_handlers)
273
+ end
274
+
275
+ value
276
+ when :set
277
+ return nil unless read_size(buffer)
278
+
279
+ value_type = type.value_type
280
+ value = ::Set.new
281
+
282
+ buffer.read_signed_int.times do
283
+ value << read_value_v4(buffer, value_type, custom_type_handlers)
284
+ end
285
+
286
+ value
287
+ when :udt
288
+ size = read_size(buffer)
289
+ return nil unless size
290
+
291
+ length = buffer.length
292
+ keyspace = type.keyspace
293
+ name = type.name
294
+ fields = type.fields
295
+ values = ::Hash.new
296
+
297
+ fields.each do |field|
298
+ values[field.name] = if length - buffer.length >= size
299
+ nil
300
+ else
301
+ read_value_v4(buffer, field.type, custom_type_handlers)
302
+ end
303
+ end
304
+
305
+ Cassandra::UDT::Strict.new(keyspace, name, fields, values)
306
+ when :tuple
307
+ return nil unless read_size(buffer)
308
+
309
+ members = type.members
310
+ values = ::Array.new
311
+
312
+ members.each do |member_type|
313
+ break if buffer.empty?
314
+ values << read_value_v4(buffer, member_type, custom_type_handlers)
315
+ end
316
+
317
+ values.fill(nil, values.length, (members.length - values.length))
318
+
319
+ Cassandra::Tuple::Strict.new(members, values)
320
+ else
321
+ raise Errors::DecodingError, %(Unsupported value type: #{type})
322
+ end
323
+ end
324
+
325
+ def write_values_v3(buffer, values, types, names = EMPTY_LIST)
326
+ if values && !values.empty?
327
+ buffer.append_short(values.size)
328
+ values.zip(types, names) do |(value, type, name)|
329
+ buffer.append_string(name) if name
330
+ write_value_v3(buffer, value, type)
331
+ end
332
+ buffer
333
+ else
334
+ buffer.append_short(0)
335
+ end
336
+ end
337
+
338
+ def write_list_v3(buffer, list, type)
339
+ raw = CqlByteBuffer.new
340
+
341
+ raw.append_int(list.size)
342
+ list.each do |element|
343
+ write_value_v3(raw, element, type)
344
+ end
345
+
346
+ buffer.append_bytes(raw)
347
+ end
348
+
349
+ def write_map_v3(buffer, map, key_type, value_type)
350
+ raw = CqlByteBuffer.new
351
+
352
+ raw.append_int(map.size)
353
+ map.each do |key, value|
354
+ write_value_v3(raw, key, key_type)
355
+ write_value_v3(raw, value, value_type)
356
+ end
357
+
358
+ buffer.append_bytes(raw)
359
+ end
360
+
361
+ def write_udt_v3(buffer, value, fields)
362
+ raw = CqlByteBuffer.new
363
+
364
+ fields.each do |field|
365
+ write_value_v3(raw, value[field.name], field.type)
366
+ end
367
+
368
+ buffer.append_bytes(raw)
369
+ end
370
+
371
+ def write_tuple_v3(buffer, value, members)
372
+ raw = CqlByteBuffer.new
373
+
374
+ members.each_with_index do |type, i|
375
+ write_value_v3(raw, value[i], type)
376
+ end
377
+
378
+ buffer.append_bytes(raw)
379
+ end
380
+
381
+ def write_value_v3(buffer, value, type)
382
+ if value.nil?
383
+ buffer.append_int(-1)
384
+ return
385
+ end
386
+
387
+ case type.kind
388
+ when :ascii then write_ascii(buffer, value)
389
+ when :bigint, :counter then write_bigint(buffer, value)
390
+ when :blob then write_blob(buffer, value)
391
+ when :boolean then write_boolean(buffer, value)
392
+ when :decimal then write_decimal(buffer, value)
393
+ when :double then write_double(buffer, value)
394
+ when :float then write_float(buffer, value)
395
+ when :int then write_int(buffer, value)
396
+ when :inet then write_inet(buffer, value)
397
+ when :timestamp then write_timestamp(buffer, value)
398
+ when :uuid, :timeuuid then write_uuid(buffer, value)
399
+ when :text then write_text(buffer, value)
400
+ when :varint then write_varint(buffer, value)
401
+ when :list, :set then write_list_v3(buffer, value, type.value_type)
402
+ when :map then write_map_v3(buffer,
403
+ value,
404
+ type.key_type,
405
+ type.value_type)
406
+ when :udt then write_udt_v3(buffer, value, type.fields)
407
+ when :tuple then write_tuple_v3(buffer, value, type.members)
408
+ else
409
+ raise Errors::EncodingError, %(Unsupported value type: #{type})
410
+ end
411
+ end
412
+
413
+ def read_values_v3(buffer, column_metadata)
414
+ ::Array.new(buffer.read_int) do |_i|
415
+ row = ::Hash.new
416
+
417
+ column_metadata.each do |(_, _, column, type)|
418
+ row[column] = read_value_v3(buffer, type)
419
+ end
420
+
421
+ row
422
+ end
423
+ end
424
+
425
+ def read_value_v3(buffer, type)
426
+ case type.kind
427
+ when :ascii then read_ascii(buffer)
428
+ when :bigint, :counter then read_bigint(buffer)
429
+ when :blob then buffer.read_bytes
430
+ when :boolean then read_boolean(buffer)
431
+ when :decimal then read_decimal(buffer)
432
+ when :double then read_double(buffer)
433
+ when :float then read_float(buffer)
434
+ when :int then read_int(buffer)
435
+ when :timestamp then read_timestamp(buffer)
436
+ when :uuid then read_uuid(buffer)
437
+ when :timeuuid then read_uuid(buffer, TimeUuid)
438
+ when :text then read_text(buffer)
439
+ when :varint then read_varint(buffer)
440
+ when :inet then read_inet(buffer)
441
+ when :list
442
+ return nil unless read_size(buffer)
443
+
444
+ value_type = type.value_type
445
+ ::Array.new(buffer.read_signed_int) { read_value_v3(buffer, value_type) }
446
+ when :map
447
+ return nil unless read_size(buffer)
448
+
449
+ key_type = type.key_type
450
+ value_type = type.value_type
451
+ value = ::Hash.new
452
+
453
+ buffer.read_signed_int.times do
454
+ value[read_value_v3(buffer, key_type)] = read_value_v3(buffer, value_type)
455
+ end
456
+
457
+ value
458
+ when :set
459
+ return nil unless read_size(buffer)
460
+
461
+ value_type = type.value_type
462
+ value = ::Set.new
463
+
464
+ buffer.read_signed_int.times do
465
+ value << read_value_v3(buffer, value_type)
466
+ end
467
+
468
+ value
469
+ when :udt
470
+ size = read_size(buffer)
471
+ return nil unless size
472
+
473
+ length = buffer.length
474
+ keyspace = type.keyspace
475
+ name = type.name
476
+ fields = type.fields
477
+ values = ::Hash.new
478
+
479
+ fields.each do |field|
480
+ values[field.name] = if length - buffer.length >= size
481
+ nil
482
+ else
483
+ read_value_v3(buffer, field.type)
484
+ end
485
+ end
486
+
487
+ Cassandra::UDT::Strict.new(keyspace, name, fields, values)
488
+ when :tuple
489
+ return nil unless read_size(buffer)
490
+
491
+ members = type.members
492
+ values = ::Array.new
493
+
494
+ members.each do |member_type|
495
+ break if buffer.empty?
496
+ values << read_value_v3(buffer, member_type)
497
+ end
498
+
499
+ values.fill(nil, values.length, (members.length - values.length))
500
+
501
+ Cassandra::Tuple::Strict.new(members, values)
502
+ else
503
+ raise Errors::DecodingError, %(Unsupported value type: #{type})
504
+ end
505
+ end
506
+
507
+ def read_metadata_v3(buffer)
508
+ flags = buffer.read_int
509
+ count = buffer.read_int
510
+
511
+ paging_state = nil
512
+ paging_state = buffer.read_bytes if flags & HAS_MORE_PAGES_FLAG != 0
513
+ column_specs = nil
514
+
515
+ if flags & NO_METADATA_FLAG == 0
516
+ if flags & GLOBAL_TABLES_SPEC_FLAG != 0
517
+ keyspace_name = buffer.read_string
518
+ table_name = buffer.read_string
519
+
520
+ column_specs = ::Array.new(count) do |_i|
521
+ [keyspace_name, table_name, buffer.read_string, read_type_v3(buffer)]
522
+ end
523
+ else
524
+ column_specs = ::Array.new(count) do |_i|
525
+ [
526
+ buffer.read_string,
527
+ buffer.read_string,
528
+ buffer.read_string,
529
+ read_type_v3(buffer)
530
+ ]
531
+ end
532
+ end
533
+ end
534
+
535
+ [column_specs, paging_state]
536
+ end
537
+
538
+ def read_type_v3(buffer)
539
+ id = buffer.read_unsigned_short
540
+ case id
541
+ when 0x0000 then Types.custom(buffer.read_string)
542
+ when 0x0001 then Types.ascii
543
+ when 0x0002 then Types.bigint
544
+ when 0x0003 then Types.blob
545
+ when 0x0004 then Types.boolean
546
+ when 0x0005 then Types.counter
547
+ when 0x0006 then Types.decimal
548
+ when 0x0007 then Types.double
549
+ when 0x0008 then Types.float
550
+ when 0x0009 then Types.int
551
+ when 0x000B then Types.timestamp
552
+ when 0x000C then Types.uuid
553
+ when 0x000D then Types.text
554
+ when 0x000E then Types.varint
555
+ when 0x000F then Types.timeuuid
556
+ when 0x0010 then Types.inet
557
+ when 0x0020 then Types.list(read_type_v3(buffer))
558
+ when 0x0021 then Types.map(read_type_v3(buffer), read_type_v3(buffer))
559
+ when 0x0022 then Types.set(read_type_v3(buffer))
560
+ when 0x0030
561
+ keyspace = buffer.read_string
562
+ name = buffer.read_string
563
+ fields = ::Array.new(buffer.read_short) do
564
+ [buffer.read_string, read_type_v3(buffer)]
565
+ end
566
+
567
+ Types.udt(keyspace, name, fields)
568
+ when 0x0031 then Types.tuple(
569
+ *::Array.new(buffer.read_short) { read_type_v3(buffer) }
570
+ )
571
+ else
572
+ raise Errors::DecodingError, %(Unsupported column type: #{id})
573
+ end
574
+ end
575
+
576
+ def write_values_v1(buffer, values, types)
577
+ if values && !values.empty?
578
+ buffer.append_short(values.size)
579
+ values.each_with_index do |value, index|
580
+ write_value_v1(buffer, value, types[index])
581
+ end
582
+ buffer
583
+ else
584
+ buffer.append_short(0)
585
+ end
586
+ end
587
+
588
+ def write_list_v1(buffer, list, type)
589
+ raw = CqlByteBuffer.new
590
+
591
+ raw.append_short(list.size)
592
+ list.each do |element|
593
+ write_short_value(raw, element, type)
594
+ end
595
+
596
+ buffer.append_bytes(raw)
597
+ end
598
+
599
+ def write_map_v1(buffer, map, key_type, value_type)
600
+ raw = CqlByteBuffer.new
601
+
602
+ raw.append_short(map.size)
603
+ map.each do |key, value|
604
+ write_short_value(raw, key, key_type)
605
+ write_short_value(raw, value, value_type)
606
+ end
607
+
608
+ buffer.append_bytes(raw)
609
+ end
610
+
611
+ def write_value_v1(buffer, value, type)
612
+ if value.nil?
613
+ buffer.append_int(-1)
614
+ return
615
+ end
616
+
617
+ case type.kind
618
+ when :ascii then write_ascii(buffer, value)
619
+ when :bigint, :counter then write_bigint(buffer, value)
620
+ when :blob then write_blob(buffer, value)
621
+ when :boolean then write_boolean(buffer, value)
622
+ when :decimal then write_decimal(buffer, value)
623
+ when :double then write_double(buffer, value)
624
+ when :float then write_float(buffer, value)
625
+ when :int then write_int(buffer, value)
626
+ when :inet then write_inet(buffer, value)
627
+ when :text then write_text(buffer, value)
628
+ when :timestamp then write_timestamp(buffer, value)
629
+ when :timeuuid, :uuid then write_uuid(buffer, value)
630
+ when :varint then write_varint(buffer, value)
631
+ when :list, :set then write_list_v1(buffer, value, type.value_type)
632
+ when :map then write_map_v1(buffer,
633
+ value,
634
+ type.key_type,
635
+ type.value_type)
636
+ else
637
+ raise Errors::EncodingError, %(Unsupported value type: #{type})
638
+ end
639
+ end
640
+
641
+ def read_values_v1(buffer, column_metadata)
642
+ ::Array.new(buffer.read_int) do |_i|
643
+ row = ::Hash.new
644
+
645
+ column_metadata.each do |(_, _, column, type)|
646
+ row[column] = read_value_v1(buffer, type)
647
+ end
648
+
649
+ row
650
+ end
651
+ end
652
+
653
+ def read_value_v1(buffer, type)
654
+ case type.kind
655
+ when :ascii then read_ascii(buffer)
656
+ when :bigint, :counter then read_bigint(buffer)
657
+ when :blob then buffer.read_bytes
658
+ when :boolean then read_boolean(buffer)
659
+ when :decimal then read_decimal(buffer)
660
+ when :double then read_double(buffer)
661
+ when :float then read_float(buffer)
662
+ when :int then read_int(buffer)
663
+ when :timestamp then read_timestamp(buffer)
664
+ when :text then read_text(buffer)
665
+ when :varint then read_varint(buffer)
666
+ when :uuid then read_uuid(buffer)
667
+ when :timeuuid then read_uuid(buffer, TimeUuid)
668
+ when :inet then read_inet(buffer)
669
+ when :list
670
+ return nil unless read_size(buffer)
671
+
672
+ value_type = type.value_type
673
+ ::Array.new(buffer.read_short) { read_short_value(buffer, value_type) }
674
+ when :map
675
+ return nil unless read_size(buffer)
676
+
677
+ key_type = type.key_type
678
+ value_type = type.value_type
679
+
680
+ value = ::Hash.new
681
+
682
+ buffer.read_short.times do
683
+ value[read_short_value(buffer, key_type)] =
684
+ read_short_value(buffer, value_type)
685
+ end
686
+
687
+ value
688
+ when :set
689
+ return nil unless read_size(buffer)
690
+
691
+ value_type = type.value_type
692
+
693
+ value = ::Set.new
694
+
695
+ buffer.read_short.times do
696
+ value << read_short_value(buffer, value_type)
697
+ end
698
+
699
+ value
700
+ else
701
+ raise Errors::DecodingError, %(Unsupported value type: #{type})
702
+ end
703
+ end
704
+
705
+ def read_metadata_v1(buffer)
706
+ flags = buffer.read_int
707
+ count = buffer.read_int
708
+
709
+ paging_state = nil
710
+ paging_state = buffer.read_bytes if flags & HAS_MORE_PAGES_FLAG != 0
711
+ column_specs = nil
712
+
713
+ if flags & NO_METADATA_FLAG == 0
714
+ if flags & GLOBAL_TABLES_SPEC_FLAG != 0
715
+ keyspace_name = buffer.read_string
716
+ table_name = buffer.read_string
717
+
718
+ column_specs = ::Array.new(count) do |_i|
719
+ [keyspace_name, table_name, buffer.read_string, read_type_v1(buffer)]
720
+ end
721
+ else
722
+ column_specs = ::Array.new(count) do |_i|
723
+ [
724
+ buffer.read_string,
725
+ buffer.read_string,
726
+ buffer.read_string,
727
+ read_type_v1(buffer)
728
+ ]
729
+ end
730
+ end
731
+ end
732
+
733
+ [column_specs, paging_state]
734
+ end
735
+
736
+ def read_type_v1(buffer)
737
+ kind = buffer.read_unsigned_short
738
+
739
+ case kind
740
+ when 0x0000 then Types.custom(buffer.read_string)
741
+ when 0x0001 then Types.ascii
742
+ when 0x0002 then Types.bigint
743
+ when 0x0003 then Types.blob
744
+ when 0x0004 then Types.boolean
745
+ when 0x0005 then Types.counter
746
+ when 0x0006 then Types.decimal
747
+ when 0x0007 then Types.double
748
+ when 0x0008 then Types.float
749
+ when 0x0009 then Types.int
750
+ when 0x000A then Types.text
751
+ when 0x000B then Types.timestamp
752
+ when 0x000C then Types.uuid
753
+ when 0x000D then Types.text
754
+ when 0x000E then Types.varint
755
+ when 0x000F then Types.timeuuid
756
+ when 0x0010 then Types.inet
757
+ when 0x0020 then Types.list(read_type_v1(buffer))
758
+ when 0x0021 then Types.map(read_type_v1(buffer), read_type_v1(buffer))
759
+ when 0x0022 then Types.set(read_type_v1(buffer))
760
+ else
761
+ raise Errors::DecodingError, %(Unsupported column type: #{kind})
762
+ end
763
+ end
764
+
765
+ def read_ascii(buffer)
766
+ value = buffer.read_bytes
767
+ value && value.force_encoding(::Encoding::ASCII)
768
+ end
769
+
770
+ def read_bigint(buffer)
771
+ read_size(buffer) && buffer.read_long
772
+ end
773
+
774
+ alias read_counter read_bigint
775
+
776
+ def read_boolean(buffer)
777
+ read_size(buffer) && buffer.read(1) == Constants::TRUE_BYTE
778
+ end
779
+
780
+ def read_custom(buffer, type, custom_type_handlers)
781
+ # Lookup the type-name to get the Class that can deserialize buffer data into a custom domain object.
782
+ unless custom_type_handlers && custom_type_handlers.key?(type)
783
+ raise Errors::DecodingError, %(Unsupported custom column type: #{type.name})
784
+ end
785
+ num_bytes = read_size(buffer)
786
+ custom_type_handlers[type].deserialize(buffer.read(num_bytes)) if num_bytes && num_bytes > 0
787
+ end
788
+
789
+ def read_decimal(buffer)
790
+ size = read_size(buffer)
791
+ size && buffer.read_decimal(size)
792
+ end
793
+
794
+ def read_double(buffer)
795
+ read_size(buffer) && buffer.read_double
796
+ end
797
+
798
+ def read_float(buffer)
799
+ read_size(buffer) && buffer.read_float
800
+ end
801
+
802
+ def read_int(buffer)
803
+ read_size(buffer) && buffer.read_signed_int
804
+ end
805
+
806
+ def read_timestamp(buffer)
807
+ return nil unless read_size(buffer)
808
+
809
+ timestamp = buffer.read_long
810
+ seconds = timestamp / 1_000
811
+ microsenconds = (timestamp % 1_000) * 1_000
812
+
813
+ ::Time.at(seconds, microsenconds)
814
+ end
815
+
816
+ def read_uuid(buffer, klass = Uuid)
817
+ read_size(buffer) && buffer.read_uuid(klass)
818
+ end
819
+
820
+ def read_text(buffer)
821
+ value = buffer.read_bytes
822
+ value && value.force_encoding(::Encoding::UTF_8)
823
+ end
824
+
825
+ def read_varint(buffer)
826
+ size = read_size(buffer)
827
+ size && buffer.read_varint(size)
828
+ end
829
+
830
+ def read_inet(buffer)
831
+ size = read_size(buffer)
832
+ size && ::IPAddr.new_ntoh(buffer.read(size))
833
+ end
834
+
835
+ def read_tinyint(buffer)
836
+ read_size(buffer) && buffer.read_tinyint
837
+ end
838
+
839
+ def read_smallint(buffer)
840
+ read_size(buffer) && buffer.read_smallint
841
+ end
842
+
843
+ def read_time(buffer)
844
+ return nil unless read_size(buffer)
845
+
846
+ Time.new(buffer.read_long)
847
+ end
848
+
849
+ def read_date(buffer)
850
+ return nil unless read_size(buffer)
851
+
852
+ ::Date.jd(DATE_OFFSET + buffer.read_int, ::Date::GREGORIAN)
853
+ end
854
+
855
+ def write_ascii(buffer, value)
856
+ buffer.append_bytes(value.encode(::Encoding::ASCII))
857
+ end
858
+
859
+ def write_bigint(buffer, value)
860
+ buffer.append_int(8)
861
+ buffer.append_long(value)
862
+ end
863
+
864
+ alias write_counter write_bigint
865
+
866
+ def write_blob(buffer, value)
867
+ buffer.append_bytes(value.encode(::Encoding::BINARY))
868
+ end
869
+
870
+ def write_boolean(buffer, value)
871
+ buffer.append_int(1)
872
+ buffer.append(value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
873
+ end
874
+
875
+ def write_custom(buffer, value, type)
876
+ # Verify that the given type-name matches the value's cql type name.
877
+ if value.class.type != type
878
+ raise Errors::EncodingError, "type mismatch: value is a #{value.type} and column is a #{type}"
879
+ end
880
+
881
+ buffer.append_bytes(value.serialize)
882
+ end
883
+
884
+ def write_decimal(buffer, value)
885
+ buffer.append_bytes(CqlByteBuffer.new.append_decimal(value))
886
+ end
887
+
888
+ def write_double(buffer, value)
889
+ buffer.append_int(8)
890
+ buffer.append_double(value)
891
+ end
892
+
893
+ def write_float(buffer, value)
894
+ buffer.append_int(4)
895
+ buffer.append_float(value)
896
+ end
897
+
898
+ def write_int(buffer, value)
899
+ buffer.append_int(4)
900
+ buffer.append_int(value)
901
+ end
902
+
903
+ def write_inet(buffer, value)
904
+ buffer.append_int(value.ipv6? ? 16 : 4)
905
+ buffer.append(value.hton)
906
+ end
907
+
908
+ def write_timestamp(buffer, value)
909
+ ms = (value.to_r.to_f * 1000).to_i
910
+ buffer.append_int(8)
911
+ buffer.append_long(ms)
912
+ end
913
+
914
+ def write_text(buffer, value)
915
+ buffer.append_bytes(value.encode(::Encoding::UTF_8))
916
+ end
917
+
918
+ def write_uuid(buffer, value)
919
+ buffer.append_int(16)
920
+ buffer.append_uuid(value)
921
+ end
922
+
923
+ def write_varint(buffer, value)
924
+ buffer.append_bytes(CqlByteBuffer.new.append_varint(value))
925
+ end
926
+
927
+ def write_tinyint(buffer, value)
928
+ buffer.append_int(1)
929
+ buffer.append_tinyint(value)
930
+ end
931
+
932
+ def write_smallint(buffer, value)
933
+ buffer.append_int(2)
934
+ buffer.append_smallint(value)
935
+ end
936
+
937
+ def write_time(buffer, value)
938
+ ns = value.to_nanoseconds
939
+ buffer.append_int(8)
940
+ buffer.append_long(ns)
941
+ end
942
+
943
+ def write_date(buffer, value)
944
+ buffer.append_int(4)
945
+ buffer.append_int(value.gregorian.jd - DATE_OFFSET)
946
+ end
947
+
948
+ def read_short_size(buffer)
949
+ size = buffer.read_short
950
+
951
+ return nil if size & 0x8000 == 0x8000 || (size == 0)
952
+
953
+ size
954
+ end
955
+
956
+ def read_short_value(buffer, type)
957
+ case type.kind
958
+ when :ascii
959
+ value = buffer.read_short_bytes
960
+ value && value.force_encoding(::Encoding::ASCII)
961
+ when :bigint, :counter
962
+ read_short_size(buffer) && buffer.read_long
963
+ when :blob
964
+ value = buffer.read_short_bytes
965
+ value && value.force_encoding(::Encoding::BINARY)
966
+ when :boolean
967
+ read_short_size(buffer) && buffer.read(1) == Constants::TRUE_BYTE
968
+ when :decimal
969
+ size = read_short_size(buffer)
970
+ size && buffer.read_decimal(size)
971
+ when :double
972
+ read_short_size(buffer) && buffer.read_double
973
+ when :float
974
+ read_short_size(buffer) && buffer.read_float
975
+ when :int
976
+ read_short_size(buffer) && buffer.read_signed_int
977
+ when :inet
978
+ size = read_short_size(buffer)
979
+ size && ::IPAddr.new_ntoh(buffer.read(size))
980
+ when :text
981
+ value = buffer.read_short_bytes
982
+ value && value.force_encoding(::Encoding::UTF_8)
983
+ when :timestamp
984
+ return nil unless read_short_size(buffer)
985
+
986
+ timestamp = buffer.read_long
987
+ seconds = timestamp / 1_000
988
+ microsenconds = (timestamp % 1_000) * 1_000
989
+
990
+ ::Time.at(seconds, microsenconds)
991
+ when :timeuuid
992
+ read_short_size(buffer) && buffer.read_uuid(TimeUuid)
993
+ when :uuid
994
+ read_short_size(buffer) && buffer.read_uuid
995
+ when :varint
996
+ size = read_short_size(buffer)
997
+ size && buffer.read_varint(size)
998
+ else
999
+ raise Errors::EncodingError, %(Unsupported short value type: #{type})
1000
+ end
1001
+ end
1002
+
1003
+ def write_short_value(buffer, value, type)
1004
+ case type.kind
1005
+ when :ascii
1006
+ buffer.append_short_bytes(value && value.encode(::Encoding::ASCII))
1007
+ when :bigint, :counter
1008
+ if value
1009
+ buffer.append_short(8)
1010
+ buffer.append_long(value)
1011
+ else
1012
+ buffer.append_short(-1)
1013
+ end
1014
+ when :blob
1015
+ buffer.append_short_bytes(value && value.encode(::Encoding::BINARY))
1016
+ when :boolean
1017
+ if !value.nil?
1018
+ buffer.append_short(1)
1019
+ buffer.append(value ? Constants::TRUE_BYTE : Constants::FALSE_BYTE)
1020
+ else
1021
+ buffer.append_short(-1)
1022
+ end
1023
+ when :decimal
1024
+ buffer.append_short_bytes(value && CqlByteBuffer.new.append_decimal(value))
1025
+ when :double
1026
+ if value
1027
+ buffer.append_short(8)
1028
+ buffer.append_double(value)
1029
+ else
1030
+ buffer.append_short(-1)
1031
+ end
1032
+ when :float
1033
+ if value
1034
+ buffer.append_short(4)
1035
+ buffer.append_float(value)
1036
+ else
1037
+ buffer.append_short(-1)
1038
+ end
1039
+ when :inet
1040
+ if value
1041
+ buffer.append_short(value.ipv6? ? 16 : 4)
1042
+ buffer.append(value.hton)
1043
+ else
1044
+ buffer.append_short(-1)
1045
+ end
1046
+ when :int
1047
+ if value
1048
+ buffer.append_short(4)
1049
+ buffer.append_int(value)
1050
+ else
1051
+ buffer.append_short(-1)
1052
+ end
1053
+ when :text
1054
+ buffer.append_short_bytes(value && value.encode(::Encoding::UTF_8))
1055
+ when :timestamp
1056
+ if value
1057
+ buffer.append_short(8)
1058
+ buffer.append_long((value.to_f * 1000).to_i)
1059
+ else
1060
+ buffer.append_short(-1)
1061
+ end
1062
+ when :timeuuid, :uuid
1063
+ if value
1064
+ buffer.append_short(16)
1065
+ buffer.append_uuid(value)
1066
+ else
1067
+ buffer.append_short(-1)
1068
+ end
1069
+ when :varint
1070
+ buffer.append_short_bytes(value && CqlByteBuffer.new.append_varint(value))
1071
+ else
1072
+ raise Errors::EncodingError, %(Unsupported short value type: #{type})
1073
+ end
1074
+ end
1075
+
1076
+ def read_size(buffer)
1077
+ size = buffer.read_signed_int
1078
+
1079
+ return nil if (size & 0x80000000 == 0x80000000) || (size == 0)
1080
+
1081
+ size
1082
+ end
1083
+ end
1084
+ end
1085
+ end