in hbase-shell/src/main/ruby/hbase/admin.rb [771:940]
def alter(table_name_str, wait = true, *args)
raise(ArgumentError, 'Table name must be of type String') unless
table_name_str.is_a?(String)
raise(ArgumentError, "Can't find a table: #{table_name_str}") unless exists?(table_name_str)
raise(ArgumentError, 'There should be at least one argument but the table name') if args.empty?
table_name = TableName.valueOf(table_name_str)
tdb = TableDescriptorBuilder.newBuilder(@admin.getDescriptor(table_name))
hasTableUpdate = false
reopen_regions = true
args.each do |arg|
arg = { NAME => arg } if arg.is_a?(String)
arg = { METHOD => 'delete', NAME => arg['delete'] } if arg['delete']
if arg.key?(REOPEN_REGIONS)
if !['true', 'false'].include?(arg[REOPEN_REGIONS].downcase)
raise(ArgumentError, "Invalid 'REOPEN_REGIONS' for non-boolean value.")
end
reopen_regions = JBoolean.valueOf(arg[REOPEN_REGIONS])
arg.delete(REOPEN_REGIONS)
end
method = arg.delete(METHOD)
if method.nil? && arg.key?(NAME)
descriptor = cfd(arg, tdb)
column_name = descriptor.getNameAsString
if tdb.build.hasColumnFamily(column_name.to_java_bytes)
tdb.modifyColumnFamily(descriptor)
else
tdb.setColumnFamily(descriptor)
end
hasTableUpdate = true
next
end
name = arg.delete(NAME)
if !method.nil? && method != 'table_att'
if method == 'delete'
raise(ArgumentError, 'NAME parameter missing for delete method') unless name
tdb.removeColumnFamily(name.to_java_bytes)
hasTableUpdate = true
elsif method == 'table_att_unset'
raise(ArgumentError, 'NAME parameter missing for table_att_unset method') unless name
if name.is_a?(Array)
name.each do |key|
if tdb.build.getValue(key).nil?
raise ArgumentError, "Could not find attribute: #{key}"
end
tdb.removeValue(key)
end
else
if tdb.build.getValue(name).nil?
raise ArgumentError, "Could not find attribute: #{name}"
end
tdb.removeValue(name)
end
hasTableUpdate = true
elsif method == 'table_remove_coprocessor'
classname = arg.delete(CLASSNAME)
raise(ArgumentError, 'CLASSNAME parameter missing for table_remove_coprocessor method') unless classname
if classname.is_a?(Array)
classname.each do |key|
tdb.removeCoprocessor(key)
end
else
tdb.removeCoprocessor(classname)
end
hasTableUpdate = true
elsif method == 'table_conf_unset'
raise(ArgumentError, 'NAME parameter missing for table_conf_unset method') unless name
if name.is_a?(Array)
name.each do |key|
if tdb.build.getValue(key).nil?
raise ArgumentError, "Could not find configuration: #{key}"
end
tdb.removeValue(key)
end
else
if tdb.build.getValue(name).nil?
raise ArgumentError, "Could not find configuration: #{name}"
end
tdb.removeValue(name)
end
hasTableUpdate = true
else
raise ArgumentError, "Unknown method: #{method}"
end
arg.each_key do |unknown_key|
puts(format('Unknown argument ignored: %s', unknown_key))
end
next
end
update_tdb_from_arg(tdb, arg)
valid_coproc_keys = []
next unless arg.is_a?(Hash)
arg.each do |key, value|
k = String.new(key)
k.strip!
next unless k =~ /
if value.is_a? String
v = String.new value
v.strip!
cp = coprocessor_descriptor_from_spec_str v
elsif value.is_a? Hash
cp = coprocessor_descriptor_from_hash value
else
raise ArgumentError.new 'coprocessor must be provided as a String or Hash'
end
tdb.setCoprocessor cp
valid_coproc_keys << key
end
valid_coproc_keys.each do |key|
arg.delete(key)
end
hasTableUpdate = true
arg.each_key do |unknown_key|
puts(format('Unknown argument ignored: %s', unknown_key))
end
next
end
if hasTableUpdate
future = @admin.modifyTableAsync(tdb.build, reopen_regions)
if reopen_regions == false
puts("WARNING: You are using REOPEN_REGIONS => 'false' to modify a table, which will
result in inconsistencies in the configuration of online regions and other risks. If you
encounter any issues, use the original 'alter' command to make the modification again!")
future.get
elsif wait == true
puts 'Updating all regions with the new schema...'
future.get
end
end
end