diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-02-19 21:25:02 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-02-19 21:25:02 +0000 |
commit | feaced0381ac6fe0351fa9dbc3b8cc172618a429 (patch) | |
tree | 512148f1c92aa5bd80496221862a3672ca2db828 | |
parent | Build most things by default (diff) | |
download | libdbpp-postgresql-feaced0381ac6fe0351fa9dbc3b8cc172618a429.tar.bz2 libdbpp-postgresql-feaced0381ac6fe0351fa9dbc3b8cc172618a429.tar.xz libdbpp-postgresql-feaced0381ac6fe0351fa9dbc3b8cc172618a429.zip |
Refactor to use std::string as buffer and increase test coverage
-rw-r--r-- | libpqpp/pq-command.cpp | 92 | ||||
-rw-r--r-- | libpqpp/pq-command.h | 6 | ||||
-rw-r--r-- | libpqpp/pq-modifycommand.cpp | 2 | ||||
-rw-r--r-- | libpqpp/pq-selectcommand.cpp | 5 | ||||
-rw-r--r-- | libpqpp/unittests/testpq.cpp | 28 |
5 files changed, 83 insertions, 50 deletions
diff --git a/libpqpp/pq-command.cpp b/libpqpp/pq-command.cpp index 9b336bd..790c7f7 100644 --- a/libpqpp/pq-command.cpp +++ b/libpqpp/pq-command.cpp @@ -14,8 +14,13 @@ PQ::Command::Command(Connection * conn, const std::string & sql, unsigned int no PQ::Command::~Command() { - for (std::vector<char *>::const_iterator i = values.begin(); i != values.end(); ++i) { - free(*i); + for (auto i = values.size(); i-- > 0;) { + if (bufs[i]) { + delete bufs[i]; + } + else { + free(values[i]); + } } } @@ -46,102 +51,99 @@ PQ::Command::paramsAtLeast(unsigned int n) if (values.size() <= n) { values.resize(n + 1, NULL); lengths.resize(n + 1, 0); - formats.resize(n + 1, 0); + bufs.resize(n + 1, NULL); } else { - free(values[n]); + if (bufs[n]) { + delete bufs[n]; + bufs[n] = nullptr; + } + else { + free(values[n]); + } values[n] = NULL; } } +template<typename ... T> void -PQ::Command::bindParamI(unsigned int n, int v) +PQ::Command::paramSet(unsigned int n, const char * fmt, const T & ... v) { paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%d", v); - formats[n] = 0; + lengths[n] = asprintf(&values[n], fmt, v...); + delete bufs[n]; + bufs[n] = nullptr; } + void -PQ::Command::bindParamI(unsigned int n, long int v) +PQ::Command::paramSet(unsigned int n, const std::string & b) { paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%ld", v); - formats[n] = 0; + delete bufs[n]; + bufs[n] = new std::string(b); + lengths[n] = b.length(); + values[n] = const_cast<char *>(bufs[n]->data()); +} + +void +PQ::Command::bindParamI(unsigned int n, int v) +{ + paramSet(n, "%d", v); +} +void +PQ::Command::bindParamI(unsigned int n, long int v) +{ + paramSet(n, "%ld", v); } void PQ::Command::bindParamI(unsigned int n, long long int v) { - paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%lld", v); - formats[n] = 0; + paramSet(n, "%lld", v); } void PQ::Command::bindParamI(unsigned int n, unsigned int v) { - paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%u", v); - formats[n] = 0; + paramSet(n, "%u", v); } void PQ::Command::bindParamI(unsigned int n, long unsigned int v) { - paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%lu", v); - formats[n] = 0; + paramSet(n, "%lu", v); } void PQ::Command::bindParamI(unsigned int n, long long unsigned int v) { - paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%llu", v); - formats[n] = 0; + paramSet(n, "%llu", v); } void PQ::Command::bindParamB(unsigned int n, bool v) { - paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%s", v ? "true" : "false"); - formats[n] = 0; + paramSet(n, "%s", v ? "true" : "false"); } void PQ::Command::bindParamF(unsigned int n, double v) { - paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%g", v); - formats[n] = 0; + paramSet(n, "%g", v); } void PQ::Command::bindParamF(unsigned int n, float v) { - paramsAtLeast(n); - lengths[n] = asprintf(&values[n], "%g", v); - formats[n] = 0; + paramSet(n, "%g", v); } void PQ::Command::bindParamS(unsigned int n, const Glib::ustring & s) { - paramsAtLeast(n); - values[n] = strndup(s.c_str(), s.bytes()); - formats[n] = 0; - lengths[n] = s.bytes(); + paramSet(n, s); } void PQ::Command::bindParamT(unsigned int n, const boost::posix_time::time_duration & v) { - paramsAtLeast(n); - auto buf = boost::posix_time::to_simple_string(v); - values[n] = strdup(buf.c_str()); - formats[n] = 0; - lengths[n] = buf.length(); + paramSet(n, boost::posix_time::to_simple_string(v)); } void PQ::Command::bindParamT(unsigned int n, const boost::posix_time::ptime & v) { - paramsAtLeast(n); - auto buf = boost::posix_time::to_iso_extended_string(v); - values[n] = strdup(buf.c_str()); - formats[n] = 0; - lengths[n] = buf.length(); + paramSet(n, boost::posix_time::to_iso_extended_string(v)); } void PQ::Command::bindNull(unsigned int n) diff --git a/libpqpp/pq-command.h b/libpqpp/pq-command.h index ea32f61..8af2d07 100644 --- a/libpqpp/pq-command.h +++ b/libpqpp/pq-command.h @@ -36,12 +36,14 @@ namespace PQ { Connection * const c; void paramsAtLeast(unsigned int); + template<typename ... T> + void paramSet(unsigned int, const char * fmt, const T & ... t); + void paramSet(unsigned int, const std::string &); std::vector<char *> values; std::vector<int> lengths; - std::vector<int> formats; + std::vector<std::string *> bufs; }; } #endif - diff --git a/libpqpp/pq-modifycommand.cpp b/libpqpp/pq-modifycommand.cpp index e08057a..4c4ca0c 100644 --- a/libpqpp/pq-modifycommand.cpp +++ b/libpqpp/pq-modifycommand.cpp @@ -32,7 +32,7 @@ unsigned int PQ::ModifyCommand::execute(bool anc) { prepare(); - PGresult * res = PQexecPrepared(c->conn, stmntName.c_str(), values.size(), &values.front(), &lengths.front(), &formats.front(), 0); + PGresult * res = PQexecPrepared(c->conn, stmntName.c_str(), values.size(), &values.front(), &lengths.front(), NULL, 0); c->checkResult(res, PGRES_COMMAND_OK, PGRES_TUPLES_OK); unsigned int rows = atoi(PQcmdTuples(res)); PQclear(res); diff --git a/libpqpp/pq-selectcommand.cpp b/libpqpp/pq-selectcommand.cpp index 55dc02c..f8f44fd 100644 --- a/libpqpp/pq-selectcommand.cpp +++ b/libpqpp/pq-selectcommand.cpp @@ -21,6 +21,9 @@ PQ::SelectCommand::SelectCommand(Connection * conn, const std::string & sql, uns PQ::SelectCommand::~SelectCommand() { + if (execRes) { + PQclear(execRes); + } if (executed) { c->checkResultFree((PQexec(c->conn, s_close.c_str())), PGRES_COMMAND_OK); } @@ -66,7 +69,7 @@ PQ::SelectCommand::execute() txOpened = true; } execRes = c->checkResult( - PQexecParams(c->conn, s_declare.c_str(), values.size(), NULL, &values.front(), &lengths.front(), &formats.front(), 0), + PQexecParams(c->conn, s_declare.c_str(), values.size(), NULL, &values.front(), &lengths.front(), NULL, 0), PGRES_COMMAND_OK); fetchTuples(); unsigned int nFields = PQnfields(execRes); diff --git a/libpqpp/unittests/testpq.cpp b/libpqpp/unittests/testpq.cpp index 96e5611..80757db 100644 --- a/libpqpp/unittests/testpq.cpp +++ b/libpqpp/unittests/testpq.cpp @@ -54,6 +54,31 @@ BOOST_AUTO_TEST_CASE( bindAndSend ) mod->bindParamT(4, testDateTime); mod->bindParamT(5, testInterval); mod->execute(); + mod->bindParamI(0, (unsigned int)(testInt + 10)); + mod->bindParamF(1, (float)(testDouble + 10)); + mod->bindParamS(2, testString + " something"); + mod->bindParamB(3, true); + mod->bindParamT(4, testDateTime); + mod->bindParamT(5, testInterval); + mod->execute(); + mod->bindNull(0); + mod->bindParamI(1, (long long unsigned int)(testDouble + 10)); + mod->bindParamI(2, (long long int)testInt); + mod->bindParamB(3, true); + mod->bindNull(4); + mod->bindNull(5); + mod->execute(); + mod->bindNull(0); + mod->bindParamI(1, (long unsigned int)(testDouble + 10)); + mod->bindParamI(2, (long int)testInt); + mod->bindParamB(3, true); + mod->bindParamS(4, "2016-01-01T12:34:56"); + mod->bindNull(5); + mod->execute(); + delete mod; + mod = rw->newModifyCommand("DELETE FROM test WHERE string = '?'"); + BOOST_REQUIRE_THROW(mod->execute(false), DB::NoRowsAffected); + BOOST_REQUIRE_EQUAL(0, mod->execute(true)); delete mod; delete rw; } @@ -103,8 +128,9 @@ BOOST_AUTO_TEST_CASE( bindAndSelectOther ) { auto ro = DB::MockDatabase::openConnectionTo("pqmock"); - auto select = ro->newSelectCommand("SELECT * FROM test WHERE id != ?"); + auto select = ro->newSelectCommand("SELECT * FROM test WHERE id != ? AND id != ?"); select->bindParamI(0, testInt); + select->bindParamI(1, testInt + 10); select->execute(); int rows = 0; while (select->fetch()) { |