yugabyte-ycql-driver 3.2.3.1

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 (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