3030#include " output-pgsql.hpp"
3131#include " util.hpp"
3232
33+ /* *
34+ * Iterate over the result from a pgsql query and call the func with all
35+ * the ids from the first column.
36+ *
37+ * \param result The result to iterate over.
38+ * \param func Lambda taking an osmid_t as only parameter.
39+ */
40+ template <typename FUNC>
41+ void for_each_id (pg_result_t const &result, FUNC &&func)
42+ {
43+ for (int i = 0 ; i < result.num_tuples (); ++i) {
44+ auto const id = osmium::string_to_object_id (result.get_value (i, 0 ));
45+ std::forward<FUNC>(func)(id);
46+ }
47+ }
48+
3349static std::string build_sql (options_t const &options, char const *templ)
3450{
3551 std::string const using_tablespace{options.tblsslim_index .empty ()
@@ -300,19 +316,17 @@ void middle_pgsql_t::node_changed(osmid_t osm_id)
300316 }
301317
302318 // Find all ways referencing this node and mark them as pending.
303- auto res = m_db_connection. exec_prepared ( " mark_ways_by_node " , osm_id);
304- for ( int i = 0 ; i < res. num_tuples (); ++i) {
305- osmid_t const marked = osmium::string_to_object_id (res. get_value (i, 0 ));
306- way_changed (marked );
307- m_ways_pending_tracker->mark (marked );
308- }
319+ auto const res_ways =
320+ m_db_connection. exec_prepared ( " mark_ways_by_node " , osm_id);
321+ for_each_id (res_ways, [ this ]( osmid_t id) {
322+ way_changed (id );
323+ m_ways_pending_tracker->mark (id );
324+ });
309325
310326 // Find all relations referencing this node and mark them as pending.
311- res = m_db_connection.exec_prepared (" mark_rels_by_node" , osm_id);
312- for (int i = 0 ; i < res.num_tuples (); ++i) {
313- osmid_t const marked = osmium::string_to_object_id (res.get_value (i, 0 ));
314- m_rels_pending_tracker->mark (marked);
315- }
327+ auto const res_rels = m_db_connection.exec_prepared (" mark_rels_by_node" , osm_id);
328+ for_each_id (res_rels,
329+ [this ](osmid_t id) { m_rels_pending_tracker->mark (id); });
316330}
317331
318332void middle_pgsql_t::way_set (osmium::Way const &way)
@@ -376,9 +390,9 @@ middle_query_pgsql_t::rel_way_members_get(osmium::Relation const &rel,
376390
377391 auto const res = m_sql_conn.exec_prepared (" get_way_list" , id_list);
378392 idlist_t wayidspg;
379- for ( int i = 0 ; i < res. num_tuples (); ++i ) {
380- wayidspg.push_back (osmium::string_to_object_id (res. get_value (i, 0 )) );
381- }
393+ for_each_id ( res, [&wayidspg]( osmid_t id ) {
394+ wayidspg.push_back (id );
395+ });
382396
383397 // Match the list of ways coming from postgres in a different order
384398 // back to the list of ways given by the caller */
@@ -437,12 +451,9 @@ void middle_pgsql_t::way_changed(osmid_t osm_id)
437451 return ;
438452 }
439453
440- // keep track of whatever rels this way intersects
454+ // Keep track of all relations having this way as member.
441455 auto const res = m_db_connection.exec_prepared (" mark_rels_by_way" , osm_id);
442- for (int i = 0 ; i < res.num_tuples (); ++i) {
443- osmid_t const marked = osmium::string_to_object_id (res.get_value (i, 0 ));
444- m_rels_pending_tracker->mark (marked);
445- }
456+ for_each_id (res, [this ](osmid_t id) { m_rels_pending_tracker->mark (id); });
446457}
447458
448459void middle_pgsql_t::relation_set (osmium::Relation const &rel)
@@ -514,12 +525,10 @@ bool middle_query_pgsql_t::relation_get(osmid_t id,
514525void middle_pgsql_t::relation_delete (osmid_t osm_id)
515526{
516527 assert (m_append);
517- // keep track of whatever ways this relation interesects
528+
529+ // Keep track of all member ways.
518530 auto const res = m_db_connection.exec_prepared (" mark_ways_by_rel" , osm_id);
519- for (int i = 0 ; i < res.num_tuples (); ++i) {
520- osmid_t const marked = osmium::string_to_object_id (res.get_value (i, 0 ));
521- m_ways_pending_tracker->mark (marked);
522- }
531+ for_each_id (res, [this ](osmid_t id) { m_ways_pending_tracker->mark (id); });
523532
524533 m_db_copy.new_line (m_tables[REL_TABLE].m_copy_target );
525534 m_db_copy.delete_object (osm_id);
@@ -540,25 +549,17 @@ void middle_pgsql_t::iterate_relations(pending_processor &pf)
540549void middle_pgsql_t::relation_changed (osmid_t osm_id)
541550{
542551 assert (m_append);
543- // keep track of whatever ways and rels these nodes intersect
544- // TODO: dont need to stop the copy above since we are only reading?
545- // TODO: can we just mark the id without querying? the where clause seems intersect reltable.parts with the id
552+
546553 auto const res = m_db_connection.exec_prepared (" mark_rels" , osm_id);
547- for (int i = 0 ; i < res.num_tuples (); ++i) {
548- osmid_t const marked = osmium::string_to_object_id (res.get_value (i, 0 ));
549- m_rels_pending_tracker->mark (marked);
550- }
554+ for_each_id (res, [this ](osmid_t id) { m_rels_pending_tracker->mark (id); });
551555}
552556
553557idlist_t middle_query_pgsql_t::relations_using_way (osmid_t way_id) const
554558{
555559 auto const result = m_sql_conn.exec_prepared (" rels_using_way" , way_id);
556- int const ntuples = result.num_tuples ();
557560 idlist_t rel_ids;
558- rel_ids.resize ((size_t )ntuples);
559- for (int i = 0 ; i < ntuples; ++i) {
560- rel_ids[i] = osmium::string_to_object_id (result.get_value (i, 0 ));
561- }
561+ rel_ids.reserve ((size_t )result.num_tuples ());
562+ for_each_id (result, [&rel_ids](osmid_t id) { rel_ids.push_back (id); });
562563
563564 return rel_ids;
564565}
0 commit comments