From 3fb930ef53d510dd73d3d042ed35520ed854aba5 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Wed, 5 Mar 2014 19:26:43 +0400 Subject: [PATCH] client: support external tables descriptions in command line arguments [METR-10071] --- dbms/src/Client/Client.cpp | 131 +++++++++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 7 deletions(-) diff --git a/dbms/src/Client/Client.cpp b/dbms/src/Client/Client.cpp index 8b054b0dc45..f6609eb3360 100644 --- a/dbms/src/Client/Client.cpp +++ b/dbms/src/Client/Client.cpp @@ -58,6 +58,93 @@ namespace DB using Poco::SharedPtr; +class ExternalTable +{ +public: + std::string file; + std::string name; + std::string format; + std::vector > structure; + + void write() + { + std::cerr << "file " << file << std::endl; + std::cerr << "name " << name << std::endl; + std::cerr << "format " << format << std::endl; + std::cerr << "structure: \n"; + for (size_t i = 0; i < structure.size(); ++i) + std::cerr << "\t" << structure[i].first << " " << structure[i].second << std::endl; + } + + ExternalTable(const boost::program_options::variables_map & external_options) + { + if (external_options.count("file")) + file = external_options["file"].as(); + else + throw Exception("File field have not been provided for external table", ErrorCodes::BAD_ARGUMENTS); + + if (external_options.count("name")) + name = external_options["name"].as(); + else + throw Exception("Name field have not been provided for external table", ErrorCodes::BAD_ARGUMENTS); + + if (external_options.count("format")) + format = external_options["format"].as(); + else + throw Exception("format field have not been provided for external table", ErrorCodes::BAD_ARGUMENTS); + + if (external_options.count("structure")) + { + std::vector temp = external_options["structure"].as>(); + + std::string argument; + for (size_t i = 0; i < temp.size(); ++i) + argument = argument + temp[i] + " "; + std::vector vals = split(argument, " ,"); + + if (vals.size() & 1) + throw Exception("Odd number of attributes in section structure", ErrorCodes::BAD_ARGUMENTS); + + for (size_t i = 0; i < vals.size(); i += 2) + structure.push_back(std::make_pair(vals[i], vals[i+1])); + } + else if (external_options.count("types")) + { + std::vector temp = external_options["types"].as>(); + std::string argument; + for (size_t i = 0; i < temp.size(); ++i) + argument = argument + temp[i] + " "; + std::vector vals = split(argument, " ,"); + + for (size_t i = 0; i < vals.size(); ++i) + structure.push_back(std::make_pair("_" + toString(i + 1), vals[i])); + } + else + throw Exception("Neither structure nor types have not been provided for external table", ErrorCodes::BAD_ARGUMENTS); + } + + static std::vector split(const std::string & s, const std::string &d) + { + std::vector res; + std::string now; + for (size_t i = 0; i < s.size(); ++i) + { + if (d.find(s[i]) != std::string::npos) + { + if (!now.empty()) + res.push_back(now); + now = ""; + continue; + } + now += s[i]; + } + if (!now.empty()) + res.push_back(now); + return res; + } +}; + + class Client : public Poco::Util::Application { public: @@ -795,12 +882,13 @@ private: public: void init(int argc, char ** argv) { + /// Останавливаем внутреннюю обработку командной строки stopOptionsProcessing(); - /// Перечисляем опции командной строки - boost::program_options::options_description desc("Allowed options"); - desc.add_options() + /// Перечисляем основные опции командной строки относящиеся к функциональности клиента + boost::program_options::options_description main_description("Main options"); + main_description.add_options() ("config-file,c", boost::program_options::value (), "config-file") ("host,h", boost::program_options::value ()->default_value("localhost"), "host") ("port,p", boost::program_options::value ()->default_value(9000), "port") @@ -811,11 +899,40 @@ public: ("multiline,m", "multiline") ; - /// Парсим командную строку - boost::program_options::variables_map options; - boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), options); + /// Перечисляем опции командной строки относящиеся к внешним таблицам + boost::program_options::options_description external_description("Main options"); + external_description.add_options() + ("file", boost::program_options::value (), "data file or - for stdin") + ("name", boost::program_options::value ()->default_value("_data"), "name of the table") + ("format", boost::program_options::value ()->default_value("TabSeparated"), "data format") + ("structure", boost::program_options::value> ()->multitoken(), "structure") + ("types", boost::program_options::value> ()->multitoken(), "types") + ; - /// Сохраняем полученные значение во внутренний конфиг + std::vector positions; + + positions.push_back(0); + for (int i = 0; i < argc; ++i) + if (std::string(argv[i]) == "--external") + positions.push_back(i); + positions.push_back(argc); + + /// Парсим основные опции командной строки + boost::program_options::variables_map options; + boost::program_options::store(boost::program_options::parse_command_line(positions[1] - positions[0], argv, main_description), options); + + std::vector external_tables; + + for (size_t i = 1; i + 1 < positions.size(); ++i) + { + boost::program_options::variables_map external_options; + boost::program_options::store(boost::program_options::parse_command_line( + positions[i+1] - positions[i], &argv[positions[i]], external_description), external_options); + external_tables.push_back(ExternalTable(external_options)); +// external_tables.back().write(); + } + + /// Сохраняем полученные данные во внутренний конфиг if (options.count("config-file")) config().setString("config-file", options["config-file"].as()); if (options.count("host"))