Mercurial > hg > orthanc-databases
comparison MySQL/Plugins/MySQLStorageArea.cpp @ 242:b97a537f4613
MySQL: Support of range reads for the storage area
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 13 Apr 2021 17:00:02 +0200 |
parents | 35598014f140 |
children | 29ac6f4a0f45 |
comparison
equal
deleted
inserted
replaced
241:a063bbf10a3e | 242:b97a537f4613 |
---|---|
19 **/ | 19 **/ |
20 | 20 |
21 | 21 |
22 #include "MySQLStorageArea.h" | 22 #include "MySQLStorageArea.h" |
23 | 23 |
24 #include "../../Framework/Common/BinaryStringValue.h" | |
24 #include "../../Framework/MySQL/MySQLDatabase.h" | 25 #include "../../Framework/MySQL/MySQLDatabase.h" |
25 #include "../../Framework/MySQL/MySQLTransaction.h" | 26 #include "../../Framework/MySQL/MySQLTransaction.h" |
26 #include "MySQLDefinitions.h" | 27 #include "MySQLDefinitions.h" |
27 | 28 |
28 #include <Compatibility.h> // For std::unique_ptr<> | 29 #include <Compatibility.h> // For std::unique_ptr<> |
96 } | 97 } |
97 | 98 |
98 ConfigureDatabase(*database, parameters, clearAll); | 99 ConfigureDatabase(*database, parameters, clearAll); |
99 SetDatabase(database.release()); | 100 SetDatabase(database.release()); |
100 } | 101 } |
102 | |
103 | |
104 class MySQLStorageArea::Accessor : public StorageBackend::AccessorBase | |
105 { | |
106 public: | |
107 Accessor(MySQLStorageArea& backend) : | |
108 AccessorBase(backend) | |
109 { | |
110 } | |
111 | |
112 virtual void ReadRange(IFileContentVisitor& visitor, | |
113 const std::string& uuid, | |
114 OrthancPluginContentType type, | |
115 uint64_t start, | |
116 uint64_t length) ORTHANC_OVERRIDE | |
117 { | |
118 DatabaseManager::Transaction transaction(GetManager(), TransactionType_ReadOnly); | |
119 | |
120 { | |
121 // https://stackoverflow.com/a/6545557/881731 | |
122 DatabaseManager::CachedStatement statement( | |
123 STATEMENT_FROM_HERE, GetManager(), | |
124 "SELECT SUBSTRING(content, ${start}, ${length}) FROM StorageArea WHERE uuid=${uuid} AND type=${type}"); | |
125 | |
126 statement.SetParameterType("uuid", ValueType_Utf8String); | |
127 statement.SetParameterType("type", ValueType_Integer64); | |
128 statement.SetParameterType("start", ValueType_Integer64); | |
129 statement.SetParameterType("length", ValueType_Integer64); | |
130 | |
131 Dictionary args; | |
132 args.SetUtf8Value("uuid", uuid); | |
133 args.SetIntegerValue("type", type); | |
134 args.SetIntegerValue("length", length); | |
135 | |
136 /** | |
137 * "For all forms of SUBSTRING(), the position of the first | |
138 * character in the string from which the substring is to be | |
139 * extracted is reckoned as 1." => hence the "+ 1" | |
140 * https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_substring | |
141 **/ | |
142 args.SetIntegerValue("start", start + 1); | |
143 | |
144 statement.Execute(args); | |
145 | |
146 if (statement.IsDone()) | |
147 { | |
148 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); | |
149 } | |
150 else if (statement.GetResultFieldsCount() != 1) | |
151 { | |
152 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | |
153 } | |
154 else | |
155 { | |
156 const IValue& value = statement.GetResultField(0); | |
157 | |
158 if (value.GetType() == ValueType_BinaryString) | |
159 { | |
160 const std::string& content = dynamic_cast<const BinaryStringValue&>(value).GetContent(); | |
161 | |
162 if (static_cast<uint64_t>(content.size()) == length) | |
163 { | |
164 visitor.Assign(content); | |
165 } | |
166 else | |
167 { | |
168 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRange); | |
169 } | |
170 } | |
171 else | |
172 { | |
173 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | |
174 } | |
175 } | |
176 } | |
177 | |
178 transaction.Commit(); | |
179 | |
180 if (!visitor.IsSuccess()) | |
181 { | |
182 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database, "Could not read range from the storage area"); | |
183 } | |
184 } | |
185 }; | |
186 | |
187 | |
188 StorageBackend::IAccessor* MySQLStorageArea::CreateAccessor() | |
189 { | |
190 return new Accessor(*this); | |
191 } | |
101 } | 192 } |