Skip to content

Commit 9aee909

Browse files
committed
Support type interpretations.
1 parent b804afe commit 9aee909

File tree

16 files changed

+608
-91
lines changed

16 files changed

+608
-91
lines changed

src/oatpp-postgresql/Executor.cpp

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,29 @@ namespace oatpp { namespace postgresql {
4040

4141
namespace {
4242

43-
#include OATPP_CODEGEN_BEGIN(DTO)
43+
#include OATPP_CODEGEN_BEGIN(DTO)
4444

45-
class VersionRow : public oatpp::DTO {
45+
class VersionRow : public oatpp::DTO {
4646

47-
DTO_INIT(VersionRow, DTO);
47+
DTO_INIT(VersionRow, DTO);
4848

49-
DTO_FIELD(Int64, version);
49+
DTO_FIELD(Int64, version);
5050

51-
};
51+
};
5252

53-
#include OATPP_CODEGEN_END(DTO)
53+
#include OATPP_CODEGEN_END(DTO)
5454

5555
}
5656

5757
Executor::QueryParams::QueryParams(const StringTemplate& queryTemplate,
5858
const std::unordered_map<oatpp::String, oatpp::Void>& params,
5959
const mapping::TypeMapper& typeMapper,
6060
const mapping::Serializer& serializer,
61-
const data::mapping::type::BaseObject::PropertyTraverser& objectTraverser)
61+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver)
6262
{
6363

64+
data::mapping::TypeResolver::Cache cache;
65+
6466
auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData());
6567

6668
query = extra->preparedTemplate->c_str();
@@ -83,38 +85,28 @@ Executor::QueryParams::QueryParams(const StringTemplate& queryTemplate,
8385
const auto& var = queryTemplate.getTemplateVariables()[i];
8486
auto it = params.find(var.name);
8587

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) {
9590

96-
continue;
97-
98-
}
91+
it = params.find(queryParameter.name);
92+
if(it != params.end()) {
9993

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+
}
10699

107-
auto& data = outData[i];
108-
serializer.serialize(data, value);
100+
auto& data = outData[i];
101+
serializer.serialize(data, value);
109102

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;
114107

115-
continue;
108+
continue;
116109

117-
}
118110
}
119111
}
120112

@@ -129,18 +121,26 @@ Executor::Executor(const std::shared_ptr<provider::Provider<Connection>>& connec
129121
: m_connectionProvider(connectionProvider)
130122
, m_resultMapper(std::make_shared<mapping::ResultMapper>())
131123
{
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({
133132
Uuid::Class::CLASS_ID
134133
});
134+
return typeResolver;
135135
}
136136

137-
Executor::DtoParam Executor::paramNameAsDtoParam(const oatpp::String& paramName) {
137+
Executor::QueryParameter Executor::parseQueryParameter(const oatpp::String& paramName) {
138138

139139
parser::Caret caret(paramName);
140140
auto nameLabel = caret.putLabel();
141141
if(caret.findChar('.') && caret.getPosition() < caret.getDataSize() - 1) {
142142

143-
DtoParam result;
143+
QueryParameter result;
144144
result.name = nameLabel.toString();
145145

146146
do {
@@ -156,11 +156,15 @@ Executor::DtoParam Executor::paramNameAsDtoParam(const oatpp::String& paramName)
156156

157157
}
158158

159-
return {};
159+
return {nameLabel.toString(), {}};
160160

161161
}
162162

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;
164168

165169
std::unique_ptr<Oid[]> result(new Oid[queryTemplate.getTemplateVariables().size()]);
166170

@@ -169,21 +173,18 @@ std::unique_ptr<Oid[]> Executor::getParamTypes(const StringTemplate& queryTempla
169173
const auto& var = queryTemplate.getTemplateVariables()[i];
170174
auto it = paramsTypeMap.find(var.name);
171175

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) {
176178

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);
182182
if(type) {
183183
result.get()[i] = m_typeMapper.getTypeOid(type);
184184
continue;
185185
}
186186
}
187+
187188
}
188189

189190
throw std::runtime_error("[oatpp::postgresql::Executor::getParamTypes()]: Error. "
@@ -196,27 +197,30 @@ std::unique_ptr<Oid[]> Executor::getParamTypes(const StringTemplate& queryTempla
196197
}
197198

198199
std::shared_ptr<QueryResult> Executor::prepareQuery(const StringTemplate& queryTemplate,
200+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
199201
const std::shared_ptr<postgresql::Connection>& connection)
200202
{
201203

202204
auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData());
205+
auto paramTypes = getParamTypes(queryTemplate, extra->paramsTypeMap, typeResolver);
203206

204207
PGresult *qres = PQprepare(connection->getHandle(),
205208
extra->templateName->c_str(),
206209
extra->preparedTemplate->c_str(),
207210
queryTemplate.getTemplateVariables().size(),
208-
extra->paramTypes.get());
211+
paramTypes.get());
209212

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);
211214

