Skip to content

Commit 97ec356

Browse files
mmd-osmWoazboat
andcommitted
Some cleanups from @Woazboat psql-array-iterator branch
Co-authored-by: Florian Kargl <f.kargl@posteo.de>
1 parent 2fa2d70 commit 97ec356

File tree

3 files changed

+133
-60
lines changed

3 files changed

+133
-60
lines changed

include/cgimap/output_formatter.hpp

+19-8
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,21 @@ struct changeset_comment_info {
132132
std::string created_at;
133133
std::string author_display_name;
134134

135-
bool operator==(const changeset_comment_info &) const;
135+
changeset_comment_info() = default;
136+
changeset_comment_info(const changeset_comment_info&) = default;
137+
changeset_comment_info(osm_changeset_comment_id_t id,
138+
osm_user_id_t author_id,
139+
std::string body,
140+
std::string created_at,
141+
std::string author_display_name);
142+
143+
constexpr bool operator==(const changeset_comment_info &other) const {
144+
return ((id == other.id) &&
145+
(author_id == other.author_id) &&
146+
(body == other.body) &&
147+
(created_at == other.created_at) &&
148+
(author_display_name == other.author_display_name));
149+
}
136150
};
137151

138152
struct member_info {
@@ -141,10 +155,7 @@ struct member_info {
141155
std::string role;
142156

143157
member_info() = default;
144-
member_info(element_type type_, osm_nwr_id_t ref_, const std::string &role_)
145-
: type(type_),
146-
ref(ref_),
147-
role(role_) {}
158+
member_info(element_type type_, osm_nwr_id_t ref_, std::string role_);
148159

149160
constexpr bool operator==(const member_info &other) const {
150161
return ((type == other.type) &&
@@ -153,9 +164,9 @@ struct member_info {
153164
}
154165
};
155166

156-
using nodes_t = std::list<osm_nwr_id_t>;
157-
using members_t = std::list<member_info>;
158-
using tags_t = std::list<std::pair<std::string, std::string> >;
167+
using nodes_t = std::vector<osm_nwr_id_t>;
168+
using members_t = std::vector<member_info>;
169+
using tags_t = std::vector<std::pair<std::string, std::string> >;
159170
using comments_t = std::vector<changeset_comment_info>;
160171

161172
/**

src/backend/apidb/common_pgsql_selection.cpp

+97-45
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "cgimap/backend/apidb/utils.hpp"
1313

1414
#include <chrono>
15+
#include <charconv>
1516

1617

1718
namespace {
@@ -122,10 +123,12 @@ struct comments_columns
122123

123124
// -------------------------------------------------------------------------------------
124125

125-
void extract_elem(const pqxx_tuple &row, element_info &elem,
126+
[[nodiscard]] element_info extract_elem(const pqxx_tuple &row,
126127
std::map<osm_changeset_id_t, changeset> &changeset_cache,
127128
const elem_columns& col) {
128129

130+
element_info elem;
131+
129132
elem.id = row[col.id_col].as<osm_nwr_id_t>();
130133
elem.version = row[col.version_col].as<int>();
131134
elem.timestamp = row[col.timestamp_col].c_str();
@@ -141,6 +144,7 @@ void extract_elem(const pqxx_tuple &row, element_info &elem,
141144
elem.uid = {};
142145
elem.display_name = {};
143146
}
147+
return elem;
144148
}
145149

146150
template <typename T>
@@ -152,10 +156,12 @@ std::optional<T> extract_optional(const pqxx_field &f) {
152156
}
153157
}
154158

155-
void extract_changeset(const pqxx_tuple &row,
156-
changeset_info &elem,
159+
[[nodiscard]] changeset_info extract_changeset(const pqxx_tuple &row,
157160
std::map<osm_changeset_id_t, changeset> &changeset_cache,
158161
const changeset_columns& col) {
162+
163+
changeset_info elem;
164+
159165
elem.id = row[col.id_col].as<osm_changeset_id_t>();
160166
elem.created_at = row[col.created_at_col].c_str();
161167
elem.closed_at = row[col.closed_at_col].c_str();
@@ -185,30 +191,50 @@ void extract_changeset(const pqxx_tuple &row,
185191
}
186192

187193
elem.num_changes = row[col.num_changes_col].as<size_t>();
194+
195+
return elem;
188196
}
189197

190-
void extract_tags(const pqxx_tuple &row, tags_t &tags, const tag_columns& col) {
191-
tags.clear();
198+
[[nodiscard]] tags_t extract_tags(const pqxx_tuple &row, const tag_columns& col) {
199+
200+
tags_t tags;
192201

193202
auto keys = psql_array_to_vector(row[col.tag_k_col].c_str());
194203
auto values = psql_array_to_vector(row[col.tag_v_col].c_str());
195204

196-
if (keys.size()!=values.size()) {
205+
if (keys.size() != values.size()) {
197206
throw std::runtime_error("Mismatch in tags key and value size");
198207
}
199208

209+
tags.reserve(keys.size());
210+
200211
for(std::size_t i=0; i<keys.size(); i++)
201212
tags.push_back(std::make_pair(keys[i], values[i]));
213+
214+
return tags;
202215
}
203216

204-
struct way;
205-
struct relation;
217+
[[nodiscard]] nodes_t extract_nodes(const pqxx_tuple &row, const way_extra_columns& col) {
218+
219+
nodes_t nodes;
206220

207-
void extract_nodes(const pqxx_tuple &row, nodes_t &nodes, const way_extra_columns& col) {
208-
nodes.clear();
209221
auto ids = psql_array_to_vector(row[col.node_ids_col].c_str());
210-
for (const auto & id : ids)
211-
nodes.push_back(std::stol(id));
222+
223+
nodes.reserve(ids.size());
224+
225+
for (const auto & id : ids) {
226+
osm_nwr_id_t node;
227+
228+
auto [_, ec] = std::from_chars(id.data(), id.data() + id.size(), node);
229+
230+
if (ec != std::errc()) {
231+
throw std::runtime_error("Node id conversion to integer failed");
232+
}
233+
234+
nodes.push_back(node);
235+
}
236+
237+
return nodes;
212238
}
213239

214240
element_type type_from_name(const char *name) {
@@ -239,56 +265,90 @@ element_type type_from_name(const char *name) {
239265
return type;
240266
}
241267

242-
struct relation;
268+
[[nodiscard]] members_t extract_members(const pqxx_tuple &row, const relation_extra_columns& col) {
243269

244-
void extract_members(const pqxx_tuple &row, members_t &members, const relation_extra_columns& col) {
245-
member_info member;
246-
members.clear();
270+
members_t members;
247271

248272
auto types = psql_array_to_vector(row[col.member_types_col].c_str());
249273
auto ids = psql_array_to_vector(row[col.member_ids_col].c_str());
250274
auto roles = psql_array_to_vector(row[col.member_roles_col].c_str());
251275

252-
if (types.size()!=ids.size() || ids.size()!=roles.size()) {
276+
if (types.size() != ids.size() ||
277+
ids.size() != roles.size()) {
253278
throw std::runtime_error("Mismatch in members types, ids and roles size");
254279
}
255280

281+
members.reserve(ids.size());
282+
256283
for (std::size_t i=0; i<ids.size(); i++) {
284+
member_info member;
257285
member.type = type_from_name(types[i].c_str());
258-
member.ref = std::stol(ids[i]);
286+
287+
{
288+
auto [_, ec] = std::from_chars(ids[i].data(), ids[i].data() + ids[i].size(), member.ref);
289+
290+
if (ec != std::errc()) {
291+
throw std::runtime_error("Member ref conversion to integer failed");
292+
}
293+
}
294+
259295
member.role = roles[i];
260296
members.push_back(member);
261297
}
298+
299+
return members;
262300
}
263301

264-
void extract_comments(const pqxx_tuple &row, comments_t &comments, const comments_columns& col) {
265-
changeset_comment_info comment;
266-
comments.clear();
302+
[[nodiscard]] comments_t extract_comments(const pqxx_tuple &row, const comments_columns& col) {
303+
304+
comments_t comments;
267305

268306
auto id = psql_array_to_vector(row[col.comment_id_col].c_str());
269307
auto author_id = psql_array_to_vector(row[col.comment_author_id_col].c_str());
270308
auto display_name = psql_array_to_vector(row[col.comment_display_name_col].c_str());
271309
auto body = psql_array_to_vector(row[col.comment_body_col].c_str());
272310
auto created_at = psql_array_to_vector(row[col.comment_created_at_col].c_str());
273311

274-
if (id.size()!=author_id.size() || author_id.size()!=display_name.size()
275-
|| display_name.size()!=body.size() || body.size()!=created_at.size()) {
312+
if (id.size() != author_id.size() ||
313+
author_id.size() != display_name.size() ||
314+
display_name.size() != body.size() ||
315+
body.size() != created_at.size()) {
276316
throw std::runtime_error("Mismatch in comments author_id, display_name, body and created_at size");
277317
}
278318

319+
comments.reserve(id.size());
320+
279321
for (std::size_t i=0; i<id.size(); i++) {
280-
comment.id = std::stol(id[i]);
281-
comment.author_id = std::stol(author_id[i]);
322+
323+
changeset_comment_info comment;
324+
325+
{
326+
auto [_, ec] = std::from_chars(id[i].data(), id[i].data() + id[i].size(), comment.id);
327+
328+
if (ec != std::errc()) {
329+
throw std::runtime_error("Comment id conversion to integer failed");
330+
}
331+
}
332+
333+
{
334+
auto [_, ec] = std::from_chars(author_id[i].data(), author_id[i].data() + author_id[i].size(), comment.author_id);
335+
336+
if (ec != std::errc()) {
337+
throw std::runtime_error("Author id conversion to integer failed");
338+
}
339+
}
340+
282341
comment.author_display_name = display_name[i];
283342
comment.body = body[i];
284343
comment.created_at = created_at[i];
285344
comments.push_back(comment);
286345
}
346+
347+
return comments;
287348
}
288349

289350

290351
struct node {
291-
292352
using extra_columns = node_extra_columns;
293353

294354
struct extra_info {
@@ -306,13 +366,12 @@ struct node {
306366
};
307367

308368
struct way {
309-
310369
using extra_columns = way_extra_columns;
311370

312371
struct extra_info {
313372
nodes_t nodes;
314373
inline void extract(const pqxx_tuple &row, const extra_columns& col) {
315-
extract_nodes(row, nodes, col);
374+
nodes = extract_nodes(row, col);
316375
}
317376
};
318377

@@ -324,13 +383,12 @@ struct way {
324383
};
325384

326385
struct relation {
327-
328386
using extra_columns = relation_extra_columns;
329387

330388
struct extra_info {
331389
members_t members;
332390
inline void extract(const pqxx_tuple &row, const extra_columns& col) {
333-
extract_members(row, members, col);
391+
members = extract_members(row, col);
334392
}
335393
};
336394

@@ -347,18 +405,15 @@ void extract(
347405
std::function<void(const element_info&)> notify,
348406
std::map<osm_changeset_id_t, changeset> &cc) {
349407

350-
element_info elem;
351-
typename T::extra_info extra;
352-
typename T::extra_columns extra_cols(rows);
353-
tags_t tags;
354-
408+
const typename T::extra_columns extra_cols(rows);
355409
const elem_columns elem_cols(rows);
356410
const tag_columns tag_cols(rows);
357411

358412
for (const auto &row : rows) {
359-
extract_elem(row, elem, cc, elem_cols);
413+
typename T::extra_info extra;
414+
auto elem = extract_elem(row, cc, elem_cols);
360415
extra.extract(row, extra_cols);
361-
extract_tags(row, tags, tag_cols);
416+
auto tags = extract_tags(row, tag_cols);
362417
if (notify)
363418
notify(elem); // let callback function know about a new element we're processing
364419
T::write(formatter, elem, extra, tags);
@@ -392,21 +447,18 @@ void extract_relations(
392447

393448
void extract_changesets(
394449
const pqxx::result &rows, output_formatter &formatter,
395-
std::map<osm_changeset_id_t, changeset> &cc, const std::chrono::system_clock::time_point &now,
450+
std::map<osm_changeset_id_t, changeset> &cc,
451+
const std::chrono::system_clock::time_point &now,
396452
bool include_changeset_discussions) {
397453

398-
changeset_info elem;
399-
tags_t tags;
400-
comments_t comments;
401-
402454
const changeset_columns changeset_cols(rows);
403455
const comments_columns comments_cols(rows);
404456
const tag_columns tag_cols(rows);
405457

406458
for (const auto &row : rows) {
407-
extract_changeset(row, elem, cc, changeset_cols);
408-
extract_tags(row, tags, tag_cols);
409-
extract_comments(row, comments, comments_cols);
459+
auto elem = extract_changeset(row, cc, changeset_cols);
460+
auto tags = extract_tags(row, tag_cols);
461+
auto comments = extract_comments(row, comments_cols);
410462
elem.comments_count = comments.size();
411463
formatter.write_changeset(
412464
elem, tags, include_changeset_discussions, comments, now);

src/output_formatter.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,20 @@ bool changeset_info::is_open_at(const std::chrono::system_clock::time_point &now
5353
return (closed_at_time > now) && (num_changes <= global_settings::get_changeset_max_elements()); // according to changeset.rb, is_open
5454
}
5555

56-
bool changeset_comment_info::operator==(const changeset_comment_info &other) const {
57-
return ((id == other.id) &&
58-
(author_id == other.author_id) &&
59-
(body == other.body) &&
60-
(created_at == other.created_at) &&
61-
(author_display_name == other.author_display_name));
62-
}
56+
changeset_comment_info::changeset_comment_info(osm_changeset_comment_id_t id,
57+
osm_user_id_t author_id,
58+
std::string body,
59+
std::string created_at,
60+
std::string author_display_name)
61+
: id(id),
62+
author_id(author_id),
63+
body(std::move(body)),
64+
created_at(std::move(created_at)),
65+
author_display_name(std::move(author_display_name))
66+
{}
67+
68+
member_info::member_info(element_type type_, osm_nwr_id_t ref_, std::string role_)
69+
: type(type_),
70+
ref(ref_),
71+
role(std::move(role_))
72+
{}

0 commit comments

Comments
 (0)