cassandra-driver 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +13 -5
  2. data/README.md +18 -9
  3. data/ext/cassandra_murmur3/cassandra_murmur3.c +1 -1
  4. data/lib/cassandra.rb +5 -1
  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/auth.rb +1 -1
  9. data/lib/cassandra/auth/providers.rb +1 -1
  10. data/lib/cassandra/auth/providers/password.rb +1 -1
  11. data/lib/cassandra/cluster.rb +1 -1
  12. data/lib/cassandra/cluster/client.rb +33 -13
  13. data/lib/cassandra/cluster/connection_pool.rb +1 -1
  14. data/lib/cassandra/cluster/connector.rb +1 -36
  15. data/lib/cassandra/cluster/control_connection.rb +85 -9
  16. data/lib/cassandra/cluster/failed_connection.rb +1 -1
  17. data/lib/cassandra/cluster/metadata.rb +1 -1
  18. data/lib/cassandra/cluster/options.rb +15 -4
  19. data/lib/cassandra/cluster/registry.rb +1 -1
  20. data/lib/cassandra/cluster/schema.rb +76 -16
  21. data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
  22. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +1 -1
  23. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +1 -1
  24. data/lib/cassandra/cluster/schema/partitioners/random.rb +1 -1
  25. data/lib/cassandra/cluster/schema/replication_strategies.rb +1 -1
  26. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +1 -1
  27. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +1 -1
  28. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +1 -1
  29. data/lib/cassandra/cluster/schema/type_parser.rb +35 -8
  30. data/lib/cassandra/column.rb +10 -14
  31. data/lib/cassandra/compression.rb +1 -1
  32. data/lib/cassandra/compression/compressors/lz4.rb +1 -1
  33. data/lib/cassandra/compression/compressors/snappy.rb +1 -1
  34. data/lib/cassandra/driver.rb +2 -2
  35. data/lib/cassandra/errors.rb +1 -1
  36. data/lib/cassandra/execution/info.rb +1 -1
  37. data/lib/cassandra/execution/options.rb +3 -2
  38. data/lib/cassandra/execution/trace.rb +1 -1
  39. data/lib/cassandra/executors.rb +1 -1
  40. data/lib/cassandra/future.rb +1 -1
  41. data/lib/cassandra/host.rb +1 -1
  42. data/lib/cassandra/keyspace.rb +55 -5
  43. data/lib/cassandra/listener.rb +1 -1
  44. data/lib/cassandra/load_balancing.rb +1 -1
  45. data/lib/cassandra/load_balancing/policies.rb +1 -1
  46. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +1 -1
  47. data/lib/cassandra/load_balancing/policies/round_robin.rb +1 -1
  48. data/lib/cassandra/load_balancing/policies/token_aware.rb +1 -1
  49. data/lib/cassandra/load_balancing/policies/white_list.rb +1 -1
  50. data/lib/cassandra/null_logger.rb +1 -1
  51. data/lib/cassandra/protocol.rb +6 -1
  52. data/lib/cassandra/protocol/coder.rb +319 -84
  53. data/lib/cassandra/protocol/cql_byte_buffer.rb +1 -1
  54. data/lib/cassandra/protocol/cql_protocol_handler.rb +24 -10
  55. data/lib/cassandra/protocol/request.rb +1 -1
  56. data/lib/cassandra/protocol/requests/auth_response_request.rb +1 -1
  57. data/lib/cassandra/protocol/requests/batch_request.rb +1 -1
  58. data/lib/cassandra/protocol/requests/credentials_request.rb +1 -1
  59. data/lib/cassandra/protocol/requests/execute_request.rb +1 -1
  60. data/lib/cassandra/protocol/requests/options_request.rb +1 -1
  61. data/lib/cassandra/protocol/requests/prepare_request.rb +1 -1
  62. data/lib/cassandra/protocol/requests/query_request.rb +5 -3
  63. data/lib/cassandra/protocol/requests/register_request.rb +1 -1
  64. data/lib/cassandra/protocol/requests/startup_request.rb +1 -1
  65. data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
  66. data/lib/cassandra/protocol/response.rb +1 -1
  67. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +1 -1
  68. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +1 -1
  69. data/lib/cassandra/protocol/responses/auth_success_response.rb +1 -1
  70. data/lib/cassandra/protocol/responses/authenticate_response.rb +1 -1
  71. data/lib/cassandra/protocol/responses/error_response.rb +1 -1
  72. data/lib/cassandra/protocol/responses/event_response.rb +1 -1
  73. data/lib/cassandra/protocol/responses/prepared_result_response.rb +1 -1
  74. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +9 -2
  75. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +1 -1
  76. data/lib/cassandra/protocol/responses/ready_response.rb +1 -1
  77. data/lib/cassandra/protocol/responses/result_response.rb +1 -1
  78. data/lib/cassandra/protocol/responses/rows_result_response.rb +1 -1
  79. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +21 -6
  80. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +18 -8
  81. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +1 -1
  82. data/lib/cassandra/protocol/responses/status_change_event_response.rb +1 -1
  83. data/lib/cassandra/protocol/responses/supported_response.rb +1 -1
  84. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +1 -1
  85. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +1 -1
  86. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +1 -1
  87. data/lib/cassandra/protocol/responses/void_result_response.rb +1 -1
  88. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +1 -1
  89. data/lib/cassandra/protocol/v1.rb +4 -2
  90. data/lib/cassandra/protocol/v3.rb +280 -0
  91. data/lib/cassandra/reconnection.rb +1 -1
  92. data/lib/cassandra/reconnection/policies.rb +1 -1
  93. data/lib/cassandra/reconnection/policies/constant.rb +1 -1
  94. data/lib/cassandra/reconnection/policies/exponential.rb +1 -1
  95. data/lib/cassandra/result.rb +1 -1
  96. data/lib/cassandra/retry.rb +1 -1
  97. data/lib/cassandra/retry/policies.rb +1 -1
  98. data/lib/cassandra/retry/policies/default.rb +1 -1
  99. data/lib/cassandra/retry/policies/downgrading_consistency.rb +1 -1
  100. data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
  101. data/lib/cassandra/session.rb +14 -80
  102. data/lib/cassandra/statement.rb +1 -1
  103. data/lib/cassandra/statements.rb +1 -1
  104. data/lib/cassandra/statements/batch.rb +10 -25
  105. data/lib/cassandra/statements/bound.rb +1 -1
  106. data/lib/cassandra/statements/prepared.rb +24 -31
  107. data/lib/cassandra/statements/simple.rb +22 -66
  108. data/lib/cassandra/statements/void.rb +1 -1
  109. data/lib/cassandra/table.rb +36 -5
  110. data/lib/cassandra/time_uuid.rb +1 -1
  111. data/lib/cassandra/tuple.rb +124 -0
  112. data/lib/cassandra/types.rb +1406 -0
  113. data/lib/cassandra/udt.rb +420 -0
  114. data/lib/cassandra/util.rb +42 -64
  115. data/lib/cassandra/uuid.rb +1 -1
  116. data/lib/cassandra/uuid/generator.rb +1 -1
  117. data/lib/cassandra/version.rb +2 -2
  118. metadata +19 -15
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e1b5e23c6268565e84412e6d619c2bb80793b1a4
4
- data.tar.gz: 72d07dc35f8834d15d53720c1bdddabc62f94d03
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MTZjZmRjY2E2Y2ZhMjcxZDNlOGQ5N2Q0NWQ3MTY5ZDc1OTZkOTg1ZA==
5
+ data.tar.gz: !binary |-
6
+ MzczYWNmN2Y4ZDU2Y2E0OTViZjg2ZjZkNGE3ZTcyZTYwOGI1ZDNjYg==
5
7
  SHA512:
