| 300 | } |
| 301 | |
| 302 | IPreparedQuery *PgDatabase::PrepareQuery(const char *query, char *error, size_t maxlength, int *errCode) |
| 303 | { |
| 304 | std::lock_guard<std::recursive_mutex> lock(m_FullLock); |
| 305 | |
| 306 | unsigned int stmtID = m_preparedStatementID; |
| 307 | std::string stmtName = std::to_string(stmtID); |
| 308 | m_preparedStatementID++; |
| 309 | |
| 310 | // Let postgresql guess the types of the arguments if there are any.. |
| 311 | PGresult *res = PQprepare(m_pgsql, stmtName.c_str(), query, 0, NULL); |
| 312 | if (res == NULL) |
| 313 | { |
| 314 | if (error) |
| 315 | { |
| 316 | strncopy(error, PQerrorMessage(m_pgsql), maxlength); |
| 317 | } |
| 318 | |
| 319 | if (errCode) |
| 320 | { |
| 321 | // PostgreSQL only supports SQLSTATE error codes. |
| 322 | // https://www.postgresql.org/docs/9.6/errcodes-appendix.html |
| 323 | *errCode = -1; |
| 324 | } |
| 325 | |
| 326 | return NULL; |
| 327 | } |
| 328 | |
| 329 | if (PQresultStatus(res) != PGRES_COMMAND_OK) |
| 330 | { |
| 331 | if (error) |
| 332 | { |
| 333 | strncopy(error, PQresultErrorMessage(res), maxlength); |
| 334 | } |
| 335 | |
| 336 | if (errCode) |
| 337 | { |
| 338 | // PostgreSQL only supports SQLSTATE error codes. |
| 339 | // https://www.postgresql.org/docs/9.6/errcodes-appendix.html |
| 340 | *errCode = -1; |
| 341 | } |
| 342 | |
| 343 | PQclear(res); |
| 344 | return NULL; |
| 345 | } |
| 346 | |
| 347 | // Only the statement name is of importance. free the PGresult here. |
| 348 | PQclear(res); |
| 349 | |
| 350 | PGresult *desc = PQdescribePrepared(m_pgsql, stmtName.c_str()); |
| 351 | if (desc == NULL || PQresultStatus(desc) != PGRES_COMMAND_OK) |
| 352 | { |
| 353 | if (error) |
| 354 | { |
| 355 | const char *message = desc != NULL ? PQresultErrorMessage(desc) : PQerrorMessage(m_pgsql); |
| 356 | strncopy(error, message, maxlength); |
| 357 | } |
| 358 | |
| 359 | if (errCode) |