cassandra-driver 3.0.0.beta.1-java → 3.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +106 -39
  3. data/lib/cassandra.rb +396 -148
  4. data/lib/cassandra/address_resolution.rb +1 -1
  5. data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +1 -1
  6. data/lib/cassandra/address_resolution/policies/none.rb +1 -1
  7. data/lib/cassandra/aggregate.rb +21 -7
  8. data/lib/cassandra/argument.rb +2 -2
  9. data/lib/cassandra/attr_boolean.rb +33 -0
  10. data/lib/cassandra/auth.rb +6 -5
  11. data/lib/cassandra/auth/providers.rb +1 -1
  12. data/lib/cassandra/auth/providers/password.rb +5 -13
  13. data/lib/cassandra/cassandra_logger.rb +80 -0
  14. data/lib/cassandra/cluster.rb +49 -9
  15. data/lib/cassandra/cluster/client.rb +835 -209
  16. data/lib/cassandra/cluster/connection_pool.rb +2 -2
  17. data/lib/cassandra/cluster/connector.rb +86 -27
  18. data/lib/cassandra/cluster/control_connection.rb +222 -95
  19. data/lib/cassandra/cluster/failed_connection.rb +1 -1
  20. data/lib/cassandra/cluster/metadata.rb +14 -8
  21. data/lib/cassandra/cluster/options.rb +68 -22
  22. data/lib/cassandra/cluster/registry.rb +81 -17
  23. data/lib/cassandra/cluster/schema.rb +70 -8
  24. data/lib/cassandra/cluster/schema/cql_type_parser.rb +15 -10
  25. data/lib/cassandra/cluster/schema/fetchers.rb +601 -241
  26. data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +39 -38
  27. data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
  28. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +6 -8
  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 +4 -23
  36. data/lib/cassandra/column_container.rb +322 -0
  37. data/lib/cassandra/compression.rb +1 -1
  38. data/lib/cassandra/compression/compressors/lz4.rb +7 -8
  39. data/lib/cassandra/compression/compressors/snappy.rb +4 -3
  40. data/lib/cassandra/driver.rb +107 -46
  41. data/lib/cassandra/errors.rb +303 -52
  42. data/lib/cassandra/execution/info.rb +16 -5
  43. data/lib/cassandra/execution/options.rb +102 -55
  44. data/lib/cassandra/execution/trace.rb +16 -9
  45. data/lib/cassandra/executors.rb +1 -1
  46. data/lib/cassandra/function.rb +19 -13
  47. data/lib/cassandra/function_collection.rb +85 -0
  48. data/lib/cassandra/future.rb +101 -49
  49. data/lib/cassandra/host.rb +25 -5
  50. data/lib/cassandra/index.rb +118 -0
  51. data/lib/cassandra/keyspace.rb +169 -33
  52. data/lib/cassandra/listener.rb +1 -1
  53. data/lib/cassandra/load_balancing.rb +2 -2
  54. data/lib/cassandra/load_balancing/policies.rb +1 -1
  55. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +39 -25
  56. data/lib/cassandra/load_balancing/policies/round_robin.rb +8 -1
  57. data/lib/cassandra/load_balancing/policies/token_aware.rb +22 -13
  58. data/lib/cassandra/load_balancing/policies/white_list.rb +18 -5
  59. data/lib/cassandra/materialized_view.rb +90 -0
  60. data/lib/cassandra/null_logger.rb +27 -6
  61. data/lib/cassandra/protocol.rb +1 -1
  62. data/lib/cassandra/protocol/coder.rb +81 -42
  63. data/lib/cassandra/protocol/cql_byte_buffer.rb +58 -44
  64. data/lib/cassandra/protocol/cql_protocol_handler.rb +57 -54
  65. data/lib/cassandra/protocol/request.rb +6 -7
  66. data/lib/cassandra/protocol/requests/auth_response_request.rb +3 -3
  67. data/lib/cassandra/protocol/requests/batch_request.rb +17 -8
  68. data/lib/cassandra/protocol/requests/credentials_request.rb +3 -3
  69. data/lib/cassandra/protocol/requests/execute_request.rb +39 -20
  70. data/lib/cassandra/protocol/requests/options_request.rb +1 -1
  71. data/lib/cassandra/protocol/requests/prepare_request.rb +5 -5
  72. data/lib/cassandra/protocol/requests/query_request.rb +28 -23
  73. data/lib/cassandra/protocol/requests/register_request.rb +2 -2
  74. data/lib/cassandra/protocol/requests/startup_request.rb +8 -8
  75. data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
  76. data/lib/cassandra/protocol/response.rb +3 -4
  77. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +12 -2
  78. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +4 -5
  79. data/lib/cassandra/protocol/responses/auth_success_response.rb +4 -5
  80. data/lib/cassandra/protocol/responses/authenticate_response.rb +4 -5
  81. data/lib/cassandra/protocol/responses/error_response.rb +104 -17
  82. data/lib/cassandra/protocol/responses/event_response.rb +3 -4
  83. data/lib/cassandra/protocol/responses/function_failure_error_response.rb +13 -2
  84. data/lib/cassandra/protocol/responses/prepared_result_response.rb +14 -9
  85. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +14 -9
  86. data/lib/cassandra/protocol/responses/read_failure_error_response.rb +26 -4
  87. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +22 -3
  88. data/lib/cassandra/protocol/responses/ready_response.rb +6 -7
  89. data/lib/cassandra/protocol/responses/result_response.rb +11 -10
  90. data/lib/cassandra/protocol/responses/rows_result_response.rb +8 -7
  91. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +8 -8
  92. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +19 -13
  93. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +5 -6
  94. data/lib/cassandra/protocol/responses/status_change_event_response.rb +5 -6
  95. data/lib/cassandra/protocol/responses/supported_response.rb +4 -5
  96. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +4 -5
  97. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +20 -3
  98. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +11 -2
  99. data/lib/cassandra/protocol/responses/void_result_response.rb +4 -5
  100. data/lib/cassandra/protocol/responses/write_failure_error_response.rb +26 -4
  101. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +22 -3
  102. data/lib/cassandra/protocol/v1.rb +98 -37
  103. data/lib/cassandra/protocol/v3.rb +121 -50
  104. data/lib/cassandra/protocol/v4.rb +172 -68
  105. data/lib/cassandra/reconnection.rb +1 -1
  106. data/lib/cassandra/reconnection/policies.rb +1 -1
  107. data/lib/cassandra/reconnection/policies/constant.rb +2 -4
  108. data/lib/cassandra/reconnection/policies/exponential.rb +6 -6
  109. data/lib/cassandra/result.rb +55 -20
  110. data/lib/cassandra/retry.rb +8 -8
  111. data/lib/cassandra/retry/policies.rb +1 -1
  112. data/lib/cassandra/retry/policies/default.rb +1 -1
  113. data/lib/cassandra/retry/policies/downgrading_consistency.rb +4 -2
  114. data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
  115. data/lib/cassandra/session.rb +24 -16
  116. data/lib/cassandra/statement.rb +1 -1
  117. data/lib/cassandra/statements.rb +1 -1
  118. data/lib/cassandra/statements/batch.rb +16 -10
  119. data/lib/cassandra/statements/bound.rb +10 -3
  120. data/lib/cassandra/statements/prepared.rb +62 -18
  121. data/lib/cassandra/statements/simple.rb +23 -10
  122. data/lib/cassandra/statements/void.rb +1 -1
  123. data/lib/cassandra/table.rb +53 -185
  124. data/lib/cassandra/time.rb +11 -6
  125. data/lib/cassandra/time_uuid.rb +12 -14
  126. data/lib/cassandra/timestamp_generator.rb +37 -0
  127. data/lib/cassandra/timestamp_generator/simple.rb +38 -0
  128. data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
  129. data/lib/cassandra/tuple.rb +4 -4
  130. data/lib/cassandra/types.rb +109 -71
  131. data/lib/cassandra/udt.rb +66 -50
  132. data/lib/cassandra/util.rb +155 -15
  133. data/lib/cassandra/uuid.rb +20 -21
  134. data/lib/cassandra/uuid/generator.rb +7 -5
  135. data/lib/cassandra/version.rb +2 -2
  136. data/lib/cassandra_murmur3.jar +0 -0
  137. data/lib/datastax/cassandra.rb +1 -1
  138. metadata +27 -16
