comparison MySQL/Plugins/MySQLIndex.cpp @ 237:35598014f140

refactoring to remove GlobalProperties.cpp
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 08 Apr 2021 19:09:04 +0200
parents d1b124d116c1
children f033cc039264
comparison
equal deleted inserted replaced
236:d1d2edbbe6fb 237:35598014f140
60 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database, 60 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database,
61 "Need to fix the MySQL permissions for \"CREATE TRIGGER\""); 61 "Need to fix the MySQL permissions for \"CREATE TRIGGER\"");
62 } 62 }
63 63
64 64
65 void MySQLIndex::ConfigureDatabase(IDatabase& database) 65 void MySQLIndex::ConfigureDatabase(DatabaseManager& manager)
66 { 66 {
67 MySQLDatabase& db = dynamic_cast<MySQLDatabase&>(database);
68
69 uint32_t expectedVersion = 6; 67 uint32_t expectedVersion = 6;
70 68
71 if (GetContext()) // "GetContext()" can possibly be NULL in the unit tests 69 if (GetContext()) // "GetContext()" can possibly be NULL in the unit tests
72 { 70 {
73 expectedVersion = OrthancPluginGetExpectedDatabaseVersion(GetContext()); 71 expectedVersion = OrthancPluginGetExpectedDatabaseVersion(GetContext());
90 if (clearAll_) 88 if (clearAll_)
91 { 89 {
92 MySQLDatabase::ClearDatabase(parameters_); 90 MySQLDatabase::ClearDatabase(parameters_);
93 } 91 }
94 92
93 MySQLDatabase& db = dynamic_cast<MySQLDatabase&>(manager.GetDatabase());
94
95 { 95 {
96 MySQLDatabase::TransientAdvisoryLock lock(db, MYSQL_LOCK_DATABASE_SETUP); 96 MySQLDatabase::TransientAdvisoryLock lock(db, MYSQL_LOCK_DATABASE_SETUP);
97 97
98 /** 98 /**
99 * In a first transaction, we create the tables. Such a 99 * In a first transaction, we create the tables. Such a
108 * error message "MySQL plugin is incompatible with database 108 * error message "MySQL plugin is incompatible with database
109 * schema version: 0" that was reported in the forum: 109 * schema version: 0" that was reported in the forum:
110 * https://groups.google.com/d/msg/orthanc-users/OCFFkm1qm0k/Mbroy8VWAQAJ 110 * https://groups.google.com/d/msg/orthanc-users/OCFFkm1qm0k/Mbroy8VWAQAJ
111 **/ 111 **/
112 { 112 {
113 MySQLTransaction t(db, TransactionType_ReadWrite); 113 DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
114 114
115 db.Execute("ALTER DATABASE " + parameters_.GetDatabase() + 115 t.ExecuteMultiLines("ALTER DATABASE " + parameters_.GetDatabase() +
116 " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci", false); 116 " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
117 117
118 // This is the first table to be created 118 // This is the first table to be created
119 if (!db.DoesTableExist(t, "GlobalProperties")) 119 if (!t.DoesTableExist("GlobalProperties"))
120 { 120 {
121 std::string query; 121 std::string query;
122 122
123 Orthanc::EmbeddedResources::GetFileResource 123 Orthanc::EmbeddedResources::GetFileResource
124 (query, Orthanc::EmbeddedResources::MYSQL_PREPARE_INDEX); 124 (query, Orthanc::EmbeddedResources::MYSQL_PREPARE_INDEX);
125 db.Execute(query, true); 125
126 // Need to escape arobases: Don't use "t.ExecuteMultiLines()" here
127 db.ExecuteMultiLines(query, true);
126 } 128 }
127 129
128 t.Commit(); 130 t.Commit();
129 } 131 }
130 132
137 **/ 139 **/
138 140
139 int version = 0; 141 int version = 0;
140 142
141 { 143 {
142 MySQLTransaction t(db, TransactionType_ReadWrite); 144 DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
143 145
144 // This is the last table to be created 146 // This is the last table to be created
145 if (!db.DoesTableExist(t, "PatientRecyclingOrder")) 147 if (!t.DoesTableExist("PatientRecyclingOrder"))
146 { 148 {
147 LOG(ERROR) << "Corrupted MySQL database"; 149 LOG(ERROR) << "Corrupted MySQL database";
148 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 150 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
149 } 151 }
150 152
151 // This is the last item to be created 153 // This is the last item to be created
152 if (!db.DoesTriggerExist(t, "PatientAdded")) 154 if (!t.DoesTriggerExist("PatientAdded"))
153 { 155 {
154 ThrowCannotCreateTrigger(); 156 ThrowCannotCreateTrigger();
155 } 157 }
156 158
157 if (!LookupGlobalIntegerProperty(version, db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion)) 159 if (!LookupGlobalIntegerProperty(version, manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion))
158 { 160 {
159 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion, expectedVersion); 161 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion, expectedVersion);
160 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, 1); 162 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, 1);
161 version = expectedVersion; 163 version = expectedVersion;
162 } 164 }
163 165
164 if (version != 6) 166 if (version != 6)
165 { 167 {
171 } 173 }
172 174
173 int revision = 0; 175 int revision = 0;
174 176
175 { 177 {
176 MySQLTransaction t(db, TransactionType_ReadWrite); 178 DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
177 179
178 if (!LookupGlobalIntegerProperty(revision, db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel)) 180 if (!LookupGlobalIntegerProperty(revision, manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel))
179 { 181 {
180 revision = 1; 182 revision = 1;
181 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); 183 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision);
182 } 184 }
183 185
184 t.Commit(); 186 t.Commit();
185 } 187 }
186 188
187 if (revision == 1) 189 if (revision == 1)
188 { 190 {
189 MySQLTransaction t(db, TransactionType_ReadWrite); 191 DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
190 192
191 // The serialization of jobs as a global property can lead to 193 // The serialization of jobs as a global property can lead to
192 // very long values => switch to the LONGTEXT type that can 194 // very long values => switch to the LONGTEXT type that can
193 // store up to 4GB: 195 // store up to 4GB:
194 // https://stackoverflow.com/a/13932834/881731 196 // https://stackoverflow.com/a/13932834/881731
195 db.Execute("ALTER TABLE GlobalProperties MODIFY value LONGTEXT", false); 197 t.ExecuteMultiLines("ALTER TABLE GlobalProperties MODIFY value LONGTEXT");
196 198
197 revision = 2; 199 revision = 2;
198 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); 200 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision);
199 201
200 t.Commit(); 202 t.Commit();
201 } 203 }
202 204
203 if (revision == 2) 205 if (revision == 2)
204 { 206 {
205 MySQLTransaction t(db, TransactionType_ReadWrite); 207 DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
206 208
207 // Install the "GetLastChangeIndex" extension 209 // Install the "GetLastChangeIndex" extension
208 std::string query; 210 std::string query;
209 211
210 Orthanc::EmbeddedResources::GetFileResource 212 Orthanc::EmbeddedResources::GetFileResource
211 (query, Orthanc::EmbeddedResources::MYSQL_GET_LAST_CHANGE_INDEX); 213 (query, Orthanc::EmbeddedResources::MYSQL_GET_LAST_CHANGE_INDEX);
212 db.Execute(query, true); 214
213 215 // Need to escape arobases: Don't use "t.ExecuteMultiLines()" here
214 if (!db.DoesTriggerExist(t, "ChangeAdded")) 216 db.ExecuteMultiLines(query, true);
217
218 if (!t.DoesTriggerExist("ChangeAdded"))
215 { 219 {
216 ThrowCannotCreateTrigger(); 220 ThrowCannotCreateTrigger();
217 } 221 }
218 222
219 revision = 3; 223 revision = 3;
220 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); 224 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision);
221 225
222 t.Commit(); 226 t.Commit();
223 } 227 }
224 228
225 if (revision == 3) 229 if (revision == 3)
226 { 230 {
227 MySQLTransaction t(db, TransactionType_ReadWrite); 231 DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
228 232
229 // Reconfiguration of "Metadata" from TEXT type (up to 64KB) 233 // Reconfiguration of "Metadata" from TEXT type (up to 64KB)
230 // to the LONGTEXT type (up to 4GB). This might be important 234 // to the LONGTEXT type (up to 4GB). This might be important
231 // for applications such as the Osimis Web viewer that stores 235 // for applications such as the Osimis Web viewer that stores
232 // large amount of metadata. 236 // large amount of metadata.
233 // http://book.orthanc-server.com/faq/features.html#central-registry-of-metadata-and-attachments 237 // http://book.orthanc-server.com/faq/features.html#central-registry-of-metadata-and-attachments
234 db.Execute("ALTER TABLE Metadata MODIFY value LONGTEXT", false); 238 t.ExecuteMultiLines("ALTER TABLE Metadata MODIFY value LONGTEXT");
235 239
236 revision = 4; 240 revision = 4;
237 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); 241 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision);
238 242
239 t.Commit(); 243 t.Commit();
240 } 244 }
241 245
242 if (revision == 4) 246 if (revision == 4)
243 { 247 {
244 MySQLTransaction t(db, TransactionType_ReadWrite); 248 DatabaseManager::Transaction t(manager, TransactionType_ReadWrite);
245 249
246 // Install the "CreateInstance" extension 250 // Install the "CreateInstance" extension
247 std::string query; 251 std::string query;
248 252
249 Orthanc::EmbeddedResources::GetFileResource 253 Orthanc::EmbeddedResources::GetFileResource
250 (query, Orthanc::EmbeddedResources::MYSQL_CREATE_INSTANCE); 254 (query, Orthanc::EmbeddedResources::MYSQL_CREATE_INSTANCE);
251 db.Execute(query, true); 255
256 // Need to escape arobases: Don't use "t.ExecuteMultiLines()" here
257 db.ExecuteMultiLines(query, true);
252 258
253 revision = 5; 259 revision = 5;
254 SetGlobalIntegerProperty(db, t, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); 260 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision);
255 261
256 t.Commit(); 262 t.Commit();
257 } 263 }
258 264
259 if (revision != 5) 265 if (revision != 5)