9
9
#include < boost/filesystem/fstream.hpp>
10
10
#include < boost/format.hpp>
11
11
#include < boost/algorithm/string/predicate.hpp>
12
+ #include < boost/lexical_cast.hpp>
12
13
13
14
#ifdef _MSC_VER
14
15
#include < windows.h>
@@ -76,10 +77,11 @@ result::~result() {
76
77
}
77
78
78
79
tempdb::tempdb ()
79
- : m_conn(conn::connect(" dbname=postgres" )) {
80
+ : m_postgres_conn(conn::connect(" dbname=postgres" ))
81
+ {
80
82
result_ptr res = nullptr ;
81
83
database_options.db = (boost::format (" osm2pgsql-test-%1%-%2%" ) % getpid () % time (nullptr )).str ();
82
- m_conn ->exec (boost::format (" DROP DATABASE IF EXISTS \" %1%\" " ) % database_options.db );
84
+ m_postgres_conn ->exec (boost::format (" DROP DATABASE IF EXISTS \" %1%\" " ) % database_options.db );
83
85
// tests can be run concurrently which means that this query can collide with other similar ones
84
86
// so we implement a simple retry here to get around the case that they do collide if we dont
85
87
// we often fail due to both trying to access template1 at the same time
@@ -88,18 +90,18 @@ tempdb::tempdb()
88
90
while (status != PGRES_COMMAND_OK && retries++ < 20 )
89
91
{
90
92
sleep (1 );
91
- res = m_conn ->exec (boost::format (" CREATE DATABASE \" %1%\" WITH ENCODING 'UTF8'" ) % database_options.db );
93
+ res = m_postgres_conn ->exec (boost::format (" CREATE DATABASE \" %1%\" WITH ENCODING 'UTF8'" ) % database_options.db );
92
94
status = PQresultStatus (res->get ());
93
95
}
94
96
if (PQresultStatus (res->get ()) != PGRES_COMMAND_OK) {
95
97
throw std::runtime_error ((boost::format (" Could not create a database: %1%" )
96
98
% PQresultErrorMessage (res->get ())).str ());
97
99
}
98
100
99
- conn_ptr db = conn::connect (database_options. conninfo () );
101
+ m_conn = conn::connect (database_options);
100
102
101
- setup_extension (db, " postgis" , {" postgis-1.5/postgis.sql" , " postgis-1.5/spatial_ref_sys.sql" });
102
- setup_extension (db, " hstore" );
103
+ setup_extension (" postgis" , {" postgis-1.5/postgis.sql" , " postgis-1.5/spatial_ref_sys.sql" });
104
+ setup_extension (" hstore" );
103
105
}
104
106
105
107
void tempdb::check_tblspc () {
@@ -120,23 +122,98 @@ void tempdb::check_tblspc() {
120
122
121
123
}
122
124
125
+ void tempdb::check_count (int expected, const std::string &query) {
126
+ pg::result_ptr res = m_conn->exec (query);
127
+ if (PQresultStatus (res->get ()) != PGRES_TUPLES_OK) {
128
+ throw std::runtime_error ((boost::format (" Expected PGRES_TUPLES_OK but "
129
+ " got %1%. %2% Query was %3%." )
130
+ % PQresStatus (PQresultStatus (res->get ()))
131
+ % PQresultErrorMessage (res->get ())
132
+ % query).str ());
133
+ }
134
+ int ntuples = PQntuples (res->get ());
135
+ if (ntuples != 1 ) {
136
+ throw std::runtime_error ((boost::format (" Expected one tuple from a query to check "
137
+ " COUNT(*), but got %1%. Query was: %2%." )
138
+ % ntuples % query).str ());
139
+ }
140
+
141
+ std::string numstr = PQgetvalue (res->get (), 0 , 0 );
142
+ int count = boost::lexical_cast<int >(numstr);
143
+
144
+ if (count != expected) {
145
+ throw std::runtime_error ((boost::format (" Expected %1%, but got %2%, when running "
146
+ " query: %3%." )
147
+ % expected % numstr % query).str ());
148
+ }
149
+ }
150
+
151
+ void tempdb::check_number (double expected, const std::string &query) {
152
+ pg::result_ptr res = m_conn->exec (query);
153
+
154
+ int ntuples = PQntuples (res->get ());
155
+ if (ntuples != 1 ) {
156
+ throw std::runtime_error ((boost::format (" Expected only one tuple from a query, "
157
+ " but got %1%. Query was: %2%." )
158
+ % ntuples % query).str ());
159
+ }
160
+
161
+ std::string numstr = PQgetvalue (res->get (), 0 , 0 );
162
+ double num = boost::lexical_cast<double >(numstr);
163
+
164
+ // floating point isn't exact, so allow a 0.01% difference
165
+ if ((num > 1.0001 *expected) || (num < 0.9999 *expected)) {
166
+ throw std::runtime_error ((boost::format (" Expected %1%, but got %2%, when running "
167
+ " query: %3%." )
168
+ % expected % num % query).str ());
169
+ }
170
+ }
171
+
172
+ void tempdb::check_string (const std::string &expected, const std::string &query) {
173
+ pg::result_ptr res = m_conn->exec (query);
174
+
175
+ int ntuples = PQntuples (res->get ());
176
+ if (ntuples != 1 ) {
177
+ throw std::runtime_error ((boost::format (" Expected only one tuple from a query, "
178
+ " but got %1%. Query was: %2%." )
179
+ % ntuples % query).str ());
180
+ }
181
+
182
+ std::string actual = PQgetvalue (res->get (), 0 , 0 );
183
+
184
+ if (actual != expected) {
185
+ throw std::runtime_error ((boost::format (" Expected %1%, but got %2%, when running "
186
+ " query: %3%." )
187
+ % expected % actual % query).str ());
188
+ }
189
+ }
190
+
191
+ void tempdb::assert_has_table (const std::string &table_name) {
192
+ std::string query = (boost::format (" select count(*) from pg_catalog.pg_class "
193
+ " where oid = '%1%'::regclass" )
194
+ % table_name).str ();
195
+
196
+ check_count (1 , query);
197
+ }
198
+
123
199
tempdb::~tempdb () {
124
- if (m_conn) {
125
- m_conn->exec (boost::format (" DROP DATABASE IF EXISTS \" %1%\" " ) % database_options.db );
200
+ m_conn.reset (); // close the connection to the db
201
+ if (m_postgres_conn) {
202
+ m_postgres_conn->exec (boost::format (" DROP DATABASE IF EXISTS \" %1%\" " ) % database_options.db );
126
203
}
127
204
}
128
205
129
- void tempdb::setup_extension (conn_ptr db, const std::string &extension,
206
+ void tempdb::setup_extension (const std::string &extension,
130
207
const std::vector<std::string> &extension_files) {
131
208
// first, try the new way of setting up extensions
132
- result_ptr res = db ->exec (boost::format (" CREATE EXTENSION %1%" ) % extension);
209
+ result_ptr res = m_conn ->exec (boost::format (" CREATE EXTENSION %1%" ) % extension);
133
210
if (PQresultStatus (res->get ()) != PGRES_COMMAND_OK) {
134
211
if (extension_files.size () == 0 ) {
135
212
throw std::runtime_error ((boost::format (" Unable to load extension %1% and no files specified" ) % extension).str ());
136
213
}
137
214
// if that fails, then fall back to trying to find the files on
138
215
// the filesystem to load to create the extension.
139
- res = db ->exec (" select regexp_replace(split_part(version(),' ',2),'\\ .[0-9]*$','');" );
216
+ res = m_conn ->exec (" select regexp_replace(split_part(version(),' ',2),'\\ .[0-9]*$','');" );
140
217
141
218
if ((PQresultStatus (res->get ()) != PGRES_TUPLES_OK) ||
142
219
(PQntuples (res->get ()) != 1 )) {
@@ -162,7 +239,7 @@ void tempdb::setup_extension(conn_ptr db, const std::string &extension,
162
239
" load extension \" %2%\" ." )
163
240
% sql_file % extension).str ());
164
241
}
165
- res = db ->exec (sql);
242
+ res = m_conn ->exec (sql);
166
243
if (PQresultStatus (res->get ()) != PGRES_COMMAND_OK) {
167
244
throw std::runtime_error ((boost::format (" Could not load extension \" %1%\" : %2%" )
168
245
% extension
0 commit comments