6
- metadata.gz: a6981ebeea62b7448aac6a522c74703678249435eda440f6ba368d5426a5d66fe53bc8059a975e141e187c152db90ff171d1359b1947334f786990daacb3808d
7
- data.tar.gz: 0b1d48e7d85c5170069733d6932586ed418bd4d1c18d67180ece0d4740dea23953b666557aba6c818b4945415491babcbb568a86f2549651a2b3879312860b0c
8
+ metadata.gz: !binary |-
9
+ OWRjMzkxYzQyNTYyNTczMGU1MmY2NzgyM2YzNDMxYjUxM2RkMWI2MmY4OTMx
10
+ MTExYmU1M2ZjZDVkYzU0OGU4NjgyMDAyY2RhZjVhOGNkZjYyZTg3YTBhNmQ1
11
+ MzcwYzA3NGU4YzhkN2Y3MWM1ZGIyZjM0OTU0ZjJhZWRjMzA0ZGI=
12
+ data.tar.gz: !binary |-
13
+ MjZhNjYwMzg2MGRlZjQzNDhkNjQ3NjYxODU3ZjBiYzk2NGY2Y2I1NWJjMTA2
14
+ YzBmNDJhZDE4MjY5YmQ1MWRiYjk5MDU1MTg3MGNkMGM0ZWM1YTEyZjMyMzVm
15
+ YjgxNjMzZmRhNzJhMDM0MGM2OTJiYzNiOTY5ZWNmY2I5NmE1M2Q=
data/README.md CHANGED
@@ -31,14 +31,12 @@ This driver is based on [the cql-rb gem](https://github.com/iconara/cql-rb) by [
31
31
 
32
32
  This driver works exclusively with the Cassandra Query Language v3 (CQL3) and Cassandra's native protocol. The current version works with:
33
33
 
34
- * Apache Cassandra versions 1.2, 2.0 and partially 2.1
34
+ * Apache Cassandra versions 1.2, 2.0 and 2.1
35
35
  * DataStax Enterprise 3.1, 3.2, 4.0 and 4.5
36
- * Ruby (MRI) 1.9.3, 2.0 and 2.1
36
+ * Ruby (MRI) 1.9.3, 2.0, 2.1 and 2.2
37
37
  * JRuby 1.7
38
38
  * Rubinius 2.2
39
39
 
40
- __Note__: Apache Cassandra 2.1 support is limited to the Cassandra 2.0 API, e.g. no user-defined types.
41
-
42
40
  __Note__: JRuby 1.6 is not officially supported, although 1.6.8 should work.
43
41
 
44
42
  ## Quick start
@@ -93,12 +91,23 @@ __Note__: if you want to use compression you should also install [snappy](http:/
93
91
 
94
92
  Some of the new features added to the driver have unfortunately led to changes in the original cql-rb API. In the examples directory, you can find [an example of how to wrap the ruby driver to achieve almost complete interface parity with cql-rb](https://github.com/datastax/ruby-driver/blob/master/examples/cql-rb-wrapper.rb) to assist you with gradual upgrade.
95
93
 
96
- ## What's new in v2.0.1
94
+ ## What's new in v2.1.0
95
+
96
+ Features:
97
+
98
+ * Apache Cassandra native protocol v3
99
+ * [User-defined types](http://datastax.github.io/ruby-driver/features/basics/user_defined_types/) and [tuples](http://datastax.github.io/ruby-driver/features/basics/datatypes/#using-tuples)
100
+ * [Schema metadata includes user-defined types](http://datastax.github.io/ruby-driver/api/keyspace/#type-instance_method)
101
+ * [Named arguments](http://datastax.github.io/ruby-driver/features/basics/prepared_statements/#an-insert-statement-is-prepared-with-named-parameters)
102
+ * [Public types api for type definition and introspection](http://datastax.github.io/ruby-driver/api/types/)
103
+
104
+ Breaking Changes:
105
+
106
+ * Splat style positional arguments support, deprecated in 2.0.0, has been dropped
97
107
 
98
- Current release lays groundwork for the upcoming support of native protocol v3 and Apache Cassandra 2.1. This release introduces the following major public API changes:
108
+ Bug Fixes:
99
109
 
100
- * Positional arguments to `Session#execute` must be passed via `:arguments` option key.
101
- * `Batch#add` and `Prepared#bind` accept an array of arguments instead of variable arguments (`args` instead of `*args`).
110
+ * [[RUBY-93](https://datastax-oss.atlassian.net/browse/RUBY-93)] Reconnection can overflow the stack
102
111
 
103
112
  ## Code examples
104
113
 
@@ -156,7 +165,7 @@ The development effort to provide an up to date, high performance, fully feature
156
165
 
157
166
  ## Copyright
158
167
 
159
- Copyright 2013-2014 DataStax, Inc.
168
+ Copyright 2013-2015 DataStax, Inc.
160
169
 
161
170
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
162
171
 
@@ -1,4 +1,4 @@
1
- // Copyright 2013-2014 DataStax, Inc.
1
+ // Copyright 2013-2015 DataStax, Inc.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // 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-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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.
@@ -510,6 +510,10 @@ end
510
510
 
511
511
  require 'cassandra/uuid'
512
512
  require 'cassandra/time_uuid'
513
+ require 'cassandra/tuple'
514
+ require 'cassandra/udt'
515
+
516
+ require 'cassandra/types'
513
517
 
514
518
  require 'cassandra/errors'
515
519
  require 'cassandra/compression'
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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,5 +1,5 @@
1
1
  #--
2
- # Copyright 2013-2014 DataStax, Inc.
2
+ # Copyright 2013-2015 DataStax, Inc.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # 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-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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.
@@ -93,10 +93,16 @@ module Cassandra
93
93
  connections.flatten!
94
94
  raise NO_HOSTS if connections.empty?
95
95
 
96
- unless connections.any?(&:connected?)
96
+ failed_connections = connections.reject(&:connected?)
97
+
98
+ if failed_connections.size == connections.size
97
99
  errors = {}
98
100
  connections.each {|c| errors[c.host] = c.error}
99
101
  raise Errors::NoHostsAvailable.new(errors)
102
+ else
103
+ failed_connections.each do |f|
104
+ connect_to_host_with_retry(f.host, connecting_hosts[f.host], @reconnection_policy.schedule)
105
+ end
100
106
  end
101
107
 
102
108
  self
@@ -199,7 +205,9 @@ module Cassandra
199
205
 
200
206
 
201
207
  def query(statement, options)
202
- request = Protocol::QueryRequest.new(statement.cql, statement.params, statement.params_types, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?)
208
+ return @futures.error(Errors::ClientError.new("Positional arguments are not supported by the current version of Apache Cassandra")) if !statement.params.empty? && @connection_options.protocol_version == 1
209
+
210
+ request = Protocol::QueryRequest.new(statement.cql, statement.params, statement.params_types, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?, statement.params_names)
203
211
  timeout = options.timeout
204
212
  promise = @futures.promise
205
213
 
@@ -375,9 +383,24 @@ module Cassandra
375
383
  end
376
384
 
377
385
  @logger.debug("Creating #{size} connections to #{host.ip}")
378
- f = @connector.connect_many(host, size)
386
+ futures = size.times.map do
387
+ @connector.connect(host).recover do |e|
388
+ FailedConnection.new(e, host)
389
+ end
390
+ end
391
+
392
+ Ione::Future.all(*futures).flat_map do |connections|
393
+ error = nil
394
+
395
+ connections.reject! do |connection|
396
+ if connection.connected?
397
+ false
398
+ else
399
+ error = connection.error
400
+ true
401
+ end
402
+ end
379
403
 
380
- f.on_value do |connections|
381
404
  @logger.debug("Created #{connections.size} connections to #{host.ip}")
382
405
 
383
406
  pool = nil
@@ -403,16 +426,13 @@ module Cassandra
403
426
  else
404
427
  connections.each {|c| c.close}
405
428
  end
406
- end
407
429
 
408
- f.on_failure do |error|
409
- synchronize do
410
- @pending_connections[host] -= size
411
- @pending_connections.delete(host) unless @pending_connections[host] > 0 || @connections.include?(host)
430
+ if error
431
+ Ione::Future.failed(error)
432
+ else
433
+ Ione::Future.resolved(connections)
412
434
  end
413
435
  end
414
-
415
- f
416
436
  end
417
437
 
418
438
  def execute_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors = nil, hosts = [])
@@ -713,7 +733,7 @@ module Cassandra
713
733
  when Protocol::RowsResultResponse
714
734
  promise.fulfill(Results::Paged.new(r.rows, r.paging_state, r.trace_id, keyspace, statement, options, hosts, request.consistency, retries, self, @futures))
715
735
  when Protocol::SchemaChangeResultResponse
716
- @schema.delete_keyspace(r.keyspace) if r.change == 'DROPPED' && r.table.empty?
736
+ @schema.delete_keyspace(r.keyspace) if r.change == 'DROPPED' && r.target == Protocol::Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
717
737
 
718
738
  @logger.debug('Waiting for schema to propagate to all hosts after a change')
719
739
  wait_for_schema_agreement(connection, @reconnection_policy.schedule).on_complete do |f|
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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.
@@ -106,10 +106,6 @@ module Cassandra
106
106
  f
107
107
  end
108
108
 
109
- def connect_many(host, count)
110
- create_additional_connections(host, count, [])
111
- end
112
-
113
109
  private
114
110
 
115
111
  NO_CONNECTIONS = Ione::Future.resolved([])
@@ -241,37 +237,6 @@ module Cassandra
241
237
  end
242
238
  end
243
239
 
244
- def create_additional_connections(host, count, established_connections, error = nil)
245
- futures = count.times.map do
246
- connect(host).recover do |e|
247
- FailedConnection.new(e, host)
248
- end
249
- end
250
-
251
- Ione::Future.all(*futures).flat_map do |connections|
252
- established_connections.select!(&:connected?)
253
-
254
- connections.each do |connection|
255
- if connection.connected?
256
- established_connections << connection
257
- else
258
- error = connection.error
259
- end
260
- end
261
-
262
- if !established_connections.empty?
263
- connections_left = count - established_connections.size
264
- if connections_left == 0
265
- Ione::Future.resolved(established_connections)
266
- else
267
- create_additional_connections(host, connections_left, established_connections, error)
268
- end
269
- else
270
- Ione::Future.failed(error)
271
- end
272
- end
273
- end
274
-
275
240
  def connected(host)
276
241
  notify = false
277
242
 
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2014 DataStax, Inc.
4
+ # Copyright 2013-2015 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.
@@ -248,10 +248,16 @@ module Cassandra
248
248
  tables = send_select_request(connection, SELECT_TABLES)
249
249
  columns = send_select_request(connection, SELECT_COLUMNS)
250
250
 
251
- Ione::Future.all(keyspaces, tables, columns).map do |(keyspaces, tables, columns)|
251
+ if @connection_options.protocol_version > 2
252
+ types = send_select_request(connection, SELECT_TYPES)
253
+ else
254
+ types = Ione::Future.resolved(EMPTY_LIST)
255
+ end
256
+
257
+ Ione::Future.all(keyspaces, tables, columns, types).map do |(keyspaces, tables, columns, types)|
252
258
  host = @registry.host(connection.host)
253
259
 
254
- @schema.update_keyspaces(host, keyspaces, tables, columns)
260
+ @schema.update_keyspaces(host, keyspaces, tables, columns, types)
255
261
  @metadata.rebuild_token_map
256
262
  end
257
263
  end
@@ -319,13 +325,19 @@ module Cassandra
319
325
  tables = send_select_request(connection, Protocol::QueryRequest.new("SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = '%s'" % keyspace, EMPTY_LIST, EMPTY_LIST, :one))
320
326
  columns = send_select_request(connection, Protocol::QueryRequest.new("SELECT * FROM system.schema_columns WHERE keyspace_name = '%s'" % keyspace, EMPTY_LIST, EMPTY_LIST, :one))
321
327
 
322
- Ione::Future.all(keyspaces, tables, columns).map do |(keyspaces, tables, columns)|
328
+ if @connection_options.protocol_version > 2
329
+ types = send_select_request(connection, Protocol::QueryRequest.new("SELECT * FROM system.schema_usertypes WHERE keyspace_name = '%s'" % keyspace, EMPTY_LIST, EMPTY_LIST, :one))
330
+ else
331
+ types = Ione::Future.resolved(EMPTY_LIST)
332
+ end
333
+
334
+ Ione::Future.all(keyspaces, tables, columns, types).map do |(keyspaces, tables, columns, types)|
323
335
  host = @registry.host(connection.host)
324
336
 
325
337
  if keyspaces.empty?
326
338
  @schema.delete_keyspace(keyspace)
327
339
  else
328
- @schema.update_keyspace(host, keyspaces.first, tables, columns)
340
+ @schema.update_keyspace(host, keyspaces.first, tables, columns, types)
329
341
  end
330
342
  end
331
343
  end
@@ -384,6 +396,59 @@ module Cassandra
384
396
  end
385
397
  end
386
398
 
399
+ def refresh_type_async_maybe_retry(keyspace, type)
400
+ refresh_type_async(keyspace, type).fallback do |e|
401
+ case e
402
+ when Errors::HostError
403
+ refresh_keyspace_async_retry(keyspace, e, @reconnection_policy.schedule)
404
+ else
405
+ connection = @connection
406
+ connection && connection.close(e)
407
+
408
+ Ione::Future.failed(e)
409
+ end
410
+ end
411
+ end
412
+
413
+ def refresh_type_async_retry(keyspace, type, error, schedule)
414
+ timeout = schedule.next
415
+ @logger.info("Failed to refresh type #{keyspace}.#{type} (#{error.class.name}: #{error.message}), retrying in #{timeout}")
416
+
417
+ timer = @io_reactor.schedule_timer(timeout)
418
+ timer.flat_map do
419
+ refresh_keyspace_async(keyspace).fallback do |e|
420
+ case e
421
+ when Errors::HostError
422
+ refresh_keyspace_async_retry(keyspace, e, schedule)
423
+ else
424
+ connection = @connection
425
+ connection && connection.close(e)
426
+
427
+ Ione::Future.failed(e)
428
+ end
429
+ end
430
+ end
431
+ end
432
+
433
+ def refresh_type_async(keyspace, type)
434
+ connection = @connection
435
+
436
+ return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
437
+
438
+ params = [keyspace, type]
439
+ types = send_select_request(connection, Protocol::QueryRequest.new("SELECT * FROM system.schema_usertypes WHERE keyspace_name = '%s' AND type_name = '%s'" % params, EMPTY_LIST, EMPTY_LIST, :one))
440
+
441
+ types.map do |types|
442
+ host = @registry.host(connection.host)
443
+
444
+ if types.empty?
445
+ @schema.delete_type(keyspace, type)
446
+ else
447
+ @schema.udpate_type(host, keyspace, types.first)
448
+ end
449
+ end
450
+ end
451
+
387
452
  def refresh_hosts_async_maybe_retry
388
453
  synchronize do
389
454
  return Ione::Future.resolved if @refreshing_hosts
@@ -644,19 +709,24 @@ Control connection failed and is unlikely to recover.
644
709
  def process_schema_changes(schema_changes)
645
710
  refresh_keyspaces = ::Hash.new
646
711
  refresh_tables = ::Hash.new
712
+ refresh_types = ::Hash.new
647
713
 
648
714
  schema_changes.each do |change|
649
715
  keyspace = change.keyspace
650
- table = change.table
651
716
 
652
717
  next if refresh_keyspaces.has_key?(keyspace)
653
718
 
654
- if table.empty?
719
+ case change.target
720
+ when Protocol::Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
655
721
  refresh_tables.delete(keyspace)
722
+ refresh_types.delete(keyspace)
656
723
  refresh_keyspaces[keyspace] = true
657
- else
724
+ when Protocol::Constants::SCHEMA_CHANGE_TARGET_TABLE
658
725
  tables = refresh_tables[keyspace] ||= ::Hash.new
659
- tables[table] = true
726
+ tables[change.table] = true
727
+ when Protocol::Constants::SCHEMA_CHANGE_TARGET_UDT
728
+ types = refresh_types[keyspace] ||= ::Hash.new
729
+ types[change.type] = true
660
730
  end
661
731
  end
662
732
 
@@ -672,6 +742,12 @@ Control connection failed and is unlikely to recover.
672
742
  end
673
743
  end
674
744
 
745
+ refresh_types.each do |(keyspace, types)|
746
+ types.each_key do |type|
747
+ futures << refresh_type_async_maybe_retry(keyspace, type)
748
+ end
749
+ end
750
+
675
751
  Ione::Future.all(*futures)
676
752
  end
677
753