HBASE-9689-Support using OperationAttributes through shell script (Ram)
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1533174 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f267e36d57
commit
968f83b2ff
|
@ -57,6 +57,7 @@ module HBaseConstants
|
||||||
SPLITALGO = 'SPLITALGO'
|
SPLITALGO = 'SPLITALGO'
|
||||||
NUMREGIONS = 'NUMREGIONS'
|
NUMREGIONS = 'NUMREGIONS'
|
||||||
CONFIGURATION = org.apache.hadoop.hbase.HConstants::CONFIGURATION
|
CONFIGURATION = org.apache.hadoop.hbase.HConstants::CONFIGURATION
|
||||||
|
ATTRIBUTES="ATTRIBUTES"
|
||||||
|
|
||||||
# Load constants from hbase java API
|
# Load constants from hbase java API
|
||||||
def self.promote_constants(constants)
|
def self.promote_constants(constants)
|
||||||
|
|
|
@ -127,9 +127,20 @@ EOF
|
||||||
# they will be much less likely to tab complete to the 'dangerous' internal method
|
# they will be much less likely to tab complete to the 'dangerous' internal method
|
||||||
#----------------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------------
|
||||||
# Put a cell 'value' at specified table/row/column
|
# Put a cell 'value' at specified table/row/column
|
||||||
def _put_internal(row, column, value, timestamp = nil)
|
def _put_internal(row, column, value, timestamp = nil, args = {})
|
||||||
p = org.apache.hadoop.hbase.client.Put.new(row.to_s.to_java_bytes)
|
p = org.apache.hadoop.hbase.client.Put.new(row.to_s.to_java_bytes)
|
||||||
family, qualifier = parse_column_name(column)
|
family, qualifier = parse_column_name(column)
|
||||||
|
if args.any?
|
||||||
|
attributes = args[ATTRIBUTES]
|
||||||
|
set_attributes(p, attributes) if attributes
|
||||||
|
end
|
||||||
|
#Case where attributes are specified without timestamp
|
||||||
|
if timestamp.kind_of?(Hash)
|
||||||
|
timestamp.each do |k, v|
|
||||||
|
set_attributes(p, v) if v
|
||||||
|
end
|
||||||
|
timestamp = nil
|
||||||
|
end
|
||||||
if timestamp
|
if timestamp
|
||||||
p.add(family, qualifier, timestamp, value.to_s.to_java_bytes)
|
p.add(family, qualifier, timestamp, value.to_s.to_java_bytes)
|
||||||
else
|
else
|
||||||
|
@ -219,7 +230,7 @@ EOF
|
||||||
# Get maxlength parameter if passed
|
# Get maxlength parameter if passed
|
||||||
maxlength = args.delete(MAXLENGTH) if args[MAXLENGTH]
|
maxlength = args.delete(MAXLENGTH) if args[MAXLENGTH]
|
||||||
filter = args.delete(FILTER) if args[FILTER]
|
filter = args.delete(FILTER) if args[FILTER]
|
||||||
|
attributes = args[ATTRIBUTES]
|
||||||
unless args.empty?
|
unless args.empty?
|
||||||
columns = args[COLUMN] || args[COLUMNS]
|
columns = args[COLUMN] || args[COLUMNS]
|
||||||
if args[VERSIONS]
|
if args[VERSIONS]
|
||||||
|
@ -251,9 +262,13 @@ EOF
|
||||||
get.setTimeStamp(args[TIMESTAMP]) if args[TIMESTAMP]
|
get.setTimeStamp(args[TIMESTAMP]) if args[TIMESTAMP]
|
||||||
get.setTimeRange(args[TIMERANGE][0], args[TIMERANGE][1]) if args[TIMERANGE]
|
get.setTimeRange(args[TIMERANGE][0], args[TIMERANGE][1]) if args[TIMERANGE]
|
||||||
else
|
else
|
||||||
# May have passed TIMESTAMP and row only; wants all columns from ts.
|
if attributes
|
||||||
unless ts = args[TIMESTAMP] || tr = args[TIMERANGE]
|
set_attributes(get, attributes) if attributes
|
||||||
raise ArgumentError, "Failed parse of #{args.inspect}, #{args.class}"
|
else
|
||||||
|
# May have passed TIMESTAMP and row only; wants all columns from ts.
|
||||||
|
unless ts = args[TIMESTAMP] || tr = args[TIMERANGE]
|
||||||
|
raise ArgumentError, "Failed parse of #{args.inspect}, #{args.class}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
get.setMaxVersions(vers)
|
get.setMaxVersions(vers)
|
||||||
|
@ -261,6 +276,7 @@ EOF
|
||||||
get.setTimeStamp(ts.to_i) if args[TIMESTAMP]
|
get.setTimeStamp(ts.to_i) if args[TIMESTAMP]
|
||||||
get.setTimeRange(args[TIMERANGE][0], args[TIMERANGE][1]) if args[TIMERANGE]
|
get.setTimeRange(args[TIMERANGE][0], args[TIMERANGE][1]) if args[TIMERANGE]
|
||||||
end
|
end
|
||||||
|
set_attributes(get, attributes) if attributes
|
||||||
end
|
end
|
||||||
|
|
||||||
unless filter.class == String
|
unless filter.class == String
|
||||||
|
@ -333,6 +349,7 @@ EOF
|
||||||
versions = args["VERSIONS"] || 1
|
versions = args["VERSIONS"] || 1
|
||||||
timerange = args[TIMERANGE]
|
timerange = args[TIMERANGE]
|
||||||
raw = args["RAW"] || false
|
raw = args["RAW"] || false
|
||||||
|
attributes = args[ATTRIBUTES]
|
||||||
|
|
||||||
# Normalize column names
|
# Normalize column names
|
||||||
columns = [columns] if columns.class == String
|
columns = [columns] if columns.class == String
|
||||||
|
@ -367,6 +384,7 @@ EOF
|
||||||
scan.setMaxVersions(versions) if versions > 1
|
scan.setMaxVersions(versions) if versions > 1
|
||||||
scan.setTimeRange(timerange[0], timerange[1]) if timerange
|
scan.setTimeRange(timerange[0], timerange[1]) if timerange
|
||||||
scan.setRaw(raw)
|
scan.setRaw(raw)
|
||||||
|
set_attributes(scan, attributes) if attributes
|
||||||
else
|
else
|
||||||
scan = org.apache.hadoop.hbase.client.Scan.new
|
scan = org.apache.hadoop.hbase.client.Scan.new
|
||||||
end
|
end
|
||||||
|
@ -408,6 +426,15 @@ EOF
|
||||||
return ((block_given?) ? count : res)
|
return ((block_given?) ? count : res)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Apply OperationAttributes to puts/scans/gets
|
||||||
|
def set_attributes(oprattr, attributes)
|
||||||
|
raise(ArgumentError, "#{"ATTRIBUTES"} must be a Hash type") unless attributes.kind_of?(Hash)
|
||||||
|
for k,v in attributes
|
||||||
|
v = v.to_s unless v.nil?
|
||||||
|
oprattr.setAttribute(k.to_s, v.to_java_bytes)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
#----------------------------
|
#----------------------------
|
||||||
# Add general administration utilities to the shell
|
# Add general administration utilities to the shell
|
||||||
# each of the names below adds this method name to the table
|
# each of the names below adds this method name to the table
|
||||||
|
|
|
@ -36,6 +36,7 @@ a dictionary of column(s), timestamp, timerange and versions. Examples:
|
||||||
hbase> get 't1', 'r1', 'c1'
|
hbase> get 't1', 'r1', 'c1'
|
||||||
hbase> get 't1', 'r1', 'c1', 'c2'
|
hbase> get 't1', 'r1', 'c1', 'c2'
|
||||||
hbase> get 't1', 'r1', ['c1', 'c2']
|
hbase> get 't1', 'r1', ['c1', 'c2']
|
||||||
|
hbsase> get 't1','r1', {COLUMN => 'c1', ATTRIBUTES => {'mykey'=>'myvalue'}}
|
||||||
|
|
||||||
Besides the default 'toStringBinary' format, 'get' also supports custom formatting by
|
Besides the default 'toStringBinary' format, 'get' also supports custom formatting by
|
||||||
column. A user can define a FORMATTER by adding it to the column name in the get
|
column. A user can define a FORMATTER by adding it to the column name in the get
|
||||||
|
|
|
@ -26,22 +26,25 @@ Put a cell 'value' at specified table/row/column and optionally
|
||||||
timestamp coordinates. To put a cell value into table 't1' at
|
timestamp coordinates. To put a cell value into table 't1' at
|
||||||
row 'r1' under column 'c1' marked with the time 'ts1', do:
|
row 'r1' under column 'c1' marked with the time 'ts1', do:
|
||||||
|
|
||||||
|
hbase> put 't1', 'r1', 'c1', 'value'
|
||||||
hbase> put 't1', 'r1', 'c1', 'value', ts1
|
hbase> put 't1', 'r1', 'c1', 'value', ts1
|
||||||
|
hbase> put 't1', 'r1', 'c1', 'value', {ATTRIBUTES=>{'mykey'=>'myvalue'}
|
||||||
|
hbase> put 't1', 'r1', 'c1', 'value', ts1, {ATTRIBUTES=>{'mykey'=>'myvalue'}
|
||||||
|
|
||||||
The same commands also can be run on a table reference. Suppose you had a reference
|
The same commands also can be run on a table reference. Suppose you had a reference
|
||||||
t to table 't1', the corresponding command would be:
|
t to table 't1', the corresponding command would be:
|
||||||
|
|
||||||
hbase> t.put 'r1', 'c1', 'value', ts1
|
hbase> t.put 'r1', 'c1', 'value', ts1, {ATTRIBUTES=>{'mykey'=>'myvalue'}
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
|
|
||||||
def command(table, row, column, value, timestamp = nil)
|
def command(table, row, column, value, timestamp=nil, args = {})
|
||||||
put table(table), row, column, value, timestamp
|
put table(table), row, column, value, timestamp, args
|
||||||
end
|
end
|
||||||
|
|
||||||
def put(table, row, column, value, timestamp = nil)
|
def put(table, row, column, value, timestamp = nil, args = {})
|
||||||
format_simple_command do
|
format_simple_command do
|
||||||
table._put_internal(row, column, value, timestamp)
|
table._put_internal(row, column, value, timestamp, args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,7 +46,8 @@ Some examples:
|
||||||
(QualifierFilter (>=, 'binary:xyz'))) AND (TimestampsFilter ( 123, 456))"}
|
(QualifierFilter (>=, 'binary:xyz'))) AND (TimestampsFilter ( 123, 456))"}
|
||||||
hbase> scan 't1', {FILTER =>
|
hbase> scan 't1', {FILTER =>
|
||||||
org.apache.hadoop.hbase.filter.ColumnPaginationFilter.new(1, 0)}
|
org.apache.hadoop.hbase.filter.ColumnPaginationFilter.new(1, 0)}
|
||||||
|
For setting the Operation Attributes
|
||||||
|
hbase> scan 't1', { COLUMNS => ['c1', 'c2'], ATTRIBUTES => {'mykey' => 'myvalue'}}
|
||||||
For experts, there is an additional option -- CACHE_BLOCKS -- which
|
For experts, there is an additional option -- CACHE_BLOCKS -- which
|
||||||
switches block caching for the scanner on (true) or off (false). By
|
switches block caching for the scanner on (true) or off (false). By
|
||||||
default it is enabled. Examples:
|
default it is enabled. Examples:
|
||||||
|
|
|
@ -106,7 +106,7 @@ module Hbase
|
||||||
@test_table.put("101", "x:a", "1")
|
@test_table.put("101", "x:a", "1")
|
||||||
@test_table.put("101", "x:a", "2", Time.now.to_i)
|
@test_table.put("101", "x:a", "2", Time.now.to_i)
|
||||||
|
|
||||||
@test_table.put("102", "x:a", "1",1212)
|
@test_table.put("102", "x:a", "1", 1212)
|
||||||
@test_table.put("102", "x:a", "2", 1213)
|
@test_table.put("102", "x:a", "2", 1213)
|
||||||
|
|
||||||
@test_table.put(103, "x:a", "3")
|
@test_table.put(103, "x:a", "3")
|
||||||
|
@ -134,7 +134,10 @@ module Hbase
|
||||||
define_test "put should work with integer values" do
|
define_test "put should work with integer values" do
|
||||||
@test_table.put("123", "x:a", 4)
|
@test_table.put("123", "x:a", 4)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
define_test "put should work with attributes" do
|
||||||
|
@test_table.put("123", "x:a", 4, {ATTRIBUTES=>{'mykey'=>'myvalue'}})
|
||||||
|
end
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
define_test "delete should work without timestamp" do
|
define_test "delete should work without timestamp" do
|
||||||
|
@ -213,6 +216,10 @@ module Hbase
|
||||||
|
|
||||||
@test_table.put(2, "x:a", 11)
|
@test_table.put(2, "x:a", 11)
|
||||||
@test_table.put(2, "x:b", 12, @test_ts)
|
@test_table.put(2, "x:b", 12, @test_ts)
|
||||||
|
|
||||||
|
@test_table.put(3, "x:a", 21, {ATTRIBUTES=>{'mykey'=>'myvalue'}})
|
||||||
|
@test_table.put(3, "x:b", 22, @test_ts, {ATTRIBUTES=>{'mykey'=>'myvalue'}})
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
define_test "count should work w/o a block passed" do
|
define_test "count should work w/o a block passed" do
|
||||||
|
@ -237,6 +244,14 @@ module Hbase
|
||||||
assert_not_nil(res['x:a'])
|
assert_not_nil(res['x:a'])
|
||||||
assert_not_nil(res['x:b'])
|
assert_not_nil(res['x:b'])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
define_test "get should work for data written with Attributes" do
|
||||||
|
res = @test_table._get_internal('3')
|
||||||
|
assert_not_nil(res)
|
||||||
|
assert_kind_of(Hash, res)
|
||||||
|
assert_not_nil(res['x:a'])
|
||||||
|
assert_not_nil(res['x:b'])
|
||||||
|
end
|
||||||
|
|
||||||
define_test "get should work with integer keys" do
|
define_test "get should work with integer keys" do
|
||||||
res = @test_table._get_internal(1)
|
res = @test_table._get_internal(1)
|
||||||
|
@ -441,7 +456,7 @@ module Hbase
|
||||||
assert_not_nil(res['2']['x:a'])
|
assert_not_nil(res['2']['x:a'])
|
||||||
assert_not_nil(res['2']['x:b'])
|
assert_not_nil(res['2']['x:b'])
|
||||||
end
|
end
|
||||||
|
|
||||||
define_test "scan should support COLUMNS parameter with a single column name" do
|
define_test "scan should support COLUMNS parameter with a single column name" do
|
||||||
res = @test_table._scan_internal COLUMNS => 'x:a'
|
res = @test_table._scan_internal COLUMNS => 'x:a'
|
||||||
assert_not_nil(res)
|
assert_not_nil(res)
|
||||||
|
|
Loading…
Reference in New Issue