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

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 (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.
@@ -55,41 +55,53 @@ module Cassandra
55
55
  raise(@error, @error.message, @error.backtrace)
56
56
  end
57
57
 
58
- alias :join :get
58
+ alias join get
59
59
 
60
60
  def on_success
61
- raise ::ArgumentError, "no block given" unless block_given?
61
+ raise ::ArgumentError, 'no block given' unless block_given?
62
62
  self
63
63
  end
64
64
 
65
65
  def on_failure
66
- raise ::ArgumentError, "no block given" unless block_given?
67
- yield(@error) rescue nil
66
+ raise ::ArgumentError, 'no block given' unless block_given?
67
+ begin
68
+ yield(@error)
69
+ rescue
70
+ nil
71
+ end
68
72
  self
69
73
  end
70
74
 
71
75
  def on_complete
72
- raise ::ArgumentError, "no block given" unless block_given?
73
- yield(nil, @error) rescue nil
76
+ raise ::ArgumentError, 'no block given' unless block_given?
77
+ begin
78
+ yield(nil, @error)
79
+ rescue
80
+ nil
81
+ end
74
82
  self
75
83
  end
76
84
 
77
85
  def add_listener(listener)
78
- unless (listener.respond_to?(:success) && listener.respond_to?(:failure))
79
- raise ::ArgumentError, "listener must respond to both #success and #failure"
86
+ unless listener.respond_to?(:success) && listener.respond_to?(:failure)
87
+ raise ::ArgumentError, 'listener must respond to both #success and #failure'
80
88
  end
81
89
 
82
- listener.failure(@error) rescue nil
90
+ begin
91
+ listener.failure(@error)
92
+ rescue
93
+ nil
94
+ end
83
95
  self
84
96
  end
85
97
 
86
98
  def then
87
- raise ::ArgumentError, "no block given" unless block_given?
99
+ raise ::ArgumentError, 'no block given' unless block_given?
88
100
  self
89
101
  end
90
102
 
91
103
  def fallback
92
- raise ::ArgumentError, "no block given" unless block_given?
104
+ raise ::ArgumentError, 'no block given' unless block_given?
93
105
 
94
106
  begin
95
107
  result = yield(@error)
@@ -111,31 +123,43 @@ module Cassandra
111
123
  @value
112
124
  end
113
125
 
114
- alias :join :get
126
+ alias join get
115
127
 
116
128
  def on_success
117
- raise ::ArgumentError, "no block given" unless block_given?
118
- yield(@value) rescue nil
129
+ raise ::ArgumentError, 'no block given' unless block_given?
130
+ begin
131
+ yield(@value)
132
+ rescue
133
+ nil
134
+ end
119
135
  self
120
136
  end
121
137
 
122
138
  def on_failure
123
- raise ::ArgumentError, "no block given" unless block_given?
139
+ raise ::ArgumentError, 'no block given' unless block_given?
124
140
  self
125
141
  end
126
142
 
127
143
  def on_complete
128
- raise ::ArgumentError, "no block given" unless block_given?
129
- yield(@value, nil) rescue nil
144
+ raise ::ArgumentError, 'no block given' unless block_given?
145
+ begin
146
+ yield(@value, nil)
147
+ rescue
148
+ nil
149
+ end
130
150
  self
131
151
  end
132
152
 
133
153
  def add_listener(listener)
134
- unless (listener.respond_to?(:success) && listener.respond_to?(:failure))
135
- raise ::ArgumentError, "listener must respond to both #success and #failure"
154
+ unless listener.respond_to?(:success) && listener.respond_to?(:failure)
155
+ raise ::ArgumentError, 'listener must respond to both #success and #failure'
136
156
  end
137
157
 
138
- listener.success(@value) rescue nil
158
+ begin
159
+ listener.success(@value)
160
+ rescue
161
+ nil
162
+ end
139
163
  self
140
164
  end
141
165
 
@@ -144,7 +168,7 @@ module Cassandra
144
168
  end
145
169
 
146
170
  def then
147
- raise ::ArgumentError, "no block given" unless block_given?
171
+ raise ::ArgumentError, 'no block given' unless block_given?
148
172
 
149
173
  begin
150
174
  result = yield(@value)
@@ -156,7 +180,7 @@ module Cassandra
156
180
  end
157
181
 
158
182
  def fallback
159
- raise ::ArgumentError, "no block given" unless block_given?
183
+ raise ::ArgumentError, 'no block given' unless block_given?
160
184
  self
161
185
  end
162
186
  end
@@ -252,7 +276,7 @@ module Cassandra
252
276
  # @raise [ArgumentError] if no block given
253
277
  # @return [self]
254
278
  def on_success(&block)
255
- raise ::ArgumentError, "no block given" unless block_given?
279
+ raise ::ArgumentError, 'no block given' unless block_given?
256
280
  @signal.on_success(&block)
257
281
  self
258
282
  end
@@ -265,7 +289,7 @@ module Cassandra
265
289
  # @raise [ArgumentError] if no block given
266
290
  # @return [self]
267
291
  def on_failure(&block)
268
- raise ::ArgumentError, "no block given" unless block_given?
292
+ raise ::ArgumentError, 'no block given' unless block_given?
269
293
  @signal.on_failure(&block)
270
294
  self
271
295
  end
@@ -281,7 +305,7 @@ module Cassandra
281
305
  # @raise [ArgumentError] if no block given
282
306
  # @return [self]
283
307
  def on_complete(&block)
284
- raise ::ArgumentError, "no block given" unless block_given?
308
+ raise ::ArgumentError, 'no block given' unless block_given?
285
309
  @signal.on_complete(&block)
286
310
  self
287
311
  end
@@ -296,8 +320,8 @@ module Cassandra
296
320
  # `#success` and `#failure`
297
321
  # @return [self]
298
322
  def add_listener(listener)
299
- unless (listener.respond_to?(:success) && listener.respond_to?(:failure))
300
- raise ::ArgumentError, "listener must respond to both #success and #failure"
323
+ unless listener.respond_to?(:success) && listener.respond_to?(:failure)
324
+ raise ::ArgumentError, 'listener must respond to both #success and #failure'
301
325
  end
302
326
 
303
327
  @signal.add_listener(listener)
@@ -325,7 +349,7 @@ module Cassandra
325
349
  # @raise [ArgumentError] if no block given
326
350
  # @return [Cassandra::Future] a new future
327
351
  def then(&block)
328
- raise ::ArgumentError, "no block given" unless block_given?
352
+ raise ::ArgumentError, 'no block given' unless block_given?
329
353
  @signal.then(&block)
330
354
  end
331
355
 
@@ -351,7 +375,7 @@ module Cassandra
351
375
  # @raise [ArgumentError] if no block given
352
376
  # @return [Cassandra::Future] a new future
353
377
  def fallback(&block)
354
- raise ::ArgumentError, "no block given" unless block_given?
378
+ raise ::ArgumentError, 'no block given' unless block_given?
355
379
  @signal.fallback(&block)
356
380
  end
357
381
 
@@ -372,7 +396,7 @@ module Cassandra
372
396
  @signal.get(timeout)
373
397
  end
374
398
 
375
- alias :join :get
399
+ alias join get
376
400
  end
377
401
 
378
402
  # @private
@@ -493,9 +517,7 @@ module Cassandra
493
517
  end
494
518
 
495
519
  def failure(error)
496
- unless error.is_a?(::Exception)
497
- raise ::ArgumentError, "error must be an exception, #{error.inspect} given"
498
- end
520
+ raise ::ArgumentError, "error must be an exception, #{error.inspect} given" unless error.is_a?(::Exception)
499
521
 
500
522
  return unless @state == :pending
501
523
 
@@ -507,12 +529,17 @@ module Cassandra
507
529
  @error = error
508
530
  @state = :broken
509
531
 
510
- listeners, @listeners = @listeners, nil
532
+ listeners = @listeners
533
+ @listeners = nil
511
534
  end
512
535
 
513
536
  @executor.execute do
514
537
  listeners.each do |listener|
515
- listener.failure(error) rescue nil
538
+ begin
539
+ listener.failure(error)
540
+ rescue
541
+ nil
542
+ end
516
543
  end
517
544
 
518
545
  synchronize do
@@ -534,12 +561,17 @@ module Cassandra
534
561
  @value = value
535
562
  @state = :fulfilled
536
563
 
537
- listeners, @listeners = @listeners, nil
564
+ listeners = @listeners
565
+ @listeners = nil
538
566
  end
539
567
 
540
568
  @executor.execute do
541
569
  listeners.each do |listener|
542
- listener.success(value) rescue nil
570
+ begin
571
+ listener.success(value)
572
+ rescue
573
+ nil
574
+ end
543
575
  end
544
576
 
545
577
  synchronize do
@@ -561,7 +593,7 @@ module Cassandra
561
593
  #
562
594
  # @return [Object] the value that the future has been resolved with
563
595
  def get(timeout = nil)
564
- timeout = timeout && Float(timeout)
596
+ timeout &&= Float(timeout)
565
597
 
566
598
  if timeout
567
599
  raise ::ArgumentError, "timeout cannot be negative, #{timeout.inspect} given" if timeout < 0
@@ -590,18 +622,18 @@ module Cassandra
590
622
 
591
623
  if @state == :pending
592
624
  total_wait = deadline - start
593
- raise Errors::TimeoutError, "Future did not complete within #{timeout.inspect} seconds. Wait time: #{total_wait.inspect}"
625
+ raise Errors::TimeoutError,
626
+ "Future did not complete within #{timeout.inspect} seconds. " \
627
+ "Wait time: #{total_wait.inspect}"
594
628
  end
595
629
  end
596
630
 
597
- if @state == :broken
598
- raise(@error, @error.message, @error.backtrace)
599
- end
631
+ raise(@error, @error.message, @error.backtrace) if @state == :broken
600
632
 
601
633
  @value
602
634
  end
603
635
 
604
- alias :join :get
636
+ alias join get
605
637
 
606
638
  def add_listener(listener)
607
639
  if @state == :pending
@@ -614,8 +646,16 @@ module Cassandra
614
646
  end
615
647
  end
616
648
 
617
- listener.success(@value) rescue nil if @state == :fulfilled
618
- listener.failure(@error) rescue nil if @state == :broken
649
+ begin
650
+ listener.success(@value)
651
+ rescue
652
+ nil
653
+ end if @state == :fulfilled
654
+ begin
655
+ listener.failure(@error)
656
+ rescue
657
+ nil
658
+ end if @state == :broken
619
659
 
620
660
  self
621
661
  end
@@ -630,7 +670,11 @@ module Cassandra
630
670
  end
631
671
  end
632
672
 
633
- yield(@value) rescue nil if @state == :fulfilled
673
+ begin
674
+ yield(@value)
675
+ rescue
676
+ nil
677
+ end if @state == :fulfilled
634
678
 
635
679
  self
636
680
  end
@@ -645,7 +689,11 @@ module Cassandra
645
689
  end
646
690
  end
647
691
 
648
- yield(@error) rescue nil if @state == :broken
692
+ begin
693
+ yield(@error)
694
+ rescue
695
+ nil
696
+ end if @state == :broken
649
697
 
650
698
  self
651
699
  end
@@ -660,7 +708,11 @@ module Cassandra
660
708
  end
661
709
  end
662
710
 
663
- yield(@value, @error) rescue nil
711
+ begin
712
+ yield(@value, @error)
713
+ rescue
714
+ nil
715
+ end
664
716
 
665
717
  self
666
718
  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.
@@ -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,9 +37,25 @@ 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
- def initialize(ip, id = nil, rack = nil, datacenter = nil, release_version = nil, tokens = EMPTY_LIST, status = :up)
50
+ def initialize(ip,
51
+ id = nil,
52
+ rack = nil,
53
+ datacenter = nil,
54
+ release_version = nil,
55
+ tokens = EMPTY_LIST,
56
+ status = :up,
57
+ broadcast_address = nil,
58
+ listen_address = nil)
43
59
  @ip = ip
44
60
  @id = id
45
61
  @rack = rack
@@ -47,6 +63,10 @@ module Cassandra
47
63
  @release_version = release_version
48
64
  @tokens = tokens
49
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
50
70
  end
51
71
 
52
72
  # @return [Boolean] whether this host's status is `:up`
@@ -72,11 +92,11 @@ module Cassandra
72
92
  def eql?(other)
73
93
  other.eql?(@ip)
74
94
  end
75
- alias :== :eql?
95
+ alias == eql?
76
96
 
77
97
  # @private
78
98
  def inspect
79
- "#<#{self.class.name}:0x#{self.object_id.to_s(16)} @ip=#{@ip}>"
99
+ "#<#{self.class.name}:0x#{object_id.to_s(16)} @ip=#{@ip}>"
80
100
  end
81
101
  end
82
102
  end
@@ -0,0 +1,118 @@
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
+ @options = options.freeze
43
+
44
+ # Target is a bit tricky; it may be an escaped name or not
45
+ # depending on C* version. Unify to be unescaped since a user
46
+ # who wants to know the target would want the bare column name.
47
+
48
+ @target = if target[0] == '"'
49
+ target[1..-2]
50
+ else
51
+ target
52
+ end.freeze
53
+ end
54
+
55
+ # @return [Boolean] whether or not this index uses a custom class.
56
+ def custom_index?
57
+ !@options['class_name'].nil?
58
+ end
59
+
60
+ # @return [String] name of the index class if this is a custom index; nil otherwise.
61
+ def custom_class_name
62
+ @options['class_name']
63
+ end
64
+
65
+ # @return [String] a cql representation of this table
66
+ def to_cql
67
+ keyspace_name = Util.escape_name(@table.keyspace.name)
68
+ table_name = Util.escape_name(@table.name)
69
+ index_name = Util.escape_name(@name)
70
+
71
+ # Target is interesting in that it's not necessarily a column name,
72
+ # so we can't simply escape it. If it contains a paren, we take it as is,
73
+ # otherwise assume it's a column name and escape accordingly.
74
+ escaped_target = @target.include?('(') ? @target : Util.escape_name(@target)
75
+
76
+ if custom_index?
77
+ "CREATE CUSTOM INDEX #{index_name} ON #{keyspace_name}.#{table_name} (#{escaped_target}) " \
78
+ "USING '#{@options['class_name']}'#{options_cql};"
79
+ else
80
+ "CREATE INDEX #{index_name} ON #{keyspace_name}.#{table_name} (#{escaped_target});"
81
+ end
82
+ end
83
+
84
+ # @private
85
+ def eql?(other)
86
+ other.is_a?(Index) &&
87
+ @table == other.table &&
88
+ @name == other.name &&
89
+ @kind == other.kind &&
90
+ @target == other.target &&
91
+ @options == other.options
92
+ end
93
+ alias == eql?
94
+
95
+ # @private
96
+ def inspect
97
+ "#<#{self.class.name}:0x#{object_id.to_s(16)} " \
98
+ "@name=#{@name.inspect} @table=#{@table.inspect} @kind=#{@kind.inspect} @target=#{@target.inspect}>"
99
+ end
100
+
101
+ private
102
+
103
+ def options_cql
104
+ # exclude 'class_name', 'target' keys
105
+ filtered_options = @options.reject do |key, _|
106
+ key == 'class_name' || key == 'target'
107
+ end
108
+ return '' if filtered_options.empty?
109
+
110
+ result = ' WITH OPTIONS = {'
111
+ result << filtered_options.map do |key, value|
112
+ "'#{key}': '#{value}'"
113
+ end.join(', ')
114
+ result << '}'
115
+ result
116
+ end
117
+ end
118
+ end