@@ -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
@@ -35,9 +39,7 @@ module Cassandra
35
39
  end
36
40
 
37
41
  def find_replicas(keyspace, statement)
38
- unless statement.respond_to?(:partition_key) && statement.respond_to?(:keyspace)
39
- return EMPTY_LIST
40
- end
42
+ return EMPTY_LIST unless statement.respond_to?(:partition_key) && statement.respond_to?(:keyspace)
41
43
 
42
44
  keyspace = String(statement.keyspace || keyspace)
43
45
  partition_key = statement.partition_key
@@ -59,7 +61,7 @@ module Cassandra
59
61
  end
60
62
 
61
63
  def update(data)
62
- @name = data['name']
64
+ @name = data['cluster_name']
63
65
  @partitioner = @partitioners[data['partitioner']]
64
66
 
65
67
  self
@@ -74,7 +76,11 @@ module Cassandra
74
76
 
75
77
  @registry.each_host do |host|
76
78
  host.tokens.each do |token|
77
- token = partitioner.parse_token(token) rescue next
79
+ token = begin
80
+ partitioner.parse_token(token)
81
+ rescue
82
+ next
83
+ end
78
84
  tokens.add(token)
79
85
  token_to_host[token] = host
80
86
  end
@@ -116,7 +122,7 @@ module Cassandra
116
122
  min = 0
