cassandra-driver 2.1.3-java → 2.1.4-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 345d45fb0e82aa5c218cbc343971f1f9067825e5
4
- data.tar.gz: 64d3a7ca35bda6993cf5d220a53b6aa4cfbc8afc
3
+ metadata.gz: 32c86970c749f6a1afe3c4af85e2d16eb62c11f9
4
+ data.tar.gz: 97c1cacbbffa03e9d1162dce3bbf0a1929b02af2
5
5
  SHA512:
6
- metadata.gz: 9dc189fe0f294bfddbdde8e6c38815a64292c365b92b367ab85861b22745aea870dfb360385489380ec3aec9ac187f1db3227f129adfd17c7a14912530c925ca
7
- data.tar.gz: f10710d0fc9d98169b42ab50b6175b7ede11a317a17c5994526fd6db6130123b04405840cba3852b55fece86f876e2b27b555aab35ce55c5f5d7fc592e48f2de
6
+ metadata.gz: 52a010f2c3254b953ff1d9af072ecba957def21236fafa3467029ef1fa4a50428c8179a5ee9cc5b9a421082347ad45da07966512bc8cf012fa687578eabcada9
7
+ data.tar.gz: 85094e7b051ae8c91c1b6caf8669383e4671ccb18095f6265c6aff8270f47fe0debde9465042e2bb1ec8070f29e8fd66d5bd6f6d6dd132ea5d54a1e99e5cf121
data/README.md CHANGED
@@ -154,7 +154,7 @@ Please [refer to the usage documentation for more information on common pitfalls
154
154
 
155
155
  ## Contributing
156
156
 
157
- For contributing read [CONTRIBUTING.md](https://github.com/datastax/ruby-driver/blob/master/README.md)
157
+ For contributing read [CONTRIBUTING.md](https://github.com/datastax/ruby-driver/blob/master/CONTRIBUTING.md)
158
158
 
159
159
  ## Credits
160
160
 
@@ -59,6 +59,9 @@ module Cassandra
59
59
  #
60
60
  # @option options [Integer] :port (9042) cassandra native protocol port.
61
61
  #
62
+ # @option options [Boolean] :nodelay (false) when set to `true`, disables
63
+ # nagle algorithm.
64
+ #
62
65
  # @option options [String] :datacenter (nil) name of current datacenter.
63
66
  # First datacenter found will be assumed current by default. Note that you
64
67
  # can skip this option if you specify only hosts from the local datacenter
@@ -122,6 +125,12 @@ module Cassandra
122
125
  # address resolver to use. Must be one of `:none` or
123
126
  # `:ec2_multi_region`.
124
127
  #
128
+ # @option options [Boolean] :client_timestamps (false) whether the driver
129
+ # should send timestamps for each executed statement. Enabling this setting
130
+ # allows mitigating Cassandra cluster clock skew because the timestamp of
131
+ # the client machine will be used. This does not help mitigate application
132
+ # cluster clock skew.
133
+ #
125
134
  # @option options [Boolean] :synchronize_schema (true) whether the driver
126
135
  # should automatically keep schema metadata synchronized. When enabled, the
127
136
  # driver updates schema metadata after receiving schema change
@@ -217,7 +226,7 @@ module Cassandra
217
226
  :connect_timeout, :futures_factory, :datacenter, :address_resolution,
218
227
  :address_resolution_policy, :idle_timeout, :heartbeat_interval, :timeout,
219
228
  :synchronize_schema, :schema_refresh_delay, :schema_refresh_timeout,
220
- :shuffle_replicas
229
+ :shuffle_replicas, :client_timestamps
221
230
  ].include?(key)
222
231
  end
223
232
 
@@ -315,10 +324,8 @@ module Cassandra
315
324
 
316
325
  case compression
317
326
  when :snappy
318
- require 'cassandra/compression/compressors/snappy'
319
327
  options[:compressor] = Compression::Compressors::Snappy.new
320
328
  when :lz4
321
- require 'cassandra/compression/compressors/lz4'
322
329
  options[:compressor] = Compression::Compressors::Lz4.new
323
330
  else
324
331
  raise ::ArgumentError, ":compression must be either :snappy or :lz4, #{compression.inspect} given"
@@ -429,6 +436,10 @@ module Cassandra
429
436
  Util.assert_one_of(CONSISTENCIES, consistency) { ":consistency must be one of #{CONSISTENCIES.inspect}, #{consistency.inspect} given" }
430
437
  end
431
438
 
439
+ if options.has_key?(:nodelay)
440
+ options[:nodelay] = !!options[:nodelay]
441
+ end
442
+
432
443
  if options.has_key?(:trace)
433
444
  options[:trace] = !!options[:trace]
434
445
  end
@@ -476,6 +487,10 @@ module Cassandra
476
487
  options[:synchronize_schema] = !!options[:synchronize_schema]
477
488
  end
478
489
 
490
+ if options.has_key?(:client_timestamps)
491
+ options[:client_timestamps] = !!options[:client_timestamps]
492
+ end
493
+
479
494
  hosts = []
480
495
 
481
496
  Array(options.fetch(:hosts, '127.0.0.1')).each do |host|
@@ -497,7 +512,7 @@ module Cassandra
497
512
 
498
513
  hosts.shuffle!
499
514
  rescue => e
500
- futures = options.fetch(:futures_factory) { Driver.new.futures_factory }
515
+ futures = options.fetch(:futures_factory) { return Future::Error.new(e) }
501
516
  futures.error(e)
502
517
  else
503
518
  driver = Driver.new(options)
@@ -207,9 +207,11 @@ module Cassandra
207
207
  def query(statement, options)
208
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
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)
211
- timeout = options.timeout
212
- promise = @futures.promise
210
+ timestamp = nil
211
+ timestamp = Time.now if @connection_options.client_timestamps? && @connection_options.protocol_version > 2
212
+ 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, timestamp)
213
+ timeout = options.timeout
214
+ promise = @futures.promise
213
215
 
