| 39 | } |
| 40 | |
| 41 | int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPosition) const |
| 42 | { |
| 43 | // TODO: add some semantic checks, not all operators apply to all fields |
| 44 | if (t == "expression") { |
| 45 | ++bindPosition; |
| 46 | if (toLower(children[0].t) == "all") { |
| 47 | sqlString += "("; |
| 48 | for (const auto &field : fieldNames.at(FieldType::text)) { |
| 49 | sqlString += "UPPER(ci." + field + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ") OR "; |
| 50 | } |
| 51 | sqlString += "UPPER(c.filename) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ") OR "; |
| 52 | sqlString += "UPPER(f.name) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; |
| 53 | } else if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::date })) { |
| 54 | sqlString += "ci." + children[0].t + " " + operatorToSQLOperator(expOperator) + " :bindPosition" + std::to_string(bindPosition) + " "; |
| 55 | } else if (isIn(fieldType(children[0].t), { FieldType::dateFolder })) { |
| 56 | sqlString += "f." + children[0].t + " " + operatorToSQLOperator(expOperator) + " :bindPosition" + std::to_string(bindPosition) + " "; |
| 57 | } else if (isIn(fieldType(children[0].t), { FieldType::boolean, FieldType::enumField })) { |
| 58 | sqlString += "ci." + children[0].t + " = :bindPosition" + std::to_string(bindPosition) + " "; |
| 59 | } else if (fieldType(children[0].t) == FieldType::filename) { |
| 60 | sqlString += "(UPPER(c." + children[0].t + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; |
| 61 | } else if (fieldType(children[0].t) == FieldType::folder) { |
| 62 | sqlString += "(UPPER(f.name) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; |
| 63 | } else if (fieldType(children[0].t) == FieldType::booleanFolder) { |
| 64 | sqlString += "f." + children[0].t + " = :bindPosition" + std::to_string(bindPosition) + " "; |
| 65 | } else if (fieldType(children[0].t) == FieldType::enumFieldFolder) { |
| 66 | if (children[0].t == "foldertype") { |
| 67 | sqlString += "f.type = :bindPosition" + std::to_string(bindPosition) + " "; |
| 68 | } else { |
| 69 | sqlString += "f." + children[0].t + " = :bindPosition" + std::to_string(bindPosition) + " "; |
| 70 | } |
| 71 | } else { |
| 72 | if (expOperator == "=" || expOperator == ":" || expOperator == "") { |
| 73 | sqlString += "(UPPER(ci." + children[0].t + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; |
| 74 | } else { |
| 75 | if (expOperator == "==") { |
| 76 | sqlString += "(UPPER(ci." + children[0].t + ") = UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; |
| 77 | } else { |
| 78 | // support for <,>,<=,>= in text fields makes sense for number, arcNumber, alternateNumber, but (TODO) the syntax won't prevent other fields from using this operators |
| 79 | sqlString += "(CAST(ci." + children[0].t + " as REAL) " + expOperator + " CAST(:bindPosition" + std::to_string(bindPosition) + " as REAL)) "; |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | } else if (t == "not") { |
| 84 | sqlString += "(NOT "; |
| 85 | bindPosition = children[0].buildSqlString(sqlString, bindPosition); |
| 86 | sqlString += ")"; |
| 87 | } else { |
| 88 | sqlString += "("; |
| 89 | bindPosition = children[0].buildSqlString(sqlString, bindPosition); |
| 90 | sqlString += " " + t + " "; |
| 91 | bindPosition = children[1].buildSqlString(sqlString, bindPosition); |
| 92 | sqlString += ")"; |
| 93 | } |
| 94 | |
| 95 | return bindPosition; |
| 96 | } |
| 97 | |
| 98 | int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) const |
no test coverage detected