cassandra-driver 3.0.0.rc.1-java → 3.0.0.rc.2-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -1
  3. data/lib/cassandra.rb +74 -55
  4. data/lib/cassandra/attr_boolean.rb +33 -0
  5. data/lib/cassandra/auth.rb +2 -1
  6. data/lib/cassandra/auth/providers/password.rb +4 -16
  7. data/lib/cassandra/cluster/connector.rb +14 -4
  8. data/lib/cassandra/cluster/control_connection.rb +59 -67
  9. data/lib/cassandra/cluster/metadata.rb +1 -3
  10. data/lib/cassandra/cluster/options.rb +9 -10
  11. data/lib/cassandra/cluster/registry.rb +16 -5
  12. data/lib/cassandra/cluster/schema.rb +45 -1
  13. data/lib/cassandra/cluster/schema/fetchers.rb +475 -272
  14. data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +2 -6
  15. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +5 -7
  16. data/lib/cassandra/column.rb +1 -20
  17. data/lib/cassandra/column_container.rb +322 -0
  18. data/lib/cassandra/compression/compressors/lz4.rb +3 -5
  19. data/lib/cassandra/driver.rb +1 -1
  20. data/lib/cassandra/errors.rb +38 -22
  21. data/lib/cassandra/execution/options.rb +4 -2
  22. data/lib/cassandra/future.rb +3 -9
  23. data/lib/cassandra/host.rb +16 -2
  24. data/lib/cassandra/index.rb +104 -0
  25. data/lib/cassandra/keyspace.rb +88 -9
  26. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +6 -10
  27. data/lib/cassandra/materialized_view.rb +90 -0
  28. data/lib/cassandra/protocol/coder.rb +3 -3
  29. data/lib/cassandra/protocol/cql_byte_buffer.rb +12 -11
  30. data/lib/cassandra/protocol/cql_protocol_handler.rb +12 -8
  31. data/lib/cassandra/protocol/request.rb +4 -5
  32. data/lib/cassandra/protocol/requests/execute_request.rb +3 -5
  33. data/lib/cassandra/protocol/requests/query_request.rb +1 -1
  34. data/lib/cassandra/protocol/requests/startup_request.rb +6 -8
  35. data/lib/cassandra/protocol/response.rb +1 -2
  36. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +3 -4
  37. data/lib/cassandra/protocol/responses/auth_success_response.rb +3 -4
  38. data/lib/cassandra/protocol/responses/authenticate_response.rb +3 -4
  39. data/lib/cassandra/protocol/responses/error_response.rb +3 -4
  40. data/lib/cassandra/protocol/responses/event_response.rb +2 -3
  41. data/lib/cassandra/protocol/responses/prepared_result_response.rb +3 -4
  42. data/lib/cassandra/protocol/responses/ready_response.rb +3 -4
  43. data/lib/cassandra/protocol/responses/result_response.rb +7 -8
  44. data/lib/cassandra/protocol/responses/rows_result_response.rb +3 -4
  45. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +3 -4
  46. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +3 -4
  47. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +3 -4
  48. data/lib/cassandra/protocol/responses/status_change_event_response.rb +3 -4
  49. data/lib/cassandra/protocol/responses/supported_response.rb +3 -4
  50. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +3 -4
  51. data/lib/cassandra/protocol/responses/void_result_response.rb +3 -4
  52. data/lib/cassandra/protocol/v1.rb +1 -5
  53. data/lib/cassandra/protocol/v3.rb +1 -3
  54. data/lib/cassandra/result.rb +2 -1
  55. data/lib/cassandra/retry/policies/downgrading_consistency.rb +1 -3
  56. data/lib/cassandra/statements/prepared.rb +3 -3
  57. data/lib/cassandra/table.rb +39 -220
  58. data/lib/cassandra/time_uuid.rb +5 -7
  59. data/lib/cassandra/tuple.rb +4 -12
  60. data/lib/cassandra/types.rb +92 -65
  61. data/lib/cassandra/udt.rb +34 -14
  62. data/lib/cassandra/uuid.rb +10 -18
  63. data/lib/cassandra/version.rb +1 -1
  64. data/lib/cassandra_murmur3.jar +0 -0
  65. metadata +8 -2
