in src/shell/commands/data_operations.cpp [1130:1335]
bool hash_scan(command_executor *e, shell_context *sc, arguments args)
{
if (args.argc < 4)
return false;
std::string hash_key = sds_to_string(args.argv[1]);
std::string start_sort_key = sds_to_string(args.argv[2]);
std::string stop_sort_key = sds_to_string(args.argv[3]);
int32_t max_count = -1;
bool detailed = false;
FILE *file = stderr;
int32_t timeout_ms = sc->timeout_ms;
std::string sort_key_filter_type_name("no_filter");
std::string value_filter_type_name("no_filter");
pegasus::pegasus_client::filter_type value_filter_type = pegasus::pegasus_client::FT_NO_FILTER;
std::string value_filter_pattern;
pegasus::pegasus_client::scan_options options;
static struct option long_options[] = {{"detailed", no_argument, 0, 'd'},
{"max_count", required_argument, 0, 'n'},
{"timeout_ms", required_argument, 0, 't'},
{"output", required_argument, 0, 'o'},
{"start_inclusive", required_argument, 0, 'a'},
{"stop_inclusive", required_argument, 0, 'b'},
{"sort_key_filter_type", required_argument, 0, 's'},
{"sort_key_filter_pattern", required_argument, 0, 'y'},
{"value_filter_type", required_argument, 0, 'v'},
{"value_filter_pattern", required_argument, 0, 'z'},
{"no_value", no_argument, 0, 'i'},
{0, 0, 0, 0}};
escape_sds_argv(args.argc, args.argv);
optind = 0;
while (true) {
int option_index = 0;
int c;
c = getopt_long(args.argc, args.argv, "dn:t:o:a:b:s:y:v:z:i", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'd':
detailed = true;
break;
case 'n':
if (!dsn::buf2int32(optarg, max_count)) {
fprintf(stderr, "ERROR: parse %s as max_count failed\n", optarg);
return false;
}
break;
case 't':
if (!dsn::buf2int32(optarg, timeout_ms)) {
fprintf(stderr, "ERROR: parse %s as timeout_ms failed\n", optarg);
return false;
}
break;
case 'o':
file = fopen(optarg, "w");
if (!file) {
fprintf(stderr, "ERROR: open filename %s failed\n", optarg);
return false;
}
break;
case 'a':
if (!dsn::buf2bool(optarg, options.start_inclusive)) {
fprintf(stderr, "ERROR: invalid start_inclusive param\n");
return false;
}
break;
case 'b':
if (!dsn::buf2bool(optarg, options.stop_inclusive)) {
fprintf(stderr, "ERROR: invalid stop_inclusive param\n");
return false;
}
break;
case 's':
options.sort_key_filter_type = parse_filter_type(optarg, false);
if (options.sort_key_filter_type == pegasus::pegasus_client::FT_NO_FILTER) {
fprintf(stderr, "ERROR: invalid sort_key_filter_type param\n");
return false;
}
sort_key_filter_type_name = optarg;
break;
case 'y':
options.sort_key_filter_pattern = unescape_str(optarg);
break;
case 'v':
value_filter_type = parse_filter_type(optarg, true);
if (value_filter_type == pegasus::pegasus_client::FT_NO_FILTER) {
fprintf(stderr, "ERROR: invalid value_filter_type param\n");
return false;
}
value_filter_type_name = optarg;
break;
case 'z':
value_filter_pattern = unescape_str(optarg);
break;
case 'i':
options.no_value = true;
break;
default:
return false;
}
}
if (value_filter_type != pegasus::pegasus_client::FT_NO_FILTER && options.no_value) {
fprintf(stderr, "ERROR: no_value should not be set when value_filter_type is set\n");
return false;
}
fprintf(stderr, "hash_key: \"%s\"\n", pegasus::utils::c_escape_string(hash_key).c_str());
fprintf(stderr,
"start_sort_key: \"%s\"\n",
pegasus::utils::c_escape_string(start_sort_key).c_str());
fprintf(stderr, "start_inclusive: %s\n", options.start_inclusive ? "true" : "false");
fprintf(
stderr, "stop_sort_key: \"%s\"\n", pegasus::utils::c_escape_string(stop_sort_key).c_str());
fprintf(stderr, "stop_inclusive: %s\n", options.stop_inclusive ? "true" : "false");
fprintf(stderr, "sort_key_filter_type: %s\n", sort_key_filter_type_name.c_str());
if (options.sort_key_filter_type != pegasus::pegasus_client::FT_NO_FILTER) {
fprintf(stderr,
"sort_key_filter_pattern: \"%s\"\n",
pegasus::utils::c_escape_string(options.sort_key_filter_pattern).c_str());
}
fprintf(stderr, "value_filter_type: %s\n", value_filter_type_name.c_str());
if (value_filter_type != pegasus::pegasus_client::FT_NO_FILTER) {
fprintf(stderr,
"value_filter_pattern: \"%s\"\n",
pegasus::utils::c_escape_string(value_filter_pattern).c_str());
}
fprintf(stderr, "max_count: %d\n", max_count);
fprintf(stderr, "timout_ms: %d\n", timeout_ms);
fprintf(stderr, "detailed: %s\n", detailed ? "true" : "false");
fprintf(stderr, "no_value: %s\n", options.no_value ? "true" : "false");
fprintf(stderr, "\n");
int count = 0;
pegasus::pegasus_client::pegasus_scanner *scanner = nullptr;
options.timeout_ms = timeout_ms;
int ret = sc->pg_client->get_scanner(hash_key, start_sort_key, stop_sort_key, options, scanner);
if (ret != pegasus::PERR_OK) {
fprintf(file, "ERROR: get scanner failed: %s\n", sc->pg_client->get_error_string(ret));
if (file != stderr) {
fprintf(
stderr, "ERROR: get scanner failed: %s\n", sc->pg_client->get_error_string(ret));
}
} else {
std::string hash_key;
std::string sort_key;
std::string value;
pegasus::pegasus_client::internal_info info;
while ((max_count <= 0 || count < max_count) &&
!(ret = scanner->next(hash_key, sort_key, value, &info))) {
if (!validate_filter(value_filter_type, value_filter_pattern, value))
continue;
fprintf(file,
"\"%s\" : \"%s\"",
pegasus::utils::c_escape_string(hash_key, sc->escape_all).c_str(),
pegasus::utils::c_escape_string(sort_key, sc->escape_all).c_str());
if (!options.no_value) {
fprintf(file,
" => \"%s\"",
pegasus::utils::c_escape_string(value, sc->escape_all).c_str());
}
if (detailed) {
fprintf(file,
" {app_id=%d, partition_index=%d, server=%s}",
info.app_id,
info.partition_index,
info.server.c_str());
}
fprintf(file, "\n");
count++;
}
if (ret != pegasus::PERR_SCAN_COMPLETE && ret != pegasus::PERR_OK) {
fprintf(file,
"ERROR: %s {app_id=%d, partition_index=%d, server=%s}\n",
sc->pg_client->get_error_string(ret),
info.app_id,
info.partition_index,
info.server.c_str());
if (file != stderr) {
fprintf(stderr,
"ERROR: %s {app_id=%d, partition_index=%d, server=%s}\n",
sc->pg_client->get_error_string(ret),
info.app_id,
info.partition_index,
info.server.c_str());
}
}
}
if (scanner) {
delete scanner;
}
if (file != stderr) {
fclose(file);
}
if (file == stderr && count > 0) {
fprintf(stderr, "\n");
}
fprintf(stderr, "%d key-value pairs got.\n", count);
return true;
}