From 78c885ff3bcbb9c7e16f3fce29f1d0052aba3086 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 4 Jan 2017 17:54:29 +0000 Subject: Add PQ specific command options to control page size and the use of bulk -v- cursor selects --- libpqpp/pq-command.cpp | 9 +++++++++ libpqpp/pq-command.h | 12 ++++++++++++ libpqpp/pq-connection.cpp | 6 +++--- libpqpp/pq-cursorselectcommand.cpp | 4 ++-- libpqpp/pq-cursorselectcommand.h | 2 +- libpqpp/unittests/testpq.cpp | 7 +++++-- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/libpqpp/pq-command.cpp b/libpqpp/pq-command.cpp index af203cc..a6259df 100644 --- a/libpqpp/pq-command.cpp +++ b/libpqpp/pq-command.cpp @@ -25,6 +25,15 @@ PQ::Command::~Command() } } +PQ::CommandOptions::CommandOptions(std::size_t hash, + unsigned int ft, + bool uc) : + DB::CommandOptions(hash), + fetchTuples(ft), + useCursor(uc) +{ +} + AdHocFormatter(PQCommandParamName, "$%?"); void PQ::Command::prepareSql(std::stringstream & psql, const std::string & sql) const diff --git a/libpqpp/pq-command.h b/libpqpp/pq-command.h index 2c0bf14..056706e 100644 --- a/libpqpp/pq-command.h +++ b/libpqpp/pq-command.h @@ -4,9 +4,21 @@ #include #include #include +#include namespace PQ { class Connection; + + class DLL_PUBLIC CommandOptions : public DB::CommandOptions { + public: + CommandOptions(std::size_t hash, + unsigned int fetchTuples = 35, + bool useCursor = true); + + unsigned int fetchTuples; + bool useCursor; + }; + class Command : public virtual DB::Command { public: Command(Connection *, const std::string & sql, unsigned int no); diff --git a/libpqpp/pq-connection.cpp b/libpqpp/pq-connection.cpp index 1fadde3..5b560a9 100644 --- a/libpqpp/pq-connection.cpp +++ b/libpqpp/pq-connection.cpp @@ -99,11 +99,11 @@ PQ::Connection::ping() const DB::SelectCommand * PQ::Connection::newSelectCommand(const std::string & sql, const DB::CommandOptions * opts) { - // Yes, this is a hack - if (sql.find("libdbpp:no-cursor") != (std::string::size_type)-1) { + auto pqco = dynamic_cast(opts); + if (pqco && !pqco->useCursor) { return new BulkSelectCommand(this, sql, pstmntNo++, opts); } - return new CursorSelectCommand(this, sql, pstmntNo++); + return new CursorSelectCommand(this, sql, pstmntNo++, pqco); } DB::ModifyCommand * diff --git a/libpqpp/pq-cursorselectcommand.cpp b/libpqpp/pq-cursorselectcommand.cpp index ac4b825..d130b89 100644 --- a/libpqpp/pq-cursorselectcommand.cpp +++ b/libpqpp/pq-cursorselectcommand.cpp @@ -7,13 +7,13 @@ AdHocFormatter(PQCursorSelectDeclare, "DECLARE %? CURSOR FOR "); AdHocFormatter(PQCursorSelectFetch, "FETCH %? IN %?"); AdHocFormatter(PQCursorSelectClose, "CLOSE %?"); -PQ::CursorSelectCommand::CursorSelectCommand(Connection * conn, const std::string & sql, unsigned int no) : +PQ::CursorSelectCommand::CursorSelectCommand(Connection * conn, const std::string & sql, unsigned int no, const PQ::CommandOptions * pqco) : DB::Command(sql), PQ::SelectBase(sql), PQ::Command(conn, sql, no), executed(false), txOpened(false), - fTuples(35), + fTuples(pqco ? pqco->fetchTuples : 35), s_fetch(PQCursorSelectFetch::get(fTuples, stmntName)), s_close(PQCursorSelectClose::get(stmntName)) { diff --git a/libpqpp/pq-cursorselectcommand.h b/libpqpp/pq-cursorselectcommand.h index e7a67e6..417cff9 100644 --- a/libpqpp/pq-cursorselectcommand.h +++ b/libpqpp/pq-cursorselectcommand.h @@ -11,7 +11,7 @@ namespace PQ { class Column; class CursorSelectCommand : public SelectBase, public Command { public: - CursorSelectCommand(Connection *, const std::string & sql, unsigned int no); + CursorSelectCommand(Connection *, const std::string & sql, unsigned int no, const PQ::CommandOptions *); virtual ~CursorSelectCommand(); bool fetch() override; diff --git a/libpqpp/unittests/testpq.cpp b/libpqpp/unittests/testpq.cpp index 15ea022..f7c327f 100644 --- a/libpqpp/unittests/testpq.cpp +++ b/libpqpp/unittests/testpq.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include class StandardMockDatabase : public PQ::Mock { @@ -291,7 +292,8 @@ BOOST_AUTO_TEST_CASE( statementReuse ) BOOST_AUTO_TEST_CASE( bulkSelect ) { auto ro = DB::MockDatabase::openConnectionTo("PQmock"); - auto sel = ro->newSelectCommand("SELECT * FROM test WHERE id > ? --libdbpp:no-cursor"); + PQ::CommandOptions co(0, 35, false); + auto sel = ro->newSelectCommand("SELECT * FROM test WHERE id > ?", &co); sel->bindParamI(0, 1); int totalInt = 0, count = 0; sel->forEachRow([&totalInt, &count](auto i) { @@ -307,7 +309,8 @@ BOOST_AUTO_TEST_CASE( bulkSelect ) BOOST_AUTO_TEST_CASE( insertReturning ) { auto ro = DB::MockDatabase::openConnectionTo("PQmock"); - auto sel = ro->newSelectCommand("INSERT INTO test(id, fl) VALUES(1, 3) RETURNING id + fl --libdbpp:no-cursor"); + PQ::CommandOptions co(0, 35, false); + auto sel = ro->newSelectCommand("INSERT INTO test(id, fl) VALUES(1, 3) RETURNING id + fl", &co); int totalInt = 0, count = 0; sel->forEachRow([&totalInt, &count](auto i) { totalInt += i; -- cgit v1.2.3