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) { |