cassandra 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ v0.18.0
2
+ - Cassandra 1.2 support (issue #175, courtesy @brainopia)
3
+ - drop_keyspace defaults to current keyspace (issue #176, courtesy @brianopia)
4
+ - Easier flush_batch interface (issue #182, courtesy @brianopia)
5
+ - Support for removing multiple columns (issue #183, courtesy @brianopia)
6
+
1
7
  v0.17.0
2
8
  - multi_get_columns with only one query (courtesy @christian-blades-cb)
3
9
  - documentation fixes for get and multi_get (issue #136, courtesy @christian-blades-cb)
data/Rakefile CHANGED
@@ -22,7 +22,8 @@ CassandraBinaries = {
22
22
  '0.7' => 'http://archive.apache.org/dist/cassandra/0.7.9/apache-cassandra-0.7.9-bin.tar.gz',
23
23
  '0.8' => 'http://archive.apache.org/dist/cassandra/0.8.7/apache-cassandra-0.8.7-bin.tar.gz',
24
24
  '1.0' => 'http://archive.apache.org/dist/cassandra/1.0.6/apache-cassandra-1.0.6-bin.tar.gz',
25
- '1.1' => 'http://archive.apache.org/dist/cassandra/1.1.5/apache-cassandra-1.1.5-bin.tar.gz'
25
+ '1.1' => 'http://archive.apache.org/dist/cassandra/1.1.5/apache-cassandra-1.1.5-bin.tar.gz',
26
+ '1.2' => 'http://archive.apache.org/dist/cassandra/1.2.1/apache-cassandra-1.2.1-bin.tar.gz'
26
27
  }
27
28
 
28
29
  CASSANDRA_HOME = ENV['CASSANDRA_HOME'] || "#{ENV['HOME']}/cassandra"
data/cassandra.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "cassandra"
5
- s.version = "0.17.0"
5
+ s.version = "0.18.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0.8") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Evan Weaver, Ryan King"]
@@ -1,4 +1,3 @@
1
-
2
1
  =begin rdoc
3
2
  Create a new Cassandra client instance. Accepts a keyspace name, and optional host and port.
4
3
 
@@ -353,7 +352,7 @@ class Cassandra
353
352
  #
354
353
  # Returns the new schema id.
355
354
  #
356
- def drop_keyspace(keyspace)
355
+ def drop_keyspace(keyspace=@keyspace)
357
356
  return false if Cassandra.VERSION.to_f < 0.7
358
357
 
359
358
  begin
@@ -481,27 +480,31 @@ class Cassandra
481
480
  # * :timestamp - Uses the current time if none specified.
482
481
  # * :consistency - Uses the default write consistency if none specified.
483
482
  #
484
- # TODO: we could change this function or add another that support multi-column removal (by list or predicate)
485
- #
486
483
  def remove(column_family, key, *columns_and_options)
487
- column_family, column, sub_column, options = extract_and_validate_params(column_family, key, columns_and_options, WRITE_DEFAULTS)
484
+ column_family, columns, sub_column, options = extract_and_validate_params(column_family, key, columns_and_options, WRITE_DEFAULTS)
488
485
 
489
- if @batch
490
- mutation_map =
491
- {
492
- key => {
493
- column_family => [ _delete_mutation(column_family, column, sub_column, options[:timestamp]|| Time.stamp) ]
494
- }
495
- }
496
- @batch << [mutation_map, options[:consistency]]
486
+ if columns.is_a? Array
487
+ if sub_column
488
+ raise ArgumentError, 'remove does not support sub_columns with array of columns'
489
+ end
497
490
  else
498
- # Let's continue using the 'remove' thrift method...not sure about the implications/performance of using the mutate instead
499
- # Otherwise we coul get use the mutation_map above, and do _mutate(mutation_map, options[:consistency])
500
- args = {:column_family => column_family}
501
- columns = is_super(column_family) ? {:super_column => column, :column => sub_column} : {:column => column}
502
- column_path = CassandraThrift::ColumnPath.new(args.merge(columns))
503
- _remove(key, column_path, options[:timestamp] || Time.stamp, options[:consistency])
491
+ columns = [columns]
504
492
  end
493
+
494
+ timestamp = options[:timestamp]|| Time.stamp
495
+
496
+ mutation_map =
497
+ {
498
+ key => {
499
+ column_family => columns.map {|column|
500
+ _delete_mutation(column_family, column, sub_column, timestamp)
501
+ }
502
+ }
503
+ }
504
+
505
+ mutation = [mutation_map, options[:consistency]]
506
+
507
+ @batch ? @batch << mutation : _mutate(*mutation)
505
508
  end
506
509
 
507
510
  ##
@@ -571,7 +574,7 @@ class Cassandra
571
574
  # * :consistency - Uses the default read consistency if none specified.
572
575
  #
573
576
  def multi_get_columns(column_family, keys, *columns_and_options)
574
- column_family, columns, sub_columns, options =
577
+ column_family, columns, sub_columns, options =
575
578
  extract_and_validate_params(column_family, keys, columns_and_options, READ_DEFAULTS)
576
579
  _multi_get_columns(column_family, keys, columns, sub_columns, options[:consistency])
577
580
  end
@@ -861,7 +864,7 @@ class Cassandra
861
864
  ##
862
865
  # Send the batch queue to the server
863
866
  #
864
- def flush_batch(options)
867
+ def flush_batch(options={})
865
868
  compacted_map,seen_clevels = compact_mutations!
866
869
 
867
870
  clevel = if options[:consistency] != nil # Override any clevel from individual mutations if
@@ -874,7 +877,7 @@ class Cassandra
874
877
 
875
878
  _mutate(compacted_map,clevel)
876
879
  end
877
-
880
+
878
881
  ##
879
882
  # Create secondary index.
880
883
  #
@@ -151,15 +151,26 @@ class Cassandra
151
151
  end
152
152
 
153
153
  def remove(column_family, key, *columns_and_options)
154
- column_family, column, sub_column, options = extract_and_validate_params_for_real(column_family, key, columns_and_options, WRITE_DEFAULTS)
154
+ column_family, columns, sub_column, options = extract_and_validate_params_for_real(column_family, key, columns_and_options, WRITE_DEFAULTS)
155
+
155
156
  if @batch
156
- @batch << [:remove, column_family, key, column, sub_column]
157
+ @batch << [:remove, column_family, key, columns, sub_column]
157
158
  else
158
- if column
159
+ if columns
159
160
  if sub_column
160
- cf(column_family)[key][column].delete(sub_column.to_s) if cf(column_family)[key][column]
161
+ if columns.is_a? Array
162
+ raise ArgumentError, 'remove does not support sub_columns with array of columns'
163
+ end
164
+
165
+ if cf(column_family)[key][columns]
166
+ cf(column_family)[key][columns].delete(sub_column.to_s)
167
+ end
161
168
  else
162
- cf(column_family)[key].delete(column.to_s) if cf(column_family)[key]
169
+ if cf(column_family)[key]
170
+ Array(columns).each do |column|
171
+ cf(column_family)[key].delete(column.to_s)
172
+ end
173
+ end
163
174
  end
164
175
  else
165
176
  cf(column_family).delete(key)
@@ -428,6 +428,13 @@ class CassandraTest < Test::Unit::TestCase
428
428
  assert_nil @twitter.get(:Statuses, key).timestamps['body']
429
429
  end
430
430
 
431
+ def test_remove_values
432
+ @twitter.insert(:Statuses, key, {'body' => 'v', 'location' => 'v'})
433
+ @twitter.remove(:Statuses, key, ['body', 'location'])
434
+ assert_nil @twitter.get(:Statuses, key, 'body')
435
+ assert_nil @twitter.get(:Statuses, key, 'location')
436
+ end
437
+
431
438
  def test_remove_super_key
432
439
  @twitter.insert(:StatusRelationships, key, {'user_timelines' => {@uuids[1] => 'v1'}})
433
440
  @twitter.remove(:StatusRelationships, key)
@@ -1327,6 +1334,24 @@ class CassandraTest < Test::Unit::TestCase
1327
1334
  assert(columns.timestamps[@uuids[1]] / 1000000 >= base_time.to_i)
1328
1335
  end
1329
1336
 
1337
+ def test_keyspace_operations
1338
+ system = Cassandra.new 'system'
1339
+ keyspace_name = 'robots'
1340
+ keyspace_definition = Cassandra::Keyspace.new :name => keyspace_name,
1341
+ :strategy_class => 'SimpleStrategy',
1342
+ :strategy_options => { 'replication_factor' => '2' },
1343
+ :cf_defs => []
1344
+ system.add_keyspace keyspace_definition
1345
+ assert system.keyspaces.any? {|it| it == keyspace_name }
1346
+
1347
+ system.drop_keyspace keyspace_name
1348
+ assert system.keyspaces.none? {|it| it == keyspace_name }
1349
+
1350
+ system.add_keyspace keyspace_definition
1351
+ Cassandra.new(keyspace_name).drop_keyspace
1352
+ assert system.keyspaces.none? {|it| it == keyspace_name }
1353
+ end
1354
+
1330
1355
  private
1331
1356
 
1332
1357
  def key
data/test/test_helper.rb CHANGED
@@ -5,7 +5,11 @@ require "#{File.expand_path(File.dirname(__FILE__))}/../lib/cassandra/#{CASSANDR
5
5
  begin; require 'ruby-debug'; rescue LoadError; end
6
6
 
7
7
  begin
8
- @test_client = Cassandra.new('Twitter', 'localhost:9160', {:exception_classes => []})
8
+ @test_client = Cassandra.new('Twitter', 'localhost:9160', :thrift_client_options => {
9
+ :retries => 3,
10
+ :timeout => 5,
11
+ :connect_timeout => 1
12
+ })
9
13
  rescue Thrift::TransportException => e
10
14
  #FIXME Make server automatically start if not running
11
15
  if e.message =~ /Could not connect/
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 17
7
+ - 18
8
8
  - 0
9
- version: 0.17.0
9
+ version: 0.18.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Evan Weaver, Ryan King