comparison SQLite/Plugins/IndexPlugin.cpp @ 206:6dcf57074dd4

starting OrthancPluginDatabaseBackendV3 wrapper
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 19 Mar 2021 10:11:17 +0100
parents 2089d4071408
children d9ef3f16e6a2
comparison
equal deleted inserted replaced
205:873e37048f96 206:6dcf57074dd4
26 #include <Logging.h> 26 #include <Logging.h>
27 27
28 static std::unique_ptr<OrthancDatabases::SQLiteIndex> backend_; 28 static std::unique_ptr<OrthancDatabases::SQLiteIndex> backend_;
29 29
30 30
31
32 #if defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE) // Macro introduced in Orthanc 1.3.1
33 # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 10, 0)
34
35 namespace OrthancDatabases
36 {
37 class Output : public IDatabaseBackendOutput
38 {
39 private:
40 _OrthancPluginDatabaseAnswerType answerType_;
41 std::list<std::string> strings_;
42
43 std::vector<OrthancPluginAttachment> attachments_;
44 std::vector<OrthancPluginChange> changes_;
45 std::vector<OrthancPluginDicomTag> tags_;
46 std::vector<OrthancPluginExportedResource> exported_;
47 std::vector<OrthancPluginDatabaseEvent> events_;
48
49 const char* StoreString(const std::string& s)
50 {
51 strings_.push_back(s);
52 return strings_.back().c_str();
53 }
54
55 void SetupAnswerType(_OrthancPluginDatabaseAnswerType type)
56 {
57 if (answerType_ == _OrthancPluginDatabaseAnswerType_None)
58 {
59 answerType_ = type;
60 }
61 else if (answerType_ != type)
62 {
63 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
64 }
65 }
66
67 public:
68 Output() :
69 answerType_(_OrthancPluginDatabaseAnswerType_None)
70 {
71 }
72
73
74 void Clear()
75 {
76 answerType_ = _OrthancPluginDatabaseAnswerType_None;
77 strings_.clear();
78
79 attachments_.clear();
80 changes_.clear();
81 tags_.clear();
82 exported_.clear();
83 events_.clear();
84 }
85
86
87 static OrthancPluginErrorCode ReadAnswersCount(OrthancPluginDatabaseTransaction* transaction,
88 uint32_t* target /* out */)
89 {
90 const Output& that = *reinterpret_cast<const Output*>(transaction);
91
92 size_t size;
93
94 switch (that.answerType_)
95 {
96 case _OrthancPluginDatabaseAnswerType_None:
97 size = 0;
98 break;
99
100 case _OrthancPluginDatabaseAnswerType_Attachment:
101 size = that.attachments_.size();
102 break;
103
104 case _OrthancPluginDatabaseAnswerType_Change:
105 size = that.changes_.size();
106 break;
107
108 case _OrthancPluginDatabaseAnswerType_DicomTag:
109 size = that.tags_.size();
110 break;
111
112 case _OrthancPluginDatabaseAnswerType_ExportedResource:
113 size = that.exported_.size();
114 break;
115
116 default:
117 return OrthancPluginErrorCode_InternalError;
118 }
119
120 *target = static_cast<uint32_t>(size);
121 return OrthancPluginErrorCode_Success;
122 }
123
124
125 static OrthancPluginErrorCode ReadAnswerAttachment(OrthancPluginDatabaseTransaction* transaction,
126 OrthancPluginAttachment* target /* out */,
127 uint32_t index)
128 {
129 const Output& that = *reinterpret_cast<const Output*>(transaction);
130
131 if (index < that.attachments_.size())
132 {
133 *target = that.attachments_[index];
134 return OrthancPluginErrorCode_Success;
135 }
136 else
137 {
138 return OrthancPluginErrorCode_ParameterOutOfRange;
139 }
140 }
141
142
143 static OrthancPluginErrorCode ReadAnswerChange(OrthancPluginDatabaseTransaction* transaction,
144 OrthancPluginChange* target /* out */,
145 uint32_t index)
146 {
147 const Output& that = *reinterpret_cast<const Output*>(transaction);
148
149 if (index < that.changes_.size())
150 {
151 *target = that.changes_[index];
152 return OrthancPluginErrorCode_Success;
153 }
154 else
155 {
156 return OrthancPluginErrorCode_ParameterOutOfRange;
157 }
158 }
159
160
161 static OrthancPluginErrorCode ReadAnswerDicomTag(OrthancPluginDatabaseTransaction* transaction,
162 uint16_t* group,
163 uint16_t* element,
164 const char** value,
165 uint32_t index)
166 {
167 const Output& that = *reinterpret_cast<const Output*>(transaction);
168
169 if (index < that.tags_.size())
170 {
171 const OrthancPluginDicomTag& tag = that.tags_[index];
172 *group = tag.group;
173 *element = tag.element;
174 *value = tag.value;
175 return OrthancPluginErrorCode_Success;
176 }
177 else
178 {
179 return OrthancPluginErrorCode_ParameterOutOfRange;
180 }
181 }
182
183
184 static OrthancPluginErrorCode ReadAnswerExportedResource(OrthancPluginDatabaseTransaction* transaction,
185 OrthancPluginExportedResource* target /* out */,
186 uint32_t index)
187 {
188 const Output& that = *reinterpret_cast<const Output*>(transaction);
189
190 if (index < that.exported_.size())
191 {
192 *target = that.exported_[index];
193 return OrthancPluginErrorCode_Success;
194 }
195 else
196 {
197 return OrthancPluginErrorCode_ParameterOutOfRange;
198 }
199 }
200
201
202 static OrthancPluginErrorCode ReadEventsCount(OrthancPluginDatabaseTransaction* transaction,
203 uint32_t* target /* out */)
204 {
205 const Output& that = *reinterpret_cast<const Output*>(transaction);
206 *target = static_cast<uint32_t>(that.events_.size());
207 return OrthancPluginErrorCode_Success;
208 }
209
210
211 static OrthancPluginErrorCode ReadEvent(OrthancPluginDatabaseTransaction* transaction,
212 OrthancPluginDatabaseEvent* event /* out */,
213 uint32_t index)
214 {
215 const Output& that = *reinterpret_cast<const Output*>(transaction);
216
217 if (index < that.events_.size())
218 {
219 *event = that.events_[index];
220 return OrthancPluginErrorCode_Success;
221 }
222 else
223 {
224 return OrthancPluginErrorCode_ParameterOutOfRange;
225 }
226 }
227
228
229 virtual void SignalDeletedAttachment(const std::string& uuid,
230 int32_t contentType,
231 uint64_t uncompressedSize,
232 const std::string& uncompressedHash,
233 int32_t compressionType,
234 uint64_t compressedSize,
235 const std::string& compressedHash) ORTHANC_OVERRIDE
236 {
237 OrthancPluginDatabaseEvent event;
238 event.type = OrthancPluginDatabaseEventType_DeletedAttachment;
239 event.content.attachment.uuid = StoreString(uuid);
240 event.content.attachment.contentType = contentType;
241 event.content.attachment.uncompressedSize = uncompressedSize;
242 event.content.attachment.uncompressedHash = StoreString(uncompressedHash);
243 event.content.attachment.compressionType = compressionType;
244 event.content.attachment.compressedSize = compressedSize;
245 event.content.attachment.compressedHash = StoreString(compressedHash);
246
247 events_.push_back(event);
248 }
249
250
251 virtual void SignalDeletedResource(const std::string& publicId,
252 OrthancPluginResourceType resourceType) ORTHANC_OVERRIDE
253 {
254 OrthancPluginDatabaseEvent event;
255 event.type = OrthancPluginDatabaseEventType_DeletedResource;
256 event.content.resource.level = resourceType;
257 event.content.resource.publicId = StoreString(publicId);
258
259 events_.push_back(event);
260 }
261
262
263 virtual void SignalRemainingAncestor(const std::string& ancestorId,
264 OrthancPluginResourceType ancestorType) ORTHANC_OVERRIDE
265 {
266 OrthancPluginDatabaseEvent event;
267 event.type = OrthancPluginDatabaseEventType_RemainingAncestor;
268 event.content.resource.level = ancestorType;
269 event.content.resource.publicId = StoreString(ancestorId);
270
271 events_.push_back(event);
272 }
273
274
275 virtual void AnswerAttachment(const std::string& uuid,
276 int32_t contentType,
277 uint64_t uncompressedSize,
278 const std::string& uncompressedHash,
279 int32_t compressionType,
280 uint64_t compressedSize,
281 const std::string& compressedHash) ORTHANC_OVERRIDE
282 {
283 SetupAnswerType(_OrthancPluginDatabaseAnswerType_Attachment);
284
285 OrthancPluginAttachment attachment;
286 attachment.uuid = StoreString(uuid);
287 attachment.contentType = contentType;
288 attachment.uncompressedSize = uncompressedSize;
289 attachment.uncompressedHash = StoreString(uncompressedHash);
290 attachment.compressionType = compressionType;
291 attachment.compressedSize = compressedSize;
292 attachment.compressedHash = StoreString(compressedHash);
293
294 attachments_.push_back(attachment);
295 }
296
297
298 virtual void AnswerChange(int64_t seq,
299 int32_t changeType,
300 OrthancPluginResourceType resourceType,
301 const std::string& publicId,
302 const std::string& date) ORTHANC_OVERRIDE
303 {
304 SetupAnswerType(_OrthancPluginDatabaseAnswerType_Change);
305
306 OrthancPluginChange change;
307 change.seq = seq;
308 change.changeType = changeType;
309 change.resourceType = resourceType;
310 change.publicId = StoreString(publicId);
311 change.date = StoreString(date);
312
313 changes_.push_back(change);
314 }
315
316
317 virtual void AnswerDicomTag(uint16_t group,
318 uint16_t element,
319 const std::string& value) ORTHANC_OVERRIDE
320 {
321 SetupAnswerType(_OrthancPluginDatabaseAnswerType_DicomTag);
322
323 OrthancPluginDicomTag tag;
324 tag.group = group;
325 tag.element = element;
326 tag.value = StoreString(value);
327
328 tags_.push_back(tag);
329 }
330
331
332 virtual void AnswerExportedResource(int64_t seq,
333 OrthancPluginResourceType resourceType,
334 const std::string& publicId,
335 const std::string& modality,
336 const std::string& date,
337 const std::string& patientId,
338 const std::string& studyInstanceUid,
339 const std::string& seriesInstanceUid,
340 const std::string& sopInstanceUid) ORTHANC_OVERRIDE
341 {
342 SetupAnswerType(_OrthancPluginDatabaseAnswerType_ExportedResource);
343
344 OrthancPluginExportedResource exported;
345 exported.seq = seq;
346 exported.resourceType = resourceType;
347 exported.publicId = StoreString(publicId);
348 exported.modality = StoreString(modality);
349 exported.date = StoreString(date);
350 exported.patientId = StoreString(patientId);
351 exported.studyInstanceUid = StoreString(studyInstanceUid);
352 exported.seriesInstanceUid = StoreString(seriesInstanceUid);
353 exported.sopInstanceUid = StoreString(sopInstanceUid);
354
355 exported_.push_back(exported);
356 }
357
358
359 virtual void AnswerMatchingResource(const std::string& resourceId) ORTHANC_OVERRIDE
360 {
361
362 }
363
364
365 virtual void AnswerMatchingResource(const std::string& resourceId,
366 const std::string& someInstanceId) ORTHANC_OVERRIDE
367 {
368
369 }
370 };
371
372
373 class Factory : public IDatabaseBackendOutput::IFactory
374 {
375 public:
376 Factory()
377 {
378 }
379
380 virtual IDatabaseBackendOutput* CreateOutput()
381 {
382 return new Output;
383 }
384 };
385
386
387 static void Register()
388 {
389 OrthancPluginDatabaseBackendV3 backend;
390 memset(&backend, 0, sizeof(backend));
391
392 backend.readAnswersCount = Output::ReadAnswersCount;
393 backend.readAnswerAttachment = Output::ReadAnswerAttachment;
394 backend.readAnswerChange = Output::ReadAnswerChange;
395 backend.readAnswerDicomTag = Output::ReadAnswerDicomTag;
396 backend.readAnswerExportedResource = Output::ReadAnswerExportedResource;
397
398 backend.readEventsCount = Output::ReadEventsCount;
399 backend.readEvent = Output::ReadEvent;
400 }
401 }
402
403 # endif
404 #endif
405
406
407
31 extern "C" 408 extern "C"
32 { 409 {
33 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) 410 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context)
34 { 411 {
35 if (!OrthancDatabases::InitializePlugin(context, "SQLite", true)) 412 if (!OrthancDatabases::InitializePlugin(context, "SQLite", true))