@@ -52,8 +52,10 @@ module Cassandra
52
52
  # @return [nil, Hash<String, String>] custom outgoing payload, a map of
53
53
  # string and byte buffers.
54
54
  #
55
- # @see https://github.com/apache/cassandra/blob/33f1edcce97779c971d4f78712a9a8bf014ffbbc/doc/native_protocol_v4.spec#L127-L133 Description of custom payload in Cassandra native protocol v4.
56
- # @see https://datastax.github.io/java-driver/manual/custom_payloads/#enabling-custom-payloads-on-c-nodes Enabling custom payloads on Cassandra nodes.
55
+ # @see https://github.com/apache/cassandra/blob/cassandra-3.4/doc/native_protocol_v4.spec#L125-L131 Description
56
+ # of custom payload in Cassandra native protocol v4.
57
+ # @see https://datastax.github.io/java-driver/manual/custom_payloads/#enabling-custom-payloads-on-c-nodes
58
+ # Enabling custom payloads on Cassandra nodes.
57
59
  #
58
60
  # @example Sending a custom payload
59
61
  # result = session.execute(payload: {
@@ -46,9 +46,7 @@ module Cassandra
46
46
  # @private
47
47
  class Error < Future
48
48
  def initialize(error)
49
- unless error.is_a?(::Exception)
50
- raise ::ArgumentError, "error must be an exception, #{error.inspect} given"
51
- end
49
+ raise ::ArgumentError, "error must be an exception, #{error.inspect} given" unless error.is_a?(::Exception)
52
50
 
53
51
  @error = error
54
52
  end
@@ -519,9 +517,7 @@ module Cassandra
519
517
  end
520
518
 
521
519
  def failure(error)
522
- unless error.is_a?(::Exception)
523
- raise ::ArgumentError, "error must be an exception, #{error.inspect} given"
524
- end
520
+ raise ::ArgumentError, "error must be an exception, #{error.inspect} given" unless error.is_a?(::Exception)
525
521
 
526
522
  return unless @state == :pending
527
523
 
@@ -600,9 +596,7 @@ module Cassandra
600
596
  timeout &&= Float(timeout)
601
597
 
602
598
  if timeout
603
- if timeout < 0
604
- raise ::ArgumentError, "timeout cannot be negative, #{timeout.inspect} given"
605
- end
599
+ raise ::ArgumentError, "timeout cannot be negative, #{timeout.inspect} given" if timeout < 0
606
600
 
607
601
  start = ::Time.now
608
602
  now = start
@@ -18,7 +18,7 @@
18
18
 
19
19
  module Cassandra
20
20
  class Host
21
- # @return [IPAddr] host ip
21
+ # @return [IPAddr] host ip that clients use to connect to this host.
22
22
  attr_reader :ip
23
23
  # @note Host id can be `nil` before cluster has connected.
24
24
  # @return [Cassandra::Uuid, nil] host id.
@@ -37,6 +37,14 @@ module Cassandra
37
37
  attr_reader :tokens
38
38
  # @return [Symbol] host status. Must be `:up` or `:down`
39
39
  attr_reader :status
40
+ # @note This is the public IP address of the host if the cluster is deployed across multiple Amazon EC2 regions
41
+ # (or equivalently multiple networks). Cassandra nodes in other EC2 regions use this address to connect to this
42
+ # host.
43
+ # @return [IPAddr, String] broadcast address, if available.
44
+ attr_reader :broadcast_address
45
+ # @note This is the address that other Cassandra nodes use to connect to this host.
46
+ # @return [IPAddr, String] listen address, if available.
47
+ attr_reader :listen_address
40
48
 
41
49
  # @private
42
50
  def initialize(ip,
@@ -45,7 +53,9 @@ module Cassandra
45
53
  datacenter = nil,
46
54
  release_version = nil,
47
55
  tokens = EMPTY_LIST,
48
- status = :up)
56
+ status = :up,
57
+ broadcast_address = nil,
58
+ listen_address = nil)
49
59
  @ip = ip
50
60
  @id = id
51
61
  @rack = rack
@@ -53,6 +63,10 @@ module Cassandra
53
63
  @release_version = release_version
54
64
  @tokens = tokens
55
65
  @status = status