214
216
  keyspace = @keyspace
215
217
  plan = @load_balancing_policy.plan(keyspace, statement, options)
@@ -234,9 +236,11 @@ module Cassandra
234
236
  end
235
237
 
236
238
  def execute(statement, options)
239
+ timestamp = nil
240
+ timestamp = Time.now if @connection_options.client_timestamps? && @connection_options.protocol_version > 2
237
241
  timeout = options.timeout
238
242
  result_metadata = statement.result_metadata
239
- request = Protocol::ExecuteRequest.new(nil, statement.params_types, statement.params, result_metadata.nil?, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?)
243
+ request = Protocol::ExecuteRequest.new(nil, statement.params_types, statement.params, result_metadata.nil?, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?, timestamp)
240
244
  promise = @futures.promise
241
245
 
242
246
  keyspace = @keyspace
@@ -250,12 +254,15 @@ module Cassandra
250
254
  def batch(statement, options)
251
255
  return @futures.error(Errors::ClientError.new("Batch statements are not supported by the current version of Apache Cassandra")) if @connection_options.protocol_version < 2
252
256
 
253
- timeout = options.timeout
254
- keyspace = @keyspace
255
- plan = @load_balancing_policy.plan(keyspace, statement, options)
256
- promise = @futures.promise
257
+ timestamp = nil
258
+ timestamp = Time.now if @connection_options.client_timestamps? && @connection_options.protocol_version > 2
259
+ timeout = options.timeout
260
+ request = Protocol::BatchRequest.new(BATCH_TYPES[statement.type], options.consistency, options.trace?, options.serial_consistency, timestamp)
261
+ keyspace = @keyspace
262
+ plan = @load_balancing_policy.plan(keyspace, statement, options)
263
+ promise = @futures.promise
257
264
 
258
- batch_by_plan(promise, keyspace, statement, options, plan, timeout)
265
+ batch_by_plan(promise, keyspace, statement, options, request, plan, timeout)
259
266
 
260
267
  promise.future
261
268
  end
@@ -509,7 +516,7 @@ module Cassandra
509
516
  end
510
517
  end
511
518
 
512
- def batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors = nil, hosts = [])
519
+ def batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors = nil, hosts = [])
513
520
  unless plan.has_next?
514
521
  promise.break(Errors::NoHostsAvailable.new(errors))
515
522
  return
