add --type-cast to allow explicit specification of type for given output attributes
/**
* 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);
}
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_FILE;
static const string_t OPTION_FILE_KEEP;
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_FILE) {
c.file = readNext(arguments, i);
} else if (option == OPTION_FILE_KEEP) {
string_t value = readNext(arguments, i);
if (value == L"auto") c.keepFile = KeepFile::Automatic;
else if (value == L"true") c.keepFile = KeepFile::Always;
else if (value == L"false") c.keepFile = KeepFile::Never;
else throw relpipe::cli::RelpipeCLIException(L"Unsupported keep-file value: " + value + L" Expecting: true, false, auto", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
} else throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
}
addQuery(c, currentQuery); // last relation
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_FILE = L"--file";
const string_t CLIParser::OPTION_FILE_KEEP = L"--file-keep";
}
}
}