@@ -1011,19 +1011,33 @@ class test_pending_processor : public middle_t::pending_processor
10111011 test_pending_processor () = default ;
10121012
10131013 void enqueue_ways (osmid_t id) override { m_way_ids.push_back (id); }
1014+ void enqueue_relations (osmid_t id) override { m_rel_ids.push_back (id); }
10141015
10151016 void process_ways () override {}
1016- void enqueue_relations (osmid_t ) override {}
10171017 void process_relations () override {}
10181018
10191019 void check_way_ids_equal_to (std::initializer_list<osmid_t > list) noexcept
10201020 {
1021- REQUIRE (m_way_ids.size () == list.size ());
1022- REQUIRE (std::equal (m_way_ids.cbegin (), m_way_ids.cend (), list.begin ()));
1021+ REQUIRE (compare (m_way_ids, list));
1022+ }
1023+
1024+ void check_rel_ids_equal_to (std::initializer_list<osmid_t > list) noexcept
1025+ {
1026+ REQUIRE (compare (m_rel_ids, list));
10231027 }
10241028
10251029private:
1030+ static bool compare (std::vector<osmid_t > const &l1,
1031+ std::initializer_list<osmid_t > const &l2) noexcept
1032+ {
1033+ if (l1.size () != l2.size ()) {
1034+ return false ;
1035+ }
1036+ return std::equal (l1.cbegin (), l1.cend (), l2.begin ());
1037+ }
1038+
10261039 std::vector<osmid_t > m_way_ids;
1040+ std::vector<osmid_t > m_rel_ids;
10271041};
10281042
10291043TEMPLATE_TEST_CASE (" middle: change nodes in way" , " " , options_slim_default,
@@ -1171,3 +1185,92 @@ TEMPLATE_TEST_CASE("middle: change nodes in way", "", options_slim_default,
11711185 }
11721186 }
11731187}
1188+
1189+ TEMPLATE_TEST_CASE (" middle: change nodes in relation" , " " , options_slim_default,
1190+ options_slim_dense_cache, options_flat_node_cache)
1191+ {
1192+ options_t options = TestType::options (db);
1193+
1194+ testing::cleanup::file_t flatnode_cleaner{
1195+ options.flat_node_file .get_value_or (" " )};
1196+
1197+ // create some nodes, ways, and relations we'll use for the tests
1198+ test_buffer_t buffer;
1199+ auto const &node10 = buffer.add_node_and_get (10 , 1.0 , 0.0 );
1200+ auto const &node11 = buffer.add_node_and_get (11 , 1.1 , 0.0 );
1201+ auto const &node12 = buffer.add_node_and_get (12 , 1.2 , 0.0 );
1202+ auto const &node10a = buffer.add_node_and_get (10 , 1.0 , 1.0 );
1203+ auto const &node11a = buffer.add_node_and_get (11 , 1.1 , 1.0 );
1204+
1205+ auto const &way20 = buffer.add_way_and_get (20 , {11 , 12 });
1206+
1207+ using otype = osmium::item_type;
1208+ auto const &rel30 = buffer.add_relation_and_get (30 , {{otype::node, 10 }});
1209+ auto const &rel31 = buffer.add_relation_and_get (31 , {{otype::way, 20 }});
1210+
1211+ // Set up middle in "create" mode to get a cleanly initialized database and
1212+ // add some nodes and ways. Does this in its own scope so that the mid is
1213+ // closed properly.
1214+ {
1215+ auto mid = std::make_shared<middle_pgsql_t >(&options);
1216+ mid->start ();
1217+
1218+ mid->node_set (node10);
1219+ mid->node_set (node11);
1220+ mid->node_set (node12);
1221+ mid->flush ();
1222+ mid->way_set (way20);
1223+ mid->flush ();
1224+ mid->relation_set (rel30);
1225+ mid->relation_set (rel31);
1226+ mid->flush ();
1227+
1228+ // Nothing pending yet
1229+ REQUIRE_FALSE (mid->has_pending ());
1230+
1231+ mid->commit ();
1232+ }
1233+
1234+ // From now on use append mode to not destroy the data we just added.
1235+ options.append = true ;
1236+
1237+ SECTION (" Single relation directly affected" )
1238+ {
1239+ auto mid = std::make_shared<middle_pgsql_t >(&options);
1240+ mid->start ();
1241+
1242+ mid->node_delete (10 );
1243+ mid->node_set (node10a);
1244+ mid->node_changed (10 );
1245+ mid->flush ();
1246+
1247+ REQUIRE (mid->has_pending ());
1248+ test_pending_processor proc;
1249+ mid->iterate_relations (proc);
1250+
1251+ proc.check_rel_ids_equal_to ({30 });
1252+ check_relation (mid, rel30);
1253+
1254+ mid->commit ();
1255+ }
1256+
1257+ SECTION (" Single relation indirectly affected (through way)" )
1258+ {
1259+ auto mid = std::make_shared<middle_pgsql_t >(&options);
1260+ mid->start ();
1261+
1262+ mid->node_delete (11 );
1263+ mid->node_set (node11a);
1264+ mid->node_changed (11 );
1265+ mid->flush ();
1266+
1267+ REQUIRE (mid->has_pending ());
1268+ test_pending_processor proc;
1269+ mid->iterate_ways (proc);
1270+ proc.check_way_ids_equal_to ({20 });
1271+
1272+ mid->iterate_relations (proc);
1273+ proc.check_rel_ids_equal_to ({31 });
1274+ check_relation (mid, rel31);
1275+ }
1276+ }
0 commit comments