Skip to content

Commit ae35b32

Browse files
authored
Merge pull request #1889 from joto/pgsql-read-wkb-binary
Pgsql read wkb binary
2 parents 0186ae4 + 43afd24 commit ae35b32

File tree

5 files changed

+73
-30
lines changed

5 files changed

+73
-30
lines changed

src/expire-tiles.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,7 @@ int expire_from_result(expire_tiles *expire, pg_result_t const &result)
291291
auto const num_tuples = result.num_tuples();
292292

293293
for (int i = 0; i < num_tuples; ++i) {
294-
char const *const wkb = result.get_value(i, 0);
295-
expire->from_geometry(ewkb_to_geom(decode_hex(wkb)));
294+
expire->from_geometry(ewkb_to_geom(result.get(i, 0)));
296295
}
297296

298297
return num_tuples;

src/flex-table.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,10 @@ pg_result_t table_connection_t::get_geom_by_id(osmium::item_type type,
399399
assert(table().has_geom_column());
400400
assert(m_db_connection);
401401
if (table().has_multicolumn_id_index()) {
402-
return m_db_connection->exec_prepared("get_wkb", type_to_char(type),
403-
id);
402+
return m_db_connection->exec_prepared_as_binary("get_wkb",
403+
type_to_char(type), id);
404404
}
405-
return m_db_connection->exec_prepared("get_wkb", id);
405+
return m_db_connection->exec_prepared_as_binary("get_wkb", id);
406406
}
407407

408408
void table_connection_t::delete_rows_with(osmium::item_type type, osmid_t id)

src/pgsql.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,18 +132,23 @@ static std::string concat_params(int num_params,
132132
return joiner();
133133
}
134134

135-
pg_result_t
136-
pg_conn_t::exec_prepared_internal(char const *stmt, int num_params,
137-
char const *const *param_values) const
135+
pg_result_t pg_conn_t::exec_prepared_internal(char const *stmt, int num_params,
136+
char const *const *param_values,
137+
int *param_lengths,
138+
int *param_formats,
139+
int result_format) const
138140
{
139141
assert(m_conn);
140142

141143
if (get_logger().log_sql()) {
142144
log_sql("EXECUTE {}({})", stmt,
143145
concat_params(num_params, param_values));
144146
}
147+
145148
pg_result_t res{PQexecPrepared(m_conn.get(), stmt, num_params, param_values,
146-
nullptr, nullptr, 0)};
149+
param_lengths, param_formats,
150+
result_format)};
151+
147152
auto const status = res.status();
148153
if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
149154
log_error("SQL command failed: EXECUTE {}({})", stmt,

src/pgsql.hpp

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ class pg_conn_t
205205
}
206206

207207
/**
208-
* Run the named prepared SQL statement and return the results.
208+
* Run the named prepared SQL statement and return the results in text
209+
* format.
209210
*
210211
* \param stmt The name of the prepared statement.
211212
* \param params Any number of arguments (will be converted to strings
@@ -215,25 +216,24 @@ class pg_conn_t
215216
template <typename... TArgs>
216217
pg_result_t exec_prepared(char const *stmt, TArgs... params) const
217218
{
218-
// We have to convert all non-string parameters into strings and
219-
// store them somewhere. We use the exec_params vector for this.
220-
// It needs to be large enough to hold all parameters without resizing
221-
// so that pointers into the strings in that vector remain valid
222-
// after new parameters have been added.
223-
constexpr auto const total_buffers_needed =
224-
(0 + ... + detail::exec_arg<TArgs>::buffers_needed);
225-
std::vector<std::string> exec_params;
226-
exec_params.reserve(total_buffers_needed);
227-
228-
// This array holds the pointers to all parameter strings, either
229-
// to the original string parameters or to the recently converted
230-
// in the exec_params vector.
231-
std::array<char const *, sizeof...(params)> param_ptrs = {
232-
detail::exec_arg<TArgs>::to_str(&exec_params,
233-
std::forward<TArgs>(params))...};
219+
return exec_prepared_with_result_format(stmt, false,
220+
std::forward<TArgs>(params)...);
221+
}
234222

235-
return exec_prepared_internal(stmt, sizeof...(params),
236-
param_ptrs.data());
223+
/**
224+
* Run the named prepared SQL statement and return the results in binary
225+
* format.
226+
*
227+
* \param stmt The name of the prepared statement.
228+
* \param params Any number of arguments (will be converted to strings
229+
* if necessary).
230+
* \throws exception if the command failed.
231+
*/
232+
template <typename... TArgs>
233+
pg_result_t exec_prepared_as_binary(char const *stmt, TArgs... params) const
234+
{
235+
return exec_prepared_with_result_format(stmt, true,
236+
std::forward<TArgs>(params)...);
237237
}
238238

239239
/**
@@ -254,7 +254,46 @@ class pg_conn_t
254254

255255
private:
256256
pg_result_t exec_prepared_internal(char const *stmt, int num_params,
257-
char const *const *param_values) const;
257+
char const *const *param_values,
258+
int *param_lengths, int *param_formats,
259+
int result_format) const;
260+
261+
/**
262+
* Run the named prepared SQL statement and return the results.
263+
*
264+
* \param stmt The name of the prepared statement.
265+
* \param result_as_binary Ask for the resuls to be returned in binary
266+
* format.
267+
* \param params Any number of arguments (will be converted to strings
268+
* if necessary).
269+
* \throws exception if the command failed.
270+
*/
271+
template <typename... TArgs>
272+
pg_result_t exec_prepared_with_result_format(char const *stmt,
273+
bool result_as_binary,
274+
TArgs... params) const
275+
{
276+
// We have to convert all non-string parameters into strings and
277+
// store them somewhere. We use the exec_params vector for this.
278+
// It needs to be large enough to hold all parameters without resizing
279+
// so that pointers into the strings in that vector remain valid
280+
// after new parameters have been added.
281+
constexpr auto const total_buffers_needed =
282+
(0 + ... + detail::exec_arg<TArgs>::buffers_needed);
283+
std::vector<std::string> exec_params;
284+
exec_params.reserve(total_buffers_needed);
285+
286+
// This array holds the pointers to all parameter strings, either
287+
// to the original string parameters or to the recently converted
288+
// in the exec_params vector.
289+
std::array<char const *, sizeof...(params)> param_ptrs = {
290+
detail::exec_arg<TArgs>::to_str(&exec_params,
291+
std::forward<TArgs>(params))...};
292+
293+
return exec_prepared_internal(stmt, sizeof...(params),
294+
param_ptrs.data(), nullptr, nullptr,
295+
result_as_binary ? 1 : 0);
296+
}
258297

259298
struct pg_conn_deleter_t
260299
{

src/table.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,6 @@ void table_t::escape_type(std::string const &value, ColumnType flags)
451451

452452
pg_result_t table_t::get_wkb(osmid_t id)
453453
{
454-
return m_sql_conn->exec_prepared("get_wkb", id);
454+
return m_sql_conn->exec_prepared_as_binary("get_wkb", id);
455455
}
456456

0 commit comments

Comments
 (0)