cassandra 0.7.5 → 0.7.6
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 +0 -0
- data/CHANGELOG +2 -0
- data/Rakefile +24 -76
- data/cassandra.gemspec +2 -2
- data/lib/cassandra/mock.rb +32 -11
- data/lib/cassandra/protocol.rb +3 -1
- data/test/cassandra_mock_test.rb +3 -3
- data/test/cassandra_test.rb +34 -18
- metadata +2 -2
- metadata.gz.sig +3 -1
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
@@ -15,33 +15,40 @@ unless ENV['FROM_BIN_CASSANDRA_HELPER']
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
CASSANDRA_HOME = "#{ENV['HOME']}/cassandra"
|
19
|
+
DIST_URL = "http://github.com/downloads/ryanking/cassandra/apache-cassandra-incubating-0.5.0.2010-02-21-bin.tar.gz"
|
20
|
+
DIST_FILE = DIST_URL.split('/').last
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
CASSANDRA_HOME = "#{ENV['HOME']}/cassandra/server"
|
23
|
-
|
24
|
-
CASSANDRA_TEST = "#{ENV['HOME']}/cassandra/test"
|
25
|
-
|
26
|
-
GIT_REPO = "git://github.com/ryanking/cassandra.git"
|
27
|
-
|
28
|
-
directory CASSANDRA_TEST
|
22
|
+
directory CASSANDRA_HOME
|
23
|
+
directory File.join(CASSANDRA_HOME, 'test', 'data')
|
29
24
|
|
30
25
|
desc "Start Cassandra"
|
31
|
-
task :cassandra => [:
|
32
|
-
# Construct environment
|
26
|
+
task :cassandra => [:java, File.join(CASSANDRA_HOME, 'server'), File.join(CASSANDRA_HOME, 'test', 'data')] do
|
33
27
|
env = ""
|
34
28
|
if !ENV["CASSANDRA_INCLUDE"]
|
35
29
|
env << "CASSANDRA_INCLUDE=#{Dir.pwd}/conf/cassandra.in.sh "
|
36
|
-
env << "CASSANDRA_HOME=#{CASSANDRA_HOME} "
|
30
|
+
env << "CASSANDRA_HOME=#{CASSANDRA_HOME}/server "
|
37
31
|
env << "CASSANDRA_CONF=#{Dir.pwd}/conf"
|
38
32
|
end
|
39
|
-
|
40
|
-
Dir.chdir(
|
41
|
-
|
33
|
+
|
34
|
+
Dir.chdir(File.join(CASSANDRA_HOME, 'server')) do
|
35
|
+
sh("env #{env} bin/cassandra -f")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
file File.join(CASSANDRA_HOME, 'server') => File.join(CASSANDRA_HOME, DIST_FILE) do
|
40
|
+
Dir.chdir(CASSANDRA_HOME) do
|
41
|
+
sh "tar xzvf #{DIST_FILE}"
|
42
|
+
sh "mv #{DIST_FILE.split('.')[0..2].join('.')} server"
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
46
|
+
file File.join(CASSANDRA_HOME, DIST_FILE) => CASSANDRA_HOME do
|
47
|
+
puts "downloading"
|
48
|
+
cmd = "curl -L -o #{File.join(CASSANDRA_HOME, DIST_FILE)} #{DIST_URL}"
|
49
|
+
sh cmd
|
50
|
+
end
|
51
|
+
|
45
52
|
desc "Check Java version"
|
46
53
|
task :java do
|
47
54
|
unless `java -version 2>&1`.split("\n").first =~ /java version "1.6/ #"
|
@@ -53,70 +60,11 @@ task :java do
|
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
56
|
-
desc "Check Git version"
|
57
|
-
task :git do
|
58
|
-
unless `git --version 2>&1` =~ /git version 1.(6|7)/
|
59
|
-
puts "You need to install git 1.6 or 1.7"
|
60
|
-
exit(1)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
desc "Checkout Cassandra from git"
|
65
|
-
task :clone_cassandra => [:java, :git] do
|
66
|
-
# Like a git submodule, but all in one more obvious place
|
67
|
-
unless File.exist?(CASSANDRA_HOME)
|
68
|
-
puts "Checking Cassandra out from git"
|
69
|
-
cmd = "git clone #{GIT_REPO} #{CASSANDRA_HOME}"
|
70
|
-
if !system(cmd)
|
71
|
-
put "Checkout failed. Try:\n #{cmd}"
|
72
|
-
exit(1)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
desc "Check out the right revision"
|
78
|
-
task :checkout_cassandra => [:clone_cassandra] do
|
79
|
-
Dir.chdir(CASSANDRA_HOME) do
|
80
|
-
current_checkout = `git log | head -n1`
|
81
|
-
if !current_checkout.include?(REVISION)
|
82
|
-
puts "Updating Cassandra."
|
83
|
-
system("rm -rf #{CASSANDRA_TEST}/data")
|
84
|
-
system("ant clean && git fetch && git reset #{REVISION} --hard")
|
85
|
-
# Delete untracked files
|
86
|
-
Array(`git status`[/Untracked files:(.*)$/m, 1].to_s.split("\n")[3..-1]).each do |file|
|
87
|
-
File.unlink(file.sub(/^.\s+/, "")) rescue nil
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
desc "Rebuild Cassandra"
|
94
|
-
task :build_cassandra => [:checkout_cassandra] do
|
95
|
-
unless File.exist?("#{CASSANDRA_HOME}/build")
|
96
|
-
puts "Building Cassandra"
|
97
|
-
cmd = "cd #{CASSANDRA_HOME} && ant"
|
98
|
-
if !system(cmd)
|
99
|
-
puts "Could not build Casssandra. Try:\n #{cmd}"
|
100
|
-
exit(1)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
desc "Clean Cassandra build"
|
106
|
-
task :clean_cassandra do
|
107
|
-
puts "Cleaning Cassandra"
|
108
|
-
if File.exist?(CASSANDRA_HOME)
|
109
|
-
Dir.chdir(CASSANDRA_HOME) do
|
110
|
-
system("ant clean")
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
63
|
namespace :data do
|
116
64
|
desc "Reset test data"
|
117
65
|
task :reset do
|
118
66
|
puts "Resetting test data"
|
119
|
-
system("rm -rf #{
|
67
|
+
system("rm -rf #{File.join(CASSANDRA_HOME, 'test', 'data')}")
|
120
68
|
end
|
121
69
|
end
|
122
70
|
|
data/cassandra.gemspec
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{cassandra}
|
5
|
-
s.version = "0.7.
|
5
|
+
s.version = "0.7.6"
|
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"]
|
9
9
|
s.cert_chain = ["/Users/ryan/.gemkeys/gem-public_cert.pem"]
|
10
|
-
s.date = %q{2010-
|
10
|
+
s.date = %q{2010-03-01}
|
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{}
|
data/lib/cassandra/mock.rb
CHANGED
@@ -15,11 +15,12 @@ class Cassandra
|
|
15
15
|
include ::Cassandra::Helpers
|
16
16
|
include ::Cassandra::Columns
|
17
17
|
|
18
|
-
def initialize(keyspace,
|
18
|
+
def initialize(keyspace, storage_xml)
|
19
19
|
@keyspace = keyspace
|
20
20
|
@column_name_class = {}
|
21
21
|
@sub_column_name_class = {}
|
22
|
-
@storage_xml =
|
22
|
+
@storage_xml = storage_xml
|
23
|
+
clear_keyspace!
|
23
24
|
end
|
24
25
|
|
25
26
|
def clear_keyspace!
|
@@ -131,14 +132,16 @@ class Cassandra
|
|
131
132
|
!!get(column_family, key, column)
|
132
133
|
end
|
133
134
|
|
134
|
-
def multi_get(column_family, keys)
|
135
|
+
def multi_get(column_family, keys, *columns_and_options)
|
136
|
+
column_family, column, sub_column, options = extract_and_validate_params_for_real(column_family, keys, columns_and_options, READ_DEFAULTS)
|
135
137
|
keys.inject(OrderedHash.new) do |hash, key|
|
136
138
|
hash[key] = get(column_family, key)
|
137
139
|
hash
|
138
140
|
end
|
139
141
|
end
|
140
142
|
|
141
|
-
def remove(column_family, key,
|
143
|
+
def remove(column_family, key, *columns_and_options)
|
144
|
+
column_family, column, sub_column, options = extract_and_validate_params_for_real(column_family, key, columns_and_options, WRITE_DEFAULTS)
|
142
145
|
if @batch
|
143
146
|
@batch << [:remove, column_family, key, column]
|
144
147
|
else
|
@@ -154,10 +157,19 @@ class Cassandra
|
|
154
157
|
end
|
155
158
|
end
|
156
159
|
|
157
|
-
def get_columns(column_family, key,
|
160
|
+
def get_columns(column_family, key, *columns_and_options)
|
161
|
+
column_family, columns, sub_columns, options = extract_and_validate_params_for_real(column_family, key, columns_and_options, READ_DEFAULTS)
|
158
162
|
d = get(column_family, key)
|
159
|
-
|
160
|
-
|
163
|
+
|
164
|
+
|
165
|
+
if sub_columns
|
166
|
+
sub_columns.collect do |sub_column|
|
167
|
+
d[columns][sub_column]
|
168
|
+
end
|
169
|
+
else
|
170
|
+
columns.collect do |column|
|
171
|
+
d[column]
|
172
|
+
end
|
161
173
|
end
|
162
174
|
end
|
163
175
|
|
@@ -180,8 +192,7 @@ class Cassandra
|
|
180
192
|
end
|
181
193
|
|
182
194
|
def get_range(column_family, options = {})
|
183
|
-
column_family, _, _, options =
|
184
|
-
extract_and_validate_params_for_real(column_family, "", [options], READ_DEFAULTS)
|
195
|
+
column_family, _, _, options = extract_and_validate_params_for_real(column_family, "", [options], READ_DEFAULTS)
|
185
196
|
_get_range(column_family, options[:start], options[:finish], options[:count]).keys
|
186
197
|
end
|
187
198
|
|
@@ -244,10 +255,20 @@ class Cassandra
|
|
244
255
|
end
|
245
256
|
|
246
257
|
def extract_and_validate_params_for_real(column_family, keys, args, options)
|
247
|
-
column_family,
|
258
|
+
column_family, columns, sub_column, options = extract_and_validate_params(column_family, keys, args, options)
|
248
259
|
options[:start] = nil if options[:start] == ''
|
249
260
|
options[:finish] = nil if options[:finish] == ''
|
250
|
-
[column_family,
|
261
|
+
[column_family, to_compare_with_types(columns, column_family), to_compare_with_types(sub_column, column_family, false), options]
|
262
|
+
end
|
263
|
+
|
264
|
+
def to_compare_with_types(column_names, column_family, standard=true)
|
265
|
+
if column_names.is_a?(Array)
|
266
|
+
column_names.collect do |name|
|
267
|
+
to_compare_with_type(name, column_family, standard)
|
268
|
+
end
|
269
|
+
else
|
270
|
+
to_compare_with_type(column_names, column_family, standard)
|
271
|
+
end
|
251
272
|
end
|
252
273
|
|
253
274
|
def to_compare_with_type(column_name, column_family, standard=true)
|
data/lib/cassandra/protocol.rb
CHANGED
@@ -38,7 +38,9 @@ class Cassandra
|
|
38
38
|
CassandraThrift::SlicePredicate.new(:column_names => columns),
|
39
39
|
consistency))
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
|
+
klass = column_name_class(column_family)
|
43
|
+
(sub_columns || columns).map { |name| result[klass.new(name)] }
|
42
44
|
end
|
43
45
|
|
44
46
|
def _multiget(column_family, keys, column, sub_column, count, start, finish, reversed, consistency)
|
data/test/cassandra_mock_test.rb
CHANGED
@@ -7,13 +7,13 @@ class CassandraMockTest < CassandraTest
|
|
7
7
|
|
8
8
|
def setup
|
9
9
|
storage_xml_path = File.expand_path(File.join(File.dirname(File.dirname(__FILE__)), 'conf', 'storage-conf.xml'))
|
10
|
-
@twitter = Cassandra::Mock.new('Twitter',
|
10
|
+
@twitter = Cassandra::Mock.new('Twitter', storage_xml_path)
|
11
11
|
@twitter.clear_keyspace!
|
12
12
|
|
13
|
-
@blogs = Cassandra::Mock.new('Multiblog',
|
13
|
+
@blogs = Cassandra::Mock.new('Multiblog', storage_xml_path)
|
14
14
|
@blogs.clear_keyspace!
|
15
15
|
|
16
|
-
@blogs_long = Cassandra::Mock.new('MultiblogLong',
|
16
|
+
@blogs_long = Cassandra::Mock.new('MultiblogLong', storage_xml_path)
|
17
17
|
@blogs_long.clear_keyspace!
|
18
18
|
|
19
19
|
@uuids = (0..6).map {|i| UUID.new(Time.at(2**(24+i))) }
|
data/test/cassandra_test.rb
CHANGED
@@ -54,6 +54,13 @@ class CassandraTest < Test::Unit::TestCase
|
|
54
54
|
assert_equal({}, @blogs.get(:Blogs, 'bogus'))
|
55
55
|
end
|
56
56
|
|
57
|
+
def test_get_multiple_time_uuid_columns
|
58
|
+
@blogs.insert(:Blogs, key,
|
59
|
+
{@uuids[0] => 'I like this cat', @uuids[1] => 'Buttons is cuter', @uuids[2] => 'I disagree'})
|
60
|
+
|
61
|
+
assert_equal(['I like this cat', 'Buttons is cuter'], @blogs.get_columns(:Blogs, key, @uuids[0..1]))
|
62
|
+
end
|
63
|
+
|
57
64
|
def test_get_first_long_column
|
58
65
|
@blogs_long.insert(:Blogs, key,
|
59
66
|
{@longs[0] => 'I like this cat', @longs[1] => 'Buttons is cuter', @longs[2] => 'I disagree'})
|
@@ -235,6 +242,13 @@ class CassandraTest < Test::Unit::TestCase
|
|
235
242
|
@twitter.get_columns(:StatusRelationships, key, ['user_timelines', 'mentions_timelines'])
|
236
243
|
end
|
237
244
|
|
245
|
+
def test_get_sub_column_values_super
|
246
|
+
user_columns = {@uuids[1] => 'v1', @uuids[2] => 'v2'}
|
247
|
+
@twitter.insert(:StatusRelationships, key, {'user_timelines' => user_columns})
|
248
|
+
assert_equal ['v1', 'v2'],
|
249
|
+
@twitter.get_columns(:StatusRelationships, key, 'user_timelines', @uuids[1..2])
|
250
|
+
end
|
251
|
+
|
238
252
|
def test_multi_get_columns
|
239
253
|
@twitter.insert(:Users, key + '1', {'body' => 'v1', 'user' => 'v1'})
|
240
254
|
@twitter.insert(:Users, key + '2', {'body' => 'v2', 'user' => 'v2'})
|
@@ -282,31 +296,33 @@ class CassandraTest < Test::Unit::TestCase
|
|
282
296
|
end
|
283
297
|
|
284
298
|
def test_batch_mutate
|
285
|
-
|
299
|
+
k = key
|
300
|
+
|
301
|
+
@twitter.insert(:Users, k + '1', {'body' => 'v1', 'user' => 'v1'})
|
286
302
|
|
287
303
|
@twitter.batch do
|
288
|
-
@twitter.insert(:Users,
|
289
|
-
@twitter.insert(:Users,
|
290
|
-
@twitter.insert(:Users,
|
291
|
-
@twitter.insert(:Statuses,
|
304
|
+
@twitter.insert(:Users, k + '2', {'body' => 'v2', 'user' => 'v2'})
|
305
|
+
@twitter.insert(:Users, k + '3', {'body' => 'bogus', 'user' => 'v3'})
|
306
|
+
@twitter.insert(:Users, k + '3', {'body' => 'v3', 'location' => 'v3'})
|
307
|
+
@twitter.insert(:Statuses, k + '3', {'body' => 'v'})
|
292
308
|
|
293
|
-
assert_equal({'body' => 'v1', 'user' => 'v1'}, @twitter.get(:Users,
|
294
|
-
assert_equal({}, @twitter.get(:Users,
|
295
|
-
assert_equal({}, @twitter.get(:Statuses,
|
309
|
+
assert_equal({'body' => 'v1', 'user' => 'v1'}, @twitter.get(:Users, k + '1')) # Written
|
310
|
+
assert_equal({}, @twitter.get(:Users, k + '2')) # Not yet written
|
311
|
+
assert_equal({}, @twitter.get(:Statuses, k + '3')) # Not yet written
|
296
312
|
|
297
|
-
@twitter.remove(:Users,
|
298
|
-
assert_equal({'body' => 'v1', 'user' => 'v1'}, @twitter.get(:Users,
|
313
|
+
@twitter.remove(:Users, k + '1')
|
314
|
+
assert_equal({'body' => 'v1', 'user' => 'v1'}, @twitter.get(:Users, k + '1')) # Not yet removed
|
299
315
|
|
300
|
-
@twitter.remove(:Users,
|
301
|
-
@twitter.insert(:Users,
|
302
|
-
assert_equal({}, @twitter.get(:Users,
|
316
|
+
@twitter.remove(:Users, k + '4')
|
317
|
+
@twitter.insert(:Users, k + '4', {'body' => 'v4', 'user' => 'v4'})
|
318
|
+
assert_equal({}, @twitter.get(:Users, k + '4')) # Not yet written
|
303
319
|
end
|
304
320
|
|
305
|
-
assert_equal({'body' => 'v2', 'user' => 'v2'}, @twitter.get(:Users,
|
306
|
-
assert_equal({'body' => 'v3', 'user' => 'v3', 'location' => 'v3'}, @twitter.get(:Users,
|
307
|
-
assert_equal({'body' => 'v4', 'user' => 'v4'}, @twitter.get(:Users,
|
308
|
-
assert_equal({'body' => 'v'}, @twitter.get(:Statuses,
|
309
|
-
assert_equal({}, @twitter.get(:Users,
|
321
|
+
assert_equal({'body' => 'v2', 'user' => 'v2'}, @twitter.get(:Users, k + '2')) # Written
|
322
|
+
assert_equal({'body' => 'v3', 'user' => 'v3', 'location' => 'v3'}, @twitter.get(:Users, k + '3')) # Written and compacted
|
323
|
+
assert_equal({'body' => 'v4', 'user' => 'v4'}, @twitter.get(:Users, k + '4')) # Written
|
324
|
+
assert_equal({'body' => 'v'}, @twitter.get(:Statuses, k + '3')) # Written
|
325
|
+
assert_equal({}, @twitter.get(:Users, k + '1')) # Removed
|
310
326
|
end
|
311
327
|
|
312
328
|
def test_complain_about_nil_key
|
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.7.
|
4
|
+
version: 0.7.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Weaver, Ryan King
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
zyKMYVRO0z/58g==
|
31
31
|
-----END CERTIFICATE-----
|
32
32
|
|
33
|
-
date: 2010-
|
33
|
+
date: 2010-03-01 00:00:00 -08:00
|
34
34
|
default_executable:
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
metadata.gz.sig
CHANGED