cassandra 0.6 → 0.7

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.
data.tar.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -1,3 +1,6 @@
1
+ v0.7 Various improvements.
2
+ - Compatibility with Cassandra 0.5.
3
+ - performance improvements
1
4
 
2
5
  v0.6. Use thrift_client gem.
3
6
 
data/README CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  cassandra
3
2
 
4
3
  A Ruby client for the Cassandra distributed database.
@@ -37,7 +36,7 @@ Now, start IRb and require the library:
37
36
 
38
37
  Connect to a server and keyspace:
39
38
 
40
- client = Cassandra.new('Twitter', "127.0.0.1")
39
+ client = Cassandra.new('Twitter', '127.0.0.1:9160')
41
40
 
42
41
  Insert into a column family. You can insert a Cassandra::OrderedHash, or a regular Hash, if order doesn't matter:
43
42
 
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ unless ENV['FROM_BIN_CASSANDRA_HELPER']
8
8
  p.project = "fauna"
9
9
  p.summary = "A Ruby client for the Cassandra distributed database."
10
10
  p.rubygems_version = ">= 0.8"
11
- p.dependencies = ['thrift_client', 'rake']
11
+ p.dependencies = ['thrift_client', 'json', 'rake']
12
12
  p.ignore_pattern = /^(data|vendor\/cassandra|cassandra|vendor\/thrift)/
13
13
  p.rdoc_pattern = /^(lib|bin|tasks|ext)|^README|^CHANGELOG|^TODO|^LICENSE|^COPYING$/
14
14
  p.url = "http://blog.evanweaver.com/files/doc/fauna/cassandra/"
@@ -16,7 +16,7 @@ unless ENV['FROM_BIN_CASSANDRA_HELPER']
16
16
  end
17
17
  end
18
18
 
19
- REVISION = "c1fa17c0e359fa032bdb2d6b5f63120359ff881f"
19
+ REVISION = "c4cc3505855c157a0887611cd9abe6f996bde345"
20
20
 
21
21
  PATCHES = []
22
22
 
@@ -35,7 +35,7 @@ task :cassandra => [:build_cassandra, CASSANDRA_TEST] do
35
35
  if !ENV["CASSANDRA_INCLUDE"]
36
36
  env << "CASSANDRA_INCLUDE=#{Dir.pwd}/conf/cassandra.in.sh "
37
37
  env << "CASSANDRA_HOME=#{CASSANDRA_HOME} "
38
- env << "CASSANDRA_CONF=#{File.expand_path(File.dirname(__FILE__))}/conf"
38
+ env << "CASSANDRA_CONF=#{Dir.pwd}/conf"
39
39
  end
40
40
  # Start server
41
41
  Dir.chdir(CASSANDRA_TEST) do
@@ -2,12 +2,12 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{cassandra}
5
- s.version = "0.6"
5
+ s.version = "0.7"
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"]
9
- s.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
10
- s.date = %q{2009-11-18}
9
+ s.cert_chain = ["/Users/ryan/.gemkeys/gem-public_cert.pem"]
10
+ s.date = %q{2010-01-08}
11
11
  s.default_executable = %q{cassandra_helper}
12
12
  s.description = %q{A Ruby client for the Cassandra distributed database.}
13
13
  s.email = %q{}
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
  s.rubyforge_project = %q{fauna}
21
21
  s.rubygems_version = %q{1.3.5}
22
- s.signing_key = %q{/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-private_key.pem}
22
+ s.signing_key = %q{/Users/ryan/.gemkeys/gem-private_key.pem}
23
23
  s.summary = %q{A Ruby client for the Cassandra distributed database.}
24
24
  s.test_files = ["test/cassandra_test.rb", "test/comparable_types_test.rb", "test/test_helper.rb"]
25
25
 
@@ -29,13 +29,16 @@ Gem::Specification.new do |s|
29
29
 
30
30
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
31
31
  s.add_runtime_dependency(%q<thrift_client>, [">= 0"])
32
+ s.add_runtime_dependency(%q<json>, [">= 0"])
32
33
  s.add_runtime_dependency(%q<rake>, [">= 0"])
33
34
  else
34
35
  s.add_dependency(%q<thrift_client>, [">= 0"])
