cassandra 0.10.0 → 0.11.0
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/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
|