# HG changeset patch # User František Kučera # Date 1549395632 -3600 # Node ID 051e580227833cf7b1f319a574663fdd1994076c # Parent 82bd0f57a88993ab250028d2c9b5891cf37b7ebb add --input-attributes-append and --input-attributes-prepend for adding attributes using --output-attribute instead of replacing whole attribute list diff -r 82bd0f57a889 -r 051e58022783 src/CLIParser.h --- a/src/CLIParser.h Tue Feb 05 12:41:54 2019 +0100 +++ b/src/CLIParser.h Tue Feb 05 20:40:32 2019 +0100 @@ -58,6 +58,8 @@ static const string_t OPTION_RELATION; static const string_t OPTION_OUTPUT_ATTRIBUTE; + static const string_t OPTION_INPUT_ATTRIBUTES_APPEND; + static const string_t OPTION_INPUT_ATTRIBUTES_PREPEND; static const string_t OPTION_BEFORE_RECORDS; static const string_t OPTION_AFTER_RECORDS; static const string_t OPTION_FOR_EACH; @@ -78,6 +80,8 @@ else if (option == OPTION_FOR_EACH) currentRelation.guileForEach = readNext(arguments, i); else if (option == OPTION_WHERE) currentRelation.guileWhere = readNext(arguments, i); else if (option == OPTION_DROP) currentRelation.drop = true; + else if (option == OPTION_INPUT_ATTRIBUTES_APPEND) currentRelation.inputAttributesAppend = true; + else if (option == OPTION_INPUT_ATTRIBUTES_PREPEND) currentRelation.inputAttributesPrepend = true; else if (option == OPTION_RELATION) { addRelation(c, currentRelation); // previous relation currentRelation.relation = readNext(arguments, i); @@ -109,6 +113,8 @@ const string_t CLIParser::OPTION_RELATION = L"--relation"; const string_t CLIParser::OPTION_OUTPUT_ATTRIBUTE = L"--output-attribute"; +const string_t CLIParser::OPTION_INPUT_ATTRIBUTES_APPEND = L"--input-attributes-append"; +const string_t CLIParser::OPTION_INPUT_ATTRIBUTES_PREPEND = L"--input-attributes-prepend"; const string_t CLIParser::OPTION_BEFORE_RECORDS = L"--before-records"; const string_t CLIParser::OPTION_AFTER_RECORDS = L"--after-records"; const string_t CLIParser::OPTION_FOR_EACH = L"--for-each"; diff -r 82bd0f57a889 -r 051e58022783 src/Configuration.h --- a/src/Configuration.h Tue Feb 05 12:41:54 2019 +0100 +++ b/src/Configuration.h Tue Feb 05 20:40:32 2019 +0100 @@ -49,24 +49,38 @@ relpipe::writer::string_t guileAfterRecords; relpipe::writer::string_t guileForEach; relpipe::writer::string_t guileWhere; + /** * If true, Guile code will be executed, but no output will be generated. */ bool drop = false; + /** * Variable definitions for this relation. * Can be used as a safe way for passing parameters from the outside environment. * See also Configuration::definitions (can be overridden by relation's definitions) */ std::vector definitions; + /** * If empty, output relation will have same metadata as the input relation. */ std::vector writerMetadata; + + /** + * Whether original attributes should be appended to those specified using --output-attribute + */ + bool inputAttributesAppend = false; + + /** + * Whether original attributes should be prepended to those specified using --output-attribute + */ + bool inputAttributesPrepend = false; }; class Configuration { public: + vector relationConfigurations; /** * Global definitions for all relations. diff -r 82bd0f57a889 -r 051e58022783 src/GuileHandler.h --- a/src/GuileHandler.h Tue Feb 05 12:41:54 2019 +0100 +++ b/src/GuileHandler.h Tue Feb 05 20:40:32 2019 +0100 @@ -62,6 +62,14 @@ integer_t currentAttributeIndex = 0; boolean_t includeCurrentRecord = false; + void add(vector& readerAttributes, vector& writerAttributes) { + for (AttributeMetadata readerAttributes : readerAttributes) + writerAttributes.push_back({ + readerAttributes.getAttributeName(), + relationalWriter->toTypeId(readerAttributes.getTypeName()) + }); + } + /** * @param attributeName name from relational pipe * @return variable name in Guile @@ -206,9 +214,11 @@ // TODO: move to a reusable method (or use same metadata on both reader and writer side?) currentWriterMetadata.clear(); if (currentRelationConfiguration && currentRelationConfiguration->writerMetadata.size()) { - currentWriterMetadata = currentRelationConfiguration->writerMetadata; + if (currentRelationConfiguration->inputAttributesPrepend) add(currentReaderMetadata, currentWriterMetadata); + currentWriterMetadata.insert(currentWriterMetadata.end(), currentRelationConfiguration->writerMetadata.begin(), currentRelationConfiguration->writerMetadata.end()); + if (currentRelationConfiguration->inputAttributesAppend) add(currentReaderMetadata, currentWriterMetadata); } else { - for (AttributeMetadata readerMetadata : attributes) currentWriterMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())}); + add(currentReaderMetadata, currentWriterMetadata); } if (!currentRelationConfiguration || !currentRelationConfiguration->drop) relationalWriter->startRelation(name, currentWriterMetadata, true);