Mercurial > hg > orthanc-databases
annotate Framework/Common/Query.cpp @ 580:35d2df9572b1 find-refactoring tip
count-resources
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 15 Oct 2024 15:52:39 +0200 |
parents | 54d518dcd74a |
children |
rev | line source |
---|---|
0 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
507
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
459
diff
changeset
|
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
54d518dcd74a
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
459
diff
changeset
|
6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium |
459
ecd0b719cff5
update year to 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
389
diff
changeset
|
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
0 | 8 * |
9 * This program is free software: you can redistribute it and/or | |
10 * modify it under the terms of the GNU Affero General Public License | |
11 * as published by the Free Software Foundation, either version 3 of | |
12 * the License, or (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, but | |
15 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Affero General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Affero General Public License | |
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21 **/ | |
22 | |
23 | |
24 #include "Query.h" | |
25 | |
152 | 26 #include <Logging.h> |
27 #include <OrthancException.h> | |
0 | 28 |
29 #include <boost/regex.hpp> | |
30 | |
31 namespace OrthancDatabases | |
32 { | |
33 class Query::Token : public boost::noncopyable | |
34 { | |
35 private: | |
36 bool isParameter_; | |
37 std::string content_; | |
38 | |
39 public: | |
40 Token(bool isParameter, | |
41 const std::string& content) : | |
42 isParameter_(isParameter), | |
43 content_(content) | |
44 { | |
45 } | |
46 | |
47 bool IsParameter() const | |
48 { | |
49 return isParameter_; | |
50 } | |
51 | |
52 const std::string& GetContent() const | |
53 { | |
54 return content_; | |
55 } | |
56 }; | |
57 | |
58 | |
59 void Query::Setup(const std::string& sql) | |
60 { | |
61 boost::regex regex("\\$\\{(.*?)\\}"); | |
62 | |
63 std::string::const_iterator last = sql.begin(); | |
64 boost::sregex_token_iterator it(sql.begin(), sql.end(), regex, 0); | |
65 boost::sregex_token_iterator end; | |
66 | |
67 while (it != end) | |
68 { | |
69 if (last != it->first) | |
70 { | |
71 tokens_.push_back(new Token(false, std::string(last, it->first))); | |
72 } | |
73 | |
74 std::string parameter = *it; | |
75 assert(parameter.size() >= 3); | |
76 parameter = parameter.substr(2, parameter.size() - 3); | |
77 | |
78 tokens_.push_back(new Token(true, parameter)); | |
79 parameters_[parameter] = ValueType_Null; | |
80 | |
81 last = it->second; | |
82 | |
83 ++it; | |
84 } | |
85 | |
86 if (last != sql.end()) | |
87 { | |
88 tokens_.push_back(new Token(false, std::string(last, sql.end()))); | |
89 } | |
90 } | |
91 | |
92 | |
93 Query::Query(const std::string& sql) : | |
94 readOnly_(false) | |
95 { | |
96 Setup(sql); | |
97 } | |
98 | |
99 | |
100 Query::Query(const std::string& sql, | |
101 bool readOnly) : | |
102 readOnly_(readOnly) | |
103 { | |
104 Setup(sql); | |
105 } | |
106 | |
107 | |
108 Query::~Query() | |
109 { | |
110 for (size_t i = 0; i < tokens_.size(); i++) | |
111 { | |
112 assert(tokens_[i] != NULL); | |
113 delete tokens_[i]; | |
114 } | |
115 } | |
116 | |
117 | |
118 bool Query::HasParameter(const std::string& parameter) const | |
119 { | |
120 return parameters_.find(parameter) != parameters_.end(); | |
121 } | |
122 | |
123 | |
124 ValueType Query::GetType(const std::string& parameter) const | |
125 { | |
126 Parameters::const_iterator found = parameters_.find(parameter); | |
127 | |
128 if (found == parameters_.end()) | |
129 { | |
70
e6c13ddd26d9
all integration tests passing with LookupResources extension
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
67
diff
changeset
|
130 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, |
e6c13ddd26d9
all integration tests passing with LookupResources extension
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
67
diff
changeset
|
131 "Inexistent parameter in a SQL query: " + parameter); |
0 | 132 } |
133 else | |
134 { | |
135 return found->second; | |
136 } | |
137 } | |
138 | |
139 | |
140 void Query::SetType(const std::string& parameter, | |
141 ValueType type) | |
142 { | |
143 Parameters::iterator found = parameters_.find(parameter); | |
144 | |
145 if (found == parameters_.end()) | |
146 { | |
70
e6c13ddd26d9
all integration tests passing with LookupResources extension
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
67
diff
changeset
|
147 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, |
e6c13ddd26d9
all integration tests passing with LookupResources extension
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
67
diff
changeset
|
148 "Inexistent parameter in a SQL query: " + parameter); |
0 | 149 } |
150 else | |
151 { | |
152 found->second = type; | |
153 } | |
154 } | |
155 | |
156 | |
157 void Query::Format(std::string& result, | |
158 IParameterFormatter& formatter) const | |
159 { | |
160 result.clear(); | |
161 | |
162 for (size_t i = 0; i < tokens_.size(); i++) | |
163 { | |
164 assert(tokens_[i] != NULL); | |
165 | |
166 const std::string& content = tokens_[i]->GetContent(); | |
167 | |
168 if (tokens_[i]->IsParameter()) | |
169 { | |
170 std::string parameter; | |
171 formatter.Format(parameter, content, GetType(content)); | |
172 result += parameter; | |
173 } | |
174 else | |
175 { | |
176 result += content; | |
177 } | |
178 } | |
179 } | |
180 } |