Mercurial > hg > orthanc
diff OrthancServer/SQLiteDatabaseWrapper.cpp @ 3031:18a2d196414b db-changes
simplification
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 19 Dec 2018 13:08:04 +0100 |
parents | 25afa7b8cb51 |
children | 5da6d1063d8f |
line wrap: on
line diff
--- a/OrthancServer/SQLiteDatabaseWrapper.cpp Wed Dec 19 11:18:39 2018 +0100 +++ b/OrthancServer/SQLiteDatabaseWrapper.cpp Wed Dec 19 13:08:04 2018 +0100 @@ -1228,38 +1228,6 @@ } - static void FormatJoin(std::string& target, - const DatabaseConstraint& constraint, - size_t index) - { - std::string tag = "t" + boost::lexical_cast<std::string>(index); - - if (constraint.IsMandatory()) - { - target = " INNER JOIN "; - } - else - { - target = " LEFT JOIN "; - } - - if (constraint.IsIdentifier()) - { - target += "DicomIdentifiers "; - } - else - { - target += "MainDicomTags "; - } - - target += (tag + " ON " + tag + ".id = " + FormatLevel(constraint.GetLevel()) + - ".internalId AND " + tag + ".tagGroup = " + - boost::lexical_cast<std::string>(constraint.GetTag().GetGroup()) + - " AND " + tag + ".tagElement = " + - boost::lexical_cast<std::string>(constraint.GetTag().GetElement())); - } - - static bool FormatComparison(std::string& target, const DatabaseConstraint& constraint, size_t index, @@ -1344,46 +1312,58 @@ case ConstraintType_Wildcard: { const std::string value = constraint.GetSingleValue(); - std::string escaped; - escaped.reserve(value.size()); - for (size_t i = 0; i < value.size(); i++) + if (value == "*") { - if (value[i] == '*') + if (!constraint.IsMandatory()) { - escaped += "%"; + // Universal constraint on an optional tag, ignore it + return false; } - else if (value[i] == '?') + } + else + { + std::string escaped; + escaped.reserve(value.size()); + + for (size_t i = 0; i < value.size(); i++) { - escaped += "_"; - } - else if (value[i] == '%') - { - escaped += "\\%"; + if (value[i] == '*') + { + escaped += "%"; + } + else if (value[i] == '?') + { + escaped += "_"; + } + else if (value[i] == '%') + { + escaped += "\\%"; + } + else if (value[i] == '_') + { + escaped += "\\_"; + } + else if (value[i] == '\\') + { + escaped += "\\\\"; + } + else + { + escaped += value[i]; + } } - else if (value[i] == '_') + + parameters.push_back(escaped); + + if (constraint.IsCaseSensitive()) { - escaped += "\\_"; - } - else if (value[i] == '\\') - { - escaped += "\\\\"; + comparison = tag + ".value LIKE ? ESCAPE '\\'"; } else { - escaped += value[i]; - } - } - - parameters.push_back(escaped); - - if (constraint.IsCaseSensitive()) - { - comparison = tag + ".value LIKE ? ESCAPE '\\'"; - } - else - { - comparison = "lower(" + tag + ".value) LIKE lower(?) ESCAPE '\\'"; + comparison = "lower(" + tag + ".value) LIKE lower(?) ESCAPE '\\'"; + } } break; @@ -1396,23 +1376,52 @@ if (constraint.IsMandatory()) { - target += comparison; + target = comparison; + } + else if (comparison.empty()) + { + target = tag + ".value IS NULL"; } else { - target += tag + ".value IS NULL OR " + comparison; + target = tag + ".value IS NULL OR " + comparison; } return true; } - static void PrepareLookup(SQLite::Connection& db) + static void FormatJoin(std::string& target, + const DatabaseConstraint& constraint, + size_t index) { - SQLite::Statement s(db, SQLITE_FROM_HERE, "DROP TABLE IF EXISTS Lookup"); - s.Run(); + std::string tag = "t" + boost::lexical_cast<std::string>(index); + + if (constraint.IsMandatory()) + { + target = " INNER JOIN "; + } + else + { + target = " LEFT JOIN "; + } + + if (constraint.IsIdentifier()) + { + target += "DicomIdentifiers "; + } + else + { + target += "MainDicomTags "; + } + + target += (tag + " ON " + tag + ".id = " + FormatLevel(constraint.GetLevel()) + + ".internalId AND " + tag + ".tagGroup = " + + boost::lexical_cast<std::string>(constraint.GetTag().GetGroup()) + + " AND " + tag + ".tagElement = " + + boost::lexical_cast<std::string>(constraint.GetTag().GetElement())); } - + static void AnswerLookup(std::vector<std::string>& resourcesId, std::vector<std::string>& instancesId, @@ -1488,76 +1497,18 @@ } - static void FormatConstraints(std::string& joins, - std::string& comparisons, - std::vector<std::string>& parameters, - const std::vector<DatabaseConstraint>& lookup) - { - size_t count = 0; - - for (size_t i = 0; i < lookup.size(); i++) - { - std::string comparison; - - if (FormatComparison(comparison, lookup[i], count, parameters)) - { - std::string join; - FormatJoin(join, lookup[i], count); - joins += join; - - comparisons += " AND (" + comparison + ")"; - - count ++; - } - } - } - - - - void SQLiteDatabaseWrapper::ApplyLookupPatients(std::vector<std::string>& patientsId, - std::vector<std::string>& instancesId, - const std::vector<DatabaseConstraint>& lookup, - size_t limit) - { - PrepareLookup(db_); - - std::string joins, comparisons; - std::vector<std::string> parameters; - FormatConstraints(joins, comparisons, parameters, lookup); - - { - std::string sql = ("CREATE TEMPORARY TABLE Lookup AS " - "SELECT patients.publicId, patients.internalId FROM Resources AS patients" + - joins + " WHERE patients.resourceType = " + - boost::lexical_cast<std::string>(ResourceType_Patient) + comparisons); - - if (limit != 0) - { - sql += " LIMIT " + boost::lexical_cast<std::string>(limit); - } - - printf("[%s]\n", sql.c_str()); - - SQLite::Statement s(db_, sql); - - for (size_t i = 0; i < parameters.size(); i++) - { - s.BindString(i, parameters[i]); - } - - s.Run(); - } - - AnswerLookup(patientsId, instancesId, db_, ResourceType_Patient); - } - - void SQLiteDatabaseWrapper::ApplyLookupResources(std::vector<std::string>& resourcesId, std::vector<std::string>& instancesId, const std::vector<DatabaseConstraint>& lookup, ResourceType queryLevel, size_t limit) { + for (size_t i = 0; i < lookup.size(); i++) + { + std::cout << i << ": " << lookup[i].GetTag() << " - " << EnumerationToString(lookup[i].GetLevel()); + std::cout << std::endl; + } + assert(ResourceType_Patient < ResourceType_Study && ResourceType_Study < ResourceType_Series && ResourceType_Series < ResourceType_Instance); @@ -1582,11 +1533,34 @@ printf("ICI 2: [%s] -> [%s]\n", EnumerationToString(upperLevel), EnumerationToString(lowerLevel)); - PrepareLookup(db_); + { + SQLite::Statement s(db_, SQLITE_FROM_HERE, "DROP TABLE IF EXISTS Lookup"); + s.Run(); + } std::string joins, comparisons; std::vector<std::string> parameters; - FormatConstraints(joins, comparisons, parameters, lookup); + + size_t count = 0; + + for (size_t i = 0; i < lookup.size(); i++) + { + std::string comparison; + + if (FormatComparison(comparison, lookup[i], count, parameters)) + { + std::string join; + FormatJoin(join, lookup[i], count); + joins += join; + + if (!comparison.empty()) + { + comparisons += " AND " + comparison; + } + + count ++; + } + } { std::string sql = ("CREATE TEMPORARY TABLE Lookup AS SELECT " + @@ -1605,7 +1579,7 @@ for (int level = queryLevel + 1; level <= lowerLevel; level++) { sql += (" INNER JOIN Resources " + - FormatLevel(static_cast<ResourceType>(level - 1)) + " ON " + + FormatLevel(static_cast<ResourceType>(level)) + " ON " + FormatLevel(static_cast<ResourceType>(level - 1)) + ".internalId=" + FormatLevel(static_cast<ResourceType>(level)) + ".parentId"); }