diff -r 09cd32a65709 -r 3c8ea5dcf793 src/StdInCommand.h --- a/src/StdInCommand.h Tue Sep 22 17:42:19 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/** - * Relational pipes - * Copyright © 2018 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 of the License. - * - * 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 . - */ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "Command.h" - -namespace relpipe { -namespace in { -namespace cli { - -/** - * TODO: consider code merge with ArgumentsCommand - */ -class StdInCommand : public Command { -private: - relpipe::writer::boolean_t readStdIn; - std::wstring_convert> convertor; // TODO: support also other encodings. - - /** - * Reads next value from arguments and (if no arguments left) from input - * @param input - * @param arguments - * @param i current index in the arguments vector - * @param required if true, exception is thrown when no data found - * @return - */ - relpipe::writer::string_t readNext(std::istream& input, const std::vector& arguments, size_t& i, relpipe::writer::boolean_t required) { - using namespace relpipe::writer; - using namespace relpipe::cli; - - if (i < arguments.size()) { - return arguments[i++]; - } else if (readStdIn) { - std::stringstream value; - - while (true) { - char ch; - input.get(ch); - if (ch == 0 || input.eof() || input.fail()) break; - else value << ch; - } - - if (required && value.str().empty()) throw RelpipeCLIException(L"Missing value on STDIN.", CLI::EXIT_CODE_BAD_SYNTAX); - - return convertor.from_bytes(value.str()); - } else { - if (required) throw RelpipeCLIException(L"Missing value on CLI.", CLI::EXIT_CODE_BAD_SYNTAX); - return L""; - } - } - - -public: - - StdInCommand(relpipe::writer::boolean_t readStdIn) : - readStdIn(readStdIn) { - } - - void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector& arguments) override { - using namespace relpipe::writer; - - size_t i = 0; - string_t relationName = readNext(input, arguments, i, true); - integer_t attributeCount = std::stol(readNext(input, arguments, i, true)); // TODO: use integer data type's method? + unsigned type - boolean_t writeHeader = true; // TODO: add option for header omitting - - std::shared_ptr writer(Factory::create(output)); - - std::vector attributes(attributeCount); - - for (size_t j = 0; j < attributeCount; j++) { - string_t attributeName = readNext(input, arguments, i, true); - TypeId attributeType = writer->toTypeId(readNext(input, arguments, i, true)); - attributes[j] = {attributeName, attributeType}; - } - - writer->startRelation(relationName, attributes, writeHeader); - - while (true) { - string_t value = readNext(input, arguments, i, false); - if (value.empty() && (input.eof() || input.fail() || (!readStdIn && i >= arguments.size()))) break; - else writer->writeAttribute(value); - // TODO: check attribute count (avoid unfinished records) - } - } -}; - -} -} -}