46 vtkInformationVector **inputVector,
47 vtkInformationVector *outputVector) {
51 auto outTable = vtkTable::GetData(outputVector);
55 auto nTables = inputVector[0]->GetNumberOfInformationObjects();
57 this->
printErr(
"No input vtkTable found");
61 std::vector<vtkTable *> inTables(nTables);
62 for(
int i = 0; i < nTables; ++i) {
63 inTables[i] = vtkTable::GetData(inputVector[0], i);
66 auto firstTable = inTables[0];
68 std::vector<std::string> sqlTableDefinitions;
69 std::vector<std::string> sqlInsertStatements;
73 for(
int i = 0; i < nTables; i++) {
74 auto inTable = inTables[i];
76 size_t const nc = inTable->GetNumberOfColumns();
77 size_t const nr = inTable->GetNumberOfRows();
78 std::vector<bool> isNumeric(nc);
80 std::vector<size_t> includeColumns(nc);
81 std::iota(includeColumns.begin(), includeColumns.end(), 0);
84 if(this->ExcludeColumnsWithRegexp) {
85 const auto oldSize{includeColumns.size()};
87 std::remove_if(includeColumns.begin(), includeColumns.end(),
88 [inTable,
this](
const size_t a) {
89 const auto name{inTable->GetColumnName(a)};
90 return std::regex_match(
91 name, std::regex(this->RegexpString));
93 includeColumns.end());
94 if(includeColumns.size() < oldSize) {
96 + std::to_string(oldSize - includeColumns.size())
97 +
" columns with regexp `" + this->RegexpString +
"'");
103 const auto oldSize{includeColumns.size()};
104 includeColumns.erase(
105 std::remove_if(includeColumns.begin(), includeColumns.end(),
106 [inTable](
const size_t a) {
107 const auto col{inTable->GetColumn(a)};
108 return col->GetNumberOfComponents() != 1;
110 includeColumns.end());
111 if(includeColumns.size() < oldSize) {
113 + std::to_string(oldSize - includeColumns.size())
114 +
" non-scalar columns");
120 const auto oldSize{includeColumns.size()};
121 includeColumns.erase(
122 std::remove_if(includeColumns.begin(), includeColumns.end(),
123 [inTable](
const size_t a) {
124 const std::string colName{inTable->GetColumnName(a)};
125 return colName.find(
' ') != std::string::npos;
127 includeColumns.end());
128 if(includeColumns.size() < oldSize) {
130 + std::to_string(oldSize - includeColumns.size())
131 +
" columns with a space in their name");
135 if(includeColumns.empty()) {
136 this->printWrn(
"No columns to process!");
142 std::string sqlTableDefinition
143 =
"CREATE TABLE InputTable" + std::to_string(i) +
" (";
145 for(
const auto j : includeColumns) {
146 auto c = inTable->GetColumn(j);
147 isNumeric[j] = c->IsNumeric();
148 sqlTableDefinition += (firstCol ?
"" :
",") + std::string(c->GetName())
149 +
" " + (isNumeric[j] ?
"REAL" :
"TEXT");
154 sqlTableDefinition +=
")";
155 sqlTableDefinitions.emplace_back(sqlTableDefinition);
161 std::string sqlInsertStatement
162 =
"INSERT INTO InputTable" + std::to_string(i) +
" VALUES ";
163 for(
size_t j = 0; j < 500 && q < nr; j++) {
165 sqlInsertStatement +=
",";
167 sqlInsertStatement +=
"(";
169 for(
const auto k : includeColumns) {
170 sqlInsertStatement += (firstCol ?
"" :
",");
175 const auto var = inTable->GetValue(q, k);
176 if(
var.IsChar() ||
var.IsSignedChar()) {
179 sqlInsertStatement += std::to_string(
var.ToInt());
180 }
else if(std::isnan(
var.ToDouble())) {
181 sqlInsertStatement +=
"'NaN'";
183 sqlInsertStatement +=
var.ToString();
187 +=
"'" + inTable->GetValue(q, k).ToString() +
"'";
190 sqlInsertStatement +=
")";
193 sqlInsertStatements.emplace_back(sqlInsertStatement);
197 this->
printMsg(
"Converting input VTK tables to SQL tables", 1,
198 conversionTimer.getElapsedTime());
203 std::string finalQueryString;
205 std::string errorMsg;
207 firstTable->GetFieldData(), finalQueryString,
209 this->printErr(errorMsg);
216 std::stringstream csvResult;
221 = this->execute(sqlTableDefinitions, sqlInsertStatements, finalQueryString,
222 csvResult, csvNColumns, csvNRows);
227 if(csvNRows < 1 || status != 1) {
229 for(
int i = 0; i < csvNColumns; i++)
230 csvResult <<
",NULL";
239 reader->SetReadFromInputString(
true);
240 reader->SetInputString(csvResult.str().data());
241 reader->DetectNumericColumnsOn();
242 reader->SetHaveHeaders(
true);
243 reader->SetFieldDelimiterCharacters(
",");
246 outTable->ShallowCopy(reader->GetOutput());
248 auto outFD = outTable->GetFieldData();
249 for(
const auto inTable : inTables) {
252 auto inFD = inTable->GetFieldData();
254 size_t const n = inFD->GetNumberOfArrays();
255 for(
size_t i = 0; i < n; i++) {
256 auto iArray = inFD->GetAbstractArray(i);
257 if(!outFD->GetAbstractArray(iArray->GetName())) {
258 outFD->AddArray(iArray);
263 this->
printMsg(
"Converting SQL result to VTK table", 1,
269 this->
printMsg(
"Complete (#rows: " + std::to_string(csvNRows) +
")", 1,
270 timer.getElapsedTime());