Mercurial > hg > orthanc-databases
changeset 559:e18ec71019fa find-refactoring
Find in PG continued: all basic integration tests ok
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Sat, 14 Sep 2024 11:23:40 +0200 |
parents | d186007b0f1e |
children | b0ce1ebc9b90 |
files | Framework/Plugins/ISqlLookupFormatter.cpp Framework/Plugins/IndexBackend.cpp |
diffstat | 2 files changed, 402 insertions(+), 163 deletions(-) [+] |
line wrap: on
line diff
--- a/Framework/Plugins/ISqlLookupFormatter.cpp Fri Sep 13 16:56:18 2024 +0200 +++ b/Framework/Plugins/ISqlLookupFormatter.cpp Sat Sep 14 11:23:40 2024 +0200 @@ -664,7 +664,7 @@ assert(upperLevel <= queryLevel && queryLevel <= lowerLevel); - std::string ordering = "NULL::BIGINT AS rowNumber"; // "row_number() over (order by publicId) as rn"; // default ordering for now + std::string ordering = "row_number() over (order by " + strQueryLevel + ".publicId) as rowNumber"; // we need a default ordering in order to make default queries repeatable when using since&limit sql = ("SELECT " + strQueryLevel + ".publicId, " +
--- a/Framework/Plugins/IndexBackend.cpp Fri Sep 13 16:56:18 2024 +0200 +++ b/Framework/Plugins/IndexBackend.cpp Sat Sep 14 11:23:40 2024 +0200 @@ -3132,11 +3132,20 @@ #define QUERY_MAIN_DICOM_TAGS 2 #define QUERY_ATTACHMENTS 3 #define QUERY_METADATA 4 -#define QUERY_PARENT_MAIN_DICOM_TAGS 5 -#define QUERY_PARENT_IDENTIFIER 6 -#define QUERY_CHILDREN_IDENTIFIERS 7 -#define QUERY_CHILDREN_MAIN_DICOM_TAGS 8 -#define QUERY_GRAND_CHILDREN_MAIN_DICOM_TAGS 9 +#define QUERY_LABELS 5 +#define QUERY_PARENT_MAIN_DICOM_TAGS 10 +#define QUERY_PARENT_IDENTIFIER 11 +#define QUERY_GRAND_PARENT_MAIN_DICOM_TAGS 15 +#define QUERY_CHILDREN_IDENTIFIERS 20 +#define QUERY_CHILDREN_MAIN_DICOM_TAGS 21 +#define QUERY_CHILDREN_METADATA 22 +#define QUERY_GRAND_CHILDREN_IDENTIFIERS 30 +#define QUERY_GRAND_CHILDREN_MAIN_DICOM_TAGS 31 +#define QUERY_GRAND_CHILDREN_METADATA 32 +#define QUERY_GRAND_GRAND_CHILDREN_IDENTIFIERS 40 +#define QUERY_ONE_INSTANCE_IDENTIFIER 50 +#define QUERY_ONE_INSTANCE_METADATA 51 +#define QUERY_ONE_INSTANCE_ATTACHMENTS 52 #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) @@ -3181,58 +3190,73 @@ // need MainDicomTags from resource ? if (request.retrieve_main_dicom_tags()) { - sql += - "UNION SELECT " - " " TOSTRING(QUERY_MAIN_DICOM_TAGS) " AS c0_queryId, " - " Lookup.internalId AS c1_internalId, " - " NULL::BIGINT AS c2_rowNumber, " - " value AS c3_string1, " - " NULL::TEXT AS c4_string2, " - " NULL::TEXT AS c5_string3, " - " tagGroup AS c6_int1, " - " tagElement AS c7_int2, " - " NULL::BIGINT AS c8_big_int1, " - " NULL::BIGINT AS c9_big_int2 " - "FROM MainDicomTags " - "INNER JOIN Lookup ON MainDicomTags.id = Lookup.internalId "; + sql += "UNION SELECT " + " " TOSTRING(QUERY_MAIN_DICOM_TAGS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " tagGroup AS c6_int1, " + " tagElement AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM MainDicomTags " + "INNER JOIN Lookup ON MainDicomTags.id = Lookup.internalId "; } // need resource metadata ? if (request.retrieve_metadata()) { - sql += - "UNION SELECT " - " " TOSTRING(QUERY_METADATA) " AS c0_queryId, " - " Lookup.internalId AS c1_internalId, " - " NULL::BIGINT AS c2_rowNumber, " - " value AS c3_string1, " - " NULL::TEXT AS c4_string2, " - " NULL::TEXT AS c5_string3, " - " type AS c6_int1, " - " NULL::INT AS c7_int2, " - " NULL::BIGINT AS c8_big_int1, " - " NULL::BIGINT AS c9_big_int2 " - "FROM Metadata " - "INNER JOIN Lookup ON Metadata.id = Lookup.internalId "; + sql += "UNION SELECT " + " " TOSTRING(QUERY_METADATA) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " type AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Metadata " + "INNER JOIN Lookup ON Metadata.id = Lookup.internalId "; } // need resource attachments ? if (request.retrieve_attachments()) { - sql += - "UNION SELECT " - " " TOSTRING(QUERY_ATTACHMENTS) " AS c0_queryId, " - " Lookup.internalId AS c1_internalId, " - " NULL::BIGINT AS c2_rowNumber, " - " uuid AS c3_string1, " - " uncompressedHash AS c4_string2, " - " compressedHash AS c5_string3, " - " fileType AS c6_int1, " - " compressionType AS c7_int2, " - " compressedSize AS c8_big_int1, " - " uncompressedSize AS c9_big_int2 " - "FROM AttachedFiles " - "INNER JOIN Lookup ON AttachedFiles.id = Lookup.internalId "; + sql += "UNION SELECT " + " " TOSTRING(QUERY_ATTACHMENTS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " uuid AS c3_string1, " + " uncompressedHash AS c4_string2, " + " compressedHash AS c5_string3, " + " fileType AS c6_int1, " + " compressionType AS c7_int2, " + " compressedSize AS c8_big_int1, " + " uncompressedSize AS c9_big_int2 " + "FROM AttachedFiles " + "INNER JOIN Lookup ON AttachedFiles.id = Lookup.internalId "; + } + + // need resource labels ? + if (request.retrieve_labels()) + { + sql += "UNION SELECT " + " " TOSTRING(QUERY_LABELS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " label AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " NULL::INT AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Labels " + "INNER JOIN Lookup ON Labels.id = Lookup.internalId "; } // need MainDicomTags from parent ? @@ -3257,21 +3281,20 @@ if (parentSpec->retrieve_main_dicom_tags()) { - sql += - "UNION SELECT " - " " TOSTRING(QUERY_PARENT_MAIN_DICOM_TAGS) " AS c0_queryId, " - " Lookup.internalId AS c1_internalId, " - " NULL::BIGINT AS c2_rowNumber, " - " value AS c3_string1, " - " NULL::TEXT AS c4_string2, " - " NULL::TEXT AS c5_string3, " - " tagGroup AS c6_int1, " - " tagElement AS c7_int2, " - " NULL::BIGINT AS c8_big_int1, " - " NULL::BIGINT AS c9_big_int2 " - "FROM MainDicomTags " - "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " - "INNER JOIN Lookup ON MainDicomTags.id = currentLevel.parentId"; + sql += "UNION SELECT " + " " TOSTRING(QUERY_PARENT_MAIN_DICOM_TAGS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " tagGroup AS c6_int1, " + " tagElement AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Lookup " + "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " + "INNER JOIN MainDicomTags ON MainDicomTags.id = currentLevel.parentId "; } // need MainDicomTags from grandparent ? @@ -3293,7 +3316,21 @@ if (grandparentSpec->retrieve_main_dicom_tags()) { - sql += "TODO"; + sql += "UNION SELECT " + " " TOSTRING(QUERY_GRAND_PARENT_MAIN_DICOM_TAGS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " tagGroup AS c6_int1, " + " tagElement AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Lookup " + "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " + "INNER JOIN Resources parentLevel ON currentLevel.parentId = parentLevel.internalId " + "INNER JOIN MainDicomTags ON MainDicomTags.id = parentLevel.parentId "; } } } @@ -3320,41 +3357,57 @@ if (childrenSpec->retrieve_main_dicom_tags_size() > 0) // TODO: retrieve only the requested tags ? { - sql += - "UNION SELECT " - " " TOSTRING(QUERY_CHILDREN_MAIN_DICOM_TAGS) " AS c0_queryId, " - " Lookup.internalId AS c1_internalId, " - " NULL::BIGINT AS c2_rowNumber, " - " value AS c3_string1, " - " NULL::TEXT AS c4_string2, " - " NULL::TEXT AS c5_string3, " - " tagGroup AS c6_int1, " - " tagElement AS c7_int2, " - " NULL::BIGINT AS c8_big_int1, " - " NULL::BIGINT AS c9_big_int2 " - "FROM MainDicomTags " - " INNER JOIN Resources childLevel ON childLevel.parentId = Lookup.internalId " - " INNER JOIN Lookup ON MainDicomTags.id = childLevel.internalId "; + sql += "UNION SELECT " + " " TOSTRING(QUERY_CHILDREN_MAIN_DICOM_TAGS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " tagGroup AS c6_int1, " + " tagElement AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Lookup " + " INNER JOIN Resources childLevel ON childLevel.parentId = Lookup.internalId " + " INNER JOIN MainDicomTags ON MainDicomTags.id = childLevel.internalId "; } // need children identifiers ? - if (childrenSpec->retrieve_identifiers()) + if (childrenSpec->retrieve_identifiers()) { - sql += - "UNION SELECT " - " " TOSTRING(QUERY_CHILDREN_IDENTIFIERS) " AS c0_queryId, " - " Lookup.internalId AS c1_internalId, " - " NULL::BIGINT AS c2_rowNumber, " - " childLevel.publicId AS c3_string1, " - " NULL::TEXT AS c4_string2, " - " NULL::TEXT AS c5_string3, " - " NULL::INT AS c6_int1, " - " NULL::INT AS c7_int2, " - " NULL::BIGINT AS c8_big_int1, " - " NULL::BIGINT AS c9_big_int2 " - "FROM Resources AS currentLevel " - " INNER JOIN Lookup ON currentLevel.internalId = Lookup.internalId " - " INNER JOIN Resources childLevel ON currentLevel.internalId = childLevel.parentId "; + sql += "UNION SELECT " + " " TOSTRING(QUERY_CHILDREN_IDENTIFIERS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " childLevel.publicId AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " NULL::INT AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Resources AS currentLevel " + " INNER JOIN Lookup ON currentLevel.internalId = Lookup.internalId " + " INNER JOIN Resources childLevel ON currentLevel.internalId = childLevel.parentId "; + } + + if (childrenSpec->retrieve_metadata_size() > 0) // TODO-FIND: retrieve only the requested metadata ? + { + sql += "UNION SELECT " + " " TOSTRING(QUERY_CHILDREN_METADATA) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " type AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Lookup " + " INNER JOIN Resources childLevel ON childLevel.parentId = Lookup.internalId " + " INNER JOIN Metadata ON Metadata.id = childLevel.internalId "; } if (request.level() <= Orthanc::DatabasePluginMessages::ResourceType::RESOURCE_STUDY) @@ -3373,24 +3426,88 @@ break; } - if (grandchildrenSpec->retrieve_main_dicom_tags_size() > 0) // TODO: retrieve only the requested tags ? + // need grand children identifiers ? + if (grandchildrenSpec->retrieve_identifiers()) + { + sql += "UNION SELECT " + " " TOSTRING(QUERY_GRAND_CHILDREN_IDENTIFIERS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " grandChildLevel.publicId AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " NULL::INT AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Resources AS currentLevel " + "INNER JOIN Lookup ON currentLevel.internalId = Lookup.internalId " + "INNER JOIN Resources childLevel ON currentLevel.internalId = childLevel.parentId " + "INNER JOIN Resources grandChildLevel ON childLevel.internalId = grandChildLevel.parentId "; + } + + if (grandchildrenSpec->retrieve_main_dicom_tags_size() > 0) // TODO-FIND: retrieve only the requested tags ? + { + sql += "UNION SELECT " + " " TOSTRING(QUERY_GRAND_CHILDREN_MAIN_DICOM_TAGS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " tagGroup AS c6_int1, " + " tagElement AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Lookup " + " INNER JOIN Resources childLevel ON childLevel.parentId = Lookup.internalId " + " INNER JOIN Resources grandChildLevel ON childLevel.parentId = Lookup.internalId " + " INNER JOIN MainDicomTags ON MainDicomTags.id = grandChildLevel.internalId "; + } + + if (grandchildrenSpec->retrieve_metadata_size() > 0) // TODO-FIND: retrieve only the requested metadata ? { - sql += - "UNION SELECT " - " " TOSTRING(QUERY_GRAND_CHILDREN_MAIN_DICOM_TAGS) " AS c0_queryId, " - " Lookup.internalId AS c1_internalId, " - " NULL::BIGINT AS c2_rowNumber, " - " value AS c3_string1, " - " NULL::TEXT AS c4_string2, " - " NULL::TEXT AS c5_string3, " - " tagGroup AS c6_int1, " - " tagElement AS c7_int2, " - " NULL::BIGINT AS c8_big_int1, " - " NULL::BIGINT AS c9_big_int2 " - "FROM MainDicomTags " - " INNER JOIN Resources childLevel ON childLevel.parentId = Lookup.internalId " - " INNER JOIN Resources grandChildLevel ON childLevel.parentId = Lookup.internalId " - " INNER JOIN Lookup ON MainDicomTags.id = grandChildLevel.internalId "; + sql += "UNION SELECT " + " " TOSTRING(QUERY_GRAND_CHILDREN_METADATA) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " type AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Lookup " + " INNER JOIN Resources childLevel ON childLevel.parentId = Lookup.internalId " + " INNER JOIN Resources grandChildLevel ON childLevel.parentId = Lookup.internalId " + " INNER JOIN Metadata ON Metadata.id = grandChildLevel.internalId "; + } + + if (request.level() == Orthanc::DatabasePluginMessages::ResourceType::RESOURCE_PATIENT) + { + const Orthanc::DatabasePluginMessages::Find_Request_ChildrenSpecification* grandgrandchildrenSpec = &(request.children_instances()); + + // need grand children identifiers ? + if (grandgrandchildrenSpec->retrieve_identifiers()) + { + sql += "UNION SELECT " + " " TOSTRING(QUERY_GRAND_GRAND_CHILDREN_IDENTIFIERS) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " grandGrandChildLevel.publicId AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " NULL::INT AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Resources AS currentLevel " + "INNER JOIN Lookup ON currentLevel.internalId = Lookup.internalId " + "INNER JOIN Resources childLevel ON currentLevel.internalId = childLevel.parentId " + "INNER JOIN Resources grandChildLevel ON childLevel.internalId = grandChildLevel.parentId " + "INNER JOIN Resources grandGrandChildLevel ON grandChildLevel.internalId = grandGrandChildLevel.parentId "; + } } } } @@ -3398,48 +3515,103 @@ // need parent identifier ? if (request.retrieve_parent_identifier()) { - sql += - "UNION SELECT " - " " TOSTRING(QUERY_PARENT_IDENTIFIER) " AS c0_queryId, " - " Lookup.internalId AS c1_internalId, " - " NULL::BIGINT AS c2_rowNumber, " - " parentLevel.publicId AS c3_string1, " - " NULL::TEXT AS c4_string2, " - " NULL::TEXT AS c5_string3, " - " NULL::INT AS c6_int1, " - " NULL::INT AS c7_int2, " - " NULL::BIGINT AS c8_big_int1, " - " NULL::BIGINT AS c9_big_int2 " - "FROM Resources AS currentLevel " - " INNER JOIN Lookup ON currentLevel.internalId = Lookup.internalId " - " INNER JOIN Resources parentLevel ON currentLevel.parentId = parentLevel.internalId "; + sql += "UNION SELECT " + " " TOSTRING(QUERY_PARENT_IDENTIFIER) " AS c0_queryId, " + " Lookup.internalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " parentLevel.publicId AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " NULL::INT AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + "FROM Resources AS currentLevel " + " INNER JOIN Lookup ON currentLevel.internalId = Lookup.internalId " + " INNER JOIN Resources parentLevel ON currentLevel.parentId = parentLevel.internalId "; } - -// Find_Request_ParentSpecification Patient.parent_patient) -// - -// if (requestLevel > ResourceType_Patient && request.GetParentSpecification(static_cast<ResourceType>(requestLevel - 1)).IsRetrieveMainDicomTags()) -// { -// sql = "SELECT currentLevel.internalId, tagGroup, tagElement, value " -// "FROM MainDicomTags " -// "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " -// "INNER JOIN Lookup ON MainDicomTags.id = currentLevel.parentId"; - -// SQLite::Statement s(db_, SQLITE_FROM_HERE, sql); -// while (s.Step()) -// { -// FindResponse::Resource& res = response.GetResourceByInternalId(s.ColumnInt64(0)); -// res.AddStringDicomTag(static_cast<ResourceType>(requestLevel - 1), -// static_cast<uint16_t>(s.ColumnInt(1)), -// static_cast<uint16_t>(s.ColumnInt(2)), -// s.ColumnString(3)); -// } -// } - - // TODO-FIND: other requests - - sql += "ORDER BY c0_queryId, c2_rowNumber"; // this is really important to make sure that the Lookup query is the first one to provide results since we use it to create the responses element ! + // need one instance info ? + if (request.level() != Orthanc::DatabasePluginMessages::ResourceType::RESOURCE_INSTANCE && + request.retrieve_one_instance_metadata_and_attachments()) + { + // Here, we create a nested CTE 'OneInstance' with one instance ID to join with metadata and main + sql += "UNION" + " (WITH OneInstance AS"; + + switch (request.level()) + { + case Orthanc::DatabasePluginMessages::ResourceType::RESOURCE_SERIES: + { + sql+= " (SELECT DISTINCT ON (Lookup.internalId) Lookup.internalId AS parentInternalId, childLevel.publicId AS instancePublicId, childLevel.internalId AS instanceInternalId" + " FROM Resources AS childLevel " + " INNER JOIN Lookup ON childLevel.parentId = Lookup.internalId) "; + }; break; + case Orthanc::DatabasePluginMessages::ResourceType::RESOURCE_STUDY: + { + sql+= " (SELECT DISTINCT ON (Lookup.internalId) Lookup.internalId AS parentInternalId, grandChildLevel.publicId AS instancePublicId, grandChildLevel.internalId AS instanceInternalId" + " FROM Resources AS grandChildLevel " + " INNER JOIN Resources childLevel ON grandChildLevel.parentId = childLevel.internalId " + " INNER JOIN Lookup ON childLevel.parentId = Lookup.internalId) "; + }; break; + case Orthanc::DatabasePluginMessages::ResourceType::RESOURCE_PATIENT: + { + sql+= " (SELECT DISTINCT ON (Lookup.internalId) Lookup.internalId AS parentInternalId, grandGrandChildLevel.publicId AS instancePublicId, grandGrandChildLevel.internalId AS instanceInternalId" + " FROM Resources AS grandGrandChildLevel " + " INNER JOIN Resources grandChildLevel ON grandGrandChildLevel.parentId = grandChildLevel.internalId " + " INNER JOIN Resources childLevel ON grandChildLevel.parentId = childLevel.internalId " + " INNER JOIN Lookup ON childLevel.parentId = Lookup.internalId) "; + }; break; + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + sql += " SELECT" + " " TOSTRING(QUERY_ONE_INSTANCE_IDENTIFIER) " AS c0_queryId, " + " parentInternalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " instancePublicId AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " NULL::INT AS c6_int1, " + " NULL::INT AS c7_int2, " + " instanceInternalId AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + " FROM OneInstance "; + + sql += " UNION SELECT" + " " TOSTRING(QUERY_ONE_INSTANCE_METADATA) " AS c0_queryId, " + " parentInternalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " Metadata.value AS c3_string1, " + " NULL::TEXT AS c4_string2, " + " NULL::TEXT AS c5_string3, " + " Metadata.type AS c6_int1, " + " NULL::INT AS c7_int2, " + " NULL::BIGINT AS c8_big_int1, " + " NULL::BIGINT AS c9_big_int2 " + " FROM Metadata " + " INNER JOIN OneInstance ON Metadata.id = OneInstance.instanceInternalId"; + + sql += " UNION SELECT" + " " TOSTRING(QUERY_ONE_INSTANCE_ATTACHMENTS) " AS c0_queryId, " + " parentInternalId AS c1_internalId, " + " NULL::BIGINT AS c2_rowNumber, " + " uuid AS c3_string1, " + " uncompressedHash AS c4_string2, " + " compressedHash AS c5_string3, " + " fileType AS c6_int1, " + " compressionType AS c7_int2, " + " compressedSize AS c8_big_int1, " + " uncompressedSize AS c9_big_int2 " + " FROM AttachedFiles " + " INNER JOIN OneInstance ON AttachedFiles.id = OneInstance.instanceInternalId"; + + sql += " ) "; + + } + + sql += " ORDER BY c0_queryId, c2_rowNumber"; // this is really important to make sure that the Lookup query is the first one to provide results since we use it to create the responses element ! DatabaseManager::StandaloneStatement statement(manager, sql); // TODO-FIND: cache dynamic statement ? Probably worth it since it can be very complex queries ! formatter.PrepareStatement(statement); @@ -3458,14 +3630,18 @@ switch (queryId) { case QUERY_LOOKUP: - responses[internalId] = response.add_find(); // the protobuf message is the owner of the response + responses[internalId] = response.add_find(); responses[internalId]->set_public_id(statement.ReadString(C3_STRING_1)); responses[internalId]->set_internal_id(internalId); break; + case QUERY_LABELS: + responses[internalId]->add_labels(statement.ReadString(C3_STRING_1)); + break; + case QUERY_MAIN_DICOM_TAGS: { - Orthanc::DatabasePluginMessages::Find_Response_ResourceContent* content = GetResourceContent(responses[internalId], request.level()); // the protobuf response will be the owner + Orthanc::DatabasePluginMessages::Find_Response_ResourceContent* content = GetResourceContent(responses[internalId], request.level()); Orthanc::DatabasePluginMessages::Find_Response_Tag* tag = content->add_main_dicom_tags(); tag->set_value(statement.ReadString(C3_STRING_1)); @@ -3475,7 +3651,17 @@ case QUERY_PARENT_MAIN_DICOM_TAGS: { - Orthanc::DatabasePluginMessages::Find_Response_ResourceContent* content = GetResourceContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() - 1)); // the protobuf response will be the owner + Orthanc::DatabasePluginMessages::Find_Response_ResourceContent* content = GetResourceContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() - 1)); + Orthanc::DatabasePluginMessages::Find_Response_Tag* tag = content->add_main_dicom_tags(); + + tag->set_value(statement.ReadString(C3_STRING_1)); + tag->set_group(statement.ReadInteger32(C6_INT_1)); + tag->set_element(statement.ReadInteger32(C7_INT_2)); + }; break; + + case QUERY_GRAND_PARENT_MAIN_DICOM_TAGS: + { + Orthanc::DatabasePluginMessages::Find_Response_ResourceContent* content = GetResourceContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() - 2)); Orthanc::DatabasePluginMessages::Find_Response_Tag* tag = content->add_main_dicom_tags(); tag->set_value(statement.ReadString(C3_STRING_1)); @@ -3485,33 +3671,62 @@ case QUERY_CHILDREN_IDENTIFIERS: { - Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 1)); // the protobuf response will be the owner + Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 1)); content->add_identifiers(statement.ReadString(C3_STRING_1)); }; break; case QUERY_CHILDREN_MAIN_DICOM_TAGS: { - Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 1)); // the protobuf response will be the owner + Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 1)); Orthanc::DatabasePluginMessages::Find_Response_MultipleTags* tag = content->add_main_dicom_tags(); - - tag->set_values(0, statement.ReadString(C3_STRING_1)); // TODO: handle sequences ?? + tag->add_values(statement.ReadString(C3_STRING_1)); // TODO: handle sequences ?? tag->set_group(statement.ReadInteger32(C6_INT_1)); tag->set_element(statement.ReadInteger32(C7_INT_2)); }; break; + case QUERY_CHILDREN_METADATA: + { + Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 1)); + Orthanc::DatabasePluginMessages::Find_Response_MultipleMetadata* metadata = content->add_metadata(); + + metadata->add_values(statement.ReadString(C3_STRING_1)); + metadata->set_key(statement.ReadInteger32(C6_INT_1)); + }; break; + + case QUERY_GRAND_CHILDREN_IDENTIFIERS: + { + Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 2)); + content->add_identifiers(statement.ReadString(C3_STRING_1)); + }; break; + case QUERY_GRAND_CHILDREN_MAIN_DICOM_TAGS: { - Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 2)); // the protobuf response will be the owner + Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 2)); Orthanc::DatabasePluginMessages::Find_Response_MultipleTags* tag = content->add_main_dicom_tags(); - tag->set_values(0, statement.ReadString(C3_STRING_1)); // TODO: handle sequences ?? + tag->add_values(statement.ReadString(C3_STRING_1)); // TODO: handle sequences ?? tag->set_group(statement.ReadInteger32(C6_INT_1)); tag->set_element(statement.ReadInteger32(C7_INT_2)); }; break; + case QUERY_GRAND_CHILDREN_METADATA: + { + Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 2)); + Orthanc::DatabasePluginMessages::Find_Response_MultipleMetadata* metadata = content->add_metadata(); + + metadata->add_values(statement.ReadString(C3_STRING_1)); + metadata->set_key(statement.ReadInteger32(C6_INT_1)); + }; break; + + case QUERY_GRAND_GRAND_CHILDREN_IDENTIFIERS: + { + Orthanc::DatabasePluginMessages::Find_Response_ChildrenContent* content = GetChildrenContent(responses[internalId], static_cast<Orthanc::DatabasePluginMessages::ResourceType>(request.level() + 3)); + content->add_identifiers(statement.ReadString(C3_STRING_1)); + }; break; + case QUERY_ATTACHMENTS: { - Orthanc::DatabasePluginMessages::FileInfo* attachment = responses[internalId]->add_attachments(); // the protobuf response is the owner + Orthanc::DatabasePluginMessages::FileInfo* attachment = responses[internalId]->add_attachments(); attachment->set_uuid(statement.ReadString(C3_STRING_1)); attachment->set_uncompressed_hash(statement.ReadString(C4_STRING_2)); @@ -3524,7 +3739,7 @@ case QUERY_METADATA: { - Orthanc::DatabasePluginMessages::Find_Response_ResourceContent* content = GetResourceContent(responses[internalId], request.level()); // the protobuf response will be the owner + Orthanc::DatabasePluginMessages::Find_Response_ResourceContent* content = GetResourceContent(responses[internalId], request.level()); Orthanc::DatabasePluginMessages::Find_Response_Metadata* metadata = content->add_metadata(); metadata->set_value(statement.ReadString(C3_STRING_1)); @@ -3536,6 +3751,30 @@ responses[internalId]->set_parent_public_id(statement.ReadString(C3_STRING_1)); }; break; + case QUERY_ONE_INSTANCE_IDENTIFIER: + { + responses[internalId]->set_one_instance_public_id(statement.ReadString(C3_STRING_1)); + }; break; + case QUERY_ONE_INSTANCE_METADATA: + { + Orthanc::DatabasePluginMessages::Find_Response_Metadata* metadata = responses[internalId]->add_one_instance_metadata(); + + metadata->set_value(statement.ReadString(C3_STRING_1)); + metadata->set_key(statement.ReadInteger32(C6_INT_1)); + }; break; + case QUERY_ONE_INSTANCE_ATTACHMENTS: + { + Orthanc::DatabasePluginMessages::FileInfo* attachment = responses[internalId]->add_one_instance_attachments(); + + attachment->set_uuid(statement.ReadString(C3_STRING_1)); + attachment->set_uncompressed_hash(statement.ReadString(C4_STRING_2)); + attachment->set_compressed_hash(statement.ReadString(C5_STRING_3)); + attachment->set_content_type(statement.ReadInteger32(C6_INT_1)); + attachment->set_compression_type(statement.ReadInteger32(C7_INT_2)); + attachment->set_compressed_size(statement.ReadInteger64(C8_BIG_INT_1)); + attachment->set_uncompressed_size(statement.ReadInteger64(C9_BIG_INT_2)); + }; break; + default: throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); }