cassandra-driver 3.0.0.beta.1 → 3.0.0.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|