117
123
  max = list.size - 1
118
124
 
119
- while min <= max do
125
+ while min <= max
120
126
  idx = (min + max) / 2
121
127
  val = list[idx]
122
128
 
@@ -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,33 @@ 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
+ extend AttrBoolean
24
+
25
+ attr_reader :auth_provider, :compressor, :connect_timeout, :credentials,
26
+ :heartbeat_interval, :idle_timeout, :port, :schema_refresh_delay,
27
+ :schema_refresh_timeout, :ssl
28
+ attr_boolean :protocol_negotiable, :synchronize_schema, :nodelay
29
+
26
30
  attr_accessor :protocol_version
27
31
 
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)
32
+ def initialize(logger,
33
+ protocol_version,
34
+ credentials,
35
+ auth_provider,
36
+ compressor,
37
+ port,
38
+ connect_timeout,
39
+ ssl,
40
+ connections_per_local_node,
41
+ connections_per_remote_node,
42
+ heartbeat_interval,
43
+ idle_timeout,
44
+ synchronize_schema,
45
+ schema_refresh_delay,
46
+ schema_refresh_timeout,
47
+ nodelay,
48
+ requests_per_connection)
49
+ @logger = logger
29
50
  @protocol_version = protocol_version
30
51
  @credentials = credentials
31
52
  @auth_provider = auth_provider
@@ -38,23 +59,19 @@ module Cassandra
38
59
  @synchronize_schema = synchronize_schema
39
60
  @schema_refresh_delay = schema_refresh_delay
40
61
  @schema_refresh_timeout = schema_refresh_timeout
41
- @client_timestamps = client_timestamps
42
62
  @nodelay = nodelay
43
63
 
44
64
  @connections_per_local_node = connections_per_local_node
45
65
  @connections_per_remote_node = connections_per_remote_node
46
- end
66
+ @requests_per_connection = requests_per_connection
47
67
 
48
- def synchronize_schema?
49
- @synchronize_schema
50
- end
51
-
52
- def client_timestamps?
53
- @client_timestamps
54
- end
68
+ # If @protocol_version is nil, it means we want the driver to negotiate the
69
+ # protocol starting with our known max (4). If @protocol_version is not nil,
70
+ # it means the user wants us to use a particular version, so we should not
71
+ # support negotiation.
55
72
 
56
- def nodelay?
57
- @nodelay
73
+ @protocol_negotiable = @protocol_version.nil?
74
+ @protocol_version ||= 4
58
75
  end
59
76
 
60
77
  def compression
@@ -65,16 +82,45 @@ module Cassandra
65
82
  @auth_provider && @auth_provider.create_authenticator(authentication_class)
66
83
  end
67
84
 
68
- # increased number of streams in native protocol v3 allow for one
69
- # connections to be sufficient
70
85
  def connections_per_local_node
71
- (@protocol_version > 2) ? 1 : @connections_per_local_node
86
+ # Return the option if set.
87
+ return @connections_per_local_node if @connections_per_local_node
88
+
89
+ # For v3 and later, default is 1 local connection.
90
+ # For v2 and earlier, default is 2 local connections.
91
+ # Return the default
92
+ (@protocol_version > 2) ? 1 : 2
72
93
  end
73
94
 
74
- # increased number of streams in native protocol v3 allow for one
75
- # connections to be sufficient
76
95
  def connections_per_remote_node
