comparison OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp @ 5207:e7529e6241d2 db-protobuf

first successful protobuf communication
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 30 Mar 2023 21:31:56 +0200
parents
children 154d37a56500
comparison
equal deleted inserted replaced
5206:fb3add662286 5207:e7529e6241d2
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) 2021-2023 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
7 *
8 * This program is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 **/
21
22
23 #include "../../Sources/PrecompiledHeadersServer.h"
24 #include "OrthancPluginDatabaseV4.h"
25
26 #if ORTHANC_ENABLE_PLUGINS != 1
27 # error The plugin support is disabled
28 #endif
29
30 #include "../../../OrthancFramework/Sources/Logging.h"
31 #include "../../../OrthancFramework/Sources/OrthancException.h"
32 #include "PluginsEnumerations.h"
33
34 #include "OrthancDatabasePlugin.pb.h"
35
36 #include <cassert>
37
38
39 namespace Orthanc
40 {
41 class OrthancPluginDatabaseV4::Transaction : public IDatabaseWrapper::ITransaction
42 {
43 private:
44 OrthancPluginDatabaseV4& that_;
45 IDatabaseListener& listener_;
46 void* transaction_;
47
48 void CheckSuccess(OrthancPluginErrorCode code) const
49 {
50 that_.CheckSuccess(code);
51 }
52
53 public:
54 Transaction(OrthancPluginDatabaseV4& that,
55 IDatabaseListener& listener,
56 TransactionType type) :
57 that_(that),
58 listener_(listener)
59 {
60 #if 0
61 CheckSuccess(that.database_.startTransaction(that.database_, &transaction_, type));
62 if (transaction_ == NULL)
63 {
64 throw OrthancException(ErrorCode_DatabasePlugin);
65 }
66 #endif
67 }
68
69
70 virtual ~Transaction()
71 {
72 #if 0
73 OrthancPluginErrorCode code = that_.database_.destructTransaction(transaction_);
74 if (code != OrthancPluginErrorCode_Success)
75 {
76 // Don't throw exception in destructors
77 that_.errorDictionary_.LogError(code, true);
78 }
79 #endif
80 }
81
82
83 virtual void Rollback() ORTHANC_OVERRIDE
84 {
85 }
86
87
88 virtual void Commit(int64_t fileSizeDelta) ORTHANC_OVERRIDE
89 {
90 }
91
92
93 virtual void AddAttachment(int64_t id,
94 const FileInfo& attachment,
95 int64_t revision) ORTHANC_OVERRIDE
96 {
97 }
98
99
100 virtual void ClearChanges() ORTHANC_OVERRIDE
101 {
102 }
103
104
105 virtual void ClearExportedResources() ORTHANC_OVERRIDE
106 {
107 }
108
109
110 virtual void DeleteAttachment(int64_t id,
111 FileContentType attachment) ORTHANC_OVERRIDE
112 {
113 }
114
115
116 virtual void DeleteMetadata(int64_t id,
117 MetadataType type) ORTHANC_OVERRIDE
118 {
119 }
120
121
122 virtual void DeleteResource(int64_t id) ORTHANC_OVERRIDE
123 {
124 }
125
126
127 virtual void GetAllMetadata(std::map<MetadataType, std::string>& target,
128 int64_t id) ORTHANC_OVERRIDE
129 {
130 }
131
132
133 virtual void GetAllPublicIds(std::list<std::string>& target,
134 ResourceType resourceType) ORTHANC_OVERRIDE
135 {
136 }
137
138
139 virtual void GetAllPublicIds(std::list<std::string>& target,
140 ResourceType resourceType,
141 size_t since,
142 size_t limit) ORTHANC_OVERRIDE
143 {
144 }
145
146
147 virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/,
148 bool& done /*out*/,
149 int64_t since,
150 uint32_t maxResults) ORTHANC_OVERRIDE
151 {
152 }
153
154
155 virtual void GetChildrenInternalId(std::list<int64_t>& target,
156 int64_t id) ORTHANC_OVERRIDE
157 {
158 }
159
160
161 virtual void GetChildrenPublicId(std::list<std::string>& target,
162 int64_t id) ORTHANC_OVERRIDE
163 {
164 }
165
166
167 virtual void GetExportedResources(std::list<ExportedResource>& target /*out*/,
168 bool& done /*out*/,
169 int64_t since,
170 uint32_t maxResults) ORTHANC_OVERRIDE
171 {
172 }
173
174
175 virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/) ORTHANC_OVERRIDE
176 {
177 }
178
179
180 virtual void GetMainDicomTags(DicomMap& target,
181 int64_t id) ORTHANC_OVERRIDE
182 {
183 }
184
185
186 virtual std::string GetPublicId(int64_t resourceId) ORTHANC_OVERRIDE
187 {
188 }
189
190
191 virtual uint64_t GetResourcesCount(ResourceType resourceType) ORTHANC_OVERRIDE
192 {
193 }
194
195
196 virtual ResourceType GetResourceType(int64_t resourceId) ORTHANC_OVERRIDE
197 {
198 }
199
200
201 virtual uint64_t GetTotalCompressedSize() ORTHANC_OVERRIDE
202 {
203 }
204
205
206 virtual uint64_t GetTotalUncompressedSize() ORTHANC_OVERRIDE
207 {
208 }
209
210
211 virtual bool IsProtectedPatient(int64_t internalId) ORTHANC_OVERRIDE
212 {
213 }
214
215
216 virtual void ListAvailableAttachments(std::set<FileContentType>& target,
217 int64_t id) ORTHANC_OVERRIDE
218 {
219 }
220
221
222 virtual void LogChange(int64_t internalId,
223 const ServerIndexChange& change) ORTHANC_OVERRIDE
224 {
225 }
226
227
228 virtual void LogExportedResource(const ExportedResource& resource) ORTHANC_OVERRIDE
229 {
230 }
231
232
233 virtual bool LookupAttachment(FileInfo& attachment,
234 int64_t& revision,
235 int64_t id,
236 FileContentType contentType) ORTHANC_OVERRIDE
237 {
238 }
239
240
241 virtual bool LookupGlobalProperty(std::string& target,
242 GlobalProperty property,
243 bool shared) ORTHANC_OVERRIDE
244 {
245 }
246
247
248 virtual bool LookupMetadata(std::string& target,
249 int64_t& revision,
250 int64_t id,
251 MetadataType type) ORTHANC_OVERRIDE
252 {
253 }
254
255
256 virtual bool LookupParent(int64_t& parentId,
257 int64_t resourceId) ORTHANC_OVERRIDE
258 {
259 }
260
261
262 virtual bool LookupResource(int64_t& id,
263 ResourceType& type,
264 const std::string& publicId) ORTHANC_OVERRIDE
265 {
266 }
267
268
269 virtual bool SelectPatientToRecycle(int64_t& internalId) ORTHANC_OVERRIDE
270 {
271 }
272
273
274 virtual bool SelectPatientToRecycle(int64_t& internalId,
275 int64_t patientIdToAvoid) ORTHANC_OVERRIDE
276 {
277 }
278
279
280 virtual void SetGlobalProperty(GlobalProperty property,
281 bool shared,
282 const std::string& value) ORTHANC_OVERRIDE
283 {
284 }
285
286
287 virtual void ClearMainDicomTags(int64_t id) ORTHANC_OVERRIDE
288 {
289 }
290
291
292 virtual void SetMetadata(int64_t id,
293 MetadataType type,
294 const std::string& value,
295 int64_t revision) ORTHANC_OVERRIDE
296 {
297 }
298
299
300 virtual void SetProtectedPatient(int64_t internalId,
301 bool isProtected) ORTHANC_OVERRIDE
302 {
303 }
304
305
306 virtual bool IsDiskSizeAbove(uint64_t threshold) ORTHANC_OVERRIDE
307 {
308 }
309
310
311 virtual void ApplyLookupResources(std::list<std::string>& resourcesId,
312 std::list<std::string>* instancesId, // Can be NULL if not needed
313 const std::vector<DatabaseConstraint>& lookup,
314 ResourceType queryLevel,
315 size_t limit) ORTHANC_OVERRIDE
316 {
317 }
318
319
320 virtual bool CreateInstance(CreateInstanceResult& result, /* out */
321 int64_t& instanceId, /* out */
322 const std::string& patient,
323 const std::string& study,
324 const std::string& series,
325 const std::string& instance) ORTHANC_OVERRIDE
326 {
327 }
328
329
330 virtual void SetResourcesContent(const ResourcesContent& content) ORTHANC_OVERRIDE
331 {
332 }
333
334
335 virtual void GetChildrenMetadata(std::list<std::string>& target,
336 int64_t resourceId,
337 MetadataType metadata) ORTHANC_OVERRIDE
338 {
339 }
340
341
342 virtual int64_t GetLastChangeIndex() ORTHANC_OVERRIDE
343 {
344 }
345
346
347 virtual bool LookupResourceAndParent(int64_t& id,
348 ResourceType& type,
349 std::string& parentPublicId,
350 const std::string& publicId) ORTHANC_OVERRIDE
351 {
352 }
353 };
354
355
356 static void CheckSuccess(PluginsErrorDictionary& errorDictionary,
357 OrthancPluginErrorCode code)
358 {
359 if (code != OrthancPluginErrorCode_Success)
360 {
361 errorDictionary.LogError(code, true);
362 throw OrthancException(static_cast<ErrorCode>(code));
363 }
364 }
365
366
367 static void Execute(DatabasePluginMessages::Response& response,
368 const _OrthancPluginRegisterDatabaseBackendV4& database,
369 PluginsErrorDictionary& errorDictionary,
370 const DatabasePluginMessages::Request& request)
371 {
372 std::string requestSerialized;
373 request.SerializeToString(&requestSerialized);
374
375 OrthancPluginMemoryBuffer64 responseSerialized;
376 CheckSuccess(errorDictionary, database.operations(
377 &responseSerialized, database.backend,
378 requestSerialized.empty() ? NULL : requestSerialized.c_str(),
379 requestSerialized.size()));
380
381 bool success = response.ParseFromArray(responseSerialized.data, responseSerialized.size);
382
383 if (responseSerialized.size > 0)
384 {
385 free(responseSerialized.data);
386 }
387
388 if (!success)
389 {
390 throw OrthancException(ErrorCode_DatabasePlugin, "Cannot unserialize protobuf originating from the database plugin");
391 }
392 }
393
394 static void ExecuteDatabase(DatabasePluginMessages::DatabaseResponse& response,
395 const _OrthancPluginRegisterDatabaseBackendV4& database,
396 PluginsErrorDictionary& errorDictionary,
397 DatabasePluginMessages::DatabaseOperation operation,
398 const DatabasePluginMessages::DatabaseRequest& request)
399 {
400 DatabasePluginMessages::Request fullRequest;
401 fullRequest.set_type(DatabasePluginMessages::REQUEST_DATABASE);
402 fullRequest.mutable_database_request()->CopyFrom(request);
403 fullRequest.mutable_database_request()->set_operation(operation);
404
405 DatabasePluginMessages::Response fullResponse;
406 Execute(fullResponse, database, errorDictionary, fullRequest);
407
408 response.CopyFrom(fullResponse.database_response());
409 }
410
411
412 OrthancPluginDatabaseV4::OrthancPluginDatabaseV4(SharedLibrary& library,
413 PluginsErrorDictionary& errorDictionary,
414 const _OrthancPluginRegisterDatabaseBackendV4& database,
415 const std::string& serverIdentifier) :
416 library_(library),
417 errorDictionary_(errorDictionary),
418 database_(database),
419 serverIdentifier_(serverIdentifier),
420 open_(false),
421 databaseVersion_(0),
422 hasFlushToDisk_(false),
423 hasRevisionsSupport_(false)
424 {
425 CLOG(INFO, PLUGINS) << "Identifier of this Orthanc server for the global properties "
426 << "of the custom database: \"" << serverIdentifier << "\"";
427
428 if (database_.backend == NULL ||
429 database_.operations == NULL ||
430 database_.finalize == NULL)
431 {
432 throw OrthancException(ErrorCode_NullPointer);
433 }
434 }
435
436
437 OrthancPluginDatabaseV4::~OrthancPluginDatabaseV4()
438 {
439 database_.finalize(database_.backend);
440 }
441
442
443 void OrthancPluginDatabaseV4::Open()
444 {
445 if (open_)
446 {
447 throw OrthancException(ErrorCode_BadSequenceOfCalls);
448 }
449
450 {
451 DatabasePluginMessages::DatabaseRequest request;
452 DatabasePluginMessages::DatabaseResponse response;
453 ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_OPEN, request);
454 }
455
456 {
457 DatabasePluginMessages::DatabaseRequest request;
458 DatabasePluginMessages::DatabaseResponse response;
459 ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_GET_SYSTEM_INFORMATION, request);
460 hasFlushToDisk_ = response.get_system_information().supports_flush_to_disk();
461 hasRevisionsSupport_ = response.get_system_information().supports_revisions();
462 }
463
464 open_ = true;
465 }
466
467
468 void OrthancPluginDatabaseV4::Close()
469 {
470 if (!open_)
471 {
472 throw OrthancException(ErrorCode_BadSequenceOfCalls);
473 }
474 else
475 {
476 DatabasePluginMessages::DatabaseRequest request;
477 DatabasePluginMessages::DatabaseResponse response;
478 ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_CLOSE, request);
479 }
480 }
481
482
483 bool OrthancPluginDatabaseV4::HasFlushToDisk() const
484 {
485 if (!open_)
486 {
487 throw OrthancException(ErrorCode_BadSequenceOfCalls);
488 }
489 else
490 {
491 return hasFlushToDisk_;
492 }
493 }
494
495
496 void OrthancPluginDatabaseV4::FlushToDisk()
497 {
498 if (!open_ ||
499 !hasFlushToDisk_)
500 {
501 throw OrthancException(ErrorCode_BadSequenceOfCalls);
502 }
503 else
504 {
505 DatabasePluginMessages::DatabaseRequest request;
506 DatabasePluginMessages::DatabaseResponse response;
507 ExecuteDatabase(response, database_, errorDictionary_, DatabasePluginMessages::OPERATION_FLUSH_TO_DISK, request);
508 }
509 }
510
511
512 IDatabaseWrapper::ITransaction* OrthancPluginDatabaseV4::StartTransaction(TransactionType type,
513 IDatabaseListener& listener)
514 {
515 if (!open_)
516 {
517 throw OrthancException(ErrorCode_BadSequenceOfCalls);
518 }
519
520 switch (type)
521 {
522 case TransactionType_ReadOnly:
523
524 case TransactionType_ReadWrite:
525
526 default:
527 throw OrthancException(ErrorCode_InternalError);
528 }
529 }
530
531
532 unsigned int OrthancPluginDatabaseV4::GetDatabaseVersion()
533 {
534 if (!open_)
535 {
536 throw OrthancException(ErrorCode_BadSequenceOfCalls);
537 }
538 else
539 {
540 return databaseVersion_;
541 }
542 }
543
544
545 void OrthancPluginDatabaseV4::Upgrade(unsigned int targetVersion,
546 IStorageArea& storageArea)
547 {
548 if (!open_)
549 {
550 throw OrthancException(ErrorCode_BadSequenceOfCalls);
551 }
552 else
553 {
554 // TODO
555 }
556 }
557
558
559 bool OrthancPluginDatabaseV4::HasRevisionsSupport() const
560 {
561 if (!open_)
562 {
563 throw OrthancException(ErrorCode_BadSequenceOfCalls);
564 }
565 else
566 {
567 return hasRevisionsSupport_;
568 }
569 }
570 }