comparison Framework/Plugins/StorageBackend.cpp @ 246:483af3f35a4b

turning ResultFileValue into a base class, and implement its primitives for PostgreSQL
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 14 Apr 2021 08:42:31 +0200
parents 9d00e5e073e8
children 7f5ee2b42a86
comparison
equal deleted inserted replaced
245:9d00e5e073e8 246:483af3f35a4b
146 const IValue& value = statement.GetResultField(0); 146 const IValue& value = statement.GetResultField(0);
147 147
148 switch (value.GetType()) 148 switch (value.GetType())
149 { 149 {
150 case ValueType_ResultFile: 150 case ValueType_ResultFile:
151 visitor.Assign(dynamic_cast<const ResultFileValue&>(value).GetContent()); 151 {
152 std::string content;
153 dynamic_cast<const ResultFileValue&>(value).ReadWhole(content);
154 visitor.Assign(content);
152 break; 155 break;
156 }
153 157
154 case ValueType_BinaryString: 158 case ValueType_BinaryString:
155 visitor.Assign(dynamic_cast<const BinaryStringValue&>(value).GetContent()); 159 visitor.Assign(dynamic_cast<const BinaryStringValue&>(value).GetContent());
156 break; 160 break;
157 161
172 176
173 void StorageBackend::AccessorBase::ReadRange(IFileContentVisitor& visitor, 177 void StorageBackend::AccessorBase::ReadRange(IFileContentVisitor& visitor,
174 const std::string& uuid, 178 const std::string& uuid,
175 OrthancPluginContentType type, 179 OrthancPluginContentType type,
176 uint64_t start, 180 uint64_t start,
177 uint64_t length) 181 size_t length)
178 { 182 {
179 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 183 /**
184 * This is a generic implementation, that will only work if
185 * "ResultFileValue" is implemented by the database backend. For
186 * instance, this will *not* work with MySQL, as the latter uses
187 * BLOB columns to store files.
188 **/
189 DatabaseManager::Transaction transaction(manager_, TransactionType_ReadOnly);
190
191 {
192 DatabaseManager::CachedStatement statement(
193 STATEMENT_FROM_HERE, manager_,
194 "SELECT content FROM StorageArea WHERE uuid=${uuid} AND type=${type}");
195
196 statement.SetParameterType("uuid", ValueType_Utf8String);
197 statement.SetParameterType("type", ValueType_Integer64);
198
199 Dictionary args;
200 args.SetUtf8Value("uuid", uuid);
201 args.SetIntegerValue("type", type);
202
203 statement.Execute(args);
204
205 if (statement.IsDone())
206 {
207 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
208 }
209 else if (statement.GetResultFieldsCount() != 1)
210 {
211 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);
212 }
213 else
214 {
215 const IValue& value = statement.GetResultField(0);
216 if (value.GetType() == ValueType_ResultFile)
217 {
218 std::string content;
219 dynamic_cast<const ResultFileValue&>(value).ReadRange(content, start, length);
220 visitor.Assign(content);
221 }
222 else
223 {
224 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);
225 }
226 }
227 }
228
229 transaction.Commit();
230
231 if (!visitor.IsSuccess())
232 {
233 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database, "Could not read attachment from the storage area");
234 }
180 } 235 }
181 236
182 237
183 void StorageBackend::AccessorBase::Remove(const std::string& uuid, 238 void StorageBackend::AccessorBase::Remove(const std::string& uuid,
184 OrthancPluginContentType type) 239 OrthancPluginContentType type)
596 void StorageBackend::ReadRangeToString(std::string& target, 651 void StorageBackend::ReadRangeToString(std::string& target,
597 IAccessor& accessor, 652 IAccessor& accessor,
598 const std::string& uuid, 653 const std::string& uuid,
599 OrthancPluginContentType type, 654 OrthancPluginContentType type,
600 uint64_t start, 655 uint64_t start,
601 uint64_t length) 656 size_t length)
602 { 657 {
603 StringVisitor visitor(target); 658 StringVisitor visitor(target);
604 accessor.ReadRange(visitor, uuid, type, start, length); 659 accessor.ReadRange(visitor, uuid, type, start, length);
605 660
606 if (!visitor.IsSuccess()) 661 if (!visitor.IsSuccess())