@@ -522,7 +529,7 @@ module Cassandra
522
529
  unless pool
523
530
  errors ||= {}
524
531
  errors[host] = NOT_CONNECTED
525
- return batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
532
+ return batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
526
533
  end
527
534
 
528
535
  connection = pool.random_connection
@@ -531,14 +538,14 @@ module Cassandra
531
538
  switch = switch_keyspace(connection, keyspace, timeout)
532
539
  switch.on_complete do |s|
533
540
  if s.resolved?
534
- batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, options, plan, timeout, errors, hosts)
541
+ batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, request, options, plan, timeout, errors, hosts)
535
542
  else
536
543
  s.on_failure do |e|
537
544
  case e
538
545
  when Errors::HostError
539
546
  errors ||= {}
540
547
  errors[host] = e
541
- batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
548
+ batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
542
549
  else
543
550
  promise.break(e)
544
551
  end
@@ -546,16 +553,16 @@ module Cassandra
546
553
  end
547
554
  end
548
555
  else
549
- batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, options, plan, timeout, errors, hosts)
556
+ batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, request, options, plan, timeout, errors, hosts)
550
557
  end
551
558
  rescue => e
552
559
  errors ||= {}
553
560
  errors[host] = e
554
- batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
561
+ batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
555
562
  end
556
563
 
557
- def batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, options, plan, timeout, errors, hosts)
558
- request = Protocol::BatchRequest.new(BATCH_TYPES[statement.type], options.consistency, options.trace?)
564
+ def batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, request, options, plan, timeout, errors, hosts)
565
+ request.clear
559
566
  unprepared = Hash.new {|hash, cql| hash[cql] = []}
560
567
 
561
568
  statement.statements.each do |statement|
@@ -598,7 +605,7 @@ module Cassandra
598
605
  when Errors::HostError
599
606
  errors ||= {}
600
607
  errors[host] = e
601
- batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
608
+ batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
602
609
  else
603
610
  promise.break(e)
604
611
  end
@@ -711,7 +718,7 @@ module Cassandra
711
718
  when Protocol::ExecuteRequest
712
719
  execute_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
713
720
  when Protocol::BatchRequest
714
- batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
721
+ batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
715
722
  end
716
723
  else
717
724
  promise.break(error)
@@ -774,7 +781,7 @@ module Cassandra
774
781
  when Protocol::ExecuteRequest
775
782
  execute_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
776
783
  when Protocol::BatchRequest
777
- batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
784
+ batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
778
785
  else
779
786
  promise.break(e)
780
787
  end
@@ -114,6 +114,13 @@ module Cassandra
114
114
  def do_connect(host)
115
115
  @reactor.connect(host.ip.to_s, @connection_options.port, {:timeout => @connection_options.connect_timeout, :ssl => @connection_options.ssl}) do |connection|
116
116
  raise Errors::ClientError, 'Not connected, reactor stopped' unless connection
117
+
118
+ if @connection_options.nodelay?
119
+ connection.to_io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
120
+ else
121
+ connection.to_io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 0)
122
+ end
123
+
117
124
  Protocol::CqlProtocolHandler.new(connection, @reactor, @connection_options.protocol_version, @connection_options.compressor, @connection_options.heartbeat_interval, @connection_options.idle_timeout)
118
125
  end.flat_map do |connection|
119
126
  f = request_options(connection)
@@ -242,6 +242,8 @@ module Cassandra
242
242
  def refresh_schema_async
243
243
  connection = @connection
244
244
 
245
+ @logger.info("Refreshing schema")
246
+
245
247
  return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
246
248
 
247
249
  keyspaces = send_select_request(connection, SELECT_KEYSPACES)
@@ -259,6 +261,7 @@ module Cassandra
259
261
 
260
262
  @schema.update_keyspaces(host, keyspaces, tables, columns, types)
261
263
  @metadata.rebuild_token_map
264
+ @logger.info("Schema refreshed")
262
265
  end
263
266
  end
264
267
 
@@ -674,7 +677,7 @@ Control connection failed and is unlikely to recover.
674
677
  register_async
675
678
  end
