src/GrepHandler.h
branchv_0
changeset 24 c69670b7b4ef
parent 18 5a3602fb1649
child 25 98be80d2e65b
equal deleted inserted replaced
23:87d22d525a3e 24:c69670b7b4ef
    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 grep {
    41 namespace grep {
    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 GrepHandler : public RelationalReaderStringHandler {
    48 class GrepHandler : public RelationalReaderStringHandler {
    47 private:
    49 private:
    48 	shared_ptr<writer::RelationalWriter> relationalWriter;
    50 	shared_ptr<writer::RelationalWriter> relationalWriter;
    49 
    51 	Configuration configuration;
    50 	wregex relationNameRegEx;
    52 	RelationConfiguration* currentFilter = nullptr;
    51 	wregex attributeNameRegEx;
       
    52 	wregex searchRegEx;
       
    53 
    53 
    54 	vector<boolean_t> currentSearchableAttributes;
    54 	vector<boolean_t> currentSearchableAttributes;
    55 	vector<string_t> currentRecord;
    55 	vector<string_t> currentRecord;
    56 	integer_t currentAttributeIndex = 0;
    56 	integer_t currentAttributeIndex = 0;
    57 	boolean_t includeCurrentRecord = false;
    57 	boolean_t includeCurrentRecord = false;
    58 	boolean_t filterCurrentRelation = false;
       
    59 
    58 
    60 public:
    59 public:
    61 
    60 
    62 	GrepHandler(ostream& output, const vector<string_t>& arguments) {
    61 	GrepHandler(shared_ptr<writer::RelationalWriter> relationalWriter, Configuration configuration) : relationalWriter(relationalWriter), configuration(configuration) {
    63 		relationalWriter.reset(writer::Factory::create(output));
       
    64 
       
    65 		if (arguments.size() == 3) {
       
    66 			relationNameRegEx = wregex(arguments[0]);
       
    67 			attributeNameRegEx = wregex(arguments[1]);
       
    68 			searchRegEx = wregex(arguments[2]);
       
    69 		} else {
       
    70 			throw cli::RelpipeCLIException(L"Usage: relpipe-tr-grep <relationNameRegExp> <attributeNameRegExp> <searchRegExp>", cli::CLI::EXIT_CODE_UNKNOWN_COMMAND);
       
    71 		}
       
    72 	}
    62 	}
    73 
    63 
    74 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
    64 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
    75 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
    65 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
    76 		vector<writer::AttributeMetadata> writerMetadata;
    66 		vector<writer::AttributeMetadata> writerMetadata;
    79 		}
    69 		}
    80 
    70 
    81 
    71 
    82 		currentRecord.resize(attributes.size());
    72 		currentRecord.resize(attributes.size());
    83 		currentSearchableAttributes.resize(attributes.size(), false);
    73 		currentSearchableAttributes.resize(attributes.size(), false);
    84 		filterCurrentRelation = regex_match(name, relationNameRegEx);
    74 		currentFilter = nullptr;
    85 		if (filterCurrentRelation) {
    75 		for (int i = 0; i < configuration.relationConfigurations.size(); i++) {
       
    76 			if (regex_match(name, configuration.relationConfigurations[i].relationPattern)) {
       
    77 				currentFilter = &configuration.relationConfigurations[i];
       
    78 				break;
       
    79 			}
       
    80 		}
       
    81 
       
    82 		if (currentFilter) {
    86 			for (int i = 0; i < currentSearchableAttributes.size(); i++) {
    83 			for (int i = 0; i < currentSearchableAttributes.size(); i++) {
    87 				currentSearchableAttributes[i] = regex_match(attributes[i].getAttributeName(), attributeNameRegEx);
    84 				currentSearchableAttributes[i] = regex_match(attributes[i].getAttributeName(), currentFilter->attributePattern);
    88 			}
    85 			}
    89 		}
    86 		}
    90 
    87 
    91 		relationalWriter->startRelation(name, writerMetadata, true);
    88 		relationalWriter->startRelation(name, writerMetadata, true);
    92 	}
    89 	}
    93 
    90 
    94 	void attribute(const string_t& value) override {
    91 	void attribute(const string_t& value) override {
    95 		if (filterCurrentRelation) {
    92 		if (currentFilter) {
    96 			currentRecord[currentAttributeIndex] = value;
    93 			currentRecord[currentAttributeIndex] = value;
    97 
    94 
    98 			if (currentSearchableAttributes[currentAttributeIndex]) {
    95 			if (currentSearchableAttributes[currentAttributeIndex]) {
    99 				includeCurrentRecord |= regex_search(value, searchRegEx);
    96 				includeCurrentRecord |= regex_search(value, currentFilter->valuePattern);
   100 			}
    97 			}
   101 
    98 
   102 			currentAttributeIndex++;
    99 			currentAttributeIndex++;
   103 
   100 
   104 			if (currentAttributeIndex > 0 && currentAttributeIndex % currentSearchableAttributes.size() == 0) {
   101 			if (currentAttributeIndex > 0 && currentAttributeIndex % currentSearchableAttributes.size() == 0) {