cassandra-driver 2.1.7-java → 3.0.0.beta.1-java
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.
- checksums.yaml +4 -4
- data/README.md +31 -53
- data/lib/cassandra.rb +22 -3
- data/lib/cassandra/aggregate.rb +109 -0
- data/lib/cassandra/argument.rb +51 -0
- data/lib/cassandra/auth/providers/password.rb +7 -4
- data/lib/cassandra/cluster.rb +14 -3
- data/lib/cassandra/cluster/client.rb +56 -34
- data/lib/cassandra/cluster/connector.rb +6 -6
- data/lib/cassandra/cluster/control_connection.rb +204 -251
- data/lib/cassandra/cluster/metadata.rb +2 -0
- data/lib/cassandra/cluster/schema.rb +131 -209
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +104 -0
- data/lib/cassandra/cluster/schema/fetchers.rb +1174 -0
- data/lib/cassandra/cluster/schema/{type_parser.rb → fqcn_type_parser.rb} +7 -3
- data/lib/cassandra/column.rb +2 -2
- data/lib/cassandra/driver.rb +27 -9
- data/lib/cassandra/errors.rb +179 -25
- data/lib/cassandra/execution/info.rb +8 -1
- data/lib/cassandra/execution/options.rb +34 -0
- data/lib/cassandra/execution/trace.rb +42 -10
- data/lib/cassandra/function.rb +150 -0
- data/lib/cassandra/future.rb +66 -35
- data/lib/cassandra/host.rb +7 -4
- data/lib/cassandra/keyspace.rb +112 -13
- data/lib/cassandra/load_balancing.rb +1 -1
- data/lib/cassandra/protocol.rb +9 -3
- data/lib/cassandra/protocol/coder.rb +434 -155
- data/lib/cassandra/protocol/cql_byte_buffer.rb +43 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +4 -1
- data/lib/cassandra/protocol/request.rb +4 -0
- data/lib/cassandra/protocol/requests/auth_response_request.rb +5 -1
- data/lib/cassandra/protocol/requests/batch_request.rb +7 -2
- data/lib/cassandra/protocol/requests/credentials_request.rb +5 -1
- data/lib/cassandra/protocol/requests/execute_request.rb +16 -10
- data/lib/cassandra/protocol/requests/prepare_request.rb +12 -3
- data/lib/cassandra/protocol/requests/query_request.rb +20 -11
- data/lib/cassandra/protocol/responses/already_exists_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/error_response.rb +14 -14
- data/lib/cassandra/protocol/responses/function_failure_error_response.rb +41 -0
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +12 -9
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +5 -3
- data/lib/cassandra/protocol/responses/read_failure_error_response.rb +43 -0
- data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/ready_response.rb +5 -1
- data/lib/cassandra/protocol/responses/result_response.rb +3 -3
- data/lib/cassandra/protocol/responses/rows_result_response.rb +2 -2
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +25 -24
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +20 -23
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +2 -2
- data/lib/cassandra/protocol/responses/unavailable_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/unprepared_error_response.rb +4 -4
- data/lib/cassandra/protocol/responses/write_failure_error_response.rb +45 -0
- data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +4 -4
- data/lib/cassandra/protocol/v1.rb +38 -13
- data/lib/cassandra/protocol/v3.rb +34 -29
- data/lib/cassandra/protocol/v4.rb +334 -0
- data/lib/cassandra/result.rb +10 -9
- data/lib/cassandra/retry.rb +17 -3
- data/lib/cassandra/retry/policies/default.rb +9 -3
- data/lib/cassandra/session.rb +15 -7
- data/lib/cassandra/statement.rb +5 -0
- data/lib/cassandra/statements/batch.rb +36 -12
- data/lib/cassandra/statements/bound.rb +2 -1
- data/lib/cassandra/statements/prepared.rb +106 -35
- data/lib/cassandra/statements/simple.rb +4 -2
- data/lib/cassandra/table.rb +70 -105
- data/lib/cassandra/time.rb +98 -0
- data/lib/cassandra/time_uuid.rb +1 -1
- data/lib/cassandra/tuple.rb +7 -0
- data/lib/cassandra/types.rb +472 -272
- data/lib/cassandra/udt.rb +10 -0
- data/lib/cassandra/util.rb +32 -1
- data/lib/cassandra/uuid.rb +6 -1
- data/lib/cassandra/uuid/generator.rb +7 -7
- data/lib/cassandra/version.rb +1 -1
- data/lib/cassandra_murmur3.jar +0 -0
- data/lib/datastax/cassandra.rb +5 -2
- metadata +27 -17
@@ -30,6 +30,8 @@ module Cassandra
|
|
30
30
|
@partitioners = schema_partitioners
|
31
31
|
@strategies = replication_strategies
|
32
32
|
@default_strategy = default_replication_strategy
|
33
|
+
@token_replicas = ::Hash.new
|
34
|
+
@token_ring = ::Array.new
|
33
35
|
end
|
34
36
|
|
35
37
|
def find_replicas(keyspace, statement)
|
@@ -22,17 +22,33 @@ module Cassandra
|
|
22
22
|
class Schema
|
23
23
|
include MonitorMixin
|
24
24
|
|
25
|
-
def initialize
|
26
|
-
@
|
27
|
-
@
|
28
|
-
@listeners = ::Set.new
|
25
|
+
def initialize
|
26
|
+
@keyspaces = ::Hash.new
|
27
|
+
@listeners = ::Set.new
|
29
28
|
|
30
29
|
mon_initialize
|
31
30
|
end
|
32
31
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
32
|
+
def get_pk_idx(metadata)
|
33
|
+
return EMPTY_LIST unless metadata
|
34
|
+
|
35
|
+
keyspace_name, table_name, _ = metadata.first
|
36
|
+
return EMPTY_LIST unless keyspace_name && table_name
|
37
|
+
|
38
|
+
keyspace = @keyspaces[keyspace_name]
|
39
|
+
return EMPTY_LIST unless keyspace
|
40
|
+
|
41
|
+
table = keyspace.table(table_name)
|
42
|
+
return EMPTY_LIST unless table
|
43
|
+
|
44
|
+
partition_key = table.partition_key
|
45
|
+
return EMPTY_LIST unless partition_key && partition_key.size <= metadata.size
|
46
|
+
|
47
|
+
partition_key.map do |column|
|
48
|
+
i = metadata.index {|(_, _, name, _)| name == column.name}
|
49
|
+
return EMPTY_LIST if i.nil?
|
50
|
+
i
|
51
|
+
end
|
36
52
|
end
|
37
53
|
|
38
54
|
def add_listener(listener)
|
@@ -51,25 +67,13 @@ module Cassandra
|
|
51
67
|
self
|
52
68
|
end
|
53
69
|
|
54
|
-
def
|
55
|
-
columns = columns.each_with_object(deephash { [] }) do |row, index|
|
56
|
-
index[row['keyspace_name']] << row
|
57
|
-
end
|
58
|
-
|
59
|
-
tables = tables.each_with_object(deephash { [] }) do |row, index|
|
60
|
-
index[row['keyspace_name']] << row
|
61
|
-
end
|
62
|
-
|
63
|
-
types = types.each_with_object(deephash { [] }) do |row, index|
|
64
|
-
index[row['keyspace_name']] << row
|
65
|
-
end
|
66
|
-
|
70
|
+
def replace(keyspaces)
|
67
71
|
current_keyspaces = ::Set.new
|
68
72
|
|
69
|
-
keyspaces.each do |
|
70
|
-
current_keyspaces << keyspace
|
73
|
+
keyspaces.each do |keyspace|
|
74
|
+
current_keyspaces << keyspace.name
|
71
75
|
|
72
|
-
|
76
|
+
replace_keyspace(keyspace)
|
73
77
|
end
|
74
78
|
|
75
79
|
@keyspaces.each do |name, keyspace|
|
@@ -79,40 +83,21 @@ module Cassandra
|
|
79
83
|
self
|
80
84
|
end
|
81
85
|
|
82
|
-
def
|
83
|
-
|
86
|
+
def replace_keyspace(keyspace)
|
87
|
+
old_keyspace = @keyspaces[keyspace.name]
|
84
88
|
|
85
|
-
|
86
|
-
index[row['columnfamily_name']][row['column_name']] = row
|
87
|
-
end
|
88
|
-
|
89
|
-
tables = tables.each_with_object(Hash.new) do |row, index|
|
90
|
-
name = row['columnfamily_name']
|
91
|
-
index[name] = create_table(row, columns[name], host.release_version)
|
92
|
-
end
|
93
|
-
|
94
|
-
types = types.each_with_object(Hash.new) do |row, index|
|
95
|
-
name = row['type_name']
|
96
|
-
index[name] = create_type(row, host.release_version)
|
97
|
-
end
|
98
|
-
|
99
|
-
replication = Keyspace::Replication.new(keyspace['strategy_class'], ::JSON.load(keyspace['strategy_options']))
|
100
|
-
keyspace = Keyspace.new(keyspace_name, keyspace['durable_writes'], replication, tables, types)
|
101
|
-
|
102
|
-
return self if keyspace == @keyspaces[keyspace_name]
|
103
|
-
|
104
|
-
created = !@keyspaces.include?(keyspace_name)
|
89
|
+
return self if old_keyspace == keyspace
|
105
90
|
|
106
91
|
synchronize do
|
107
92
|
keyspaces = @keyspaces.dup
|
108
|
-
keyspaces[
|
93
|
+
keyspaces[keyspace.name] = keyspace
|
109
94
|
@keyspaces = keyspaces
|
110
95
|
end
|
111
96
|
|
112
|
-
if
|
113
|
-
keyspace_created(keyspace)
|
114
|
-
else
|
97
|
+
if old_keyspace
|
115
98
|
keyspace_changed(keyspace)
|
99
|
+
else
|
100
|
+
keyspace_created(keyspace)
|
116
101
|
end
|
117
102
|
|
118
103
|
self
|
@@ -134,20 +119,20 @@ module Cassandra
|
|
134
119
|
self
|
135
120
|
end
|
136
121
|
|
137
|
-
def
|
138
|
-
keyspace = @keyspaces[
|
122
|
+
def replace_table(table)
|
123
|
+
keyspace = @keyspaces[table.keyspace]
|
139
124
|
|
140
125
|
return self unless keyspace
|
141
126
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
127
|
+
old_table = keyspace.table(table.name)
|
128
|
+
|
129
|
+
return self if old_table == table
|
130
|
+
|
146
131
|
keyspace = keyspace.update_table(table)
|
147
132
|
|
148
133
|
synchronize do
|
149
134
|
keyspaces = @keyspaces.dup
|
150
|
-
keyspaces[
|
135
|
+
keyspaces[keyspace.name] = keyspace
|
151
136
|
@keyspaces = keyspaces
|
152
137
|
end
|
153
138
|
|
@@ -161,6 +146,10 @@ module Cassandra
|
|
161
146
|
|
162
147
|
return self unless keyspace
|
163
148
|
|
149
|
+
table = keyspace.table(table_name)
|
150
|
+
|
151
|
+
return self unless table
|
152
|
+
|
164
153
|
keyspace = keyspace.delete_table(table_name)
|
165
154
|
|
166
155
|
synchronize do
|
@@ -174,17 +163,20 @@ module Cassandra
|
|
174
163
|
self
|
175
164
|
end
|
176
165
|
|
177
|
-
def
|
178
|
-
keyspace = @keyspaces[
|
166
|
+
def replace_type(type)
|
167
|
+
keyspace = @keyspaces[type.keyspace]
|
179
168
|
|
180
169
|
return self unless keyspace
|
181
170
|
|
182
|
-
|
171
|
+
old_type = keyspace.type(type.name)
|
172
|
+
|
173
|
+
return self if old_type == type
|
174
|
+
|
183
175
|
keyspace = keyspace.update_type(type)
|
184
176
|
|
185
177
|
synchronize do
|
186
178
|
keyspaces = @keyspaces.dup
|
187
|
-
keyspaces[
|
179
|
+
keyspaces[keyspace.name] = keyspace
|
188
180
|
@keyspaces = keyspaces
|
189
181
|
end
|
190
182
|
|
@@ -198,6 +190,10 @@ module Cassandra
|
|
198
190
|
|
199
191
|
return self unless keyspace
|
200
192
|
|
193
|
+
type = keyspace.type(type_name)
|
194
|
+
|
195
|
+
return self unless type
|
196
|
+
|
201
197
|
keyspace = keyspace.delete_type(type_name)
|
202
198
|
|
203
199
|
synchronize do
|
@@ -211,189 +207,113 @@ module Cassandra
|
|
211
207
|
self
|
212
208
|
end
|
213
209
|
|
214
|
-
def
|
215
|
-
@keyspaces.
|
216
|
-
end
|
210
|
+
def replace_function(function)
|
211
|
+
keyspace = @keyspaces[function.keyspace]
|
217
212
|
|
218
|
-
|
219
|
-
@keyspaces[name]
|
220
|
-
end
|
221
|
-
|
222
|
-
def each_keyspace(&block)
|
223
|
-
if block_given?
|
224
|
-
@keyspaces.each_value(&block)
|
225
|
-
self
|
226
|
-
else
|
227
|
-
@keyspaces.values
|
228
|
-
end
|
229
|
-
end
|
230
|
-
alias :keyspaces :each_keyspace
|
213
|
+
return self unless keyspace
|
231
214
|
|
232
|
-
|
215
|
+
old_function = keyspace.function(function.name, *function.argument_types)
|
233
216
|
|
234
|
-
|
235
|
-
keyspace = type['keyspace_name']
|
236
|
-
name = type['type_name']
|
237
|
-
fields = ::Array.new
|
217
|
+
return self if old_function == function
|
238
218
|
|
239
|
-
|
240
|
-
field_type = @type_parser.parse(field_type).results.first.first
|
219
|
+
keyspace = keyspace.update_function(function)
|
241
220
|
|
242
|
-
|
221
|
+
synchronize do
|
222
|
+
keyspaces = @keyspaces.dup
|
223
|
+
keyspaces[keyspace.name] = keyspace
|
224
|
+
@keyspaces = keyspaces
|
243
225
|
end
|
244
226
|
|
245
|
-
|
227
|
+
keyspace_changed(keyspace)
|
228
|
+
|
229
|
+
self
|
246
230
|
end
|
247
231
|
|
248
|
-
def
|
249
|
-
keyspace
|
250
|
-
|
251
|
-
|
252
|
-
comparator = @type_parser.parse(table['comparator'])
|
253
|
-
column_aliases = ::JSON.load(table['column_aliases'])
|
232
|
+
def delete_function(keyspace_name, function_name, function_arg_types)
|
233
|
+
keyspace = @keyspaces[keyspace_name]
|
234
|
+
|
235
|
+
return self unless keyspace
|
254
236
|
|
255
|
-
|
256
|
-
column_aliases, version)
|
237
|
+
function = keyspace.function(function_name, *function_arg_types)
|
257
238
|
|
258
|
-
|
259
|
-
is_compact = is_dense || !comparator.collections
|
260
|
-
partition_key = []
|
261
|
-
clustering_columns = []
|
262
|
-
clustering_order = []
|
239
|
+
return self unless function
|
263
240
|
|
264
|
-
|
265
|
-
table['compaction_strategy_class'],
|
266
|
-
::JSON.load(table['compaction_strategy_options'])
|
267
|
-
)
|
268
|
-
compression_parameters = ::JSON.load(table['compression_parameters'])
|
241
|
+
keyspace = keyspace.delete_function(function_name, function_arg_types)
|
269
242
|
|
270
|
-
|
271
|
-
|
243
|
+
synchronize do
|
244
|
+
keyspaces = @keyspaces.dup
|
245
|
+
keyspaces[keyspace_name] = keyspace
|
246
|
+
@keyspaces = keyspaces
|
247
|
+
end
|
248
|
+
|
249
|
+
keyspace_changed(keyspace)
|
272
250
|
|
273
|
-
|
251
|
+
self
|
274
252
|
end
|
275
253
|
|
276
|
-
def
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
(!comparator.collections.empty? || aliases.size == size - 1 && comparator.results.last.first == :text) ? size - 1 : size
|
281
|
-
else
|
282
|
-
(!aliases.empty? || columns.empty?) ? 1 : 0
|
283
|
-
end
|
284
|
-
else
|
285
|
-
max_index = nil
|
254
|
+
def replace_aggregate(aggregate)
|
255
|
+
keyspace = @keyspaces[aggregate.keyspace]
|
256
|
+
|
257
|
+
return self unless keyspace
|
286
258
|
|
287
|
-
|
288
|
-
if cl['type'].to_s.upcase == 'CLUSTERING_KEY'
|
289
|
-
index = cl['component_index'] || 0
|
259
|
+
old_aggregate = keyspace.aggregate(aggregate.name, *aggregate.argument_types)
|
290
260
|
|
291
|
-
|
292
|
-
max_index = index
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|
261
|
+
return self if old_aggregate == aggregate
|
296
262
|
|
297
|
-
|
263
|
+
keyspace = keyspace.update_aggregate(aggregate)
|
298
264
|
|
299
|
-
|
265
|
+
synchronize do
|
266
|
+
keyspaces = @keyspaces.dup
|
267
|
+
keyspaces[keyspace.name] = keyspace
|
268
|
+
@keyspaces = keyspaces
|
300
269
|
end
|
270
|
+
|
271
|
+
keyspace_changed(keyspace)
|
272
|
+
|
273
|
+
self
|
301
274
|
end
|
302
275
|
|
303
|
-
def
|
304
|
-
|
305
|
-
other_columns = []
|
306
|
-
|
307
|
-
if cassandra_version.start_with?('1')
|
308
|
-
key_aliases = ::JSON.load(table['key_aliases'])
|
309
|
-
|
310
|
-
key_validator.results.each_with_index do |(type, order, is_frozen), i|
|
311
|
-
key_alias = key_aliases.fetch(i) { i.zero? ? "key" : "key#{i + 1}" }
|
312
|
-
|
313
|
-
partition_key[i] = Column.new(key_alias, type, order, nil, false, is_frozen)
|
314
|
-
end
|
315
|
-
|
316
|
-
if comparator.results.size > 1
|
317
|
-
clustering_size.times do |i|
|
318
|
-
column_alias = column_aliases.fetch(i) { "column#{i + 1}" }
|
319
|
-
type, order, is_frozen = comparator.results.fetch(i)
|
320
|
-
|
321
|
-
clustering_columns[i] = Column.new(column_alias, type, order, nil, false, is_frozen)
|
322
|
-
clustering_order[i] = order
|
323
|
-
end
|
324
|
-
else
|
325
|
-
column_alias = column_aliases.first || "column1"
|
326
|
-
type, order, is_frozen = comparator.results.first
|
327
|
-
|
328
|
-
clustering_columns[0] = Column.new(column_alias, type, order, nil, false, is_frozen)
|
329
|
-
clustering_order[0] = order
|
330
|
-
end
|
331
|
-
|
332
|
-
if is_dense
|
333
|
-
value_alias = table['value_alias']
|
334
|
-
value_alias = 'value' if value_alias.nil? || value_alias.empty?
|
335
|
-
type, order, is_frozen = @type_parser.parse(table['default_validator']).results.first
|
336
|
-
other_columns << Column.new(value_alias, type, order, nil, false, is_frozen)
|
337
|
-
end
|
338
|
-
|
339
|
-
columns.each do |name, row|
|
340
|
-
other_columns << create_column(row)
|
341
|
-
end
|
342
|
-
else
|
343
|
-
columns.each do |name, row|
|
344
|
-
next if row['column_name'].empty?
|
345
|
-
|
346
|
-
column = create_column(row)
|
347
|
-
type = row['type'].to_s
|
348
|
-
index = row['component_index'] || 0
|
349
|
-
|
350
|
-
case type.upcase
|
351
|
-
when 'PARTITION_KEY'
|
352
|
-
partition_key[index] = column
|
353
|
-
when 'CLUSTERING_KEY'
|
354
|
-
clustering_columns[index] = column
|
355
|
-
clustering_order[index] = column.order
|
356
|
-
else
|
357
|
-
other_columns << column
|
358
|
-
end
|
359
|
-
end
|
360
|
-
end
|
276
|
+
def delete_aggregate(keyspace_name, aggregate_name, aggregate_arg_types)
|
277
|
+
keyspace = @keyspaces[keyspace_name]
|
361
278
|
|
362
|
-
|
363
|
-
table_columns[column.name] = column
|
364
|
-
end
|
279
|
+
return self unless keyspace
|
365
280
|
|
366
|
-
|
367
|
-
|
368
|
-
|
281
|
+
aggregate = keyspace.aggregate(aggregate_name, *aggregate_arg_types)
|
282
|
+
|
283
|
+
return self unless aggregate
|
369
284
|
|
370
|
-
|
371
|
-
|
285
|
+
keyspace = keyspace.delete_aggregate(aggregate_name, aggregate_arg_types)
|
286
|
+
|
287
|
+
synchronize do
|
288
|
+
keyspaces = @keyspaces.dup
|
289
|
+
keyspaces[keyspace_name] = keyspace
|
290
|
+
@keyspaces = keyspaces
|
372
291
|
end
|
373
292
|
|
374
|
-
|
293
|
+
keyspace_changed(keyspace)
|
294
|
+
|
295
|
+
self
|
296
|
+
end
|
297
|
+
|
298
|
+
def has_keyspace?(name)
|
299
|
+
@keyspaces.include?(name)
|
375
300
|
end
|
376
301
|
|
377
|
-
def
|
378
|
-
name
|
379
|
-
|
380
|
-
is_static = (column['type'] == 'STATIC')
|
302
|
+
def keyspace(name)
|
303
|
+
@keyspaces[name]
|
304
|
+
end
|
381
305
|
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
306
|
+
def each_keyspace(&block)
|
307
|
+
if block_given?
|
308
|
+
@keyspaces.each_value(&block)
|
309
|
+
self
|
386
310
|
else
|
387
|
-
|
388
|
-
index = Column::Index.new(column['index_name'], options && options['class_name'])
|
311
|
+
@keyspaces.values
|
389
312
|
end
|
390
|
-
|
391
|
-
Column.new(name, type, order, index, is_static, is_frozen)
|
392
313
|
end
|
314
|
+
alias :keyspaces :each_keyspace
|
393
315
|
|
394
|
-
|
395
|
-
::Hash.new {|hash, key| hash[key] = yield}
|
396
|
-
end
|
316
|
+
private
|
397
317
|
|
398
318
|
def keyspace_created(keyspace)
|
399
319
|
@listeners.each do |listener|
|
@@ -416,6 +336,8 @@ module Cassandra
|
|
416
336
|
end
|
417
337
|
end
|
418
338
|
|
339
|
+
require 'cassandra/cluster/schema/cql_type_parser'
|
340
|
+
require 'cassandra/cluster/schema/fetchers'
|
419
341
|
require 'cassandra/cluster/schema/partitioners'
|
420
342
|
require 'cassandra/cluster/schema/replication_strategies'
|
421
|
-
require 'cassandra/cluster/schema/
|
343
|
+
require 'cassandra/cluster/schema/fqcn_type_parser'
|