676
679
  f = f.flat_map { refresh_hosts_async_maybe_retry }
677
- f = f.flat_map { refresh_schema_async_maybe_retry }
680
+ f = f.flat_map { refresh_schema_async_maybe_retry } if @connection_options.synchronize_schema?
678
681
  f = f.fallback do |error|
679
682
  @logger.debug("Connection to #{host.ip} failed (#{error.class.name}: #{error.message})")
680
683
 
@@ -80,16 +80,22 @@ module Cassandra
80
80
 
81
81
  token_ring = tokens.to_a
82
82
  token_replicas = ::Hash.new
83
+ token_maps = ::Hash.new
83
84
 
84
85
  @schema.each_keyspace do |keyspace|
85
86
  replication = keyspace.replication
86
- strategy = @strategies[replication.klass] || @default_strategy
87
+ key = replication_key(replication.klass, replication.options)
88
+
89
+ unless token_maps.include?(key)
90
+ strategy = @strategies[replication.klass] || @default_strategy
91
+ token_maps[key] = strategy.replication_map(
92
+ token_to_host,
93
+ token_ring,
94
+ replication.options
95
+ )
96
+ end
87
97
 
88
- token_replicas[keyspace.name] = strategy.replication_map(
89
- token_to_host,
90
- token_ring,
91
- replication.options
92
- )
98
+ token_replicas[keyspace.name] = token_maps[key]
93
99
  end
94
100
 
95
101
  @token_replicas = token_replicas
@@ -100,6 +106,10 @@ module Cassandra
100
106
 
101
107
  private
102
108
 
109
+ def replication_key(klass, options)
110
+ (klass + ':' + options.keys.sort.map {|k| "#{k}=#{options[k]}"}.join(',')).hash
111
+ end
112
+
103
113
  def insertion_point(list, item)
104
114
  min = 0
105
115
  max = list.size - 1
@@ -25,7 +25,7 @@ module Cassandra
25
25
  :schema_refresh_delay, :schema_refresh_timeout
26
26
  attr_accessor :protocol_version
27
27
 
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)
28
+ def initialize(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node, heartbeat_interval, idle_timeout, synchronize_schema, schema_refresh_delay, schema_refresh_timeout, client_timestamps, nodelay)
29
29
  @protocol_version = protocol_version
30
30
  @credentials = credentials
31
31
  @auth_provider = auth_provider
@@ -38,6 +38,8 @@ module Cassandra
38
38
  @synchronize_schema = synchronize_schema
39
39
  @schema_refresh_delay = schema_refresh_delay
40
40
  @schema_refresh_timeout = schema_refresh_timeout
41
+ @client_timestamps = client_timestamps
42
+ @nodelay = nodelay
41
43
 
42
44
  @connections_per_local_node = connections_per_local_node
43
45
  @connections_per_remote_node = connections_per_remote_node
@@ -47,6 +49,14 @@ module Cassandra
47
49
  @synchronize_schema
48
50
  end
49
51
 
52
+ def client_timestamps?
53
+ @client_timestamps
54
+ end
55
+
56
+ def nodelay?
57
+ @nodelay
58
+ end
59
+
50
60
  def compression
51
61
  @compressor && @compressor.algorithm
52
62
  end
@@ -385,7 +385,7 @@ module Cassandra
385
385
  index = Column::Index.new(column['index_name'])
386
386
  else
387
387
  options = ::JSON.load(column['index_options'])
388
- index = Column::Index.new(column['index_name'], options['class_name'])
388
+ index = Column::Index.new(column['index_name'], options && options['class_name'])
389
389
  end
390
390
 
391
391
  Column.new(name, type, order, index, is_static, is_frozen)
@@ -24,56 +24,65 @@ module Cassandra
24
24
  # @private
25
25
  class NetworkTopology
26
26
  def replication_map(token_hosts, token_ring, replication_options)
27
- size = token_ring.size
28
- racks = ::Hash.new
29
- token_hosts.each_value do |host|
27
+ racks = ::Hash.new
28
+ datacenter_token_rings = ::Hash.new
29
+ size = token_ring.size
30
+
31
+ token_ring.each_with_index do |token, i|
32
+ host = token_hosts[token]
33
+
30
34
  racks[host.datacenter] ||= ::Set.new