77
- (@protocol_version > 2) ? 1 : @connections_per_remote_node
96
+ # Return the option if set; otherwise return the default (1).
97
+ @connections_per_remote_node || 1
98
+ end
99
+
100
+ def requests_per_connection
101
+ # There are a few possibilities here based on @requests_per_connection:
102
+ # nil: default to 1024 for protocol 3 and later, 128 for < 3.
103
+ # we're in v2 and value too high: return 128. We don't worry
104
+ # about this case for v3+ because option validation in
105
+ # Cassandra::cluster_async takes care of that.
106
+ # good value: return it.
107
+ #
108
+ # NOTE: We can't compute and cache the result because protocol_version
109
+ # can change over time in theory (if all nodes are upgraded to a new
110
+ # version of Cassandra)
111
+
112
+ # Return the default if option wasn't specified.
113
+ default_requests_per_connection = @protocol_version > 2 ? 1024 : 128
114
+ return default_requests_per_connection unless @requests_per_connection
115
+
116
+ if @requests_per_connection > 128 && @protocol_version < 3
117
+ @logger.warn(
118
+ ":requests_per_connection setting of #{@requests_per_connection} is more " \
119
+ 'than the max of 128 for protocol v2. Falling back to 128.'
120
+ )
121
+ return 128
122
+ end
123
+ @requests_per_connection
78
124
  end
79
125
  end
80
126
  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 = {})
@@ -76,13 +76,16 @@ module Cassandra
76
76
  if host.id == data['host_id'] &&
77
77
  host.release_version == data['release_version'] &&
78
78
  host.rack == data['rack'] &&
79
- host.datacenter == data['data_center']
79
+ host.datacenter == data['data_center'] &&
80
+ host.broadcast_address == data['broadcast_address'] &&
81
+ host.listen_address == data['listen_address']
80
82
 
81
83
  return self if host.up?
82
84
 
83
85
  host = toggle_up(host)
84
86
  else
85
- @logger.debug("Host #{host.ip} metadata has been updated, it will be considered lost and found")
87
+ @logger.debug("Host #{host.ip} metadata has been updated, it will be " \
88
+ 'considered lost and found')
86
89
 
87
90
  notify_lost(host)
88
91
 
@@ -143,7 +146,7 @@ module Cassandra
143
146
  ip = address.to_s
144
147
  host = nil
145
148
 
146
- return self unless @hosts.has_key?(ip)
149
+ return self unless @hosts.key?(ip)
147
150
 
148
151
  synchronize do
149
152
  hosts = @hosts.dup
@@ -159,23 +162,56 @@ module Cassandra
159
162
  private
160
163
 
161
164
  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)
165
+ Host.new(ip,
166
+ data['host_id'],
167
+ data['rack'],
168
+ data['data_center'],
169
+ data['release_version'],
170
+ Array(data['tokens']).freeze,
171
+ :up,
172
+ data['broadcast_address'],
173
+ data['listen_address']
174
+ )
163
175
  end
164
176
 
165
177
  def toggle_up(host)
166
- host = Host.new(host.ip, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :up)
178
+ host = Host.new(host.ip,
179
+ host.id,
180
+ host.rack,
181
+ host.datacenter,
182
+ host.release_version,
183
+ host.tokens,
184
+ :up,
185
+ host.broadcast_address,
186
+ host.listen_address)
167
187
  @logger.debug("Host #{host.ip} is up")
168
188
  @listeners.each do |listener|
169
- listener.host_up(host) rescue nil
189
+ begin
190
+ listener.host_up(host)
191
+ rescue
192
+ nil
193
+ end
170
194
  end
171
195
  host
172
196
  end
173
197
 
174
198
  def toggle_down(host)
175
- host = Host.new(host.ip, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :down)
199
+ host = Host.new(host.ip,
200
+ host.id,
201
+ host.rack,
202
+ host.datacenter,
203
+ host.release_version,
204
+ host.tokens,
205
+ :down,
206
+ host.broadcast_address,
207
+ host.listen_address)
176
208
  @logger.debug("Host #{host.ip} is down")
177
209
  @listeners.reverse_each do |listener|
178
- listener.host_down(host) rescue nil
210
+ begin
211
+ listener.host_down(host)
212
+ rescue
213
+ nil
214
+ end
179
215
  end
180
216
  host
181
217
  end
@@ -183,15 +219,35 @@ module Cassandra
183
219
  def notify_lost(host)
184
220
  if host.up?
185
221
  @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)
