2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #include <protocol/TBinaryProtocol.h>
27 #include <transport/TSocket.h>
28 #include <transport/TTransportUtils.h>
32 using namespace apache::thrift
;
33 using namespace apache::thrift::protocol
;
34 using namespace apache::thrift::transport
;
36 using namespace apache::hadoop::hbase::thrift
;
40 typedef std::vector
<std::string
> StrVec
;
41 typedef std::map
<std::string
,std::string
> StrMap
;
42 typedef std::vector
<ColumnDescriptor
> ColVec
;
43 typedef std::map
<std::string
,ColumnDescriptor
> ColMap
;
44 typedef std::vector
<TCell
> CellVec
;
45 typedef std::map
<std::string
,TCell
> CellMap
;
49 printRow(const std::vector
<TRowResult
> &rowResult
)
51 for (size_t i
= 0; i
< rowResult
.size(); i
++) {
52 std::cout
<< "row: " << rowResult
[i
].row
<< ", cols: ";
53 for (CellMap::const_iterator it
= rowResult
[i
].columns
.begin();
54 it
!= rowResult
[i
].columns
.end(); ++it
) {
55 std::cout
<< it
->first
<< " => " << it
->second
.value
<< "; ";
57 std::cout
<< std::endl
;
62 printVersions(const std::string
&row
, const CellVec
&versions
)
64 std::cout
<< "row: " << row
<< ", values: ";
65 for (CellVec::const_iterator it
= versions
.begin(); it
!= versions
.end(); ++it
) {
66 std::cout
<< (*it
).value
<< "; ";
68 std::cout
<< std::endl
;
74 main(int argc
, char** argv
)
77 std::cerr
<< "Invalid arguments!\n" << "Usage: DemoClient host port" << std::endl
;
80 bool isFramed
= false;
81 std::shared_ptr
<TTransport
> socket
= std::make_shared
<TSocket
>(argv
[1], std::stoi(argv
[2]));
82 std::shared_ptr
<TTransport
> transport
;
85 transport
= std::make_shared
<TFramedTransport
>(socket
);
87 transport
= std::make_shared
<TBufferedTransport
>(socket
);
89 std::shared_ptr
<TProtocol
> protocol
= std::make_shared
<TBinaryProtocol
>(transport
);
91 const std::map
<Text
, Text
> dummyAttributes
; // see HBASE-6806 HBASE-4658
92 HbaseClient
client(protocol
);
96 std::string
t("demo_table");
99 // Scan all tables, look for the demo table and delete it.
101 std::cout
<< "scanning tables..." << std::endl
;
103 client
.getTableNames(tables
);
104 for (StrVec::const_iterator it
= tables
.begin(); it
!= tables
.end(); ++it
) {
105 std::cout
<< " found: " << *it
<< std::endl
;
107 if (client
.isTableEnabled(*it
)) {
108 std::cout
<< " disabling table: " << *it
<< std::endl
;
109 client
.disableTable(*it
);
111 std::cout
<< " deleting table: " << *it
<< std::endl
;
112 client
.deleteTable(*it
);
117 // Create the demo table with two column families, entry: and unused:
120 columns
.push_back(ColumnDescriptor());
121 columns
.back().name
= "entry:";
122 columns
.back().maxVersions
= 10;
123 columns
.push_back(ColumnDescriptor());
124 columns
.back().name
= "unused:";
126 std::cout
<< "creating table: " << t
<< std::endl
;
128 client
.createTable(t
, columns
);
129 } catch (const AlreadyExists
&ae
) {
130 std::cerr
<< "WARN: " << ae
.message
<< std::endl
;
134 client
.getColumnDescriptors(columnMap
, t
);
135 std::cout
<< "column families in " << t
<< ": " << std::endl
;
136 for (ColMap::const_iterator it
= columnMap
.begin(); it
!= columnMap
.end(); ++it
) {
137 std::cout
<< " column: " << it
->second
.name
<< ", maxVer: " << it
->second
.maxVersions
<< std::endl
;
141 // Test UTF-8 handling
143 std::string
invalid("foo-\xfc\xa1\xa1\xa1\xa1\xa1");
144 std::string
valid("foo-\xE7\x94\x9F\xE3\x83\x93\xE3\x83\xBC\xE3\x83\xAB");
146 // non-utf8 is fine for data
147 std::vector
<Mutation
> mutations
;
148 mutations
.push_back(Mutation());
149 mutations
.back().column
= "entry:foo";
150 mutations
.back().value
= invalid
;
151 client
.mutateRow(t
, "foo", mutations
, dummyAttributes
);
155 mutations
.push_back(Mutation());
156 mutations
.back().column
= "entry:";
157 mutations
.back().value
= "";
158 client
.mutateRow(t
, "", mutations
, dummyAttributes
);
160 // this row name is valid utf8
162 mutations
.push_back(Mutation());
163 mutations
.back().column
= "entry:foo";
164 mutations
.back().value
= valid
;
165 client
.mutateRow(t
, valid
, mutations
, dummyAttributes
);
167 // non-utf8 is now allowed in row names because HBase stores values as binary
169 mutations
.push_back(Mutation());
170 mutations
.back().column
= "entry:foo";
171 mutations
.back().value
= invalid
;
172 client
.mutateRow(t
, invalid
, mutations
, dummyAttributes
);
174 // Run a scanner on the rows we just created
176 columnNames
.push_back("entry:");
178 std::cout
<< "Starting scanner..." << std::endl
;
179 int scanner
= client
.scannerOpen(t
, "", columnNames
, dummyAttributes
);
182 std::vector
<TRowResult
> value
;
183 client
.scannerGet(value
, scanner
);
184 if (value
.size() == 0)
188 } catch (const IOError
&ioe
) {
189 std::cerr
<< "FATAL: Scanner raised IOError" << std::endl
;
192 client
.scannerClose(scanner
);
193 std::cout
<< "Scanner finished" << std::endl
;
196 // Run some operations on a bunch of rows.
198 for (int i
= 100; i
>= 0; --i
) {
199 // format row keys as "00000" to "00100"
201 sprintf(buf
, "%05d", i
);
202 std::string
row(buf
);
203 std::vector
<TRowResult
> rowResult
;
206 mutations
.push_back(Mutation());
207 mutations
.back().column
= "unused:";
208 mutations
.back().value
= "DELETE_ME";
209 client
.mutateRow(t
, row
, mutations
, dummyAttributes
);
210 client
.getRow(rowResult
, t
, row
, dummyAttributes
);
212 client
.deleteAllRow(t
, row
, dummyAttributes
);
215 mutations
.push_back(Mutation());
216 mutations
.back().column
= "entry:num";
217 mutations
.back().value
= "0";
218 mutations
.push_back(Mutation());
219 mutations
.back().column
= "entry:foo";
220 mutations
.back().value
= "FOO";
221 client
.mutateRow(t
, row
, mutations
, dummyAttributes
);
222 client
.getRow(rowResult
, t
, row
, dummyAttributes
);
225 // sleep to force later timestamp
229 mutations
.push_back(Mutation());
230 mutations
.back().column
= "entry:foo";
231 mutations
.back().isDelete
= true;
232 mutations
.push_back(Mutation());
233 mutations
.back().column
= "entry:num";
234 mutations
.back().value
= "-1";
235 client
.mutateRow(t
, row
, mutations
, dummyAttributes
);
236 client
.getRow(rowResult
, t
, row
, dummyAttributes
);
240 mutations
.push_back(Mutation());
241 mutations
.back().column
= "entry:num";
242 mutations
.back().value
= std::to_string(i
);
243 mutations
.push_back(Mutation());
244 mutations
.back().column
= "entry:sqr";
245 mutations
.back().value
= std::to_string(i
* i
);
246 client
.mutateRow(t
, row
, mutations
, dummyAttributes
);
247 client
.getRow(rowResult
, t
, row
, dummyAttributes
);
251 mutations
.push_back(Mutation());
252 mutations
.back().column
= "entry:num";
253 mutations
.back().value
= "-999";
254 mutations
.push_back(Mutation());
255 mutations
.back().column
= "entry:sqr";
256 mutations
.back().isDelete
= true;
257 client
.mutateRowTs(t
, row
, mutations
, 1, dummyAttributes
); // shouldn't override latest
258 client
.getRow(rowResult
, t
, row
, dummyAttributes
);
262 client
.getVer(versions
, t
, row
, "entry:num", 10, dummyAttributes
);
263 printVersions(row
, versions
);
264 assert(versions
.size());
265 std::cout
<< std::endl
;
268 std::vector
<TCell
> value
;
269 client
.get(value
, t
, row
, "entry:foo", dummyAttributes
);
271 std::cerr
<< "FATAL: shouldn't get here!" << std::endl
;
274 } catch (const IOError
&ioe
) {
279 // scan all rows/columns
282 client
.getColumnDescriptors(columnMap
, t
);
283 std::cout
<< "The number of columns: " << columnMap
.size() << std::endl
;
284 for (ColMap::const_iterator it
= columnMap
.begin(); it
!= columnMap
.end(); ++it
) {
285 std::cout
<< " column with name: " + it
->second
.name
<< std::endl
;
286 columnNames
.push_back(it
->second
.name
);
288 std::cout
<< std::endl
;
290 std::cout
<< "Starting scanner..." << std::endl
;
291 scanner
= client
.scannerOpenWithStop(t
, "00020", "00040", columnNames
, dummyAttributes
);
294 std::vector
<TRowResult
> value
;
295 client
.scannerGet(value
, scanner
);
296 if (value
.size() == 0)
300 } catch (const IOError
&ioe
) {
301 std::cerr
<< "FATAL: Scanner raised IOError" << std::endl
;
304 client
.scannerClose(scanner
);
305 std::cout
<< "Scanner finished" << std::endl
;
308 } catch (const TException
&tx
) {
309 std::cerr
<< "ERROR: " << tx
.what() << std::endl
;