66
+ @broadcast_address = broadcast_address.is_a?(String) ?
67
+ ::IPAddr.new(broadcast_address) : broadcast_address
68
+ @listen_address = listen_address.is_a?(String) ?
69
+ ::IPAddr.new(listen_address) : listen_address
56
70
  end
57
71
 
58
72
  # @return [Boolean] whether this host's status is `:up`
@@ -0,0 +1,104 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2016 DataStax, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #++
18
+
19
+ module Cassandra
20
+ # Represents an index on a cassandra table
21
+ class Index
22
+ # @return [Cassandra::Table] table that the index applies to.
23
+ attr_reader :table
24
+ # @return [String] name of the index.
25
+ attr_reader :name
26
+ # @return [Symbol] kind of index: `:keys`, `:composites`, or `:custom`.
27
+ attr_reader :kind
28
+ # @return [String] name of column that the index applies to.
29
+ attr_reader :target
30
+ # @return [Hash] options of the index.
31
+ attr_reader :options
32
+
33
+ # @private
34
+ def initialize(table,
35
+ name,
36
+ kind,
37
+ target,
38
+ options)
39
+ @table = table
40
+ @name = name.freeze
41
+ @kind = kind
42
+ @target = target.freeze
43
+ @options = options.freeze
44
+ end
45
+
46
+ # @return [Boolean] whether or not this index uses a custom class.
47
+ def custom_index?
48
+ !@options['class_name'].nil?
49
+ end
50
+
51
+ # @return [String] name of the index class if this is a custom index; nil otherwise.
52
+ def custom_class_name
53
+ @options['class_name']
54
+ end
55
+
56
+ # @return [String] a cql representation of this table
57
+ def to_cql
58
+ keyspace_name = Util.escape_name(@table.keyspace.name)
59
+ table_name = Util.escape_name(@table.name)
60
+ index_name = Util.escape_name(name)
61
+
62
+ if custom_index?
63
+ "CREATE CUSTOM INDEX #{index_name} ON #{keyspace_name}.#{table_name} (#{target}) " \
64
+ "USING '#{@options['class_name']}' #{options_cql};"
65
+ else
66
+ "CREATE INDEX #{index_name} ON #{keyspace_name}.#{table_name} (#{target});"
67
+ end
68
+ end
69
+
70
+ # @private
71
+ def eql?(other)
72
+ other.is_a?(Index) &&
73
+ @table == other.table &&
74
+ @name == other.name &&
75
+ @kind == other.kind &&
76
+ @target == other.target &&
77
+ @options == other.options
78
+ end
79
+ alias == eql?
80
+
81
+ # @private
82
+ def inspect
83
+ "#<#{self.class.name}:0x#{object_id.to_s(16)} " \
84
+ "@name=#{@name} table_name=#{@table.name} kind=#{@kind} target=#{@target}>"
85
+ end
86
+
87
+ private
88
+
89
+ def options_cql
90
+ # exclude 'class_name', 'target' keys
91
+ filtered_options = @options.reject do |key, _|
92
+ key == 'class_name' || key == 'target'
93
+ end
94
+ return '' if filtered_options.empty?
95
+
96
+ result = 'WITH OPTIONS = {'
97
+ result << filtered_options.map do |key, value|
98
+ "'#{key}':'#{value}'"
99
+ end.join(', ')
100
+ result << '}'
101
+ result
102
+ end
103
+ end
104
+ end
@@ -57,7 +57,8 @@ module Cassandra
57
57
  tables,
58
58
  types,
59
59
  functions,
60
- aggregates)
60
+ aggregates,
61
+ views)
61
62
  @name = name
62
63
  @durable_writes = durable_writes
63
64
  @replication = replication
@@ -65,6 +66,15 @@ module Cassandra
65
66
  @types = types
66
67
  @functions = functions
67
68
  @aggregates = aggregates
69
+ @views = views
70
+
71
+ # Set the keyspace attribute on the tables and views.
72
+ @tables.each_value do |t|
73
+ t.set_keyspace(self)
74
+ end
75
+ @views.each_value do |v|
76
+ v.set_keyspace(self)
77
+ end
68
78
  end
69
79
 
70
80
  # @return [Boolean] whether durables writes are enabled for this keyspace
@@ -100,6 +110,34 @@ module Cassandra
100
110
  end
101
111
  alias tables each_table
