cassandra 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/Rakefile +25 -14
- data/cassandra.gemspec +2 -2
- data/lib/cassandra.rb +0 -2
- data/lib/cassandra/0.6/protocol.rb +12 -15
- data/lib/cassandra/0.7/protocol.rb +12 -15
- data/lib/cassandra/0.8/protocol.rb +12 -15
- data/lib/cassandra/cassandra.rb +109 -10
- data/lib/cassandra/columns.rb +9 -0
- data/lib/cassandra/mock.rb +56 -14
- data/test/cassandra_mock_test.rb +1 -1
- data/test/cassandra_test.rb +76 -20
- data/test/test_helper.rb +2 -2
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
v0.11.0
|
2
|
+
- Remove direct thrift dependency. Allow thrift_client to require it.
|
3
|
+
- Add functions for each and each_key to iterate through key ranges.
|
4
|
+
- Add function for get_range_keys which returns an array of keys in a given range.
|
5
|
+
- Changed the return value of get_range to an OrderedHash.
|
6
|
+
- Change get_range to accept both a range of keys and a range of columns.
|
7
|
+
- Add batched range support to get_range and add get_range_batch.
|
8
|
+
|
1
9
|
v0.10.0 Major Update (rjackson)
|
2
10
|
- Update Rakefile to install 0.6.13, 0.7.4, 0.8.0-beta1 to ~/cassandra/cassandra-VERSION
|
3
11
|
- Add data:load task to Rakefile for creating the schema required for the tests
|
data/Rakefile
CHANGED
@@ -42,10 +42,7 @@ def setup_cassandra_version(version = CASSANDRA_VERSION)
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
|
-
task :cassandra => :java do
|
47
|
-
setup_cassandra_version
|
48
|
-
|
45
|
+
def setup_environment
|
49
46
|
env = ""
|
50
47
|
if !ENV["CASSANDRA_INCLUDE"]
|
51
48
|
env << "CASSANDRA_INCLUDE=#{File.expand_path(Dir.pwd)}/conf/#{CASSANDRA_VERSION}/cassandra.in.sh "
|
@@ -57,13 +54,26 @@ task :cassandra => :java do
|
|
57
54
|
env << "CASSANDRA_CONF=#{ENV['CASSANDRA_CONF']}"
|
58
55
|
end
|
59
56
|
|
60
|
-
|
57
|
+
env
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Start Cassandra"
|
61
|
+
task :cassandra => :java do
|
62
|
+
setup_cassandra_version
|
63
|
+
|
64
|
+
env = setup_environment
|
61
65
|
|
62
66
|
Dir.chdir(File.join(CASSANDRA_HOME, "cassandra-#{CASSANDRA_VERSION}")) do
|
63
67
|
sh("env #{env} bin/cassandra -f")
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
71
|
+
desc "Run the Cassandra CLI"
|
72
|
+
task :cli do
|
73
|
+
Dir.chdir(File.join(CASSANDRA_HOME, "cassandra-#{CASSANDRA_VERSION}")) do
|
74
|
+
sh("bin/cassandra-cli -host localhost -port 9160")
|
75
|
+
end
|
76
|
+
end
|
67
77
|
|
68
78
|
desc "Check Java version"
|
69
79
|
task :java do
|
@@ -85,15 +95,16 @@ namespace :data do
|
|
85
95
|
|
86
96
|
desc "Load test data structures."
|
87
97
|
task :load do
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
98
|
+
unless CASSANDRA_VERSION == '0.6'
|
99
|
+
|
100
|
+
schema_path = "#{File.expand_path(Dir.pwd)}/conf/#{CASSANDRA_VERSION}/schema.txt"
|
101
|
+
puts "Loading test data structures."
|
102
|
+
Dir.chdir(File.join(CASSANDRA_HOME, "cassandra-#{CASSANDRA_VERSION}")) do
|
103
|
+
begin
|
104
|
+
sh("bin/cassandra-cli --host localhost --batch < #{schema_path}")
|
105
|
+
rescue
|
106
|
+
puts "Schema already loaded."
|
107
|
+
end
|
97
108
|
end
|
98
109
|
end
|
99
110
|
end
|
data/cassandra.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{cassandra}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.11.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"]
|
9
|
-
s.date = %q{2011-
|
9
|
+
s.date = %q{2011-05-18}
|
10
10
|
s.description = %q{A Ruby client for the Cassandra distributed database.}
|
11
11
|
s.email = %q{}
|
12
12
|
s.executables = ["cassandra_helper"]
|
data/lib/cassandra.rb
CHANGED
@@ -71,22 +71,19 @@ class Cassandra
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
def _get_range(column_family, start, finish, count, consistency)
|
74
|
+
def _get_range(column_family, start_key, finish_key, key_count, columns, start, finish, count, consistency)
|
75
75
|
column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
|
76
|
-
predicate =
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
column_parent
|
87
|
-
predicate = CassandraThrift::SlicePredicate.new(:column_names => [])
|
88
|
-
range = CassandraThrift::KeyRange.new(:start_key => '', :end_key => '')
|
89
|
-
client.get_range_slices(@keyspace, column_parent, predicate, range, 1).each{|i| yield i.key }
|
76
|
+
predicate = if columns
|
77
|
+
CassandraThrift::SlicePredicate.new(:column_names => columns)
|
78
|
+
else
|
79
|
+
CassandraThrift::SlicePredicate.new(:slice_range =>
|
80
|
+
CassandraThrift::SliceRange.new(
|
81
|
+
:start => start,
|
82
|
+
:finish => finish,
|
83
|
+
:count => count))
|
84
|
+
end
|
85
|
+
range = CassandraThrift::KeyRange.new(:start_key => start_key, :end_key => finish_key, :count => key_count)
|
86
|
+
client.get_range_slices(@keyspace, column_parent, predicate, range, consistency)
|
90
87
|
end
|
91
88
|
end
|
92
89
|
end
|
@@ -83,15 +83,19 @@ class Cassandra
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
def _get_range(column_family, start, finish, count, consistency)
|
86
|
+
def _get_range(column_family, start_key, finish_key, key_count, columns, start, finish, count, consistency)
|
87
87
|
column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
|
88
|
-
predicate =
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
88
|
+
predicate = if columns
|
89
|
+
CassandraThrift::SlicePredicate.new(:column_names => columns)
|
90
|
+
else
|
91
|
+
CassandraThrift::SlicePredicate.new(:slice_range =>
|
92
|
+
CassandraThrift::SliceRange.new(
|
93
|
+
:start => start,
|
94
|
+
:finish => finish,
|
95
|
+
:count => count))
|
96
|
+
end
|
97
|
+
range = CassandraThrift::KeyRange.new(:start_key => start_key, :end_key => finish_key, :count => key_count)
|
98
|
+
client.get_range_slices(column_parent, predicate, range, consistency)
|
95
99
|
end
|
96
100
|
|
97
101
|
# TODO: Supercolumn support
|
@@ -109,12 +113,5 @@ class Cassandra
|
|
109
113
|
end
|
110
114
|
client.get_indexed_slices(column_parent, idx_clause, predicate, consistency)
|
111
115
|
end
|
112
|
-
|
113
|
-
def each_key(column_family)
|
114
|
-
column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family.to_s)
|
115
|
-
predicate = CassandraThrift::SlicePredicate.new(:column_names => [])
|
116
|
-
range = CassandraThrift::KeyRange.new(:start_key => '', :end_key => '')
|
117
|
-
client.get_range_slices(column_parent, predicate, range, 1).each{|i| yield i.key }
|
118
|
-
end
|
119
116
|
end
|
120
117
|
end
|
@@ -83,15 +83,19 @@ class Cassandra
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
def _get_range(column_family, start, finish, count, consistency)
|
86
|
+
def _get_range(column_family, start_key, finish_key, key_count, columns, start, finish, count, consistency)
|
87
87
|
column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
|
88
|
-
predicate =
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
88
|
+
predicate = if columns
|
89
|
+
CassandraThrift::SlicePredicate.new(:column_names => columns)
|
90
|
+
else
|
91
|
+
CassandraThrift::SlicePredicate.new(:slice_range =>
|
92
|
+
CassandraThrift::SliceRange.new(
|
93
|
+
:start => start,
|
94
|
+
:finish => finish,
|
95
|
+
:count => count))
|
96
|
+
end
|
97
|
+
range = CassandraThrift::KeyRange.new(:start_key => start_key, :end_key => finish_key, :count => key_count)
|
98
|
+
client.get_range_slices(column_parent, predicate, range, consistency)
|
95
99
|
end
|
96
100
|
|
97
101
|
# TODO: Supercolumn support
|
@@ -109,12 +113,5 @@ class Cassandra
|
|
109
113
|
end
|
110
114
|
client.get_indexed_slices(column_parent, idx_clause, predicate, consistency)
|
111
115
|
end
|
112
|
-
|
113
|
-
def each_key(column_family)
|
114
|
-
column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family.to_s)
|
115
|
-
predicate = CassandraThrift::SlicePredicate.new(:column_names => [])
|
116
|
-
range = CassandraThrift::KeyRange.new(:start_key => '', :end_key => '')
|
117
|
-
client.get_range_slices(column_parent, predicate, range, 1).each{|i| yield i.key }
|
118
|
-
end
|
119
116
|
end
|
120
117
|
end
|
data/lib/cassandra/cassandra.rb
CHANGED
@@ -30,7 +30,7 @@ For write methods, valid option parameters are:
|
|
30
30
|
|
31
31
|
For the initial client instantiation, you may also pass in <tt>:thrift_client<tt> with a ThriftClient subclass attached. On connection, that class will be used instead of the default ThriftClient class, allowing you to add additional behavior to the connection (e.g. query logging).
|
32
32
|
|
33
|
-
=end
|
33
|
+
=end
|
34
34
|
|
35
35
|
class Cassandra
|
36
36
|
include Columns
|
@@ -226,21 +226,120 @@ class Cassandra
|
|
226
226
|
end
|
227
227
|
end
|
228
228
|
|
229
|
-
# Return
|
229
|
+
# Return an OrderedHash containing the columns specified for the given
|
230
|
+
# range of keys in the column_family you request. Only works well if
|
230
231
|
# the table is partitioned with OrderPreservingPartitioner. Supports the
|
231
|
-
# <tt>:
|
232
|
-
#
|
232
|
+
# <tt>:key_count</tt>, <tt>:start_key</tt>, <tt>:finish_key</tt>,
|
233
|
+
# <tt>:columns</tt>, <tt>:start</tt>, <tt>:finish</tt>, <tt>:count</tt>,
|
234
|
+
# and <tt>:consistency</tt> options. Please note that Cassandra returns
|
235
|
+
# a row for each row that has existed in the system since gc_grace_seconds.
|
236
|
+
# This is because deleted row keys are marked as deleted, but left in the
|
237
|
+
# system until the cluster has had resonable time to replicate the deletion.
|
238
|
+
# This function attempts to suppress deleted rows (actually any row returned without
|
239
|
+
# columns is suppressed).
|
233
240
|
def get_range(column_family, options = {})
|
241
|
+
if block_given? || options[:key_count] || options[:batch_size]
|
242
|
+
get_range_batch(column_family, options)
|
243
|
+
else
|
244
|
+
get_range_single(column_family, options)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def get_range_single(column_family, options = {})
|
249
|
+
return_empty_rows = options.delete(:return_empty_rows) || false
|
250
|
+
|
234
251
|
column_family, _, _, options =
|
235
|
-
extract_and_validate_params(column_family, "", [options],
|
236
|
-
|
252
|
+
extract_and_validate_params(column_family, "", [options],
|
253
|
+
READ_DEFAULTS.merge(:start_key => '',
|
254
|
+
:end_key => '',
|
255
|
+
:key_count => 100,
|
256
|
+
:columns => nil
|
257
|
+
)
|
258
|
+
)
|
259
|
+
|
260
|
+
results = _get_range( column_family,
|
261
|
+
options[:start_key].to_s,
|
262
|
+
options[:finish_key].to_s,
|
263
|
+
options[:key_count],
|
264
|
+
options[:columns],
|
265
|
+
options[:start].to_s,
|
266
|
+
options[:finish].to_s,
|
267
|
+
options[:count],
|
268
|
+
options[:consistency] )
|
269
|
+
|
270
|
+
multi_key_slices_to_hash(column_family, results, return_empty_rows)
|
271
|
+
end
|
272
|
+
|
273
|
+
def get_range_batch(column_family, options = {})
|
274
|
+
batch_size = options.delete(:batch_size) || 100
|
275
|
+
count = options.delete(:key_count)
|
276
|
+
result = {}
|
277
|
+
|
278
|
+
options[:start_key] ||= ''
|
279
|
+
last_key = nil
|
280
|
+
|
281
|
+
while options[:start_key] != last_key && (count.nil? || count > result.length)
|
282
|
+
options[:start_key] = last_key
|
283
|
+
res = get_range_single(column_family, options.merge!(:start_key => last_key,
|
284
|
+
:key_count => batch_size,
|
285
|
+
:return_empty_rows => true
|
286
|
+
))
|
287
|
+
res.each do |key, columns|
|
288
|
+
next if options[:start_key] == key
|
289
|
+
next if result.length == count
|
290
|
+
|
291
|
+
unless columns == {}
|
292
|
+
yield key, columns if block_given?
|
293
|
+
result[key] = columns
|
294
|
+
end
|
295
|
+
last_key = key
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
result
|
237
300
|
end
|
238
301
|
|
239
|
-
# Count all rows in the column_family you request.
|
240
|
-
#
|
241
|
-
# <tt>:
|
302
|
+
# Count all rows in the column_family you request. Supports the <tt>:start_key</tt>,
|
303
|
+
# <tt>:finish_key</tt>, and <tt>:consistency</tt> options. Please note that
|
304
|
+
# <tt>:start_key</tt> and <tt>:finish_key</tt> only work properly when
|
305
|
+
# OrderPreservingPartitioner.
|
242
306
|
def count_range(column_family, options = {})
|
243
|
-
|
307
|
+
get_range_keys(column_family, options).length
|
308
|
+
end
|
309
|
+
|
310
|
+
# Return an Array containing all of the keys within a given range. (Only works
|
311
|
+
# properly if the Cassandra cluster is using the OrderPreservingPartitioner.)
|
312
|
+
# Supports <tt>:start_key</tt>, <tt>:finish_key</tt>, <tt>:count</tt>, and
|
313
|
+
# <tt>:consistency</tt> options.
|
314
|
+
def get_range_keys(column_family, options = {})
|
315
|
+
get_range(column_family,options.merge!(:count => 1)).keys
|
316
|
+
end
|
317
|
+
|
318
|
+
# Iterate through each key within the given parameters. This function can be
|
319
|
+
# used to iterate over each key in the given column family. However, if you
|
320
|
+
# only want to walk through a range of keys you need to have your cluster
|
321
|
+
# setup with OrderPreservingPartitioner. Please note that this function walks
|
322
|
+
# the list of keys in batches using the passed in <tt>:count</tt> option.
|
323
|
+
# Supports <tt>:start_key</tt>, <tt>:finish_key</tt>, <tt>:count</tt>, and
|
324
|
+
# <tt>:consistency</tt> options.
|
325
|
+
def each_key(column_family, options = {})
|
326
|
+
get_range_batch(column_family, options) do |key, columns|
|
327
|
+
yield key
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
# Iterate through each row and yields each key and value within the given parameters.
|
332
|
+
# This function can be used to iterate over each key in the given column family.
|
333
|
+
# However, if you only want to walk through a range of keys you need to have your
|
334
|
+
# cluster setup with OrderPreservingPartitioner. Please note that this function walks
|
335
|
+
# the list of keys in batches using the passed in <tt>:count</tt> option.
|
336
|
+
# Supports the <tt>:key_count</tt>, <tt>:start_key</tt>, <tt>:finish_key</tt>,
|
337
|
+
# <tt>:columns</tt>, <tt>:start</tt>, <tt>:finish</tt>, <tt>:count</tt>,
|
338
|
+
# and <tt>:consistency</tt> options.
|
339
|
+
def each(column_family, options = {})
|
340
|
+
get_range_batch(column_family, options) do |key, columns|
|
341
|
+
yield key, columns
|
342
|
+
end
|
244
343
|
end
|
245
344
|
|
246
345
|
# Open a batch operation and yield self. Inserts and deletes will be queued
|
data/lib/cassandra/columns.rb
CHANGED
@@ -34,6 +34,15 @@ class Cassandra
|
|
34
34
|
schema[column_family][key]
|
35
35
|
end
|
36
36
|
|
37
|
+
def multi_key_slices_to_hash(column_family, array, return_empty_rows = false)
|
38
|
+
ret = {}
|
39
|
+
array.each do |value|
|
40
|
+
next if return_empty_rows == false && value.columns.length == 0
|
41
|
+
ret[value.key] = columns_to_hash(column_family, value.columns)
|
42
|
+
end
|
43
|
+
ret
|
44
|
+
end
|
45
|
+
|
37
46
|
def multi_column_to_hash!(hash)
|
38
47
|
hash.each do |key, column_or_supercolumn|
|
39
48
|
hash[key] = (column_or_supercolumn.column.value if column_or_supercolumn.column)
|
data/lib/cassandra/mock.rb
CHANGED
@@ -181,19 +181,57 @@ class Cassandra
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def get_range(column_family, options = {})
|
184
|
-
column_family, _, _, options = extract_and_validate_params_for_real(column_family, "", [options],
|
185
|
-
|
184
|
+
column_family, _, _, options = extract_and_validate_params_for_real(column_family, "", [options],
|
185
|
+
READ_DEFAULTS.merge(:start_key => '',
|
186
|
+
:end_key => '',
|
187
|
+
:key_count => 100,
|
188
|
+
:columns => nil
|
189
|
+
)
|
190
|
+
)
|
191
|
+
_get_range(column_family,
|
192
|
+
options[:start_key],
|
193
|
+
options[:finish_key],
|
194
|
+
options[:key_count],
|
195
|
+
options[:columns],
|
196
|
+
options[:start],
|
197
|
+
options[:finish],
|
198
|
+
options[:count],
|
199
|
+
options[:consistency])
|
200
|
+
end
|
201
|
+
|
202
|
+
def get_range_keys(column_family, options = {})
|
203
|
+
get_range(column_family,options.merge!(:columns => [])).keys
|
204
|
+
end
|
205
|
+
|
206
|
+
def count_range(column_family, options = {})
|
207
|
+
get_range(column_family, options).select{|k,v| v.length > 0}.keys.compact.length
|
208
|
+
end
|
209
|
+
|
210
|
+
def each_key(column_family, options = {})
|
211
|
+
each(column_family, options.merge!(:columns => [])) do |key, value|
|
212
|
+
yield key
|
213
|
+
end
|
186
214
|
end
|
187
215
|
|
188
|
-
def
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
216
|
+
def each(column_family, options = {})
|
217
|
+
batch_size = options.delete(:batch_size) || 100
|
218
|
+
count = options.delete(:key_count)
|
219
|
+
yielded_count = 0
|
220
|
+
|
221
|
+
options[:start_key] ||= ''
|
222
|
+
last_key = nil
|
223
|
+
|
224
|
+
while options[:start_key] != last_key && (count.nil? || count > yielded_count)
|
225
|
+
options[:start_key] = last_key
|
226
|
+
res = get_range(column_family, options.merge!(:start_key => last_key, :key_count => batch_size))
|
227
|
+
res.each do |key, columns|
|
228
|
+
next if options[:start_key] == key
|
229
|
+
next if yielded_count == count
|
230
|
+
yield key, columns
|
231
|
+
yielded_count += 1
|
232
|
+
last_key = key
|
233
|
+
end
|
195
234
|
end
|
196
|
-
count
|
197
235
|
end
|
198
236
|
|
199
237
|
def create_index(ks_name, cf_name, c_name, v_class)
|
@@ -264,14 +302,18 @@ class Cassandra
|
|
264
302
|
@schema
|
265
303
|
end
|
266
304
|
|
267
|
-
def _get_range(column_family, start, finish, count)
|
305
|
+
def _get_range(column_family, start_key, finish_key, key_count, columns, start, finish, count, consistency)
|
268
306
|
ret = OrderedHash.new
|
269
307
|
start = to_compare_with_type(start, column_family)
|
270
308
|
finish = to_compare_with_type(finish, column_family)
|
271
309
|
cf(column_family).keys.sort.each do |key|
|
272
|
-
break if ret.keys.size >=
|
273
|
-
if (
|
274
|
-
|
310
|
+
break if ret.keys.size >= key_count
|
311
|
+
if (start_key.nil? || key >= start_key) && (finish_key.nil? || key <= finish_key)
|
312
|
+
if columns
|
313
|
+
ret[key] = columns.inject(OrderedHash.new){|hash, column_name| hash[column_name] = cf(column_family)[key][column_name]; hash;}
|
314
|
+
else
|
315
|
+
ret[key] = apply_range(cf(column_family)[key], column_family, start, finish, !is_super(column_family))
|
316
|
+
end
|
275
317
|
end
|
276
318
|
end
|
277
319
|
ret
|
data/test/cassandra_mock_test.rb
CHANGED
@@ -38,7 +38,7 @@ class CassandraMockTest < CassandraTest
|
|
38
38
|
def test_sorting_row_keys
|
39
39
|
@twitter.insert(:Statuses, 'b', {:text => 'foo'})
|
40
40
|
@twitter.insert(:Statuses, 'a', {:text => 'foo'})
|
41
|
-
assert_equal ['a'], @twitter.get_range(:Statuses, :
|
41
|
+
assert_equal ['a'], @twitter.get_range(:Statuses, :key_count => 1).keys
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_inserting_array_for_indices
|
data/test/cassandra_test.rb
CHANGED
@@ -43,7 +43,7 @@ class CassandraTest < Test::Unit::TestCase
|
|
43
43
|
hash = OrderedHash['b', '', 'c', '', 'd', '', 'a', '']
|
44
44
|
@twitter.insert(:Users, key, hash)
|
45
45
|
assert_equal(hash.keys.sort, @twitter.get(:Users, key).keys)
|
46
|
-
assert_equal(hash.timestamps.keys.sort, @twitter.get(:Users, key).timestamps.keys
|
46
|
+
assert_equal(hash.timestamps.keys.sort, @twitter.get(:Users, key).timestamps.keys)
|
47
47
|
assert_not_equal(hash.keys, @twitter.get(:Users, key).keys)
|
48
48
|
end
|
49
49
|
|
@@ -190,24 +190,79 @@ class CassandraTest < Test::Unit::TestCase
|
|
190
190
|
assert_nil @twitter.get(:StatusRelationships, 'bogus', 'user_timelines', columns.keys.first)
|
191
191
|
end
|
192
192
|
|
193
|
+
def test_get_range_with_key_range
|
194
|
+
skip('This test requires the use of OrderPreservingPartitioner on the cluster to work properly.')
|
195
|
+
k = key
|
196
|
+
@twitter.insert(:Statuses, k + '2', {'body' => '1'})
|
197
|
+
@twitter.insert(:Statuses, k + '3', {'body' => '1'})
|
198
|
+
@twitter.insert(:Statuses, k + '4', {'body' => '1'})
|
199
|
+
@twitter.insert(:Statuses, k + '5', {'body' => '1'})
|
200
|
+
@twitter.insert(:Statuses, k + '6', {'body' => '1'})
|
201
|
+
assert_equal([k + '3', k + '4', k + '5'], @twitter.get_range(:Statuses, :start_key => k + '3', :finish_key => k + '5').keys)
|
202
|
+
end
|
193
203
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
# assert_equal(['3', '4', '5'], @twitter.get_range(:Statuses, :start => '3', :finish => '5'))
|
202
|
-
# end
|
204
|
+
def test_get_range
|
205
|
+
# make sure that deleted rows are not included in the iteration
|
206
|
+
10.times do |i|
|
207
|
+
@twitter.insert(:Statuses, i.to_s, {'body' => '1'})
|
208
|
+
@twitter.insert(:Statuses, i.to_s + '_delete_me', {'test' => 'value'})
|
209
|
+
@twitter.remove(:Statuses, i.to_s + '_delete_me')
|
210
|
+
end
|
203
211
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
212
|
+
assert_equal(4, @twitter.get_range_keys(:Statuses, :key_count => 4).size)
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_each_key
|
216
|
+
k = key
|
217
|
+
keys_yielded = []
|
218
|
+
|
219
|
+
10.times do |i|
|
220
|
+
@twitter.insert(:Statuses, k + i.to_s, {"body-#{i.to_s}" => 'v'})
|
221
|
+
end
|
222
|
+
|
223
|
+
# make sure that deleted rows are not included in the iteration
|
224
|
+
@twitter.insert(:Statuses, k + '_delete_me', {'test' => 'value'})
|
225
|
+
@twitter.remove(:Statuses, k + '_delete_me')
|
226
|
+
|
227
|
+
@twitter.each_key(:Statuses) do |key|
|
228
|
+
keys_yielded << key
|
229
|
+
end
|
230
|
+
|
231
|
+
assert_equal 10, keys_yielded.length
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_each
|
235
|
+
k = key
|
236
|
+
key_columns = {}
|
237
|
+
|
238
|
+
10.times do |i|
|
239
|
+
key_columns[k + i.to_s] = {"body-#{i.to_s}" => 'v', 'single_column_lookup' => "value = #{i.to_s}"}
|
240
|
+
@twitter.insert(:Statuses, k + i.to_s, key_columns[k + i.to_s])
|
241
|
+
end
|
242
|
+
|
243
|
+
keys_yielded = []
|
244
|
+
@twitter.each(:Statuses, :batch_size => 5) do |key, columns|
|
245
|
+
assert_equal key_columns[key], columns
|
246
|
+
keys_yielded << key
|
247
|
+
end
|
248
|
+
|
249
|
+
assert_equal 10, keys_yielded.length
|
250
|
+
|
251
|
+
keys_yielded = []
|
252
|
+
@twitter.each(:Statuses, :key_count => 7, :batch_size => 5) do |key, columns|
|
253
|
+
assert_equal key_columns[key], columns
|
254
|
+
keys_yielded << key
|
255
|
+
end
|
256
|
+
|
257
|
+
assert_equal 7, keys_yielded.length, 'each limits to specified count'
|
258
|
+
|
259
|
+
keys_yielded = []
|
260
|
+
@twitter.each(:Statuses, :columns => ['single_column_lookup'], :batch_size => 5) do |key, columns|
|
261
|
+
assert_equal key_columns[key].reject {|k,v| k != 'single_column_lookup'}, columns
|
262
|
+
keys_yielded << key
|
263
|
+
end
|
264
|
+
|
265
|
+
assert_equal 10, keys_yielded.length
|
211
266
|
end
|
212
267
|
|
213
268
|
def test_multi_get
|
@@ -329,9 +384,10 @@ class CassandraTest < Test::Unit::TestCase
|
|
329
384
|
end
|
330
385
|
|
331
386
|
def test_count_keys
|
332
|
-
|
333
|
-
@twitter.insert(:Statuses,
|
334
|
-
@twitter.insert(:Statuses,
|
387
|
+
k = key
|
388
|
+
@twitter.insert(:Statuses, k + "1", {'body' => '1'})
|
389
|
+
@twitter.insert(:Statuses, k + "2", {'body' => '2'})
|
390
|
+
@twitter.insert(:Statuses, k + "3", {'body' => '3'})
|
335
391
|
assert_equal 3, @twitter.count_range(:Statuses)
|
336
392
|
end
|
337
393
|
|
data/test/test_helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
CASSANDRA_VERSION
|
1
|
+
CASSANDRA_VERSION ||= ENV['CASSANDRA_VERSION'] || '0.7'
|
2
2
|
|
3
3
|
require 'test/unit'
|
4
4
|
require "#{File.expand_path(File.dirname(__FILE__))}/../lib/cassandra/#{CASSANDRA_VERSION}"
|
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
rescue Thrift::TransportException => e
|
10
10
|
#FIXME Make server automatically start if not running
|
11
11
|
if e.message =~ /Could not connect/
|
12
|
-
puts "*** Please start the Cassandra server by running 'rake cassandra'. ***"
|
12
|
+
puts "*** Please start the Cassandra server by running 'rake cassandra'. ***"
|
13
13
|
exit 1
|
14
14
|
end
|
15
15
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cassandra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 51
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 11
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.11.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Evan Weaver, Ryan King
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-05-18 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: thrift_client
|