HBASE-26921 Rewrite the counting cells part in TestMultiVersions (#4316)
[hbase.git] / hbase-examples / src / main / cpp / DemoClient.cpp
blob452387b3a3aa062749306a639ada34ea441cfa96
1 /**
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.
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <sys/time.h>
22 #include <poll.h>
24 #include <iostream>
26 #include <protocol/TBinaryProtocol.h>
27 #include <transport/TSocket.h>
28 #include <transport/TTransportUtils.h>
30 #include "Hbase.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;
38 namespace {
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;
48 static void
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;
61 static void
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;
73 int
74 main(int argc, char** argv)
76 if (argc < 3) {
77 std::cerr << "Invalid arguments!\n" << "Usage: DemoClient host port" << std::endl;
78 return -1;
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;
84 if (isFramed) {
85 transport = std::make_shared<TFramedTransport>(socket);
86 } else {
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);
93 try {
94 transport->open();
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;
102 StrVec tables;
103 client.getTableNames(tables);
104 for (StrVec::const_iterator it = tables.begin(); it != tables.end(); ++it) {
105 std::cout << " found: " << *it << std::endl;
106 if (t == *it) {
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:
119 ColVec columns;
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;
127 try {
128 client.createTable(t, columns);
129 } catch (const AlreadyExists &ae) {
130 std::cerr << "WARN: " << ae.message << std::endl;
133 ColMap columnMap;
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);
153 // try empty strings
154 mutations.clear();
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
161 mutations.clear();
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
168 mutations.clear();
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
175 StrVec columnNames;
176 columnNames.push_back("entry:");
178 std::cout << "Starting scanner..." << std::endl;
179 int scanner = client.scannerOpen(t, "", columnNames, dummyAttributes);
180 try {
181 while (true) {
182 std::vector<TRowResult> value;
183 client.scannerGet(value, scanner);
184 if (value.size() == 0)
185 break;
186 printRow(value);
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"
200 char buf[32];
201 sprintf(buf, "%05d", i);
202 std::string row(buf);
203 std::vector<TRowResult> rowResult;
205 mutations.clear();
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);
211 printRow(rowResult);
212 client.deleteAllRow(t, row, dummyAttributes);
214 mutations.clear();
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);
223 printRow(rowResult);
225 // sleep to force later timestamp
226 poll(0, 0, 50);
228 mutations.clear();
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);
237 printRow(rowResult);
239 mutations.clear();
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);
248 printRow(rowResult);
250 mutations.clear();
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);
259 printRow(rowResult);
261 CellVec versions;
262 client.getVer(versions, t, row, "entry:num", 10, dummyAttributes);
263 printVersions(row, versions);
264 assert(versions.size());
265 std::cout << std::endl;
267 try {
268 std::vector<TCell> value;
269 client.get(value, t, row, "entry:foo", dummyAttributes);
270 if (value.size()) {
271 std::cerr << "FATAL: shouldn't get here!" << std::endl;
272 return -1;
274 } catch (const IOError &ioe) {
275 // blank
279 // scan all rows/columns
281 columnNames.clear();
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);
292 try {
293 while (true) {
294 std::vector<TRowResult> value;
295 client.scannerGet(value, scanner);
296 if (value.size() == 0)
297 break;
298 printRow(value);
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;
307 transport->close();
308 } catch (const TException &tx) {
309 std::cerr << "ERROR: " << tx.what() << std::endl;