hbase-jruby 0.3.5-java → 0.4.0-java
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.md +13 -0
- data/README.md +135 -30
- data/lib/hbase-jruby/batch_exception.rb +12 -0
- data/lib/hbase-jruby/byte_array.rb +6 -0
- data/lib/hbase-jruby/dependency.rb +6 -4
- data/lib/hbase-jruby/row.rb +8 -2
- data/lib/hbase-jruby/schema.rb +2 -1
- data/lib/hbase-jruby/scoped.rb +7 -4
- data/lib/hbase-jruby/table/batch_action.rb +69 -0
- data/lib/hbase-jruby/table/checked_operation.rb +11 -8
- data/lib/hbase-jruby/table/mutation.rb +130 -0
- data/lib/hbase-jruby/table.rb +130 -82
- data/lib/hbase-jruby/version.rb +1 -1
- data/lib/hbase-jruby.rb +3 -0
- data/test/helper.rb +8 -1
- data/test/test_byte_array.rb +4 -0
- data/test/test_schema.rb +123 -67
- data/test/test_table.rb +266 -120
- metadata +5 -2
data/lib/hbase-jruby/table.rb
CHANGED
@@ -43,7 +43,7 @@ class Table
|
|
43
43
|
|
44
44
|
[:get, :count, :aggregate,
|
45
45
|
:range, :project, :filter, :while,
|
46
|
-
:limit, :versions, :caching, :batch,
|
46
|
+
:limit, :versions, :caching, # :batch,
|
47
47
|
:time_range, :at
|
48
48
|
].each do |method|
|
49
49
|
define_method(method) do |*args|
|
@@ -72,11 +72,11 @@ class Table
|
|
72
72
|
def put *args
|
73
73
|
case args.length
|
74
74
|
when 1
|
75
|
-
puts = args.first.map { |rowkey, props|
|
75
|
+
puts = args.first.map { |rowkey, props| @mutation.put rowkey, props }
|
76
76
|
htable.put puts
|
77
77
|
puts.length
|
78
78
|
when 2
|
79
|
-
htable.put
|
79
|
+
htable.put @mutation.put(*args)
|
80
80
|
1
|
81
81
|
else
|
82
82
|
raise ArgumentError, 'invalid number of arguments'
|
@@ -125,14 +125,24 @@ class Table
|
|
125
125
|
def delete *args
|
126
126
|
specs = args.first.is_a?(Array) ? args : [args]
|
127
127
|
|
128
|
-
|
128
|
+
list = specs.map { |spec| spec.empty? ? nil : @mutation.delete(*spec) }.compact
|
129
|
+
if list.length == 1
|
130
|
+
htable.delete list.first
|
131
|
+
else
|
132
|
+
htable.delete list
|
133
|
+
end
|
129
134
|
end
|
130
135
|
|
131
136
|
# Delete rows.
|
132
137
|
# @param [*Object] rowkeys List of rowkeys of rows to delete
|
133
138
|
# @return [nil]
|
134
139
|
def delete_row *rowkeys
|
135
|
-
|
140
|
+
list = rowkeys.map { |rk| Delete.new(Util.to_bytes rk) }
|
141
|
+
if list.length == 1
|
142
|
+
htable.delete list.first
|
143
|
+
else
|
144
|
+
htable.delete list
|
145
|
+
end
|
136
146
|
end
|
137
147
|
|
138
148
|
# Atomically increase numeric values
|
@@ -141,41 +151,69 @@ class Table
|
|
141
151
|
# @param [Object] rowkey Rowkey
|
142
152
|
# @param [String, Array] column Column expression in String "FAMILY:QUALIFIER", or in Array [FAMILY, QUALIFIER]
|
143
153
|
# @param [Fixnum] by Increment amount
|
144
|
-
# @return [
|
154
|
+
# @return [Hash]
|
145
155
|
# @example
|
146
156
|
# table.increment('a000', 'cf1:col1', 1)
|
147
157
|
# @overload increment(rowkey, column_by_hash)
|
148
158
|
# Atomically increase values of multiple columns
|
149
159
|
# @param [Object] rowkey Rowkey
|
150
160
|
# @param [Hash] column_by_hash Column expression to increment amount pairs
|
161
|
+
# @return [Hash]
|
151
162
|
# @example
|
152
163
|
# table.increment('a000', 'cf1:col1' => 1, 'cf1:col2' => 2)
|
153
164
|
# @overload increment(inc_spec)
|
154
165
|
# Increase values of multiple columns from multiple rows.
|
155
166
|
# @param [Hash] inc_spec { rowkey => { col => by } }
|
167
|
+
# @return [Hash]
|
156
168
|
# @example
|
157
169
|
# table.increment 'a000' => { 'cf1:col1' => 1, 'cf1:col2' => 2 },
|
158
170
|
# 'a001' => { 'cf1:col1' => 3, 'cf1:col2' => 4 }
|
159
171
|
def increment rowkey, *args
|
160
172
|
if args.empty? && rowkey.is_a?(Hash)
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
elsif args.first.is_a?(Hash)
|
165
|
-
cols = args.first
|
166
|
-
htable.increment Increment.new(Util.to_bytes rowkey).tap { |inc|
|
167
|
-
cols.each do |col, by|
|
168
|
-
cf, cq, _ = lookup_and_parse col
|
169
|
-
inc.addColumn cf, cq, by
|
173
|
+
INSENSITIVE_ROW_HASH.clone.tap { |result|
|
174
|
+
rowkey.each do |key, spec|
|
175
|
+
result[Util.java_bytes?(key) ? ByteArray[key] : key] = increment(key, spec)
|
170
176
|
end
|
171
177
|
}
|
172
178
|
else
|
173
|
-
|
174
|
-
|
175
|
-
|
179
|
+
incr = @mutation.increment(rowkey, *args)
|
180
|
+
Row.send(:new, self, htable.increment(incr)).to_h.tap { |h|
|
181
|
+
h.each do |k, v|
|
182
|
+
h[k] = Util.from_bytes :fixnum, v unless v.is_a?(Fixnum)
|
183
|
+
end
|
184
|
+
}
|
176
185
|
end
|
177
186
|
end
|
178
187
|
|
188
|
+
# Appends values to one or more columns within a single row.
|
189
|
+
# @param [Object] rowkey Rowkey
|
190
|
+
# @param [Hash] spec Hash (column to value)
|
191
|
+
# @return [Hash] Updated values
|
192
|
+
# @example
|
193
|
+
# table.put :rowkey, col1: 'hello', col2: 'foo'
|
194
|
+
# table.append :rowkey, col1: ' world', col2: 'bar'
|
195
|
+
# # { col1: 'hello world', col2: 'foobar' }
|
196
|
+
def append rowkey, spec
|
197
|
+
result = htable.append @mutation.append(rowkey, spec)
|
198
|
+
Row.send(:new, self, result).to_h if result # (maybe null)
|
199
|
+
end
|
200
|
+
|
201
|
+
# Performs multiple mutations atomically on a single row.
|
202
|
+
# Currently Put and Delete are supported.
|
203
|
+
# The mutations are performed in the order in which they were specified.
|
204
|
+
# @param [Object] rowkey Rowkey
|
205
|
+
# @yield [HBase::Table::Mutation::Mutator]
|
206
|
+
# @return [nil]
|
207
|
+
# @example
|
208
|
+
# table.mutate do |m|
|
209
|
+
# m.put a: 100, b: 'hello'
|
210
|
+
# m.delete :c, :d
|
211
|
+
# m.put e: 3.14
|
212
|
+
# end
|
213
|
+
def mutate(rowkey, &block)
|
214
|
+
htable.mutateRow @mutation.mutate(rowkey, &block)
|
215
|
+
end
|
216
|
+
|
179
217
|
# Scan through the table
|
180
218
|
# @yield [row] Yields each row in the scope
|
181
219
|
# @yieldparam [HBase::Row] row
|
@@ -187,7 +225,7 @@ class Table
|
|
187
225
|
# Returns HBase::Scoped object for this table
|
188
226
|
# @return [HBase::Scoped]
|
189
227
|
def scoped
|
190
|
-
Scoped.send(:new, self)
|
228
|
+
Scoped.send(:new, self, @hbase.config.get('hbase.client.scanner.caching').to_i)
|
191
229
|
end
|
192
230
|
|
193
231
|
# Returns CheckedOperation instance for check-and-put and check-and-delete
|
@@ -198,22 +236,82 @@ class Table
|
|
198
236
|
raise ArgumentError, 'invalid check condition' unless cond.length == 1
|
199
237
|
col, val = cond.first
|
200
238
|
|
201
|
-
cf, cq, type = lookup_and_parse(col)
|
239
|
+
cf, cq, type = lookup_and_parse(col, true)
|
202
240
|
|
203
241
|
# If the passed value is null, the check is for the lack of column
|
204
|
-
CheckedOperation.new self, Util.to_bytes(rowkey),
|
242
|
+
CheckedOperation.new self, @mutation, Util.to_bytes(rowkey),
|
205
243
|
cf, cq,
|
206
244
|
(val.nil? ? nil : Util.to_typed_bytes(type, val))
|
207
245
|
end
|
208
246
|
|
247
|
+
# Method that does a batch call on Deletes, Gets, Puts, Increments, Appends
|
248
|
+
# and RowMutations. The ordering of execution of the actions is not defined.
|
249
|
+
# An Array of Hashes are returned as the results of each operation. For
|
250
|
+
# Delete, Put, and RowMutation, :result entry of the returned Hash is
|
251
|
+
# Boolean. For Increment and Append, it will be plain Hashes, and for Get,
|
252
|
+
# HBase::Rows will be returned.
|
253
|
+
# When an error has occurred, you can still access the partial results using
|
254
|
+
# `results` method of the thrown BatchException instance.
|
255
|
+
# @yield [HBase::Table::BatchAction]
|
256
|
+
# @return [Array<Hash>]
|
257
|
+
# @raise [HBase::BatchException]
|
258
|
+
def batch arg = nil
|
259
|
+
if arg
|
260
|
+
# Backward compatibility
|
261
|
+
return scoped.batch(arg)
|
262
|
+
else
|
263
|
+
raise ArgumentError, "Block not given" unless block_given?
|
264
|
+
end
|
265
|
+
b = BatchAction.send(:new, self, @mutation)
|
266
|
+
yield b
|
267
|
+
results = Array.new(b.actions.length).to_java
|
268
|
+
process = lambda do
|
269
|
+
results.each_with_index do |r, idx|
|
270
|
+
action = b.actions[idx]
|
271
|
+
type = action[:type]
|
272
|
+
case type
|
273
|
+
when :get
|
274
|
+
action[:result] = (r.nil? || r.empty?) ? nil : Row.send(:new, self, r)
|
275
|
+
when :append
|
276
|
+
action[:result] = r && Row.send(:new, self, r).to_h
|
277
|
+
when :increment
|
278
|
+
action[:result] = r &&
|
279
|
+
Row.send(:new, self, r).to_h.tap { |h|
|
280
|
+
h.each do |k, v|
|
281
|
+
h[k] = Util.from_bytes :fixnum, v unless v.is_a?(Fixnum)
|
282
|
+
end
|
283
|
+
}
|
284
|
+
else
|
285
|
+
case r
|
286
|
+
when java.lang.Exception
|
287
|
+
action[:result] = false
|
288
|
+
action[:exception] = r
|
289
|
+
when nil
|
290
|
+
action[:result] = false
|
291
|
+
else
|
292
|
+
action[:result] = true
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
b.actions
|
297
|
+
end
|
298
|
+
|
299
|
+
begin
|
300
|
+
htable.batch b.actions.map { |a| a[:action] }, results
|
301
|
+
process.call
|
302
|
+
rescue Exception => e
|
303
|
+
raise HBase::BatchException.new(e, process.call)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
209
307
|
# @private
|
210
308
|
def lookup_schema col
|
211
309
|
@hbase.schema.lookup @name_sym, col
|
212
310
|
end
|
213
311
|
|
214
312
|
# @private
|
215
|
-
def lookup_and_parse col
|
216
|
-
@hbase.schema.lookup_and_parse @name_sym, col
|
313
|
+
def lookup_and_parse col, expect_cq
|
314
|
+
@hbase.schema.lookup_and_parse @name_sym, col, expect_cq
|
217
315
|
end
|
218
316
|
|
219
317
|
private
|
@@ -222,73 +320,23 @@ private
|
|
222
320
|
@config = config
|
223
321
|
@name = name.to_s
|
224
322
|
@name_sym = name.to_sym
|
323
|
+
@mutation = Mutation.new(self)
|
225
324
|
end
|
226
325
|
|
227
326
|
def check_closed
|
228
327
|
raise RuntimeError, "HBase connection is already closed" if @hbase.closed?
|
229
328
|
end
|
230
329
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
cf, cq, type = lookup_and_parse col
|
237
|
-
|
238
|
-
case val
|
239
|
-
when Hash
|
240
|
-
val.each do |t, v|
|
241
|
-
case t
|
242
|
-
# Timestamp / Ruby Time
|
243
|
-
when Time, Fixnum
|
244
|
-
put.add cf, cq, time_to_long(t), Util.to_typed_bytes(type, v)
|
245
|
-
# Types: :byte, :short, :int, ...
|
246
|
-
else
|
247
|
-
put.add cf, cq, Util.to_typed_bytes(t, v)
|
248
|
-
end unless v.nil?
|
249
|
-
end
|
250
|
-
else
|
251
|
-
put.add cf, cq, Util.to_typed_bytes(type, val)
|
330
|
+
INSENSITIVE_ROW_HASH = {}.tap { |h|
|
331
|
+
h.instance_eval do
|
332
|
+
def [] key
|
333
|
+
if Util.java_bytes?(key)
|
334
|
+
key = ByteArray[key]
|
252
335
|
end
|
336
|
+
super key
|
253
337
|
end
|
254
|
-
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
|
-
def make_delete rowkey, *extra
|
259
|
-
Delete.new(Util.to_bytes rowkey).tap { |del|
|
260
|
-
cf = cq = nil
|
261
|
-
prcd = false
|
262
|
-
|
263
|
-
prc = lambda do
|
264
|
-
unless prcd
|
265
|
-
if cq
|
266
|
-
# Delete all versions
|
267
|
-
del.deleteColumns cf, cq
|
268
|
-
elsif cf
|
269
|
-
del.deleteFamily cf
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
extra.each do |x|
|
275
|
-
case x
|
276
|
-
when Fixnum, Time
|
277
|
-
if cq
|
278
|
-
del.deleteColumn cf, cq, time_to_long(x)
|
279
|
-
prcd = true
|
280
|
-
else
|
281
|
-
raise ArgumentError, 'qualifier not given'
|
282
|
-
end
|
283
|
-
else
|
284
|
-
prc.call
|
285
|
-
cf, cq, _ = lookup_and_parse x
|
286
|
-
prcd = false
|
287
|
-
end
|
288
|
-
end
|
289
|
-
prc.call
|
290
|
-
}
|
291
|
-
end
|
338
|
+
end
|
339
|
+
}
|
292
340
|
end#Table
|
293
341
|
end#HBase
|
294
342
|
|
data/lib/hbase-jruby/version.rb
CHANGED
data/lib/hbase-jruby.rb
CHANGED
@@ -11,7 +11,10 @@ require 'hbase-jruby/admin'
|
|
11
11
|
require 'hbase-jruby/scoped/aggregation'
|
12
12
|
require 'hbase-jruby/scoped'
|
13
13
|
require 'hbase-jruby/schema'
|
14
|
+
require 'hbase-jruby/batch_exception'
|
14
15
|
require 'hbase-jruby/table'
|
16
|
+
require 'hbase-jruby/table/mutation'
|
17
|
+
require 'hbase-jruby/table/batch_action'
|
15
18
|
require 'hbase-jruby/table/admin'
|
16
19
|
require 'hbase-jruby/table/inspection'
|
17
20
|
require 'hbase-jruby/table/checked_operation'
|
data/test/helper.rb
CHANGED
@@ -12,6 +12,7 @@ unless defined? Enumerator
|
|
12
12
|
end
|
13
13
|
|
14
14
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
15
|
+
$rowkey = Time.now.to_i
|
15
16
|
|
16
17
|
require "hbase-jruby"
|
17
18
|
if dist = ENV['HBASE_JRUBY_TEST_DIST']
|
@@ -31,7 +32,9 @@ class TestHBaseJRubyBase < Test::Unit::TestCase
|
|
31
32
|
hbase.close
|
32
33
|
|
33
34
|
def connect
|
34
|
-
HBase.new
|
35
|
+
HBase.new('hbase.zookeeper.quorum' => ZK,
|
36
|
+
'hbase.client.retries.number' => 10,
|
37
|
+
'hbase.client.scanner.caching' => 100)
|
35
38
|
end
|
36
39
|
|
37
40
|
def setup
|
@@ -53,6 +56,10 @@ class TestHBaseJRubyBase < Test::Unit::TestCase
|
|
53
56
|
end
|
54
57
|
end
|
55
58
|
|
59
|
+
def next_rowkey
|
60
|
+
$rowkey += 1
|
61
|
+
end
|
62
|
+
|
56
63
|
def teardown
|
57
64
|
if RECREATE
|
58
65
|
@table.drop! if @table && @table.exists?
|
data/test/test_byte_array.rb
CHANGED
data/test/test_schema.rb
CHANGED
@@ -52,17 +52,19 @@ class TestSchema < TestHBaseJRubyBase
|
|
52
52
|
}
|
53
53
|
|
54
54
|
# PUT
|
55
|
-
|
55
|
+
rk1 = next_rowkey
|
56
|
+
rk2 = next_rowkey
|
57
|
+
@table.put rk1, 'cf1:a' => data[:a], 'cf1:b' => data[:b], 'cf1:c' => data[:c],
|
56
58
|
'cf1:d' => data[:d], 'cf1:d2' => data[:d2], 'cf2:e' => data[:e],
|
57
59
|
'cf3:f' => data[:f], 'cf1:x' => data[[:cf1, HBase::ByteArray['x']]]
|
58
|
-
@table.put
|
60
|
+
@table.put rk2, data
|
59
61
|
|
60
62
|
# GET
|
61
|
-
row = @table.get(
|
62
|
-
assert_equal Set[ *@table.get(
|
63
|
-
Set[ *
|
64
|
-
assert_equal Set[ *@table.get(
|
65
|
-
assert_equal Set[ *data.keys ],
|
63
|
+
row = @table.get(rk2)
|
64
|
+
assert_equal Set[ *@table.get(rk1).to_h.values.map { |b| HBase::ByteArray.new b }],
|
65
|
+
Set[ * row.to_h.values.map { |b| HBase::ByteArray.new b }]
|
66
|
+
assert_equal Set[ *@table.get(rk1).to_h.keys ], Set[ *row.to_h.keys ]
|
67
|
+
assert_equal Set[ *data.keys ], Set[ *row.to_h.keys ]
|
66
68
|
|
67
69
|
assert_equal data[:a], row[:a]
|
68
70
|
assert_equal data[:a], row['a']
|
@@ -84,17 +86,20 @@ class TestSchema < TestHBaseJRubyBase
|
|
84
86
|
|
85
87
|
assert_equal data[[:cf1, HBase::ByteArray['x']]], HBase::Util.from_bytes(:long, row['cf1:x'])
|
86
88
|
|
87
|
-
data1 = @table.get(
|
89
|
+
data1 = @table.get(rk1).to_h
|
88
90
|
data1[:a] *= 2
|
89
91
|
data1[:b] = :new_symbol
|
90
|
-
|
91
|
-
|
92
|
+
|
93
|
+
rk3 = next_rowkey
|
94
|
+
@table.put rk3, data1
|
95
|
+
ret = @table.increment rk3, :a => 5
|
92
96
|
|
93
97
|
# PUT again
|
94
|
-
assert_equal data[:a] * 2 + 5,
|
95
|
-
assert_equal :
|
96
|
-
assert_equal :new_symbol, @table.get(
|
97
|
-
assert_equal :new_symbol, @table.get(
|
98
|
+
assert_equal data[:a] * 2 + 5, ret[:a]
|
99
|
+
assert_equal data[:a] * 2 + 5, @table.get(rk3)[:a]
|
100
|
+
assert_equal :new_symbol, @table.get(rk3)[:b]
|
101
|
+
assert_equal :new_symbol, @table.get(rk3)['b']
|
102
|
+
assert_equal :new_symbol, @table.get(rk3)['cf1:b']
|
98
103
|
|
99
104
|
# PROJECT
|
100
105
|
assert_equal [:a, :c, :e, :f],
|
@@ -110,17 +115,18 @@ class TestSchema < TestHBaseJRubyBase
|
|
110
115
|
assert_equal 1, @table.filter(:a => { :gt => 150 }).count
|
111
116
|
|
112
117
|
# cf:g (automatic type conversion)
|
113
|
-
@table.put
|
114
|
-
assert_equal 3.14, @table.get(
|
115
|
-
@table.put
|
116
|
-
assert_equal 314, @table.get(
|
118
|
+
@table.put rk3, :g => 3.14
|
119
|
+
assert_equal 3.14, @table.get(rk3)[:g]
|
120
|
+
@table.put rk3, :g => 314
|
121
|
+
assert_equal 314, @table.get(rk3)[:g]
|
117
122
|
|
118
123
|
# cf3:g vs. cf2:g
|
119
|
-
|
120
|
-
|
121
|
-
assert_equal
|
122
|
-
assert_equal
|
123
|
-
assert_equal
|
124
|
+
rk4 = next_rowkey
|
125
|
+
@table.put rk4, :g => 3.14, 'cf2:g' => 'String'
|
126
|
+
assert_equal 3.14, @table.get(rk4)[:g]
|
127
|
+
assert_equal 'String', @table.get(rk4)['cf2:g'].to_s
|
128
|
+
assert_equal 3.14, @table.get(rk4).to_h[:g]
|
129
|
+
assert_equal 'String', @table.get(rk4).to_h['cf2:g'].to_s
|
124
130
|
end
|
125
131
|
|
126
132
|
def test_schema_readme
|
@@ -152,9 +158,10 @@ class TestSchema < TestHBaseJRubyBase
|
|
152
158
|
:alive => true
|
153
159
|
}
|
154
160
|
|
155
|
-
|
161
|
+
rk = next_rowkey
|
162
|
+
@table.put(rk => data)
|
156
163
|
|
157
|
-
john = @table.get(
|
164
|
+
john = @table.get(rk)
|
158
165
|
|
159
166
|
data.each do |k, v|
|
160
167
|
assert_equal v, john[k]
|
@@ -170,6 +177,7 @@ class TestSchema < TestHBaseJRubyBase
|
|
170
177
|
|
171
178
|
def test_schema_book
|
172
179
|
table = @table
|
180
|
+
rk = next_rowkey
|
173
181
|
|
174
182
|
@hbase.schema[table.name] = {
|
175
183
|
# Columns in cf1 family
|
@@ -210,12 +218,12 @@ class TestSchema < TestHBaseJRubyBase
|
|
210
218
|
:comment1 => 'A must-have',
|
211
219
|
:comment2 => 'Rewarding purchase'
|
212
220
|
}
|
213
|
-
table.put
|
221
|
+
table.put rk, data
|
214
222
|
# Since we can't directly compare java byte arrays
|
215
223
|
data[:image] = HBase::ByteArray[ data[:image] ]
|
216
224
|
|
217
225
|
# Get data (rowkey: 1)
|
218
|
-
book = table.get
|
226
|
+
book = table.get rk
|
219
227
|
|
220
228
|
assert_equal data, book.to_h.tap { |h| h[:image] = HBase::ByteArray[ h[:image] ] }
|
221
229
|
assert_equal data[:title], book['title']
|
@@ -229,13 +237,15 @@ class TestSchema < TestHBaseJRubyBase
|
|
229
237
|
assert_equal true, book.to_H.values.map(&:keys).flatten.all? { |e| e.is_a? Fixnum }
|
230
238
|
|
231
239
|
# Scan table
|
232
|
-
|
233
|
-
assert_equal
|
234
|
-
assert_equal
|
235
|
-
assert_equal 1, table.range(
|
236
|
-
assert_equal 1, table.range(
|
240
|
+
range = (rk - 1)..(rk + 1)
|
241
|
+
assert_equal 1890, table.range(range).first[:year]
|
242
|
+
assert_equal 2, table.range(range).first.raw(:year).length
|
243
|
+
assert_equal 1, table.range(range).filter(:year => 1890).to_a.length
|
244
|
+
assert_equal 1, table.range(range).filter(:year => 1890).count
|
245
|
+
assert_equal 1, table.range(range).filter(:year => 1880...1900).count
|
237
246
|
cnt = 0
|
238
|
-
|
247
|
+
inc1 = inc2 = nil
|
248
|
+
table.range(range).
|
239
249
|
filter(:year => 1880...1900,
|
240
250
|
:in_print => true,
|
241
251
|
:category => ['Comics', 'Fiction', /cult/i],
|
@@ -253,27 +263,33 @@ class TestSchema < TestHBaseJRubyBase
|
|
253
263
|
table.put book.rowkey => { :price => book[:price] + BigDecimal('1') }
|
254
264
|
|
255
265
|
# Atomic increment
|
256
|
-
table.increment book.rowkey
|
266
|
+
inc1 = table.increment book.rowkey => { :reviews => 1, :stars => 2 }
|
267
|
+
inc2 = table.increment book.rowkey, :stars => 3
|
257
268
|
cnt += 1
|
258
269
|
end
|
259
270
|
assert_equal 1, cnt
|
260
271
|
|
261
|
-
assert_equal data[:price] + 1.0, table.get(
|
262
|
-
assert_equal data[:reviews] + 1, table.get(
|
263
|
-
assert_equal data[:stars] + 5, table.get(
|
272
|
+
assert_equal data[:price] + 1.0, table.get(rk)[:price]
|
273
|
+
assert_equal data[:reviews] + 1, table.get(rk)[:reviews]
|
274
|
+
assert_equal data[:stars] + 5, table.get(rk)[:stars]
|
275
|
+
|
276
|
+
assert_equal data[:reviews] + 1, inc1[book.rowkey][:reviews]
|
277
|
+
assert_equal data[:stars] + 2, inc1[book.rowkey][:stars]
|
278
|
+
assert_equal nil, inc2[:reviews]
|
279
|
+
assert_equal data[:stars] + 5, inc2[:stars]
|
264
280
|
|
265
281
|
# Coprocessor
|
266
282
|
table.enable_aggregation!
|
267
|
-
table.put
|
283
|
+
table.put next_rowkey, :reviews => 100, :stars => 500
|
268
284
|
assert_equal data[:reviews] + 1 + data[:stars] + 5 + 100 + 500,
|
269
285
|
table.project(:reviews, :stars).aggregate(:sum)
|
270
286
|
#table.disable_aggregation!
|
271
287
|
|
272
288
|
# Undefined columns
|
273
|
-
table.put
|
274
|
-
table.put
|
275
|
-
table.put
|
276
|
-
assert_equal 1000, table.get(
|
289
|
+
table.put rk, 'cf1:x' => 1000
|
290
|
+
table.put rk, [:cf1, :y] => 2000
|
291
|
+
table.put rk, [:cf1, 2013] => 3000
|
292
|
+
assert_equal 1000, table.get(rk).fixnum('cf1:x')
|
277
293
|
|
278
294
|
[
|
279
295
|
[:cf1, HBase::ByteArray['x']],
|
@@ -284,30 +300,68 @@ class TestSchema < TestHBaseJRubyBase
|
|
284
300
|
%w[cf1 x],
|
285
301
|
'cf1:x'
|
286
302
|
].each do |param|
|
287
|
-
assert_equal 1000, HBase::Util.from_bytes(:fixnum, table.get(
|
288
|
-
assert_equal 1000, HBase::Util.from_bytes(:fixnum, table.get(
|
289
|
-
assert_equal 1000, HBase::Util.from_bytes(:fixnum, table.get(
|
303
|
+
assert_equal 1000, HBase::Util.from_bytes(:fixnum, table.get(rk)[param])
|
304
|
+
assert_equal 1000, HBase::Util.from_bytes(:fixnum, table.get(rk)[*param])
|
305
|
+
assert_equal 1000, HBase::Util.from_bytes(:fixnum, table.get(rk).to_h[param])
|
290
306
|
end
|
291
307
|
|
292
|
-
assert_equal 2000, HBase::Util.from_bytes(:fixnum, table.get(
|
293
|
-
assert_equal 3000, HBase::Util.from_bytes(:fixnum, table.get(
|
294
|
-
assert_equal 3000, HBase::Util.from_bytes(:fixnum, table.get(
|
295
|
-
assert_equal 3000, HBase::Util.from_bytes(:fixnum, table.get(
|
296
|
-
assert_equal 3000, HBase::Util.from_bytes(:fixnum, table.get(
|
308
|
+
assert_equal 2000, HBase::Util.from_bytes(:fixnum, table.get(rk)[:cf1, :y])
|
309
|
+
assert_equal 3000, HBase::Util.from_bytes(:fixnum, table.get(rk)[:cf1, 2013])
|
310
|
+
assert_equal 3000, HBase::Util.from_bytes(:fixnum, table.get(rk)[[:cf1, 2013]])
|
311
|
+
assert_equal 3000, HBase::Util.from_bytes(:fixnum, table.get(rk).to_h[[:cf1, HBase::ByteArray[2013]]])
|
312
|
+
assert_equal 3000, HBase::Util.from_bytes(:fixnum, table.get(rk).to_h[[:cf1, 2013]])
|
313
|
+
|
314
|
+
# Append string to title column
|
315
|
+
ret = table.append rk, :title => '!!!'
|
316
|
+
assert_equal data[:title] + '!!!', ret[:title]
|
317
|
+
assert_equal data[:title] + '!!!', table.get(rk)[:title]
|
318
|
+
|
319
|
+
# Mutation
|
320
|
+
table.mutate(rk) do |m|
|
321
|
+
m.delete :comment1, :comment2
|
322
|
+
m.put :comment3 => 'nice', :comment4 => 'great'
|
323
|
+
assert_raise(ArgumentError) {
|
324
|
+
m.put :some_unknown_column => 'perfect'
|
325
|
+
}
|
326
|
+
end
|
327
|
+
assert_equal nil, table.get(rk)[:comment1]
|
328
|
+
assert_equal nil, table.get(rk)[:comment2]
|
329
|
+
assert_equal 'nice', table.get(rk)[:comment3]
|
330
|
+
assert_equal 'great', table.get(rk)[:comment4]
|
331
|
+
|
332
|
+
# Batch
|
333
|
+
ret = table.batch do |b|
|
334
|
+
b.put rk, :comment5 => 'gnarly'
|
335
|
+
b.delete rk, :comment4
|
336
|
+
b.increment rk, :stars => 100, :reviews => 200
|
337
|
+
b.mutate(rk) do |m|
|
338
|
+
m.put :comment6 => 'rad'
|
339
|
+
m.delete :image
|
340
|
+
end
|
341
|
+
b.append rk, :category => '/Etc'
|
342
|
+
b.get rk
|
343
|
+
end
|
344
|
+
assert_equal 6, ret.length
|
345
|
+
assert_equal [true] * 3, ret.values_at(0, 1, 3).map { |r| r[:result] }
|
346
|
+
assert_equal data[:stars] + 5 + 100, ret[2][:result][:stars]
|
347
|
+
assert_equal data[:reviews] + 1 + 200, ret[2][:result][:reviews]
|
348
|
+
assert_equal data[:category] + '/Etc', ret[4][:result][:category]
|
349
|
+
assert_instance_of HBase::Row, ret[5][:result]
|
350
|
+
assert_equal 1890, ret[5][:result][:year]
|
297
351
|
|
298
352
|
# Delete :title column of book 1
|
299
|
-
table.delete
|
300
|
-
assert_equal nil, table.get(
|
301
|
-
assert_equal data[:author], table.get(
|
353
|
+
table.delete rk, :title
|
354
|
+
assert_equal nil, table.get(rk)[:title]
|
355
|
+
assert_equal data[:author], table.get(rk)[:author]
|
302
356
|
|
303
357
|
# Delete column family
|
304
|
-
table.delete
|
305
|
-
assert_equal nil, table.get(
|
306
|
-
assert_equal data[:summary], table.get(
|
358
|
+
table.delete rk, :cf1
|
359
|
+
assert_equal nil, table.get(rk)[:author]
|
360
|
+
assert_equal data[:summary], table.get(rk)[:summary]
|
307
361
|
|
308
362
|
# Delete book 1
|
309
|
-
table.delete
|
310
|
-
assert_equal nil, table.get(
|
363
|
+
table.delete rk
|
364
|
+
assert_equal nil, table.get(rk)
|
311
365
|
|
312
366
|
# Drop table for subsequent tests
|
313
367
|
table.drop!
|
@@ -323,11 +377,12 @@ class TestSchema < TestHBaseJRubyBase
|
|
323
377
|
}
|
324
378
|
}
|
325
379
|
|
380
|
+
rk = next_rowkey
|
326
381
|
assert_raise(ArgumentError) {
|
327
|
-
@table.put
|
382
|
+
@table.put rk, :a => nil, :b => nil, :c => nil, 'cf1:z' => nil
|
328
383
|
}
|
329
|
-
@table.put
|
330
|
-
h = @table.get(
|
384
|
+
@table.put rk, :a => nil, :b => nil, :c => nil, :d => 'yo', 'cf1:z' => 1000
|
385
|
+
h = @table.get(rk).to_h
|
331
386
|
assert !h.has_key?(:a)
|
332
387
|
assert !h.has_key?(:b)
|
333
388
|
assert !h.has_key?(:c)
|
@@ -345,14 +400,15 @@ class TestSchema < TestHBaseJRubyBase
|
|
345
400
|
:cf1 => { :a => :fixnum }
|
346
401
|
}
|
347
402
|
|
348
|
-
|
349
|
-
|
350
|
-
assert_equal 100, @table.get(
|
403
|
+
rk = next_rowkey
|
404
|
+
@table.put rk, :a => 100
|
405
|
+
assert_equal 100, @table.get(rk)[:a]
|
406
|
+
assert_equal 100, @table.get(rk)['cf1:a']
|
351
407
|
|
352
408
|
@hbase.schema.delete @table.name
|
353
|
-
|
354
|
-
assert_equal true, HBase::Util.java_bytes?(@table.get(
|
355
|
-
assert_equal 100, HBase::Util.from_bytes(:fixnum, @table.get(
|
409
|
+
assert_raise(ArgumentError) { @table.get(rk)[:a] }
|
410
|
+
assert_equal true, HBase::Util.java_bytes?(@table.get(rk)['cf1:a'])
|
411
|
+
assert_equal 100, HBase::Util.from_bytes(:fixnum, @table.get(rk)['cf1:a'])
|
356
412
|
end
|
357
413
|
end
|
358
414
|
|