alter

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