212215
}
213216

214217
std::shared_ptr<QueryResult> Executor::executeQueryPrepared(const StringTemplate& queryTemplate,
215218
const std::unordered_map<oatpp::String, oatpp::Void>& params,
219+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
216220
const std::shared_ptr<postgresql::Connection>& connection)
217221
{
218222

219-
QueryParams queryParams(queryTemplate, params, m_typeMapper, m_serializer, m_objectTraverser);
223+
QueryParams queryParams(queryTemplate, params, m_typeMapper, m_serializer, typeResolver);
220224

221225
PGresult *qres = PQexecPrepared(connection->getHandle(),
222226
queryParams.queryName,
@@ -226,16 +230,17 @@ std::shared_ptr<QueryResult> Executor::executeQueryPrepared(const StringTemplate
226230
queryParams.paramFormats.data(),
227231
1);
228232

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);
230234

231235
}
232236

233237
std::shared_ptr<QueryResult> Executor::executeQuery(const StringTemplate& queryTemplate,
234238
const std::unordered_map<oatpp::String, oatpp::Void>& params,
239+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
235240
const std::shared_ptr<postgresql::Connection>& connection)
236241
{
237242

238-
QueryParams queryParams(queryTemplate, params, m_typeMapper, m_serializer, m_objectTraverser);
243+
QueryParams queryParams(queryTemplate, params, m_typeMapper, m_serializer, typeResolver);
239244

240245
PGresult *qres = PQexecParams(connection->getHandle(),
241246
queryParams.query,
@@ -246,7 +251,7 @@ std::shared_ptr<QueryResult> Executor::executeQuery(const StringTemplate& queryT
246251
queryParams.paramFormats.data(),
247252
1);
248253

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);
250255

251256
}
252257