31
35
  racks[host.datacenter].add(host.rack)
36
+
37
+ datacenter_token_rings[host.datacenter] ||= Hash.new
38
+ datacenter_token_rings[host.datacenter][i] = token
32
39
  end
33
40
 
34
41
  replication_map = ::Hash.new
35
42
 
36
43
  token_ring.each_with_index do |token, i|
37
- all_replicas = ::Hash.new
38
- visited = ::Hash.new
39
- skipped_datacenter_hosts = ::Hash.new
40
44
  replicas = ::Set.new
45
+ visited = ::Hash.new
46
+ skipped = ::Hash.new
41
47
 
42
- size.times do |j|
43
- break if all_replicas.size == racks.size && !all_replicas.any? {|(datacenter, r)| r.size < Integer(replication_options[datacenter])}
44
-
45
- host = token_hosts[token_ring[(i + j) % size]]
46
- datacenter = host.datacenter
47
- next if datacenter.nil?
48
+ replication_options.each do |datacenter, factor|
49
+ ring = datacenter_token_rings[datacenter]
50
+ next unless ring
51
+ factor = [Integer(factor), ring.size].min rescue next
48
52
 
49
- factor = replication_options[datacenter]
50
- next unless factor
51
53
 
52
- factor = Integer(factor) rescue next
54
+ total_racks = racks[datacenter].size
55
+ visited_racks = visited[datacenter] ||= ::Set.new
56
+ skipped_hosts = skipped[datacenter] ||= ::Set.new
57
+ added_replicas = ::Set.new
53
58
 
54
- replicas_in_datacenter = all_replicas[datacenter] ||= ::Set.new
55
- next if replicas_in_datacenter.size >= factor
59
+ size.times do |j|
60
+ break if added_replicas.size >= factor
56
61
 
57
- rack = host.rack
58
- visited_racks = visited[datacenter] ||= ::Set.new
62
+ tk = ring[(i + j) % size]
63
+ next unless tk
64
+ host = token_hosts[tk]
65
+ rack = host.rack
59
66
 
60
- if rack.nil? || visited_racks.size == racks[datacenter].size
61
- replicas << host
62
- replicas_in_datacenter << host
63
- else
64
- if visited_racks.include?(rack)
65
- skipped_hosts = skipped_datacenter_hosts[datacenter] ||= ::Set.new
66
- skipped_hosts << host
67
- else
67
+ # unknown rack or seen all racks
68
+ if rack.nil? || visited_racks.size == total_racks
68
69
  replicas << host
69
- replicas_in_datacenter << host
70
- visited_racks << rack
71
-
72
- if visited_racks.size == racks[datacenter].size && (skipped_hosts = skipped_datacenter_hosts[datacenter]) && replicas_in_datacenter.size < factor
73
- skipped_hosts.each do |skipped_host|
74
- replicas << skipped_host
75
- replicas_in_datacenter << skipped_host
76
- break if replicas_in_datacenter.size >= factor
70
+ added_replicas << host
71
+ else
72
+ if visited_racks.include?(rack)
73
+ skipped_hosts << host
74
+ else
75
+ replicas << host
76
+ visited_racks << rack
77
+ added_replicas << host
78
+
79
+ if visited_racks.size == total_racks
80
+ skipped_hosts.each do |skipped_host|
81
+ break if added_replicas.size >= factor
82
+
83
+ replicas << skipped_host
84
+ added_replicas << host
85
+ end
77
86
  end
78
87
  end
79
88
  end
@@ -108,7 +108,7 @@ module Cassandra
108
108
  return lookup_type(node.children.first)
109
109
  end
110
110
 
111
- type = @@types[node.name]
111
+ type = @@types.fetch(node.name) { return Cassandra::Types.custom(dump_node(node)) }
112
112
 
113
113
  case type
114
114
  when :set, :list
@@ -159,6 +159,12 @@ module Cassandra
159
159
 
160
160
  root
161
161
  end
162
+
163
+ def dump_node(node)
164
+ str = node.name
165
+ str << '(' + node.children.map {|n| dump_node(n)}.join(',') + ')' unless node.children.empty?
166
+ str
167
+ end
162
168
  end
