add boolean parameter to --list-data-sources + allow listing and SELECTing at the same time
/**
* Relational pipes
* Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vector>
#include <relpipe/writer/typedefs.h>
#include <relpipe/cli/CLI.h>
#include <relpipe/cli/RelpipeCLIException.h>
#include "Configuration.h"
namespace relpipe {
namespace tr {
namespace sql {
class CLIParser {
private:
// FIXME: move common methods/classes to relpipe-lib-cli or relpipe-lib-helper
string_t readNext(std::vector<string_t> arguments, int& i) {
if (i < arguments.size()) return arguments[i++];
else throw relpipe::cli::RelpipeCLIException(L"Missing CLI argument" + (i > 0 ? (L" after " + arguments[i - 1]) : L""), relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
}
/**
* TODO: use a common method
*/
bool parseBoolean(const string_t& value) {
if (value == L"true") return true;
else if (value == L"false") return false;
else throw relpipe::cli::RelpipeCLIException(L"Unable to parse boolean value: " + value + L" (expecting true or false)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
}
void addQuery(Configuration& c, Statement& currentQuery) {
if (currentQuery.sql.size()) {
c.statements.push_back(currentQuery);
currentQuery = Statement();
}
}
public:
static const string_t OPTION_RELATION;
static const string_t OPTION_TYPE_CAST;
static const string_t OPTION_PARAMETER;
static const string_t OPTION_COPY;
static const string_t OPTION_COPY_RENAMED;
static const string_t OPTION_DATA_SOURCE_NAME;
static const string_t OPTION_DATA_SOURCE_STRING;
static const string_t OPTION_LIST_DATA_SOURCES;
Configuration parse(const std::vector<string_t>& arguments) {
Configuration c;
Statement currentQuery;
for (int i = 0; i < arguments.size();) {
string_t option = readNext(arguments, i);
if (option == OPTION_RELATION) {
addQuery(c, currentQuery); // previous relation
currentQuery.relation = readNext(arguments, i);
currentQuery.sql = readNext(arguments, i);
} else if (option == OPTION_TYPE_CAST) {
TypeCast typeCast;
typeCast.name = readNext(arguments, i);
typeCast.type = readNext(arguments, i);
currentQuery.typeCasts.push_back(typeCast);
} else if (option == OPTION_PARAMETER) {
Parameter parameter;
parameter.value = readNext(arguments, i);
currentQuery.parameters.push_back(parameter);
} else if (option == OPTION_COPY) {
c.copyRelations.push_back({readNext(arguments, i), L"", false});
} else if (option == OPTION_COPY_RENAMED) {
c.copyRelations.push_back({readNext(arguments, i), readNext(arguments, i), true});
} else if (option == OPTION_DATA_SOURCE_NAME) {
c.dataSourceName = readNext(arguments, i);
} else if (option == OPTION_DATA_SOURCE_STRING) {
c.dataSourceString = readNext(arguments, i);
} else if (option == OPTION_LIST_DATA_SOURCES) {
c.listDataSources = parseBoolean(readNext(arguments, i));
} else throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
}
addQuery(c, currentQuery); // last relation
if (c.dataSourceName.size() && c.dataSourceString.size()) throw relpipe::cli::RelpipeCLIException(L"Specify data source name or data source string, not both.", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
return c;
}
virtual ~CLIParser() {
}
};
// relpipe-tr-sql --relation "tabulka" "SELECT * FROM fstab WHERE id = ?" --parameter "123"
// TODO: --type string/integer/boolean (default is string)
const string_t CLIParser::OPTION_RELATION = L"--relation";
const string_t CLIParser::OPTION_TYPE_CAST = L"--type-cast";
const string_t CLIParser::OPTION_PARAMETER = L"--parameter";
const string_t CLIParser::OPTION_COPY = L"--copy";
const string_t CLIParser::OPTION_COPY_RENAMED = L"--copy-renamed";
const string_t CLIParser::OPTION_LIST_DATA_SOURCES = L"--list-data-sources";
const string_t CLIParser::OPTION_DATA_SOURCE_NAME = L"--data-source-name";
const string_t CLIParser::OPTION_DATA_SOURCE_STRING = L"--data-source-string";
}
}
}