<?xml version="1.0"?>
  <chapter xml:id="shell"
      version="5.0" xmlns="http://docbook.org/ns/docbook"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      xmlns:svg="http://www.w3.org/2000/svg"
      xmlns:m="http://www.w3.org/1998/Math/MathML"
      xmlns:html="http://www.w3.org/1999/xhtml"
      xmlns:db="http://docbook.org/ns/docbook">
<!--
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
    <title>The Apache HBase Shell</title>

    <para>
        The Apache HBase Shell is <link xlink:href="http://jruby.org">(J)Ruby</link>'s
        IRB with some HBase particular commands added.  Anything you can do in
        IRB, you should be able to do in the HBase Shell.</para>
        <para>To run the HBase shell,
        do as follows:
        <programlisting>$ ./bin/hbase shell</programlisting>
        </para>
            <para>Type <command>help</command> and then <command>&lt;RETURN&gt;</command>
            to see a listing of shell
            commands and options. Browse at least the paragraphs at the end of
            the help emission for the gist of how variables and command
            arguments are entered into the
            HBase shell; in particular note how table names, rows, and
            columns, etc., must be quoted.</para>
        <para>See <xref linkend="shell_exercises" />
            for example basic shell operation.
        </para>
        <para>Here is a nicely formatted listing of <link xlink:href="http://learnhbase.wordpress.com/2013/03/02/hbase-shell-commands/">all shell commands</link> by Rajeshbabu Chintaguntla.
        </para>

    <section xml:id="scripting"><title>Scripting</title>
        <para>For examples scripting Apache HBase, look in the
            HBase <filename>bin</filename> directory.  Look at the files
            that end in <filename>*.rb</filename>.  To run one of these
            files, do as follows:
            <programlisting>$ ./bin/hbase org.jruby.Main PATH_TO_SCRIPT</programlisting>
        </para>
    </section>

    <section xml:id="shell_tricks"><title>Shell Tricks</title>
      <section xml:id="table_variables"><title>Table variables</title>

	<para>
	  HBase 0.95 adds shell commands that provide a jruby-style
	  object-oriented references for tables.  Previously all of
	  the shell commands that act upon a table have a procedural
	  style that always took the name of the table as an
	  argument. HBase 0.95 introduces the ability to assign a
	  table to a jruby variable.  The table reference can be used
	  to perform data read write operations such as puts, scans,
	  and gets well as admin functionality such as disabling,
	  dropping, describing tables.
	</para>
	
	<para>
	  For example, previously you would always specify a table name:
	  <programlisting>
hbase(main):000:0> create ‘t’, ‘f’
0 row(s) in 1.0970 seconds
hbase(main):001:0> put 't', 'rold', 'f', 'v'
0 row(s) in 0.0080 seconds

hbase(main):002:0> scan 't' 
ROW                                COLUMN+CELL                                                                                      
 rold                              column=f:, timestamp=1378473207660, value=v                                                      
1 row(s) in 0.0130 seconds

