Mercurial > hg > orthanc-databases
comparison PostgreSQL/Plugins/PostgreSQLIndex.cpp @ 226:a4918d57435c
DatabaseManager doesn't IDatabaseFactory anymore
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 02 Apr 2021 19:23:36 +0200 |
parents | 94c9908e6aca |
children | 35598014f140 |
comparison
equal
deleted
inserted
replaced
225:94c9908e6aca | 226:a4918d57435c |
---|---|
43 } | 43 } |
44 | 44 |
45 | 45 |
46 namespace OrthancDatabases | 46 namespace OrthancDatabases |
47 { | 47 { |
48 IDatabase* PostgreSQLIndex::OpenInternal() | 48 PostgreSQLIndex::PostgreSQLIndex(OrthancPluginContext* context, |
49 const PostgreSQLParameters& parameters) : | |
50 IndexBackend(context), | |
51 parameters_(parameters), | |
52 clearAll_(false) | |
53 { | |
54 } | |
55 | |
56 | |
57 IDatabase* PostgreSQLIndex::OpenDatabaseConnection() | |
58 { | |
59 return PostgreSQLDatabase::OpenDatabaseConnection(parameters_); | |
60 } | |
61 | |
62 | |
63 void PostgreSQLIndex::ConfigureDatabase(IDatabase& database) | |
49 { | 64 { |
50 uint32_t expectedVersion = 6; | 65 uint32_t expectedVersion = 6; |
51 | 66 |
52 if (GetContext()) // "GetContext()" can possibly be NULL in the unit tests | 67 if (GetContext()) // "GetContext()" can possibly be NULL in the unit tests |
53 { | 68 { |
61 << "expecting the DB schema version " << expectedVersion | 76 << "expecting the DB schema version " << expectedVersion |
62 << ", but this plugin is only compatible with version 6"; | 77 << ", but this plugin is only compatible with version 6"; |
63 throw Orthanc::OrthancException(Orthanc::ErrorCode_Plugin); | 78 throw Orthanc::OrthancException(Orthanc::ErrorCode_Plugin); |
64 } | 79 } |
65 | 80 |
66 std::unique_ptr<PostgreSQLDatabase> db(new PostgreSQLDatabase(parameters_)); | 81 PostgreSQLDatabase& db = dynamic_cast<PostgreSQLDatabase&>(database); |
67 | |
68 db->Open(); | |
69 | 82 |
70 if (parameters_.HasLock()) | 83 if (parameters_.HasLock()) |
71 { | 84 { |
72 db->AdvisoryLock(POSTGRESQL_LOCK_INDEX); | 85 db.AdvisoryLock(POSTGRESQL_LOCK_INDEX); |
73 } | 86 } |
74 | 87 |
75 { | 88 { |
76 PostgreSQLDatabase::TransientAdvisoryLock lock(*db, POSTGRESQL_LOCK_DATABASE_SETUP); | 89 PostgreSQLDatabase::TransientAdvisoryLock lock(db, POSTGRESQL_LOCK_DATABASE_SETUP); |
77 | 90 |
78 if (clearAll_) | 91 if (clearAll_) |
79 { | 92 { |
80 db->ClearAll(); | 93 db.ClearAll(); |
81 } | 94 } |
82 | 95 |
83 { | 96 { |
84 PostgreSQLTransaction t(*db, TransactionType_ReadWrite); | 97 PostgreSQLTransaction t(db, TransactionType_ReadWrite); |
85 | 98 |
86 if (!db->DoesTableExist("Resources")) | 99 if (!db.DoesTableExist("Resources")) |
87 { | 100 { |
88 std::string query; | 101 std::string query; |
89 | 102 |
90 Orthanc::EmbeddedResources::GetFileResource | 103 Orthanc::EmbeddedResources::GetFileResource |
91 (query, Orthanc::EmbeddedResources::POSTGRESQL_PREPARE_INDEX); | 104 (query, Orthanc::EmbeddedResources::POSTGRESQL_PREPARE_INDEX); |
92 db->Execute(query); | 105 db.Execute(query); |
93 | 106 |
94 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion, expectedVersion); | 107 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion, expectedVersion); |
95 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, 1); | 108 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, 1); |
96 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasTrigramIndex, 0); | 109 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasTrigramIndex, 0); |
97 } | 110 } |
98 | 111 |
99 if (!db->DoesTableExist("Resources")) | 112 if (!db.DoesTableExist("Resources")) |
100 { | 113 { |
101 LOG(ERROR) << "Corrupted PostgreSQL database"; | 114 LOG(ERROR) << "Corrupted PostgreSQL database"; |
102 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | 115 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
103 } | 116 } |
104 | 117 |
105 int version = 0; | 118 int version = 0; |
106 if (!LookupGlobalIntegerProperty(version, *db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion) || | 119 if (!LookupGlobalIntegerProperty(version, db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion) || |
107 version != 6) | 120 version != 6) |
108 { | 121 { |
109 LOG(ERROR) << "PostgreSQL plugin is incompatible with database schema version: " << version; | 122 LOG(ERROR) << "PostgreSQL plugin is incompatible with database schema version: " << version; |
110 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | 123 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); |
111 } | 124 } |
112 | 125 |
113 int revision; | 126 int revision; |
114 if (!LookupGlobalIntegerProperty(revision, *db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel)) | 127 if (!LookupGlobalIntegerProperty(revision, db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel)) |
115 { | 128 { |
116 revision = 1; | 129 revision = 1; |
117 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); | 130 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); |
118 } | 131 } |
119 | 132 |
120 if (revision != 1) | 133 if (revision != 1) |
121 { | 134 { |
122 LOG(ERROR) << "PostgreSQL plugin is incompatible with database schema revision: " << revision; | 135 LOG(ERROR) << "PostgreSQL plugin is incompatible with database schema revision: " << revision; |
125 | 138 |
126 t.Commit(); | 139 t.Commit(); |
127 } | 140 } |
128 | 141 |
129 { | 142 { |
130 PostgreSQLTransaction t(*db, TransactionType_ReadWrite); | 143 PostgreSQLTransaction t(db, TransactionType_ReadWrite); |
131 | 144 |
132 int hasTrigram = 0; | 145 int hasTrigram = 0; |
133 if (!LookupGlobalIntegerProperty(hasTrigram, *db, t, MISSING_SERVER_IDENTIFIER, | 146 if (!LookupGlobalIntegerProperty(hasTrigram, db, t, MISSING_SERVER_IDENTIFIER, |
134 Orthanc::GlobalProperty_HasTrigramIndex) || | 147 Orthanc::GlobalProperty_HasTrigramIndex) || |
135 hasTrigram != 1) | 148 hasTrigram != 1) |
136 { | 149 { |
137 /** | 150 /** |
138 * Apply fix for performance issue (speed up wildcard search | 151 * Apply fix for performance issue (speed up wildcard search |
148 { | 161 { |
149 // We've observed 9 minutes on DB with 100000 studies | 162 // We've observed 9 minutes on DB with 100000 studies |
150 LOG(WARNING) << "Trying to enable trigram matching on the PostgreSQL database " | 163 LOG(WARNING) << "Trying to enable trigram matching on the PostgreSQL database " |
151 << "to speed up wildcard searches. This may take several minutes"; | 164 << "to speed up wildcard searches. This may take several minutes"; |
152 | 165 |
153 db->Execute( | 166 db.Execute( |
154 "CREATE EXTENSION IF NOT EXISTS pg_trgm; " | 167 "CREATE EXTENSION IF NOT EXISTS pg_trgm; " |
155 "CREATE INDEX DicomIdentifiersIndexValues2 ON DicomIdentifiers USING gin(value gin_trgm_ops);"); | 168 "CREATE INDEX DicomIdentifiersIndexValues2 ON DicomIdentifiers USING gin(value gin_trgm_ops);"); |
156 | 169 |
157 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasTrigramIndex, 1); | 170 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasTrigramIndex, 1); |
158 LOG(WARNING) << "Trigram index has been created"; | 171 LOG(WARNING) << "Trigram index has been created"; |
159 | 172 |
160 t.Commit(); | 173 t.Commit(); |
161 } | 174 } |
162 catch (Orthanc::OrthancException&) | 175 catch (Orthanc::OrthancException&) |
172 t.Commit(); | 185 t.Commit(); |
173 } | 186 } |
174 } | 187 } |
175 | 188 |
176 { | 189 { |
177 PostgreSQLTransaction t(*db, TransactionType_ReadWrite); | 190 PostgreSQLTransaction t(db, TransactionType_ReadWrite); |
178 | 191 |
179 int property = 0; | 192 int property = 0; |
180 if (!LookupGlobalIntegerProperty(property, *db, t, MISSING_SERVER_IDENTIFIER, | 193 if (!LookupGlobalIntegerProperty(property, db, t, MISSING_SERVER_IDENTIFIER, |
181 Orthanc::GlobalProperty_HasCreateInstance) || | 194 Orthanc::GlobalProperty_HasCreateInstance) || |
182 property != 2) | 195 property != 2) |
183 { | 196 { |
184 LOG(INFO) << "Installing the CreateInstance extension"; | 197 LOG(INFO) << "Installing the CreateInstance extension"; |
185 | 198 |
186 if (property == 1) | 199 if (property == 1) |
187 { | 200 { |
188 // Drop older, experimental versions of this extension | 201 // Drop older, experimental versions of this extension |
189 db->Execute("DROP FUNCTION CreateInstance(" | 202 db.Execute("DROP FUNCTION CreateInstance(" |
190 "IN patient TEXT, IN study TEXT, IN series TEXT, in instance TEXT)"); | 203 "IN patient TEXT, IN study TEXT, IN series TEXT, in instance TEXT)"); |
191 } | 204 } |
192 | 205 |
193 std::string query; | 206 std::string query; |
194 Orthanc::EmbeddedResources::GetFileResource | 207 Orthanc::EmbeddedResources::GetFileResource |
195 (query, Orthanc::EmbeddedResources::POSTGRESQL_CREATE_INSTANCE); | 208 (query, Orthanc::EmbeddedResources::POSTGRESQL_CREATE_INSTANCE); |
196 db->Execute(query); | 209 db.Execute(query); |
197 | 210 |
198 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasCreateInstance, 2); | 211 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasCreateInstance, 2); |
199 } | 212 } |
200 | 213 |
201 | 214 |
202 if (!LookupGlobalIntegerProperty(property, *db, t, MISSING_SERVER_IDENTIFIER, | 215 if (!LookupGlobalIntegerProperty(property, db, t, MISSING_SERVER_IDENTIFIER, |
203 Orthanc::GlobalProperty_GetTotalSizeIsFast) || | 216 Orthanc::GlobalProperty_GetTotalSizeIsFast) || |
204 property != 1) | 217 property != 1) |
205 { | 218 { |
206 LOG(INFO) << "Installing the FastTotalSize extension"; | 219 LOG(INFO) << "Installing the FastTotalSize extension"; |
207 | 220 |
208 std::string query; | 221 std::string query; |
209 Orthanc::EmbeddedResources::GetFileResource | 222 Orthanc::EmbeddedResources::GetFileResource |
210 (query, Orthanc::EmbeddedResources::POSTGRESQL_FAST_TOTAL_SIZE); | 223 (query, Orthanc::EmbeddedResources::POSTGRESQL_FAST_TOTAL_SIZE); |
211 db->Execute(query); | 224 db.Execute(query); |
212 | 225 |
213 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_GetTotalSizeIsFast, 1); | 226 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_GetTotalSizeIsFast, 1); |
214 } | 227 } |
215 | 228 |
216 | 229 |
217 // Installing this extension requires the "GlobalIntegers" table | 230 // Installing this extension requires the "GlobalIntegers" table |
218 // created by the "FastTotalSize" extension | 231 // created by the "FastTotalSize" extension |
219 property = 0; | 232 property = 0; |
220 if (!LookupGlobalIntegerProperty(property, *db, t, MISSING_SERVER_IDENTIFIER, | 233 if (!LookupGlobalIntegerProperty(property, db, t, MISSING_SERVER_IDENTIFIER, |
221 Orthanc::GlobalProperty_HasFastCountResources) || | 234 Orthanc::GlobalProperty_HasFastCountResources) || |
222 property != 1) | 235 property != 1) |
223 { | 236 { |
224 LOG(INFO) << "Installing the FastCountResources extension"; | 237 LOG(INFO) << "Installing the FastCountResources extension"; |
225 | 238 |
226 std::string query; | 239 std::string query; |
227 Orthanc::EmbeddedResources::GetFileResource | 240 Orthanc::EmbeddedResources::GetFileResource |
228 (query, Orthanc::EmbeddedResources::POSTGRESQL_FAST_COUNT_RESOURCES); | 241 (query, Orthanc::EmbeddedResources::POSTGRESQL_FAST_COUNT_RESOURCES); |
229 db->Execute(query); | 242 db.Execute(query); |
230 | 243 |
231 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasFastCountResources, 1); | 244 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasFastCountResources, 1); |
232 } | 245 } |
233 | 246 |
234 | 247 |
235 // Installing this extension requires the "GlobalIntegers" table | 248 // Installing this extension requires the "GlobalIntegers" table |
236 // created by the "GetLastChangeIndex" extension | 249 // created by the "GetLastChangeIndex" extension |
237 property = 0; | 250 property = 0; |
238 if (!LookupGlobalIntegerProperty(property, *db, t, MISSING_SERVER_IDENTIFIER, | 251 if (!LookupGlobalIntegerProperty(property, db, t, MISSING_SERVER_IDENTIFIER, |
239 Orthanc::GlobalProperty_GetLastChangeIndex) || | 252 Orthanc::GlobalProperty_GetLastChangeIndex) || |
240 property != 1) | 253 property != 1) |
241 { | 254 { |
242 LOG(INFO) << "Installing the GetLastChangeIndex extension"; | 255 LOG(INFO) << "Installing the GetLastChangeIndex extension"; |
243 | 256 |
244 std::string query; | 257 std::string query; |
245 Orthanc::EmbeddedResources::GetFileResource | 258 Orthanc::EmbeddedResources::GetFileResource |
246 (query, Orthanc::EmbeddedResources::POSTGRESQL_GET_LAST_CHANGE_INDEX); | 259 (query, Orthanc::EmbeddedResources::POSTGRESQL_GET_LAST_CHANGE_INDEX); |
247 db->Execute(query); | 260 db.Execute(query); |
248 | 261 |
249 SetGlobalIntegerProperty(*db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_GetLastChangeIndex, 1); | 262 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_GetLastChangeIndex, 1); |
250 } | 263 } |
251 | 264 |
252 t.Commit(); | 265 t.Commit(); |
253 } | 266 } |
254 } | 267 } |
255 | 268 } |
256 return db.release(); | 269 |
257 } | 270 |
258 | |
259 | |
260 PostgreSQLIndex::PostgreSQLIndex(OrthancPluginContext* context, | |
261 const PostgreSQLParameters& parameters) : | |
262 IndexBackend(context), | |
263 parameters_(parameters), | |
264 clearAll_(false) | |
265 { | |
266 } | |
267 | |
268 | |
269 int64_t PostgreSQLIndex::CreateResource(DatabaseManager& manager, | 271 int64_t PostgreSQLIndex::CreateResource(DatabaseManager& manager, |
270 const char* publicId, | 272 const char* publicId, |
271 OrthancPluginResourceType type) | 273 OrthancPluginResourceType type) |
272 { | 274 { |
273 DatabaseManager::CachedStatement statement( | 275 DatabaseManager::CachedStatement statement( |