diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2019-02-04 19:48:03 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2019-02-04 19:48:03 +0000 |
commit | 5ac2273a3bf8831d5ceb1a1b5b9fcab27fb95c1e (patch) | |
tree | 8b482bdfbdd8a1e69e3464dd96614a182223d6d3 | |
parent | Explicit desctructor not required (diff) | |
download | libdbpp-postgresql-5ac2273a3bf8831d5ceb1a1b5b9fcab27fb95c1e.tar.bz2 libdbpp-postgresql-5ac2273a3bf8831d5ceb1a1b5b9fcab27fb95c1e.tar.xz libdbpp-postgresql-5ac2273a3bf8831d5ceb1a1b5b9fcab27fb95c1e.zip |
CTF for parameter binding
-rw-r--r-- | libpqpp/pq-command.cpp | 69 | ||||
-rw-r--r-- | libpqpp/pq-command.h | 8 |
2 files changed, 31 insertions, 46 deletions
diff --git a/libpqpp/pq-command.cpp b/libpqpp/pq-command.cpp index 97f649c..81501bd 100644 --- a/libpqpp/pq-command.cpp +++ b/libpqpp/pq-command.cpp @@ -17,18 +17,6 @@ PQ::Command::Command(Connection * conn, const std::string & sql, const DB::Comma { } -PQ::Command::~Command() -{ - for (auto i = values.size(); i-- > 0;) { - if (bufs[i]) { - delete bufs[i]; - } - else if (formats[i] == 0) { - free(values[i]); - } - } -} - PQ::CommandOptions::CommandOptions(std::size_t hash, const DB::CommandOptionsMap & map) : DB::CommandOptions(hash), fetchTuples(get(map, "page-size", 35)), @@ -76,90 +64,84 @@ void PQ::Command::paramsAtLeast(unsigned int n) { if (values.size() <= n) { - values.resize(n + 1, NULL); + values.resize(n + 1, nullptr); lengths.resize(n + 1, 0); formats.resize(n + 1, 0); - bufs.resize(n + 1, NULL); - } - else { - if (bufs[n]) { - delete bufs[n]; - bufs[n] = nullptr; - } - else if (formats[n] == 0) { - free(values[n]); - } - values[n] = NULL; - formats[n] = 0; + bufs.resize(n + 1); } } +AdHocFormatter(PQCommandParamFmt, "%?"); template<typename ... T> void -PQ::Command::paramSet(unsigned int n, const char * fmt, const T & ... v) +PQ::Command::paramSet(unsigned int n, const T & ... v) { paramsAtLeast(n); - lengths[n] = asprintf(&values[n], fmt, v...); + bufs[n] = std::make_unique<std::string>(PQCommandParamFmt::get(v...)); + lengths[n] = bufs[n]->length(); + formats[n] = 0; + values[n] = bufs[n]->data(); } void PQ::Command::paramSet(unsigned int n, const std::string_view & b) { paramsAtLeast(n); - bufs[n] = new std::string(b); + bufs[n] = std::make_unique<std::string>(b); lengths[n] = b.length(); - values[n] = const_cast<char *>(bufs[n]->data()); + formats[n] = 0; + values[n] = bufs[n]->data(); } void PQ::Command::bindParamI(unsigned int n, int v) { - paramSet(n, "%d", v); + paramSet(n, v); } void PQ::Command::bindParamI(unsigned int n, long int v) { - paramSet(n, "%ld", v); + paramSet(n, v); } void PQ::Command::bindParamI(unsigned int n, long long int v) { - paramSet(n, "%lld", v); + paramSet(n, v); } void PQ::Command::bindParamI(unsigned int n, unsigned int v) { - paramSet(n, "%u", v); + paramSet(n, v); } void PQ::Command::bindParamI(unsigned int n, long unsigned int v) { - paramSet(n, "%lu", v); + paramSet(n, v); } void PQ::Command::bindParamI(unsigned int n, long long unsigned int v) { - paramSet(n, "%llu", v); + paramSet(n, v); } void PQ::Command::bindParamB(unsigned int n, bool v) { - paramSet(n, "%s", v ? "true" : "false"); + paramSet(n, v); } void PQ::Command::bindParamF(unsigned int n, double v) { - paramSet(n, "%g", v); + paramSet(n, v); } void PQ::Command::bindParamF(unsigned int n, float v) { - paramSet(n, "%g", v); + paramSet(n, v); } void PQ::Command::bindParamS(unsigned int n, const Glib::ustring & s) { - paramSet(n, s.raw()); + paramSet(n, std::string_view(s.data(), s.length())); } void PQ::Command::bindParamS(unsigned int n, const std::string_view & s) @@ -182,13 +164,16 @@ PQ::Command::bindParamBLOB(unsigned int n, const DB::Blob & v) paramsAtLeast(n); lengths[n] = v.len; formats[n] = 1; - values[n] = reinterpret_cast<char *>(const_cast<void *>(v.data)); - delete bufs[n]; - bufs[n] = nullptr; + values[n] = static_cast<const char *>(v.data); + bufs[n].reset(); } void PQ::Command::bindNull(unsigned int n) { paramsAtLeast(n); + lengths[n] = 0; + formats[n] = 0; + values[n] = nullptr; + bufs[n].reset(); } diff --git a/libpqpp/pq-command.h b/libpqpp/pq-command.h index a26bae8..4123d4c 100644 --- a/libpqpp/pq-command.h +++ b/libpqpp/pq-command.h @@ -4,6 +4,7 @@ #include <command.h> #include <libpq-fe.h> #include <vector> +#include <memory> #include <visibility.h> #include "pq-connection.h" @@ -28,7 +29,6 @@ namespace PQ { class Command : public virtual DB::Command { public: Command(Connection *, const std::string & sql, const DB::CommandOptionsCPtr &); - virtual ~Command() = 0; void bindParamI(unsigned int, int) override; void bindParamI(unsigned int, long int) override; @@ -59,12 +59,12 @@ namespace PQ { void paramsAtLeast(unsigned int); template<typename ... T> - void paramSet(unsigned int, const char * fmt, const T & ... t); + void paramSet(unsigned int, const T & ... t); void paramSet(unsigned int, const std::string_view &); - std::vector<char *> values; + std::vector<const char *> values; std::vector<int> lengths; std::vector<int> formats; - std::vector<std::string *> bufs; + std::vector<std::unique_ptr<std::string>> bufs; }; } |