# HG changeset patch # User Sebastien Jodogne # Date 1680800429 -7200 # Node ID 7b3acfa95bd81745baa230eac7f7fb8175639d05 # Parent a7a0290436706040c7106177f8a3a2e1fb401374 implementation of list/add/remove labels in postgresql diff -r a7a029043670 -r 7b3acfa95bd8 Framework/Plugins/DatabaseBackendAdapterV4.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV4.cpp Wed Apr 05 14:53:57 2023 +0200 +++ b/Framework/Plugins/DatabaseBackendAdapterV4.cpp Thu Apr 06 19:00:29 2023 +0200 @@ -408,6 +408,7 @@ response.mutable_get_system_information()->set_database_version(accessor.GetBackend().GetDatabaseVersion(accessor.GetManager())); response.mutable_get_system_information()->set_supports_flush_to_disk(false); response.mutable_get_system_information()->set_supports_revisions(accessor.GetBackend().HasRevisionsSupport()); + response.mutable_get_system_information()->set_supports_labels(accessor.GetBackend().HasLabelsSupport()); break; } @@ -1166,6 +1167,32 @@ break; } + case Orthanc::DatabasePluginMessages::OPERATION_ADD_LABEL: + { + backend.AddLabel(manager, request.add_label().id(), request.add_label().label()); + break; + } + + case Orthanc::DatabasePluginMessages::OPERATION_REMOVE_LABEL: + { + backend.RemoveLabel(manager, request.remove_label().id(), request.remove_label().label()); + break; + } + + case Orthanc::DatabasePluginMessages::OPERATION_LIST_LABELS: + { + std::list labels; + backend.ListLabels(labels, manager, request.list_labels().id()); + + response.mutable_list_available_attachments()->mutable_attachments()->Reserve(labels.size()); + for (std::list::const_iterator it = labels.begin(); it != labels.end(); ++it) + { + response.mutable_list_labels()->add_labels(*it); + } + + break; + } + default: LOG(ERROR) << "Not implemented transaction operation from protobuf: " << request.operation(); throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); diff -r a7a029043670 -r 7b3acfa95bd8 Framework/Plugins/IDatabaseBackend.h --- a/Framework/Plugins/IDatabaseBackend.h Wed Apr 05 14:53:57 2023 +0200 +++ b/Framework/Plugins/IDatabaseBackend.h Thu Apr 06 19:00:29 2023 +0200 @@ -324,15 +324,18 @@ virtual bool HasLabelsSupport() const = 0; // New in Orthanc 1.12.0 - virtual void AddLabel(int64_t resource, + virtual void AddLabel(DatabaseManager& manager, + int64_t resource, const std::string& label) = 0; // New in Orthanc 1.12.0 - virtual void RemoveLabel(int64_t resource, + virtual void RemoveLabel(DatabaseManager& manager, + int64_t resource, const std::string& label) = 0; // New in Orthanc 1.12.0 - virtual void ListLabels(std::set& target, + virtual void ListLabels(std::list& target, + DatabaseManager& manager, int64_t resource) = 0; }; } diff -r a7a029043670 -r 7b3acfa95bd8 Framework/Plugins/IndexBackend.cpp --- a/Framework/Plugins/IndexBackend.cpp Wed Apr 05 14:53:57 2023 +0200 +++ b/Framework/Plugins/IndexBackend.cpp Thu Apr 06 19:00:29 2023 +0200 @@ -2617,24 +2617,69 @@ #endif - void IndexBackend::AddLabel(int64_t resource, + void IndexBackend::AddLabel(DatabaseManager& manager, + int64_t resource, const std::string& label) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + std::unique_ptr statement; + + switch (manager.GetDialect()) + { + case Dialect_PostgreSQL: + statement.reset(new DatabaseManager::CachedStatement( + STATEMENT_FROM_HERE, manager, + "INSERT INTO Labels VALUES(${id}, ${label}) ON CONFLICT DO NOTHING")); + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + } + + statement->SetParameterType("id", ValueType_Integer64); + statement->SetParameterType("label", ValueType_Utf8String); + + Dictionary args; + args.SetIntegerValue("id", resource); + args.SetUtf8Value("label", label); + + statement->Execute(args); } - void IndexBackend::RemoveLabel(int64_t resource, + void IndexBackend::RemoveLabel(DatabaseManager& manager, + int64_t resource, const std::string& label) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + DatabaseManager::CachedStatement statement( + STATEMENT_FROM_HERE, manager, + "DELETE FROM Labels WHERE id=${id} AND label=${label}"); + + statement.SetParameterType("id", ValueType_Integer64); + statement.SetParameterType("label", ValueType_Utf8String); + + Dictionary args; + args.SetIntegerValue("id", resource); + args.SetUtf8Value("label", label); + + statement.Execute(args); } - void IndexBackend::ListLabels(std::set& target, + void IndexBackend::ListLabels(std::list& target, + DatabaseManager& manager, int64_t resource) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + DatabaseManager::CachedStatement statement( + STATEMENT_FROM_HERE, manager, + "SELECT label FROM Labels WHERE id=${id}"); + + statement.SetReadOnly(true); + statement.SetParameterType("id", ValueType_Integer64); + + Dictionary args; + args.SetIntegerValue("id", resource); + + ReadListOfStrings(target, statement, args); } @@ -2691,7 +2736,7 @@ } catch (boost::bad_lexical_cast&) { - LOG(ERROR) << "Corrupted PostgreSQL database"; + LOG(ERROR) << "Corrupted database"; throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); } } diff -r a7a029043670 -r 7b3acfa95bd8 Framework/Plugins/IndexBackend.h --- a/Framework/Plugins/IndexBackend.h Wed Apr 05 14:53:57 2023 +0200 +++ b/Framework/Plugins/IndexBackend.h Thu Apr 06 19:00:29 2023 +0200 @@ -381,13 +381,16 @@ int32_t property, int value); - virtual void AddLabel(int64_t resource, + virtual void AddLabel(DatabaseManager& manager, + int64_t resource, const std::string& label) ORTHANC_OVERRIDE; - virtual void RemoveLabel(int64_t resource, + virtual void RemoveLabel(DatabaseManager& manager, + int64_t resource, const std::string& label) ORTHANC_OVERRIDE; - virtual void ListLabels(std::set& target, + virtual void ListLabels(std::list& target, + DatabaseManager& manager, int64_t resource) ORTHANC_OVERRIDE; /** diff -r a7a029043670 -r 7b3acfa95bd8 PostgreSQL/Plugins/PostgreSQLIndex.cpp --- a/PostgreSQL/Plugins/PostgreSQLIndex.cpp Wed Apr 05 14:53:57 2023 +0200 +++ b/PostgreSQL/Plugins/PostgreSQLIndex.cpp Thu Apr 06 19:00:29 2023 +0200 @@ -297,6 +297,24 @@ t.Commit(); } + + + { + // New in release 5.0 to deal with labels + DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); + + if (!t.GetDatabaseTransaction().DoesTableExist("Labels")) + { + t.GetDatabaseTransaction().ExecuteMultiLines( + "CREATE TABLE Labels(" + "id BIGINT REFERENCES Resources(internalId) ON DELETE CASCADE," + "label TEXT, PRIMARY KEY(id, label));" + "CREATE INDEX LabelsIndex1 ON LABELS(id);" + "CREATE INDEX LabelsIndex2 ON LABELS(label);"); + } + + t.Commit(); + } } } diff -r a7a029043670 -r 7b3acfa95bd8 PostgreSQL/Plugins/PostgreSQLIndex.h --- a/PostgreSQL/Plugins/PostgreSQLIndex.h Wed Apr 05 14:53:57 2023 +0200 +++ b/PostgreSQL/Plugins/PostgreSQLIndex.h Thu Apr 06 19:00:29 2023 +0200 @@ -86,7 +86,7 @@ // New primitive since Orthanc 1.12.0 virtual bool HasLabelsSupport() const ORTHANC_OVERRIDE { - return false; + return true; } }; }