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:
parent
62c4e4b5b4
commit
42b368a2c5
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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...
|
||||
|
||||
|
|
Loading…
Reference in New Issue