sessionm-cassandra 1.0.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.
Files changed (96) hide show
  1. data/CHANGELOG +135 -0
  2. data/Gemfile +8 -0
  3. data/LICENSE +202 -0
  4. data/Manifest +94 -0
  5. data/README.md +373 -0
  6. data/Rakefile +195 -0
  7. data/bin/cassandra_helper +16 -0
  8. data/conf/0.6/cassandra.in.sh +47 -0
  9. data/conf/0.6/log4j.properties +38 -0
  10. data/conf/0.6/schema.json +57 -0
  11. data/conf/0.6/storage-conf.xml +352 -0
  12. data/conf/0.7/cassandra.in.sh +46 -0
  13. data/conf/0.7/cassandra.yaml +336 -0
  14. data/conf/0.7/log4j-server.properties +41 -0
  15. data/conf/0.7/schema.json +57 -0
  16. data/conf/0.7/schema.txt +45 -0
  17. data/conf/0.8/cassandra.in.sh +41 -0
  18. data/conf/0.8/cassandra.yaml +61 -0
  19. data/conf/0.8/log4j-server.properties +40 -0
  20. data/conf/0.8/schema.json +72 -0
  21. data/conf/0.8/schema.txt +57 -0
  22. data/conf/1.0/cassandra.in.sh +41 -0
  23. data/conf/1.0/cassandra.yaml +415 -0
  24. data/conf/1.0/log4j-server.properties +40 -0
  25. data/conf/1.0/schema.json +72 -0
  26. data/conf/1.0/schema.txt +57 -0
  27. data/conf/1.1/cassandra.in.sh +41 -0
  28. data/conf/1.1/cassandra.yaml +567 -0
  29. data/conf/1.1/log4j-server.properties +44 -0
  30. data/conf/1.1/schema.json +72 -0
  31. data/conf/1.1/schema.txt +57 -0
  32. data/ext/cassandra_native.c +34 -0
  33. data/ext/extconf.rb +9 -0
  34. data/lib/cassandra/0.6/cassandra.rb +113 -0
  35. data/lib/cassandra/0.6/columns.rb +78 -0
  36. data/lib/cassandra/0.6/protocol.rb +91 -0
  37. data/lib/cassandra/0.6.rb +7 -0
  38. data/lib/cassandra/0.7/cassandra.rb +2 -0
  39. data/lib/cassandra/0.7/columns.rb +4 -0
  40. data/lib/cassandra/0.7/protocol.rb +5 -0
  41. data/lib/cassandra/0.7.rb +7 -0
  42. data/lib/cassandra/0.8/cassandra.rb +51 -0
  43. data/lib/cassandra/0.8/columns.rb +28 -0
  44. data/lib/cassandra/0.8/protocol.rb +10 -0
  45. data/lib/cassandra/0.8.rb +7 -0
  46. data/lib/cassandra/1.0/cassandra.rb +1 -0
  47. data/lib/cassandra/1.0/columns.rb +1 -0
  48. data/lib/cassandra/1.0/protocol.rb +1 -0
  49. data/lib/cassandra/1.0.rb +7 -0
  50. data/lib/cassandra/1.1/cassandra.rb +1 -0
  51. data/lib/cassandra/1.1/columns.rb +1 -0
  52. data/lib/cassandra/1.1/protocol.rb +1 -0
  53. data/lib/cassandra/1.1.rb +7 -0
  54. data/lib/cassandra/array.rb +8 -0
  55. data/lib/cassandra/batch.rb +41 -0
  56. data/lib/cassandra/cassandra.rb +1088 -0
  57. data/lib/cassandra/column_family.rb +3 -0
  58. data/lib/cassandra/columns.rb +172 -0
  59. data/lib/cassandra/comparable.rb +28 -0
  60. data/lib/cassandra/composite.rb +140 -0
  61. data/lib/cassandra/constants.rb +11 -0
  62. data/lib/cassandra/debug.rb +9 -0
  63. data/lib/cassandra/dynamic_composite.rb +96 -0
  64. data/lib/cassandra/helpers.rb +41 -0
  65. data/lib/cassandra/keyspace.rb +3 -0
  66. data/lib/cassandra/long.rb +58 -0
  67. data/lib/cassandra/mock.rb +525 -0
  68. data/lib/cassandra/ordered_hash.rb +192 -0
  69. data/lib/cassandra/protocol.rb +137 -0
  70. data/lib/cassandra/time.rb +11 -0
  71. data/lib/cassandra.rb +41 -0
  72. data/sessionm-cassandra.gemspec +47 -0
  73. data/test/cassandra_client_test.rb +20 -0
  74. data/test/cassandra_mock_test.rb +128 -0
  75. data/test/cassandra_test.rb +1353 -0
  76. data/test/comparable_types_test.rb +45 -0
  77. data/test/composite_type_test.rb +64 -0
  78. data/test/eventmachine_test.rb +42 -0
  79. data/test/ordered_hash_test.rb +386 -0
  80. data/test/test_helper.rb +19 -0
  81. data/vendor/0.6/gen-rb/cassandra.rb +1481 -0
  82. data/vendor/0.6/gen-rb/cassandra_constants.rb +12 -0
  83. data/vendor/0.6/gen-rb/cassandra_types.rb +482 -0
  84. data/vendor/0.7/gen-rb/cassandra.rb +1936 -0
  85. data/vendor/0.7/gen-rb/cassandra_constants.rb +12 -0
  86. data/vendor/0.7/gen-rb/cassandra_types.rb +681 -0
  87. data/vendor/0.8/gen-rb/cassandra.rb +2215 -0
  88. data/vendor/0.8/gen-rb/cassandra_constants.rb +12 -0
  89. data/vendor/0.8/gen-rb/cassandra_types.rb +824 -0
  90. data/vendor/1.0/gen-rb/cassandra.rb +2215 -0
  91. data/vendor/1.0/gen-rb/cassandra_constants.rb +12 -0
  92. data/vendor/1.0/gen-rb/cassandra_types.rb +857 -0
  93. data/vendor/1.1/gen-rb/cassandra.rb +2571 -0
  94. data/vendor/1.1/gen-rb/cassandra_constants.rb +12 -0
  95. data/vendor/1.1/gen-rb/cassandra_types.rb +928 -0
  96. metadata +287 -0