@@ -265,10 +270,7 @@ data::share::StringTemplate Executor::parseQueryTemplate(const oatpp::String& na
265270
extra->templateName = name;
266271
ql_template::TemplateValueProvider valueProvider;
267272
extra->preparedTemplate = t.format(&valueProvider);
268-
269-
if(prepare) {
270-
extra->paramTypes = getParamTypes(t, paramsTypeMap);
271-
}
273+
extra->paramsTypeMap = paramsTypeMap;
272274

273275
return t;
274276

@@ -280,6 +282,7 @@ std::shared_ptr<orm::Connection> Executor::getConnection() {
280282

281283
std::shared_ptr<orm::QueryResult> Executor::execute(const StringTemplate& queryTemplate,
282284
const std::unordered_map<oatpp::String, oatpp::Void>& params,
285+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
283286
const std::shared_ptr<orm::Connection>& connection)
284287
{
285288

@@ -296,19 +299,19 @@ std::shared_ptr<orm::QueryResult> Executor::execute(const StringTemplate& queryT
296299
if(prepare) {
297300

298301
if (!pgConnection->isPrepared(extra->templateName)) {
299-
auto result = prepareQuery(queryTemplate, pgConnection);
302+
auto result = prepareQuery(queryTemplate, typeResolver, pgConnection);
300303
if(result->isSuccess()) {
301304
pgConnection->setPrepared(extra->templateName);
302305
} else {
303306
return result;
304307
}
305308
}
306309

307-
return executeQueryPrepared(queryTemplate, params, pgConnection);
310+
return executeQueryPrepared(queryTemplate, params, typeResolver, pgConnection);
308311

309312
}
310313

311-
return executeQuery(queryTemplate, params, pgConnection);
314+
return executeQuery(queryTemplate, params, typeResolver, pgConnection);
312315

313316
}
314317

@@ -338,7 +341,7 @@ std::shared_ptr<orm::QueryResult> Executor::exec(const oatpp::String& statement,
338341
qres = PQexec(pgConnection->getHandle(), statement->c_str());
339342
}
340343

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);
342345

343346
}
344347

src/oatpp-postgresql/Executor.hpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ namespace oatpp { namespace postgresql {
4343
class Executor : public orm::Executor {
4444
private:
4545

46-
struct DtoParam {
46+
struct QueryParameter {
4747
oatpp::String name;
4848
std::vector<std::string> propertyPath;
4949
};
5050

51-
static DtoParam paramNameAsDtoParam(const oatpp::String& paramName);
51+
static QueryParameter parseQueryParameter(const oatpp::String& paramName);
5252

5353
private:
5454

@@ -61,7 +61,7 @@ class Executor : public orm::Executor {
6161
const std::unordered_map<oatpp::String, oatpp::Void>& params,
6262
const mapping::TypeMapper& typeMapper,
6363
const mapping::Serializer& serializer,
64-
const data::mapping::type::BaseObject::PropertyTraverser& objectTraverser);
64+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver);
6565

6666
int count;
6767

@@ -89,29 +89,35 @@ class Executor : public orm::Executor {
8989

9090
private:
9191

92-
std::unique_ptr<Oid[]> getParamTypes(const StringTemplate& queryTemplate, const ParamsTypeMap& paramsTypeMap);
92+
std::unique_ptr<Oid[]> getParamTypes(const StringTemplate& queryTemplate,
93+
const ParamsTypeMap& paramsTypeMap,
94+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver);
9395

9496
std::shared_ptr<QueryResult> prepareQuery(const StringTemplate& queryTemplate,
97+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
9598
const std::shared_ptr<postgresql::Connection>& connection);
9699

97100
std::shared_ptr<QueryResult> executeQueryPrepared(const StringTemplate& queryTemplate,
98101
const std::unordered_map<oatpp::String, oatpp::Void>& params,
102+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
99103
const std::shared_ptr<postgresql::Connection>& connection);
100104

101105
std::shared_ptr<QueryResult> executeQuery(const StringTemplate& queryTemplate,
102106
const std::unordered_map<oatpp::String, oatpp::Void>& params,
107+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
103108
const std::shared_ptr<postgresql::Connection>& connection);
104109

105110
private:
106111
std::shared_ptr<provider::Provider<Connection>> m_connectionProvider;
107112
std::shared_ptr<mapping::ResultMapper> m_resultMapper;
108113
mapping::TypeMapper m_typeMapper;
109114
mapping::Serializer m_serializer;
110-
data::mapping::type::BaseObject::PropertyTraverser m_objectTraverser;
111115
public:
112116

113117
Executor(const std::shared_ptr<provider::Provider<Connection>>& connectionProvider);
114118

119+
std::shared_ptr<data::mapping::TypeResolver> createTypeResolver() override;
120+
115121
StringTemplate parseQueryTemplate(const oatpp::String& name,
116122
const oatpp::String& text,
117123
const ParamsTypeMap& paramsTypeMap,
@@ -121,6 +127,7 @@ class Executor : public orm::Executor {
121127

122128
std::shared_ptr<orm::QueryResult> execute(const StringTemplate& queryTemplate,
123129
const std::unordered_map<oatpp::String, oatpp::Void>& params,
130+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver,
124131
const std::shared_ptr<orm::Connection>& connection) override;
125132

126133
std::shared_ptr<orm::QueryResult> begin(const std::shared_ptr<orm::Connection>& connection = nullptr) override;

src/oatpp-postgresql/QueryResult.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@ namespace oatpp { namespace postgresql {
2929
QueryResult::QueryResult(PGresult* dbResult,
3030
const std::shared_ptr<Connection>& connection,
3131
const std::shared_ptr<provider::Provider<Connection>>& connectionProvider,
32-
const std::shared_ptr<mapping::ResultMapper>& resultMapper)
32+
const std::shared_ptr<mapping::ResultMapper>& resultMapper,
33+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver)
3334
: m_dbResult(dbResult)
3435
, m_connection(connection)
3536
, m_connectionProvider(connectionProvider)
3637
, m_resultMapper(resultMapper)
37-
, m_resultData(dbResult)
38+
, m_resultData(dbResult, typeResolver)
3839
{
3940
auto status = PQresultStatus(m_dbResult);
4041
switch(status) {

src/oatpp-postgresql/QueryResult.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ class QueryResult : public orm::QueryResult {
5252
QueryResult(PGresult* dbResult,
5353
const std::shared_ptr<Connection>& connection,
5454
const std::shared_ptr<provider::Provider<Connection>>& connectionProvider,
55-
const std::shared_ptr<mapping::ResultMapper>& resultMapper);
55+
const std::shared_ptr<mapping::ResultMapper>& resultMapper,
56+
const std::shared_ptr<const data::mapping::TypeResolver>& typeResolver);
5657

5758
~QueryResult();
5859

0 commit comments

Comments
 (0)