HBASE-822 Added all other languages examples (only Python went in last commit of 822)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@694454 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jean-Daniel Cryans 2008-09-11 20:12:52 +00:00
parent 62c4e4b5b4
commit 42b368a2c5
8 changed files with 376 additions and 198 deletions

View File

@ -5,6 +5,7 @@ Release 0.18.0 - Unreleased
HBASE-697 Thrift idl needs update/edit to match new 0.2 API (and to fix bugs)
(Tim Sell via Stack)
HBASE-822 Update thrift README and HBase.thrift to use thrift 20080411
Updated all other languages examples (only python went in)
BUG FIXES
HBASE-881 Fixed bug when Master tries to reassign split or offline regions

View File

@ -17,6 +17,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Instructions:
* 1. Run Thrift to generate the cpp module HBase
* thrift --gen cpp ../../../src/java/org/apache/hadoop/hbase/thrift/Hbase.thrift
* 2. Execute {make}.
* 3. Execute {./DemoClient}.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
@ -40,30 +49,27 @@ typedef std::vector<std::string> StrVec;
typedef std::map<std::string,std::string> StrMap;
typedef std::vector<ColumnDescriptor> ColVec;
typedef std::map<std::string,ColumnDescriptor> ColMap;
typedef std::vector<TCell> CellVec;
typedef std::map<std::string,TCell> CellMap;
static void
printRow(const std::string &row, const StrMap &columns)
printRow(const TRowResult &rowResult)
{
std::cout << "row: " << row << ", cols: ";
for (StrMap::const_iterator it = columns.begin(); it != columns.end(); ++it) {
std::cout << it->first << " => " << it->second << "; ";
std::cout << "row: " << rowResult.row << ", cols: ";
for (CellMap::const_iterator it = rowResult.columns.begin();
it != rowResult.columns.end(); ++it) {
std::cout << it->first << " => " << it->second.value << "; ";
}
std::cout << std::endl;
}
static void
printEntry(const ScanEntry &entry)
{
printRow(entry.row, entry.columns);
}
static void
printVersions(const std::string &row, const StrVec &versions)
printVersions(const std::string &row, const CellVec &versions)
{
std::cout << "row: " << row << ", values: ";
for (StrVec::const_iterator it = versions.begin(); it != versions.end(); ++it) {
std::cout << *it << "; ";
for (CellVec::const_iterator it = versions.begin(); it != versions.end(); ++it) {
std::cout << (*it).value << "; ";
}
std::cout << std::endl;
}
@ -90,6 +96,10 @@ main(int argc, char** argv)
for (StrVec::const_iterator it = tables.begin(); it != tables.end(); ++it) {
std::cout << " found: " << *it << std::endl;
if (t == *it) {
if (client.isTableEnabled(*it)) {
std::cout << " disabling table: " << *it << std::endl;
client.disableTable(*it);
}
std::cout << " deleting table: " << *it << std::endl;
client.deleteTable(*it);
}
@ -126,17 +136,33 @@ main(int argc, char** argv)
std::string valid("foo-\xE7\x94\x9F\xE3\x83\x93\xE3\x83\xBC\xE3\x83\xAB");
// non-utf8 is fine for data
client.put(t, "foo", "entry:foo", invalid);
std::vector<Mutation> mutations;
mutations.push_back(Mutation());
mutations.back().column = "entry:foo";
mutations.back().value = invalid;
client.mutateRow(t, "foo", mutations);
// try empty strings
client.put(t, "", "entry:", "");
mutations.clear();
mutations.push_back(Mutation());
mutations.back().column = "entry:";
mutations.back().value = "";
client.mutateRow(t, "", mutations);
// this row name is valid utf8
client.put(t, valid, "entry:foo", valid);
mutations.clear();
mutations.push_back(Mutation());
mutations.back().column = "entry:foo";
mutations.back().value = valid;
client.mutateRow(t, valid, mutations);
// non-utf8 is not allowed in row names
try {
client.put(t, invalid, "entry:foo", invalid);
mutations.clear();
mutations.push_back(Mutation());
mutations.back().column = "entry:foo";
mutations.back().value = invalid;
client.mutateRow(t, invalid, mutations);
std::cout << "FATAL: shouldn't get here!" << std::endl;
exit(-1);
} catch (IOError e) {
@ -151,9 +177,9 @@ main(int argc, char** argv)
int scanner = client.scannerOpen(t, "", columnNames);
try {
while (true) {
ScanEntry value;
TRowResult value;
client.scannerGet(value, scanner);
printEntry(value);
printRow(value);
}
} catch (NotFound &nf) {
client.scannerClose(scanner);
@ -169,22 +195,32 @@ main(int argc, char** argv)
sprintf(buf, "%0.5d", i);
std::string row(buf);
StrMap values;
TRowResult rowResult;
client.put(t, row, "unused:", "DELETE_ME");
client.getRow(values, t, row);
printRow(row, values);
mutations.clear();
mutations.push_back(Mutation());
mutations.back().column = "unused:";
mutations.back().value = "DELETE_ME";
client.mutateRow(t, row, mutations);
client.getRow(rowResult, t, row);
printRow(rowResult);
client.deleteAllRow(t, row);
client.put(t, row, "entry:num", "0");
client.put(t, row, "entry:foo", "FOO");
client.getRow(values, t, row);
printRow(row, values);
mutations.clear();
mutations.push_back(Mutation());
mutations.back().column = "entry:num";
mutations.back().value = "0";
mutations.push_back(Mutation());
mutations.back().column = "entry:foo";
mutations.back().value = "FOO";
client.mutateRow(t, row, mutations);
client.getRow(rowResult, t, row);
printRow(rowResult);
// sleep to force later timestamp
poll(0, 0, 50);
std::vector<Mutation> mutations;
mutations.clear();
mutations.push_back(Mutation());
mutations.back().column = "entry:foo";
mutations.back().isDelete = true;
@ -192,13 +228,19 @@ main(int argc, char** argv)
mutations.back().column = "entry:num";
mutations.back().value = "-1";
client.mutateRow(t, row, mutations);
client.getRow(values, t, row);
printRow(row, values);
client.put(t, row, "entry:num", boost::lexical_cast<std::string>(i));
client.put(t, row, "entry:sqr", boost::lexical_cast<std::string>(i*i));
client.getRow(values, t, row);
printRow(row, values);
client.getRow(rowResult, t, row);
printRow(rowResult);
mutations.clear();
mutations.push_back(Mutation());
mutations.back().column = "entry:num";
mutations.back().value = boost::lexical_cast<std::string>(i);
mutations.push_back(Mutation());
mutations.back().column = "entry:sqr";
mutations.back().value = boost::lexical_cast<std::string>(i*i);
client.mutateRow(t, row, mutations);
client.getRow(rowResult, t, row);
printRow(rowResult);
mutations.clear();
mutations.push_back(Mutation());
@ -208,17 +250,17 @@ main(int argc, char** argv)
mutations.back().column = "entry:sqr";
mutations.back().isDelete = true;
client.mutateRowTs(t, row, mutations, 1); // shouldn't override latest
client.getRow(values, t, row);
printRow(row, values);
client.getRow(rowResult, t, row);
printRow(rowResult);
StrVec versions;
CellVec versions;
client.getVer(versions, t, row, "entry:num", 10);
printVersions(row, versions);
assert(versions.size() == 4);
std::cout << std::endl;
try {
std::string value;
TCell value;
client.get(value, t, row, "entry:foo");
std::cout << "FATAL: shouldn't get here!" << std::endl;
exit(-1);
@ -232,16 +274,17 @@ main(int argc, char** argv)
columnNames.clear();
client.getColumnDescriptors(columnMap, t);
for (ColMap::const_iterator it = columnMap.begin(); it != columnMap.end(); ++it) {
columnNames.push_back(it->first);
std::cout << "column with name: " + it->second.name << std::endl;
columnNames.push_back(it->second.name + ":");
}
std::cout << "Starting scanner..." << std::endl;
scanner = client.scannerOpenWithStop(t, "00020", "00040", columnNames);
try {
while (true) {
ScanEntry value;
TRowResult value;
client.scannerGet(value, scanner);
printEntry(value);
printRow(value);
}
} catch (NotFound &nf) {
client.scannerClose(scanner);

View File

@ -47,14 +47,30 @@ import com.facebook.thrift.protocol.TProtocol;
import com.facebook.thrift.transport.TSocket;
import com.facebook.thrift.transport.TTransport;
/*
* Instructions:
* 1. Run Thrift to generate the java module HBase
* thrift --gen java ../../../src/java/org/apache/hadoop/hbase/thrift/Hbase.thrift
* 2. Acquire a jar of compiled Thrift java classes. As of this writing, HBase ships
* with this jar (libthrift-[VERSION].jar). If this jar is not present, or it is
* out-of-date with your current version of thrift, you can compile the jar
* yourself by executing {ant} in {$THRIFT_HOME}/lib/java.
* 3. Compile and execute this file with both the libthrift jar and the gen-java/
* directory in the classpath. This can be done on the command-line with the
* following lines: (from the directory containing this file and gen-java/)
*
* javac -cp /path/to/libthrift/jar.jar:gen-java/ DemoClient.java
* mv DemoClient.class gen-java/org/apache/hadoop/hbase/thrift/
* java -cp /path/to/libthrift/jar.jar:gen-java/ org.apache.hadoop.hbase.thrift.DemoClient
*
*/
public class DemoClient {
protected int port = 9090;
CharsetDecoder decoder = null;
public static void main(String[] args)
throws IOError, TException, NotFound, UnsupportedEncodingException, IllegalArgument, AlreadyExists
{
throws IOError, TException, NotFound, UnsupportedEncodingException, IllegalArgument, AlreadyExists {
DemoClient client = new DemoClient();
client.run();
}
@ -100,9 +116,10 @@ public class DemoClient {
for (byte[] name : client.getTableNames()) {
System.out.println(" found: " + utf8(name));
if (utf8(name).equals(utf8(t))) {
System.out.println(" disabling table: " + utf8(name));
if (client.isTableEnabled(name))
if (client.isTableEnabled(name)) {
System.out.println(" disabling table: " + utf8(name));
client.disableTable(name);
}
System.out.println(" deleting table: " + utf8(name));
client.deleteTable(name);
}
@ -154,7 +171,7 @@ public class DemoClient {
// this row name is valid utf8
mutations = new ArrayList<Mutation>();
mutations.add(new Mutation(false, bytes("entry:foo"), valid));
client.mutateRow(t, bytes("foo"), mutations);
client.mutateRow(t, valid, mutations);
// non-utf8 is not allowed in row names
try {
@ -264,7 +281,7 @@ public class DemoClient {
columnNames.clear();
for (ColumnDescriptor col2 : client.getColumnDescriptors(t).values()) {
System.out.println("column name is " + new String(col2.name));
System.out.println("column with name: " + new String(col2.name));
System.out.println(col2.toString());
columnNames.add((utf8(col2.name) + ":").getBytes());
}

View File

@ -19,8 +19,15 @@
* limitations under the License.
*/
# Instructions:
# 1. Run Thrift to generate the php module HBase
# thrift -php ../../../src/java/org/apache/hadoop/hbase/thrift/Hbase.thrift
# 2. Modify the import string below to point to {$THRIFT_HOME}/lib/php/src.
# 3. Execute {php DemoClient.php}. Note that you must use php5 or higher.
# 4. See {$THRIFT_HOME}/lib/php/README for additional help.
# Change this to match your thrift root
$GLOBALS['THRIFT_ROOT'] = dirname(__FILE__).'/thrift';
$GLOBALS['THRIFT_ROOT'] = '/Users/irubin/Thrift/thrift-20080411p1/lib/php/src';
require_once( $GLOBALS['THRIFT_ROOT'].'/Thrift.php' );
@ -29,21 +36,19 @@ require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php' );
# According to the thrift documentation, compiled PHP thrift libraries should
# reside under the THRIFT_ROOT/packages directory.
# reside under the THRIFT_ROOT/packages directory. If these compiled libraries
# are not present in this directory, move them there from gen-php/.
require_once( $GLOBALS['THRIFT_ROOT'].'/packages/Hbase/Hbase.php' );
function printRow( $row, $values ) {
echo( "row: {$row}, cols: \n" );
function printRow( $rowresult ) {
echo( "row: {$rowresult->row}, cols: \n" );
$values = $rowresult->columns;
asort( $values );
foreach ( $values as $k=>$v ) {
echo( " {$k} => {$v}\n" );
echo( " {$k} => {$v->value}\n" );
}
}
function printEntry( $entry ) {
printRow( $entry->row, $entry->columns );
}
$socket = new TSocket( 'localhost', 9090 );
$socket->setSendTimeout( 10000 ); // Ten seconds (too long for production, but this is just a demo ;)
$socket->setRecvTimeout( 20000 ); // Twenty seconds
@ -72,6 +77,10 @@ sort( $tables );
foreach ( $tables as $name ) {
echo( " found: {$name}\n" );
if ( $name == $t ) {
if ($client->isTableEnabled( $name )) {
echo( " disabling table: {$name}\n");
$client->disableTable( $name );
}
echo( " deleting table: {$name}\n" );
$client->deleteTable( $name );
}
@ -111,17 +120,41 @@ $invalid = "foo-\xfc\xa1\xa1\xa1\xa1\xa1";
$valid = "foo-\xE7\x94\x9F\xE3\x83\x93\xE3\x83\xBC\xE3\x83\xAB";
# non-utf8 is fine for data
$client->put( $t, "foo", "entry:foo", $invalid );
$mutations = array(
new Mutation( array(
'column' => 'entry:foo',
'value' => $invalid
) ),
);
$client->mutateRow( $t, "foo", $mutations );
# try empty strings
$client->put( $t, "", "entry:", "" );
$mutations = array(
new Mutation( array(
'column' => 'entry:',
'value' => ""
) ),
);
$client->mutateRow( $t, "", $mutations );
# this row name is valid utf8
$client->put( $t, $valid, "entry:foo", $valid );
$mutations = array(
new Mutation( array(
'column' => 'entry:foo',
'value' => $valid
) ),
);
$client->mutateRow( $t, $valid, $mutations );
# non-utf8 is not allowed in row names
try {
$client->put( $t, $invalid, "entry:foo", $invalid );
$mutations = array(
new Mutation( array(
'column' => 'entry:foo',
'value' => $invalid
) ),
);
$client->mutateRow( $t, $invalid, $mutations );
throw new Exception( "shouldn't get here!" );
} catch ( IOError $e ) {
echo( "expected error: {$e->message}\n" );
@ -131,7 +164,7 @@ try {
echo( "Starting scanner...\n" );
$scanner = $client->scannerOpen( $t, "", array( "entry:" ) );
try {
while (true) printEntry( $client->scannerGet( $scanner ) );
while (true) printRow( $client->scannerGet( $scanner ) );
} catch ( NotFound $nf ) {
$client->scannerClose( $scanner );
echo( "Scanner finished\n" );
@ -145,13 +178,28 @@ for ($e=100; $e>=0; $e--) {
# format row keys as "00000" to "00100"
$row = str_pad( $e, 5, '0', STR_PAD_LEFT );
$client->put( $t, $row, "unused:", "DELETE_ME" );
printRow( $row, $client->getRow( $t, $row ) );
$mutations = array(
new Mutation( array(
'column' => 'unused:',
'value' => "DELETE_ME"
) ),
);
$client->mutateRow( $t, $row, $mutations);
printRow( $client->getRow( $t, $row ));
$client->deleteAllRow( $t, $row );
$client->put( $t, $row, "entry:num", "0" );
$client->put( $t, $row, "entry:foo", "FOO");
printRow( $row, $client->getRow( $t, $row ) );
$mutations = array(
new Mutation( array(
'column' => 'entry:num',
'value' => "0"
) ),
new Mutation( array(
'column' => 'entry:foo',
'value' => "FOO"
) ),
);
$client->mutateRow( $t, $row, $mutations );
printRow( $client->getRow( $t, $row ));
$mutations = array(
new Mutation( array(
@ -164,16 +212,25 @@ for ($e=100; $e>=0; $e--) {
) ),
);
$client->mutateRow( $t, $row, $mutations );
printRow( $row, $client->getRow( $t, $row ) );
printRow( $client->getRow( $t, $row ) );
$client->put( $t, $row, "entry:num", $e );
$client->put( $t, $row, "entry:sqr", $e * $e );
printRow( $row, $client->getRow( $t, $row ) );
$mutations = array(
new Mutation( array(
'column' => "entry:num",
'value' => $e
) ),
new Mutation( array(
'column' => "entry:sqr",
'value' => $e * $e
) ),
);
$client->mutateRow( $t, $row, $mutations );
printRow( $client->getRow( $t, $row ));
$mutations = array(
new Mutation( array(
'column' => 'entry:num',
'isDelete' => '-999'
'value' => '-999'
) ),
new Mutation( array(
'column' => 'entry:sqr',
@ -181,11 +238,11 @@ for ($e=100; $e>=0; $e--) {
) ),
);
$client->mutateRowTs( $t, $row, $mutations, 1 ); # shouldn't override latest
printRow( $row, $client->getRow( $t, $row ) );
printRow( $client->getRow( $t, $row ) );
$versions = $client->getVer( $t, $row, "entry:num", 10 );
echo( "row: {$row}, values: \n" );
foreach ( $versions as $v ) echo( " {$v};\n" );
foreach ( $versions as $v ) echo( " {$v->value};\n" );
try {
$client->get( $t, $row, "entry:foo");
@ -197,12 +254,15 @@ for ($e=100; $e>=0; $e--) {
}
$columns = array();
foreach ( $client->getColumnDescriptors($t) as $col=>$desc ) $columns[] = $col;
foreach ( $client->getColumnDescriptors($t) as $col=>$desc ) {
echo("column with name: {$desc->name}\n");
$columns[] = $desc->name.":";
}
echo( "Starting scanner...\n" );
$scanner = $client->scannerOpenWithStop( $t, "00020", "00040", $columns );
try {
while (true) printEntry( $client->scannerGet( $scanner ) );
while (true) printRow( $client->scannerGet( $scanner ) );
} catch ( NotFound $nf ) {
$client->scannerClose( $scanner );
echo( "Scanner finished\n" );

View File

@ -18,10 +18,15 @@
limitations under the License.
'''
# Instructions:
# 1. Run Thrift to generate python module HBase
# 1. Run Thrift to generate the python module HBase
# thrift --gen py ../../../src/java/org/apache/hadoop/hbase/thrift/Hbase.thrift
# 2. Copy gen-py/HBase module into your project tree and change import string
# Contributed by: Ivan Begtin (ibegtin@gmail.com, ibegtin@enotpoiskun.ru)
# 2. Create a directory of your choosing that contains:
# a. This file (DemoClient.py).
# b. The directory gen-py/hbase (generated by instruction step 1).
# c. The directory {$THRIFT_HOME}/lib/py/build/lib.{YOUR_SYSTEM}/thrift.
# Or, modify the import statements below such that this file can access the
# directories from steps 3b and 3c.
# 3. Execute {python DemoClient.py}.
import sys
import time
@ -29,21 +34,20 @@ import time
from thrift import Thrift
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol
from Hbase import ttypes
from Hbase.Hbase import Client, ColumnDescriptor, Mutation
from hbase import ttypes
from hbase.Hbase import Client, ColumnDescriptor, Mutation
def printVersions(row, versions):
print "row: " + row + ", values: ",
for cell in versions:
print cell.value + "; ",
print
print "row: " + row + ", values: ",
for cell in versions:
print cell.value + "; ",
print
def printRow(entry):
print "row: " + entry.row + ", cols",
for k in sorted(entry.columns):
print k + " => " + entry.columns[k].value,
print
print "row: " + entry.row + ", cols:",
for k in sorted(entry.columns):
print k + " => " + entry.columns[k].value,
print
# Make socket
transport = TSocket.TSocket('localhost', 9090)
@ -67,13 +71,13 @@ t = "demo_table"
#
print "scanning tables..."
for table in client.getTableNames():
print " found: %s" %(table)
if table == t:
print " disabling table: %s" %(t)
if client.isTableEnabled(table):
client.disableTable(table)
print " deleting table: %s" %(t)
client.deleteTable(table)
print " found: %s" %(table)
if table == t:
if client.isTableEnabled(table):
print " disabling table: %s" %(t)
client.disableTable(table)
print " deleting table: %s" %(t)
client.deleteTable(table)
columns = []
col = ColumnDescriptor()
@ -85,14 +89,16 @@ col.name = 'unused:'
columns.append(col)
try:
client.createTable(t, columns)
print "creating table: %s" %(t)
client.createTable(t, columns)
except AlreadyExists, ae:
print "WARN: " + ae.message
print "WARN: " + ae.message
cols = client.getColumnDescriptors(t)
print "column families in %s" %(t)
for col_name in cols.keys():
col = cols[col_name]
print " column: %s, maxVer: %d" % (col.name, col.maxVersions)
col = cols[col_name]
print " column: %s, maxVer: %d" % (col.name, col.maxVersions)
#
# Test UTF-8 handling
#
@ -105,96 +111,95 @@ client.mutateRow(t, "foo", mutations)
# try empty strings
mutations = [Mutation({"column":"entry:", "value":""})]
client.mutateRow(t, "foo", mutations)
client.mutateRow(t, "", mutations)
# this row name is valid utf8
mutations = [Mutation({"column":"entry:foo", "value":valid})]
client.mutateRow(t, "foo", mutations)
client.mutateRow(t, valid, mutations)
# non-utf8 is not allowed in row names
try:
mutations = [Mutation({"column":"entry:foo", "value":invalid})]
client.mutateRow(t, invalid, mutations)
mutations = [Mutation({"column":"entry:foo", "value":invalid})]
client.mutateRow(t, invalid, mutations)
except ttypes.IOError, e:
print 'expected exception: %s' %(e.message)
print 'expected exception: %s' %(e.message)
# Run a scanner on the rows we just created
print "Starting scanner..."
scanner = client.scannerOpen(t, "", ["entry::"])
scanner = client.scannerOpen(t, "", ["entry:"])
try:
while 1:
printRow(client.scannerGet(scanner))
while 1:
printRow(client.scannerGet(scanner))
except ttypes.NotFound, e:
print "Scanner finished"
print "Scanner finished"
#
# Run some operations on a bunch of rows.
#
for e in range(100, 0, -1):
# format row keys as "00000" to "00100"
row = "%0.5d" % (e)
row = "%0.5d" % (e)
mutations = [Mutation({"column":"unused:", "value":"DELETE_ME"})]
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row))
client.deleteAllRow(t, row)
mutations = [Mutation({"column":"entry:num", "value":"0"}),
Mutation({"column":"entry:foo", "value":"FOO"})]
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row));
mutations = [Mutation({"column":"unused:", "value":"DELETE_ME"})]
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row))
client.deleteAllRow(t, row)
mutations = []
m = Mutation()
m.column = "entry:foo"
m.isDelete = 1
mutations.append(m)
m = Mutation()
m.column = "entry:num"
m.value = "-1"
mutations.append(m)
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row));
mutations = [Mutation({"column":"entry:num", "value":"0"}),
Mutation({"column":"entry:foo", "value":"FOO"})]
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row));
mutations = [Mutation({"column":"entry:num", "value":str(e)}),
Mutation({"column":"entry:sqr", "value":str(e*e)})]
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row));
mutations = []
m = Mutation()
m.column = "entry:foo"
m.isDelete = 1
mutations.append(m)
m = Mutation()
m.column = "entry:num"
m.value = "-1"
mutations.append(m)
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row))
time.sleep(0.05)
mutations = []
m = Mutation()
m.column = "entry:num"
m.value = "-999"
mutations.append(m)
m = Mutation()
m.column = "entry:sqr"
m.isDelete = 1
mutations.append(m)
client.mutateRowTs(t, row, mutations, 1) # shouldn't override latest
printRow(client.getRow(t, row))
mutations = [Mutation({"column":"entry:num", "value":str(e)}),
Mutation({"column":"entry:sqr", "value":str(e*e)})]
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row));
versions = client.getVer(t, row, "entry:num", 10)
printVersions(row, versions)
if len(versions) != 4:
print("FATAL: wrong # of versions")
sys.exit(-1)
try:
client.get(t, row, "entry:foo")
print("FATAL: shouldn't get here")
sys.exit(-1)
except ttypes.NotFound:
time.sleep(0.05)
mutations = []
m = Mutation()
m.column = "entry:num"
m.value = "-999"
mutations.append(m)
m = Mutation()
m.column = "entry:sqr"
m.isDelete = 1
mutations.append(m)
client.mutateRowTs(t, row, mutations, 1) # shouldn't override latest
printRow(client.getRow(t, row))
versions = client.getVer(t, row, "entry:num", 10)
printVersions(row, versions)
if len(versions) != 4:
print("FATAL: wrong # of versions")
sys.exit(-1)
try:
client.get(t, row, "entry:foo")
raise "shouldn't get here!"
except ttypes.NotFound, e:
pass
print
print
columnNames = []
for col2 in client.getColumnDescriptors(t):
print "column name is "+col2.name
print col2
columnNames.append(col2.name+":")
for (col, desc) in client.getColumnDescriptors(t).items():
print "column with name: "+desc.name
print desc
columnNames.append(desc.name+":")
print "Starting scanner..."
scanner = client.scannerOpenWithStop(t, "00020", "00040", columnNames)
@ -202,7 +207,7 @@ try:
while 1:
printRow(client.scannerGet(scanner))
except ttypes.NotFound:
client.scannerClose(scanner)
print "Scanner finished"
client.scannerClose(scanner)
print "Scanner finished"
transport.close()

View File

@ -18,7 +18,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
$:.push('~/thrift/trunk/lib/rb/lib')
# Instructions:
# 1. Run Thrift to generate the ruby module HBase
# thrift --gen rb ../../../src/java/org/apache/hadoop/hbase/thrift/Hbase.thrift
# 2. Modify the import string below to point to {$THRIFT_HOME}/lib/rb/lib.
# 3. Execute {ruby DemoClient.rb}.
# You will need to modify this import string:
$:.push('~/Thrift/thrift-20080411p1/lib/rb/lib')
$:.push('./gen-rb')
require 'thrift/transport/tsocket'
@ -26,18 +33,14 @@ require 'thrift/protocol/tbinaryprotocol'
require 'Hbase'
def printRow(row, values)
print "row: #{row}, cols: "
values.sort.each do |k,v|
print "#{k} => #{v}; "
def printRow(rowresult)
print "row: #{rowresult.row}, cols: "
rowresult.columns.sort.each do |k,v|
print "#{k} => #{v.value}; "
end
puts ""
end
def printEntry(entry)
printRow(entry.row, entry.columns)
end
transport = TBufferedTransport.new(TSocket.new("localhost", 9090))
protocol = TBinaryProtocol.new(transport)
client = Apache::Hadoop::Hbase::Thrift::Hbase::Client.new(protocol)
@ -52,7 +55,11 @@ t = "demo_table"
puts "scanning tables..."
client.getTableNames().sort.each do |name|
puts " found: #{name}"
if (name == t)
if (name == t)
if (client.isTableEnabled(name))
puts " disabling table: #{name}"
client.disableTable(name)
end
puts " deleting table: #{name}"
client.deleteTable(name)
end
@ -89,17 +96,37 @@ invalid = "foo-\xfc\xa1\xa1\xa1\xa1\xa1"
valid = "foo-\xE7\x94\x9F\xE3\x83\x93\xE3\x83\xBC\xE3\x83\xAB";
# non-utf8 is fine for data
client.put(t, "foo", "entry:foo", invalid)
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "entry:foo"
m.value = invalid
mutations << m
client.mutateRow(t, "foo", mutations)
# try empty strings
client.put(t, "", "entry:", "");
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "entry:"
m.value = ""
mutations << m
client.mutateRow(t, "", mutations)
# this row name is valid utf8
client.put(t, valid, "entry:foo", valid)
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "entry:foo"
m.value = valid
mutations << m
client.mutateRow(t, valid, mutations)
# non-utf8 is not allowed in row names
begin
client.put(t, invalid, "entry:foo", invalid)
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "entry:foo"
m.value = invalid
mutations << m
client.mutateRow(t, invalid, mutations)
raise "shouldn't get here!"
rescue Apache::Hadoop::Hbase::Thrift::IOError => e
puts "expected error: #{e.message}"
@ -110,7 +137,7 @@ puts "Starting scanner..."
scanner = client.scannerOpen(t, "", ["entry:"])
begin
while (true)
printEntry(client.scannerGet(scanner))
printRow(client.scannerGet(scanner))
end
rescue Apache::Hadoop::Hbase::Thrift::NotFound => nf
client.scannerClose(scanner)
@ -124,13 +151,26 @@ end
# format row keys as "00000" to "00100"
row = format("%0.5d", e)
client.put(t, row, "unused:", "DELETE_ME");
printRow(row, client.getRow(t, row));
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "unused:"
m.value = "DELETE_ME"
mutations << m
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row))
client.deleteAllRow(t, row)
client.put(t, row, "entry:num", "0")
client.put(t, row, "entry:foo", "FOO")
printRow(row, client.getRow(t, row));
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "entry:num"
m.value = "0"
mutations << m
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "entry:foo"
m.value = "FOO"
mutations << m
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row))
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
@ -142,11 +182,19 @@ end
m.value = "-1"
mutations << m
client.mutateRow(t, row, mutations)
printRow(row, client.getRow(t, row));
printRow(client.getRow(t, row));
client.put(t, row, "entry:num", e.to_s)
client.put(t, row, "entry:sqr", (e*e).to_s)
printRow(row, client.getRow(t, row));
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "entry:num"
m.value = e.to_s
mutations << m
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
m.column = "entry:sqr"
m.value = (e*e).to_s
mutations << m
client.mutateRow(t, row, mutations)
printRow(client.getRow(t, row))
mutations = []
m = Apache::Hadoop::Hbase::Thrift::Mutation.new
@ -158,12 +206,12 @@ end
m.isDelete = 1
mutations << m
client.mutateRowTs(t, row, mutations, 1) # shouldn't override latest
printRow(row, client.getRow(t, row));
printRow(client.getRow(t, row));
versions = client.getVer(t, row, "entry:num", 10)
print "row: #{row}, values: "
versions.each do |v|
print "#{v}; "
print "#{v.value}; "
end
puts ""
@ -179,14 +227,15 @@ end
columns = []
client.getColumnDescriptors(t).each do |col, desc|
columns << col
puts "column with name: #{desc.name}"
columns << desc.name + ":"
end
puts "Starting scanner..."
scanner = client.scannerOpenWithStop(t, "00020", "00040", columns)
begin
while (true)
printEntry(client.scannerGet(scanner))
printRow(client.scannerGet(scanner))
end
rescue Apache::Hadoop::Hbase::Thrift::NotFound => nf
client.scannerClose(scanner)

View File

@ -2,13 +2,15 @@ Hbase Thrift Client Examples
============================
Included in this directory are sample clients of the HBase ThriftServer. They
all perform the same actions but are implemented in C++, Java, Ruby, and PHP
respectively.
all perform the same actions but are implemented in C++, Java, Ruby, PHP, and
Python respectively.
To run/compile this clients, you will first need to install the thrift package
(from http://developers.facebook.com/thrift/) and then run thrift to generate
the language files:
thrift --gen cpp --gen java --gen rb --gen php \
thrift --gen cpp --gen java --gen rb --gen py -php \
../../../src/java/org/apache/hadoop/hbase/thrift/Hbase.thrift
See the individual DemoClient test files for more specific instructions on
running each test.

View File

@ -34,6 +34,7 @@
namespace java org.apache.hadoop.hbase.thrift.generated
namespace cpp apache.hadoop.hbase.thrift
namespace rb Apache.Hadoop.Hbase.Thrift
namespace py hbase
// note: other language namespaces tbd...