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(