hbase-jruby 0.1.1-java → 0.1.2-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 +17 -0
- data/README.md +126 -33
- data/hbase-jruby.gemspec +1 -0
- data/lib/hbase-jruby/admin.rb +1 -0
- data/lib/hbase-jruby/cell.rb +3 -11
- data/lib/hbase-jruby/result.rb +27 -51
- data/lib/hbase-jruby/scoped/aggregation.rb +47 -0
- data/lib/hbase-jruby/scoped.rb +51 -23
- data/lib/hbase-jruby/table.rb +72 -66
- data/lib/hbase-jruby/util.rb +12 -5
- data/lib/hbase-jruby/version.rb +1 -1
- data/lib/hbase-jruby.rb +1 -0
- data/test/helper.rb +1 -3
- data/test/test_aggregation.rb +40 -0
- data/test/test_cell.rb +0 -1
- data/test/test_hbase.rb +1 -1
- data/test/test_scoped.rb +45 -1
- data/test/test_table.rb +46 -11
- data/test/test_table_admin.rb +22 -0
- data/test/test_util.rb +2 -3
- metadata +37 -27
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Changelog
|
2
|
+
=========
|
3
|
+
|
4
|
+
0.1.2
|
5
|
+
-----
|
6
|
+
|
7
|
+
- Dropped Bignum support. Automatic conversion from Fixnum to Bignum (or vice versa)
|
8
|
+
will produce columns whose values are of heterogeneous types, that are impossible to be read in a consistent way.
|
9
|
+
You can use BigDecimal type instead for large numbers.
|
10
|
+
- Added `HBase::Scoped#while` which allows early termination of scan
|
11
|
+
with [WhileMatchFilter](http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/WhileMatchFilter.html)
|
12
|
+
- Filtering with regular expressions
|
13
|
+
- Implemented comparator for `HBase::Result`
|
14
|
+
- Added coprocessor administration methods
|
15
|
+
- Basic aggregation with Coprocessor
|
16
|
+
- `HBase::Scoped#count` with block
|
17
|
+
- Allows PUT operation with timestamps
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@ Anyhow, JRuby is Ruby, not Java, right?
|
|
9
9
|
|
10
10
|
*hbase-jruby* provides the followings:
|
11
11
|
- Easy, Ruby-esque interface for the fundamental HBase operations
|
12
|
-
- ActiveRecord-like method chaining for
|
12
|
+
- ActiveRecord-like method chaining for data retrieval
|
13
13
|
- Automatic Hadoop/HBase dependency resolution
|
14
14
|
|
15
15
|
## A quick example
|
@@ -17,6 +17,8 @@ Anyhow, JRuby is Ruby, not Java, right?
|
|
17
17
|
```ruby
|
18
18
|
require 'hbase-jruby'
|
19
19
|
|
20
|
+
HBase.resolve_dependency! 'cdh4.1.2'
|
21
|
+
|
20
22
|
hbase = HBase.new
|
21
23
|
table = hbase.table(:test_table)
|
22
24
|
|
@@ -25,16 +27,17 @@ table.put :rowkey1 => { 'cf1:a' => 100, 'cf2:b' => "Hello" }
|
|
25
27
|
|
26
28
|
# GET
|
27
29
|
row = table.get(:rowkey1)
|
28
|
-
number = row.
|
30
|
+
number = row.fixnum('cf1:a')
|
29
31
|
string = row.string('cf1:b')
|
30
32
|
|
31
33
|
# SCAN
|
32
34
|
table.range('rowkey1'..'rowkey9').
|
33
35
|
filter('cf1:a' => 100..200, # cf1:a between 100 and 200
|
34
|
-
'
|
35
|
-
'cf2:c' =>
|
36
|
+
'cf1:b' => 'Hello', # cf1:b = 'Hello'
|
37
|
+
'cf2:c' => /world/i). # cf2:c matches /world/i
|
38
|
+
'cf2:d' => ['foo', /^BAR/i], # cf2:d = 'foo' OR matches /^BAR/i
|
36
39
|
project('cf1:a', 'cf2').each do |row|
|
37
|
-
puts row.
|
40
|
+
puts row.fixnum('cf1:a')
|
38
41
|
end
|
39
42
|
|
40
43
|
# DELETE
|
@@ -174,6 +177,14 @@ table.put 'rowkey1', 'cf1:col1' => "Hello", 'cf2:col2' => "World"
|
|
174
177
|
table.put 'rowkey1' => { 'cf1:col1' => "Hello", 'cf2:col2' => "World" },
|
175
178
|
'rowkey2' => { 'cf1:col1' => "Howdy", 'cf2:col2' => "World" },
|
176
179
|
'rowkey3' => { 'cf1:col1' => "So long", 'cf2:col2' => "World" }
|
180
|
+
|
181
|
+
# Putting values with timestamps
|
182
|
+
table.put 'rowkey1' => {
|
183
|
+
'cf1:col1' => {
|
184
|
+
1353143856665 => "Hello",
|
185
|
+
1352978648642 => "Goodbye" },
|
186
|
+
'cf2:col2' => "World"
|
187
|
+
}
|
177
188
|
```
|
178
189
|
|
179
190
|
### GET
|
@@ -191,12 +202,12 @@ rowk = row.rowkey
|
|
191
202
|
col0 = row.raw 'cf1:col0'
|
192
203
|
|
193
204
|
# Decode column values
|
194
|
-
col1 = row.string
|
195
|
-
col2 = row.fixnum
|
196
|
-
col3 = row.
|
197
|
-
col4 = row.float
|
198
|
-
col5 = row.boolean
|
199
|
-
col6 = row.symbol
|
205
|
+
col1 = row.string 'cf1:col1'
|
206
|
+
col2 = row.fixnum 'cf1:col2'
|
207
|
+
col3 = row.bigdecimal 'cf1:col3'
|
208
|
+
col4 = row.float 'cf1:col4'
|
209
|
+
col5 = row.boolean 'cf1:col5'
|
210
|
+
col6 = row.symbol 'cf1:col6'
|
200
211
|
|
201
212
|
# Decode multiple columns at once
|
202
213
|
row.string ['cf1:str1', 'cf1:str2']
|
@@ -225,13 +236,13 @@ row.strings ['cf1:str1', 'cf1:str2']
|
|
225
236
|
# ]
|
226
237
|
|
227
238
|
# Plural-form methods are provided for any other data types as well
|
228
|
-
cols0 = row.raws
|
229
|
-
cols1 = row.strings
|
230
|
-
cols2 = row.fixnums
|
231
|
-
cols3 = row.
|
232
|
-
cols4 = row.floats
|
233
|
-
cols5 = row.booleans
|
234
|
-
cols6 = row.symbols
|
239
|
+
cols0 = row.raws 'cf1:col0'
|
240
|
+
cols1 = row.strings 'cf1:col1'
|
241
|
+
cols2 = row.fixnums 'cf1:col2'
|
242
|
+
cols3 = row.bigdecimals 'cf1:col3'
|
243
|
+
cols4 = row.floats 'cf1:col4'
|
244
|
+
cols5 = row.booleans 'cf1:col5'
|
245
|
+
cols6 = row.symbols 'cf1:col6'
|
235
246
|
```
|
236
247
|
|
237
248
|
#### Intra-row scan
|
@@ -262,7 +273,7 @@ end
|
|
262
273
|
schema = {
|
263
274
|
'cf1:col1' => :string,
|
264
275
|
'cf1:col2' => :fixnum,
|
265
|
-
'cf1:col3' => :
|
276
|
+
'cf1:col3' => :bigdecimal,
|
266
277
|
'cf1:col4' => :float,
|
267
278
|
'cf1:col5' => :boolean,
|
268
279
|
'cf1:col6' => :symbol }
|
@@ -359,6 +370,7 @@ table.range('A'..'Z'). # Row key range,
|
|
359
370
|
filter('cf2:d' => 100..200). # Range filter on cf2:d
|
360
371
|
filter('cf2:e' => [10, 20..30]). # Set-inclusion condition on cf2:e
|
361
372
|
filter(RandomRowFilter.new(0.5)). # Any Java HBase filter
|
373
|
+
while('cf2:f' => { ne: 'OPEN' }). # Early termination of scan
|
362
374
|
limit(10). # Limits the size of the result set
|
363
375
|
versions(2). # Only fetches 2 versions for each value
|
364
376
|
batch(100). # Batch size for scan set to 100
|
@@ -366,7 +378,7 @@ table.range('A'..'Z'). # Row key range,
|
|
366
378
|
to_a # To Array
|
367
379
|
```
|
368
380
|
|
369
|
-
### range
|
381
|
+
### *range*
|
370
382
|
|
371
383
|
`HBase::Scoped#range` method is used to filter rows based on their row keys.
|
372
384
|
|
@@ -416,7 +428,7 @@ scope.range(1, 100).
|
|
416
428
|
# Same as `scope.range(1, 1000)`
|
417
429
|
```
|
418
430
|
|
419
|
-
### filter
|
431
|
+
### *filter*
|
420
432
|
|
421
433
|
You can configure server-side filtering of rows and columns with `HBase::Scoped#filter` calls.
|
422
434
|
Multiple calls have conjunctive effects.
|
@@ -424,22 +436,56 @@ Multiple calls have conjunctive effects.
|
|
424
436
|
```ruby
|
425
437
|
# Range scanning the table with filters
|
426
438
|
table.range(nil, 1000).
|
427
|
-
filter(
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
439
|
+
filter(
|
440
|
+
# Numbers and characters: Checks if the value is equal to the given value
|
441
|
+
'cf1:a' => 'Hello',
|
442
|
+
'cf1:b' => 1024,
|
443
|
+
|
444
|
+
# Range of numbers or characters: Checks if the value falls within the range
|
445
|
+
'cf1:c' => 100..200,
|
446
|
+
'cf1:d' => 'A'..'C',
|
447
|
+
|
448
|
+
# Regular expression: Checks if the value matches the regular expression
|
449
|
+
'cf1:e' => /world$/i,
|
450
|
+
|
451
|
+
# Hash: Tests the value with 6 types of operators (:gt, :lt, :gte, :lte, :eq, :ne)
|
452
|
+
'cf1:f' => { gt: 1000, lte: 2000 },
|
453
|
+
'cf1:g' => { ne: 1000 },
|
454
|
+
|
455
|
+
# Array of the aforementioned types: OR condition (disjunctive)
|
456
|
+
'cf1:h' => %w[A B C],
|
457
|
+
'cf1:i' => ['A'...'B', 'C', /^D/, { lt: 'F' }]).
|
458
|
+
|
459
|
+
# Multiple calls for conjunctive filtering
|
460
|
+
filter('cf1:j' => ['Alice'..'Bob', 'Cat']).
|
461
|
+
|
462
|
+
# Any number of Java filters can be applied
|
435
463
|
filter(org.apache.hadoop.hbase.filter.RandomRowFilter.new(0.5)).
|
436
|
-
|
437
|
-
each do |record|
|
464
|
+
each do |record|
|
438
465
|
# ...
|
439
466
|
end
|
440
467
|
```
|
441
468
|
|
442
|
-
###
|
469
|
+
### *while*
|
470
|
+
|
471
|
+
`HBase::Scoped#while` method takes the same parameters as `filter` method, the difference is that
|
472
|
+
each filtering condition passed to `while` method is wrapped by `WhileMatchFilter`,
|
473
|
+
which aborts scan immediately when the condition is not met at a certain row.
|
474
|
+
See the following example.
|
475
|
+
|
476
|
+
```ruby
|
477
|
+
(0...30).each do |idx|
|
478
|
+
table.put idx, 'cf1:a' => idx % 10
|
479
|
+
end
|
480
|
+
|
481
|
+
table.filter('cf1:a' => { lte: 1 }).to_a
|
482
|
+
# 0, 1, 10, 11, 20, 21
|
483
|
+
table.while('cf1:a' => { lte: 1 }).to_a
|
484
|
+
# 0, 1
|
485
|
+
# Scan terminates immediately when condition not met.
|
486
|
+
```
|
487
|
+
|
488
|
+
### *project*
|
443
489
|
|
444
490
|
`HBase::Scoped#project` allows you to fetch only a subset of columns from each row.
|
445
491
|
Multiple calls have additive effects.
|
@@ -521,6 +567,44 @@ end
|
|
521
567
|
scoped.count
|
522
568
|
```
|
523
569
|
|
570
|
+
## Basic aggregation using coprocessor
|
571
|
+
|
572
|
+
*hbase-jruby* provides a few basic aggregation methods using
|
573
|
+
the built-in coprocessor called
|
574
|
+
`org.apache.hadoop.hbase.coprocessor.AggregateImplementation`.
|
575
|
+
|
576
|
+
To enable this feature, call `enable_aggregation!` method,
|
577
|
+
which will first disable the table, add the coprocessor, then enable it.
|
578
|
+
|
579
|
+
```ruby
|
580
|
+
table.enable_aggregation!
|
581
|
+
# Just a shorthand notation for
|
582
|
+
# table.add_coprocessor! 'org.apache.hadoop.hbase.coprocessor.AggregateImplementation'
|
583
|
+
```
|
584
|
+
|
585
|
+
Then you can get the sum, average, minimum, maximum, row count, and standard deviation
|
586
|
+
of the projected columns.
|
587
|
+
|
588
|
+
```ruby
|
589
|
+
# cf1:a must hold 8-byte integer values
|
590
|
+
table.project('cf1:a').aggregate(:sum)
|
591
|
+
table.project('cf1:a').aggregate(:avg)
|
592
|
+
table.project('cf1:a').aggregate(:min)
|
593
|
+
table.project('cf1:a').aggregate(:max)
|
594
|
+
table.project('cf1:a').aggregate(:std)
|
595
|
+
table.project('cf1:a').aggregate(:row_count)
|
596
|
+
|
597
|
+
# Aggregation of multiple columns
|
598
|
+
table.project('cf1:a', 'cf1:b').aggregate(:sum)
|
599
|
+
```
|
600
|
+
|
601
|
+
By default, aggregate method assumes the column values are 8-byte integers.
|
602
|
+
For types other than that, you can pass your own ColumnInterpreter.
|
603
|
+
|
604
|
+
```ruby
|
605
|
+
table.project('cf1:b').aggregate(:sum, MyColumnInterpreter.new)
|
606
|
+
```
|
607
|
+
|
524
608
|
## Advanced topics
|
525
609
|
|
526
610
|
### Lexicographic scan order
|
@@ -556,7 +640,6 @@ table.get('rowkey').string(HBase::ColumnKey(:cf1, 100))
|
|
556
640
|
# ...
|
557
641
|
```
|
558
642
|
|
559
|
-
|
560
643
|
### Table administration
|
561
644
|
|
562
645
|
`HBase#Table` provides a few *synchronous* table administration methods.
|
@@ -588,6 +671,16 @@ table.alter_family! :cf2, :bloomfilter => :rowcol
|
|
588
671
|
|
589
672
|
# Remove column family
|
590
673
|
table.delete_family! :cf1
|
674
|
+
|
675
|
+
# Add Coprocessor
|
676
|
+
unless table.has_coprocessor?(cp_class_name1)
|
677
|
+
table.add_coprocessor! cp_class_name1
|
678
|
+
end
|
679
|
+
table.add_coprocessor! cp_class_name2,
|
680
|
+
:path => path, :priority => priority, :params => params
|
681
|
+
|
682
|
+
# Remove coprocessor
|
683
|
+
table.remove_coprocessor! cp_class_name1
|
591
684
|
```
|
592
685
|
|
593
686
|
You can perform other types of administrative tasks
|
data/hbase-jruby.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.summary = %q{Ruby-esque interface for accessing HBase from JRuby}
|
13
13
|
gem.homepage = "https://github.com/junegunn/hbase-jruby"
|
14
14
|
gem.platform = 'java'
|
15
|
+
gem.license = 'MIT'
|
15
16
|
|
16
17
|
gem.files = `git ls-files`.split($/)
|
17
18
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
data/lib/hbase-jruby/admin.rb
CHANGED
data/lib/hbase-jruby/cell.rb
CHANGED
@@ -14,7 +14,7 @@ class Cell
|
|
14
14
|
|
15
15
|
# Returns the rowkey of the cell decoded as the given type
|
16
16
|
# @param [Symbol] type The type of the rowkey.
|
17
|
-
# Can be one of :string, :symbol, :fixnum, :float, :
|
17
|
+
# Can be one of :string, :symbol, :fixnum, :float, :bigdecimal, :boolean and :raw.
|
18
18
|
# @return [String, byte[]]
|
19
19
|
def rowkey type = :string
|
20
20
|
Util.from_bytes type, @java.getRow
|
@@ -35,7 +35,7 @@ class Cell
|
|
35
35
|
|
36
36
|
# Returns the column qualifier of the cell
|
37
37
|
# @param [Symbol] type The type of the qualifier.
|
38
|
-
# Can be one of :string, :symbol, :fixnum, :float, :
|
38
|
+
# Can be one of :string, :symbol, :fixnum, :float, :bigdecimal, :boolean and :raw.
|
39
39
|
# @return [Object]
|
40
40
|
def qualifier type = :string
|
41
41
|
Util.from_bytes type, @java.getQualifier
|
@@ -49,7 +49,7 @@ class Cell
|
|
49
49
|
end
|
50
50
|
alias ts timestamp
|
51
51
|
|
52
|
-
# Returns the value of the cell as a Java byte array
|
52
|
+
# Returns the value of the cell as a Java byte array
|
53
53
|
# @return [byte[]]
|
54
54
|
def value
|
55
55
|
@java.getValue
|
@@ -78,14 +78,6 @@ class Cell
|
|
78
78
|
alias integer fixnum
|
79
79
|
alias int fixnum
|
80
80
|
|
81
|
-
# Returns the column value as a Bignum
|
82
|
-
# @return [Bignum]
|
83
|
-
def bignum
|
84
|
-
Util.from_bytes :bignum, value
|
85
|
-
end
|
86
|
-
alias biginteger bignum
|
87
|
-
alias bigint bignum
|
88
|
-
|
89
81
|
# Returns the column value as a BigDecimal
|
90
82
|
# @return [BigDecimal]
|
91
83
|
def bigdecimal
|
data/lib/hbase-jruby/result.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'bigdecimal'
|
2
2
|
|
3
|
-
# Represents a row returned by HBase
|
4
3
|
class HBase
|
4
|
+
# Represents a row returned by HBase
|
5
5
|
# @author Junegunn Choi <junegunn.c@gmail.com>
|
6
6
|
class Result
|
7
7
|
include Enumerable
|
8
|
-
|
8
|
+
|
9
9
|
# Returns the rowkey of the row
|
10
10
|
# @param [Symbol] type The type of the rowkey
|
11
|
-
# Can be one of :string, :symbol, :fixnum, :float, :
|
11
|
+
# Can be one of :string, :symbol, :fixnum, :float, :bigdecimal, :boolean and :raw.
|
12
12
|
# @return [String, byte[]]
|
13
13
|
def rowkey type = :string
|
14
14
|
Util.from_bytes type, @result.getRow
|
@@ -55,7 +55,7 @@ class Result
|
|
55
55
|
name = ColumnKey.new(cf, cq)
|
56
56
|
type = schema[name]
|
57
57
|
|
58
|
-
ret[name] =
|
58
|
+
ret[name] =
|
59
59
|
Hash[
|
60
60
|
tsmap.map { |ts, val|
|
61
61
|
[ ts, type ? Util.from_bytes(type, val) : val ]
|
@@ -71,7 +71,7 @@ class Result
|
|
71
71
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
72
72
|
# @return [byte[]] Byte array representation of the latest value
|
73
73
|
# @overload raw(columns)
|
74
|
-
# For each column specified,
|
74
|
+
# For each column specified,
|
75
75
|
# returns the latest column value as a byte array
|
76
76
|
# @param [<String|HBase::ColumnKey>] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
77
77
|
# @return [Array<byte[]>] Byte array representations of the latest values
|
@@ -91,7 +91,7 @@ class Result
|
|
91
91
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
92
92
|
# @return [Hash<Fixnum, byte[]>]
|
93
93
|
# @overload raws(columns)
|
94
|
-
# For each column specified,
|
94
|
+
# For each column specified,
|
95
95
|
# returns all versions of column values as byte arrays in a Hash indexed by their timestamps
|
96
96
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
97
97
|
# @return [Array<Hash<Fixnum, byte[]>>]
|
@@ -111,7 +111,7 @@ class Result
|
|
111
111
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
112
112
|
# @return [String]
|
113
113
|
# @overload string(columns)
|
114
|
-
# For each column specified,
|
114
|
+
# For each column specified,
|
115
115
|
# returns the latest column value as a String
|
116
116
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
117
117
|
# @return [Array<String>]
|
@@ -125,7 +125,7 @@ class Result
|
|
125
125
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
126
126
|
# @return [Hash<Fixnum, String>]
|
127
127
|
# @overload strings(columns)
|
128
|
-
# For each column specified,
|
128
|
+
# For each column specified,
|
129
129
|
# returns all versions of column values as Strings in a Hash indexed by their timestamps
|
130
130
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
131
131
|
# @return [Array<Hash<Fixnum, String>>]
|
@@ -139,7 +139,7 @@ class Result
|
|
139
139
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
140
140
|
# @return [Symbol]
|
141
141
|
# @overload symbol(columns)
|
142
|
-
# For each column specified,
|
142
|
+
# For each column specified,
|
143
143
|
# returns the latest column values as a Symbol
|
144
144
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
145
145
|
# @return [Array<Symbol>]
|
@@ -153,7 +153,7 @@ class Result
|
|
153
153
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
154
154
|
# @return [Hash<Fixnum, Symbol>]
|
155
155
|
# @overload symbols(columns)
|
156
|
-
# For each column specified,
|
156
|
+
# For each column specified,
|
157
157
|
# returns all versions of column values as Symbols in a Hash indexed by their timestamps
|
158
158
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
159
159
|
# @return [Array<Hash<Fixnum, Symbol>>]
|
@@ -167,7 +167,7 @@ class Result
|
|
167
167
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
168
168
|
# @return [Fixnum]
|
169
169
|
# @overload fixnum(columns)
|
170
|
-
# For each column specified,
|
170
|
+
# For each column specified,
|
171
171
|
# returns the latest column values as a Fixnum
|
172
172
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
173
173
|
# @return [Array<Fixnum>]
|
@@ -182,7 +182,7 @@ class Result
|
|
182
182
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
183
183
|
# @return [Hash<Fixnum, Fixnum>]
|
184
184
|
# @overload fixnums(columns)
|
185
|
-
# For each column specified,
|
185
|
+
# For each column specified,
|
186
186
|
# returns all versions of column values as Fixnums in a Hash indexed by their timestamps
|
187
187
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
188
188
|
# @return [Array<Hash<Fixnum, Fixnum>>]
|
@@ -192,42 +192,12 @@ class Result
|
|
192
192
|
alias integers fixnums
|
193
193
|
alias ints fixnums
|
194
194
|
|
195
|
-
# @overload bignum(column)
|
196
|
-
# Returns the latest column value as a Bignum
|
197
|
-
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
198
|
-
# @return [Bignum]
|
199
|
-
# @overload bignum(columns)
|
200
|
-
# For each column specified,
|
201
|
-
# returns the latest column values as a Bignum
|
202
|
-
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
203
|
-
# @return [Array<Bignum>]
|
204
|
-
def bignum cols
|
205
|
-
decode_values :bignum, cols
|
206
|
-
end
|
207
|
-
alias biginteger bignum
|
208
|
-
alias bigint bignum
|
209
|
-
|
210
|
-
# @overload bignums(column)
|
211
|
-
# Returns all versions of column values as Bignums in a Hash indexed by their timestamps
|
212
|
-
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
213
|
-
# @return [Hash<Fixnum, Bignum>]
|
214
|
-
# @overload bignums(columns)
|
215
|
-
# For each column specified,
|
216
|
-
# returns all versions of column values as Bignums in a Hash indexed by their timestamps
|
217
|
-
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
218
|
-
# @return [Array<Hash<Fixnum, Bignum>>]
|
219
|
-
def bignums cols
|
220
|
-
decode_values :bignum, cols, true
|
221
|
-
end
|
222
|
-
alias bigintegers bignums
|
223
|
-
alias bigints bignums
|
224
|
-
|
225
195
|
# @overload bigdecimal(column)
|
226
196
|
# Returns the latest column value as a BigDecimal
|
227
197
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
228
198
|
# @return [BigDecimal]
|
229
199
|
# @overload bigdecimal(columns)
|
230
|
-
# For each column specified,
|
200
|
+
# For each column specified,
|
231
201
|
# returns the latest column values as a BigDecimal
|
232
202
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
233
203
|
# @return [Array<BigDecimal>]
|
@@ -240,7 +210,7 @@ class Result
|
|
240
210
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
241
211
|
# @return [Hash<Fixnum, BigDecimal>]
|
242
212
|
# @overload bigdecimals(columns)
|
243
|
-
# For each column specified,
|
213
|
+
# For each column specified,
|
244
214
|
# returns all versions of column values as BigDecimals in a Hash indexed by their timestamps
|
245
215
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
246
216
|
# @return [Array<Hash<Fixnum, BigDecimal>>]
|
@@ -253,7 +223,7 @@ class Result
|
|
253
223
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
254
224
|
# @return [Float]
|
255
225
|
# @overload float(columns)
|
256
|
-
# For each column specified,
|
226
|
+
# For each column specified,
|
257
227
|
# returns the latest column values as a Float
|
258
228
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
259
229
|
# @return [Array<Float>]
|
@@ -267,7 +237,7 @@ class Result
|
|
267
237
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
268
238
|
# @return [Hash<Fixnum, Float>]
|
269
239
|
# @overload floats(columns)
|
270
|
-
# For each column specified,
|
240
|
+
# For each column specified,
|
271
241
|
# returns all versions of column values as Floats in a Hash indexed by their timestamps
|
272
242
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
273
243
|
# @return [Array<Hash<Fixnum, Float>>]
|
@@ -281,7 +251,7 @@ class Result
|
|
281
251
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
282
252
|
# @return [true, false]
|
283
253
|
# @overload boolean(columns)
|
284
|
-
# For each column specified,
|
254
|
+
# For each column specified,
|
285
255
|
# returns the latest column values as a boolean value
|
286
256
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
287
257
|
# @return [Array<true|false>]
|
@@ -295,7 +265,7 @@ class Result
|
|
295
265
|
# @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
|
296
266
|
# @return [Hash<Fixnum, true|false>]
|
297
267
|
# @overload booleans(columns)
|
298
|
-
# For each column specified,
|
268
|
+
# For each column specified,
|
299
269
|
# returns all versions of column values as boolean values in a Hash indexed by their timestamps
|
300
270
|
# @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
|
301
271
|
# @return [Array<Hash<Fixnum, true|false>>]
|
@@ -304,6 +274,10 @@ class Result
|
|
304
274
|
end
|
305
275
|
alias bools booleans
|
306
276
|
|
277
|
+
def <=> other
|
278
|
+
Bytes.compareTo(rowkey(:raw), other.rowkey(:raw))
|
279
|
+
end
|
280
|
+
|
307
281
|
private
|
308
282
|
HASH_TEMPLATE = {}.tap { |h|
|
309
283
|
h.instance_eval do
|
@@ -326,7 +300,9 @@ private
|
|
326
300
|
cols.map { |col|
|
327
301
|
cf, cq = Util.parse_column_name(col)
|
328
302
|
if with_versions
|
329
|
-
|
303
|
+
# Need to make it a Ruby hash:
|
304
|
+
# Prevents implicit conversion from ruby type to java type when updating the Hash
|
305
|
+
Hash[ allmap.fetch(cf, {}).fetch(cq, {}) ]
|
330
306
|
else
|
331
307
|
@result.getValue cf, cq
|
332
308
|
end
|
@@ -365,7 +341,7 @@ private
|
|
365
341
|
def parse_schema schema
|
366
342
|
{}.tap { |ret|
|
367
343
|
schema.each do |name, type|
|
368
|
-
ck =
|
344
|
+
ck =
|
369
345
|
case name
|
370
346
|
when ColumnKey
|
371
347
|
name
|
@@ -378,5 +354,5 @@ private
|
|
378
354
|
}
|
379
355
|
end
|
380
356
|
end#Result
|
381
|
-
end#HBase
|
357
|
+
end#HBase
|
382
358
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class HBase
|
2
|
+
class Scoped
|
3
|
+
# Basic data aggregation with coprocessor based on AggregateImplementation
|
4
|
+
# @author Junegunn Choi <junegunn.c@gmail.com>
|
5
|
+
module Aggregation
|
6
|
+
module Admin
|
7
|
+
# Enables aggregation support for the table
|
8
|
+
# @return [nil]
|
9
|
+
def enable_aggregation!
|
10
|
+
add_coprocessor! 'org.apache.hadoop.hbase.coprocessor.AggregateImplementation'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Performs aggregation with coprocessor
|
15
|
+
# @param [Symbol] op Aggregation type: :sum, :min, :max, :avg, :std, :row_count
|
16
|
+
# @param [Symbol, org.apache.hadoop.hbase.coprocessor.ColumnInterpreter] type
|
17
|
+
# Column type (only :fixnum is supported as of now) or ColumnInterpreter object used to decode the value
|
18
|
+
def aggregate op, type = :fixnum
|
19
|
+
aggregation_impl op, type
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def aggregation_impl method, type
|
24
|
+
raise ArgumentError.new("No column specified") if method != :row_count && @project.empty?
|
25
|
+
|
26
|
+
@aggregation_client ||= AggregationClient.new(table.config)
|
27
|
+
@aggregation_client.send(
|
28
|
+
method,
|
29
|
+
Util.to_bytes(table.name),
|
30
|
+
column_interpreter_for(type),
|
31
|
+
filtered_scan)
|
32
|
+
end
|
33
|
+
|
34
|
+
def column_interpreter_for type
|
35
|
+
case type
|
36
|
+
when :fixnum, :int, :integer
|
37
|
+
LongColumnInterpreter.new
|
38
|
+
when org.apache.hadoop.hbase.coprocessor.ColumnInterpreter
|
39
|
+
type
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Column interpreter for #{type} not implemented."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end#Aggregation
|
45
|
+
end#Scoped
|
46
|
+
end#HBase
|
47
|
+
|