Mercurial > hg > orthanc-databases
comparison Framework/Plugins/DatabaseBackendAdapterV3.cpp @ 569:f18e46d7dbf8 attach-custom-data
merged find-refactoring -> attach-custom-data
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 24 Sep 2024 15:04:21 +0200 |
parents | cd9521e04249 1a23f1ce3b98 |
children |
comparison
equal
deleted
inserted
replaced
368:82f73188b58d | 569:f18e46d7dbf8 |
---|---|
1 /** | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | 2 * Orthanc - A Lightweight, RESTful DICOM Store |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
4 * Department, University Hospital of Liege, Belgium | 4 * Department, University Hospital of Liege, Belgium |
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium | 5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium | |
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium | |
6 * | 8 * |
7 * This program is free software: you can redistribute it and/or | 9 * This program is free software: you can redistribute it and/or |
8 * modify it under the terms of the GNU Affero General Public License | 10 * modify it under the terms of the GNU Affero General Public License |
9 * as published by the Free Software Foundation, either version 3 of | 11 * as published by the Free Software Foundation, either version 3 of |
10 * the License, or (at your option) any later version. | 12 * the License, or (at your option) any later version. |
22 #include "DatabaseBackendAdapterV3.h" | 24 #include "DatabaseBackendAdapterV3.h" |
23 | 25 |
24 #if defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE) // Macro introduced in Orthanc 1.3.1 | 26 #if defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE) // Macro introduced in Orthanc 1.3.1 |
25 # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 9, 2) | 27 # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 9, 2) |
26 | 28 |
29 #include "IndexConnectionsPool.h" | |
30 | |
27 #include <Logging.h> | 31 #include <Logging.h> |
28 #include <MultiThreading/SharedMessageQueue.h> | |
29 #include <OrthancException.h> | 32 #include <OrthancException.h> |
30 | 33 |
31 #include <stdexcept> | 34 #include <stdexcept> |
32 #include <list> | 35 #include <list> |
33 #include <string> | 36 #include <string> |
79 target.push_back(*it); | 82 target.push_back(*it); |
80 } | 83 } |
81 } | 84 } |
82 | 85 |
83 | 86 |
84 class DatabaseBackendAdapterV3::Adapter : public boost::noncopyable | |
85 { | |
86 private: | |
87 class ManagerReference : public Orthanc::IDynamicObject | |
88 { | |
89 private: | |
90 DatabaseManager* manager_; | |
91 | |
92 public: | |
93 ManagerReference(DatabaseManager& manager) : | |
94 manager_(&manager) | |
95 { | |
96 } | |
97 | |
98 DatabaseManager& GetManager() | |
99 { | |
100 assert(manager_ != NULL); | |
101 return *manager_; | |
102 } | |
103 }; | |
104 | |
105 std::unique_ptr<IndexBackend> backend_; | |
106 OrthancPluginContext* context_; | |
107 boost::shared_mutex connectionsMutex_; | |
108 size_t countConnections_; | |
109 std::list<DatabaseManager*> connections_; | |
110 Orthanc::SharedMessageQueue availableConnections_; | |
111 | |
112 public: | |
113 Adapter(IndexBackend* backend, | |
114 size_t countConnections) : | |
115 backend_(backend), | |
116 countConnections_(countConnections) | |
117 { | |
118 if (countConnections == 0) | |
119 { | |
120 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, | |
121 "There must be a non-zero number of connections to the database"); | |
122 } | |
123 else if (backend == NULL) | |
124 { | |
125 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
126 } | |
127 else | |
128 { | |
129 context_ = backend_->GetContext(); | |
130 } | |
131 } | |
132 | |
133 ~Adapter() | |
134 { | |
135 for (std::list<DatabaseManager*>::iterator | |
136 it = connections_.begin(); it != connections_.end(); ++it) | |
137 { | |
138 assert(*it != NULL); | |
139 delete *it; | |
140 } | |
141 } | |
142 | |
143 OrthancPluginContext* GetContext() const | |
144 { | |
145 return context_; | |
146 } | |
147 | |
148 void OpenConnections() | |
149 { | |
150 boost::unique_lock<boost::shared_mutex> lock(connectionsMutex_); | |
151 | |
152 if (connections_.size() == 0) | |
153 { | |
154 assert(backend_.get() != NULL); | |
155 | |
156 { | |
157 std::unique_ptr<DatabaseManager> manager(new DatabaseManager(backend_->CreateDatabaseFactory())); | |
158 manager->GetDatabase(); // Make sure to open the database connection | |
159 | |
160 backend_->ConfigureDatabase(*manager); | |
161 connections_.push_back(manager.release()); | |
162 } | |
163 | |
164 for (size_t i = 1; i < countConnections_; i++) | |
165 { | |
166 connections_.push_back(new DatabaseManager(backend_->CreateDatabaseFactory())); | |
167 connections_.back()->GetDatabase(); // Make sure to open the database connection | |
168 } | |
169 | |
170 for (std::list<DatabaseManager*>::iterator | |
171 it = connections_.begin(); it != connections_.end(); ++it) | |
172 { | |
173 assert(*it != NULL); | |
174 availableConnections_.Enqueue(new ManagerReference(**it)); | |
175 } | |
176 } | |
177 else | |
178 { | |
179 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
180 } | |
181 } | |
182 | |
183 void CloseConnections() | |
184 { | |
185 boost::unique_lock<boost::shared_mutex> lock(connectionsMutex_); | |
186 | |
187 if (connections_.size() != countConnections_) | |
188 { | |
189 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
190 } | |
191 else if (availableConnections_.GetSize() != countConnections_) | |
192 { | |
193 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database, "Some connections are still in use, bug in the Orthanc core"); | |
194 } | |
195 else | |
196 { | |
197 for (std::list<DatabaseManager*>::iterator | |
198 it = connections_.begin(); it != connections_.end(); ++it) | |
199 { | |
200 assert(*it != NULL); | |
201 (*it)->Close(); | |
202 } | |
203 } | |
204 } | |
205 | |
206 class DatabaseAccessor : public boost::noncopyable | |
207 { | |
208 private: | |
209 boost::shared_lock<boost::shared_mutex> lock_; | |
210 Adapter& adapter_; | |
211 DatabaseManager* manager_; | |
212 | |
213 public: | |
214 DatabaseAccessor(Adapter& adapter) : | |
215 lock_(adapter.connectionsMutex_), | |
216 adapter_(adapter), | |
217 manager_(NULL) | |
218 { | |
219 for (;;) | |
220 { | |
221 std::unique_ptr<Orthanc::IDynamicObject> manager(adapter.availableConnections_.Dequeue(100)); | |
222 if (manager.get() != NULL) | |
223 { | |
224 manager_ = &dynamic_cast<ManagerReference&>(*manager).GetManager(); | |
225 return; | |
226 } | |
227 } | |
228 } | |
229 | |
230 ~DatabaseAccessor() | |
231 { | |
232 assert(manager_ != NULL); | |
233 adapter_.availableConnections_.Enqueue(new ManagerReference(*manager_)); | |
234 } | |
235 | |
236 IndexBackend& GetBackend() const | |
237 { | |
238 return *adapter_.backend_; | |
239 } | |
240 | |
241 DatabaseManager& GetManager() const | |
242 { | |
243 assert(manager_ != NULL); | |
244 return *manager_; | |
245 } | |
246 }; | |
247 }; | |
248 | |
249 | |
250 class DatabaseBackendAdapterV3::Output : public IDatabaseBackendOutput | 87 class DatabaseBackendAdapterV3::Output : public IDatabaseBackendOutput |
251 { | 88 { |
252 private: | 89 private: |
253 struct Metadata | 90 struct Metadata |
254 { | 91 { |
801 | 638 |
802 | 639 |
803 class DatabaseBackendAdapterV3::Transaction : public boost::noncopyable | 640 class DatabaseBackendAdapterV3::Transaction : public boost::noncopyable |
804 { | 641 { |
805 private: | 642 private: |
806 Adapter& adapter_; | 643 IndexConnectionsPool& pool_; |
807 std::unique_ptr<Adapter::DatabaseAccessor> accessor_; | 644 std::unique_ptr<IndexConnectionsPool::Accessor> accessor_; |
808 std::unique_ptr<Output> output_; | 645 std::unique_ptr<Output> output_; |
809 | 646 |
810 public: | 647 public: |
811 Transaction(Adapter& adapter) : | 648 Transaction(IndexConnectionsPool& pool) : |
812 adapter_(adapter), | 649 pool_(pool), |
813 accessor_(new Adapter::DatabaseAccessor(adapter)), | 650 accessor_(new IndexConnectionsPool::Accessor(pool)), |
814 output_(new Output) | 651 output_(new Output) |
815 { | 652 { |
816 } | 653 } |
817 | 654 |
818 ~Transaction() | 655 ~Transaction() |
960 } | 797 } |
961 | 798 |
962 | 799 |
963 static OrthancPluginErrorCode Open(void* database) | 800 static OrthancPluginErrorCode Open(void* database) |
964 { | 801 { |
965 DatabaseBackendAdapterV3::Adapter* adapter = reinterpret_cast<DatabaseBackendAdapterV3::Adapter*>(database); | 802 IndexConnectionsPool* pool = reinterpret_cast<IndexConnectionsPool*>(database); |
966 | 803 |
967 try | 804 try |
968 { | 805 { |
969 adapter->OpenConnections(); | 806 std::list<IdentifierTag> identifierTags; |
970 return OrthancPluginErrorCode_Success; | 807 pool->OpenConnections(false, identifierTags); |
971 } | 808 return OrthancPluginErrorCode_Success; |
972 ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext()); | 809 } |
810 ORTHANC_PLUGINS_DATABASE_CATCH(pool->GetContext()); | |
973 } | 811 } |
974 | 812 |
975 | 813 |
976 static OrthancPluginErrorCode Close(void* database) | 814 static OrthancPluginErrorCode Close(void* database) |
977 { | 815 { |
978 DatabaseBackendAdapterV3::Adapter* adapter = reinterpret_cast<DatabaseBackendAdapterV3::Adapter*>(database); | 816 IndexConnectionsPool* pool = reinterpret_cast<IndexConnectionsPool*>(database); |
979 | 817 |
980 try | 818 try |
981 { | 819 { |
982 adapter->CloseConnections(); | 820 pool->CloseConnections(); |
983 return OrthancPluginErrorCode_Success; | 821 return OrthancPluginErrorCode_Success; |
984 } | 822 } |
985 ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext()); | 823 ORTHANC_PLUGINS_DATABASE_CATCH(pool->GetContext()); |
986 } | 824 } |
987 | 825 |
988 | 826 |
989 static OrthancPluginErrorCode DestructDatabase(void* database) | 827 static OrthancPluginErrorCode DestructDatabase(void* database) |
990 { | 828 { |
991 DatabaseBackendAdapterV3::Adapter* adapter = reinterpret_cast<DatabaseBackendAdapterV3::Adapter*>(database); | 829 IndexConnectionsPool* pool = reinterpret_cast<IndexConnectionsPool*>(database); |
992 | 830 |
993 if (adapter == NULL) | 831 if (pool == NULL) |
994 { | 832 { |
995 return OrthancPluginErrorCode_InternalError; | 833 return OrthancPluginErrorCode_InternalError; |
996 } | 834 } |
997 else | 835 else |
998 { | 836 { |
1000 { | 838 { |
1001 isBackendInUse_ = false; | 839 isBackendInUse_ = false; |
1002 } | 840 } |
1003 else | 841 else |
1004 { | 842 { |
1005 OrthancPluginLogError(adapter->GetContext(), "More than one index backend was registered, internal error"); | 843 OrthancPluginLogError(pool->GetContext(), "More than one index backend was registered, internal error"); |
1006 } | 844 } |
1007 | 845 |
1008 delete adapter; | 846 delete pool; |
1009 | 847 |
1010 return OrthancPluginErrorCode_Success; | 848 return OrthancPluginErrorCode_Success; |
1011 } | 849 } |
1012 } | 850 } |
1013 | 851 |
1014 | 852 |
1015 static OrthancPluginErrorCode GetDatabaseVersion(void* database, | 853 static OrthancPluginErrorCode GetDatabaseVersion(void* database, |
1016 uint32_t* version) | 854 uint32_t* version) |
1017 { | 855 { |
1018 DatabaseBackendAdapterV3::Adapter* adapter = reinterpret_cast<DatabaseBackendAdapterV3::Adapter*>(database); | 856 IndexConnectionsPool* pool = reinterpret_cast<IndexConnectionsPool*>(database); |
1019 | 857 |
1020 try | 858 try |
1021 { | 859 { |
1022 DatabaseBackendAdapterV3::Adapter::DatabaseAccessor accessor(*adapter); | 860 IndexConnectionsPool::Accessor accessor(*pool); |
1023 *version = accessor.GetBackend().GetDatabaseVersion(accessor.GetManager()); | 861 *version = accessor.GetBackend().GetDatabaseVersion(accessor.GetManager()); |
1024 return OrthancPluginErrorCode_Success; | 862 return OrthancPluginErrorCode_Success; |
1025 } | 863 } |
1026 ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext()); | 864 ORTHANC_PLUGINS_DATABASE_CATCH(pool->GetContext()); |
1027 } | 865 } |
1028 | 866 |
1029 | 867 |
1030 static OrthancPluginErrorCode UpgradeDatabase(void* database, | 868 static OrthancPluginErrorCode UpgradeDatabase(void* database, |
1031 OrthancPluginStorageArea* storageArea, | 869 OrthancPluginStorageArea* storageArea, |
1032 uint32_t targetVersion) | 870 uint32_t targetVersion) |
1033 { | 871 { |
1034 DatabaseBackendAdapterV3::Adapter* adapter = reinterpret_cast<DatabaseBackendAdapterV3::Adapter*>(database); | 872 IndexConnectionsPool* pool = reinterpret_cast<IndexConnectionsPool*>(database); |
1035 | 873 |
1036 try | 874 try |
1037 { | 875 { |
1038 DatabaseBackendAdapterV3::Adapter::DatabaseAccessor accessor(*adapter); | 876 IndexConnectionsPool::Accessor accessor(*pool); |
1039 accessor.GetBackend().UpgradeDatabase(accessor.GetManager(), targetVersion, storageArea); | 877 accessor.GetBackend().UpgradeDatabase(accessor.GetManager(), targetVersion, storageArea); |
1040 return OrthancPluginErrorCode_Success; | 878 return OrthancPluginErrorCode_Success; |
1041 } | 879 } |
1042 ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext()); | 880 ORTHANC_PLUGINS_DATABASE_CATCH(pool->GetContext()); |
1043 } | 881 } |
1044 | 882 |
1045 | 883 |
1046 static OrthancPluginErrorCode HasRevisionsSupport(void* database, | 884 static OrthancPluginErrorCode HasRevisionsSupport(void* database, |
1047 uint8_t* target) | 885 uint8_t* target) |
1048 { | 886 { |
1049 DatabaseBackendAdapterV3::Adapter* adapter = reinterpret_cast<DatabaseBackendAdapterV3::Adapter*>(database); | 887 IndexConnectionsPool* pool = reinterpret_cast<IndexConnectionsPool*>(database); |
1050 | 888 |
1051 try | 889 try |
1052 { | 890 { |
1053 DatabaseBackendAdapterV3::Adapter::DatabaseAccessor accessor(*adapter); | 891 IndexConnectionsPool::Accessor accessor(*pool); |
1054 *target = (accessor.GetBackend().HasRevisionsSupport() ? 1 : 0); | 892 *target = (accessor.GetBackend().HasRevisionsSupport() ? 1 : 0); |
1055 return OrthancPluginErrorCode_Success; | 893 return OrthancPluginErrorCode_Success; |
1056 } | 894 } |
1057 ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext()); | 895 ORTHANC_PLUGINS_DATABASE_CATCH(pool->GetContext()); |
1058 } | 896 } |
1059 | 897 |
1060 | 898 |
1061 static OrthancPluginErrorCode StartTransaction(void* database, | 899 static OrthancPluginErrorCode StartTransaction(void* database, |
1062 OrthancPluginDatabaseTransaction** target /* out */, | 900 OrthancPluginDatabaseTransaction** target /* out */, |
1063 OrthancPluginDatabaseTransactionType type) | 901 OrthancPluginDatabaseTransactionType type) |
1064 { | 902 { |
1065 DatabaseBackendAdapterV3::Adapter* adapter = reinterpret_cast<DatabaseBackendAdapterV3::Adapter*>(database); | 903 IndexConnectionsPool* pool = reinterpret_cast<IndexConnectionsPool*>(database); |
1066 | 904 |
1067 try | 905 try |
1068 { | 906 { |
1069 std::unique_ptr<DatabaseBackendAdapterV3::Transaction> transaction(new DatabaseBackendAdapterV3::Transaction(*adapter)); | 907 std::unique_ptr<DatabaseBackendAdapterV3::Transaction> transaction(new DatabaseBackendAdapterV3::Transaction(*pool)); |
1070 | 908 |
1071 switch (type) | 909 switch (type) |
1072 { | 910 { |
1073 case OrthancPluginDatabaseTransactionType_ReadOnly: | 911 case OrthancPluginDatabaseTransactionType_ReadOnly: |
1074 transaction->GetManager().StartTransaction(TransactionType_ReadOnly); | 912 transaction->GetManager().StartTransaction(TransactionType_ReadOnly); |
1084 | 922 |
1085 *target = reinterpret_cast<OrthancPluginDatabaseTransaction*>(transaction.release()); | 923 *target = reinterpret_cast<OrthancPluginDatabaseTransaction*>(transaction.release()); |
1086 | 924 |
1087 return OrthancPluginErrorCode_Success; | 925 return OrthancPluginErrorCode_Success; |
1088 } | 926 } |
1089 ORTHANC_PLUGINS_DATABASE_CATCH(adapter->GetContext()); | 927 ORTHANC_PLUGINS_DATABASE_CATCH(pool->GetContext()); |
1090 } | 928 } |
1091 | 929 |
1092 | 930 |
1093 static OrthancPluginErrorCode DestructTransaction(OrthancPluginDatabaseTransaction* transaction) | 931 static OrthancPluginErrorCode DestructTransaction(OrthancPluginDatabaseTransaction* transaction) |
1094 { | 932 { |
1665 { | 1503 { |
1666 DatabaseBackendAdapterV3::Transaction* t = reinterpret_cast<DatabaseBackendAdapterV3::Transaction*>(transaction); | 1504 DatabaseBackendAdapterV3::Transaction* t = reinterpret_cast<DatabaseBackendAdapterV3::Transaction*>(transaction); |
1667 | 1505 |
1668 try | 1506 try |
1669 { | 1507 { |
1670 OrthancPluginExportedResource exported; | 1508 t->GetOutput().Clear(); |
1671 exported.seq = 0; | 1509 t->GetBackend().LogExportedResource(t->GetManager(), resourceType, publicId, modality, date, |
1672 exported.resourceType = resourceType; | 1510 patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid); |
1673 exported.publicId = publicId; | |
1674 exported.modality = modality; | |
1675 exported.date = date; | |
1676 exported.patientId = patientId; | |
1677 exported.studyInstanceUid = studyInstanceUid; | |
1678 exported.seriesInstanceUid = seriesInstanceUid; | |
1679 exported.sopInstanceUid = sopInstanceUid; | |
1680 | |
1681 t->GetOutput().Clear(); | |
1682 t->GetBackend().LogExportedResource(t->GetManager(), exported); | |
1683 return OrthancPluginErrorCode_Success; | 1511 return OrthancPluginErrorCode_Success; |
1684 } | 1512 } |
1685 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetBackend().GetContext()); | 1513 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetBackend().GetContext()); |
1686 } | 1514 } |
1687 | 1515 |
1812 | 1640 |
1813 try | 1641 try |
1814 { | 1642 { |
1815 t->GetOutput().Clear(); | 1643 t->GetOutput().Clear(); |
1816 | 1644 |
1817 std::vector<Orthanc::DatabaseConstraint> lookup; | 1645 DatabaseConstraints lookup; |
1818 lookup.reserve(constraintsCount); | |
1819 | 1646 |
1820 for (uint32_t i = 0; i < constraintsCount; i++) | 1647 for (uint32_t i = 0; i < constraintsCount; i++) |
1821 { | 1648 { |
1822 lookup.push_back(Orthanc::DatabaseConstraint(constraints[i])); | 1649 lookup.AddConstraint(new DatabaseConstraint(constraints[i])); |
1823 } | 1650 } |
1824 | 1651 |
1825 t->GetBackend().LookupResources(t->GetOutput(), t->GetManager(), lookup, queryLevel, limit, (requestSomeInstanceId != 0)); | 1652 std::set<std::string> noLabel; |
1653 t->GetBackend().LookupResources(t->GetOutput(), t->GetManager(), lookup, queryLevel, noLabel, | |
1654 LabelsConstraint_All, limit, (requestSomeInstanceId != 0)); | |
1826 return OrthancPluginErrorCode_Success; | 1655 return OrthancPluginErrorCode_Success; |
1827 } | 1656 } |
1828 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetBackend().GetContext()); | 1657 ORTHANC_PLUGINS_DATABASE_CATCH(t->GetBackend().GetContext()); |
1829 } | 1658 } |
1830 | 1659 |
1987 | 1816 |
1988 void DatabaseBackendAdapterV3::Register(IndexBackend* backend, | 1817 void DatabaseBackendAdapterV3::Register(IndexBackend* backend, |
1989 size_t countConnections, | 1818 size_t countConnections, |
1990 unsigned int maxDatabaseRetries) | 1819 unsigned int maxDatabaseRetries) |
1991 { | 1820 { |
1821 std::unique_ptr<IndexBackend> protection(backend); | |
1822 | |
1992 if (isBackendInUse_) | 1823 if (isBackendInUse_) |
1993 { | 1824 { |
1994 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | 1825 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
1995 } | 1826 } |
1996 | 1827 |
2070 params.setGlobalProperty = SetGlobalProperty; | 1901 params.setGlobalProperty = SetGlobalProperty; |
2071 params.setMetadata = SetMetadata; | 1902 params.setMetadata = SetMetadata; |
2072 params.setProtectedPatient = SetProtectedPatient; | 1903 params.setProtectedPatient = SetProtectedPatient; |
2073 params.setResourcesContent = SetResourcesContent; | 1904 params.setResourcesContent = SetResourcesContent; |
2074 | 1905 |
2075 OrthancPluginContext* context = backend->GetContext(); | 1906 OrthancPluginContext* context = protection->GetContext(); |
2076 | 1907 |
2077 if (OrthancPluginRegisterDatabaseBackendV3( | 1908 if (OrthancPluginRegisterDatabaseBackendV3( |
2078 context, ¶ms, sizeof(params), maxDatabaseRetries, | 1909 context, ¶ms, sizeof(params), maxDatabaseRetries, |
2079 new Adapter(backend, countConnections)) != OrthancPluginErrorCode_Success) | 1910 new IndexConnectionsPool(protection.release(), countConnections)) != OrthancPluginErrorCode_Success) |
2080 { | 1911 { |
1912 delete backend; | |
2081 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Unable to register the database backend"); | 1913 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Unable to register the database backend"); |
2082 } | 1914 } |
2083 | 1915 |
2084 backend->SetOutputFactory(new Factory); | 1916 backend->SetOutputFactory(new Factory); |
2085 | 1917 |