src/SedHandler.h
branchv_0
changeset 25 0cfbaf5c57a6
parent 19 9bac174d11b6
child 26 576d4965434f
equal deleted inserted replaced
24:82e40295dfb4 25:0cfbaf5c57a6
    32 
    32 
    33 #include <relpipe/writer/Factory.h>
    33 #include <relpipe/writer/Factory.h>
    34 
    34 
    35 #include <relpipe/cli/RelpipeCLIException.h>
    35 #include <relpipe/cli/RelpipeCLIException.h>
    36 
    36 
       
    37 #include "Configuration.h"
       
    38 
    37 namespace relpipe {
    39 namespace relpipe {
    38 namespace tr {
    40 namespace tr {
    39 namespace sed {
    41 namespace sed {
    40 
    42 
    41 using namespace std;
    43 using namespace std;
    44 using namespace relpipe::reader::handlers;
    46 using namespace relpipe::reader::handlers;
    45 
    47 
    46 class SedHandler : public RelationalReaderStringHandler {
    48 class SedHandler : public RelationalReaderStringHandler {
    47 private:
    49 private:
    48 	shared_ptr<writer::RelationalWriter> relationalWriter;
    50 	shared_ptr<writer::RelationalWriter> relationalWriter;
       
    51 	Configuration configuration;
       
    52 	RelationConfiguration* currentFilter = nullptr;
    49 
    53 
    50 	wregex relationNameRegEx;
    54 	std::vector<std::vector<RewriteRule*>> currentRules;
    51 	wregex attributeNameRegEx;
       
    52 	wregex searchRegEx;
       
    53 	string_t replacement;
       
    54 
       
    55 	vector<boolean_t> currentReplacableAttributes;
       
    56 	integer_t currentAttributeIndex = 0;
    55 	integer_t currentAttributeIndex = 0;
    57 
    56 
    58 public:
    57 public:
    59 
    58 
    60 	SedHandler(ostream& output, const vector<string_t>& arguments) {
    59 	SedHandler(shared_ptr<writer::RelationalWriter> relationalWriter, Configuration configuration) : relationalWriter(relationalWriter), configuration(configuration) {
    61 		relationalWriter.reset(writer::Factory::create(output));
       
    62 
       
    63 		if (arguments.size() == 4) {
       
    64 			relationNameRegEx = wregex(arguments[0]);
       
    65 			attributeNameRegEx = wregex(arguments[1]);
       
    66 			searchRegEx = wregex(arguments[2]);
       
    67 			replacement = arguments[3];
       
    68 		} else {
       
    69 			throw cli::RelpipeCLIException(L"Usage: relpipe-tr-sed <relationNameRegExp> <attributeNameRegExp> <searchRegExp> <replacement>", cli::CLI::EXIT_CODE_UNKNOWN_COMMAND);
       
    70 		}
       
    71 	}
    60 	}
    72 
    61 
    73 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
    62 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
    74 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
    63 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
    75 		vector<writer::AttributeMetadata> writerMetadata;
    64 		vector<writer::AttributeMetadata> writerMetadata;
    76 		for (AttributeMetadata readerMetadata : attributes) {
    65 		for (AttributeMetadata readerMetadata : attributes) {
    77 			writerMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())});
    66 			writerMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())});
    78 		}
    67 		}
    79 
    68 
    80 
    69 
    81 		currentReplacableAttributes.resize(attributes.size(), false);
    70 		currentRules.resize(attributes.size());
    82 		if (regex_match(name, relationNameRegEx)) {
    71 		for (RelationConfiguration& rc : configuration.relationConfigurations) {
    83 			for (int i = 0; i < currentReplacableAttributes.size(); i++) {
    72 			if (std::regex_match(name, rc.relationPattern) ^ rc.invertMatch[ENTITY::RELATION]) {
    84 				currentReplacableAttributes[i] = regex_match(attributes[i].getAttributeName(), attributeNameRegEx);
    73 				for (int i = 0; i < currentRules.size(); i++) {
       
    74 					for (RewriteRule& rule : rc.rules) {
       
    75 						if (std::regex_match(attributes[i].getAttributeName(), rule.attributePattern) ^ rule.invertMatch[ENTITY::ATTRIBUTE]) currentRules[i].push_back(&rule);
       
    76 					}
       
    77 				}
    85 			}
    78 			}
    86 		}
    79 		}
    87 
    80 
    88 		relationalWriter->startRelation(name, writerMetadata, true);
    81 		relationalWriter->startRelation(name, writerMetadata, true);
    89 	}
    82 	}
    90 
    83 
    91 	void attribute(const string_t& value) override {
    84 	void attribute(const string_t& value) override {
    92 		if (currentReplacableAttributes[currentAttributeIndex]) {
    85 		string_t newValue = value;
    93 			relationalWriter->writeAttribute(regex_replace(value, searchRegEx, replacement));
    86 
    94 		} else {
    87 		for (RewriteRule* rule : currentRules[currentAttributeIndex]) {
    95 			relationalWriter->writeAttribute(value);
    88 			if (rule) newValue = std::regex_replace(value, rule->valuePattern, rule->replacement);
    96 		}
    89 		}
    97 
    90 
       
    91 		relationalWriter->writeAttribute(newValue);
       
    92 
    98 		currentAttributeIndex++;
    93 		currentAttributeIndex++;
    99 		currentAttributeIndex = currentAttributeIndex % currentReplacableAttributes.size();
    94 		currentAttributeIndex = currentAttributeIndex % currentRules.size();
   100 	}
    95 	}
   101 
    96 
   102 	void endOfPipe() {
    97 	void endOfPipe() {
   103 
    98 
   104 	}
    99 	}