36
+ s.add_dependency(%q<json>, [">= 0"])
35
37
  s.add_dependency(%q<rake>, [">= 0"])
36
38
  end
37
39
  else
38
40
  s.add_dependency(%q<thrift_client>, [">= 0"])
41
+ s.add_dependency(%q<json>, [">= 0"])
39
42
  s.add_dependency(%q<rake>, [">= 0"])
40
43
  end
41
44
  end
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'thrift_client'
3
+ require 'json'
3
4
 
4
5
  here = File.expand_path(File.dirname(__FILE__))
5
6
 
@@ -37,10 +37,8 @@ class Cassandra
37
37
  include CassandraThrift::ConsistencyLevel
38
38
  end
39
39
 
40
- MAX_INT = 2**31 - 1
41
-
42
40
  WRITE_DEFAULTS = {
43
- :count => MAX_INT,
41
+ :count => 1000,
44
42
  :timestamp => nil,
45
43
  :consistency => Consistency::ONE
46
44
  }.freeze
@@ -72,13 +70,18 @@ class Cassandra
72
70
 
73
71
 
74
72
  def client
75
- @client ||= begin
76
- client = ThriftClient.new(CassandraThrift::Cassandra::Client, @servers, @thrift_client_options)
77
- unless client.get_string_list_property("keyspaces").include?(@keyspace)
78
- raise AccessError, "Keyspace #{@keyspace.inspect} not found. Available: #{keyspaces.inspect}"
79
- end
80
- client
73
+ return @client if defined?(@client)
74
+ client!
75
+ end
76
+
77
+ def client!
78
+ @client = raw_client
79
+ unless (keyspaces = client.get_string_list_property("keyspaces")).include?(@keyspace)
80
+ raise AccessError, "Keyspace #{@keyspace.inspect} not found. Available: #{keyspaces.inspect}"
81
81
  end
82
+ @servers = all_nodes
83
+ @client.disconnect!
84
+ @client = raw_client
82
85
  end
83
86
 
84
87
  def keyspaces
@@ -128,7 +131,9 @@ class Cassandra
128
131
  # FIXME May not currently delete all records without multiple calls. Waiting
129
132
  # for ranged remove support in Cassandra.
130
133
  def clear_column_family!(column_family, options = {})
131
- get_range(column_family).each { |key| remove(column_family, key, options) }
134
+ while (keys = get_range(column_family, :count => 100)).length > 0
135
+ keys.each { |key| remove(column_family, key, options) }
136
+ end
132
137
  end
133
138
 
134
139
  # Remove all rows in the keyspace. Supports options <tt>:consistency</tt> and
@@ -214,9 +219,15 @@ class Cassandra
214
219
  # Count all rows in the column_family you request. Requires the table
215
220
  # to be partitioned with OrderPreservingHash. Supports the <tt>:start</tt>,
216
221
  # <tt>:finish</tt>, and <tt>:consistency</tt> options.
217
- # FIXME will count only MAX_INT records
218
222
  def count_range(column_family, options = {})
219
- get_range(column_family, options.merge(:count => MAX_INT)).size
223
+ count = 0
224
+ l = []
225
+ start_key = ''
226
+ while (l = get_range(column_family, options.merge(:count => 1000, :start => start_key))).size > 0
227
+ count += l.size
228
+ start_key = l.last.succ
229
+ end
230
+ count
220
231
  end
221
232
 
222
233
  # Open a batch operation and yield. Inserts and deletes will be queued until
@@ -298,4 +309,14 @@ class Cassandra
298
309
  @schema ||= client.describe_keyspace(@keyspace)
299
310
  end
300
311
  end
312
+
313
+ def raw_client
314
+ ThriftClient.new(CassandraThrift::Cassandra::Client, @servers, @thrift_client_options)
315
+ end
316
+
317
+ def all_nodes
318
+ ips = ::JSON.parse(@client.get_string_property('token map')).values
319
+ port = @servers.first.split(':').last
320
+ ips.map{|ip| "#{ip}:#{port}" }
321
+ end
301
322
  end
@@ -18,7 +18,7 @@ class Cassandra
18
18
  end
19
19
 
20
20
  def ==(other)
