# HG changeset patch # User Sebastien Jodogne # Date 1618586013 -7200 # Node ID e184dcadf163ccc3fe5acbebddfa86399706e44f # Parent d663d9e44f8d2a0a5bb9099c7d561f071e195292 handling of revisions in metadata diff -r d663d9e44f8d -r e184dcadf163 Framework/Plugins/DatabaseBackendAdapterV2.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV2.cpp Wed Apr 14 17:57:08 2021 +0200 +++ b/Framework/Plugins/DatabaseBackendAdapterV2.cpp Fri Apr 16 17:13:33 2021 +0200 @@ -1073,7 +1073,8 @@ DatabaseBackendAdapterV2::Adapter::DatabaseAccessor accessor(*adapter); std::string s; - if (adapter->GetBackend().LookupMetadata(s, accessor.GetManager(), id, metadata)) + int64_t revision; // not handled in this API + if (adapter->GetBackend().LookupMetadata(s, revision, accessor.GetManager(), id, metadata)) { OrthancPluginDatabaseAnswerString(adapter->GetBackend().GetContext(), output->GetDatabase(), s.c_str()); @@ -1244,7 +1245,8 @@ try { DatabaseBackendAdapterV2::Adapter::DatabaseAccessor accessor(*adapter); - adapter->GetBackend().SetMetadata(accessor.GetManager(), id, metadata, value); + adapter->GetBackend().SetMetadata(accessor.GetManager(), id, metadata, value, + 0 /* revision number, unused in old API */); return OrthancPluginErrorCode_Success; } ORTHANC_PLUGINS_DATABASE_CATCH; diff -r d663d9e44f8d -r e184dcadf163 Framework/Plugins/DatabaseBackendAdapterV3.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV3.cpp Wed Apr 14 17:57:08 2021 +0200 +++ b/Framework/Plugins/DatabaseBackendAdapterV3.cpp Fri Apr 16 17:13:33 2021 +0200 @@ -1707,6 +1707,7 @@ static OrthancPluginErrorCode LookupMetadata(OrthancPluginDatabaseTransaction* transaction, + int64_t* revision /* out */, int64_t id, int32_t metadata) { @@ -1717,7 +1718,7 @@ t->GetOutput().Clear(); std::string s; - if (t->GetBackend().LookupMetadata(s, t->GetManager(), id, metadata)) + if (t->GetBackend().LookupMetadata(s, *revision, t->GetManager(), id, metadata)) { t->GetOutput().AnswerString(s); } @@ -1913,14 +1914,15 @@ static OrthancPluginErrorCode SetMetadata(OrthancPluginDatabaseTransaction* transaction, int64_t id, int32_t metadata, - const char* value) + const char* value, + int64_t revision) { DatabaseBackendAdapterV3::Transaction* t = reinterpret_cast(transaction); try { t->GetOutput().Clear(); - t->GetBackend().SetMetadata(t->GetManager(), id, metadata, value); + t->GetBackend().SetMetadata(t->GetManager(), id, metadata, value, revision); return OrthancPluginErrorCode_Success; } ORTHANC_PLUGINS_DATABASE_CATCH(t->GetBackend().GetContext()); diff -r d663d9e44f8d -r e184dcadf163 Framework/Plugins/IDatabaseBackend.h --- a/Framework/Plugins/IDatabaseBackend.h Wed Apr 14 17:57:08 2021 +0200 +++ b/Framework/Plugins/IDatabaseBackend.h Fri Apr 16 17:13:33 2021 +0200 @@ -190,6 +190,7 @@ const char* end) = 0; virtual bool LookupMetadata(std::string& target /*out*/, + int64_t& revision /*out*/, DatabaseManager& manager, int64_t id, int32_t metadataType) = 0; @@ -230,7 +231,8 @@ virtual void SetMetadata(DatabaseManager& manager, int64_t id, int32_t metadataType, - const char* value) = 0; + const char* value, + int64_t revision) = 0; virtual void SetProtectedPatient(DatabaseManager& manager, int64_t internalId, diff -r d663d9e44f8d -r e184dcadf163 Framework/Plugins/IndexBackend.cpp --- a/Framework/Plugins/IndexBackend.cpp Wed Apr 14 17:57:08 2021 +0200 +++ b/Framework/Plugins/IndexBackend.cpp Fri Apr 16 17:13:33 2021 +0200 @@ -446,7 +446,7 @@ SignalDeletedFiles(output, manager); } - + void IndexBackend::DeleteMetadata(DatabaseManager& manager, int64_t id, int32_t metadataType) @@ -465,7 +465,7 @@ statement.Execute(args); } - + void IndexBackend::DeleteResource(IDatabaseBackendOutput& output, DatabaseManager& manager, int64_t id) @@ -1256,31 +1256,60 @@ bool IndexBackend::LookupMetadata(std::string& target /*out*/, + int64_t& revision /*out*/, DatabaseManager& manager, int64_t id, int32_t metadataType) { - DatabaseManager::CachedStatement statement( - STATEMENT_FROM_HERE, manager, - "SELECT value FROM Metadata WHERE id=${id} and type=${type}"); + std::unique_ptr statement; + + switch (manager.GetDialect()) + { + case Dialect_MySQL: + case Dialect_PostgreSQL: + statement.reset(new DatabaseManager::CachedStatement( + STATEMENT_FROM_HERE, manager, + "SELECT value FROM Metadata WHERE id=${id} and type=${type}")); + break; - statement.SetReadOnly(true); - statement.SetParameterType("id", ValueType_Integer64); - statement.SetParameterType("type", ValueType_Integer64); + case Dialect_SQLite: + statement.reset(new DatabaseManager::CachedStatement( + STATEMENT_FROM_HERE, manager, + "SELECT value, revision FROM Metadata WHERE id=${id} and type=${type}")); + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + } + + + statement->SetReadOnly(true); + statement->SetParameterType("id", ValueType_Integer64); + statement->SetParameterType("type", ValueType_Integer64); Dictionary args; args.SetIntegerValue("id", id); args.SetIntegerValue("type", metadataType); - statement.Execute(args); + statement->Execute(args); - if (statement.IsDone()) + if (statement->IsDone()) { return false; } else { - target = ReadString(statement, 0); + target = ReadString(*statement, 0); + + if (manager.GetDialect() == Dialect_SQLite) + { + revision = ReadInteger64(*statement, 1); + } + else + { + revision = 0; // TODO - REVISIONS + } + return true; } } @@ -1560,27 +1589,31 @@ void IndexBackend::SetMetadata(DatabaseManager& manager, int64_t id, int32_t metadataType, - const char* value) + const char* value, + int64_t revision) { if (manager.GetDialect() == Dialect_SQLite) { DatabaseManager::CachedStatement statement( STATEMENT_FROM_HERE, manager, - "INSERT OR REPLACE INTO Metadata VALUES (${id}, ${type}, ${value})"); + "INSERT OR REPLACE INTO Metadata VALUES (${id}, ${type}, ${value}, ${revision})"); statement.SetParameterType("id", ValueType_Integer64); statement.SetParameterType("type", ValueType_Integer64); statement.SetParameterType("value", ValueType_Utf8String); + statement.SetParameterType("revision", ValueType_Integer64); Dictionary args; args.SetIntegerValue("id", id); args.SetIntegerValue("type", metadataType); args.SetUtf8Value("value", value); + args.SetIntegerValue("revision", revision); statement.Execute(args); } else { + // TODO - REVISIONS { DatabaseManager::CachedStatement statement( STATEMENT_FROM_HERE, manager, @@ -2048,10 +2081,16 @@ std::string name = "m" + boost::lexical_cast(i); args.SetUtf8Value(name, metadata[i].value); + + std::string revisionSuffix; + if (manager.GetDialect() == Dialect_SQLite) + { + revisionSuffix = ", 0"; // TODO - REVISIONS + } std::string insert = ("(" + boost::lexical_cast(metadata[i].resource) + ", " + boost::lexical_cast(metadata[i].metadata) + ", " + - "${" + name + "})"); + "${" + name + "}" + revisionSuffix + ")"); std::string remove = ("(id=" + boost::lexical_cast(metadata[i].resource) + " AND type=" + boost::lexical_cast(metadata[i].metadata) @@ -2121,7 +2160,7 @@ ExecuteSetResourcesContentTags(manager, "MainDicomTags", "t", countMainDicomTags, mainDicomTags); - + ExecuteSetResourcesContentMetadata(manager, countMetadata, metadata); } #endif diff -r d663d9e44f8d -r e184dcadf163 Framework/Plugins/IndexBackend.h --- a/Framework/Plugins/IndexBackend.h Wed Apr 14 17:57:08 2021 +0200 +++ b/Framework/Plugins/IndexBackend.h Fri Apr 16 17:13:33 2021 +0200 @@ -231,6 +231,7 @@ const char* end) ORTHANC_OVERRIDE; virtual bool LookupMetadata(std::string& target /*out*/, + int64_t& revision /*out*/, DatabaseManager& manager, int64_t id, int32_t metadataType) ORTHANC_OVERRIDE; @@ -271,7 +272,8 @@ virtual void SetMetadata(DatabaseManager& manager, int64_t id, int32_t metadataType, - const char* value) ORTHANC_OVERRIDE; + const char* value, + int64_t revision) ORTHANC_OVERRIDE; virtual void SetProtectedPatient(DatabaseManager& manager, int64_t internalId, diff -r d663d9e44f8d -r e184dcadf163 Framework/Plugins/IndexUnitTests.h --- a/Framework/Plugins/IndexUnitTests.h Wed Apr 14 17:57:08 2021 +0200 +++ b/Framework/Plugins/IndexUnitTests.h Fri Apr 16 17:13:33 2021 +0200 @@ -270,32 +270,61 @@ ASSERT_TRUE(ci.back() == b || ci.back() == c); ASSERT_NE(ci.front(), ci.back()); - db.SetMetadata(*manager, a, Orthanc::MetadataType_ModifiedFrom, "modified"); - db.SetMetadata(*manager, a, Orthanc::MetadataType_LastUpdate, "update2"); - ASSERT_FALSE(db.LookupMetadata(s, *manager, b, Orthanc::MetadataType_LastUpdate)); - ASSERT_TRUE(db.LookupMetadata(s, *manager, a, Orthanc::MetadataType_LastUpdate)); + db.SetMetadata(*manager, a, Orthanc::MetadataType_ModifiedFrom, "modified", 42); + db.SetMetadata(*manager, a, Orthanc::MetadataType_LastUpdate, "update2", 43); + int64_t revision = -1; + ASSERT_FALSE(db.LookupMetadata(s, revision, *manager, b, Orthanc::MetadataType_LastUpdate)); + ASSERT_TRUE(db.LookupMetadata(s, revision, *manager, a, Orthanc::MetadataType_LastUpdate)); ASSERT_EQ("update2", s); - db.SetMetadata(*manager, a, Orthanc::MetadataType_LastUpdate, "update"); - ASSERT_TRUE(db.LookupMetadata(s, *manager, a, Orthanc::MetadataType_LastUpdate)); + +#if ORTHANC_ENABLE_SQLITE == 1 + ASSERT_EQ(43, revision); // Only SQLite implements revisions so far +#else + ASSERT_EQ(0, revision); +#endif + + db.SetMetadata(*manager, a, Orthanc::MetadataType_LastUpdate, "update", 44); + ASSERT_TRUE(db.LookupMetadata(s, revision, *manager, a, Orthanc::MetadataType_LastUpdate)); ASSERT_EQ("update", s); +#if ORTHANC_ENABLE_SQLITE == 1 + ASSERT_EQ(44, revision); // Only SQLite implements revisions so far +#else + ASSERT_EQ(0, revision); +#endif + std::list md; db.ListAvailableMetadata(md, *manager, a); ASSERT_EQ(2u, md.size()); ASSERT_TRUE(md.front() == Orthanc::MetadataType_ModifiedFrom || md.back() == Orthanc::MetadataType_ModifiedFrom); ASSERT_TRUE(md.front() == Orthanc::MetadataType_LastUpdate || md.back() == Orthanc::MetadataType_LastUpdate); std::string mdd; - ASSERT_TRUE(db.LookupMetadata(mdd, *manager, a, Orthanc::MetadataType_ModifiedFrom)); + ASSERT_TRUE(db.LookupMetadata(mdd, revision, *manager, a, Orthanc::MetadataType_ModifiedFrom)); ASSERT_EQ("modified", mdd); - ASSERT_TRUE(db.LookupMetadata(mdd, *manager, a, Orthanc::MetadataType_LastUpdate)); + +#if ORTHANC_ENABLE_SQLITE == 1 + ASSERT_EQ(42, revision); // Only SQLite implements revisions so far +#else + ASSERT_EQ(0, revision); +#endif + + ASSERT_TRUE(db.LookupMetadata(mdd, revision, *manager, a, Orthanc::MetadataType_LastUpdate)); ASSERT_EQ("update", mdd); +#if ORTHANC_ENABLE_SQLITE == 1 + ASSERT_EQ(44, revision); // Only SQLite implements revisions so far +#else + ASSERT_EQ(0, revision); +#endif + db.ListAvailableMetadata(md, *manager, b); ASSERT_EQ(0u, md.size()); + ASSERT_TRUE(db.LookupMetadata(s, revision, *manager, a, Orthanc::MetadataType_LastUpdate)); db.DeleteMetadata(*manager, a, Orthanc::MetadataType_LastUpdate); + ASSERT_FALSE(db.LookupMetadata(s, revision, *manager, a, Orthanc::MetadataType_LastUpdate)); db.DeleteMetadata(*manager, b, Orthanc::MetadataType_LastUpdate); - ASSERT_FALSE(db.LookupMetadata(s, *manager, a, Orthanc::MetadataType_LastUpdate)); + ASSERT_FALSE(db.LookupMetadata(s, revision, *manager, a, Orthanc::MetadataType_LastUpdate)); db.ListAvailableMetadata(md, *manager, a); ASSERT_EQ(1u, md.size()); diff -r d663d9e44f8d -r e184dcadf163 SQLite/Plugins/PrepareIndex.sql --- a/SQLite/Plugins/PrepareIndex.sql Wed Apr 14 17:57:08 2021 +0200 +++ b/SQLite/Plugins/PrepareIndex.sql Fri Apr 16 17:13:33 2021 +0200 @@ -30,6 +30,7 @@ id INTEGER REFERENCES Resources(internalId) ON DELETE CASCADE, type INTEGER, value TEXT, + revision INTEGER, PRIMARY KEY(id, type) );