@@ -40,27 +40,29 @@ namespace oatpp { namespace postgresql {
40
40
41
41
namespace {
42
42
43
- #include OATPP_CODEGEN_BEGIN(DTO)
43
+ #include OATPP_CODEGEN_BEGIN(DTO)
44
44
45
- class VersionRow : public oatpp ::DTO {
45
+ class VersionRow : public oatpp ::DTO {
46
46
47
- DTO_INIT (VersionRow, DTO);
47
+ DTO_INIT (VersionRow, DTO);
48
48
49
- DTO_FIELD (Int64, version);
49
+ DTO_FIELD (Int64, version);
50
50
51
- };
51
+ };
52
52
53
- #include OATPP_CODEGEN_END(DTO)
53
+ #include OATPP_CODEGEN_END(DTO)
54
54
55
55
}
56
56
57
57
Executor::QueryParams::QueryParams (const StringTemplate& queryTemplate,
58
58
const std::unordered_map<oatpp::String, oatpp::Void>& params,
59
59
const mapping::TypeMapper& typeMapper,
60
60
const mapping::Serializer& serializer,
61
- const data::mapping::type::BaseObject::PropertyTraverser& objectTraverser )
61
+ const std::shared_ptr< const data::mapping::TypeResolver>& typeResolver )
62
62
{
63
63
64
+ data::mapping::TypeResolver::Cache cache;
65
+
64
66
auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData ());
65
67
66
68
query = extra->preparedTemplate ->c_str ();
@@ -83,38 +85,28 @@ Executor::QueryParams::QueryParams(const StringTemplate& queryTemplate,
83
85
const auto & var = queryTemplate.getTemplateVariables ()[i];
84
86
auto it = params.find (var.name );
85
87
86
- if (it != params.end ()) {
87
-
88
- auto & data = outData[i];
89
- serializer.serialize (data, it->second );
90
-
91
- paramOids[i] = typeMapper.getTypeOid (it->second .valueType );
92
- paramValues[i] = data.data ;
93
- paramLengths[i] = data.dataSize ;
94
- paramFormats[i] = data.dataFormat ;
88
+ auto queryParameter = parseQueryParameter (var.name );
89
+ if (queryParameter.name ) {
95
90
96
- continue ;
97
-
98
- }
91
+ it = params.find (queryParameter.name );
92
+ if (it != params.end ()) {
99
93
100
- auto dtoParam = paramNameAsDtoParam (var.name );
101
- if (dtoParam.name ) {
102
- it = params.find (dtoParam.name );
103
- if (it != params.end () && it->second .valueType ->classId .id == data::mapping::type::__class::AbstractObject::CLASS_ID.id ) {
104
- auto value = objectTraverser.findPropertyValue (it->second , dtoParam.propertyPath , {});
105
- if (value.valueType ->classId .id != oatpp::Void::Class::CLASS_ID.id ) {
94
+ auto value = typeResolver->resolveObjectPropertyValue (it->second , queryParameter.propertyPath , cache);
95
+ if (value.valueType ->classId .id == oatpp::Void::Class::CLASS_ID.id ) {
96
+ throw std::runtime_error (" [oatpp::postgresql::Executor::QueryParams::QueryParams()]: "
97
+ " Error. Can't bind object property. Property not found or its type is unknown." );
98
+ }
106
99
107
- auto & data = outData[i];
108
- serializer.serialize (data, value);
100
+ auto & data = outData[i];
101
+ serializer.serialize (data, value);
109
102
110
- paramOids[i] = typeMapper.getTypeOid (value.valueType );
111
- paramValues[i] = data.data ;
112
- paramLengths[i] = data.dataSize ;
113
- paramFormats[i] = data.dataFormat ;
103
+ paramOids[i] = typeMapper.getTypeOid (value.valueType );
104
+ paramValues[i] = data.data ;
105
+ paramLengths[i] = data.dataSize ;
106
+ paramFormats[i] = data.dataFormat ;
114
107
115
- continue ;
108
+ continue ;
116
109
117
- }
118
110
}
119
111
}
120
112
@@ -129,18 +121,26 @@ Executor::Executor(const std::shared_ptr<provider::Provider<Connection>>& connec
129
121
: m_connectionProvider(connectionProvider)
130
122
, m_resultMapper(std::make_shared<mapping::ResultMapper>())
131
123
{
132
- m_objectTraverser.addKnownTypes ({
124
+ m_defaultTypeResolver->addKnownClasses ({
125
+ Uuid::Class::CLASS_ID
126
+ });
127
+ }
128
+
129
+ std::shared_ptr<data::mapping::TypeResolver> Executor::createTypeResolver () {
130
+ auto typeResolver = std::make_shared<data::mapping::TypeResolver>();
131
+ typeResolver->addKnownClasses ({
133
132
Uuid::Class::CLASS_ID
134
133
});
134
+ return typeResolver;
135
135
}
136
136
137
- Executor::DtoParam Executor::paramNameAsDtoParam (const oatpp::String& paramName) {
137
+ Executor::QueryParameter Executor::parseQueryParameter (const oatpp::String& paramName) {
138
138
139
139
parser::Caret caret (paramName);
140
140
auto nameLabel = caret.putLabel ();
141
141
if (caret.findChar (' .' ) && caret.getPosition () < caret.getDataSize () - 1 ) {
142
142
143
- DtoParam result;
143
+ QueryParameter result;
144
144
result.name = nameLabel.toString ();
145
145
146
146
do {
@@ -156,11 +156,15 @@ Executor::DtoParam Executor::paramNameAsDtoParam(const oatpp::String& paramName)
156
156
157
157
}
158
158
159
- return {};
159
+ return {nameLabel. toString (), {} };
160
160
161
161
}
162
162
163
- std::unique_ptr<Oid[]> Executor::getParamTypes (const StringTemplate& queryTemplate, const ParamsTypeMap& paramsTypeMap) {
163
+ std::unique_ptr<Oid[]> Executor::getParamTypes (const StringTemplate& queryTemplate,
164
+ const ParamsTypeMap& paramsTypeMap,
165
+ const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver) {
166
+
167
+ data::mapping::TypeResolver::Cache cache;
164
168
165
169
std::unique_ptr<Oid[]> result (new Oid[queryTemplate.getTemplateVariables ().size ()]);
166
170
@@ -169,21 +173,18 @@ std::unique_ptr<Oid[]> Executor::getParamTypes(const StringTemplate& queryTempla
169
173
const auto & var = queryTemplate.getTemplateVariables ()[i];
170
174
auto it = paramsTypeMap.find (var.name );
171
175
172
- if (it != paramsTypeMap.end ()) {
173
- result.get ()[i] = m_typeMapper.getTypeOid (it->second );
174
- continue ;
175
- }
176
+ auto queryParameter = parseQueryParameter (var.name );
177
+ if (queryParameter.name ) {
176
178
177
- auto dtoParam = paramNameAsDtoParam (var.name );
178
- if (dtoParam.name ) {
179
- it = paramsTypeMap.find (dtoParam.name );
180
- if (it != paramsTypeMap.end () && it->second ->classId .id == data::mapping::type::__class::AbstractObject::CLASS_ID.id ) {
181
- auto type = m_objectTraverser.findPropertyType (it->second , dtoParam.propertyPath , {});
179
+ it = paramsTypeMap.find (queryParameter.name );
180
+ if (it != paramsTypeMap.end ()) {
181
+ auto type = typeResolver->resolveObjectPropertyType (it->second , queryParameter.propertyPath , cache);
182
182
if (type) {
183
183
result.get ()[i] = m_typeMapper.getTypeOid (type);
184
184
continue ;
185
185
}
186
186
}
187
+
187
188
}
188
189
189
190
throw std::runtime_error (" [oatpp::postgresql::Executor::getParamTypes()]: Error. "
@@ -196,27 +197,30 @@ std::unique_ptr<Oid[]> Executor::getParamTypes(const StringTemplate& queryTempla
196
197
}
197
198
198
199
std::shared_ptr<QueryResult> Executor::prepareQuery (const StringTemplate& queryTemplate,
200
+ const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
199
201
const std::shared_ptr<postgresql::Connection>& connection)
200
202
{
201
203
202
204
auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData ());
205
+ auto paramTypes = getParamTypes (queryTemplate, extra->paramsTypeMap , typeResolver);
203
206
204
207
PGresult *qres = PQprepare (connection->getHandle (),
205
208
extra->templateName ->c_str (),
206
209
extra->preparedTemplate ->c_str (),
207
210
queryTemplate.getTemplateVariables ().size (),
208
- extra-> paramTypes .get ());
211
+ paramTypes.get ());
209
212
210
- return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper);
213
+ return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper, typeResolver );
211
214
212
215
}
213
216
214
217
std::shared_ptr<QueryResult> Executor::executeQueryPrepared (const StringTemplate& queryTemplate,
215
218
const std::unordered_map<oatpp::String, oatpp::Void>& params,
219
+ const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
216
220
const std::shared_ptr<postgresql::Connection>& connection)
217
221
{
218
222
219
- QueryParams queryParams (queryTemplate, params, m_typeMapper, m_serializer, m_objectTraverser );
223
+ QueryParams queryParams (queryTemplate, params, m_typeMapper, m_serializer, typeResolver );
220
224
221
225
PGresult *qres = PQexecPrepared (connection->getHandle (),
222
226
queryParams.queryName ,
@@ -226,16 +230,17 @@ std::shared_ptr<QueryResult> Executor::executeQueryPrepared(const StringTemplate
226
230
queryParams.paramFormats .data (),
227
231
1 );
228
232
229
- return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper);
233
+ return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper, typeResolver );
230
234
231
235
}
232
236
233
237
std::shared_ptr<QueryResult> Executor::executeQuery (const StringTemplate& queryTemplate,
234
238
const std::unordered_map<oatpp::String, oatpp::Void>& params,
239
+ const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
235
240
const std::shared_ptr<postgresql::Connection>& connection)
236
241
{
237
242
238
- QueryParams queryParams (queryTemplate, params, m_typeMapper, m_serializer, m_objectTraverser );
243
+ QueryParams queryParams (queryTemplate, params, m_typeMapper, m_serializer, typeResolver );
239
244
240
245
PGresult *qres = PQexecParams (connection->getHandle (),
241
246
queryParams.query ,
@@ -246,7 +251,7 @@ std::shared_ptr<QueryResult> Executor::executeQuery(const StringTemplate& queryT
246
251
queryParams.paramFormats .data (),
247
252
1 );
248
253
249
- return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper);
254
+ return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper, typeResolver );
250
255
251
256
}
252
257
@@ -265,10 +270,7 @@ data::share::StringTemplate Executor::parseQueryTemplate(const oatpp::String& na
265
270
extra->templateName = name;
266
271
ql_template::TemplateValueProvider valueProvider;
267
272
extra->preparedTemplate = t.format (&valueProvider);
268
-
269
- if (prepare) {
270
- extra->paramTypes = getParamTypes (t, paramsTypeMap);
271
- }
273
+ extra->paramsTypeMap = paramsTypeMap;
272
274
273
275
return t;
274
276
@@ -280,6 +282,7 @@ std::shared_ptr<orm::Connection> Executor::getConnection() {
280
282
281
283
std::shared_ptr<orm::QueryResult> Executor::execute (const StringTemplate& queryTemplate,
282
284
const std::unordered_map<oatpp::String, oatpp::Void>& params,
285
+ const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
283
286
const std::shared_ptr<orm::Connection>& connection)
284
287
{
285
288
@@ -296,19 +299,19 @@ std::shared_ptr<orm::QueryResult> Executor::execute(const StringTemplate& queryT
296
299
if (prepare) {
297
300
298
301
if (!pgConnection->isPrepared (extra->templateName )) {
299
- auto result = prepareQuery (queryTemplate, pgConnection);
302
+ auto result = prepareQuery (queryTemplate, typeResolver, pgConnection);
300
303
if (result->isSuccess ()) {
301
304
pgConnection->setPrepared (extra->templateName );
302
305
} else {
303
306
return result;
304
307
}
305
308
}
306
309
307
- return executeQueryPrepared (queryTemplate, params, pgConnection);
310
+ return executeQueryPrepared (queryTemplate, params, typeResolver, pgConnection);
308
311
309
312
}
310
313
311
- return executeQuery (queryTemplate, params, pgConnection);
314
+ return executeQuery (queryTemplate, params, typeResolver, pgConnection);
312
315
313
316
}
314
317
@@ -338,7 +341,7 @@ std::shared_ptr<orm::QueryResult> Executor::exec(const oatpp::String& statement,
338
341
qres = PQexec (pgConnection->getHandle (), statement->c_str ());
339
342
}
340
343
341
- return std::make_shared<QueryResult>(qres, pgConnection, m_connectionProvider, m_resultMapper);
344
+ return std::make_shared<QueryResult>(qres, pgConnection, m_connectionProvider, m_resultMapper, m_defaultTypeResolver );
342
345
343
346
}
344
347
0 commit comments