cassandra-driver 3.0.0.beta.1 → 3.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +90 -38
- data/ext/cassandra_murmur3/cassandra_murmur3.c +1 -1
- data/lib/cassandra.rb +327 -130
- 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/auth.rb +4 -4
- data/lib/cassandra/auth/providers.rb +1 -1
- data/lib/cassandra/auth/providers/password.rb +9 -5
- data/lib/cassandra/cassandra_logger.rb +80 -0
- data/lib/cassandra/cluster.rb +38 -9
- data/lib/cassandra/cluster/client.rb +801 -205
- data/lib/cassandra/cluster/connection_pool.rb +2 -2
- data/lib/cassandra/cluster/connector.rb +74 -25
- data/lib/cassandra/cluster/control_connection.rb +217 -82
- data/lib/cassandra/cluster/failed_connection.rb +1 -1
- data/lib/cassandra/cluster/metadata.rb +12 -4
- data/lib/cassandra/cluster/options.rb +60 -11
- data/lib/cassandra/cluster/registry.rb +69 -16
- data/lib/cassandra/cluster/schema.rb +25 -7
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +15 -10
- data/lib/cassandra/cluster/schema/fetchers.rb +263 -106
- data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +41 -36
- data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
- data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +3 -3
- 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 +3 -3
- data/lib/cassandra/compression.rb +1 -1
- data/lib/cassandra/compression/compressors/lz4.rb +4 -3
- data/lib/cassandra/compression/compressors/snappy.rb +4 -3
- data/lib/cassandra/driver.rb +103 -41
- data/lib/cassandra/errors.rb +265 -30
- data/lib/cassandra/execution/info.rb +16 -5
- data/lib/cassandra/execution/options.rb +99 -54
- 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 +106 -48
- data/lib/cassandra/host.rb +10 -4
- data/lib/cassandra/keyspace.rb +90 -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 +18 -18
- data/lib/cassandra/load_balancing/policies/round_robin.rb +1 -1
- data/lib/cassandra/load_balancing/policies/token_aware.rb +15 -13
- data/lib/cassandra/load_balancing/policies/white_list.rb +11 -5
- data/lib/cassandra/null_logger.rb +27 -6
- data/lib/cassandra/protocol.rb +1 -1
- data/lib/cassandra/protocol/coder.rb +78 -39
- data/lib/cassandra/protocol/cql_byte_buffer.rb +50 -33
- data/lib/cassandra/protocol/cql_protocol_handler.rb +44 -45
- data/lib/cassandra/protocol/request.rb +2 -2
- data/lib/cassandra/protocol/requests/auth_response_request.rb +3 -3
- data/lib/cassandra/protocol/requests/batch_request.rb +16 -7
- data/lib/cassandra/protocol/requests/credentials_request.rb +3 -3
- data/lib/cassandra/protocol/requests/execute_request.rb +41 -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 +27 -22
- data/lib/cassandra/protocol/requests/register_request.rb +2 -2
- data/lib/cassandra/protocol/requests/startup_request.rb +6 -4
- data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
- data/lib/cassandra/protocol/response.rb +2 -2
- data/lib/cassandra/protocol/responses/already_exists_error_response.rb +12 -2
- data/lib/cassandra/protocol/responses/auth_challenge_response.rb +1 -1
- data/lib/cassandra/protocol/responses/auth_success_response.rb +1 -1
- data/lib/cassandra/protocol/responses/authenticate_response.rb +1 -1
- data/lib/cassandra/protocol/responses/error_response.rb +101 -13
- data/lib/cassandra/protocol/responses/event_response.rb +1 -1
- data/lib/cassandra/protocol/responses/function_failure_error_response.rb +13 -2
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +11 -5
- 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 +3 -3
- data/lib/cassandra/protocol/responses/result_response.rb +4 -2
- data/lib/cassandra/protocol/responses/rows_result_response.rb +5 -3
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +5 -4
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +16 -9
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +2 -2
- data/lib/cassandra/protocol/responses/status_change_event_response.rb +2 -2
- data/lib/cassandra/protocol/responses/supported_response.rb +1 -1
- data/lib/cassandra/protocol/responses/topology_change_event_response.rb +1 -1
- 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 +1 -1
- 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 +101 -36
- data/lib/cassandra/protocol/v3.rb +124 -51
- 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 +53 -19
- 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 +7 -3
- data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
- data/lib/cassandra/session.rb +22 -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 +59 -15
- data/lib/cassandra/statements/simple.rb +23 -10
- data/lib/cassandra/statements/void.rb +1 -1
- data/lib/cassandra/table.rb +79 -30
- data/lib/cassandra/time.rb +11 -6
- data/lib/cassandra/time_uuid.rb +7 -7
- data/lib/cassandra/tuple.rb +16 -8
- data/lib/cassandra/types.rb +20 -9
- data/lib/cassandra/udt.rb +32 -36
- data/lib/cassandra/util.rb +20 -13
- data/lib/cassandra/uuid.rb +22 -15
- data/lib/cassandra/uuid/generator.rb +7 -5
- data/lib/cassandra/version.rb +2 -2
- data/lib/datastax/cassandra.rb +1 -1
- metadata +5 -3
@@ -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.
|
@@ -24,7 +24,11 @@ module Cassandra
|
|
24
24
|
|
25
25
|
attr_reader :name
|
26
26
|
|
27
|
-
def initialize(cluster_registry,
|
27
|
+
def initialize(cluster_registry,
|
28
|
+
cluster_schema,
|
29
|
+
schema_partitioners,
|
30
|
+
replication_strategies,
|
31
|
+
default_replication_strategy)
|
28
32
|
@registry = cluster_registry
|
29
33
|
@schema = cluster_schema
|
30
34
|
@partitioners = schema_partitioners
|
@@ -74,7 +78,11 @@ module Cassandra
|
|
74
78
|
|
75
79
|
@registry.each_host do |host|
|
76
80
|
host.tokens.each do |token|
|
77
|
-
token =
|
81
|
+
token = begin
|
82
|
+
partitioner.parse_token(token)
|
83
|
+
rescue
|
84
|
+
next
|
85
|
+
end
|
78
86
|
tokens.add(token)
|
79
87
|
token_to_host[token] = host
|
80
88
|
end
|
@@ -116,7 +124,7 @@ module Cassandra
|
|
116
124
|
min = 0
|
117
125
|
max = list.size - 1
|
118
126
|
|
119
|
-
while min <= max
|
127
|
+
while min <= max
|
120
128
|
idx = (min + max) / 2
|
121
129
|
val = list[idx]
|
122
130
|
|
@@ -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.
|
@@ -20,12 +20,31 @@ module Cassandra
|
|
20
20
|
class Cluster
|
21
21
|
# @private
|
22
22
|
class Options
|
23
|
-
attr_reader :
|
24
|
-
:
|
25
|
-
:
|
23
|
+
attr_reader :auth_provider, :compressor, :connect_timeout, :credentials,
|
24
|
+
:heartbeat_interval, :idle_timeout, :port, :schema_refresh_delay,
|
25
|
+
:schema_refresh_timeout, :ssl
|
26
|
+
|
26
27
|
attr_accessor :protocol_version
|
27
28
|
|
28
|
-
def initialize(
|
29
|
+
def initialize(logger,
|
30
|
+
protocol_version,
|
31
|
+
credentials,
|
32
|
+
auth_provider,
|
33
|
+
compressor,
|
34
|
+
port,
|
35
|
+
connect_timeout,
|
36
|
+
ssl,
|
37
|
+
connections_per_local_node,
|
38
|
+
connections_per_remote_node,
|
39
|
+
heartbeat_interval,
|
40
|
+
idle_timeout,
|
41
|
+
synchronize_schema,
|
42
|
+
schema_refresh_delay,
|
43
|
+
schema_refresh_timeout,
|
44
|
+
client_timestamps,
|
45
|
+
nodelay,
|
46
|
+
requests_per_connection)
|
47
|
+
@logger = logger
|
29
48
|
@protocol_version = protocol_version
|
30
49
|
@credentials = credentials
|
31
50
|
@auth_provider = auth_provider
|
@@ -43,6 +62,7 @@ module Cassandra
|
|
43
62
|
|
44
63
|
@connections_per_local_node = connections_per_local_node
|
45
64
|
@connections_per_remote_node = connections_per_remote_node
|
65
|
+
@requests_per_connection = requests_per_connection
|
46
66
|
end
|
47
67
|
|
48
68
|
def synchronize_schema?
|
@@ -65,16 +85,45 @@ module Cassandra
|
|
65
85
|
@auth_provider && @auth_provider.create_authenticator(authentication_class)
|
66
86
|
end
|
67
87
|
|
68
|
-
# increased number of streams in native protocol v3 allow for one
|
69
|
-
# connections to be sufficient
|
70
88
|
def connections_per_local_node
|
71
|
-
|
89
|
+
# Return the option if set.
|
90
|
+
return @connections_per_local_node if @connections_per_local_node
|
91
|
+
|
92
|
+
# For v3 and later, default is 1 local connection.
|
93
|
+
# For v2 and earlier, default is 2 local connections.
|
94
|
+
# Return the default
|
95
|
+
(@protocol_version > 2) ? 1 : 2
|
72
96
|
end
|
73
97
|
|
74
|
-
# increased number of streams in native protocol v3 allow for one
|
75
|
-
# connections to be sufficient
|
76
98
|
def connections_per_remote_node
|
77
|
-
|
99
|
+
# Return the option if set; otherwise return the default (1).
|
100
|
+
@connections_per_remote_node || 1
|
101
|
+
end
|
102
|
+
|
103
|
+
def requests_per_connection
|
104
|
+
# There are a few possibilities here based on @requests_per_connection:
|
105
|
+
# nil: default to 1024 for protocol 3 and later, 128 for < 3.
|
106
|
+
# we're in v2 and value too high: return 128. We don't worry
|
107
|
+
# about this case for v3+ because option validation in
|
108
|
+
# Cassandra::cluster_async takes care of that.
|
109
|
+
# good value: return it.
|
110
|
+
#
|
111
|
+
# NOTE: We can't compute and cache the result because protocol_version
|
112
|
+
# can change over time in theory (if all nodes are upgraded to a new
|
113
|
+
# version of Cassandra)
|
114
|
+
|
115
|
+
# Return the default if option wasn't specified.
|
116
|
+
default_requests_per_connection = @protocol_version > 2 ? 1024 : 128
|
117
|
+
return default_requests_per_connection unless @requests_per_connection
|
118
|
+
|
119
|
+
if @requests_per_connection > 128 && @protocol_version < 3
|
120
|
+
@logger.warn(
|
121
|
+
":requests_per_connection setting of #{@requests_per_connection} is more " \
|
122
|
+
'than the max of 128 for protocol v2. Falling back to 128.'
|
123
|
+
)
|
124
|
+
return 128
|
125
|
+
end
|
126
|
+
@requests_per_connection
|
78
127
|
end
|
79
128
|
end
|
80
129
|
end
|
@@ -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.
|
@@ -58,14 +58,14 @@ module Cassandra
|
|
58
58
|
@hosts.values
|
59
59
|
end
|
60
60
|
end
|
61
|
-
alias
|
61
|
+
alias hosts each_host
|
62
62
|
|
63
63
|
def host(address)
|
64
64
|
@hosts[address.to_s]
|
65
65
|
end
|
66
66
|
|
67
67
|
def has_host?(address)
|
68
|
-
@hosts.
|
68
|
+
@hosts.key?(address.to_s)
|
69
69
|
end
|
70
70
|
|
71
71
|
def host_found(address, data = {})
|
@@ -82,7 +82,8 @@ module Cassandra
|
|
82
82
|
|
83
83
|
host = toggle_up(host)
|
84
84
|
else
|
85
|
-
@logger.debug("Host #{host.ip} metadata has been updated, it will be
|
85
|
+
@logger.debug("Host #{host.ip} metadata has been updated, it will be " \
|
86
|
+
'considered lost and found')
|
86
87
|
|
87
88
|
notify_lost(host)
|
88
89
|
|
@@ -143,7 +144,7 @@ module Cassandra
|
|
143
144
|
ip = address.to_s
|
144
145
|
host = nil
|
145
146
|
|
146
|
-
return self unless @hosts.
|
147
|
+
return self unless @hosts.key?(ip)
|
147
148
|
|
148
149
|
synchronize do
|
149
150
|
hosts = @hosts.dup
|
@@ -159,23 +160,49 @@ module Cassandra
|
|
159
160
|
private
|
160
161
|
|
161
162
|
def create_host(ip, data)
|
162
|
-
Host.new(ip,
|
163
|
+
Host.new(ip,
|
164
|
+
data['host_id'],
|
165
|
+
data['rack'],
|
166
|
+
data['data_center'],
|
167
|
+
data['release_version'],
|
168
|
+
Array(data['tokens']).freeze,
|
169
|
+
:up)
|
163
170
|
end
|
164
171
|
|
165
172
|
def toggle_up(host)
|
166
|
-
host = Host.new(host.ip,
|
173
|
+
host = Host.new(host.ip,
|
174
|
+
host.id,
|
175
|
+
host.rack,
|
176
|
+
host.datacenter,
|
177
|
+
host.release_version,
|
178
|
+
host.tokens,
|
179
|
+
:up)
|
167
180
|
@logger.debug("Host #{host.ip} is up")
|
168
181
|
@listeners.each do |listener|
|
169
|
-
|
182
|
+
begin
|
183
|
+
listener.host_up(host)
|
184
|
+
rescue
|
185
|
+
nil
|
186
|
+
end
|
170
187
|
end
|
171
188
|
host
|
172
189
|
end
|
173
190
|
|
174
191
|
def toggle_down(host)
|
175
|
-
host = Host.new(host.ip,
|
192
|
+
host = Host.new(host.ip,
|
193
|
+
host.id,
|
194
|
+
host.rack,
|
195
|
+
host.datacenter,
|
196
|
+
host.release_version,
|
197
|
+
host.tokens,
|
198
|
+
:down)
|
176
199
|
@logger.debug("Host #{host.ip} is down")
|
177
200
|
@listeners.reverse_each do |listener|
|
178
|
-
|
201
|
+
begin
|
202
|
+
listener.host_down(host)
|
203
|
+
rescue
|
204
|
+
nil
|
205
|
+
end
|
179
206
|
end
|
180
207
|
host
|
181
208
|
end
|
@@ -183,15 +210,33 @@ module Cassandra
|
|
183
210
|
def notify_lost(host)
|
184
211
|
if host.up?
|
185
212
|
@logger.debug("Host #{host.ip} is down and lost")
|
186
|
-
host = Host.new(host.ip,
|
213
|
+
host = Host.new(host.ip,
|
214
|
+
host.id,
|
215
|
+
host.rack,
|
216
|
+
host.datacenter,
|
217
|
+
host.release_version,
|
218
|
+
host.tokens,
|
219
|
+
:down)
|
187
220
|
@listeners.reverse_each do |listener|
|
188
|
-
|
189
|
-
|
221
|
+
begin
|
222
|
+
listener.host_down(host)
|
223
|
+
rescue
|
224
|
+
nil
|
225
|
+
end
|
226
|
+
begin
|
227
|
+
listener.host_lost(host)
|
228
|
+
rescue
|
229
|
+
nil
|
230
|
+
end
|
190
231
|
end
|
191
232
|
else
|
192
233
|
@logger.debug("Host #{host.ip} is lost")
|
193
234
|
@listeners.reverse_each do |listener|
|
194
|
-
|
235
|
+
begin
|
236
|
+
listener.host_lost(host)
|
237
|
+
rescue
|
238
|
+
nil
|
239
|
+
end
|
195
240
|
end
|
196
241
|
end
|
197
242
|
end
|
@@ -199,8 +244,16 @@ module Cassandra
|
|
199
244
|
def notify_found(host)
|
200
245
|
@logger.debug("Host #{host.ip} is found and up")
|
201
246
|
@listeners.each do |listener|
|
202
|
-
|
203
|
-
|
247
|
+
begin
|
248
|
+
listener.host_found(host)
|
249
|
+
rescue
|
250
|
+
nil
|
251
|
+
end
|
252
|
+
begin
|
253
|
+
listener.host_up(host)
|
254
|
+
rescue
|
255
|
+
nil
|
256
|
+
end
|
204
257
|
end
|
205
258
|
end
|
206
259
|
end
|
@@ -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.
|
@@ -32,7 +32,13 @@ module Cassandra
|
|
32
32
|
def get_pk_idx(metadata)
|
33
33
|
return EMPTY_LIST unless metadata
|
34
34
|
|
35
|
-
|
35
|
+
# metadata is an array of column-specs; each column-spec is an array
|
36
|
+
# of keyspace_name, tablename, other stuff. We only care about the first two.
|
37
|
+
# See read_prepared_metadata_v4 in coder.rb for more details.
|
38
|
+
# NB: sandman: I think all of the column specs have the same keyspace and
|
39
|
+
# table name in this context, so we can safely grab the first.
|
40
|
+
|
41
|
+
keyspace_name, table_name = metadata.first
|
36
42
|
return EMPTY_LIST unless keyspace_name && table_name
|
37
43
|
|
38
44
|
keyspace = @keyspaces[keyspace_name]
|
@@ -76,7 +82,7 @@ module Cassandra
|
|
76
82
|
replace_keyspace(keyspace)
|
77
83
|
end
|
78
84
|
|
79
|
-
@keyspaces.each do |name,
|
85
|
+
@keyspaces.each do |name, _keyspace|
|
80
86
|
delete_keyspace(name) unless current_keyspaces.include?(name)
|
81
87
|
end
|
82
88
|
|
@@ -311,25 +317,37 @@ module Cassandra
|
|
311
317
|
@keyspaces.values
|
312
318
|
end
|
313
319
|
end
|
314
|
-
alias
|
320
|
+
alias keyspaces each_keyspace
|
315
321
|
|
316
322
|
private
|
317
323
|
|
318
324
|
def keyspace_created(keyspace)
|
319
325
|
@listeners.each do |listener|
|
320
|
-
|
326
|
+
begin
|
327
|
+
listener.keyspace_created(keyspace)
|
328
|
+
rescue
|
329
|
+
nil
|
330
|
+
end
|
321
331
|
end
|
322
332
|
end
|
323
333
|
|
324
334
|
def keyspace_changed(keyspace)
|
325
335
|
@listeners.each do |listener|
|
326
|
-
|
336
|
+
begin
|
337
|
+
listener.keyspace_changed(keyspace)
|
338
|
+
rescue
|
339
|
+
nil
|
340
|
+
end
|
327
341
|
end
|
328
342
|
end
|
329
343
|
|
330
344
|
def keyspace_dropped(keyspace)
|
331
345
|
@listeners.each do |listener|
|
332
|
-
|
346
|
+
begin
|
347
|
+
listener.keyspace_dropped(keyspace)
|
348
|
+
rescue
|
349
|
+
nil
|
350
|
+
end
|
333
351
|
end
|
334
352
|
end
|
335
353
|
end
|
@@ -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.
|
@@ -100,7 +100,8 @@ module Cassandra
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def fetch_function(connection, keyspace_name, function_name, function_args)
|
103
|
-
select_function(connection, keyspace_name, function_name, function_args).
|
103
|
+
select_function(connection, keyspace_name, function_name, function_args).
|
104
|
+
map do |rows_functions|
|
104
105
|
if rows_functions.empty?
|
105
106
|
nil
|
106
107
|
else
|
@@ -110,11 +111,13 @@ module Cassandra
|
|
110
111
|
end
|
111
112
|
|
112
113
|
def fetch_aggregate(connection, keyspace_name, aggregate_name, aggregate_args)
|
113
|
-
select_aggregate(connection, keyspace_name, aggregate_name, aggregate_args).
|
114
|
+
select_aggregate(connection, keyspace_name, aggregate_name, aggregate_args).
|
115
|
+
map do |rows_aggregates|
|
114
116
|
if rows_aggregates.empty?
|
115
117
|
nil
|
116
118
|
else
|
117
|
-
create_aggregate(rows_aggregates.first, @schema.keyspace(keyspace_name).
|
119
|
+
create_aggregate(rows_aggregates.first, @schema.keyspace(keyspace_name).
|
120
|
+
send(:raw_functions))
|
118
121
|
end
|
119
122
|
end
|
120
123
|
end
|
@@ -191,7 +194,8 @@ module Cassandra
|
|
191
194
|
|
192
195
|
def send_select_request(connection, cql, params = EMPTY_LIST, types = EMPTY_LIST)
|
193
196
|
backtrace = caller
|
194
|
-
connection.send_request(
|
197
|
+
connection.send_request(
|
198
|
+
Protocol::QueryRequest.new(cql, params, types, :one)).map do |r|
|
195
199
|
case r
|
196
200
|
when Protocol::RowsResultResponse
|
197
201
|
r.rows
|
@@ -225,11 +229,24 @@ module Cassandra
|
|
225
229
|
SELECT_KEYSPACES = 'SELECT * FROM system.schema_keyspaces'.freeze
|
226
230
|
SELECT_TABLES = 'SELECT * FROM system.schema_columnfamilies'.freeze
|
227
231
|
SELECT_COLUMNS = 'SELECT * FROM system.schema_columns'.freeze
|
228
|
-
SELECT_KEYSPACE =
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
232
|
+
SELECT_KEYSPACE =
|
233
|
+
'SELECT * ' \
|
234
|
+
'FROM system.schema_keyspaces ' \
|
235
|
+
'WHERE keyspace_name = \'%s\''.freeze
|
236
|
+
SELECT_KEYSPACE_TABLES =
|
237
|
+
'SELECT * ' \
|
238
|
+
'FROM system.schema_columnfamilies ' \
|
239
|
+
'WHERE keyspace_name = \'%s\''.freeze
|
240
|
+
SELECT_KEYSPACE_COLUMNS =
|
241
|
+
'SELECT * FROM system.schema_columns WHERE keyspace_name = \'%s\''.freeze
|
242
|
+
SELECT_TABLE =
|
243
|
+
'SELECT * ' \
|
244
|
+
'FROM system.schema_columnfamilies ' \
|
245
|
+
'WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
|
246
|
+
SELECT_TABLE_COLUMNS =
|
247
|
+
'SELECT * ' \
|
248
|
+
'FROM system.schema_columns ' \
|
249
|
+
'WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
|
233
250
|
|
234
251
|
include Fetcher
|
235
252
|
|
@@ -269,7 +286,8 @@ module Cassandra
|
|
269
286
|
end
|
270
287
|
|
271
288
|
def select_table_columns(connection, keyspace_name, table_name)
|
272
|
-
send_select_request(connection,
|
289
|
+
send_select_request(connection,
|
290
|
+
SELECT_TABLE_COLUMNS % [keyspace_name, table_name])
|
273
291
|
end
|
274
292
|
|
275
293
|
def create_replication(keyspace_data)
|
@@ -287,18 +305,16 @@ module Cassandra
|
|
287
305
|
types[row['type_name']] = create_type(row)
|
288
306
|
end
|
289
307
|
|
290
|
-
#
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
func = create_function(row)
|
295
|
-
collector[[func.name, func.argument_types]] = func
|
308
|
+
# Create a FunctionCollection for the functions and aggregates.
|
309
|
+
functions = Cassandra::FunctionCollection.new
|
310
|
+
rows_functions.each do |row|
|
311
|
+
functions.add_or_update(create_function(row))
|
296
312
|
end
|
297
313
|
|
298
|
-
aggregates =
|
299
|
-
|
300
|
-
|
301
|
-
|
314
|
+
aggregates = Cassandra::FunctionCollection.new
|
315
|
+
rows_aggregates.each do |row|
|
316
|
+
aggregates.add_or_update(create_aggregate(row, functions))
|
317
|
+
end
|
302
318
|
|
303
319
|
lookup_columns = map_rows_by(rows_columns, 'columnfamily_name')
|
304
320
|
tables = rows_tables.each_with_object({}) do |row, tables|
|
@@ -306,8 +322,13 @@ module Cassandra
|
|
306
322
|
tables[table_name] = create_table(row, lookup_columns[table_name])
|
307
323
|
end
|
308
324
|
|
309
|
-
Keyspace.new(keyspace_name,
|
310
|
-
|
325
|
+
Keyspace.new(keyspace_name,
|
326
|
+
keyspace_data['durable_writes'],
|
327
|
+
replication,
|
328
|
+
tables,
|
329
|
+
types,
|
330
|
+
functions,
|
331
|
+
aggregates)
|
311
332
|
end
|
312
333
|
|
313
334
|
def create_table(table_data, rows_columns)
|
@@ -323,7 +344,8 @@ module Cassandra
|
|
323
344
|
is_compact = false
|
324
345
|
has_value = false
|
325
346
|
clustering_size = size - 2
|
326
|
-
elsif column_aliases.size == size - 1 &&
|
347
|
+
elsif column_aliases.size == size - 1 &&
|
348
|
+
comparator.results.last.first == Cassandra::Types.varchar
|
327
349
|
is_compact = false
|
328
350
|
has_value = false
|
329
351
|
clustering_size = size - 1
|
@@ -348,7 +370,8 @@ module Cassandra
|
|
348
370
|
clustering_order = []
|
349
371
|
|
350
372
|
compaction_strategy = create_compaction_strategy(table_data)
|
351
|
-
table_options =
|
373
|
+
table_options =
|
374
|
+
create_table_options(table_data, compaction_strategy, is_compact)
|
352
375
|
table_columns = {}
|
353
376
|
other_columns = []
|
354
377
|
|
@@ -364,7 +387,8 @@ module Cassandra
|
|
364
387
|
column_alias = column_aliases.fetch(i) { "column#{i + 1}" }
|
365
388
|
type, order, is_frozen = comparator.results.fetch(i)
|
366
389
|
|
367
|
-
clustering_columns[i] =
|
390
|
+
clustering_columns[i] =
|
391
|
+
Column.new(column_alias, type, order, nil, false, is_frozen)
|
368
392
|
clustering_order[i] = order
|
369
393
|
end
|
370
394
|
|
@@ -373,8 +397,10 @@ module Cassandra
|
|
373
397
|
value_alias ||= 'value'
|
374
398
|
|
375
399
|
unless value_alias.empty?
|
376
|
-
type, order, is_frozen =
|
377
|
-
|
400
|
+
type, order, is_frozen =
|
401
|
+
@type_parser.parse(table_data['default_validator']).results.first
|
402
|
+
other_columns <<
|
403
|
+
Column.new(value_alias, type, order, nil, false, is_frozen)
|
378
404
|
end
|
379
405
|
end
|
380
406
|
|
@@ -394,22 +420,30 @@ module Cassandra
|
|
394
420
|
table_columns[column.name] = column
|
395
421
|
end
|
396
422
|
|
397
|
-
Table.new(keyspace_name,
|
398
|
-
|
423
|
+
Table.new(keyspace_name,
|
424
|
+
table_name,
|
425
|
+
partition_key,
|
426
|
+
clustering_columns,
|
427
|
+
table_columns,
|
428
|
+
table_options,
|
429
|
+
clustering_order)
|
399
430
|
end
|
400
431
|
|
401
432
|
def create_column(column_data)
|
402
433
|
name = column_data['column_name']
|
403
434
|
is_static = (column_data['type'] == 'STATIC')
|
404
|
-
type, order, is_frozen =
|
435
|
+
type, order, is_frozen =
|
436
|
+
@type_parser.parse(column_data['validator']).results.first
|
405
437
|
|
406
438
|
if column_data['index_type'].nil?
|
407
439
|
index = nil
|
408
|
-
elsif column_data['index_type'].to_s.upcase == 'CUSTOM' ||
|
440
|
+
elsif column_data['index_type'].to_s.upcase == 'CUSTOM' ||
|
441
|
+
!column_data['index_options']
|
409
442
|
index = Column::Index.new(column_data['index_name'])
|
410
443
|
else
|
411
444
|
options = ::JSON.load(column_data['index_options'])
|
412
|
-
index = Column::Index.new(column_data['index_name'],
|
445
|
+
index = Column::Index.new(column_data['index_name'],
|
446
|
+
options && options['class_name'])
|
413
447
|
end
|
414
448
|
|
415
449
|
Column.new(name, type, order, index, is_static, is_frozen)
|
@@ -424,7 +458,10 @@ module Cassandra
|
|
424
458
|
|
425
459
|
def create_table_options(table_data, compaction_strategy, is_compact)
|
426
460
|
compression_parameters = ::JSON.load(table_data['compression_parameters'])
|
427
|
-
|
461
|
+
if compression_parameters['sstable_compression']
|
462
|
+
compression_parameters['sstable_compression'].
|
463
|
+
slice!(COMPRESSION_PACKAGE_PREFIX)
|
464
|
+
end
|
428
465
|
Table::Options.new(
|
429
466
|
table_data['comment'],
|
430
467
|
table_data['read_repair_chance'],
|
@@ -448,11 +485,20 @@ module Cassandra
|
|
448
485
|
end
|
449
486
|
|
450
487
|
class V2_0_x < V1_2_x
|
451
|
-
SELECT_KEYSPACE =
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
488
|
+
SELECT_KEYSPACE =
|
489
|
+
'SELECT * FROM system.schema_keyspaces WHERE keyspace_name = ?'.freeze
|
490
|
+
SELECT_KEYSPACE_TABLES =
|
491
|
+
'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = ?'.freeze
|
492
|
+
SELECT_KEYSPACE_COLUMNS =
|
493
|
+
'SELECT * FROM system.schema_columns WHERE keyspace_name = ?'.freeze
|
494
|
+
SELECT_TABLE =
|
495
|
+
'SELECT * ' \
|
496
|
+
'FROM system.schema_columnfamilies ' \
|
497
|
+
'WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
|
498
|
+
SELECT_TABLE_COLUMNS =
|
499
|
+
'SELECT * ' \
|
500
|
+
'FROM system.schema_columns ' \
|
501
|
+
'WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
|
456
502
|
|
457
503
|
private
|
458
504
|
|
@@ -503,11 +549,18 @@ module Cassandra
|
|
503
549
|
end
|
504
550
|
|
505
551
|
compaction_strategy = create_compaction_strategy(table_data)
|
506
|
-
is_compact = (clustering_size != comparator.results.size - 1) ||
|
507
|
-
|
552
|
+
is_compact = (clustering_size != comparator.results.size - 1) ||
|
553
|
+
!comparator.collections
|
554
|
+
table_options =
|
555
|
+
create_table_options(table_data, compaction_strategy, is_compact)
|
508
556
|
|
509
|
-
Table.new(keyspace_name,
|
510
|
-
|
557
|
+
Table.new(keyspace_name,
|
558
|
+
table_name,
|
559
|
+
partition_key,
|
560
|
+
clustering_columns,
|
561
|
+
table_columns,
|
562
|
+
table_options,
|
563
|
+
clustering_order)
|
511
564
|
end
|
512
565
|
|
513
566
|
def select_keyspace(connection, keyspace_name)
|
@@ -542,7 +595,10 @@ module Cassandra
|
|
542
595
|
|
543
596
|
def create_table_options(table_data, compaction_strategy, is_compact)
|
544
597
|
compression_parameters = ::JSON.load(table_data['compression_parameters'])
|
545
|
-
|
598
|
+
if compression_parameters['sstable_compression']
|
599
|
+
compression_parameters['sstable_compression'].
|
600
|
+
slice!(COMPRESSION_PACKAGE_PREFIX)
|
601
|
+
end
|
546
602
|
Table::Options.new(
|
547
603
|
table_data['comment'],
|
548
604
|
table_data['read_repair_chance'],
|
@@ -567,8 +623,12 @@ module Cassandra
|
|
567
623
|
|
568
624
|
class V2_1_x < V2_0_x
|
569
625
|
SELECT_TYPES = 'SELECT * FROM system.schema_usertypes'.freeze
|
570
|
-
SELECT_KEYSPACE_TYPES =
|
571
|
-
|
626
|
+
SELECT_KEYSPACE_TYPES =
|
627
|
+
'SELECT * FROM system.schema_usertypes WHERE keyspace_name = ?'.freeze
|
628
|
+
SELECT_TYPE =
|
629
|
+
'SELECT * ' \
|
630
|
+
'FROM system.schema_usertypes ' \
|
631
|
+
'WHERE keyspace_name = ? AND type_name = ?'.freeze
|
572
632
|
|
573
633
|
private
|
574
634
|
|
@@ -607,7 +667,10 @@ module Cassandra
|
|
607
667
|
|
608
668
|
def create_table_options(table_data, compaction_strategy, is_compact)
|
609
669
|
compression_parameters = ::JSON.load(table_data['compression_parameters'])
|
610
|
-
|
670
|
+
if compression_parameters['sstable_compression']
|
671
|
+
compression_parameters['sstable_compression'].
|
672
|
+
slice!(COMPRESSION_PACKAGE_PREFIX)
|
673
|
+
end
|
611
674
|
Table::Options.new(
|
612
675
|
table_data['comment'],
|
613
676
|
table_data['read_repair_chance'],
|
@@ -633,12 +696,23 @@ module Cassandra
|
|
633
696
|
class V2_2_x < V2_1_x
|
634
697
|
SELECT_FUNCTIONS = 'SELECT * FROM system.schema_functions'.freeze
|
635
698
|
SELECT_AGGREGATES = 'SELECT * FROM system.schema_aggregates'.freeze
|
636
|
-
SELECT_KEYSPACE_FUNCTIONS =
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
699
|
+
SELECT_KEYSPACE_FUNCTIONS =
|
700
|
+
'SELECT * FROM system.schema_functions WHERE keyspace_name = ?'.freeze
|
701
|
+
SELECT_KEYSPACE_AGGREGATES =
|
702
|
+
'SELECT * FROM system.schema_aggregates WHERE keyspace_name = ?'.freeze
|
703
|
+
SELECT_FUNCTION =
|
704
|
+
'SELECT * ' \
|
705
|
+
'FROM system.schema_functions ' \
|
706
|
+
'WHERE keyspace_name = ? AND function_name = ? ' \
|
707
|
+
'AND argument_types = ?'.freeze
|
708
|
+
SELECT_AGGREGATE =
|
709
|
+
'SELECT * ' \
|
710
|
+
'FROM system.schema_aggregates ' \
|
711
|
+
'WHERE keyspace_name = ? AND aggregate_name = ? ' \
|
712
|
+
'AND argument_types = ?'.freeze
|
713
|
+
|
714
|
+
# parse an array of string argument types and return an array of
|
715
|
+
# [Cassandra::Type]s.
|
642
716
|
# @param connection a connection to a Cassandra node.
|
643
717
|
# @param keyspace_name [String] name of the keyspace.
|
644
718
|
# @param argument_types [Array<String>] array of argument types.
|
@@ -655,35 +729,59 @@ module Cassandra
|
|
655
729
|
keyspace_name = function_data['keyspace_name']
|
656
730
|
function_name = function_data['function_name']
|
657
731
|
function_lang = function_data['language']
|
658
|
-
function_type =
|
732
|
+
function_type =
|
733
|
+
@type_parser.parse(function_data['return_type']).results.first.first
|
659
734
|
function_body = function_data['body']
|
660
735
|
called_on_null = function_data['called_on_null_input']
|
661
736
|
|
662
737
|
arguments = []
|
663
738
|
|
664
|
-
Array(function_data['argument_names']).
|
739
|
+
Array(function_data['argument_names']).
|
740
|
+
zip(Array(function_data['argument_types'])) do |argument_name, fqcn|
|
665
741
|
argument_type = @type_parser.parse(fqcn).results.first.first
|
666
742
|
arguments << Argument.new(argument_name, argument_type)
|
667
743
|
end
|
668
744
|
|
669
|
-
Function.new(keyspace_name,
|
745
|
+
Function.new(keyspace_name,
|
746
|
+
function_name,
|
747
|
+
function_lang,
|
748
|
+
function_type,
|
749
|
+
arguments,
|
750
|
+
function_body,
|
751
|
+
called_on_null)
|
670
752
|
end
|
671
753
|
|
672
754
|
def create_aggregate(aggregate_data, functions)
|
673
755
|
keyspace_name = aggregate_data['keyspace_name']
|
674
756
|
aggregate_name = aggregate_data['aggregate_name']
|
675
|
-
aggregate_type =
|
676
|
-
|
677
|
-
|
678
|
-
|
757
|
+
aggregate_type =
|
758
|
+
@type_parser.parse(aggregate_data['return_type']).results.first.first
|
759
|
+
argument_types = aggregate_data['argument_types'].map do |fqcn|
|
760
|
+
@type_parser.parse(fqcn).results.first.first
|
761
|
+
end.freeze
|
762
|
+
state_type =
|
763
|
+
@type_parser.parse(aggregate_data['state_type']).results.first.first
|
764
|
+
initial_state = Util.encode_object(
|
765
|
+
Protocol::Coder.read_value_v4(
|
766
|
+
Protocol::CqlByteBuffer.new.append_bytes(aggregate_data['initcond']),
|
767
|
+
state_type))
|
679
768
|
|
680
769
|
# The state-function takes arguments: first the stype, then the args of the aggregate.
|
681
|
-
state_function = functions
|
770
|
+
state_function = functions.get(aggregate_data['state_func'],
|
771
|
+
[state_type].concat(argument_types))
|
682
772
|
|
683
773
|
# The final-function takes an stype argument.
|
684
|
-
final_function = functions
|
774
|
+
final_function = functions.get(aggregate_data['final_func'],
|
775
|
+
[state_type])
|
685
776
|
|
686
|
-
Aggregate.new(keyspace_name,
|
777
|
+
Aggregate.new(keyspace_name,
|
778
|
+
aggregate_name,
|
779
|
+
aggregate_type,
|
780
|
+
argument_types,
|
781
|
+
state_type,
|
782
|
+
initial_state,
|
783
|
+
state_function,
|
784
|
+
final_function)
|
687
785
|
end
|
688
786
|
|
689
787
|
def select_functions(connection)
|
@@ -729,23 +827,47 @@ module Cassandra
|
|
729
827
|
SELECT_INDEXES = "SELECT * FROM system_schema.indexes".freeze
|
730
828
|
SELECT_VIEWS = "SELECT * FROM system_schema.materialized_views".freeze
|
731
829
|
|
732
|
-
SELECT_KEYSPACE =
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
830
|
+
SELECT_KEYSPACE =
|
831
|
+
'SELECT * FROM system_schema.keyspaces WHERE keyspace_name = ?'.freeze
|
832
|
+
SELECT_KEYSPACE_TABLES =
|
833
|
+
'SELECT * FROM system_schema.tables WHERE keyspace_name = ?'.freeze
|
834
|
+
SELECT_KEYSPACE_COLUMNS =
|
835
|
+
'SELECT * FROM system_schema.columns WHERE keyspace_name = ?'.freeze
|
836
|
+
SELECT_KEYSPACE_TYPES =
|
837
|
+
"SELECT * FROM system_schema.types WHERE keyspace_name = ?".freeze
|
838
|
+
SELECT_KEYSPACE_FUNCTIONS =
|
839
|
+
'SELECT * FROM system_schema.functions WHERE keyspace_name = ?'.freeze
|
840
|
+
SELECT_KEYSPACE_AGGREGATES =
|
841
|
+
'SELECT * FROM system_schema.aggregates WHERE keyspace_name = ?'.freeze
|
842
|
+
|
843
|
+
SELECT_TABLE =
|
844
|
+
'SELECT * ' \
|
845
|
+
'FROM system_schema.tables ' \
|
846
|
+
'WHERE keyspace_name = ? AND table_name = ?'.freeze
|
847
|
+
SELECT_TABLE_COLUMNS =
|
848
|
+
'SELECT * ' \
|
849
|
+
'FROM system_schema.columns ' \
|
850
|
+
'WHERE keyspace_name = ? AND table_name = ?'.freeze
|
851
|
+
|
852
|
+
SELECT_TYPE =
|
853
|
+
'SELECT * ' \
|
854
|
+
'FROM system_schema.types ' \
|
855
|
+
'WHERE keyspace_name = ? AND type_name = ?'.freeze
|
856
|
+
|
857
|
+
SELECT_FUNCTION =
|
858
|
+
'SELECT * ' \
|
859
|
+
'FROM system_schema.functions ' \
|
860
|
+
'WHERE keyspace_name = ? AND function_name = ? ' \
|
861
|
+
'AND argument_types = ?'.freeze
|
862
|
+
|
863
|
+
SELECT_AGGREGATE =
|
864
|
+
'SELECT * ' \
|
865
|
+
'FROM system_schema.aggregates ' \
|
866
|
+
'WHERE keyspace_name = ? AND aggregate_name = ? ' \
|
867
|
+
'AND argument_types = ?'.freeze
|
868
|
+
|
869
|
+
# parse an array of string argument types and return an array of
|
870
|
+
# [Cassandra::Type]s.
|
749
871
|
# @param connection a connection to a Cassandra node.
|
750
872
|
# @param keyspace_name [String] name of the keyspace.
|
751
873
|
# @param argument_types [Array<String>] array of argument types.
|
@@ -860,29 +982,50 @@ module Cassandra
|
|
860
982
|
|
861
983
|
arguments = []
|
862
984
|
|
863
|
-
function_data['argument_names'].
|
864
|
-
|
985
|
+
function_data['argument_names'].
|
986
|
+
zip(function_data['argument_types']) do |argument_name, argument_type|
|
987
|
+
arguments << Argument.new(argument_name,
|
988
|
+
@type_parser.parse(argument_type, types).first)
|
865
989
|
end
|
866
990
|
|
867
|
-
Function.new(keyspace_name,
|
991
|
+
Function.new(keyspace_name,
|
992
|
+
function_name,
|
993
|
+
function_lang,
|
994
|
+
function_type,
|
995
|
+
arguments,
|
996
|
+
function_body,
|
997
|
+
called_on_null)
|
868
998
|
end
|
869
999
|
|
870
1000
|
def create_aggregate(aggregate_data, functions, types = nil)
|
871
1001
|
keyspace_name = aggregate_data['keyspace_name']
|
872
1002
|
aggregate_name = aggregate_data['aggregate_name']
|
873
1003
|
types ||= @schema.keyspace(keyspace_name).send(:raw_types)
|
874
|
-
aggregate_type =
|
875
|
-
|
1004
|
+
aggregate_type =
|
1005
|
+
@type_parser.parse(aggregate_data['return_type'], types).first
|
1006
|
+
argument_types = aggregate_data['argument_types'].map do |argument_type|
|
1007
|
+
@type_parser.parse(argument_type, types).first
|
1008
|
+
end.freeze
|
876
1009
|
state_type = @type_parser.parse(aggregate_data['state_type'], types).first
|
877
1010
|
initial_state = aggregate_data['initcond'] || 'null'
|
878
1011
|
|
879
|
-
# The state-function takes arguments: first the stype, then the args of the
|
880
|
-
|
1012
|
+
# The state-function takes arguments: first the stype, then the args of the
|
1013
|
+
# aggregate.
|
1014
|
+
state_function = functions.get(aggregate_data['state_func'],
|
1015
|
+
[state_type].concat(argument_types))
|
881
1016
|
|
882
1017
|
# The final-function takes an stype argument.
|
883
|
-
final_function = functions
|
1018
|
+
final_function = functions.get(aggregate_data['final_func'],
|
1019
|
+
[state_type])
|
884
1020
|
|
885
|
-
Aggregate.new(keyspace_name,
|
1021
|
+
Aggregate.new(keyspace_name,
|
1022
|
+
aggregate_name,
|
1023
|
+
aggregate_type,
|
1024
|
+
argument_types,
|
1025
|
+
state_type,
|
1026
|
+
initial_state,
|
1027
|
+
state_function,
|
1028
|
+
final_function)
|
886
1029
|
end
|
887
1030
|
|
888
1031
|
def create_types(rows_types, types)
|
@@ -930,17 +1073,15 @@ module Cassandra
|
|
930
1073
|
types = ::Hash.new
|
931
1074
|
create_types(rows_types, types)
|
932
1075
|
|
933
|
-
#
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
func = create_function(row, types)
|
938
|
-
collector[[func.name, func.argument_types]] = func
|
1076
|
+
# Create a FunctionCollection for the functions and aggregates.
|
1077
|
+
functions = Cassandra::FunctionCollection.new
|
1078
|
+
rows_functions.each do |row|
|
1079
|
+
functions.add_or_update(create_function(row, types))
|
939
1080
|
end
|
940
1081
|
|
941
|
-
aggregates =
|
942
|
-
|
943
|
-
|
1082
|
+
aggregates = Cassandra::FunctionCollection.new
|
1083
|
+
rows_aggregates.each do |row|
|
1084
|
+
aggregates.add_or_update(create_aggregate(row, functions, types))
|
944
1085
|
end
|
945
1086
|
|
946
1087
|
lookup_columns = map_rows_by(rows_columns, 'table_name')
|
@@ -949,8 +1090,13 @@ module Cassandra
|
|
949
1090
|
tables[table_name] = create_table(row, lookup_columns[table_name], types)
|
950
1091
|
end
|
951
1092
|
|
952
|
-
Keyspace.new(keyspace_name,
|
953
|
-
|
1093
|
+
Keyspace.new(keyspace_name,
|
1094
|
+
keyspace_data['durable_writes'],
|
1095
|
+
replication,
|
1096
|
+
tables,
|
1097
|
+
types,
|
1098
|
+
functions,
|
1099
|
+
aggregates)
|
954
1100
|
end
|
955
1101
|
|
956
1102
|
def create_replication(keyspace_data)
|
@@ -969,7 +1115,9 @@ module Cassandra
|
|
969
1115
|
|
970
1116
|
def create_table_options(table_data, compaction_strategy, is_compact)
|
971
1117
|
compression = table_data['compression']
|
972
|
-
|
1118
|
+
if compression['class']
|
1119
|
+
compression['class'].slice!(COMPRESSION_PACKAGE_PREFIX)
|
1120
|
+
end
|
973
1121
|
|
974
1122
|
Table::Options.new(
|
975
1123
|
table_data['comment'],
|
@@ -1054,10 +1202,16 @@ module Cassandra
|
|
1054
1202
|
end
|
1055
1203
|
|
1056
1204
|
compaction_strategy = create_compaction_strategy(table_data)
|
1057
|
-
table_options =
|
1205
|
+
table_options =
|
1206
|
+
create_table_options(table_data, compaction_strategy, is_compact)
|
1058
1207
|
|
1059
|
-
Table.new(keyspace_name,
|
1060
|
-
|
1208
|
+
Table.new(keyspace_name,
|
1209
|
+
table_name,
|
1210
|
+
partition_key,
|
1211
|
+
clustering_columns,
|
1212
|
+
table_columns,
|
1213
|
+
table_options,
|
1214
|
+
clustering_order)
|
1061
1215
|
end
|
1062
1216
|
end
|
1063
1217
|
|
@@ -1130,13 +1284,16 @@ module Cassandra
|
|
1130
1284
|
return Ione::Future.failed(e)
|
1131
1285
|
end
|
1132
1286
|
|
1133
|
-
# parse an array of string argument types and return an array of
|
1287
|
+
# parse an array of string argument types and return an array of
|
1288
|
+
# [Cassandra::Type]s.
|
1134
1289
|
# @param connection a connection to a Cassandra node.
|
1135
1290
|
# @param keyspace_name [String] name of the keyspace.
|
1136
1291
|
# @param argument_types [Array<String>] array of argument types.
|
1137
1292
|
# @return [Array<Cassandra::Type>] array of parsed types.
|
1138
1293
|
def parse_argument_types(connection, keyspace_name, argument_types)
|
1139
|
-
find_fetcher(connection).parse_argument_types(connection,
|
1294
|
+
find_fetcher(connection).parse_argument_types(connection,
|
1295
|
+
keyspace_name,
|
1296
|
+
argument_types)
|
1140
1297
|
end
|
1141
1298
|
|
1142
1299
|
private
|