@@ -0,0 +1,41 @@
1
+ class Cassandra
2
+ module Helpers
3
+ def extract_and_validate_params(column_family, keys, args, options)
4
+ options = options.dup
5
+ column_family = column_family.to_s
6
+ # Keys
7
+ [keys].flatten.each do |key|
8
+ raise ArgumentError, "Key #{key.inspect} must be a String for #{caller[2].inspect}." unless key.is_a?(String)
9
+ end
10
+
11
+ # Options
12
+ if args.last.is_a?(Hash)
13
+ extras = args.last.keys - options.keys
14
+ raise ArgumentError, "Invalid options #{extras.inspect[1..-2]} for #{caller[1]}" if extras.any?
15
+ options.merge!(args.pop)
16
+ end
17
+
18
+ # Ranges
19
+ column, sub_column = args[0], args[1]
20
+ raise ArgumentError, "Invalid arguments: subcolumns specified for a non-supercolumn family" if sub_column && !is_super(column_family)
21
+ klass, sub_klass = column_name_class(column_family), sub_column_name_class(column_family)
22
+ range_class = column ? sub_klass : klass
23
+
24
+ [:start, :finish].each do |opt|
25
+ options[opt] = options[opt] ? range_class.new(options[opt]).to_s : ''
26
+ end
27
+
28
+ [column_family, s_map(column, klass), s_map(sub_column, sub_klass), options]
29
+ end
30
+
31
+ # Convert stuff to strings.
32
+ def s_map(el, klass)
33
+ case el
34
+ when Array then el.map { |i| s_map(i, klass) }
35
+ when NilClass then nil
36
+ else
37
+ klass.new(el).to_s
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ class Cassandra
2
+ class Keyspace < CassandraThrift::KsDef ; end
3
+ end
@@ -0,0 +1,58 @@
1
+
2
+ class Cassandra
3
+ # A temporally-ordered Long class for use in Cassandra column names
4
+ class Long < Comparable
5
+
6
+ # FIXME Should unify with or subclass Cassandra::UUID
7
+ def initialize(bytes = nil)
8
+ case bytes
9
+ when self.class # Long
10
+ @bytes = bytes.to_s
11
+ when String
12
+ case bytes.size
13
+ when 8 # Raw byte array
14
+ @bytes = bytes
15
+ when 18 # Human-readable UUID-like representation; inverse of #to_guid
16
+ elements = bytes.split("-")
17
+ raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (malformed UUID-like representation)" if elements.size != 3
18
+ @bytes = [elements.join].pack('H32')
19
+ else
20
+ raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (invalid bytecount)"
21
+ end
22
+ when Integer
23
+ raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (integer out of range)" if bytes < 0 or bytes > 2**64
24
+ @bytes = [bytes >> 32, bytes % 2**32].pack("NN")
25
+ when NilClass, Time
26
+ # Time.stamp is 52 bytes, so we have 12 bytes of entropy left over
27
+ int = ((bytes || Time).stamp << 12) + rand(2**12)
28
+ @bytes = [int >> 32, int % 2**32].pack("NN")
29
+ else
30
+ raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (unknown source class)"
31
+ end
32
+ end
33
+
34
+ def to_i
35
+ @to_i ||= begin
36
+ ints = @bytes.unpack("NN")
37
+ (ints[0] << 32) +
38
+ ints[1]
39
+ end
40
+ end
41
+
42
+ def to_guid
43
+ "%08x-%04x-%04x" % @bytes.unpack("Nnn")
44
+ end
45
+
46
+ def inspect
47
+ "<Cassandra::Long##{object_id} time: #{
48
+ Time.at((to_i >> 12) / 1_000_000).utc.inspect
49
+ }, usecs: #{
50
+ (to_i >> 12) % 1_000_000
51
+ }, jitter: #{
52
+ to_i % 2**12
53
+ }, guid: #{
54
+ to_guid
55
+ }>"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,525 @@
1
+ class SimpleUUID::UUID
2
+ def >=(other)
3
+ (self <=> other) >= 0
4
+ end
5
+
6
+ def <=(other)
7
+ (self <=> other) <= 0
8
+ end
9
+ end
10
+
11
+ class Cassandra
12
+ class Mock
13
+ include ::Cassandra::Helpers
14
+ include ::Cassandra::Columns
15
+
16
+ attr_reader :keyspace
17
+
18
+ def initialize(keyspace, schema)
19
+ @is_super = {}
20
+ @keyspace = keyspace
21
+ @column_name_class = {}
22
+ @sub_column_name_class = {}
23
+ @column_name_maker = {}
24
+ @sub_column_name_maker = {}
25
+ @indexes = {}
26
+ @schema = schema[keyspace]
27
+ clear_keyspace!
28
+ end
29
+
30
+ def disconnect!
31
+ end
32
+
33
+ def clear_keyspace!
34
+ @data = {}
35
+ end
36
+
37
+ def clear_column_family!(column_family)
38
+ @data[column_family.to_sym] = OrderedHash.new
39
+ end
40
+
41
+ def default_write_consistency=(value)
42
+ WRITE_DEFAULTS[:consistency] = value
43
+ end
44
+
45
+ def default_read_consistency=(value)
46
+ READ_DEFAULTS[:consistency] = value
47
+ end
48
+
49
+ def insert(column_family, key, hash_or_array, options = {})
50
+ if @batch
51
+ @batch << [:insert, column_family, key, hash_or_array, options]
52
+ else
53
+ raise ArgumentError if key.nil?
54
+ if !is_super(column_family)
55
+ insert_standard(column_family, key, hash_or_array)
56
+ else
57
+ insert_super(column_family, key, hash_or_array)
58
+ end
59
+ end
60
+ end
61
+
62
+ def insert_standard(column_family, key, hash_or_array)
63
+ old = cf(column_family)[key] || OrderedHash.new
64
+ cf(column_family)[key] = merge_and_sort(old, hash_or_array)
65
+ end
66
+
67
+ def insert_super(column_family, key, hash)
68
+ raise ArgumentError unless hash.is_a?(Hash)
69
+ cf(column_family)[key] ||= OrderedHash.new
70
+
71
+ hash.keys.each do |sub_key|
72
+ old = cf(column_family)[key][sub_key] || OrderedHash.new
73
+ cf(column_family)[key][sub_key] = merge_and_sort(old, hash[sub_key])
74
+ end
75
+ end
76
+
77
+ def batch(options={})
78
+ @batch = Cassandra::Batch.new(self, options)
79
+ yield
80
+ flush_batch(options)
81
+ ensure
82
+ @batch = nil
83
+ end
84
+
85
+ def flush_batch(options)
86
+ b = @batch
87
+ @batch = nil
88
+ b.each do |mutation|
89
+ send(*mutation)
90
+ end
91
+ @batch = b
92
+ end
93
+
94
+ def get(column_family, key, *columns_and_options)
95
+ column_family, column, sub_column, options =
96
+ extract_and_validate_params_for_real(column_family, [key], columns_and_options, READ_DEFAULTS)
97
+ if !is_super(column_family)
98
+ get_standard(column_family, key, column, options)
99
+ else
100
+ get_super(column_family, key, column, sub_column, options)
101
+ end
102
+ end
103
+
104
+ def get_standard(column_family, key, column, options)
105
+ columns = cf(column_family)[key] || OrderedHash.new
106
+ row = columns_to_hash(column_family, columns)
107
+
108
+ if column
109
+ row[column]
110
+ else
111
+ row = apply_range(row, column_family, options[:start], options[:finish])
112
+ row = apply_count(row, options[:count], options[:reversed])
113
+ end
114
+ end
115
+
116
+ def get_super(column_family, key, column, sub_column, options)
117
+ columns = cf(column_family)[key] || OrderedHash.new
118
+ row = columns_to_hash(column_family, columns)
119
+
120
+ if column
121
+ if sub_column
122
+ if row[column] &&
123
+ row[column][sub_column]
124
+ row[column][sub_column]
125
+ else
126
+ nil
127
+ end
128
+ else
129
+ row = row[column] || OrderedHash.new
130
+ row = apply_range(row, column_family, options[:start], options[:finish], false)
131
+ row = apply_count(row, options[:count], options[:reversed])
132
+ end
133
+ else
134
+ row
135
+ end
136
+ end
137
+
138
+ def exists?(column_family, key, *columns_and_options)
139
+ column_family, column, sub_column, options = extract_and_validate_params_for_real(column_family, [key], columns_and_options, READ_DEFAULTS)
140
+ results = get(column_family, key, column, sub_column)
141
+
142
+ ![{}, nil].include?(results)
143
+ end
144
+
145
+ def multi_get(column_family, keys, *columns_and_options)
146
+ column_family, column, sub_column, options = extract_and_validate_params_for_real(column_family, keys, columns_and_options, READ_DEFAULTS)
147
+ keys.inject(OrderedHash.new) do |hash, key|
148
+ hash[key] = get(column_family, key)
149
+ hash
150
+ end
151
+ end
152
+
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)
155
+ if @batch
156
+ @batch << [:remove, column_family, key, column, sub_column]
157
+ else
158
+ if column
159
+ if sub_column
160
+ cf(column_family)[key][column].delete(sub_column.to_s) if cf(column_family)[key][column]
161
+ else
162
+ cf(column_family)[key].delete(column.to_s) if cf(column_family)[key]
163
+ end
164
+ else
165
+ cf(column_family).delete(key)
166
+ end
167
+ end
168
+ end
169
+
170
+ def get_columns(column_family, key, *columns_and_options)
171
+ column_family, columns, sub_columns, options = extract_and_validate_params_for_real(column_family, key, columns_and_options, READ_DEFAULTS)
172
+ d = get(column_family, key)
173
+
174
+ if sub_columns
175
+ sub_columns.collect do |sub_column|
176
+ d[columns][sub_column]
177
+ end
178
+ else
179
+ columns.collect do |column|
180
+ d[column]
181
+ end
182
+ end
183
+ end
184
+
185
+ def count_columns(column_family, key, *columns_and_options)
186
+ column_family, columns, sub_columns, options = extract_and_validate_params_for_real(column_family, key, columns_and_options, READ_DEFAULTS)
187
+
188
+ get(column_family, key, columns, options).keys.length
189
+ end
190
+
191
+ def multi_get_columns(column_family, keys, columns)
192
+ keys.inject(OrderedHash.new) do |hash, key|
193
+ hash[key] = get_columns(column_family, key, columns)
194
+ hash
195
+ end
196
+ end
197
+
198
+ def multi_count_columns(column_family, keys)
199
+ keys.inject(OrderedHash.new) do |hash, key|
200
+ hash[key] = count_columns(column_family, key)
201
+ hash
202
+ end
203
+ end
204
+
205
+ def get_range(column_family, options = {}, &blk)
206
+ column_family, _, _, options = extract_and_validate_params_for_real(column_family, "", [options],
207
+ READ_DEFAULTS.merge(:start_key => nil,
208
+ :finish_key => nil,
209
+ :key_count => 100,
210
+ :columns => nil,
211
+ :reversed => false
212
+ )
213
+ )
214
+ res = _get_range(column_family,
215
+ options[:start_key],
216
+ options[:finish_key],
217
+ options[:key_count],
218
+ options[:columns],
219
+ options[:start],
220
+ options[:finish],
221
+ options[:count],
222
+ options[:consistency],
223
+ options[:reversed], &blk)
224
+
225
+ if blk.nil?
226
+ res
227
+ else
228
+ nil
229
+ end
230
+ end
231
+
232
+ def get_range_keys(column_family, options = {})
233
+ get_range(column_family,options.merge!(:columns => [])).keys
234
+ end
235
+
236
+ def count_range(column_family, options = {})
237
+ Hash[get_range(column_family, options).select{|k,v| v.length > 0}].keys.compact.length
238
+ end
239
+
240
+ def each_key(column_family, options = {})
241
+ each(column_family, options.merge!(:columns => [])) do |key, value|
242
+ yield key
243
+ end
244
+ end
245
+
246
+ def each(column_family, options = {})
247
+ batch_size = options.delete(:batch_size) || 100
248
+ count = options.delete(:key_count)
249
+ yielded_count = 0
250
+
251
+ options[:start_key] ||= ''
252
+ last_key = nil
253
+
254
+ while options[:start_key] != last_key && (count.nil? || count > yielded_count)
255
+ options[:start_key] = last_key
256
+ res = get_range(column_family, options.merge!(:start_key => last_key, :key_count => batch_size))
257
+ res.each do |key, columns|
258
+ next if options[:start_key] == key
259
+ next if yielded_count == count
260
+ yield key, columns
261
+ yielded_count += 1
262
+ last_key = key
263
+ end
264
+ end
265
+ end
266
+
267
+ def create_index(ks_name, cf_name, c_name, v_class)
268
+ if @indexes[ks_name] &&
269
+ @indexes[ks_name][cf_name] &&
270
+ @indexes[ks_name][cf_name][c_name]
271
+ nil
272
+
273
+ else
274
+ @indexes[ks_name] ||= {}
275
+ @indexes[ks_name][cf_name] ||= {}
276
+ @indexes[ks_name][cf_name][c_name] = true
277
+ end
278
+ end
279
+
280
+ def drop_index(ks_name, cf_name, c_name)
281
+ if @indexes[ks_name] &&
282
+ @indexes[ks_name][cf_name] &&
283
+ @indexes[ks_name][cf_name][c_name]
284
+
285
+ @indexes[ks_name][cf_name].delete(c_name)
286
+ else
287
+ nil
288
+ end
289
+ end
290
+
291
+ def create_index_expression(c_name, value, op)
292
+ {:column_name => c_name, :value => value, :comparison => op}
293
+ end
294
+ alias :create_idx_expr :create_index_expression
295
+
296
+ def create_index_clause(idx_expressions, start = "", count = 100)
297
+ {:start => start, :index_expressions => idx_expressions, :count => count, :type => :index_clause}
298
+ end
299
+ alias :create_idx_clause :create_index_clause
300
+
301
+ def get_indexed_slices(column_family, idx_clause, *columns_and_options)
302
+ column_family, columns, _, options =
303
+ extract_and_validate_params_for_real(column_family, [], columns_and_options,
304
+ READ_DEFAULTS.merge(:key_count => 100, :start_key => nil, :key_start => nil))
305
+
306
+ start_key = options[:start_key] || options[:key_start] || ""
307
+
308
+ unless [Hash, OrderedHash].include?(idx_clause.class) && idx_clause[:type] == :index_clause
309
+ idx_clause = create_index_clause(idx_clause, start_key, options[:key_count])
310
+ end
311
+
312
+ ret = OrderedHash.new
313
+ cf(column_family).each do |key, row|
314
+ next if idx_clause[:start] != '' && key < idx_clause[:start]
315
+ next if ret.length == idx_clause[:count]
316
+
317
+ matches = []
318
+ idx_clause[:index_expressions].each do |expr|
319
+ next if row[expr[:column_name]].nil?
320
+ next unless row[expr[:column_name]].send(expr[:comparison].to_sym, expr[:value])
321
+
322
+ matches << expr
323
+ end
324
+
325
+ ret[key] = row if matches.length == idx_clause[:index_expressions].length
326
+ end
327
+
328
+ ret
329
+ end
330
+
331
+ def add(column_family, key, value, *columns_and_options)
332
+ if @batch
333
+ @batch << [:add, column_family, key, value, *columns_and_options]
334
+ else
335
+ column_family, column, sub_column, options = extract_and_validate_params_for_real(column_family, key, columns_and_options, WRITE_DEFAULTS)
336
+
337
+ if is_super(column_family)
338
+ cf(column_family)[key] ||= OrderedHash.new
339
+ cf(column_family)[key][column] ||= OrderedHash.new
340
+ cf(column_family)[key][column][sub_column] ||= 0
341
+ cf(column_family)[key][column][sub_column] += value
342
+ else
343
+ cf(column_family)[key] ||= OrderedHash.new
344
+ cf(column_family)[key][column] ||= 0
345
+ cf(column_family)[key][column] += value
346
+ end
347
+
348
+ nil
349
+ end
350
+ end
351
+
352
+ def column_families
353
+ cf_defs = {}
354
+ schema.each do |key, value|
355
+ cf_def = Cassandra::ColumnFamily.new
356
+
357
+ value.each do |property, property_value|
358
+ cf_def.send(:"#{property}=", property_value)
359
+ end
360
+
361
+ cf_defs[key] = cf_def
362
+ end
363
+
364
+ cf_defs
365
+ end
366
+
367
+ def schema(load=true)
368
+ @schema
369
+ end
370
+
371
+ def column_family_property(column_family, key)
372
+ schema[column_family.to_s][key]
373
+ end
374
+
375
+ def add_column_family(cf)
376
+ @schema[cf.name.to_s] ||= OrderedHash.new
377
+
378
+ cf.instance_variables.each do |var|
379
+ @schema[cf.name.to_s][var.slice(1..-1)] = cf.instance_variable_get(var)
380
+ end
381
+ end
382
+
383
+ def update_column_family(cf)
384
+ return false unless @schema.include?(cf.name.to_s)
385
+
386
+ cf.instance_variables.each do |var|
387
+ @schema[cf.name.to_s][var.slice(1..-1)] = cf.instance_variable_get(var)
388
+ end
389
+ end
390
+
391
+ def drop_column_family(column_family_name)
392
+ @schema.delete(column_family_name)
393
+ end
394
+
395
+ private
396
+
397
+ def schema_for_keyspace(keyspace)
398
+ @schema
399
+ end
400
+
401
+ def _get_range(column_family, start_key, finish_key, key_count, columns, start, finish, count, consistency, reversed, &blk)
402
+ ret = OrderedHash.new
403
+ start = to_compare_with_type(start, column_family)
404
+ finish = to_compare_with_type(finish, column_family)
405
+ cf(column_family).keys.sort.each do |key|
406
+ break if ret.keys.size >= key_count
407
+ if (start_key.nil? || key >= start_key) && (finish_key.nil? || key <= finish_key)
408
+ if columns
409
+ #ret[key] = columns.inject(OrderedHash.new){|hash, column_name| hash[column_name] = cf(column_family)[key][column_name]; hash;}
410
+ selected_hash = OrderedHash.new
411
+ cf(column_family)[key].each do |k, v|
412
+ selected_hash.[]=(k, v, cf(column_family)[key].timestamps[k]) if columns.include?(k)
413
+ end
414
+ ret[key] = columns_to_hash(column_family, selected_hash)
415
+ ret[key] = apply_count(ret[key], count, reversed)
416
+ blk.call(key,ret[key]) unless blk.nil?
417
+ else
418
+ #ret[key] = apply_range(cf(column_family)[key], column_family, start, finish, !is_super(column_family))
419
+ start, finish = finish, start if reversed
420
+ ret[key] = apply_range(columns_to_hash(column_family, cf(column_family)[key]), column_family, start, finish)
421
+ ret[key] = apply_count(ret[key], count, reversed)
422
+ blk.call(key,ret[key]) unless blk.nil?
423
+ end
424
+ end
425
+ end
426
+ ret
427
+ end
428
+
429
+ def extract_and_validate_params_for_real(column_family, keys, args, options)
430
+ column_family, columns, sub_column, options = extract_and_validate_params(column_family, keys, args, options)
431
+ options[:start] = nil if options[:start] == ''
432
+ options[:finish] = nil if options[:finish] == ''
433
+ [column_family, to_compare_with_types(columns, column_family), to_compare_with_types(sub_column, column_family, false), options]
434
+ end
435
+
436
+ def to_compare_with_types(column_names, column_family, standard=true)
437
+ if column_names.is_a?(Array)
438
+ column_names.collect do |name|
439
+ to_compare_with_type(name, column_family, standard)
440
+ end
441
+ else
442
+ to_compare_with_type(column_names, column_family, standard)
443
+ end
444
+ end
445
+
446
+ def to_compare_with_type(column_name, column_family, standard=true)
447
+ return column_name if column_name.nil?
448
+ klass = if standard
449
+ column_name_class(column_family)
450
+ else
451
+ sub_column_name_class(column_family)
452
+ end
453
+
454
+ klass.new(column_name)
455
+ end
456
+
457
+ def cf(column_family)
458
+ @data[column_family.to_sym] ||= OrderedHash.new
459
+ end
460
+
461
+ def merge_and_sort(old_stuff, new_stuff)
462
+ if new_stuff.is_a?(Array)
463
+ new_stuff = new_stuff.inject({}){|h,k| h[k] = nil; h }
464
+ end
465
+
466
+ new_stuff = new_stuff.to_a.inject({}){|h,k| h[k[0].to_s] = k[1]; h }
467
+
468
+ new_stuff.each { |k,v| old_stuff.[]=(k, v, (Time.now.to_f * 1000000).to_i) }
469
+ hash = OrderedHash.new
470
+ old_stuff.sort{ |a,b| a[0] <=> b[0] }.each do |k, v|
471
+ hash.[]=(k, v, old_stuff.timestamps[k])
472
+ end
473
+ hash
474
+ end
475
+
476
+ def columns_to_hash(column_family, columns)
477
+ column_class, sub_column_class = column_name_class(column_family), sub_column_name_class(column_family)
478
+ output = OrderedHash.new
479
+
480
+ columns.each do |column_name, value|
481
+ timestamp = columns.timestamps[column_name]
482
+ column = column_class.new(column_name)
483
+
484
+ if [Hash, OrderedHash].include?(value.class)
485
+ output[column] ||= OrderedHash.new
486
+ value.each do |sub_column, sub_column_value|
487
+ timestamp = value.timestamps[sub_column]
488
+ output[column].[]=(sub_column_class.new(sub_column), sub_column_value, timestamp)
489
+ end
490
+ else
491
+ output.[]=(column_class.new(column_name), value, timestamp)
492
+ end
493
+ end
494
+
495
+ output
496
+ end
497
+
498
+ def apply_count(row, count, reversed=false)
499
+ if count
500
+ keys = row.keys.sort
501
+ keys = keys.reverse if reversed
502
+ keys = keys[0...count]
503
+ keys.inject(OrderedHash.new) do |memo, key|
504
+ memo.[]=(key, row[key], row.timestamps[key])
505
+ memo
506
+ end
507
+ else
508
+ row
509
+ end
510
+ end
511
+
512
+ def apply_range(row, column_family, strt, fin, standard=true)
513
+ start = to_compare_with_type(strt, column_family, standard)
514
+ finish = to_compare_with_type(fin, column_family, standard)
515
+ ret = OrderedHash.new
516
+ row.keys.each do |key|
517
+ if (start.nil? || key >= start) && (finish.nil? || key <= finish)
518
+ ret.[]=(key, row[key], row.timestamps[key])
519
+ end
520
+ end
521
+ ret
522
+ end
523
+
524
+ end
525
+ end