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 } |