35
35
36
36
namespace oatpp { namespace postgresql {
37
37
38
+ Executor::QueryParams::QueryParams (const StringTemplate& queryTemplate,
39
+ const std::unordered_map<oatpp::String, oatpp::Void>& params,
40
+ const mapping::TypeMapper& typeMapper,
41
+ const mapping::Serializer& serializer)
42
+ {
43
+
44
+ auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData ());
45
+
46
+ query = extra->preparedTemplate ->c_str ();
47
+ queryName = extra->templateName ->c_str ();
48
+
49
+ count = queryTemplate.getTemplateVariables ().size ();
50
+
51
+ outData.resize (count);
52
+ paramOids.resize (count);
53
+ paramValues.resize (count);
54
+ paramLengths.resize (count);
55
+ paramFormats.resize (count);
56
+
57
+ for (v_uint32 i = 0 ; i < count; i ++) {
58
+ const auto & var = queryTemplate.getTemplateVariables ()[i];
59
+ auto it = params.find (var.name );
60
+ if (it == params.end ()) {
61
+ throw std::runtime_error (" [oatpp::postgresql::Executor::QueryParams::QueryParams()]: "
62
+ " Error. Parameter not found " + var.name ->std_str ());
63
+ }
64
+
65
+ auto & data = outData[i];
66
+ serializer.serialize (data, it->second );
67
+
68
+ paramOids[i] = typeMapper.getTypeOid (it->second .valueType );
69
+ paramValues[i] = data.data ;
70
+ paramLengths[i] = data.dataSize ;
71
+ paramFormats[i] = data.dataFormat ;
72
+ }
73
+
74
+ }
75
+
38
76
Executor::Executor (const std::shared_ptr<provider::Provider<Connection>>& connectionProvider)
39
77
: m_connectionProvider(connectionProvider)
40
78
, m_resultMapper(std::make_shared<mapping::ResultMapper>())
@@ -71,69 +109,67 @@ std::shared_ptr<QueryResult> Executor::prepareQuery(const StringTemplate& queryT
71
109
queryTemplate.getTemplateVariables ().size (),
72
110
extra->paramTypes .get ());
73
111
74
- return std::make_shared<QueryResult>(qres, connection, m_resultMapper);
112
+ return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper);
75
113
76
114
}
77
115
78
- std::shared_ptr<QueryResult> Executor::executeQuery (const StringTemplate& queryTemplate,
79
- const std::unordered_map<oatpp::String, oatpp::Void>& params,
80
- const std::shared_ptr<postgresql::Connection>& connection)
116
+ std::shared_ptr<QueryResult> Executor::executeQueryPrepared (const StringTemplate& queryTemplate,
117
+ const std::unordered_map<oatpp::String, oatpp::Void>& params,
118
+ const std::shared_ptr<postgresql::Connection>& connection)
81
119
{
82
120
83
- auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData ());
84
-
85
- v_uint32 paramsNumber = queryTemplate.getTemplateVariables ().size ();
121
+ QueryParams queryParams (queryTemplate, params, m_typeMapper, m_serializer);
86
122
87
- std::vector<mapping::Serializer::OutputData> outData (paramsNumber);
123
+ PGresult *qres = PQexecPrepared (connection->getHandle (),
124
+ queryParams.queryName ,
125
+ queryParams.count ,
126
+ queryParams.paramValues .data (),
127
+ queryParams.paramLengths .data (),
128
+ queryParams.paramFormats .data (),
129
+ 1 );
88
130
89
- std::unique_ptr<const char * []> paramValues (new const char *[paramsNumber]);
90
- std::unique_ptr<int []> paramLengths (new int [paramsNumber]);
91
- std::unique_ptr<int []> paramFormats (new int [paramsNumber]);
131
+ return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper);
92
132
93
- for (v_uint32 i = 0 ; i < paramsNumber; i ++) {
94
- const auto & var = queryTemplate.getTemplateVariables ()[i];
95
- auto it = params.find (var.name );
96
- if (it == params.end ()) {
97
- throw std::runtime_error (" [oatpp::postgresql::Executor::executeQuery()]: "
98
- " Error. Parameter not found " + var.name ->std_str ());
99
- }
133
+ }
100
134
101
- auto & data = outData[i];
102
- m_serializer.serialize (data, it->second );
135
+ std::shared_ptr<QueryResult> Executor::executeQuery (const StringTemplate& queryTemplate,
136
+ const std::unordered_map<oatpp::String, oatpp::Void>& params,
137
+ const std::shared_ptr<postgresql::Connection>& connection)
138
+ {
103
139
104
- paramValues[i] = data.data ;
105
- paramLengths[i] = data.dataSize ;
106
- paramFormats[i] = data.dataFormat ;
107
- }
140
+ QueryParams queryParams (queryTemplate, params, m_typeMapper, m_serializer);
108
141
109
- PGresult *qres = PQexecPrepared (connection->getHandle (),
110
- extra->templateName ->c_str (),
111
- paramsNumber,
112
- paramValues.get (),
113
- paramLengths.get (),
114
- paramFormats.get (),
115
- 1 );
142
+ PGresult *qres = PQexecParams (connection->getHandle (),
143
+ queryParams.query ,
144
+ queryParams.count ,
145
+ queryParams.paramOids .data (),
146
+ queryParams.paramValues .data (),
147
+ queryParams.paramLengths .data (),
148
+ queryParams.paramFormats .data (),
149
+ 1 );
116
150
117
- return std::make_shared<QueryResult>(qres, connection, m_resultMapper);
151
+ return std::make_shared<QueryResult>(qres, connection, m_connectionProvider, m_resultMapper);
118
152
119
153
}
120
154
121
155
data::share::StringTemplate Executor::parseQueryTemplate (const oatpp::String& name,
122
156
const oatpp::String& text,
123
- const ParamsTypeMap& paramsTypeMap)
157
+ const ParamsTypeMap& paramsTypeMap,
158
+ bool prepare)
124
159
{
125
160
126
161
auto && t = ql_template::Parser::parseTemplate (text);
127
162
128
163
auto extra = std::make_shared<ql_template::Parser::TemplateExtra>();
129
- extra-> templateName = name ;
164
+ t. setExtraData ( extra) ;
130
165
166
+ extra->templateName = name;
131
167
ql_template::TemplateValueProvider valueProvider;
132
168
extra->preparedTemplate = t.format (&valueProvider);
133
169
134
- extra-> paramTypes = getParamTypes (t, paramsTypeMap);
135
-
136
- t. setExtraData (extra);
170
+ if (prepare) {
171
+ extra-> paramTypes = getParamTypes (t, paramsTypeMap);
172
+ }
137
173
138
174
return t;
139
175
@@ -145,7 +181,8 @@ std::shared_ptr<orm::Connection> Executor::getConnection() {
145
181
146
182
std::shared_ptr<orm::QueryResult> Executor::execute (const StringTemplate& queryTemplate,
147
183
const std::unordered_map<oatpp::String, oatpp::Void>& params,
148
- const std::shared_ptr<orm::Connection>& connection)
184
+ const std::shared_ptr<orm::Connection>& connection,
185
+ bool prepare)
149
186
{
150
187
151
188
std::shared_ptr<orm::Connection> conn = connection;
@@ -157,9 +194,19 @@ std::shared_ptr<orm::QueryResult> Executor::execute(const StringTemplate& queryT
157
194
158
195
auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData ());
159
196
160
- if (!pgConnection->isPrepared (extra->templateName )) {
161
- prepareQuery (queryTemplate, pgConnection);
162
- pgConnection->setPrepared (extra->templateName );
197
+ if (prepare) {
198
+
199
+ if (!pgConnection->isPrepared (extra->templateName )) {
200
+ auto result = prepareQuery (queryTemplate, pgConnection);
201
+ if (result->isSuccess ()) {
202
+ pgConnection->setPrepared (extra->templateName );
203
+ } else {
204
+ return result;
205
+ }
206
+ }
207
+
208
+ return executeQueryPrepared (queryTemplate, params, pgConnection);
209
+
163
210
}
164
211
165
212
return executeQuery (queryTemplate, params, pgConnection);
0 commit comments