hbase(main):003:0> describe 't'
DESCRIPTION                                                                           ENABLED                                       
 't', {NAME => 'f', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_ true                                          
 SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2                                               
 147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false                                               
 ', BLOCKCACHE => 'true'}                                                                                 
1 row(s) in 1.4430 seconds

hbase(main):004:0> disable 't'
0 row(s) in 14.8700 seconds

hbase(main):005:0> drop 't'
0 row(s) in 23.1670 seconds

hbase(main):006:0> 
	  </programlisting>
	</para>
	
	<para>
	  Now you can assign the table to a variable and use the results in jruby shell code.
	  <programlisting>
hbase(main):007 > t = create 't', 'f'
0 row(s) in 1.0970 seconds

=> Hbase::Table - t
hbase(main):008 > t.put 'r', 'f', 'v'
0 row(s) in 0.0640 seconds
hbase(main):009 > t.scan
ROW                           COLUMN+CELL                                                                        
 r                            column=f:, timestamp=1331865816290, value=v                                        
1 row(s) in 0.0110 seconds
hbase(main):010:0> t.describe
DESCRIPTION                                                                           ENABLED                                       
 't', {NAME => 'f', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_ true                                          
 SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2                                               
 147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false                                               
 ', BLOCKCACHE => 'true'}                                                                                 
1 row(s) in 0.0210 seconds
hbase(main):038:0> t.disable
0 row(s) in 6.2350 seconds
hbase(main):039:0> t.drop
0 row(s) in 0.2340 seconds
	  </programlisting>
	</para>

	<para>
	  If the table has already been created, you can assign a
	  Table to a variable by using the get_table method:
	  <programlisting>
hbase(main):011 > create 't','f'
0 row(s) in 1.2500 seconds

=> Hbase::Table - t
hbase(main):012:0> tab = get_table 't'
0 row(s) in 0.0010 seconds

=> Hbase::Table - t
hbase(main):013:0> tab.put ‘r1’ ,’f’, ‘v’ 
0 row(s) in 0.0100 seconds
hbase(main):014:0> tab.scan
ROW                                COLUMN+CELL                                                                                      
 r1                                column=f:, timestamp=1378473876949, value=v                                                      
1 row(s) in 0.0240 seconds
hbase(main):015:0> 
	  </programlisting>
	</para>

	<para>
	  The list functionality has also been extended so that it
	  returns a list of table names as strings.  You can then use
	  jruby to script table operations based on these names.  The
	  list_snapshots command also acts similarly.
	  <programlisting>
hbase(main):016 > tables = list(‘t.*’)
TABLE                                                                                                                               
t                                                                                                                                   
1 row(s) in 0.1040 seconds

=> #&lt;#&lt;Class:0x7677ce29>:0x21d377a4>
hbase(main):017:0> tables.map { |t| disable t ; drop  t}
0 row(s) in 2.2510 seconds

=> [nil]
hbase(main):018:0> 
            </programlisting>
          </para>
        </section>

        <section><title><filename>irbrc</filename></title>
                <para>Create an <filename>.irbrc</filename> file for yourself in your home
                directory. Add customizations. A useful one is command history so commands are save
                across Shell invocations:
                <programlisting>
                        $ more .irbrc
                        require 'irb/ext/save-history'
                        IRB.conf[:SAVE_HISTORY] = 100
                        IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"</programlisting>
                See the <application>ruby</application> documentation of <filename>.irbrc</filename>
                to learn about other possible configurations. </para>
        </section>
        <section><title>LOG data to timestamp</title>
            <para>
                To convert the date '08/08/16 20:56:29' from an hbase log into a timestamp, do:
                <programlisting>
                    hbase(main):021:0> import java.text.SimpleDateFormat
                    hbase(main):022:0> import java.text.ParsePosition
                    hbase(main):023:0> SimpleDateFormat.new("yy/MM/dd HH:mm:ss").parse("08/08/16 20:56:29", ParsePosition.new(0)).getTime() => 1218920189000</programlisting>
            </para>
            <para>
                To go the other direction:
                <programlisting>
                    hbase(main):021:0> import java.util.Date
                    hbase(main):022:0> Date.new(1218920189000).toString() => "Sat Aug 16 20:56:29 UTC 2008"</programlisting>
            </para>
            <para>
                To output in a format that is exactly like that of the HBase log format will take a little messing with
                <link xlink:href="http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</link>.
            </para>
        </section>
        <section><title>Debug</title>
            <section><title>Shell debug switch</title>
                <para>You can set a debug switch in the shell to see more output
                    -- e.g. more of the stack trace on exception --
                    when you run a command:
                    <programlisting>hbase> debug &lt;RETURN&gt;</programlisting>
                 </para>
            </section>
            <section><title>DEBUG log level</title>
                <para>To enable DEBUG level logging in the shell,
                    launch it with the <command>-d</command> option.
                    <programlisting>$ ./bin/hbase shell -d</programlisting>
               </para>
            </section>
         </section>
        <section><title>Commands</title>
            <section><title>count</title>
                <para>Count command returns the number of rows in a table.
		    It's quite fast when configured with the right CACHE
            <programlisting>hbase> count '&lt;tablename&gt;', CACHE => 1000</programlisting>
            The above count fetches 1000 rows at a time.  Set CACHE lower if your rows are big.
            Default is to fetch one row at a time.
                 </para>
            </section>
         </section>

    </section>
  </chapter>