102
112
 
113
+ # @return [Boolean] whether this keyspace has a materialized view with the given name
114
+ # @param name [String] materialized view name
115
+ def has_materialized_view?(name)
116
+ @views.key?(name)
117
+ end
118
+
119
+ # @return [Cassandra::MaterializedView, nil] a materialized view or nil
120
+ # @param name [String] materialized view name
121
+ def materialized_view(name)
122
+ @views[name]
123
+ end
124
+
125
+ # Yield or enumerate each materialized view defined in this keyspace
126
+ # @overload each_materialized_view
127
+ # @yieldparam view [Cassandra::MaterializedView] current materialized view
128
+ # @return [Cassandra::Keyspace] self
129
+ # @overload each_materialized_view
130
+ # @return [Array<Cassandra::MaterializedView>] a list of materialized views
131
+ def each_materialized_view(&block)
132
+ if block_given?
133
+ @views.each_value(&block)
134
+ self
135
+ else
136
+ @views.values
137
+ end
138
+ end
139
+ alias materialized_views each_materialized_view
140
+
103
141
  # @return [Boolean] whether this keyspace has a user-defined type with the
104
142
  # given name
105
143
  # @param name [String] user-defined type name
@@ -228,7 +266,8 @@ module Cassandra
228
266
  tables,
229
267
  @types,
230
268
  @functions,
231
- @aggregates)
269
+ @aggregates,
270
+ @views)
232
271
  end
233
272
 
234
273
  # @private
@@ -241,7 +280,36 @@ module Cassandra
241
280
  tables,
242
281
  @types,
243
282
  @functions,
244
- @aggregates)
283
+ @aggregates,
284
+ @views)
285
+ end
286
+
287
+ # @private
288
+ def update_materialized_view(view)
289
+ views = @views.dup
290
+ views[view.name] = view
291
+ Keyspace.new(@name,
292
+ @durable_writes,
293
+ @replication,
294
+ @tables,
295
+ @types,
296
+ @functions,
297
+ @aggregates,
298
+ views)
299
+ end
300
+
301
+ # @private
302
+ def delete_materialized_view(view_name)
303
+ views = @views.dup
304
+ views.delete(view_name)
305
+ Keyspace.new(@name,
306
+ @durable_writes,
307
+ @replication,
308
+ @tables,
309
+ @types,
310
+ @functions,
311
+ @aggregates,
312
+ views)
245
313
  end
246
314
 
247
315
  # @private
@@ -254,7 +322,8 @@ module Cassandra
254
322
  @tables,
255
323
  types,
256
324
  @functions,
257
- @aggregates)
325
+ @aggregates,
326
+ @views)
258
327
  end
259
328
 
260
329
  # @private
@@ -267,7 +336,8 @@ module Cassandra
267
336
  @tables,
268
337
  types,
269
338
  @functions,
270
- @aggregates)
339
+ @aggregates,
340
+ @views)
271
341
  end
272
342
 
273
343
  # @private
@@ -280,7 +350,8 @@ module Cassandra
280
350
  @tables,
281
351
  @types,
282
352
  functions,
283
- @aggregates)
353
+ @aggregates,
354
+ @views)
284
355
  end
285
356
 
286
357
  # @private
@@ -293,7 +364,8 @@ module Cassandra
293
364
  @tables,
294
365
  @types,
295
366
  functions,
296
- @aggregates)
367
+ @aggregates,
368
+ @views)
297
369
  end
298
370
 
299
371
  # @private
@@ -306,7 +378,8 @@ module Cassandra
306
378
  @tables,
307
379
  @types,
308
380
  @functions,
309
- aggregates)
381
+ aggregates,
382
+ @views)
310
383
  end
311
384
 
312
385
  # @private
@@ -319,7 +392,8 @@ module Cassandra
319
392
  @tables,
320
393
  @types,
321
394
  @functions,
322
- aggregates)
395
+ aggregates,
396
+ @views)
323
397
  end
324
398
 
325
399
  # @private
@@ -333,6 +407,11 @@ module Cassandra
333
407
  @tables
334
408
  end
335
409
 
410
+ # @private
411
+ def raw_materialized_views
412
+ @views
413
+ end
414
+
336
415
  # @private
337
416
  def raw_types