222
+ host = Host.new(host.ip,
223
+ host.id,
224
+ host.rack,
225
+ host.datacenter,
226
+ host.release_version,
227
+ host.tokens,
228
+ :down,
229
+ host.broadcast_address,
230
+ host.listen_address)
187
231
  @listeners.reverse_each do |listener|
188
- listener.host_down(host) rescue nil
189
- listener.host_lost(host) rescue nil
232
+ begin
233
+ listener.host_down(host)
234
+ rescue
235
+ nil
236
+ end
237
+ begin
238
+ listener.host_lost(host)
239
+ rescue
240
+ nil
241
+ end
190
242
  end
191
243
  else
192
244
  @logger.debug("Host #{host.ip} is lost")
193
245
  @listeners.reverse_each do |listener|
194
- listener.host_lost(host) rescue nil
246
+ begin
247
+ listener.host_lost(host)
248
+ rescue
249
+ nil
250
+ end
195
251
  end
196
252
  end
197
253
  end
@@ -199,8 +255,16 @@ module Cassandra
199
255
  def notify_found(host)
200
256
  @logger.debug("Host #{host.ip} is found and up")
201
257
  @listeners.each do |listener|
202
- listener.host_found(host) rescue nil
203
- listener.host_up(host) rescue nil
258
+ begin
259
+ listener.host_found(host)
260
+ rescue
261
+ nil
262
+ end
263
+ begin
264
+ listener.host_up(host)
265
+ rescue
266
+ nil
267
+ end
204
268
  end
205
269
  end
206
270
  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
 
@@ -120,7 +126,7 @@ module Cassandra
120
126
  end
121
127
 
122
128
  def replace_table(table)
123
- keyspace = @keyspaces[table.keyspace]
129
+ keyspace = table.keyspace
124
130
 
125
131
  return self unless keyspace
126
132
 
@@ -163,6 +169,50 @@ module Cassandra
163
169
  self
164
170
  end
165
171
 
172
+ def replace_materialized_view(view)
173
+ keyspace = view.keyspace
174
+
175
+ return self unless keyspace
176
+
177
+ old_view = keyspace.materialized_view(view.name)
178
+
179
+ return self if old_view == view
180
+
181
+ keyspace = keyspace.update_materialized_view(view)
182
+
183
+ synchronize do
184
+ keyspaces = @keyspaces.dup
185
+ keyspaces[keyspace.name] = keyspace
186
+ @keyspaces = keyspaces
187
+ end
188
+
189
+ keyspace_changed(keyspace)
190
+
191
+ self
192
+ end
193
+
194
+ def delete_materialized_view(keyspace_name, view_name)
195
+ keyspace = @keyspaces[keyspace_name]
196
+
197
+ return self unless keyspace
198
+
199
+ view = keyspace.materialized_view(view_name)
200
+
201
+ return self unless view
202
+
203
+ keyspace = keyspace.delete_materialized_view(view_name)
204
+
205
+ synchronize do
206
+ keyspaces = @keyspaces.dup
207
+ keyspaces[keyspace_name] = keyspace
208
+ @keyspaces = keyspaces
209
+ end
210
+
211
+ keyspace_changed(keyspace)
212
+
213
+ self
214
+ end
215
+
166
216
  def replace_type(type)
167
217
  keyspace = @keyspaces[type.keyspace]
168
218
 
@@ -311,25 +361,37 @@ module Cassandra
311
361
  @keyspaces.values
312
362
  end
313
363
  end
314
- alias :keyspaces :each_keyspace
364
+ alias keyspaces each_keyspace
315
365
 
316
366
  private
317
367
 
318
368
  def keyspace_created(keyspace)
319
369
  @listeners.each do |listener|
320
- listener.keyspace_created(keyspace) rescue nil
370
+ begin
371
+ listener.keyspace_created(keyspace)
372
+ rescue
373
+ nil
374
+ end
321
375
  end
322
376
  end
323
377
 
324
378
  def keyspace_changed(keyspace)
325
379
  @listeners.each do |listener|
326
- listener.keyspace_changed(keyspace) rescue nil
380
+ begin
381
+ listener.keyspace_changed(keyspace)
382
+ rescue
383
+ nil
384
+ end
327
385
  end
328
386
  end
329
387
 
330
388
  def keyspace_dropped(keyspace)
331
389
  @listeners.each do |listener|
332
- listener.keyspace_dropped(keyspace) rescue nil
390
+ begin
391
+ listener.keyspace_dropped(keyspace)
392
+ rescue
393
+ nil
394
+ end
333
395
  end
334
396
  end
335
397
  end