163
169
  end
164
170
  end
@@ -64,3 +64,6 @@ module Cassandra
64
64
  end
65
65
  end
66
66
  end
67
+
68
+ require 'cassandra/compression/compressors/snappy'
69
+ require 'cassandra/compression/compressors/lz4'
@@ -16,12 +16,6 @@
16
16
  # limitations under the License.
17
17
  #++
18
18
 
19
- begin
20
- require 'lz4-ruby'
21
- rescue LoadError => e
22
- raise LoadError, %[LZ4 support requires the "lz4-ruby" gem: #{e.message}], e.backtrace
23
- end
24
-
25
19
  module Cassandra
26
20
  module Compression
27
21
  module Compressors
@@ -40,6 +34,14 @@ module Cassandra
40
34
  # @param [Integer] min_size (64) Don't compress frames smaller than
41
35
  # this size (see {#compress?}).
42
36
  def initialize(min_size=64)
37
+ unless defined?(::LZ4::Raw)
38
+ begin
39
+ require 'lz4-ruby'
40
+ rescue LoadError => e
41
+ raise LoadError, %[LZ4 support requires the "lz4-ruby" gem: #{e.message}], e.backtrace
42
+ end
43
+ end
44
+
43
45
  @algorithm = 'lz4'.freeze
44
46
  @min_size = min_size
45
47
  end
@@ -16,12 +16,6 @@
16
16
  # limitations under the License.
17
17
  #++
18
18
 
19
- begin
20
- require 'snappy'
21
- rescue LoadError => e
22
- raise LoadError, %[Snappy support requires the "snappy" gem: #{e.message}], e.backtrace
23
- end
24
-
25
19
  module Cassandra
26
20
  module Compression
27
21
  module Compressors
@@ -40,6 +34,14 @@ module Cassandra
40
34
  # @param [Integer] min_size (64) Don't compress frames smaller than
41
35
  # this size (see {#compress?}).
42
36
  def initialize(min_size=64)
37
+ unless defined?(::Snappy)
38
+ begin
39
+ require 'snappy'
40
+ rescue LoadError => e
41
+ raise LoadError, %[Snappy support requires the "snappy" gem: #{e.message}], e.backtrace
42
+ end
43
+ end
44
+
43
45
  @algorithm = 'snappy'.freeze
44
46
  @min_size = min_size
45
47
  end
@@ -86,7 +86,9 @@ module Cassandra
86
86
  idle_timeout,
87
87
  synchronize_schema,
88
88
  schema_refresh_delay,
89
- schema_refresh_timeout
89
+ schema_refresh_timeout,
90
+ client_timestamps,
91
+ nodelay
90
92
  )
91
93
  end
92
94
 
@@ -114,6 +116,8 @@ module Cassandra
114
116
  let(:schema_refresh_timeout) { 10 }
115
117
  let(:thread_pool_size) { 4 }
116
118
  let(:shuffle_replicas) { true }
119
+ let(:client_timestamps) { false }
120
+ let(:nodelay) { false }
117
121
 
118
122
  let(:connections_per_local_node) { 2 }
119
123
  let(:connections_per_remote_node) { 1 }
@@ -143,7 +147,11 @@ module Cassandra
143
147
  if f.resolved?
144
148
  promise.fulfill(cluster)
145
149
  else
146
- f.on_failure {|e| promise.break(e)}
150
+ f.on_failure do |e|
151
+ cluster.close_async.on_complete do |_, _|
152
+ promise.break(e)
153
+ end
154
+ end
147
155
  end
148
156
  end
149
157
 
@@ -258,6 +258,10 @@ module Cassandra
258
258
  self
259
259
  end
260
260
 
261
+ def append_timestamp(timestamp)
262
+ append_long(timestamp.tv_sec * 1000000 + timestamp.tv_usec)
263
+ end
264
+
261
265
  def append_long(n)
262
266
  top = n >> 32
263
267
  bottom = n & 0xffffffff
@@ -23,14 +23,21 @@ module Cassandra
23
23
  UNLOGGED_TYPE = 1
24
24
  COUNTER_TYPE = 2
25
25
 
26
- attr_reader :type
26
+ attr_reader :type, :timestamp
27
27
  attr_accessor :consistency, :retries
28
28
 
29
- def initialize(type, consistency, trace=false)
29
+ def initialize(type, consistency, trace=false, serial_consistency = nil, timestamp = nil)
30
30
  super(0x0D, trace)
31
31
  @type = type
32
32
  @parts = []
33
33
  @consistency = consistency
34
+ @serial_consistency = serial_consistency
35
+ @timestamp = timestamp
36
+ end
37
+
38
+ def clear
39
+ @parts.clear
40
+ nil
34
41
  end
35
42
 
36
43
  def add_query(cql, values, types)
@@ -54,9 +61,13 @@ module Cassandra
54
61
  buffer.append_consistency(@consistency)
55
62
 
56
63
  if protocol_version > 2
57
- flags = 0
64
+ flags = 0
65
+ flags |= 0x10 if @serial_consistency
66
+ flags |= 0x20 if @timestamp
58
67
 
59
68
  buffer.append(flags.chr)
69
+ buffer.append_consistency(@serial_consistency) if @serial_consistency
70
+ buffer.append_timestamp(@timestamp) if @timestamp
60
71
  end
61
72
 
62
73
  buffer
@@ -19,10 +19,10 @@
19
19
  module Cassandra
20
20
  module Protocol
21
21
  class ExecuteRequest < Request
22
- attr_reader :metadata, :values, :request_metadata, :serial_consistency, :page_size, :paging_state
22
+ attr_reader :metadata, :values, :request_metadata, :serial_consistency, :page_size, :paging_state, :timestamp
23
23
  attr_accessor :consistency, :retries, :id
24
24
 
25
- def initialize(id, metadata, values, request_metadata, consistency, serial_consistency=nil, page_size=nil, paging_state=nil, trace=false)
25
+ def initialize(id, metadata, values, request_metadata, consistency, serial_consistency=nil, page_size=nil, paging_state=nil, trace=false, timestamp = nil)
26
26
  raise ArgumentError, "Metadata for #{metadata.size} columns, but #{values.size} values given" if metadata.size != values.size
27
27
  raise ArgumentError, %(No such consistency: #{consistency.inspect}) if consistency.nil? || !CONSISTENCIES.include?(consistency)
28
28
  raise ArgumentError, %(No such consistency: #{serial_consistency.inspect}) unless serial_consistency.nil? || CONSISTENCIES.include?(serial_consistency)
@@ -36,6 +36,7 @@ module Cassandra
36
36
  @serial_consistency = serial_consistency
37
37
  @page_size = page_size
38
38
  @paging_state = paging_state
39
+ @timestamp = timestamp
39
40
  end
40
41
 
41
42
  def write(buffer, protocol_version, encoder)
@@ -48,6 +49,9 @@ module Cassandra
48
49
  flags |= 0x04 if @page_size
49
50
  flags |= 0x08 if @paging_state
50
51
  flags |= 0x10 if @serial_consistency
52
+ if protocol_version > 2
53
+ flags |= 0x20 if @timestamp
54
+ end
51
55
  buffer.append(flags.chr)
52
56
  if @values.size > 0
53
57
  encoder.write_parameters(buffer, @values, @metadata)
@@ -55,6 +59,9 @@ module Cassandra
55
59
  buffer.append_int(@page_size) if @page_size
56
60
  buffer.append_bytes(@paging_state) if @paging_state
57
61
  buffer.append_consistency(@serial_consistency) if @serial_consistency
62
+ if protocol_version > 2
63
+ buffer.append_timestamp(@timestamp) if @timestamp
64
+ end
58
65
  else
59
66
  encoder.write_parameters(buffer, @values, @metadata)
60
67
  buffer.append_consistency(@consistency)
@@ -19,10 +19,10 @@
19
19
  module Cassandra
20
20
  module Protocol
21
21
  class QueryRequest < Request
22
- attr_reader :cql, :values, :type_hints, :serial_consistency, :page_size, :paging_state
22
+ attr_reader :cql, :values, :type_hints, :serial_consistency, :page_size, :paging_state, :timestamp
23
23
  attr_accessor :consistency, :retries
24
24
 
25
- def initialize(cql, values, type_hints, consistency, serial_consistency = nil, page_size = nil, paging_state = nil, trace = false, names = EMPTY_LIST)
25
+ def initialize(cql, values, type_hints, consistency, serial_consistency = nil, page_size = nil, paging_state = nil, trace = false, names = EMPTY_LIST, timestamp = nil)
26
26
  super(7, trace)
27
27
  @cql = cql
28
28
  @values = values
@@ -32,6 +32,7 @@ module Cassandra
32
32
  @page_size = page_size
33
33
  @paging_state = paging_state
34
34
  @names = names
35
+ @timestamp = timestamp
35
36
  end
36
37
 
37
38
  def write(buffer, protocol_version, encoder)
@@ -42,9 +43,14 @@ module Cassandra
42
43
  flags |= 0x04 if @page_size
43
44
  flags |= 0x08 if @paging_state
44
45
  flags |= 0x10 if @serial_consistency
46
+ if protocol_version > 2
47
+ flags |= 0x20 if @timestamp
48
+ end
45
49
  if @values && @values.size > 0
46
50
  flags |= 0x01
47
- flags |= 0x40 unless @names.empty?
51
+ if protocol_version > 2
52
+ flags |= 0x40 unless @names.empty?
53
+ end
48
54
  buffer.append(flags.chr)
49
55
  encoder.write_parameters(buffer, @values, @type_hints, @names)
50
56
  else
@@ -53,6 +59,9 @@ module Cassandra
53
59
  buffer.append_int(@page_size) if @page_size
54
60
  buffer.append_bytes(@paging_state) if @paging_state
55
61
  buffer.append_consistency(@serial_consistency) if @serial_consistency
62
+ if protocol_version > 2
63
+ buffer.append_timestamp(@timestamp) if @timestamp
64
+ end
56
65
  end
57
66
  buffer
58
67
  end
@@ -1199,8 +1199,13 @@ module Cassandra
1199
1199
 
1200
1200
  # @return [String] a cassandra representation of this type
1201
1201
  def to_s
1202
- "custom: #{@name}"
1202
+ "'#{@name}'"
1203
1203
  end
1204
+
1205
+ def eql?(other)
1206
+ other.is_a?(Custom) && @name == other.name
1207
+ end
1208
+ alias :== :eql?
1204
1209
  end
1205
1210
 
1206
1211
  # @return [Cassandra::Types::Varchar] varchar type
@@ -17,5 +17,5 @@
17
17
  #++
18
18
 
19
19
  module Cassandra
20
- VERSION = '2.1.3'.freeze
20
+ VERSION = '2.1.4'.freeze
21
21
  end
Binary file
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # Copyright 2013-2015 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 DataStax
20
+ @base = __FILE__ + '/../..'
21
+
22
+ def self.require(path)
23
+ if path.start_with?('cassandra/')
24
+ include(path)
25
+ else
26
+ ::Kernel.require(path)
27
+ end
28
+ end
29
+
30
+ def self.include(path)
31
+ path = File.expand_path(path + '.rb', @base)
32
+ class_eval(File.read(path), path, 1)
33
+ end
34
+
35
+ previous = nil
36
+ if defined?(::Cassandra)
37
+ previous = ::Cassandra
38
+ Object.send(:remove_const, :Cassandra)
39
+ end
40
+ include 'cassandra'
41
+ DataStax::Cassandra::Murmur3 = ::Cassandra::Murmur3
42
+ Object.send(:remove_const, :Cassandra)
43
+ ::Cassandra = previous if previous
44
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cassandra-driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.3
4
+ version: 2.1.4
5
5
  platform: java
6
6
  authors:
7
7
  - Theo Hultberg
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-13 00:00:00.000000000 Z
12
+ date: 2015-07-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ione
@@ -180,6 +180,7 @@ files:
180
180
  - lib/cassandra/uuid/generator.rb
181
181
  - lib/cassandra/version.rb
182
182
  - lib/cassandra_murmur3.jar
183
+ - lib/datastax/cassandra.rb
183
184
  homepage: http://datastax.github.io/ruby-driver
184
185
  licenses:
185
186
  - Apache License 2.0