338
417
  @types
@@ -20,6 +20,11 @@ module Cassandra
20
20
  module LoadBalancing
21
21
  module Policies
22
22
  class DCAwareRoundRobin < Policy
23
+ # @private
24
+ LOCAL_CONSISTENCIES = [:local_quorum, :local_one].freeze
25
+ # @private
26
+ EMPTY_ARRAY = [].freeze
27
+
23
28
  # @private
24
29
  class Plan
25
30
  def initialize(local, remote, index)
@@ -62,9 +67,7 @@ module Cassandra
62
67
  datacenter &&= String(datacenter)
63
68
  max_remote_hosts_to_use &&= Integer(max_remote_hosts_to_use)
64
69
 
65
- unless datacenter.nil?
66
- Util.assert_not_empty(datacenter) { 'datacenter cannot be empty' }
67
- end
70
+ Util.assert_not_empty(datacenter) { 'datacenter cannot be empty' } unless datacenter.nil?
68
71
 
69
72
  unless max_remote_hosts_to_use.nil?
70
73
  Util.assert(max_remote_hosts_to_use >= 0) do
@@ -145,13 +148,6 @@ module Cassandra
145
148
 
146
149
  Plan.new(local, remote, position)
147
150
  end
148
-
149
- private
150
-
151
- # @private
152
- LOCAL_CONSISTENCIES = [:local_quorum, :local_one].freeze
153
- # @private
154
- EMPTY_ARRAY = [].freeze
155
151
  end
156
152
  end
157
153
  end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2016 DataStax, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #++
18
+
19
+ module Cassandra
20
+ # Represents a cassandra materialized view
21
+ # @see Cassandra::Keyspace#each_materialized_view
22
+ # @see Cassandra::Keyspace#materialized_view
23
+ class MaterializedView < ColumnContainer
24
+ # @return [Table] the table that this materialized view applies to.
25
+ attr_reader :base_table
26
+
27
+ # @private
28
+ def initialize(keyspace,
29
+ name,
30
+ partition_key,
31
+ clustering_columns,
32
+ other_columns,
33
+ options,
34
+ include_all_columns,
35
+ where_clause,
36
+ base_table,
37
+ id)
38
+ super(keyspace, name, partition_key, clustering_columns, other_columns, options, id)
39
+ @include_all_columns = include_all_columns
40
+ @where_clause = where_clause
41
+ @base_table = base_table
42
+ end
43
+
44
+ # @return [String] a cql representation of this materialized view
45
+ def to_cql
46
+ keyspace_name = Util.escape_name(@keyspace.name)
47
+ cql = "CREATE MATERIALIZED VIEW #{keyspace_name}.#{Util.escape_name(@name)} AS\nSELECT "
48
+ cql << if @include_all_columns
49
+ '*'
50
+ else
51
+ @columns.map do |column|
52
+ Util.escape_name(column.name)
53
+ end.join(', ')
54
+ end
55
+ cql << "\nFROM #{keyspace_name}.#{Util.escape_name(@base_table.name)}"
56
+ cql << "\nWHERE #{@where_clause}" if @where_clause
57
+ cql << "\nPRIMARY KEY (("
58
+ cql << @partition_key.map do |column|
59
+ Util.escape_name(column.name)
60
+ end.join(', ')
61
+ cql << ')'
62
+ unless @clustering_columns.empty?
63
+ cql << ', '
64
+ cql << @clustering_columns.map do |column|
65
+ Util.escape_name(column.name)
66
+ end.join(', ')
67
+ end
68
+ cql << ")\nWITH #{@options.to_cql.split("\n").join("\n ")};"
69
+ end
70
+
71
+ # @private
72
+ def eql?(other)
73
+ other.is_a?(MaterializedView) &&
74
+ super.eql?(other) &&
75
+ @include_all_columns == other.include_all_columns &&
76
+ @where_clause == other.where_clause &&
77
+ @base_table == other.base_table
78
+ end
79
+ alias == eql?
80
+
81
+ private
82
+
83
+ # We need these accessors for eql? to work, but we don't want random users to
84
+ # get these.
85
+
86
+ # @private
87
+ attr_reader :include_all_columns, :where_clause
88
+ protected :include_all_columns, :where_clause
89
+ end
90
+ end