1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
/**
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This file is part of osm2pgsql (https://osm2pgsql.org/).
*
* Copyright (C) 2006-2025 by the osm2pgsql developer community.
* For a full list of authors see the git log.
*/
#include <catch.hpp>
#include "common-import.hpp"
#include "pgsql.hpp"
namespace {
testing::db::import_t db;
} // anonymous namespace
TEST_CASE("Tablespace clause with no tablespace")
{
REQUIRE(tablespace_clause("").empty());
}
TEST_CASE("Tablespace clause with tablespace")
{
REQUIRE(tablespace_clause("foo") == R"( TABLESPACE "foo")");
}
TEST_CASE("Table name with public schema")
{
REQUIRE(qualified_name("public", "foo") == R"("public"."foo")");
}
TEST_CASE("Table name with schema")
{
REQUIRE(qualified_name("osm", "foo") == R"("osm"."foo")");
}
TEST_CASE("query with SELECT should work")
{
auto const conn = db.db().connect();
auto const result = conn.exec("SELECT 42");
REQUIRE(result.status() == PGRES_TUPLES_OK);
REQUIRE(result.num_fields() == 1);
REQUIRE(result.num_tuples() == 1);
REQUIRE(result.get(0, 0) == "42");
}
TEST_CASE("query with invalid SQL should fail")
{
auto const conn = db.db().connect();
REQUIRE_THROWS(conn.exec("NOT-VALID-SQL"));
}
TEST_CASE("exec with invalid SQL should fail")
{
auto const conn = db.db().connect();
REQUIRE_THROWS(conn.exec("XYZ"));
}
TEST_CASE("exec_prepared with single string parameters should work")
{
auto const conn = db.db().connect();
conn.exec("PREPARE test(int) AS SELECT $1");
auto const result = conn.exec_prepared("test", "17");
REQUIRE(result.status() == PGRES_TUPLES_OK);
REQUIRE(result.num_fields() == 1);
REQUIRE(result.num_tuples() == 1);
REQUIRE(result.get(0, 0) == "17");
}
TEST_CASE("exec_prepared with string parameters should work")
{
auto const conn = db.db().connect();
conn.exec("PREPARE test(int, int, int, int, int)"
" AS SELECT $1 + $2 + $3 + $4 + $5");
std::string a{"4"}; // NOLINT(misc-const-correctness)
std::string const b{"5"};
auto const result =
conn.exec_prepared("test", "1", "2", std::string{"3"}, a, b);
REQUIRE(result.status() == PGRES_TUPLES_OK);
REQUIRE(result.num_fields() == 1);
REQUIRE(result.num_tuples() == 1);
REQUIRE(result.get(0, 0) == "15");
}
TEST_CASE("exec_prepared with non-string parameters should work")
{
auto const conn = db.db().connect();
conn.exec("PREPARE test(int, int, int) AS SELECT $1 + $2 + $3");
auto const result = conn.exec_prepared("test", 1, 2.0, 3ULL);
REQUIRE(result.status() == PGRES_TUPLES_OK);
REQUIRE(result.num_fields() == 1);
REQUIRE(result.num_tuples() == 1);
REQUIRE(result.get(0, 0) == "6");
}
TEST_CASE("exec_prepared with binary parameter should work")
{
auto const conn = db.db().connect();
conn.exec("PREPARE test(bytea) AS SELECT length($1)");
binary_param const p{"foo \x01 bar"};
auto const result = conn.exec_prepared("test", p);
REQUIRE(result.status() == PGRES_TUPLES_OK);
REQUIRE(result.num_fields() == 1);
REQUIRE(result.num_tuples() == 1);
REQUIRE(result.get(0, 0) == "9");
}
TEST_CASE("exec_prepared with mixed parameter types should work")
{
auto const conn = db.db().connect();
conn.exec("PREPARE test(text, bytea, int) AS"
" SELECT length($1) + length($2) + $3");
std::string const p1{"foo bar"};
binary_param const p2{"foo \x01 bar"};
int const p3 = 17;
auto const result = conn.exec_prepared("test", p1, p2, p3);
REQUIRE(result.status() == PGRES_TUPLES_OK);
REQUIRE(result.num_fields() == 1);
REQUIRE(result.num_tuples() == 1);
REQUIRE(result.get(0, 0) == "33"); // 7 + 9 + 17
}
TEST_CASE("create table and insert something")
{
auto const conn = db.db().connect();
conn.exec("CREATE TABLE foo (x int)");
auto const result = conn.exec("INSERT INTO foo (x) VALUES (1), (2)");
REQUIRE(result.status() == PGRES_COMMAND_OK);
REQUIRE(result.num_fields() == 0);
REQUIRE(result.num_tuples() == 0);
REQUIRE(result.affected_rows() == 2);
}
TEST_CASE("empty result object should return fatal status")
{
pg_result_t const result;
REQUIRE(result.status() == PGRES_FATAL_ERROR);
REQUIRE_FALSE(result);
REQUIRE(result.num_fields() == 0);
REQUIRE(result.num_tuples() == 0);
REQUIRE(result.affected_rows() == 0);
}
|