cassandra-driver 2.1.7-java → 3.0.0.beta.1-java
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|