# Command passed to org.jruby.Main. Pollutes jirb with hbase imports and hbase # commands and then loads jirb. Outputs a banner that tells user where to find # help, shell version, etc. # TODO: Process command-line arguments: e.g. --master= or -Dhbase.etc and --formatter # or read hbase shell configurations from irbrc # TODO: Write a base class for formatters with ascii, xhtml, and json subclasses. # Run the java magic include and import basic HBase types that will help ease # hbase hacking. include Java import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.client.HTable import org.apache.hadoop.hbase.client.HBaseAdmin import org.apache.hadoop.hbase.HColumnDescriptor import org.apache.hadoop.hbase.HConstants import org.apache.hadoop.hbase.HTableDescriptor import org.apache.hadoop.hbase.io.BatchUpdate # Some goodies for hirb. Should these be left up to the user's discretion? require 'irb/completion' # Add the $HBASE_HOME/bin directory, the presumed location of this script, # to the ruby load path so I can load up my HBase ruby modules $LOAD_PATH.unshift File.dirname($PROGRAM_NAME) require 'Formatter' require 'HBase' # A HERE document used outputting shell command-line options. @cmdline_help = < 'Output HBase version', 'list' => 'List all tables', # The help string in the below is carefully formatted to wrap nicely in # our dumb Console formatter 'create' => "Create table; pass a table name, a dictionary of \ specifications per column family, and optionally, named parameters of table \ options. Dictionaries are specified with curly-brackets, uppercase keys, a '=>'\ key/value delimiter and then a value. Named parameters are like dict- \ ionary elements with uppercase names and a '=>' delimiter. E.g. To \ create a table named 'table1' with an alternate maximum region size \ and a single family named 'family1' with an alternate maximum cells: \ create 'table1' {NAME =>'family1', MAX_NUM_VERSIONS => 5}, REGION_SIZE => 12345", 'enable' => "Enable named table", 'disable' => "Disable named table", 'exists' => "Does named table exist", } @formatter.header(["HBase Shell Commands:"]) # TODO: Add general note that all names must be quoted and a general # description of dictionary so create doesn't have to be so long. for k, v in commands.sort @formatter.row([k, v]) end @formatter.footer() end def version @formatter.header() @formatter.row(["Version: #{org.apache.hadoop.hbase.util.VersionInfo.getVersion()},\ r#{org.apache.hadoop.hbase.util.VersionInfo.getRevision()},\ #{org.apache.hadoop.hbase.util.VersionInfo.getDate()}"]) @formatter.footer() end # DDL def create(table_name, *args) @admin = HBase::Admin.new(@configuration, @formatter) unless @admin @admin.create(table_name, args) end def drop(table_name) @admin = HBase::Admin.new(@configuration, @formatter) unless @admin @admin.drop(table_name) end def alter(table_name, *args) puts "Not implemented yet" end # Administration def list @admin = HBase::Admin.new(@configuration, @formatter) unless @admin @admin.list() end def enable(table_name) @admin = HBase::Admin.new(@configuration, @formatter) unless @admin @admin.enable(table_name) end def disable(table_name) @admin = HBase::Admin.new(@configuration, @formatter) unless @admin @admin.disable(table_name) end def exists(table_name) @admin = HBase::Admin.new(@configuration, @formatter) unless @admin @admin.exists(table_name) end # CRUD def get(table_name, row_key, *args) puts "Not implemented yet" end def put(table_name, row_key, *args) puts "Not implemented yet" end def scan(table_name, start_key, end_key, *args) puts "Not implemented yet" end def delete(table_name, row_key, *args) puts "Not implemented yet" end # Output a banner message that tells users where to go for help # TODO: Test that we're in irb context. For now presume it. # TODO: Test that we are in shell context. puts "HBase Shell; type 'hbase' for the list of supported HBase commands" version require "irb" # IRB::ExtendCommandBundle.instance_variable_get("@EXTEND_COMMANDS").delete_if{|x| x.first == :irb_help} module IRB module ExtendCommandBundle # These are attempts at blocking the complaint about :irb_help on startup. # @EXTEND_COMMANDS.delete_if{|x| x[0] == :irb_help} # @EXTEND_COMMANDS.each{|x| x[3][1] = OVERRIDE_ALL if x[0] == :irb_help} # @EXTEND_COMMANDS.each{|x| puts x if x[0] == :irb_help} end class HIRB < Irb # Subclass irb so can intercept methods def output_value # Suppress output if last_value is 'nil' # Otherwise, when user types help, get ugly 'nil' # after all output. if @context.last_value super end end end def IRB.start(ap_path = nil) $0 = File::basename(ap_path, ".rb") if ap_path IRB.setup(ap_path) @CONF[:IRB_NAME]="hbase" if @CONF[:SCRIPT] hirb = HIRB.new(nil, @CONF[:SCRIPT]) else hirb = HIRB.new end @CONF[:IRB_RC].call(hirb.context) if @CONF[:IRB_RC] @CONF[:MAIN_CONTEXT] = hirb.context trap("SIGINT") do hirb.signal_handle end catch(:IRB_EXIT) do hirb.eval_input end end end IRB.start