21
- self.to_i == other.to_i
21
+ other.respond_to?(:to_i) && self.to_i == other.to_i
22
22
  end
23
23
 
24
24
  def to_s
@@ -38,7 +38,7 @@ class Cassandra
38
38
  CassandraThrift::SlicePredicate.new(:column_names => columns),
39
39
  consistency))
40
40
  end
41
- sub_columns || columns.map { |name| result[name] }
41
+ (sub_columns || columns).map { |name| result[name] }
42
42
  end
43
43
 
44
44
  def _multiget(column_family, keys, column, sub_column, count, start, finish, reversed, consistency)
@@ -91,6 +91,10 @@ class Cassandra
91
91
  total_usecs <=> other.send(:total_usecs)
92
92
  end
93
93
 
94
+ def ==(other)
95
+ to_s == other.to_s
96
+ end
97
+
94
98
  def inspect(long = false)
95
99
  "<Cassandra::UUID##{object_id} time: #{
96
100
  Time.at(seconds).inspect
@@ -24,15 +24,6 @@ class CassandraTest < Test::Unit::TestCase
24
24
  end
25
25
  end
26
26
 
27
- def test_connection_reopens
28
- assert_raises(Thrift::ProtocolException) do
29
- @twitter.send("_insert", [], -5, '')
30
- end
31
- assert_nothing_raised do
32
- @twitter.insert(:Statuses, key, {'body' => 'v'})
33
- end
34
- end
35
-
36
27
  def test_get_key
37
28
  @twitter.insert(:Users, key, {'body' => 'v', 'user' => 'v'})
38
29
  assert_equal({'body' => 'v', 'user' => 'v'}, @twitter.get(:Users, key))
@@ -324,6 +315,13 @@ class CassandraTest < Test::Unit::TestCase
324
315
  end
325
316
  end
326
317
 
318
+ def test_raise_access_error_on_nonexistent_keyspace
319
+ nonexistent = Cassandra.new('Nonexistent')
320
+ assert_raises(Cassandra::AccessError) do
321
+ nonexistent.get "foo", "bar"
322
+ end
323
+ end
324
+
327
325
  private
328
326
 
329
327
  def key
@@ -43,4 +43,9 @@ class ComparableTypesTest < Test::Unit::TestCase
43
43
  UUID.new("bogus")
44
44
  end
45
45
  end
46
+
47
+ def test_types_behave_well
48
+ assert !(UUID.new() == false)
49
+ assert !(Long.new() == false)
50
+ end
46
51
  end
@@ -100,6 +100,7 @@ require 'cassandra_types'
100
100
  end
101
101
 
102
102
  def get_key_range(keyspace, column_family, start, finish, count, consistency_level)
103
+
103
104
  send_get_key_range(keyspace, column_family, start, finish, count, consistency_level)
104
105
  return recv_get_key_range()
