Skip to content

Commit 5f9a9dc

Browse files
committed
status + confirm delete
1 parent 0a80a64 commit 5f9a9dc

File tree

1 file changed

+102
-3
lines changed

1 file changed

+102
-3
lines changed

src/infoLoggerAdminDB.cxx

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323
#include <iomanip>
2424
#include <ctime>
2525
#include <sstream>
26+
#include <vector>
2627

2728
void printUsage()
2829
{
2930
printf("Usage: infoLoggerAdminDB ...\n");
30-
printf(" -c command : action to execute. One of archive (archive main table and create new one), create (create main table), clear (delete main table content), destroy (destroy all tables, including archives), list (show existing message tables)\n");
31+
printf(" -c command : action to execute. One of archive (archive main table and create new one), create (create main table), clear (delete main table content), destroy (destroy all tables, including archives), list (show existing message tables), status (show database content info)\n");
3132
printf(" [-z pathToConfigurationFile] : sets which configuration to use. By default %s\n", INFOLOGGER_DEFAULT_CONFIG_PATH);
32-
printf(" [-o optionName] : enable options not set by default. Possible values: partitioning (create new tables with partition by day)\n");
33+
printf(" [-o optionName] : enable options not set by default. Possible values: partitioning (create new tables with partition by day), noWarning (disable interactive confirmation in delete operations).\n");
3334
printf(" [-h] : print this help\n");
3435
}
3536

@@ -49,6 +50,9 @@ int main(int argc, char* argv[])
4950
bool optList = 0; // list current tables
5051
bool optNone = 0; // no command specified - test DB access only
5152
bool optShowCreate = 0; // print command used to create table
53+
bool optStatus = 0; // get a summary of database content
54+
bool optStatusMore = 0; // print a summary of database content
55+
bool optNoWarning = 0; // when set, there is no warning/interactive confirmation when data to be deleted
5256

5357
// configure log output
5458
log.setOutputFormat(SimpleLog::FormatOption::ShowSeverityTxt | SimpleLog::FormatOption::ShowMessage);
@@ -78,8 +82,11 @@ int main(int argc, char* argv[])
7882
std::string optString = optarg;
7983
if (optString == "partitioning") {
8084
optPartitioning = 1;
85+
} else if (optString == "noWarning") {
86+
optNoWarning = 1;
8187
} else {
8288
log.error("Wrong option %s", optString.c_str());
89+
return -1;
8390
}
8491
} break;
8592

@@ -95,12 +102,17 @@ int main(int argc, char* argv[])
95102
optCreate = 1;
96103
} else if (command == "clear") {
97104
optDelete = 1;
105+
optStatus = 1;
98106
} else if (command == "destroy") {
99107
optDestroy = 1;
108+
optStatus = 1;
100109
} else if (command == "list") {
101110
optList = 1;
102111
} else if (command == "showCreate") {
103112
optShowCreate = 1;
113+
} else if (command == "status") {
114+
optStatus = 1;
115+
optStatusMore = 1;
104116
} else if (command == "") {
105117
optNone = 1;
106118
} else {
@@ -144,7 +156,70 @@ int main(int argc, char* argv[])
144156
return 0;
145157
}
146158

