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.
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