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.
Files changed (131) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +90 -38
  3. data/ext/cassandra_murmur3/cassandra_murmur3.c +1 -1
  4. data/lib/cassandra.rb +327 -130
  5. data/lib/cassandra/address_resolution.rb +1 -1
  6. data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +1 -1
  7. data/lib/cassandra/address_resolution/policies/none.rb +1 -1
  8. data/lib/cassandra/aggregate.rb +21 -7
  9. data/lib/cassandra/argument.rb +2 -2
  10. data/lib/cassandra/auth.rb +4 -4
  11. data/lib/cassandra/auth/providers.rb +1 -1
  12. data/lib/cassandra/auth/providers/password.rb +9 -5
  13. data/lib/cassandra/cassandra_logger.rb +80 -0
  14. data/lib/cassandra/cluster.rb +38 -9
  15. data/lib/cassandra/cluster/client.rb +801 -205
  16. data/lib/cassandra/cluster/connection_pool.rb +2 -2
  17. data/lib/cassandra/cluster/connector.rb +74 -25
  18. data/lib/cassandra/cluster/control_connection.rb +217 -82
  19. data/lib/cassandra/cluster/failed_connection.rb +1 -1
  20. data/lib/cassandra/cluster/metadata.rb +12 -4
  21. data/lib/cassandra/cluster/options.rb +60 -11
  22. data/lib/cassandra/cluster/registry.rb +69 -16
  23. data/lib/cassandra/cluster/schema.rb +25 -7
  24. data/lib/cassandra/cluster/schema/cql_type_parser.rb +15 -10
  25. data/lib/cassandra/cluster/schema/fetchers.rb +263 -106
  26. data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +41 -36
  27. data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
  28. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +3 -3
  29. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +1 -1
  30. data/lib/cassandra/cluster/schema/partitioners/random.rb +1 -1
  31. data/lib/cassandra/cluster/schema/replication_strategies.rb +1 -1
  32. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +19 -18
  33. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +1 -1
  34. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +1 -1
  35. data/lib/cassandra/column.rb +3 -3
  36. data/lib/cassandra/compression.rb +1 -1
  37. data/lib/cassandra/compression/compressors/lz4.rb +4 -3
  38. data/lib/cassandra/compression/compressors/snappy.rb +4 -3
  39. data/lib/cassandra/driver.rb +103 -41
  40. data/lib/cassandra/errors.rb +265 -30
  41. data/lib/cassandra/execution/info.rb +16 -5
  42. data/lib/cassandra/execution/options.rb +99 -54
  43. data/lib/cassandra/execution/trace.rb +16 -9
  44. data/lib/cassandra/executors.rb +1 -1
  45. data/lib/cassandra/function.rb +19 -13
  46. data/lib/cassandra/function_collection.rb +85 -0
  47. data/lib/cassandra/future.rb +106 -48
  48. data/lib/cassandra/host.rb +10 -4
  49. data/lib/cassandra/keyspace.rb +90 -33
  50. data/lib/cassandra/listener.rb +1 -1
  51. data/lib/cassandra/load_balancing.rb +2 -2
  52. data/lib/cassandra/load_balancing/policies.rb +1 -1
  53. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +18 -18
  54. data/lib/cassandra/load_balancing/policies/round_robin.rb +1 -1
  55. data/lib/cassandra/load_balancing/policies/token_aware.rb +15 -13
  56. data/lib/cassandra/load_balancing/policies/white_list.rb +11 -5
  57. data/lib/cassandra/null_logger.rb +27 -6
  58. data/lib/cassandra/protocol.rb +1 -1
  59. data/lib/cassandra/protocol/coder.rb +78 -39
  60. data/lib/cassandra/protocol/cql_byte_buffer.rb +50 -33
  61. data/lib/cassandra/protocol/cql_protocol_handler.rb +44 -45
  62. data/lib/cassandra/protocol/request.rb +2 -2
  63. data/lib/cassandra/protocol/requests/auth_response_request.rb +3 -3
  64. data/lib/cassandra/protocol/requests/batch_request.rb +16 -7
  65. data/lib/cassandra/protocol/requests/credentials_request.rb +3 -3
  66. data/lib/cassandra/protocol/requests/execute_request.rb +41 -20
  67. data/lib/cassandra/protocol/requests/options_request.rb +1 -1
  68. data/lib/cassandra/protocol/requests/prepare_request.rb +5 -5
  69. data/lib/cassandra/protocol/requests/query_request.rb +27 -22
  70. data/lib/cassandra/protocol/requests/register_request.rb +2 -2
  71. data/lib/cassandra/protocol/requests/startup_request.rb +6 -4
  72. data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
  73. data/lib/cassandra/protocol/response.rb +2 -2
  74. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +12 -2
  75. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +1 -1
  76. data/lib/cassandra/protocol/responses/auth_success_response.rb +1 -1
  77. data/lib/cassandra/protocol/responses/authenticate_response.rb +1 -1
  78. data/lib/cassandra/protocol/responses/error_response.rb +101 -13
  79. data/lib/cassandra/protocol/responses/event_response.rb +1 -1
  80. data/lib/cassandra/protocol/responses/function_failure_error_response.rb +13 -2
  81. data/lib/cassandra/protocol/responses/prepared_result_response.rb +11 -5
  82. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +14 -9
  83. data/lib/cassandra/protocol/responses/read_failure_error_response.rb +26 -4
  84. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +22 -3
  85. data/lib/cassandra/protocol/responses/ready_response.rb +3 -3
  86. data/lib/cassandra/protocol/responses/result_response.rb +4 -2
  87. data/lib/cassandra/protocol/responses/rows_result_response.rb +5 -3
  88. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +5 -4
  89. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +16 -9
  90. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +2 -2
  91. data/lib/cassandra/protocol/responses/status_change_event_response.rb +2 -2
  92. data/lib/cassandra/protocol/responses/supported_response.rb +1 -1
  93. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +1 -1
  94. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +20 -3
  95. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +11 -2
  96. data/lib/cassandra/protocol/responses/void_result_response.rb +1 -1
  97. data/lib/cassandra/protocol/responses/write_failure_error_response.rb +26 -4
  98. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +22 -3
  99. data/lib/cassandra/protocol/v1.rb +101 -36
  100. data/lib/cassandra/protocol/v3.rb +124 -51
  101. data/lib/cassandra/protocol/v4.rb +172 -68
  102. data/lib/cassandra/reconnection.rb +1 -1
  103. data/lib/cassandra/reconnection/policies.rb +1 -1
  104. data/lib/cassandra/reconnection/policies/constant.rb +2 -4
  105. data/lib/cassandra/reconnection/policies/exponential.rb +6 -6
  106. data/lib/cassandra/result.rb +53 -19
  107. data/lib/cassandra/retry.rb +8 -8
  108. data/lib/cassandra/retry/policies.rb +1 -1
  109. data/lib/cassandra/retry/policies/default.rb +1 -1
  110. data/lib/cassandra/retry/policies/downgrading_consistency.rb +7 -3
  111. data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
  112. data/lib/cassandra/session.rb +22 -16
  113. data/lib/cassandra/statement.rb +1 -1
  114. data/lib/cassandra/statements.rb +1 -1
  115. data/lib/cassandra/statements/batch.rb +16 -10
  116. data/lib/cassandra/statements/bound.rb +10 -3
  117. data/lib/cassandra/statements/prepared.rb +59 -15
  118. data/lib/cassandra/statements/simple.rb +23 -10
  119. data/lib/cassandra/statements/void.rb +1 -1
  120. data/lib/cassandra/table.rb +79 -30
  121. data/lib/cassandra/time.rb +11 -6
  122. data/lib/cassandra/time_uuid.rb +7 -7
  123. data/lib/cassandra/tuple.rb +16 -8
  124. data/lib/cassandra/types.rb +20 -9
  125. data/lib/cassandra/udt.rb +32 -36
  126. data/lib/cassandra/util.rb +20 -13
  127. data/lib/cassandra/uuid.rb +22 -15
  128. data/lib/cassandra/uuid/generator.rb +7 -5
  129. data/lib/cassandra/version.rb +2 -2
  130. data/lib/datastax/cassandra.rb +1 -1
  131. metadata +5 -3
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2015 DataStax, Inc.
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.
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2015 DataStax, Inc.
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, cluster_schema, schema_partitioners, replication_strategies, default_replication_strategy)
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 = partitioner.parse_token(token) rescue next
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 do
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-2015 DataStax, Inc.
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 :credentials, :auth_provider, :compressor, :port,
24
- :connect_timeout, :ssl, :heartbeat_interval, :idle_timeout,
25
- :schema_refresh_delay, :schema_refresh_timeout
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(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node, heartbeat_interval, idle_timeout, synchronize_schema, schema_refresh_delay, schema_refresh_timeout, client_timestamps, nodelay)
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
- (@protocol_version > 2) ? 1 : @connections_per_local_node
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
- (@protocol_version > 2) ? 1 : @connections_per_remote_node
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-2015 DataStax, Inc.
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 :hosts :each_host
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.has_key?(address.to_s)
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 considered lost and found")
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.has_key?(ip)
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, data['host_id'], data['rack'], data['data_center'], data['release_version'], Array(data['tokens']).freeze, :up)
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, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :up)
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
- listener.host_up(host) rescue nil
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, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :down)
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
- listener.host_down(host) rescue nil
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, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :down)
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
- listener.host_down(host) rescue nil
189
- listener.host_lost(host) rescue nil
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
- listener.host_lost(host) rescue nil
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
- listener.host_found(host) rescue nil
203
- listener.host_up(host) rescue nil
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-2015 DataStax, Inc.
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
- keyspace_name, table_name, _ = metadata.first
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, keyspace|
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 :keyspaces :each_keyspace
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
- listener.keyspace_created(keyspace) rescue nil
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
- listener.keyspace_changed(keyspace) rescue nil
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
- listener.keyspace_dropped(keyspace) rescue nil
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-2015 DataStax, Inc.
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 Cassandra::Types.map(*node.children.map { |t| lookup_type(t, types)})
68
- when 'set' then Cassandra::Types.set(lookup_type(node.children.first, types))
69
- when 'list' then Cassandra::Types.list(lookup_type(node.children.first, types))
70
- when 'tuple' then Cassandra::Types.tuple(*node.children.map { |t| lookup_type(t, types)})
71
- when 'empty' then Cassandra::Types.custom('org.apache.cassandra.db.marshal.EmptyType')
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) { raise IncompleteTypeError, "unable to lookup type #{node.name.inspect}" }
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-2015 DataStax, Inc.
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).map do |rows_functions|
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).map do |rows_aggregates|
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).send(:raw_functions))
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(Protocol::QueryRequest.new(cql, params, types, :one)).map do |r|
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 = 'SELECT * FROM system.schema_keyspaces WHERE keyspace_name = \'%s\''.freeze
229
- SELECT_KEYSPACE_TABLES = 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = \'%s\''.freeze
230
- SELECT_KEYSPACE_COLUMNS = 'SELECT * FROM system.schema_columns WHERE keyspace_name = \'%s\''.freeze
231
- SELECT_TABLE = 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
232
- SELECT_TABLE_COLUMNS = 'SELECT * FROM system.schema_columns WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
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, SELECT_TABLE_COLUMNS % [keyspace_name, table_name])
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
- # We want the functions hash to be keyed on [name, arg-types-list].
291
- # Similarly for the aggregates hash.
292
-
293
- functions = rows_functions.each_with_object({}) do |row, collector|
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 = rows_aggregates.each_with_object({}) do |row, collector|
299
- agg = create_aggregate(row, functions)
300
- collector[[agg.name, agg.argument_types]] = agg
301
- end
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, keyspace_data['durable_writes'],
310
- replication, tables, types, functions, aggregates)
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 && comparator.results.last.first == Cassandra::Types.varchar
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 = create_table_options(table_data, compaction_strategy, is_compact)
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] = Column.new(column_alias, type, order, nil, false, is_frozen)
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 = @type_parser.parse(table_data['default_validator']).results.first
377
- other_columns << Column.new(value_alias, type, order, nil, false, is_frozen)
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, table_name, partition_key, clustering_columns,
398
- table_columns, table_options, clustering_order)
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 = @type_parser.parse(column_data['validator']).results.first
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' || !column_data['index_options']
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'], options && options['class_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
- compression_parameters['sstable_compression'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression_parameters['sstable_compression']
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 = 'SELECT * FROM system.schema_keyspaces WHERE keyspace_name = ?'.freeze
452
- SELECT_KEYSPACE_TABLES = 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = ?'.freeze
453
- SELECT_KEYSPACE_COLUMNS = 'SELECT * FROM system.schema_columns WHERE keyspace_name = ?'.freeze
454
- SELECT_TABLE = 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
455
- SELECT_TABLE_COLUMNS = 'SELECT * FROM system.schema_columns WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
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) || !comparator.collections
507
- table_options = create_table_options(table_data, compaction_strategy, is_compact)
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, table_name, partition_key, clustering_columns,
510
- table_columns, table_options, clustering_order)
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
- compression_parameters['sstable_compression'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression_parameters['sstable_compression']
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 = 'SELECT * FROM system.schema_usertypes WHERE keyspace_name = ?'.freeze
571
- SELECT_TYPE = 'SELECT * FROM system.schema_usertypes WHERE keyspace_name = ? AND type_name = ?'.freeze
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
- compression_parameters['sstable_compression'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression_parameters['sstable_compression']
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 = 'SELECT * FROM system.schema_functions WHERE keyspace_name = ?'.freeze
637
- SELECT_KEYSPACE_AGGREGATES = 'SELECT * FROM system.schema_aggregates WHERE keyspace_name = ?'.freeze
638
- SELECT_FUNCTION = 'SELECT * FROM system.schema_functions WHERE keyspace_name = ? AND function_name = ? AND argument_types = ?'.freeze
639
- SELECT_AGGREGATE = 'SELECT * FROM system.schema_aggregates WHERE keyspace_name = ? AND aggregate_name = ? AND argument_types = ?'.freeze
640
-
641
- # parse an array of string argument types and return an array of [Cassandra::Type]s.
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 = @type_parser.parse(function_data['return_type']).results.first.first
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']).zip(Array(function_data['argument_types'])) do |argument_name, fqcn|
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, function_name, function_lang, function_type, arguments, function_body, called_on_null)
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 = @type_parser.parse(aggregate_data['return_type']).results.first.first
676
- argument_types = aggregate_data['argument_types'].map {|fqcn| @type_parser.parse(fqcn).results.first.first}.freeze
677
- state_type = @type_parser.parse(aggregate_data['state_type']).results.first.first
678
- initial_state = Util.encode_object(Protocol::Coder.read_value_v4(Protocol::CqlByteBuffer.new.append_bytes(aggregate_data['initcond']), state_type))
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[[aggregate_data['state_func'], [state_type].concat(argument_types)]]
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[[aggregate_data['final_func'], [state_type]]]
774
+ final_function = functions.get(aggregate_data['final_func'],
775
+ [state_type])
685
776
 
686
- Aggregate.new(keyspace_name, aggregate_name, aggregate_type, argument_types, state_type, initial_state, state_function, final_function)
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 = 'SELECT * FROM system_schema.keyspaces WHERE keyspace_name = ?'.freeze
733
- SELECT_KEYSPACE_TABLES = 'SELECT * FROM system_schema.tables WHERE keyspace_name = ?'.freeze
734
- SELECT_KEYSPACE_COLUMNS = 'SELECT * FROM system_schema.columns WHERE keyspace_name = ?'.freeze
735
- SELECT_KEYSPACE_TYPES = "SELECT * FROM system_schema.types WHERE keyspace_name = ?".freeze
736
- SELECT_KEYSPACE_FUNCTIONS = 'SELECT * FROM system_schema.functions WHERE keyspace_name = ?'.freeze
737
- SELECT_KEYSPACE_AGGREGATES = 'SELECT * FROM system_schema.aggregates WHERE keyspace_name = ?'.freeze
738
-
739
- SELECT_TABLE = 'SELECT * FROM system_schema.tables WHERE keyspace_name = ? AND table_name = ?'.freeze
740
- SELECT_TABLE_COLUMNS = 'SELECT * FROM system_schema.columns WHERE keyspace_name = ? AND table_name = ?'.freeze
741
-
742
- SELECT_TYPE = 'SELECT * FROM system_schema.types WHERE keyspace_name = ? AND type_name = ?'.freeze
743
-
744
- SELECT_FUNCTION = 'SELECT * FROM system_schema.functions WHERE keyspace_name = ? AND function_name = ? AND argument_types = ?'.freeze
745
-
746
- SELECT_AGGREGATE = 'SELECT * FROM system_schema.aggregates WHERE keyspace_name = ? AND aggregate_name = ? AND argument_types = ?'.freeze
747
-
748
- # parse an array of string argument types and return an array of [Cassandra::Type]s.
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'].zip(function_data['argument_types']) do |argument_name, argument_type|
864
- arguments << Argument.new(argument_name, @type_parser.parse(argument_type, types).first)
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, function_name, function_lang, function_type, arguments, function_body, called_on_null)
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 = @type_parser.parse(aggregate_data['return_type'], types).first
875
- argument_types = aggregate_data['argument_types'].map {|argument_type| @type_parser.parse(argument_type, types).first}.freeze
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 aggregate.
880
- state_function = functions[[aggregate_data['state_func'], [state_type].concat(argument_types)]]
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[[aggregate_data['final_func'], [state_type]]]
1018
+ final_function = functions.get(aggregate_data['final_func'],
1019
+ [state_type])
884
1020
 
885
- Aggregate.new(keyspace_name, aggregate_name, aggregate_type, argument_types, state_type, initial_state, state_function, final_function)
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
- # We want the functions hash to be keyed on [name, arg-types-list].
934
- # Similarly for the aggregates hash.
935
-
936
- functions = rows_functions.each_with_object({}) do |row, collector|
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 = rows_aggregates.each_with_object({}) do |row, collector|
942
- agg = create_aggregate(row, functions, types)
943
- collector[[agg.name, agg.argument_types]] = agg
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, keyspace_data['durable_writes'],
953
- replication, tables, types, functions, aggregates)
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
- compression['class'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression['class']
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 = create_table_options(table_data, compaction_strategy, is_compact)
1205
+ table_options =
1206
+ create_table_options(table_data, compaction_strategy, is_compact)
1058
1207
 
1059
- Table.new(keyspace_name, table_name, partition_key, clustering_columns,
1060
- table_columns, table_options, clustering_order)
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 [Cassandra::Type]s.
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, keyspace_name, argument_types)
1294
+ find_fetcher(connection).parse_argument_types(connection,
1295
+ keyspace_name,
1296
+ argument_types)
1140
1297
  end
1141
1298
 
1142
1299
  private