159+
// info on current database content
160+
struct infoTable {
161+
std::string name;
162+
unsigned long rows;
163+
unsigned long size;
164+
};
165+
std::vector<infoTable> tables;
166+
unsigned long long totalTables = 0; // number of tables
167+
unsigned long long totalRows = 0; // number of rows
168+
unsigned long long totalBytes = 0; // number of bytes
169+
unsigned long long mainRows = 0; // number of messages in main table
170+
unsigned long long mainBytes = 0; // number of bytes in main table
171+
147172
// execute command(s)
173+
if (optStatus) {
174+
std::string sqlQuery = "select TABLE_NAME,TABLE_ROWS,DATA_LENGTH from information_schema.TABLES where table_name like '" INFOLOGGER_TABLE_MESSAGES "%' order by table_name";
175+
if (mysql_query(&db, sqlQuery.c_str())) {
176+
log.error("Failed to execute %s\n%s", sqlQuery.c_str(), mysql_error(&db));
177+
return -1;
178+
}
179+
MYSQL_RES* res;
180+
res = mysql_store_result(&db);
181+
if (res == NULL) {
182+
log.error("Failed to retrieve results from query %s", sqlQuery.c_str());
183+
return -1;
184+
}
185+
const int numFields = 3;
186+
if (mysql_num_fields(res) != numFields) {
187+
log.error("Failed to retrieve %d fields from query %s", numFields, sqlQuery.c_str());
188+
return -1;
189+
}
190+
MYSQL_ROW row;
191+
for (int n=0;;n++) {
192+
row = mysql_fetch_row(res);
193+
if (row == NULL) {
194+
break;
195+
}
196+
for (int i=0; i<numFields; i++) {
197+
if (row[i] == NULL) {
198+
log.error("No field[%d] in row %d returned for query %s", i, n, sqlQuery.c_str());
199+
return -1;
200+
}
201+
}
202+
unsigned long long nRows = strtoul(row[1], NULL, 10);
203+
unsigned long long nBytes = strtoul(row[2], NULL, 10);
204+
tables.push_back({row[0], nRows, nBytes});
205+
totalTables++;
206+
totalRows += nRows;
207+
totalBytes += nBytes;
208+
if (!strcmp(row[0], INFOLOGGER_TABLE_MESSAGES)) {
209+
mainRows = nRows;
210+
mainBytes = nBytes;
211+
}
212+
}
213+
mysql_free_result(res);
214+
if (optStatusMore) {
215+
log.info("Found following tables:");
216+
for (const auto &i: tables) {
217+
log.info(" %s : %lu rows, %lu bytes", i.name.c_str(), i.rows, i.size);
218+
}
219+
log.info("Total: %llu tables, %llu rows, %llu bytes", totalTables, totalRows, totalBytes);
220+
}
221+
}
222+
148223
if (optList) {
149224
// list all messages tables
150225
std::string sqlQuery = "show tables like '" INFOLOGGER_TABLE_MESSAGES "%'";
@@ -174,8 +249,27 @@ int main(int argc, char* argv[])
174249
mysql_free_result(res);
175250
}
176251

252+
auto confirm = [&]() {
253+
if (!optNoWarning) {
254+
log.info("Please confirm: type 'yes'");
255+
char buf[5]="";
256+
fgets(buf, 5, stdin);
257+
if (strcmp("yes\n", buf)) {
258+
log.info("Operation aborted %s",buf);
259+
return 0;
260+
}
261+
}
262+
return 1;
263+
};
264+
177265
if (optDelete) {
178266
log.info("Delete main table content");
267+
if ((mainRows)&&(!optNoWarning)) {
268+
log.warning("This table is not empty ! %llu rows (%llu bytes) will be deleted", mainRows, mainBytes);
269+
if (!confirm()) {
270+
return -1;
271+
}
272+
}
179273
std::string sqlQuery = "truncate table " INFOLOGGER_TABLE_MESSAGES;
180274
if (mysql_query(&db, sqlQuery.c_str())) {
181275
log.error("Failed to execute %s\n%s", sqlQuery.c_str(), mysql_error(&db));
@@ -185,7 +279,12 @@ int main(int argc, char* argv[])
185279

186280
if (optDestroy) {
187281
log.info("Destroy all tables");
188-
282+
if ((totalRows)&&(!optNoWarning)) {
283+
log.warning("The tables are not empty ! %llu tables %llu rows (%llu bytes) will be deleted", totalTables, totalRows, totalBytes);
284+
if (!confirm()) {
285+
return -1;
286+
}
287+
}
189288
// destroy all messages tables
190289
std::string sqlQuery = "show tables like '" INFOLOGGER_TABLE_MESSAGES "%'";
191290
if (mysql_query(&db, sqlQuery.c_str())) {

0 commit comments

Comments
 (0)