105
106
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cassandra
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.6"
4
+ version: "0.7"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Weaver
@@ -10,27 +10,27 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ0wCwYDVQQDDARldmFu
14
- MRgwFgYKCZImiZPyLGQBGRYIY2xvdWRidXIxEjAQBgoJkiaJk/IsZAEZFgJzdDAe
15
- Fw0wNzA5MTYxMDMzMDBaFw0wODA5MTUxMDMzMDBaMD0xDTALBgNVBAMMBGV2YW4x
16
- GDAWBgoJkiaJk/IsZAEZFghjbG91ZGJ1cjESMBAGCgmSJomT8ixkARkWAnN0MIIB
17
- IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5C0Io89nyApnr+PvbNFge9Vs
18
- yRWAlGBUEMahpXp28VrrfXZT0rAW7JBo4PlCE3jl4nE4dzE6gAdItSycjTosrw7A
19
- Ir5+xoyl4Vb35adv56TIQQXvNz+BzlqnkAY5JN0CSBRTQb6mxS3hFyD/h4qgDosj
20
- R2RFVzHqSxCS8xq4Ny8uzOwOi+Xyu4w67fI5JvnPvMxqrlR1eaIQHmxnf76RzC46
21
- QO5QhufjAYGGXd960XzbQsQyTDUYJzrvT7AdOfiyZzKQykKt8dEpDn+QPjFTnGnT
22
- QmgJBX5WJN0lHF2l1sbv3gh4Kn1tZu+kTUqeXY6ShAoDTyvZRiFqQdwh8w2lTQID
23
- AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU+WqJz3xQ
24
- XSea1hRvvHWcIMgeeC4wDQYJKoZIhvcNAQEFBQADggEBAGLZ75jfOEW8Nsl26CTt
25
- JFrWxQTcQT/UljeefVE3xYr7lc9oQjbqO3FOyued3qW7TaNEtZfSHoYeUSMYbpw1
26
- XAwocIPuSRFDGM4B+hgQGVDx8PMGiJKom4qLXjO40UZsR7QyN/u869Vj45LURm6h
27
- MBcPeqCASI+WNprj9+uZa2kmHiitrFqqfMBNlm5IFbn9XeYSta9AHVvs5QQqV2m5
28
- hIPfLqCyxsn/YgOGvo6iwyQTWyTswamaAC3HRWZxIS1sfn/Ssqa7E7oQMkv5FAXr
29
- x5rKePfXINf8XTJczkl9OBEYdE9aNdJsJpXD0asLgGVwBICS5Bjohp6mizJcDC1+
30
- yZ0=
13
+ MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMQ0wCwYDVQQDDARyeWFu
14
+ MRswGQYKCZImiZPyLGQBGRYLdGhlcnlhbmtpbmcxEzARBgoJkiaJk/IsZAEZFgNj
15
+ b20wHhcNMTAwMTA4MTc1MDM0WhcNMTEwMTA4MTc1MDM0WjBBMQ0wCwYDVQQDDARy
16
+ eWFuMRswGQYKCZImiZPyLGQBGRYLdGhlcnlhbmtpbmcxEzARBgoJkiaJk/IsZAEZ
17
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLPp+0PtRT3qCI
18
+ 02sMsADSn7Uf1GpyXUtk4Fb94LqUO6Scl91YDmbFMpjzrQwQvBYMIVreWcwSish6
19
+ nip6WEk9lqXcOeDmex/qY2/FVXG8ffqjFHiNiN9vpWrWj5VMICequ+ftzWLKsPIS
20
+ DGJ4o+Z6wEYRuirgaRPCYAUDPglsaqctJ56wPuycryMe5+ApSkOS9iLWMprQKEAq
21
+ j2R2OBV0dSARdbtzuKwrP7sLDo7uPa0egFBUlcZ+nujGr4LvmpryB8scNRNmZK1w
22
+ 1rEI7O06CbULj08qYxEhnKmFE7LbBoN/HrmvZLVQK5mWuiZQhtmJuhBfStJsaDux
23
+ 5tBEkYZVAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
24
+ BBSnLarDEo5eBE2arSMrBdOOhtrnPTANBgkqhkiG9w0BAQUFAAOCAQEANER07s4K
25
+ Pvc1DSduliRDMUax/VSfLzDTtTAQwuSAPDrWAYXKugcJtOZOXjDbGL7c5zoWmy9u
26
+ Fn5vEVdm/93J+84D/IMaaof3BwX/NNEYH01CeZEIGMfc5AFFha7dabzP/uiPpb/c
27
+ GSvomC9IzyN37+eWwOS16cC+5XnBT6KRCaXYg2Fh6WpTgde67OVgXr4Q58HXlaZ+
28
+ /2BB3wq9lZ4JskvlpYpYnlPAUyiyc6R2Mjts1pURz5nkW4SuS7Kd1KCOOyr1McDH
29
+ VP12sTSjJclmI17BjDGQpAF0n9v5ExhJxWpeOjeBUPQsOin3ypEM1KkckLmOKvH6
30
+ zyKMYVRO0z/58g==
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2009-11-18 00:00:00 -08:00
33
+ date: 2010-01-08 00:00:00 -08:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
@@ -43,6 +43,16 @@ dependencies:
43
43
  - !ruby/object:Gem::Version
44
44
  version: "0"
45
45
  version:
46
+ - !ruby/object:Gem::Dependency
47
+ name: json
48
+ type: :runtime
49
+ version_requirement:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
46
56
  - !ruby/object:Gem::Dependency
47
57
  name: rake
48
58
  type: :runtime
metadata.gz.sig CHANGED
Binary file