Commit 012d4aa4 authored by Mateusz Loskot's avatar Mateusz Loskot Committed by Ronan

Drop support for PostgreSQL 7.x

Remove uses of CMake opions and related #define-s
  SOCI_POSTGRESQL_NOPREPARE
  SOCI_POSTGRESQL_NOPARAMS
  SOCI_POSTGRESQL_NOBINDBYNAME.

Closes #122
parent 4e6a6490
......@@ -107,16 +107,6 @@ int id = 7;
sql << "select name from person where id = :id", use(id, "id")
```
Apart from the portable "colon-name" syntax above, which is achieved by rewriting the query string, the backend also supports the PostgreSQL native numbered syntax:
```cpp
int i = 7;
int j = 8;
sql << "insert into t(x, y) values($1, $2)", use(i), use(j);
```
The use of native syntax is not recommended, but can be nevertheless imposed by switching off the query rewriting. This can be achieved by defining the macro `SOCI_POSTGRESQL_NOBINDBYNAME` and it is actually necessary for PostgreSQL 7.3, in which case binding of use elements is not supported at all. See the [Configuration options](#options) section for details.
### Bulk Operations
The PostgreSQL backend has full support for SOCI's [bulk operations](../binding.md#bulk-operations) interface.
......@@ -165,7 +155,4 @@ format of UUID on output. See the test `test_uuid_column_type_support` for usage
To support older PostgreSQL versions, the following configuration macros are recognized:
* `SOCI_POSTGRESQL_NOBINDBYNAME` - switches off the query rewriting.
* `SOCI_POSTGRESQL_NOPARAMS` - disables support for parameterized queries (binding of use elements), automatically imposes also the `SOCI_POSTGRESQL_NOBINDBYNAME` macro. It is necessary for PostgreSQL 7.3.
* `SOCI_POSTGRESQL_NOPREPARE` - disables support for separate query preparation, which in this backend is significant only in terms of optimization. It is necessary for PostgreSQL 7.3 and 7.4.
* `SOCI_POSTGRESQL_NOSINGLEROWMODE` - disable single mode retrieving query results row-by-row. It is necessary for PostgreSQL prior to version 9.
* `SOCI_POSTGRESQL_NOSINLGEROWMODE` - disable single mode retrieving query results row-by-row. It is necessary for PostgreSQL prior to version 9.
......@@ -83,11 +83,6 @@ string const& name = getNameFromSomewhere();
sql << "insert into person(name) values(:n)", use(name);
```
### Portability note
Older versions of the PostgreSQL client API do not allow to use input parameters at all.
In order to compile SOCI with those old client libraries, define the `SOCI_POSTGRESQL_NOPARAMS` preprocessor name passing `-DSOCI_POSTGRESQL_NOPARAMS=ON` variable to CMake.
## Binding by position
If there is more output or input "holes" in the single statement, it is possible to use many `into` and `use` expressions, separated by commas, where each expression will be responsible for the consecutive "hole" in the statement:
......@@ -128,17 +123,6 @@ sql << "update person"
use(addr, "addr");
```
### Portability notes
The PostgreSQL backend allows to use the "native" PostgreSQL way of naming parameters in the query, which is by numbers like `$1`, `$2`, `$3`, etc.
In fact, the backend *rewrites* the given query to the native form - and this is also one of the very few places where SOCI intrudes into the SQL query.
For portability reasons, it is recommended to use named parameters, as shown in the examples above.
The query rewriting can be switched off by compiling the backend with the `SOCI_POSTGRESQL_NOBINDBYNAME` name defined (pass `-DSOCI_POSTGRESQL_NOBINDBYNAME=ON` variable to CMake).
Note that in this case it is also necessary to define `SOCI_POSTGRESQL_NOPREPARE` (controlled by CMake variable `-DSOCI_POSTGRESQL_NOPREPARE=ON`), because statement preparation relies on successful query rewriting.
In practice, both macros will be needed for PostgreSQL server older than 8.0.
## Bulk operations
Bulk operations allow the user to bind, as into or use element, whole vectors of objects.
......
......@@ -47,9 +47,6 @@ The `true` parameter given to the `execute` method indicates that the actual dat
The above syntax is supported for all backends, even if some database server does not actually provide this functionality - in which case the library will internally execute the query in a single phase, without really separating the statement preparation from execution.
For PostgreSQL servers older than 8.0 it is necessary to define the `SOCI_POSTGRESQL_NOPREPARE` macro while compiling the library to fall back to this one-phase behaviour.
Simply, pass `-DSOCI_POSTGRESQL_NOPREPARE=ON` variable to CMake.
## Rowset and iterator
The `rowset` class provides an alternative means of executing queries and accessing results using STL-like iterator interface.
......
......@@ -15,30 +15,6 @@ option(SOCI_POSTGRESQL_NOSINGLEROWMODE
"Do not use single row mode. PostgreSQL <9 portability."
OFF)
option(SOCI_POSTGRESQL_NOPARAMS
"Do not use input parameters. PostgreSQL 7.x portability."
OFF)
option(SOCI_POSTGRESQL_NOBINDBYNAME
"Disable query rewriting to native form. PostgreSQL 7.0 portability."
OFF)
cmake_dependent_option(SOCI_POSTGRESQL_NOPREPARE
"Disable prepared statements. Set ON if SOCI_POSTGRESQL_NOBINDBYNAME is ON. PostgreSQL 7.0 portability." ON
SOCI_POSTGRESQL_NOBINDBYNAME OFF)
if(SOCI_POSTGRESQL_NOPARAMS)
add_definitions(-DSOCI_POSTGRESQL_NOPARAMS=1)
endif()
if(SOCI_POSTGRESQL_NOBINDBYNAME)
add_definitions(-DSOCI_POSTGRESQL_NOBINDBYNAME=1)
endif()
if(SOCI_POSTGRESQL_NOPREPARE)
add_definitions(-DSOCI_POSTGRESQL_NOPREPARE=1)
endif()
if (POSTGRESQL_VERSION VERSION_LESS "9.0.0")
set(SOCI_POSTGRESQL_NOSINGLEROWMODE ON CACHE BOOL "Use single row mode for PostgreSQL 9+" FORCE)
endif()
......@@ -53,7 +29,4 @@ soci_backend(PostgreSQL
AUTHORS "Maciej Sobczak, Stephen Hutton"
MAINTAINERS "Mateusz Loskot")
boost_report_value(SOCI_POSTGRESQL_NOPARAMS)
boost_report_value(SOCI_POSTGRESQL_NOBINDBYNAME)
boost_report_value(SOCI_POSTGRESQL_NOPREPARE)
boost_report_value(SOCI_POSTGRESQL_NOSINGLEROWMODE)
boost_report_value(SOCI_POSTGRESQL_NOSINLGEROWMODE)
......@@ -14,12 +14,6 @@
#include <ctime>
#include <sstream>
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
......
......@@ -11,12 +11,6 @@
#include "soci/backend-loader.h"
#include <libpq/libpq-fs.h> // libpq
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
......
......@@ -14,12 +14,6 @@
#include <ctime>
#include <sstream>
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
......
......@@ -17,12 +17,6 @@
#include <ctime>
#include <sstream>
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
using namespace soci;
using namespace soci::details;
......
......@@ -23,12 +23,6 @@
#include <ctime>
#include <sstream>
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
using namespace soci;
using namespace soci::details;
using namespace soci::details::postgresql;
......
......@@ -21,12 +21,6 @@
#include <limits>
#include <sstream>
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
using namespace soci;
using namespace soci::details;
......
......@@ -16,12 +16,6 @@
#include <ctime>
#include <sstream>
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
using namespace soci;
using namespace soci::details;
......@@ -109,9 +103,6 @@ void postgresql_statement_backend::clean_up()
void postgresql_statement_backend::prepare(std::string const & query,
statement_type stType)
{
#ifdef SOCI_POSTGRESQL_NOBINDBYNAME
query_ = query;
#else
// rewrite the query by transforming all named parameters into
// the postgresql_ numbers ones (:abc -> $1, etc.)
......@@ -210,10 +201,6 @@ void postgresql_statement_backend::prepare(std::string const & query,
query_ += ss.str();
}
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#ifndef SOCI_POSTGRESQL_NOPREPARE
if (stType == st_repeatable_query)
{
if (!statementName_.empty())
......@@ -256,8 +243,6 @@ void postgresql_statement_backend::prepare(std::string const & query,
}
stType_ = stType;
#endif // SOCI_POSTGRESQL_NOPREPARE
}
statement_backend::exec_fetch_result
......@@ -359,43 +344,6 @@ postgresql_statement_backend::execute(int number)
}
}
#ifdef SOCI_POSTGRESQL_NOPARAMS
throw soci_error("Queries with parameters are not supported.");
#else
#ifdef SOCI_POSTGRESQL_NOPREPARE
#ifndef SOCI_POSTGRESQL_NOSINGLEROWMODE
if (single_row_mode_)
{
int result = PQsendQueryParams(
session_.conn_, query_.c_str(),
static_cast<int>(paramValues.size()),
NULL, &paramValues[0], NULL, NULL, 0);
if (result != 1)
{
throw_soci_error(session_.conn_,
"Cannot execute query in single-row mode");
}
result = PQsetSingleRowMode(session_.conn_);
if (result != 1)
{
throw_soci_error(session_.conn_,
"cannot set singlerow mode");
}
}
else
#endif // !SOCI_POSTGRESQL_NOSINGLEROWMODE
{
// default multi-row execution
result_.reset(PQexecParams(session_.conn_, query_.c_str(),
static_cast<int>(paramValues.size()),
NULL, &paramValues[0], NULL, NULL, 0));
}
#else
if (stType_ == st_repeatable_query)
{
// this query was separately prepared
......@@ -466,10 +414,6 @@ postgresql_statement_backend::execute(int number)
}
}
#endif // SOCI_POSTGRESQL_NOPREPARE
#endif // SOCI_POSTGRESQL_NOPARAMS
if (numberOfExecutions > 1)
{
// there are only bulk use elements (no intos)
......@@ -497,34 +441,6 @@ postgresql_statement_backend::execute(int number)
{
// there are no use elements
// - execute the query without parameter information
#ifdef SOCI_POSTGRESQL_NOPREPARE
#ifndef SOCI_POSTGRESQL_NOSINGLEROWMODE
if (single_row_mode_)
{
int result = PQsendQuery(session_.conn_, query_.c_str());
if (result != 1)
{
throw_soci_error(session_.conn_,
"Cannot execute query in single-row mode");
}
result = PQsetSingleRowMode(session_.conn_);
if (result != 1)
{
throw_soci_error(session_.conn_,
"Cannot set single-row mode");
}
}
else
#endif // !SOCI_POSTGRESQL_NOSINGLEROWMODE
{
// default multi-row execution
result_.reset(PQexec(session_.conn_, query_.c_str()));
}
#else
if (stType_ == st_repeatable_query)
{
// this query was separately prepared
......@@ -583,8 +499,6 @@ postgresql_statement_backend::execute(int number)
result_.reset(PQexec(session_.conn_, query_.c_str()));
}
}
#endif // SOCI_POSTGRESQL_NOPREPARE
}
}
......
......@@ -19,12 +19,6 @@
#include <ctime>
#include <sstream>
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
using namespace soci;
using namespace soci::details;
using namespace soci::details::postgresql;
......
......@@ -19,13 +19,6 @@
#include <limits>
#include <sstream>
#ifdef SOCI_POSTGRESQL_NOPARAMS
#ifndef SOCI_POSTGRESQL_NOBINDBYNAME
#define SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOBINDBYNAME
#endif // SOCI_POSTGRESQL_NOPARAMS
using namespace soci;
using namespace soci::details;
using namespace soci::details::postgresql;
......
......@@ -1293,9 +1293,6 @@ TEST_CASE_METHOD(common_tests, "Indicators vector", "[core][indicator][vector]")
}
// Note: this functionality is not available with older PostgreSQL
#ifndef SOCI_POSTGRESQL_NOPARAMS
// "use" tests, type conversions, etc.
TEST_CASE_METHOD(common_tests, "Use type conversion", "[core][use]")
{
......@@ -1519,8 +1516,6 @@ TEST_CASE_METHOD(common_tests, "Use type conversion", "[core][use]")
}
}
#endif // SOCI_POSTGRESQL_NOPARAMS
// test for multiple use (and into) elements
TEST_CASE_METHOD(common_tests, "Multiple use and into", "[core][use][into]")
{
......@@ -1532,18 +1527,9 @@ TEST_CASE_METHOD(common_tests, "Multiple use and into", "[core][use][into]")
int i2 = 6;
int i3 = 7;
#ifndef SOCI_POSTGRESQL_NOPARAMS
sql << "insert into soci_test(i1, i2, i3) values(:i1, :i2, :i3)",
use(i1), use(i2), use(i3);
#else
// Older PostgreSQL does not support use elements.
sql << "insert into soci_test(i1, i2, i3) values(5, 6, 7)";
#endif // SOCI_POSTGRESQL_NOPARAMS
i1 = 0;
i2 = 0;
i3 = 0;
......@@ -1561,8 +1547,6 @@ TEST_CASE_METHOD(common_tests, "Multiple use and into", "[core][use][into]")
i2 = 0;
i3 = 0;
#ifndef SOCI_POSTGRESQL_NOPARAMS
statement st = (sql.prepare
<< "insert into soci_test(i1, i2, i3) values(:i1, :i2, :i3)",
use(i1), use(i2), use(i3));
......@@ -1580,15 +1564,6 @@ TEST_CASE_METHOD(common_tests, "Multiple use and into", "[core][use][into]")
i3 = 9;
st.execute(true);
#else
// Older PostgreSQL does not support use elements.
sql << "insert into soci_test(i1, i2, i3) values(1, 2, 3)";
sql << "insert into soci_test(i1, i2, i3) values(4, 5, 6)";
sql << "insert into soci_test(i1, i2, i3) values(7, 8, 9)";
#endif // SOCI_POSTGRESQL_NOPARAMS
std::vector<int> v1(5);
std::vector<int> v2(5);
std::vector<int> v3(5);
......@@ -1611,9 +1586,6 @@ TEST_CASE_METHOD(common_tests, "Multiple use and into", "[core][use][into]")
}
}
// Not supported with older PostgreSQL
#ifndef SOCI_POSTGRESQL_NOPARAMS
// use vector elements
TEST_CASE_METHOD(common_tests, "Use vector", "[core][use][vector]")
{
......@@ -1915,7 +1887,6 @@ TEST_CASE_METHOD(common_tests, "Named parameters with similar names", "[core][us
// }
}
}
#endif // SOCI_POSTGRESQL_NOPARAMS
// transaction test
TEST_CASE_METHOD(common_tests, "Transactions", "[core][transaction]")
......@@ -1989,8 +1960,6 @@ TEST_CASE_METHOD(common_tests, "Transactions", "[core][transaction]")
}
}
#ifndef SOCI_POSTGRESQL_NOPARAMS
std::tm generate_tm()
{
std::tm t = std::tm();
......@@ -2074,8 +2043,6 @@ TEST_CASE_METHOD(common_tests, "Use with indicators", "[core][use][indicator]")
CHECK(vals[4] == 10);
}
#endif // SOCI_POSTGRESQL_NOPARAMS
// Dynamic binding to Row objects
TEST_CASE_METHOD(common_tests, "Dynamic row binding", "[core][dynamic]")
{
......@@ -2200,7 +2167,6 @@ TEST_CASE_METHOD(common_tests, "Dynamic row binding 2", "[core][dynamic]")
sql << "insert into soci_test(id, val) values(2, 20)";
sql << "insert into soci_test(id, val) values(3, 30)";
#ifndef SOCI_POSTGRESQL_NOPARAMS
{
int id = 2;
row r;
......@@ -2234,16 +2200,6 @@ TEST_CASE_METHOD(common_tests, "Dynamic row binding 2", "[core][dynamic]")
CHECK(r.get_properties(0).get_data_type() == dt_integer);
CHECK(r.get<int>(0) == 10);
}
#else
{
row r;
sql << "select val from soci_test where id = 2", into(r);
CHECK(r.size() == 1);
CHECK(r.get_properties(0).get_data_type() == dt_integer);
CHECK(r.get<int>(0) == 20);
}
#endif // SOCI_POSTGRESQL_NOPARAMS
}
// More Dynamic binding to row objects
......@@ -2499,8 +2455,6 @@ TEST_CASE_METHOD(common_tests, "Numeric round trip", "[core][float]")
ASSERT_EQUAL_EXACT(d1, d2);
}
#ifndef SOCI_POSTGRESQL_NOPARAMS
// test for bulk fetch with single use
TEST_CASE_METHOD(common_tests, "Bulk fetch with single use", "[core][bulk]")
{
......@@ -2525,8 +2479,6 @@ TEST_CASE_METHOD(common_tests, "Bulk fetch with single use", "[core][bulk]")
CHECK(names[2] == "julian");
}
#endif // SOCI_POSTGRESQL_NOPARAMS
// test for basic logging support
TEST_CASE_METHOD(common_tests, "Basic logging support", "[core][logging]")
{
......
......@@ -54,24 +54,9 @@ TEST_CASE("PostgreSQL ROWID", "[postgresql][rowid][oid]")
int id;
std::string name;
#ifndef SOCI_POSTGRESQL_NOPARAMS
sql << "select id, name from soci_test where oid = :rid",
into(id), into(name), use(rid);
#else
// Older PostgreSQL does not support use elements.
postgresql_rowid_backend *rbe
= static_cast<postgresql_rowid_backend *>(rid.get_backend());
unsigned long oid = rbe->value_;
sql << "select id, name from soci_test where oid = " << oid,
into(id), into(name);
#endif // SOCI_POSTGRESQL_NOPARAMS
CHECK(id == 7);
CHECK(name == "John");
}
......@@ -98,8 +83,6 @@ public:
try { sql << "create language plpgsql"; }
catch (soci_error const &) {} // ignore if error
#ifndef SOCI_POSTGRESQL_NOPARAMS
sql <<
"create or replace function soci_test(msg varchar) "
"returns varchar as $$ "
......@@ -107,16 +90,6 @@ public:
"begin "
" return msg; "
"end $$ language plpgsql";
#else
sql <<
"create or replace function soci_test(varchar) "
"returns varchar as \' "
"declare x int := 1;"
"begin "
" return $1; "
"end \' language plpgsql";
#endif
}
protected:
......@@ -136,22 +109,11 @@ TEST_CASE("PostgreSQL function call", "[postgresql][function]")
std::string in("my message");
std::string out;
#ifndef SOCI_POSTGRESQL_NOPARAMS
statement st = (sql.prepare <<
"select soci_test(:input)",
into(out),
use(in, "input"));
#else
// Older PostgreSQL does not support use elements.
statement st = (sql.prepare <<
"select soci_test(\'" << in << "\')",
into(out));
#endif // SOCI_POSTGRESQL_NOPARAMS
st.execute(true);
CHECK(out == in);
......@@ -160,20 +122,10 @@ TEST_CASE("PostgreSQL function call", "[postgresql][function]")
std::string in("my message2");
std::string out;
#ifndef SOCI_POSTGRESQL_NOPARAMS
procedure proc = (sql.prepare <<
"soci_test(:input)",
into(out), use(in, "input"));
#else
// Older PostgreSQL does not support use elements.
procedure proc = (sql.prepare <<
"soci_test(\'" << in << "\')", into(out));
#endif // SOCI_POSTGRESQL_NOPARAMS
proc.execute(true);
CHECK(out == in);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment