comparison Framework/Plugins/IndexConnectionsPool.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 54d518dcd74a
children
comparison
equal deleted inserted replaced
368:82f73188b58d 569:f18e46d7dbf8
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, 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
8 *
9 * This program is free software: you can redistribute it and/or
10 * modify it under the terms of the GNU Affero General Public License
11 * as published by the Free Software Foundation, either version 3 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 **/
22
23
24 #include "IndexConnectionsPool.h"
25
26 namespace OrthancDatabases
27 {
28 class IndexConnectionsPool::ManagerReference : public Orthanc::IDynamicObject
29 {
30 private:
31 DatabaseManager* manager_;
32
33 public:
34 explicit ManagerReference(DatabaseManager& manager) :
35 manager_(&manager)
36 {
37 }
38
39 DatabaseManager& GetManager()
40 {
41 assert(manager_ != NULL);
42 return *manager_;
43 }
44 };
45
46
47 IndexConnectionsPool::IndexConnectionsPool(IndexBackend* backend,
48 size_t countConnections) :
49 backend_(backend),
50 countConnections_(countConnections)
51 {
52 if (countConnections == 0)
53 {
54 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange,
55 "There must be a non-zero number of connections to the database");
56 }
57 else if (backend == NULL)
58 {
59 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
60 }
61 else
62 {
63 context_ = backend_->GetContext();
64 }
65 }
66
67
68 IndexConnectionsPool::~IndexConnectionsPool()
69 {
70 for (std::list<DatabaseManager*>::iterator
71 it = connections_.begin(); it != connections_.end(); ++it)
72 {
73 assert(*it != NULL);
74 delete *it;
75 }
76 }
77
78
79 void IndexConnectionsPool::OpenConnections(bool hasIdentifierTags,
80 const std::list<IdentifierTag>& identifierTags)
81 {
82 boost::unique_lock<boost::shared_mutex> lock(connectionsMutex_);
83
84 if (connections_.size() == 0)
85 {
86 assert(backend_.get() != NULL);
87
88 {
89 std::unique_ptr<DatabaseManager> manager(new DatabaseManager(backend_->CreateDatabaseFactory()));
90 manager->GetDatabase(); // Make sure to open the database connection
91
92 backend_->ConfigureDatabase(*manager, hasIdentifierTags, identifierTags);
93 connections_.push_back(manager.release());
94 }
95
96 for (size_t i = 1; i < countConnections_; i++)
97 {
98 connections_.push_back(new DatabaseManager(backend_->CreateDatabaseFactory()));
99 connections_.back()->GetDatabase(); // Make sure to open the database connection
100 }
101
102 for (std::list<DatabaseManager*>::iterator
103 it = connections_.begin(); it != connections_.end(); ++it)
104 {
105 assert(*it != NULL);
106 availableConnections_.Enqueue(new ManagerReference(**it));
107 }
108 }
109 else
110 {
111 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
112 }
113 }
114
115
116 void IndexConnectionsPool::CloseConnections()
117 {
118 boost::unique_lock<boost::shared_mutex> lock(connectionsMutex_);
119
120 if (connections_.size() != countConnections_)
121 {
122 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
123 }
124 else if (availableConnections_.GetSize() != countConnections_)
125 {
126 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database, "Some connections are still in use, bug in the Orthanc core");
127 }
128 else
129 {
130 for (std::list<DatabaseManager*>::iterator
131 it = connections_.begin(); it != connections_.end(); ++it)
132 {
133 assert(*it != NULL);
134 (*it)->Close();
135 }
136 }
137 }
138
139
140 IndexConnectionsPool::Accessor::Accessor(IndexConnectionsPool& pool) :
141 lock_(pool.connectionsMutex_),
142 pool_(pool),
143 manager_(NULL)
144 {
145 for (;;)
146 {
147 std::unique_ptr<Orthanc::IDynamicObject> manager(pool.availableConnections_.Dequeue(100));
148 if (manager.get() != NULL)
149 {
150 manager_ = &dynamic_cast<ManagerReference&>(*manager).GetManager();
151 return;
152 }
153 }
154 }
155
156
157 IndexConnectionsPool::Accessor::~Accessor()
158 {
159 assert(manager_ != NULL);
160 pool_.availableConnections_.Enqueue(new ManagerReference(*manager_));
161 }
162
163
164 IndexBackend& IndexConnectionsPool::Accessor::GetBackend() const
165 {
166 return *pool_.backend_;
167 }
168
169
170 DatabaseManager& IndexConnectionsPool::Accessor::GetManager() const
171 {
172 assert(manager_ != NULL);
173 return *manager_;
174 }
175 }