cassandra-driver 3.0.0.beta.1-java → 3.0.0-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 +106 -39
- data/lib/cassandra.rb +396 -148
- data/lib/cassandra/address_resolution.rb +1 -1
- data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +1 -1
- data/lib/cassandra/address_resolution/policies/none.rb +1 -1
- data/lib/cassandra/aggregate.rb +21 -7
- data/lib/cassandra/argument.rb +2 -2
- data/lib/cassandra/attr_boolean.rb +33 -0
- data/lib/cassandra/auth.rb +6 -5
- data/lib/cassandra/auth/providers.rb +1 -1
- data/lib/cassandra/auth/providers/password.rb +5 -13
- data/lib/cassandra/cassandra_logger.rb +80 -0
- data/lib/cassandra/cluster.rb +49 -9
- data/lib/cassandra/cluster/client.rb +835 -209
- data/lib/cassandra/cluster/connection_pool.rb +2 -2
- data/lib/cassandra/cluster/connector.rb +86 -27
- data/lib/cassandra/cluster/control_connection.rb +222 -95
- data/lib/cassandra/cluster/failed_connection.rb +1 -1
- data/lib/cassandra/cluster/metadata.rb +14 -8
- data/lib/cassandra/cluster/options.rb +68 -22
- data/lib/cassandra/cluster/registry.rb +81 -17
- data/lib/cassandra/cluster/schema.rb +70 -8
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +15 -10
- data/lib/cassandra/cluster/schema/fetchers.rb +601 -241
- data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +39 -38
- data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
- data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +6 -8
- data/lib/cassandra/cluster/schema/partitioners/ordered.rb +1 -1
- data/lib/cassandra/cluster/schema/partitioners/random.rb +1 -1
- data/lib/cassandra/cluster/schema/replication_strategies.rb +1 -1
- data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +19 -18
- data/lib/cassandra/cluster/schema/replication_strategies/none.rb +1 -1
- data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +1 -1
- data/lib/cassandra/column.rb +4 -23
- data/lib/cassandra/column_container.rb +322 -0
- data/lib/cassandra/compression.rb +1 -1
- data/lib/cassandra/compression/compressors/lz4.rb +7 -8
- data/lib/cassandra/compression/compressors/snappy.rb +4 -3
- data/lib/cassandra/driver.rb +107 -46
- data/lib/cassandra/errors.rb +303 -52
- data/lib/cassandra/execution/info.rb +16 -5
- data/lib/cassandra/execution/options.rb +102 -55
- data/lib/cassandra/execution/trace.rb +16 -9
- data/lib/cassandra/executors.rb +1 -1
- data/lib/cassandra/function.rb +19 -13
- data/lib/cassandra/function_collection.rb +85 -0
- data/lib/cassandra/future.rb +101 -49
- data/lib/cassandra/host.rb +25 -5
- data/lib/cassandra/index.rb +118 -0
- data/lib/cassandra/keyspace.rb +169 -33
- data/lib/cassandra/listener.rb +1 -1
- data/lib/cassandra/load_balancing.rb +2 -2
- data/lib/cassandra/load_balancing/policies.rb +1 -1
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +39 -25
- data/lib/cassandra/load_balancing/policies/round_robin.rb +8 -1
- data/lib/cassandra/load_balancing/policies/token_aware.rb +22 -13
- data/lib/cassandra/load_balancing/policies/white_list.rb +18 -5
- data/lib/cassandra/materialized_view.rb +90 -0
- data/lib/cassandra/null_logger.rb +27 -6
- data/lib/cassandra/protocol.rb +1 -1
- data/lib/cassandra/protocol/coder.rb +81 -42
- data/lib/cassandra/protocol/cql_byte_buffer.rb +58 -44
- data/lib/cassandra/protocol/cql_protocol_handler.rb +57 -54
- data/lib/cassandra/protocol/request.rb +6 -7
- data/lib/cassandra/protocol/requests/auth_response_request.rb +3 -3
- data/lib/cassandra/protocol/requests/batch_request.rb +17 -8
- data/lib/cassandra/protocol/requests/credentials_request.rb +3 -3
- data/lib/cassandra/protocol/requests/execute_request.rb +39 -20
- data/lib/cassandra/protocol/requests/options_request.rb +1 -1
- data/lib/cassandra/protocol/requests/prepare_request.rb +5 -5
- data/lib/cassandra/protocol/requests/query_request.rb +28 -23
- data/lib/cassandra/protocol/requests/register_request.rb +2 -2
- data/lib/cassandra/protocol/requests/startup_request.rb +8 -8
- data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
- data/lib/cassandra/protocol/response.rb +3 -4
- data/lib/cassandra/protocol/responses/already_exists_error_response.rb +12 -2
- data/lib/cassandra/protocol/responses/auth_challenge_response.rb +4 -5
- data/lib/cassandra/protocol/responses/auth_success_response.rb +4 -5
- data/lib/cassandra/protocol/responses/authenticate_response.rb +4 -5
- data/lib/cassandra/protocol/responses/error_response.rb +104 -17
- data/lib/cassandra/protocol/responses/event_response.rb +3 -4
- data/lib/cassandra/protocol/responses/function_failure_error_response.rb +13 -2
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +14 -9
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +14 -9
- data/lib/cassandra/protocol/responses/read_failure_error_response.rb +26 -4
- data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +22 -3
- data/lib/cassandra/protocol/responses/ready_response.rb +6 -7
- data/lib/cassandra/protocol/responses/result_response.rb +11 -10
- data/lib/cassandra/protocol/responses/rows_result_response.rb +8 -7
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +8 -8
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +19 -13
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +5 -6
- data/lib/cassandra/protocol/responses/status_change_event_response.rb +5 -6
- data/lib/cassandra/protocol/responses/supported_response.rb +4 -5
- data/lib/cassandra/protocol/responses/topology_change_event_response.rb +4 -5
- data/lib/cassandra/protocol/responses/unavailable_error_response.rb +20 -3
- data/lib/cassandra/protocol/responses/unprepared_error_response.rb +11 -2
- data/lib/cassandra/protocol/responses/void_result_response.rb +4 -5
- data/lib/cassandra/protocol/responses/write_failure_error_response.rb +26 -4
- data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +22 -3
- data/lib/cassandra/protocol/v1.rb +98 -37
- data/lib/cassandra/protocol/v3.rb +121 -50
- data/lib/cassandra/protocol/v4.rb +172 -68
- data/lib/cassandra/reconnection.rb +1 -1
- data/lib/cassandra/reconnection/policies.rb +1 -1
- data/lib/cassandra/reconnection/policies/constant.rb +2 -4
- data/lib/cassandra/reconnection/policies/exponential.rb +6 -6
- data/lib/cassandra/result.rb +55 -20
- data/lib/cassandra/retry.rb +8 -8
- data/lib/cassandra/retry/policies.rb +1 -1
- data/lib/cassandra/retry/policies/default.rb +1 -1
- data/lib/cassandra/retry/policies/downgrading_consistency.rb +4 -2
- data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
- data/lib/cassandra/session.rb +24 -16
- data/lib/cassandra/statement.rb +1 -1
- data/lib/cassandra/statements.rb +1 -1
- data/lib/cassandra/statements/batch.rb +16 -10
- data/lib/cassandra/statements/bound.rb +10 -3
- data/lib/cassandra/statements/prepared.rb +62 -18
- data/lib/cassandra/statements/simple.rb +23 -10
- data/lib/cassandra/statements/void.rb +1 -1
- data/lib/cassandra/table.rb +53 -185
- data/lib/cassandra/time.rb +11 -6
- data/lib/cassandra/time_uuid.rb +12 -14
- data/lib/cassandra/timestamp_generator.rb +37 -0
- data/lib/cassandra/timestamp_generator/simple.rb +38 -0
- data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
- data/lib/cassandra/tuple.rb +4 -4
- data/lib/cassandra/types.rb +109 -71
- data/lib/cassandra/udt.rb +66 -50
- data/lib/cassandra/util.rb +155 -15
- data/lib/cassandra/uuid.rb +20 -21
- data/lib/cassandra/uuid/generator.rb +7 -5
- data/lib/cassandra/version.rb +2 -2
- data/lib/cassandra_murmur3.jar +0 -0
- data/lib/datastax/cassandra.rb +1 -1
- metadata +27 -16
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright 2013-
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -40,9 +40,7 @@ module Cassandra
|
|
40
40
|
private
|
41
41
|
|
42
42
|
def lookup_type(node, types)
|
43
|
-
if node.name == 'frozen'
|
44
|
-
return lookup_type(node.children.first, types)
|
45
|
-
end
|
43
|
+
return lookup_type(node.children.first, types) if node.name == 'frozen'
|
46
44
|
|
47
45
|
case node.name
|
48
46
|
when 'text' then Cassandra::Types.text
|
@@ -64,13 +62,20 @@ module Cassandra
|
|
64
62
|
when 'smallint' then Cassandra::Types.smallint
|
65
63
|
when 'time' then Cassandra::Types.time
|
66
64
|
when 'tinyint' then Cassandra::Types.tinyint
|
67
|
-
when 'map' then
|
68
|
-
|
69
|
-
when '
|
70
|
-
|
71
|
-
when '
|
65
|
+
when 'map' then
|
66
|
+
Cassandra::Types.map(*node.children.map { |t| lookup_type(t, types)})
|
67
|
+
when 'set' then
|
68
|
+
Cassandra::Types.set(lookup_type(node.children.first, types))
|
69
|
+
when 'list' then
|
70
|
+
Cassandra::Types.list(lookup_type(node.children.first, types))
|
71
|
+
when 'tuple' then
|
72
|
+
Cassandra::Types.tuple(*node.children.map { |t| lookup_type(t, types)})
|
73
|
+
when 'empty' then
|
74
|
+
Cassandra::Types.custom('org.apache.cassandra.db.marshal.EmptyType')
|
72
75
|
else
|
73
|
-
types.fetch(node.name)
|
76
|
+
types.fetch(node.name) do
|
77
|
+
raise IncompleteTypeError, "unable to lookup type #{node.name.inspect}"
|
78
|
+
end
|
74
79
|
end
|
75
80
|
end
|
76
81
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright 2013-
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -26,20 +26,23 @@ module Cassandra
|
|
26
26
|
COMPRESSION_PACKAGE_PREFIX = 'org.apache.cassandra.io.compress.'.freeze
|
27
27
|
|
28
28
|
def fetch(connection)
|
29
|
+
# rubocop:disable Metrics/LineLength
|
29
30
|
Ione::Future.all(select_keyspaces(connection),
|
30
31
|
select_tables(connection),
|
31
32
|
select_columns(connection),
|
32
33
|
select_types(connection),
|
33
34
|
select_functions(connection),
|
34
|
-
select_aggregates(connection)
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
select_aggregates(connection),
|
36
|
+
select_materialized_views(connection),
|
37
|
+
select_indexes(connection))
|
38
|
+
.map do |rows_keyspaces, rows_tables, rows_columns, rows_types, rows_functions, rows_aggregates, rows_views, rows_indexes|
|
38
39
|
lookup_tables = map_rows_by(rows_tables, 'keyspace_name')
|
39
40
|
lookup_columns = map_rows_by(rows_columns, 'keyspace_name')
|
40
41
|
lookup_types = map_rows_by(rows_types, 'keyspace_name')
|
41
42
|
lookup_functions = map_rows_by(rows_functions, 'keyspace_name')
|
42
43
|
lookup_aggregates = map_rows_by(rows_aggregates, 'keyspace_name')
|
44
|
+
lookup_views = map_rows_by(rows_views, 'keyspace_name')
|
45
|
+
lookup_indexes = map_rows_by(rows_indexes, 'keyspace_name')
|
43
46
|
|
44
47
|
rows_keyspaces.map do |keyspace_data|
|
45
48
|
name = keyspace_data['keyspace_name']
|
@@ -49,7 +52,9 @@ module Cassandra
|
|
49
52
|
lookup_columns[name],
|
50
53
|
lookup_types[name],
|
51
54
|
lookup_functions[name],
|
52
|
-
lookup_aggregates[name]
|
55
|
+
lookup_aggregates[name],
|
56
|
+
lookup_views[name],
|
57
|
+
lookup_indexes[name])
|
53
58
|
end
|
54
59
|
end
|
55
60
|
end
|
@@ -60,9 +65,10 @@ module Cassandra
|
|
60
65
|
select_keyspace_columns(connection, keyspace_name),
|
61
66
|
select_keyspace_types(connection, keyspace_name),
|
62
67
|
select_keyspace_functions(connection, keyspace_name),
|
63
|
-
select_keyspace_aggregates(connection, keyspace_name)
|
64
|
-
|
65
|
-
|
68
|
+
select_keyspace_aggregates(connection, keyspace_name),
|
69
|
+
select_keyspace_materialized_views(connection, keyspace_name),
|
70
|
+
select_keyspace_indexes(connection, keyspace_name))
|
71
|
+
.map do |rows_keyspaces, rows_tables, rows_columns, rows_types, rows_functions, rows_aggregates, rows_views, rows_indexes|
|
66
72
|
if rows_keyspaces.empty?
|
67
73
|
nil
|
68
74
|
else
|
@@ -71,20 +77,40 @@ module Cassandra
|
|
71
77
|
rows_columns,
|
72
78
|
rows_types,
|
73
79
|
rows_functions,
|
74
|
-
rows_aggregates
|
80
|
+
rows_aggregates,
|
81
|
+
rows_views,
|
82
|
+
rows_indexes)
|
75
83
|
end
|
76
84
|
end
|
77
85
|
end
|
78
86
|
|
79
87
|
def fetch_table(connection, keyspace_name, table_name)
|
80
88
|
Ione::Future.all(select_table(connection, keyspace_name, table_name),
|
81
|
-
select_table_columns(connection, keyspace_name, table_name)
|
82
|
-
|
89
|
+
select_table_columns(connection, keyspace_name, table_name),
|
90
|
+
select_table_indexes(connection, keyspace_name, table_name))
|
91
|
+
.map do |(rows_tables, rows_columns, rows_indexes)|
|
83
92
|
if rows_tables.empty?
|
84
93
|
nil
|
85
94
|
else
|
86
95
|
create_table(rows_tables.first,
|
87
|
-
rows_columns
|
96
|
+
rows_columns,
|
97
|
+
rows_indexes)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def fetch_materialized_view(connection, keyspace_name, view_name)
|
103
|
+
Ione::Future.all(select_materialized_view(connection, keyspace_name, view_name),
|
104
|
+
select_table_columns(connection, keyspace_name, view_name))
|
105
|
+
.map do |rows_views, rows_columns|
|
106
|
+
if rows_views.empty?
|
107
|
+
nil
|
108
|
+
else
|
109
|
+
view_row = rows_views.first
|
110
|
+
base_table = @schema.keyspace(keyspace_name).table(view_row['base_table_name'])
|
111
|
+
create_materialized_view(view_row,
|
112
|
+
rows_columns,
|
113
|
+
base_table)
|
88
114
|
end
|
89
115
|
end
|
90
116
|
end
|
@@ -100,7 +126,8 @@ module Cassandra
|
|
100
126
|
end
|
101
127
|
|
102
128
|
def fetch_function(connection, keyspace_name, function_name, function_args)
|
103
|
-
select_function(connection, keyspace_name, function_name, function_args)
|
129
|
+
select_function(connection, keyspace_name, function_name, function_args)
|
130
|
+
.map do |rows_functions|
|
104
131
|
if rows_functions.empty?
|
105
132
|
nil
|
106
133
|
else
|
@@ -110,11 +137,13 @@ module Cassandra
|
|
110
137
|
end
|
111
138
|
|
112
139
|
def fetch_aggregate(connection, keyspace_name, aggregate_name, aggregate_args)
|
113
|
-
select_aggregate(connection, keyspace_name, aggregate_name, aggregate_args)
|
140
|
+
select_aggregate(connection, keyspace_name, aggregate_name, aggregate_args)
|
141
|
+
.map do |rows_aggregates|
|
114
142
|
if rows_aggregates.empty?
|
115
143
|
nil
|
116
144
|
else
|
117
|
-
create_aggregate(rows_aggregates.first, @schema.keyspace(keyspace_name)
|
145
|
+
create_aggregate(rows_aggregates.first, @schema.keyspace(keyspace_name)
|
146
|
+
.send(:raw_functions))
|
118
147
|
end
|
119
148
|
end
|
120
149
|
end
|
@@ -129,10 +158,18 @@ module Cassandra
|
|
129
158
|
FUTURE_EMPTY_LIST
|
130
159
|
end
|
131
160
|
|
161
|
+
def select_materialized_views(connection)
|
162
|
+
FUTURE_EMPTY_LIST
|
163
|
+
end
|
164
|
+
|
132
165
|
def select_columns(connection)
|
133
166
|
FUTURE_EMPTY_LIST
|
134
167
|
end
|
135
168
|
|
169
|
+
def select_indexes(connection)
|
170
|
+
FUTURE_EMPTY_LIST
|
171
|
+
end
|
172
|
+
|
136
173
|
def select_types(connection)
|
137
174
|
FUTURE_EMPTY_LIST
|
138
175
|
end
|
@@ -153,10 +190,18 @@ module Cassandra
|
|
153
190
|
FUTURE_EMPTY_LIST
|
154
191
|
end
|
155
192
|
|
193
|
+
def select_keyspace_materialized_views(connection, keyspace_name)
|
194
|
+
FUTURE_EMPTY_LIST
|
195
|
+
end
|
196
|
+
|
156
197
|
def select_keyspace_columns(connection, keyspace_name)
|
157
198
|
FUTURE_EMPTY_LIST
|
158
199
|
end
|
159
200
|
|
201
|
+
def select_keyspace_indexes(connection, keyspace_name)
|
202
|
+
FUTURE_EMPTY_LIST
|
203
|
+
end
|
204
|
+
|
160
205
|
def select_keyspace_types(connection, keyspace_name)
|
161
206
|
FUTURE_EMPTY_LIST
|
162
207
|
end
|
@@ -173,10 +218,18 @@ module Cassandra
|
|
173
218
|
FUTURE_EMPTY_LIST
|
174
219
|
end
|
175
220
|
|
221
|
+
def select_materialized_view(connection, keyspace_name, view_name)
|
222
|
+
FUTURE_EMPTY_LIST
|
223
|
+
end
|
224
|
+
|
176
225
|
def select_table_columns(connection, keyspace_name, table_name)
|
177
226
|
FUTURE_EMPTY_LIST
|
178
227
|
end
|
179
228
|
|
229
|
+
def select_table_indexes(connection, keyspace_name, table_name)
|
230
|
+
FUTURE_EMPTY_LIST
|
231
|
+
end
|
232
|
+
|
180
233
|
def select_type(connection, keyspace_name, type_name)
|
181
234
|
FUTURE_EMPTY_LIST
|
182
235
|
end
|
@@ -191,7 +244,8 @@ module Cassandra
|
|
191
244
|
|
192
245
|
def send_select_request(connection, cql, params = EMPTY_LIST, types = EMPTY_LIST)
|
193
246
|
backtrace = caller
|
194
|
-
connection.send_request(
|
247
|
+
connection.send_request(
|
248
|
+
Protocol::QueryRequest.new(cql, params, types, :one)).map do |r|
|
195
249
|
case r
|
196
250
|
when Protocol::RowsResultResponse
|
197
251
|
r.rows
|
@@ -208,30 +262,44 @@ module Cassandra
|
|
208
262
|
def map_rows_by(rows, key_name, &block)
|
209
263
|
rows.each_with_object(::Hash.new { EMPTY_LIST }) do |row, map|
|
210
264
|
key = row[key_name]
|
211
|
-
map[key] = [] unless map.
|
265
|
+
map[key] = [] unless map.key?(key)
|
212
266
|
|
213
|
-
if block
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
267
|
+
map[key] << if block
|
268
|
+
yield(row)
|
269
|
+
else
|
270
|
+
row
|
271
|
+
end
|
218
272
|
end
|
219
273
|
end
|
220
274
|
end
|
221
275
|
|
222
276
|
# @private
|
223
277
|
module Fetchers
|
278
|
+
# rubocop:disable Style/ClassAndModuleCamelCase
|
224
279
|
class V1_2_x
|
225
280
|
SELECT_KEYSPACES = 'SELECT * FROM system.schema_keyspaces'.freeze
|
226
281
|
SELECT_TABLES = 'SELECT * FROM system.schema_columnfamilies'.freeze
|
227
282
|
SELECT_COLUMNS = 'SELECT * FROM system.schema_columns'.freeze
|
228
|
-
SELECT_KEYSPACE =
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
283
|
+
SELECT_KEYSPACE =
|
284
|
+
'SELECT * ' \
|
285
|
+
'FROM system.schema_keyspaces ' \
|
286
|
+
'WHERE keyspace_name = \'%s\''.freeze
|
287
|
+
SELECT_KEYSPACE_TABLES =
|
288
|
+
'SELECT * ' \
|
289
|
+
'FROM system.schema_columnfamilies ' \
|
290
|
+
'WHERE keyspace_name = \'%s\''.freeze
|
291
|
+
SELECT_KEYSPACE_COLUMNS =
|
292
|
+
'SELECT * FROM system.schema_columns WHERE keyspace_name = \'%s\''.freeze
|
293
|
+
SELECT_TABLE =
|
294
|
+
'SELECT * ' \
|
295
|
+
'FROM system.schema_columnfamilies ' \
|
296
|
+
'WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
|
297
|
+
SELECT_TABLE_COLUMNS =
|
298
|
+
'SELECT * ' \
|
299
|
+
'FROM system.schema_columns ' \
|
300
|
+
'WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
|
301
|
+
|
302
|
+
include Cassandra::Cluster::Schema::Fetcher
|
235
303
|
|
236
304
|
def initialize(type_parser, schema)
|
237
305
|
@type_parser = type_parser
|
@@ -257,19 +325,20 @@ module Cassandra
|
|
257
325
|
end
|
258
326
|
|
259
327
|
def select_keyspace_tables(connection, keyspace_name)
|
260
|
-
send_select_request(connection, SELECT_KEYSPACE_TABLES
|
328
|
+
send_select_request(connection, format(SELECT_KEYSPACE_TABLES, keyspace_name))
|
261
329
|
end
|
262
330
|
|
263
331
|
def select_keyspace_columns(connection, keyspace_name)
|
264
|
-
send_select_request(connection, SELECT_KEYSPACE_COLUMNS
|
332
|
+
send_select_request(connection, format(SELECT_KEYSPACE_COLUMNS, keyspace_name))
|
265
333
|
end
|
266
334
|
|
267
335
|
def select_table(connection, keyspace_name, table_name)
|
268
|
-
send_select_request(connection, SELECT_TABLE
|
336
|
+
send_select_request(connection, format(SELECT_TABLE, keyspace_name, table_name))
|
269
337
|
end
|
270
338
|
|
271
339
|
def select_table_columns(connection, keyspace_name, table_name)
|
272
|
-
send_select_request(connection,
|
340
|
+
send_select_request(connection,
|
341
|
+
format(SELECT_TABLE_COLUMNS, keyspace_name, table_name))
|
273
342
|
end
|
274
343
|
|
275
344
|
def create_replication(keyspace_data)
|
@@ -280,50 +349,66 @@ module Cassandra
|
|
280
349
|
end
|
281
350
|
|
282
351
|
def create_keyspace(keyspace_data, rows_tables, rows_columns,
|
283
|
-
rows_types, rows_functions, rows_aggregates
|
352
|
+
rows_types, rows_functions, rows_aggregates,
|
353
|
+
rows_views, rows_indexes)
|
284
354
|
keyspace_name = keyspace_data['keyspace_name']
|
285
355
|
replication = create_replication(keyspace_data)
|
286
|
-
types = rows_types.each_with_object({}) do |row,
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
# We want the functions hash to be keyed on [name, arg-types-list].
|
291
|
-
# Similarly for the aggregates hash.
|
356
|
+
types = rows_types.each_with_object({}) do |row, h|
|
357
|
+
h[row['type_name']] = create_type(row)
|
358
|
+
end
|
292
359
|
|
293
|
-
|
294
|
-
|
295
|
-
|
360
|
+
# Create a FunctionCollection for the functions and aggregates.
|
361
|
+
functions = Cassandra::FunctionCollection.new
|
362
|
+
rows_functions.each do |row|
|
363
|
+
functions.add_or_update(create_function(row))
|
296
364
|
end
|
297
365
|
|
298
|
-
aggregates =
|
299
|
-
|
300
|
-
|
301
|
-
|
366
|
+
aggregates = Cassandra::FunctionCollection.new
|
367
|
+
rows_aggregates.each do |row|
|
368
|
+
aggregates.add_or_update(create_aggregate(row, functions))
|
369
|
+
end
|
302
370
|
|
303
371
|
lookup_columns = map_rows_by(rows_columns, 'columnfamily_name')
|
304
|
-
tables = rows_tables.each_with_object({}) do |row,
|
372
|
+
tables = rows_tables.each_with_object({}) do |row, h|
|
305
373
|
table_name = row['columnfamily_name']
|
306
|
-
|
374
|
+
# rows_indexes is nil for C* < 3.0.
|
375
|
+
h[table_name] = create_table(row, lookup_columns[table_name], nil)
|
307
376
|
end
|
308
377
|
|
309
|
-
Keyspace.new(keyspace_name,
|
310
|
-
|
378
|
+
Keyspace.new(keyspace_name,
|
379
|
+
keyspace_data['durable_writes'],
|
380
|
+
replication,
|
381
|
+
tables,
|
382
|
+
types,
|
383
|
+
functions,
|
384
|
+
aggregates,
|
385
|
+
{})
|
311
386
|
end
|
312
387
|
|
313
|
-
def create_table(table_data, rows_columns)
|
388
|
+
def create_table(table_data, rows_columns, rows_indexes)
|
314
389
|
keyspace_name = table_data['keyspace_name']
|
315
390
|
table_name = table_data['columnfamily_name']
|
316
391
|
key_validator = @type_parser.parse(table_data['key_validator'])
|
317
392
|
comparator = @type_parser.parse(table_data['comparator'])
|
318
393
|
column_aliases = ::JSON.load(table_data['column_aliases'])
|
319
394
|
|
320
|
-
if
|
395
|
+
if comparator.collections.nil?
|
396
|
+
is_compact = true
|
397
|
+
if !column_aliases.empty? || rows_columns.empty?
|
398
|
+
has_value = true
|
399
|
+
clustering_size = comparator.results.size
|
400
|
+
else
|
401
|
+
has_value = false
|
402
|
+
clustering_size = 0
|
403
|
+
end
|
404
|
+
else
|
321
405
|
size = comparator.results.size
|
322
406
|
if !comparator.collections.empty?
|
323
407
|
is_compact = false
|
324
408
|
has_value = false
|
325
409
|
clustering_size = size - 2
|
326
|
-
elsif column_aliases.size == size - 1 &&
|
410
|
+
elsif column_aliases.size == size - 1 &&
|
411
|
+
comparator.results.last.first == Cassandra::Types.varchar
|
327
412
|
is_compact = false
|
328
413
|
has_value = false
|
329
414
|
clustering_size = size - 1
|
@@ -332,39 +417,32 @@ module Cassandra
|
|
332
417
|
has_value = (!column_aliases.empty? || rows_columns.empty?)
|
333
418
|
clustering_size = size
|
334
419
|
end
|
335
|
-
else
|
336
|
-
is_compact = true
|
337
|
-
if (!column_aliases.empty? || rows_columns.empty?)
|
338
|
-
has_value = true
|
339
|
-
clustering_size = comparator.results.size
|
340
|
-
else
|
341
|
-
has_value = false
|
342
|
-
clustering_size = 0
|
343
|
-
end
|
344
420
|
end
|
345
421
|
|
422
|
+
# Separate out the partition-key, clustering-columns, and other-columns
|
346
423
|
partition_key = []
|
347
424
|
clustering_columns = []
|
348
425
|
clustering_order = []
|
426
|
+
other_columns = []
|
349
427
|
|
350
428
|
compaction_strategy = create_compaction_strategy(table_data)
|
351
|
-
table_options =
|
352
|
-
|
353
|
-
other_columns = []
|
429
|
+
table_options =
|
430
|
+
create_table_options(table_data, compaction_strategy, is_compact)
|
354
431
|
|
355
432
|
key_aliases = ::JSON.load(table_data['key_aliases'])
|
356
433
|
|
357
434
|
key_validator.results.each_with_index do |(type, order, is_frozen), i|
|
358
|
-
key_alias = key_aliases.fetch(i) { i.zero? ?
|
435
|
+
key_alias = key_aliases.fetch(i) { i.zero? ? 'key' : "key#{i + 1}" }
|
359
436
|
|
360
|
-
partition_key[i] = Column.new(key_alias, type, order,
|
437
|
+
partition_key[i] = Column.new(key_alias, type, order, false, is_frozen)
|
361
438
|
end
|
362
439
|
|
363
440
|
clustering_size.times do |i|
|
364
441
|
column_alias = column_aliases.fetch(i) { "column#{i + 1}" }
|
365
442
|
type, order, is_frozen = comparator.results.fetch(i)
|
366
443
|
|
367
|
-
clustering_columns[i] =
|
444
|
+
clustering_columns[i] =
|
445
|
+
Column.new(column_alias, type, order, false, is_frozen)
|
368
446
|
clustering_order[i] = order
|
369
447
|
end
|
370
448
|
|
@@ -373,59 +451,87 @@ module Cassandra
|
|
373
451
|
value_alias ||= 'value'
|
374
452
|
|
375
453
|
unless value_alias.empty?
|
376
|
-
type, order, is_frozen =
|
377
|
-
|
454
|
+
type, order, is_frozen =
|
455
|
+
@type_parser.parse(table_data['default_validator']).results.first
|
456
|
+
other_columns <<
|
457
|
+
Column.new(value_alias, type, order, false, is_frozen)
|
378
458
|
end
|
379
459
|
end
|
380
460
|
|
461
|
+
index_rows = []
|
381
462
|
rows_columns.each do |row|
|
382
|
-
|
383
|
-
|
463
|
+
column = create_column(row)
|
464
|
+
other_columns << column
|
384
465
|
|
385
|
-
|
386
|
-
|
466
|
+
# In C* 1.2.x, index info is in the column metadata; rows_indexes is nil.
|
467
|
+
index_rows << [column, row] unless row['index_type'].nil?
|
387
468
|
end
|
388
469
|
|
389
|
-
|
390
|
-
|
470
|
+
table = Cassandra::Table.new(@schema.keyspace(keyspace_name),
|
471
|
+
table_name,
|
472
|
+
partition_key,
|
473
|
+
clustering_columns,
|
474
|
+
other_columns,
|
475
|
+
table_options,
|
476
|
+
clustering_order,
|
477
|
+
table_data['id'])
|
478
|
+
|
479
|
+
# Create Index objects and add them to the table.
|
480
|
+
index_rows.each do |column, row|
|
481
|
+
create_index(table, column, row)
|
391
482
|
end
|
483
|
+
table
|
484
|
+
end
|
392
485
|
|
393
|
-
|
394
|
-
|
486
|
+
def create_index(table, column, row_column)
|
487
|
+
# Most of this logic was taken from the Java driver.
|
488
|
+
options = {}
|
489
|
+
# For some versions of C*, this field could have a literal string 'null' value.
|
490
|
+
if !row_column['index_options'].nil? && row_column['index_options'] != 'null' && !row_column['index_options'].empty?
|
491
|
+
options = ::JSON.load(row_column['index_options'])
|
395
492
|
end
|
396
|
-
|
397
|
-
|
398
|
-
|
493
|
+
column_name = Util.escape_name(column.name)
|
494
|
+
target = if options.key?('index_keys')
|
495
|
+
"keys(#{column_name})"
|
496
|
+
elsif options.key?('index_keys_and_values')
|
497
|
+
"entries(#{column_name})"
|
498
|
+
elsif column.frozen? && (column.type == Cassandra::Types::Set ||
|
499
|
+
column.type == Cassandra::Types::List ||
|
500
|
+
column.type == Cassandra::Types::Map)
|
501
|
+
"full(#{column_name})"
|
502
|
+
else
|
503
|
+
column_name
|
504
|
+
end
|
505
|
+
|
506
|
+
table.add_index(Cassandra::Index.new(table,
|
507
|
+
row_column['index_name'],
|
508
|
+
row_column['index_type'].downcase.to_sym,
|
509
|
+
target,
|
510
|
+
options))
|
399
511
|
end
|
400
512
|
|
401
513
|
def create_column(column_data)
|
402
514
|
name = column_data['column_name']
|
403
515
|
is_static = (column_data['type'] == 'STATIC')
|
404
|
-
type, order, is_frozen =
|
405
|
-
|
406
|
-
|
407
|
-
index = nil
|
408
|
-
elsif column_data['index_type'].to_s.upcase == 'CUSTOM' || !column_data['index_options']
|
409
|
-
index = Column::Index.new(column_data['index_name'])
|
410
|
-
else
|
411
|
-
options = ::JSON.load(column_data['index_options'])
|
412
|
-
index = Column::Index.new(column_data['index_name'], options && options['class_name'])
|
413
|
-
end
|
414
|
-
|
415
|
-
Column.new(name, type, order, index, is_static, is_frozen)
|
516
|
+
type, order, is_frozen =
|
517
|
+
@type_parser.parse(column_data['validator']).results.first
|
518
|
+
Column.new(name, type, order, is_static, is_frozen)
|
416
519
|
end
|
417
520
|
|
418
521
|
def create_compaction_strategy(table_data)
|
419
522
|
klass = table_data['compaction_strategy_class']
|
420
523
|
klass.slice!('org.apache.cassandra.db.compaction.')
|
421
524
|
options = ::JSON.load(table_data['compaction_strategy_options'])
|
422
|
-
|
525
|
+
ColumnContainer::Compaction.new(klass, options)
|
423
526
|
end
|
424
527
|
|
425
528
|
def create_table_options(table_data, compaction_strategy, is_compact)
|
426
529
|
compression_parameters = ::JSON.load(table_data['compression_parameters'])
|
427
|
-
|
428
|
-
|
530
|
+
if compression_parameters['sstable_compression']
|
531
|
+
compression_parameters['sstable_compression']
|
532
|
+
.slice!(COMPRESSION_PACKAGE_PREFIX)
|
533
|
+
end
|
534
|
+
Cassandra::ColumnContainer::Options.new(
|
429
535
|
table_data['comment'],
|
430
536
|
table_data['read_repair_chance'],
|
431
537
|
table_data['local_read_repair_chance'],
|
@@ -442,72 +548,87 @@ module Cassandra
|
|
442
548
|
nil,
|
443
549
|
compaction_strategy,
|
444
550
|
compression_parameters,
|
445
|
-
is_compact
|
551
|
+
is_compact,
|
552
|
+
table_data['crc_check_chance'],
|
553
|
+
table_data['extensions']
|
446
554
|
)
|
447
555
|
end
|
448
556
|
end
|
449
557
|
|
450
558
|
class V2_0_x < V1_2_x
|
451
|
-
SELECT_KEYSPACE =
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
559
|
+
SELECT_KEYSPACE =
|
560
|
+
'SELECT * FROM system.schema_keyspaces WHERE keyspace_name = ?'.freeze
|
561
|
+
SELECT_KEYSPACE_TABLES =
|
562
|
+
'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = ?'.freeze
|
563
|
+
SELECT_KEYSPACE_COLUMNS =
|
564
|
+
'SELECT * FROM system.schema_columns WHERE keyspace_name = ?'.freeze
|
565
|
+
SELECT_TABLE =
|
566
|
+
'SELECT * ' \
|
567
|
+
'FROM system.schema_columnfamilies ' \
|
568
|
+
'WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
|
569
|
+
SELECT_TABLE_COLUMNS =
|
570
|
+
'SELECT * ' \
|
571
|
+
'FROM system.schema_columns ' \
|
572
|
+
'WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
|
456
573
|
|
457
574
|
private
|
458
575
|
|
459
|
-
def create_table(table_data, rows_columns)
|
576
|
+
def create_table(table_data, rows_columns, rows_indexes)
|
460
577
|
keyspace_name = table_data['keyspace_name']
|
461
578
|
table_name = table_data['columnfamily_name']
|
462
579
|
comparator = @type_parser.parse(table_data['comparator'])
|
463
|
-
table_columns = {}
|
464
|
-
other_columns = []
|
465
580
|
clustering_size = 0
|
466
581
|
|
582
|
+
# Separate out partition-key, clustering columns, other columns.
|
467
583
|
partition_key = []
|
468
584
|
clustering_columns = []
|
469
585
|
clustering_order = []
|
586
|
+
other_columns = []
|
470
587
|
|
588
|
+
index_rows = []
|
471
589
|
rows_columns.each do |row|
|
472
590
|
next if row['column_name'].empty?
|
473
591
|
|
474
592
|
column = create_column(row)
|
475
593
|
type = row['type'].to_s
|
476
|
-
|
594
|
+
ind = row['component_index'] || 0
|
477
595
|
|
478
596
|
case type.upcase
|
479
597
|
when 'PARTITION_KEY'
|
480
|
-
partition_key[
|
598
|
+
partition_key[ind] = column
|
481
599
|
when 'CLUSTERING_KEY'
|
482
|
-
clustering_columns[
|
483
|
-
clustering_order[
|
600
|
+
clustering_columns[ind] = column
|
601
|
+
clustering_order[ind] = column.order
|
484
602
|
|
485
|
-
if clustering_size.zero? ||
|
486
|
-
clustering_size = index + 1
|
487
|
-
end
|
603
|
+
clustering_size = ind + 1 if clustering_size.zero? || ind == clustering_size
|
488
604
|
else
|
489
605
|
other_columns << column
|
490
606
|
end
|
491
|
-
end
|
492
|
-
|
493
|
-
partition_key.each do |column|
|
494
|
-
table_columns[column.name] = column
|
495
|
-
end
|
496
607
|
|
497
|
-
|
498
|
-
|
499
|
-
end
|
500
|
-
|
501
|
-
other_columns.each do |column|
|
502
|
-
table_columns[column.name] = column
|
608
|
+
# In C* 2.0.x, index info is in the column metadata; rows_indexes is nil.
|
609
|
+
index_rows << [column, row] unless row['index_type'].nil?
|
503
610
|
end
|
504
611
|
|
505
612
|
compaction_strategy = create_compaction_strategy(table_data)
|
506
|
-
is_compact = (clustering_size != comparator.results.size - 1) ||
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
613
|
+
is_compact = (clustering_size != comparator.results.size - 1) ||
|
614
|
+
!comparator.collections
|
615
|
+
table_options =
|
616
|
+
create_table_options(table_data, compaction_strategy, is_compact)
|
617
|
+
|
618
|
+
table = Cassandra::Table.new(@schema.keyspace(keyspace_name),
|
619
|
+
table_name,
|
620
|
+
partition_key,
|
621
|
+
clustering_columns,
|
622
|
+
other_columns,
|
623
|
+
table_options,
|
624
|
+
clustering_order,
|
625
|
+
table_data['id'])
|
626
|
+
|
627
|
+
# Create Index objects and add them to the table.
|
628
|
+
index_rows.each do |column, row|
|
629
|
+
create_index(table, column, row)
|
630
|
+
end
|
631
|
+
table
|
511
632
|
end
|
512
633
|
|
513
634
|
def select_keyspace(connection, keyspace_name)
|
@@ -542,8 +663,11 @@ module Cassandra
|
|
542
663
|
|
543
664
|
def create_table_options(table_data, compaction_strategy, is_compact)
|
544
665
|
compression_parameters = ::JSON.load(table_data['compression_parameters'])
|
545
|
-
|
546
|
-
|
666
|
+
if compression_parameters['sstable_compression']
|
667
|
+
compression_parameters['sstable_compression']
|
668
|
+
.slice!(COMPRESSION_PACKAGE_PREFIX)
|
669
|
+
end
|
670
|
+
Cassandra::ColumnContainer::Options.new(
|
547
671
|
table_data['comment'],
|
548
672
|
table_data['read_repair_chance'],
|
549
673
|
table_data['local_read_repair_chance'],
|
@@ -560,15 +684,21 @@ module Cassandra
|
|
560
684
|
nil,
|
561
685
|
compaction_strategy,
|
562
686
|
compression_parameters,
|
563
|
-
is_compact
|
687
|
+
is_compact,
|
688
|
+
table_data['crc_check_chance'],
|
689
|
+
table_data['extensions']
|
564
690
|
)
|
565
691
|
end
|
566
692
|
end
|
567
693
|
|
568
694
|
class V2_1_x < V2_0_x
|
569
695
|
SELECT_TYPES = 'SELECT * FROM system.schema_usertypes'.freeze
|
570
|
-
SELECT_KEYSPACE_TYPES =
|
571
|
-
|
696
|
+
SELECT_KEYSPACE_TYPES =
|
697
|
+
'SELECT * FROM system.schema_usertypes WHERE keyspace_name = ?'.freeze
|
698
|
+
SELECT_TYPE =
|
699
|
+
'SELECT * ' \
|
700
|
+
'FROM system.schema_usertypes ' \
|
701
|
+
'WHERE keyspace_name = ? AND type_name = ?'.freeze
|
572
702
|
|
573
703
|
private
|
574
704
|
|
@@ -607,8 +737,11 @@ module Cassandra
|
|
607
737
|
|
608
738
|
def create_table_options(table_data, compaction_strategy, is_compact)
|
609
739
|
compression_parameters = ::JSON.load(table_data['compression_parameters'])
|
610
|
-
|
611
|
-
|
740
|
+
if compression_parameters['sstable_compression']
|
741
|
+
compression_parameters['sstable_compression']
|
742
|
+
.slice!(COMPRESSION_PACKAGE_PREFIX)
|
743
|
+
end
|
744
|
+
Cassandra::ColumnContainer::Options.new(
|
612
745
|
table_data['comment'],
|
613
746
|
table_data['read_repair_chance'],
|
614
747
|
table_data['local_read_repair_chance'],
|
@@ -625,7 +758,9 @@ module Cassandra
|
|
625
758
|
table_data['max_index_interval'],
|
626
759
|
compaction_strategy,
|
627
760
|
compression_parameters,
|
628
|
-
is_compact
|
761
|
+
is_compact,
|
762
|
+
table_data['crc_check_chance'],
|
763
|
+
table_data['extensions']
|
629
764
|
)
|
630
765
|
end
|
631
766
|
end
|
@@ -633,12 +768,23 @@ module Cassandra
|
|
633
768
|
class V2_2_x < V2_1_x
|
634
769
|
SELECT_FUNCTIONS = 'SELECT * FROM system.schema_functions'.freeze
|
635
770
|
SELECT_AGGREGATES = 'SELECT * FROM system.schema_aggregates'.freeze
|
636
|
-
SELECT_KEYSPACE_FUNCTIONS =
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
771
|
+
SELECT_KEYSPACE_FUNCTIONS =
|
772
|
+
'SELECT * FROM system.schema_functions WHERE keyspace_name = ?'.freeze
|
773
|
+
SELECT_KEYSPACE_AGGREGATES =
|
774
|
+
'SELECT * FROM system.schema_aggregates WHERE keyspace_name = ?'.freeze
|
775
|
+
SELECT_FUNCTION =
|
776
|
+
'SELECT * ' \
|
777
|
+
'FROM system.schema_functions ' \
|
778
|
+
'WHERE keyspace_name = ? AND function_name = ? ' \
|
779
|
+
'AND argument_types = ?'.freeze
|
780
|
+
SELECT_AGGREGATE =
|
781
|
+
'SELECT * ' \
|
782
|
+
'FROM system.schema_aggregates ' \
|
783
|
+
'WHERE keyspace_name = ? AND aggregate_name = ? ' \
|
784
|
+
'AND argument_types = ?'.freeze
|
785
|
+
|
786
|
+
# parse an array of string argument types and return an array of
|
787
|
+
# [Cassandra::Type]s.
|
642
788
|
# @param connection a connection to a Cassandra node.
|
643
789
|
# @param keyspace_name [String] name of the keyspace.
|
644
790
|
# @param argument_types [Array<String>] array of argument types.
|
@@ -655,35 +801,59 @@ module Cassandra
|
|
655
801
|
keyspace_name = function_data['keyspace_name']
|
656
802
|
function_name = function_data['function_name']
|
657
803
|
function_lang = function_data['language']
|
658
|
-
function_type =
|
804
|
+
function_type =
|
805
|
+
@type_parser.parse(function_data['return_type']).results.first.first
|
659
806
|
function_body = function_data['body']
|
660
807
|
called_on_null = function_data['called_on_null_input']
|
661
808
|
|
662
809
|
arguments = []
|
663
810
|
|
664
|
-
Array(function_data['argument_names'])
|
811
|
+
Array(function_data['argument_names'])
|
812
|
+
.zip(Array(function_data['argument_types'])) do |argument_name, fqcn|
|
665
813
|
argument_type = @type_parser.parse(fqcn).results.first.first
|
666
814
|
arguments << Argument.new(argument_name, argument_type)
|
667
815
|
end
|
668
816
|
|
669
|
-
Function.new(keyspace_name,
|
817
|
+
Cassandra::Function.new(keyspace_name,
|
818
|
+
function_name,
|
819
|
+
function_lang,
|
820
|
+
function_type,
|
821
|
+
arguments,
|
822
|
+
function_body,
|
823
|
+
called_on_null)
|
670
824
|
end
|
671
825
|
|
672
826
|
def create_aggregate(aggregate_data, functions)
|
673
827
|
keyspace_name = aggregate_data['keyspace_name']
|
674
828
|
aggregate_name = aggregate_data['aggregate_name']
|
675
|
-
aggregate_type =
|
676
|
-
|
677
|
-
|
678
|
-
|
829
|
+
aggregate_type =
|
830
|
+
@type_parser.parse(aggregate_data['return_type']).results.first.first
|
831
|
+
argument_types = aggregate_data['argument_types'].map do |fqcn|
|
832
|
+
@type_parser.parse(fqcn).results.first.first
|
833
|
+
end.freeze
|
834
|
+
state_type =
|
835
|
+
@type_parser.parse(aggregate_data['state_type']).results.first.first
|
836
|
+
initial_state = Util.encode_object(
|
837
|
+
Protocol::Coder.read_value_v4(
|
838
|
+
Protocol::CqlByteBuffer.new.append_bytes(aggregate_data['initcond']),
|
839
|
+
state_type))
|
679
840
|
|
680
841
|
# The state-function takes arguments: first the stype, then the args of the aggregate.
|
681
|
-
state_function = functions
|
842
|
+
state_function = functions.get(aggregate_data['state_func'],
|
843
|
+
[state_type].concat(argument_types))
|
682
844
|
|
683
845
|
# The final-function takes an stype argument.
|
684
|
-
final_function = functions
|
846
|
+
final_function = functions.get(aggregate_data['final_func'],
|
847
|
+
[state_type])
|
685
848
|
|
686
|
-
Aggregate.new(keyspace_name,
|
849
|
+
Aggregate.new(keyspace_name,
|
850
|
+
aggregate_name,
|
851
|
+
aggregate_type,
|
852
|
+
argument_types,
|
853
|
+
state_type,
|
854
|
+
initial_state,
|
855
|
+
state_function,
|
856
|
+
final_function)
|
687
857
|
end
|
688
858
|
|
689
859
|
def select_functions(connection)
|
@@ -720,32 +890,69 @@ module Cassandra
|
|
720
890
|
end
|
721
891
|
|
722
892
|
class V3_0_x < V2_2_x
|
723
|
-
SELECT_KEYSPACES =
|
724
|
-
SELECT_TABLES =
|
725
|
-
SELECT_COLUMNS =
|
726
|
-
SELECT_TYPES =
|
727
|
-
SELECT_FUNCTIONS =
|
728
|
-
SELECT_AGGREGATES =
|
729
|
-
SELECT_INDEXES =
|
730
|
-
SELECT_VIEWS =
|
731
|
-
|
732
|
-
SELECT_KEYSPACE =
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
893
|
+
SELECT_KEYSPACES = 'SELECT * FROM system_schema.keyspaces'.freeze
|
894
|
+
SELECT_TABLES = 'SELECT * FROM system_schema.tables'.freeze
|
895
|
+
SELECT_COLUMNS = 'SELECT * FROM system_schema.columns'.freeze
|
896
|
+
SELECT_TYPES = 'SELECT * FROM system_schema.types'.freeze
|
897
|
+
SELECT_FUNCTIONS = 'SELECT * FROM system_schema.functions'.freeze
|
898
|
+
SELECT_AGGREGATES = 'SELECT * FROM system_schema.aggregates'.freeze
|
899
|
+
SELECT_INDEXES = 'SELECT * FROM system_schema.indexes'.freeze
|
900
|
+
SELECT_VIEWS = 'SELECT * FROM system_schema.views'.freeze
|
901
|
+
|
902
|
+
SELECT_KEYSPACE =
|
903
|
+
'SELECT * FROM system_schema.keyspaces WHERE keyspace_name = ?'.freeze
|
904
|
+
SELECT_KEYSPACE_TABLES =
|
905
|
+
'SELECT * FROM system_schema.tables WHERE keyspace_name = ?'.freeze
|
906
|
+
SELECT_KEYSPACE_INDEXES =
|
907
|
+
'SELECT * FROM system_schema.indexes WHERE keyspace_name = ?'.freeze
|
908
|
+
SELECT_KEYSPACE_COLUMNS =
|
909
|
+
'SELECT * FROM system_schema.columns WHERE keyspace_name = ?'.freeze
|
910
|
+
SELECT_KEYSPACE_VIEWS =
|
911
|
+
'SELECT * FROM system_schema.views WHERE keyspace_name = ?'.freeze
|
912
|
+
SELECT_KEYSPACE_TYPES =
|
913
|
+
'SELECT * FROM system_schema.types WHERE keyspace_name = ?'.freeze
|
914
|
+
SELECT_KEYSPACE_FUNCTIONS =
|
915
|
+
'SELECT * FROM system_schema.functions WHERE keyspace_name = ?'.freeze
|
916
|
+
SELECT_KEYSPACE_AGGREGATES =
|
917
|
+
'SELECT * FROM system_schema.aggregates WHERE keyspace_name = ?'.freeze
|
918
|
+
|
919
|
+
SELECT_TABLE =
|
920
|
+
'SELECT * ' \
|
921
|
+
'FROM system_schema.tables ' \
|
922
|
+
'WHERE keyspace_name = ? AND table_name = ?'.freeze
|
923
|
+
SELECT_TABLE_COLUMNS =
|
924
|
+
'SELECT * ' \
|
925
|
+
'FROM system_schema.columns ' \
|
926
|
+
'WHERE keyspace_name = ? AND table_name = ?'.freeze
|
927
|
+
SELECT_TABLE_INDEXES =
|
928
|
+
'SELECT * ' \
|
929
|
+
'FROM system_schema.indexes ' \
|
930
|
+
'WHERE keyspace_name = ? AND table_name = ?'.freeze
|
931
|
+
|
932
|
+
SELECT_VIEW =
|
933
|
+
'SELECT * ' \
|
934
|
+
'FROM system_schema.views ' \
|
935
|
+
'WHERE keyspace_name = ? AND view_name = ?'.freeze
|
936
|
+
|
937
|
+
SELECT_TYPE =
|
938
|
+
'SELECT * ' \
|
939
|
+
'FROM system_schema.types ' \
|
940
|
+
'WHERE keyspace_name = ? AND type_name = ?'.freeze
|
941
|
+
|
942
|
+
SELECT_FUNCTION =
|
943
|
+
'SELECT * ' \
|
944
|
+
'FROM system_schema.functions ' \
|
945
|
+
'WHERE keyspace_name = ? AND function_name = ? ' \
|
946
|
+
'AND argument_types = ?'.freeze
|
947
|
+
|
948
|
+
SELECT_AGGREGATE =
|
949
|
+
'SELECT * ' \
|
950
|
+
'FROM system_schema.aggregates ' \
|
951
|
+
'WHERE keyspace_name = ? AND aggregate_name = ? ' \
|
952
|
+
'AND argument_types = ?'.freeze
|
953
|
+
|
954
|
+
# parse an array of string argument types and return an array of
|
955
|
+
# [Cassandra::Type]s.
|
749
956
|
# @param connection a connection to a Cassandra node.
|
750
957
|
# @param keyspace_name [String] name of the keyspace.
|
751
958
|
# @param argument_types [Array<String>] array of argument types.
|
@@ -767,6 +974,14 @@ module Cassandra
|
|
767
974
|
send_select_request(connection, SELECT_TABLES)
|
768
975
|
end
|
769
976
|
|
977
|
+
def select_indexes(connection)
|
978
|
+
send_select_request(connection, SELECT_INDEXES)
|
979
|
+
end
|
980
|
+
|
981
|
+
def select_materialized_views(connection)
|
982
|
+
send_select_request(connection, SELECT_VIEWS)
|
983
|
+
end
|
984
|
+
|
770
985
|
def select_columns(connection)
|
771
986
|
send_select_request(connection, SELECT_COLUMNS)
|
772
987
|
end
|
@@ -801,6 +1016,18 @@ module Cassandra
|
|
801
1016
|
send_select_request(connection, SELECT_KEYSPACE_COLUMNS, params, hints)
|
802
1017
|
end
|
803
1018
|
|
1019
|
+
def select_keyspace_indexes(connection, keyspace_name)
|
1020
|
+
params = [keyspace_name]
|
1021
|
+
hints = [Types.varchar]
|
1022
|
+
send_select_request(connection, SELECT_KEYSPACE_INDEXES, params, hints)
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
def select_keyspace_materialized_views(connection, keyspace_name)
|
1026
|
+
params = [keyspace_name]
|
1027
|
+
hints = [Types.varchar]
|
1028
|
+
send_select_request(connection, SELECT_KEYSPACE_VIEWS, params, hints)
|
1029
|
+
end
|
1030
|
+
|
804
1031
|
def select_keyspace_types(connection, keyspace_name)
|
805
1032
|
params = [keyspace_name]
|
806
1033
|
hints = [Types.varchar]
|
@@ -826,11 +1053,26 @@ module Cassandra
|
|
826
1053
|
end
|
827
1054
|
|
828
1055
|
def select_table_columns(connection, keyspace_name, table_name)
|
1056
|
+
# This is identical to the 2.0 impl, but the SELECT_TABLE_COLUMNS query
|
1057
|
+
# is different between the two, so we need two impls. :(
|
1058
|
+
# Also, this method works fine for finding view columns as well.
|
829
1059
|
params = [keyspace_name, table_name]
|
830
1060
|
hints = [Types.varchar, Types.varchar]
|
831
1061
|
send_select_request(connection, SELECT_TABLE_COLUMNS, params, hints)
|
832
1062
|
end
|
833
1063
|
|
1064
|
+
def select_table_indexes(connection, keyspace_name, table_name)
|
1065
|
+
params = [keyspace_name, table_name]
|
1066
|
+
hints = [Types.varchar, Types.varchar]
|
1067
|
+
send_select_request(connection, SELECT_TABLE_INDEXES, params, hints)
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
def select_materialized_view(connection, keyspace_name, view_name)
|
1071
|
+
params = [keyspace_name, view_name]
|
1072
|
+
hints = [Types.varchar, Types.varchar]
|
1073
|
+
send_select_request(connection, SELECT_VIEW, params, hints)
|
1074
|
+
end
|
1075
|
+
|
834
1076
|
def select_type(connection, keyspace_name, type_name)
|
835
1077
|
params = [keyspace_name, type_name]
|
836
1078
|
hints = [Types.varchar, Types.varchar]
|
@@ -860,29 +1102,50 @@ module Cassandra
|
|
860
1102
|
|
861
1103
|
arguments = []
|
862
1104
|
|
863
|
-
function_data['argument_names']
|
864
|
-
|
1105
|
+
function_data['argument_names']
|
1106
|
+
.zip(function_data['argument_types']) do |argument_name, argument_type|
|
1107
|
+
arguments << Argument.new(argument_name,
|
1108
|
+
@type_parser.parse(argument_type, types).first)
|
865
1109
|
end
|
866
1110
|
|
867
|
-
Function.new(keyspace_name,
|
1111
|
+
Cassandra::Function.new(keyspace_name,
|
1112
|
+
function_name,
|
1113
|
+
function_lang,
|
1114
|
+
function_type,
|
1115
|
+
arguments,
|
1116
|
+
function_body,
|
1117
|
+
called_on_null)
|
868
1118
|
end
|
869
1119
|
|
870
1120
|
def create_aggregate(aggregate_data, functions, types = nil)
|
871
1121
|
keyspace_name = aggregate_data['keyspace_name']
|
872
1122
|
aggregate_name = aggregate_data['aggregate_name']
|
873
1123
|
types ||= @schema.keyspace(keyspace_name).send(:raw_types)
|
874
|
-
aggregate_type =
|
875
|
-
|
1124
|
+
aggregate_type =
|
1125
|
+
@type_parser.parse(aggregate_data['return_type'], types).first
|
1126
|
+
argument_types = aggregate_data['argument_types'].map do |argument_type|
|
1127
|
+
@type_parser.parse(argument_type, types).first
|
1128
|
+
end.freeze
|
876
1129
|
state_type = @type_parser.parse(aggregate_data['state_type'], types).first
|
877
1130
|
initial_state = aggregate_data['initcond'] || 'null'
|
878
1131
|
|
879
|
-
# The state-function takes arguments: first the stype, then the args of the
|
880
|
-
|
1132
|
+
# The state-function takes arguments: first the stype, then the args of the
|
1133
|
+
# aggregate.
|
1134
|
+
state_function = functions.get(aggregate_data['state_func'],
|
1135
|
+
[state_type].concat(argument_types))
|
881
1136
|
|
882
1137
|
# The final-function takes an stype argument.
|
883
|
-
final_function = functions
|
1138
|
+
final_function = functions.get(aggregate_data['final_func'],
|
1139
|
+
[state_type])
|
884
1140
|
|
885
|
-
Aggregate.new(keyspace_name,
|
1141
|
+
Aggregate.new(keyspace_name,
|
1142
|
+
aggregate_name,
|
1143
|
+
aggregate_type,
|
1144
|
+
argument_types,
|
1145
|
+
state_type,
|
1146
|
+
initial_state,
|
1147
|
+
state_function,
|
1148
|
+
final_function)
|
886
1149
|
end
|
887
1150
|
|
888
1151
|
def create_types(rows_types, types)
|
@@ -914,43 +1177,60 @@ module Cassandra
|
|
914
1177
|
|
915
1178
|
break if skipped_rows.empty?
|
916
1179
|
|
917
|
-
if rows_size == skipped_rows.size
|
918
|
-
|
919
|
-
|
920
|
-
rows_types, skipped_rows = skipped_rows, rows_types
|
921
|
-
end
|
1180
|
+
raise 'Unable to resolve circular references among UDTs when parsing' if rows_size == skipped_rows.size
|
1181
|
+
|
1182
|
+
rows_types, skipped_rows = skipped_rows, rows_types
|
922
1183
|
end
|
923
1184
|
end
|
924
1185
|
|
925
|
-
def create_keyspace(keyspace_data, rows_tables, rows_columns,
|
926
|
-
|
1186
|
+
def create_keyspace(keyspace_data, rows_tables, rows_columns, rows_types,
|
1187
|
+
rows_functions, rows_aggregates, rows_views, rows_indexes)
|
927
1188
|
keyspace_name = keyspace_data['keyspace_name']
|
928
1189
|
replication = create_replication(keyspace_data)
|
929
1190
|
|
930
1191
|
types = ::Hash.new
|
931
1192
|
create_types(rows_types, types)
|
932
1193
|
|
933
|
-
#
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
func = create_function(row, types)
|
938
|
-
collector[[func.name, func.argument_types]] = func
|
1194
|
+
# Create a FunctionCollection for the functions and aggregates.
|
1195
|
+
functions = Cassandra::FunctionCollection.new
|
1196
|
+
rows_functions.each do |row|
|
1197
|
+
functions.add_or_update(create_function(row, types))
|
939
1198
|
end
|
940
1199
|
|
941
|
-
aggregates =
|
942
|
-
|
943
|
-
|
1200
|
+
aggregates = Cassandra::FunctionCollection.new
|
1201
|
+
rows_aggregates.each do |row|
|
1202
|
+
aggregates.add_or_update(create_aggregate(row, functions, types))
|
944
1203
|
end
|
945
1204
|
|
1205
|
+
# lookup_columns is a hash of <table-name, rows_columns for that table>.
|
1206
|
+
# However, views are analogous to tables in this context, so we get
|
1207
|
+
# view columns organized by view-name also.
|
1208
|
+
|
946
1209
|
lookup_columns = map_rows_by(rows_columns, 'table_name')
|
947
|
-
|
1210
|
+
lookup_indexes = map_rows_by(rows_indexes, 'table_name')
|
1211
|
+
tables = rows_tables.each_with_object({}) do |row, h|
|
948
1212
|
table_name = row['table_name']
|
949
|
-
|
1213
|
+
h[table_name] = create_table(row, lookup_columns[table_name],
|
1214
|
+
lookup_indexes[table_name], types)
|
950
1215
|
end
|
951
1216
|
|
952
|
-
|
953
|
-
|
1217
|
+
views = rows_views.each_with_object({}) do |row, h|
|
1218
|
+
view_name = row['view_name']
|
1219
|
+
base_table = tables[row['base_table_name']]
|
1220
|
+
h[view_name] = create_materialized_view(row,
|
1221
|
+
lookup_columns[view_name],
|
1222
|
+
base_table,
|
1223
|
+
types)
|
1224
|
+
end
|
1225
|
+
|
1226
|
+
Keyspace.new(keyspace_name,
|
1227
|
+
keyspace_data['durable_writes'],
|
1228
|
+
replication,
|
1229
|
+
tables,
|
1230
|
+
types,
|
1231
|
+
functions,
|
1232
|
+
aggregates,
|
1233
|
+
views)
|
954
1234
|
end
|
955
1235
|
|
956
1236
|
def create_replication(keyspace_data)
|
@@ -964,14 +1244,14 @@ module Cassandra
|
|
964
1244
|
options = table_data['compaction']
|
965
1245
|
klass = options.delete('class')
|
966
1246
|
klass.slice!('org.apache.cassandra.db.compaction.')
|
967
|
-
|
1247
|
+
ColumnContainer::Compaction.new(klass, options)
|
968
1248
|
end
|
969
1249
|
|
970
1250
|
def create_table_options(table_data, compaction_strategy, is_compact)
|
971
1251
|
compression = table_data['compression']
|
972
1252
|
compression['class'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression['class']
|
973
1253
|
|
974
|
-
|
1254
|
+
Cassandra::ColumnContainer::Options.new(
|
975
1255
|
table_data['comment'],
|
976
1256
|
table_data['read_repair_chance'],
|
977
1257
|
table_data['dclocal_read_repair_chance'],
|
@@ -988,76 +1268,146 @@ module Cassandra
|
|
988
1268
|
table_data['max_index_interval'],
|
989
1269
|
compaction_strategy,
|
990
1270
|
compression,
|
991
|
-
is_compact
|
1271
|
+
is_compact,
|
1272
|
+
table_data['crc_check_chance'],
|
1273
|
+
table_data['extensions']
|
992
1274
|
)
|
993
1275
|
end
|
994
1276
|
|
995
1277
|
def create_column(column_data, types)
|
996
1278
|
name = column_data['column_name']
|
997
|
-
is_static =
|
1279
|
+
is_static = column_data['kind'].to_s.casecmp('STATIC').zero?
|
998
1280
|
order = column_data['clustering_order'] == 'desc' ? :desc : :asc
|
999
|
-
|
1281
|
+
if column_data['type'][0] == "'"
|
1282
|
+
# This is a custom column type.
|
1283
|
+
type = Types.custom(column_data['type'].slice(1, column_data['type'].length - 2))
|
1284
|
+
is_frozen = false
|
1285
|
+
else
|
1286
|
+
type, is_frozen = @type_parser.parse(column_data['type'], types)
|
1287
|
+
end
|
1000
1288
|
|
1001
|
-
Column.new(name, type, order,
|
1289
|
+
Column.new(name, type, order, is_static, is_frozen)
|
1002
1290
|
end
|
1003
1291
|
|
1004
|
-
def create_table(table_data, rows_columns, types = nil)
|
1292
|
+
def create_table(table_data, rows_columns, rows_indexes, types = nil)
|
1005
1293
|
keyspace_name = table_data['keyspace_name']
|
1006
1294
|
table_name = table_data['table_name']
|
1007
1295
|
table_flags = table_data['flags']
|
1008
|
-
table_columns = {}
|
1009
|
-
other_columns = []
|
1010
|
-
clustering_size = 0
|
1011
1296
|
|
1012
1297
|
is_dense = table_flags.include?('dense')
|
1013
1298
|
is_super = table_flags.include?('super')
|
1014
1299
|
is_compound = table_flags.include?('compound')
|
1015
1300
|
is_compact = is_super || is_dense || !is_compound
|
1301
|
+
is_static_compact = !is_super && !is_dense && !is_compound
|
1016
1302
|
|
1303
|
+
# Separate out partition-key, clustering columns, other columns.
|
1017
1304
|
partition_key = []
|
1018
1305
|
clustering_columns = []
|
1019
1306
|
clustering_order = []
|
1020
|
-
|
1307
|
+
other_columns = []
|
1308
|
+
types ||= @schema.keyspace(keyspace_name).send(:raw_types)
|
1021
1309
|
|
1022
1310
|
rows_columns.each do |row|
|
1023
1311
|
next if row['column_name'].empty?
|
1024
1312
|
|
1025
|
-
column = create_column(row, types)
|
1026
1313
|
kind = row['kind'].to_s
|
1027
1314
|
index = row['position'] || 0
|
1028
1315
|
|
1316
|
+
if is_static_compact
|
1317
|
+
if kind.casecmp('CLUSTERING').zero? || kind.casecmp('REGULAR').zero?
|
1318
|
+
# Skip clustering columns in static-compact tables; they are internal to C*.
|
1319
|
+
# Oddly so are regular columns.
|
1320
|
+
next
|
1321
|
+
end
|
1322
|
+
if kind.casecmp('STATIC').zero?
|
1323
|
+
# Coerce static type to regular.
|
1324
|
+
kind = 'REGULAR'
|
1325
|
+
row['kind'] = 'regular'
|
1326
|
+
end
|
1327
|
+
end
|
1328
|
+
|
1329
|
+
column = create_column(row, types)
|
1029
1330
|
case kind.upcase
|
1030
1331
|
when 'PARTITION_KEY'
|
1031
1332
|
partition_key[index] = column
|
1032
1333
|
when 'CLUSTERING'
|
1033
1334
|
clustering_columns[index] = column
|
1034
1335
|
clustering_order[index] = column.order
|
1035
|
-
|
1036
|
-
if clustering_size.zero? || index == clustering_size
|
1037
|
-
clustering_size = index + 1
|
1038
|
-
end
|
1039
1336
|
else
|
1040
1337
|
other_columns << column
|
1041
1338
|
end
|
1042
1339
|
end
|
1043
1340
|
|
1044
|
-
|
1045
|
-
|
1341
|
+
# Default the crc_check_chance to 1.0 (Java driver does this, so we
|
1342
|
+
# should, too).
|
1343
|
+
table_data['crc_check_chance'] ||= 1.0
|
1344
|
+
compaction_strategy = create_compaction_strategy(table_data)
|
1345
|
+
table_options =
|
1346
|
+
create_table_options(table_data, compaction_strategy, is_compact)
|
1347
|
+
|
1348
|
+
table = Cassandra::Table.new(@schema.keyspace(keyspace_name),
|
1349
|
+
table_name,
|
1350
|
+
partition_key,
|
1351
|
+
clustering_columns,
|
1352
|
+
other_columns,
|
1353
|
+
table_options,
|
1354
|
+
clustering_order,
|
1355
|
+
table_data['id'])
|
1356
|
+
rows_indexes.each do |row|
|
1357
|
+
create_index(table, row)
|
1046
1358
|
end
|
1359
|
+
table
|
1360
|
+
end
|
1047
1361
|
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1362
|
+
def create_index(table, row_index)
|
1363
|
+
options = row_index['options']
|
1364
|
+
table.add_index(Cassandra::Index.new(table, row_index['index_name'],
|
1365
|
+
row_index['kind'].downcase.to_sym,
|
1366
|
+
options['target'], options))
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
def create_materialized_view(view_data, rows_columns, base_table, types = nil)
|
1370
|
+
keyspace_name = view_data['keyspace_name']
|
1371
|
+
view_name = view_data['view_name']
|
1372
|
+
include_all_columns = view_data['include_all_columns']
|
1373
|
+
where_clause = view_data['where_clause']
|
1374
|
+
|
1375
|
+
# Separate out partition key, clustering columns, other columns
|
1376
|
+
partition_key = []
|
1377
|
+
clustering_columns = []
|
1378
|
+
other_columns = []
|
1379
|
+
types ||= @schema.keyspace(keyspace_name).send(:raw_types)
|
1380
|
+
|
1381
|
+
rows_columns.each do |row|
|
1382
|
+
next if row['column_name'].empty?
|
1383
|
+
|
1384
|
+
column = create_column(row, types)
|
1385
|
+
kind = row['kind'].to_s
|
1386
|
+
index = row['position'] || 0
|
1051
1387
|
|
1052
|
-
|
1053
|
-
|
1388
|
+
case kind.upcase
|
1389
|
+
when 'PARTITION_KEY'
|
1390
|
+
partition_key[index] = column
|
1391
|
+
when 'CLUSTERING'
|
1392
|
+
clustering_columns[index] = column
|
1393
|
+
else
|
1394
|
+
other_columns << column
|
1395
|
+
end
|
1054
1396
|
end
|
1055
1397
|
|
1056
|
-
compaction_strategy = create_compaction_strategy(
|
1057
|
-
|
1398
|
+
compaction_strategy = create_compaction_strategy(view_data)
|
1399
|
+
view_options = create_table_options(view_data, compaction_strategy, false)
|
1058
1400
|
|
1059
|
-
|
1060
|
-
|
1401
|
+
MaterializedView.new(@schema.keyspace(keyspace_name),
|
1402
|
+
view_name,
|
1403
|
+
partition_key,
|
1404
|
+
clustering_columns,
|
1405
|
+
other_columns,
|
1406
|
+
view_options,
|
1407
|
+
include_all_columns,
|
1408
|
+
where_clause,
|
1409
|
+
base_table,
|
1410
|
+
view_data['id'])
|
1061
1411
|
end
|
1062
1412
|
end
|
1063
1413
|
|
@@ -1109,6 +1459,13 @@ module Cassandra
|
|
1109
1459
|
return Ione::Future.failed(e)
|
1110
1460
|
end
|
1111
1461
|
|
1462
|
+
def fetch_materialized_view(connection, keyspace_name, view_name)
|
1463
|
+
find_fetcher(connection)
|
1464
|
+
.fetch_materialized_view(connection, keyspace_name, view_name)
|
1465
|
+
rescue => e
|
1466
|
+
return Ione::Future.failed(e)
|
1467
|
+
end
|
1468
|
+
|
1112
1469
|
def fetch_type(connection, keyspace_name, type_name)
|
1113
1470
|
find_fetcher(connection)
|
1114
1471
|
.fetch_type(connection, keyspace_name, type_name)
|
@@ -1130,13 +1487,16 @@ module Cassandra
|
|
1130
1487
|
return Ione::Future.failed(e)
|
1131
1488
|
end
|
1132
1489
|
|
1133
|
-
# parse an array of string argument types and return an array of
|
1490
|
+
# parse an array of string argument types and return an array of
|
1491
|
+
# [Cassandra::Type]s.
|
1134
1492
|
# @param connection a connection to a Cassandra node.
|
1135
1493
|
# @param keyspace_name [String] name of the keyspace.
|
1136
1494
|
# @param argument_types [Array<String>] array of argument types.
|
1137
1495
|
# @return [Array<Cassandra::Type>] array of parsed types.
|
1138
1496
|
def parse_argument_types(connection, keyspace_name, argument_types)
|
1139
|
-
find_fetcher(connection).parse_argument_types(connection,
|
1497
|
+
find_fetcher(connection).parse_argument_types(connection,
|
1498
|
+
keyspace_name,
|
1499
|
+
argument_types)
|
1140
1500
|
end
|
1141
1501
|
|
1142
1502
|
private
|
@@ -1147,21 +1507,21 @@ module Cassandra
|
|
1147
1507
|
unless host
|
1148
1508
|
ips = @registry.hosts.map(&:ip)
|
1149
1509
|
raise Errors::ClientError,
|
1150
|
-
|
1510
|
+
'unable to find release version for current host, ' \
|
1151
1511
|
"connected to #{connection.host}, but cluster contains " \
|
1152
1512
|
"#{ips}."
|
1153
1513
|
end
|
1154
1514
|
|
1155
1515
|
version = host.release_version
|
1156
1516
|
unless version
|
1157
|
-
raise Errors::ClientError,
|
1517
|
+
raise Errors::ClientError, 'unable to determine release ' \
|
1158
1518
|
"version for host: #{host.inspect}"
|
1159
1519
|
end
|
1160
1520
|
|
1161
1521
|
@fetchers[version] ||= begin
|
1162
1522
|
current = @versions.find {|v| v.matches?(version)}
|
1163
1523
|
unless current
|
1164
|
-
raise Errors::ClientError,
|
1524
|
+
raise Errors::ClientError, 'unsupported release version ' \
|
1165
1525
|
"#{version.inspect}."
|
1166
1526
|
end
|
1167
1527
|
current.fetcher
|