summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2019-02-04 19:48:03 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2019-02-04 19:48:03 +0000
commit5ac2273a3bf8831d5ceb1a1b5b9fcab27fb95c1e (patch)
tree8b482bdfbdd8a1e69e3464dd96614a182223d6d3
parentExplicit desctructor not required (diff)
downloadlibdbpp-postgresql-5ac2273a3bf8831d5ceb1a1b5b9fcab27fb95c1e.tar.bz2
libdbpp-postgresql-5ac2273a3bf8831d5ceb1a1b5b9fcab27fb95c1e.tar.xz
libdbpp-postgresql-5ac2273a3bf8831d5ceb1a1b5b9fcab27fb95c1e.zip
CTF for parameter binding
-rw-r--r--libpqpp/pq-command.cpp69
-rw-r--r--libpqpp/pq-command.h8
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;
};
}