File: common-pg.hpp

package info (click to toggle)
osm2pgsql 0.92.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,420 kB
  • ctags: 1,429
  • sloc: cpp: 11,650; python: 543; sh: 98; makefile: 14
file content (112 lines) | stat: -rw-r--r-- 3,290 bytes parent folder | download | duplicates (3)
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
#ifndef COMMON_PG_HPP
#define COMMON_PG_HPP

#include <string>
#include <memory>
#include <boost/format.hpp>
#include <boost/noncopyable.hpp>
#include <libpq-fe.h>

// reuse the database_options_t class
#include "options.hpp"

/* Some RAII objects to make writing stuff that needs a temporary database
 * easier, and to keep track of and free connections and results objects.
 */
namespace pg {

struct conn;
struct result;

typedef std::shared_ptr<conn> conn_ptr;
typedef std::shared_ptr<result> result_ptr;

struct conn
    : public boost::noncopyable,
      public std::enable_shared_from_this<conn> {

    static conn_ptr connect(const std::string &conninfo);
    static conn_ptr connect(const database_options_t &database_options);
    result_ptr exec(const std::string &query);
    result_ptr exec(const boost::format &fmt);
    PGconn *get();

    ~conn();

private:
    conn(const std::string &conninfo);

    PGconn *m_conn;
};

struct result
  : public boost::noncopyable {
    result(conn_ptr conn, const std::string &query);
    PGresult *get();
    ~result();

private:
    conn_ptr m_conn;
    PGresult *m_result;
};

struct tempdb
  : public boost::noncopyable {

    tempdb();
    ~tempdb();

    static std::unique_ptr<pg::tempdb> create_db_or_skip();

    database_options_t database_options;

    void check_tblspc();
    /**
     * Checks the result of a query with COUNT(*).
     * It will work with any integer-returning query.
     * \param[in] expected expected result
     * \param[in] query SQL query to run. Must return one tuple.
     * \throws std::runtime_error if query result is not expected
     */
    void check_count(int expected, const std::string &query);

    /**
     * Checks a floating point number.
     * It allows a small variance around the expected result to allow for
     * floating point differences.
     * The query must only return one tuple
     * \param[in] expected expected result
     * \param[in] query SQL query to run. Must return one tuple.
     * \throws std::runtime_error if query result is not expected
     */
    void check_number(double expected, const std::string &query);

    /**
     * Check the string a query returns.
     * \param[in] expected expected result
     * \param[in] query SQL query to run. Must return one tuple.
     * \throws std::runtime_error if query result is not expected
     */
    void check_string(const std::string &expected, const std::string &query);
    /**
     * Assert that the database has a certain table_name
     * \param[in] table_name Name of the table to check, optionally schema-qualified
     * \throws std::runtime_error if missing the table
     */
    void assert_has_table(const std::string &table_name);

private:
    /**
     * Sets up an extension, trying first with 9.1 CREATE EXTENSION, and falling
     * back to trying to find extension_files. The fallback is not likely to
     * work on systems not based on Debian.
     */
    void setup_extension(const std::string &extension, const std::vector<std::string> &extension_files = std::vector<std::string>());

    conn_ptr m_conn; ///< connection to the test DB
    conn_ptr m_postgres_conn; ///< Connection to the "postgres" db, used to create and drop test DBs
};

} // namespace pg

#endif /* COMMON_PG_HPP */