22 #ifndef DBALLE_DB_POSTGRESQL_INTERNALS_H 23 #define DBALLE_DB_POSTGRESQL_INTERNALS_H 26 #include <dballe/db/sql.h> 28 #include <arpa/inet.h> 49 wreport::ErrorCode code()
const throw () {
return wreport::WR_ERR_ODBC; }
51 virtual const char* what()
const throw () {
return msg.c_str(); }
53 static void throwf(PGconn* db,
const char* fmt, ...) WREPORT_THROWF_ATTRS(2, 3);
54 static void throwf(PGresult* db,
const char* fmt, ...) WREPORT_THROWF_ATTRS(2, 3);
57 namespace postgresql {
59 int64_t encode_datetime(
const Datetime& arg);
60 int64_t encode_int64_t(int64_t arg);
63 template<
typename... ARGS>
struct Params 65 static const int count =
sizeof...(ARGS);
66 const char* args[
sizeof...(ARGS)];
67 int lengths[
sizeof...(ARGS)];
68 int formats[
sizeof...(ARGS)];
69 void* local[
sizeof...(ARGS)];
71 Params(
const ARGS&... args)
93 template<
typename... REST>
94 void _add(
unsigned pos, std::nullptr_t arg,
const REST&... rest)
100 _add(pos + 1, rest...);
104 template<
typename... REST>
105 void _add(
unsigned pos, int32_t arg,
const REST&... rest)
107 local[pos] = malloc(
sizeof(int32_t));
108 *(int32_t*)local[pos] = (int32_t)htonl((uint32_t)arg);
109 args[pos] = (
const char*)local[pos];
110 lengths[pos] =
sizeof(int32_t);
112 _add(pos + 1, rest...);
116 template<
typename... REST>
117 void _add(
unsigned pos, uint64_t arg,
const REST&... rest)
119 local[pos] = malloc(
sizeof(int64_t));
120 *(int64_t*)local[pos] = encode_int64_t(arg);
121 args[pos] = (
const char*)local[pos];
122 lengths[pos] =
sizeof(int64_t);
124 _add(pos + 1, rest...);
128 template<
typename... REST>
129 void _add(
unsigned pos,
const char* arg,
const REST&... rest)
131 local[pos] =
nullptr;
135 _add(pos + 1, rest...);
139 template<
typename... REST>
140 void _add(
unsigned pos,
const std::string& arg,
const REST&... rest)
142 local[pos] =
nullptr;
143 args[pos] = arg.data();
144 lengths[pos] = arg.size();
146 _add(pos + 1, rest...);
150 template<
typename... REST>
153 local[pos] = malloc(
sizeof(int64_t));
154 *(int64_t*)local[pos] = encode_datetime(arg);
155 args[pos] = (
const char*)local[pos];
156 lengths[pos] =
sizeof(int64_t);
158 _add(pos + 1, rest...);
167 Result() : res(
nullptr) {}
168 Result(PGresult* res) : res(res) {}
169 ~
Result() { PQclear(res); }
175 if (
this == &o)
return *
this;
182 operator bool()
const {
return res !=
nullptr; }
183 operator PGresult*() {
return res; }
184 operator const PGresult*()
const {
return res; }
187 void expect_no_data(
const std::string& query);
190 void expect_result(
const std::string& query);
193 void expect_one_row(
const std::string& query);
196 void expect_success(
const std::string& query);
199 unsigned rowcount()
const {
return PQntuples(res); }
202 bool is_null(
unsigned row,
unsigned col)
const 204 return PQgetisnull(res, row, col);
210 char* val = PQgetvalue(res, row, col);
215 uint16_t
get_int2(
unsigned row,
unsigned col)
const 217 char* val = PQgetvalue(res, row, col);
218 return ntohs(*(uint16_t*)val);
222 uint32_t
get_int4(
unsigned row,
unsigned col)
const 224 char* val = PQgetvalue(res, row, col);
225 return ntohl(*(uint32_t*)val);
229 uint64_t get_int8(
unsigned row,
unsigned col)
const;
234 return PQgetvalue(res, row, col);
238 Datetime get_timestamp(
unsigned row,
unsigned col)
const;
253 PGconn* db =
nullptr;
256 void init_after_connect();
266 operator PGconn*() {
return db; }
274 void open_url(
const std::string& connection_string);
277 std::unique_ptr<Transaction> transaction()
override;
280 void prepare(
const std::string& name,
const std::string& query);
284 return PQexecParams(db, query, 0,
nullptr,
nullptr,
nullptr,
nullptr, 1);
289 return PQexecParams(db, query.c_str(), 0,
nullptr,
nullptr,
nullptr,
nullptr, 1);
292 template<
typename STRING>
293 void exec_no_data(STRING query)
296 res.expect_no_data(query);
299 template<
typename STRING>
303 res.expect_result(query);
307 template<
typename STRING>
311 res.expect_one_row(query);
315 template<
typename ...ARGS>
319 return PQexecParams(db, query, params.count,
nullptr, params.args, params.lengths, params.formats, 1);
322 template<
typename ...ARGS>
326 return PQexecParams(db, query.c_str(), params.count,
nullptr, params.args, params.lengths, params.formats, 1);
329 template<
typename STRING,
typename ...ARGS>
330 void exec_no_data(STRING query, ARGS... args)
333 res.expect_no_data(query);
336 template<
typename STRING,
typename ...ARGS>
340 res.expect_result(query);
344 template<
typename STRING,
typename ...ARGS>
348 res.expect_one_row(query);
354 return PQexecPrepared(db, name, 0,
nullptr,
nullptr,
nullptr, 1);
359 return PQexecPrepared(db, name.c_str(), 0,
nullptr,
nullptr,
nullptr, 1);
362 template<
typename STRING>
363 void exec_prepared_no_data(STRING name)
366 res.expect_no_data(name);
369 template<
typename STRING>
373 res.expect_result(name);
377 template<
typename STRING>
381 res.expect_one_row(name);
385 template<
typename ...ARGS>
389 return PQexecPrepared(db, name, params.count, params.args, params.lengths, params.formats, 1);
392 template<
typename ...ARGS>
396 return PQexecPrepared(db, name.c_str(), params.count, params.args, params.lengths, params.formats, 1);
399 template<
typename STRING,
typename ...ARGS>
400 void exec_prepared_no_data(STRING name, ARGS... args)
403 res.expect_no_data(name);
406 template<
typename STRING,
typename ...ARGS>
410 res.expect_result(name);
414 template<
typename STRING,
typename ...ARGS>
418 res.expect_one_row(name);
423 void cancel_running_query_nothrow() noexcept;
426 void discard_all_input_nothrow() noexcept;
429 bool has_table(const std::
string& name) override;
436 std::
string get_setting(const std::
string& key) override;
443 void set_setting(const std::
string& key, const std::
string& value) override;
446 void drop_settings() override;
451 void drop_table_if_exists(const
char* name);
457 void pqexec(const std::
string& query);
464 void pqexec_nothrow(const std::
string& query) noexcept;
void _add(unsigned pos, const Datetime &arg, const REST &...rest)
Fill in the argument structures.
Definition: postgresql/internals.h:151
Argument list for PQexecParams built at compile time.
Definition: postgresql/internals.h:63
bool get_bool(unsigned row, unsigned col) const
Return a result value, transmitted in binary as a byte (?)
Definition: postgresql/internals.h:208
Report an PostgreSQL error.
Definition: postgresql/internals.h:36
void _add(unsigned pos, uint64_t arg, const REST &...rest)
Fill in the argument structures.
Definition: postgresql/internals.h:117
const char * get_string(unsigned row, unsigned col) const
Return a result value, transmitted as a string.
Definition: postgresql/internals.h:232
Wrap a PGresult, taking care of its memory management.
Definition: postgresql/internals.h:163
void _add(unsigned pos, const char *arg, const REST &...rest)
Fill in the argument structures.
Definition: postgresql/internals.h:129
uint16_t get_int2(unsigned row, unsigned col) const
Return a result value, transmitted in binary as a 2 bit integer.
Definition: postgresql/internals.h:215
Base exception for database errors.
Definition: db/defs.h:54
Copyright (C) 2008–2010 ARPA-SIM urpsim@smr.arpa.emr.it
Definition: cmdline.h:17
Functions used to connect to DB-All.e and insert, query and delete data.
void _add(unsigned pos)
Terminating condition for compile-time arg expansion.
Definition: postgresql/internals.h:88
void _add(unsigned pos, int32_t arg, const REST &...rest)
Fill in the argument structures.
Definition: postgresql/internals.h:105
void _add(unsigned pos, std::nullptr_t arg, const REST &...rest)
Fill in the argument structures.
Definition: postgresql/internals.h:94
unsigned rowcount() const
Get the number of rows in the result.
Definition: postgresql/internals.h:199
Database connection.
Definition: postgresql/internals.h:249
error_postgresql(PGconn *db, const std::string &msg)
Copy informations from the ODBC diagnostic record to the dba error report.
void _add(unsigned pos, const std::string &arg, const REST &...rest)
Fill in the argument structures.
Definition: postgresql/internals.h:140
Date and time.
Definition: types.h:147
Result(Result &&o)
Implement move.
Definition: postgresql/internals.h:172
uint32_t get_int4(unsigned row, unsigned col) const
Return a result value, transmitted in binary as a 4 bit integer.
Definition: postgresql/internals.h:222
bool is_null(unsigned row, unsigned col) const
Check if a result value is null.
Definition: postgresql/internals.h:202