src/GrepHandler.h
branchv_0
changeset 8 f66c759d1111
parent 7 aebaf590a838
equal deleted inserted replaced
7:aebaf590a838 8:f66c759d1111
    31 #include <relpipe/reader/handlers/RelationalReaderStringHandler.h>
    31 #include <relpipe/reader/handlers/RelationalReaderStringHandler.h>
    32 #include <relpipe/reader/handlers/AttributeMetadata.h>
    32 #include <relpipe/reader/handlers/AttributeMetadata.h>
    33 
    33 
    34 #include <relpipe/writer/Factory.h>
    34 #include <relpipe/writer/Factory.h>
    35 
    35 
       
    36 #include <relpipe/cli/RelpipeCLIException.h>
       
    37 
    36 namespace relpipe {
    38 namespace relpipe {
    37 namespace tr {
    39 namespace tr {
    38 namespace grep {
    40 namespace grep {
    39 
    41 
       
    42 using namespace std;
    40 using namespace relpipe;
    43 using namespace relpipe;
    41 using namespace relpipe::reader;
    44 using namespace relpipe::reader;
    42 using namespace relpipe::reader::handlers;
    45 using namespace relpipe::reader::handlers;
    43 
    46 
    44 class GrepHandler : public RelationalReaderStringHadler {
    47 class GrepHandler : public RelationalReaderStringHadler {
    45 private:
    48 private:
    46 	std::shared_ptr<writer::RelationalWriter> relationalWriter;
    49 	shared_ptr<writer::RelationalWriter> relationalWriter;
       
    50 
       
    51 	wregex relationNameRegEx;
       
    52 	wregex attributeNameRegEx;
       
    53 	wregex searchRegEx;
       
    54 
       
    55 	vector<boolean_t> currentSearchableAttributes;
       
    56 	vector<string_t> currentRecord;
       
    57 	integer_t currentAttributeIndex = 0;
       
    58 	boolean_t includeCurrentRecord = false;
       
    59 	boolean_t filterCurrentRelation = false;
       
    60 
    47 public:
    61 public:
    48 
    62 
    49 	GrepHandler(std::ostream& output) {
    63 	GrepHandler(ostream& output, const vector<string_t>& arguments) {
    50 		relationalWriter.reset(writer::Factory::create(output));
    64 		relationalWriter.reset(writer::Factory::create(output));
       
    65 
       
    66 		if (arguments.size() == 3) {
       
    67 			relationNameRegEx = wregex(arguments[0]);
       
    68 			attributeNameRegEx = wregex(arguments[1]);
       
    69 			searchRegEx = wregex(arguments[2]);
       
    70 		} else {
       
    71 			throw cli::RelpipeCLIException(L"Usage: relpipe-tr-grep <relationNameRegExp> <attributeNameRegExp> <searchRegExp>", cli::CLI::EXIT_CODE_UNKNOWN_COMMAND);
       
    72 		}
    51 	}
    73 	}
    52 
    74 
    53 	void startRelation(string_t name, std::vector<AttributeMetadata> attributes) override {
    75 	void startRelation(string_t name, vector<AttributeMetadata> attributes) override {
    54 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
    76 		// TODO: move to a reusable method (or use same metadata on both reader and writer side?)
    55 		std::vector<writer::AttributeMetadata> writerMetadata;
    77 		vector<writer::AttributeMetadata> writerMetadata;
    56 		for (AttributeMetadata readerMetadata : attributes) {
    78 		for (AttributeMetadata readerMetadata : attributes) {
    57 			writerMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())});
    79 			writerMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())});
    58 		}
    80 		}
    59 		
    81 
       
    82 
       
    83 		currentRecord.resize(attributes.size());
       
    84 		currentSearchableAttributes.resize(attributes.size(), false);
       
    85 		filterCurrentRelation = regex_match(name, relationNameRegEx);
       
    86 		if (filterCurrentRelation) {
       
    87 			for (int i = 0; i < currentSearchableAttributes.size(); i++) {
       
    88 				currentSearchableAttributes[i] = regex_match(attributes[i].getAttributeName(), attributeNameRegEx);
       
    89 			}
       
    90 		}
       
    91 
    60 		relationalWriter->startRelation(name, writerMetadata, true);
    92 		relationalWriter->startRelation(name, writerMetadata, true);
    61 	}
    93 	}
    62 
    94 
    63 	void attribute(const string_t& value) override {
    95 	void attribute(const string_t& value) override {
    64 		relationalWriter->writeAttribute(value);
    96 		if (filterCurrentRelation) {
       
    97 			currentRecord[currentAttributeIndex] = value;
       
    98 
       
    99 			if (currentSearchableAttributes[currentAttributeIndex]) {
       
   100 				includeCurrentRecord |= regex_search(value, searchRegEx);
       
   101 			}
       
   102 
       
   103 			currentAttributeIndex++;
       
   104 
       
   105 			if (currentAttributeIndex > 0 && currentAttributeIndex % currentSearchableAttributes.size() == 0) {
       
   106 				if (includeCurrentRecord) for (string_t v : currentRecord) relationalWriter->writeAttribute(v);
       
   107 				includeCurrentRecord = false;
       
   108 			}
       
   109 
       
   110 			currentAttributeIndex = currentAttributeIndex % currentSearchableAttributes.size();
       
   111 		} else {
       
   112 			relationalWriter->writeAttribute(value);
       
   113 		}
    65 	}
   114 	}
    66 
   115 
    67 	void endOfPipe() {
   116 	void endOfPipe() {
    68 
   117 
    69 	}
   118 	}