use rusqlite::Connection;
const SQL_ATTACH_SOURCE: &str = "ATTACH DATABASE ?1 AS merge_src";
const SQL_DETACH_SOURCE: &str = "DETACH DATABASE merge_src";
const SQL_MERGE_ADMIN_LEVELS: &str = "
INSERT INTO admin_levels (
id,
relation_id,
way_id,
admin_level,
wkb,
name,
country_iso_code,
post_code,
merged_way_ids
)
SELECT
id,
relation_id,
way_id,
admin_level,
wkb,
name,
country_iso_code,
post_code,
{source_merged_way_ids}
FROM merge_src.admin_levels
WHERE TRUE
ON CONFLICT (id) DO UPDATE SET
name = excluded.name,
country_iso_code = excluded.country_iso_code,
post_code = excluded.post_code,
wkb = excluded.wkb,
merged_way_ids = excluded.merged_way_ids
";
const SQL_MERGE_HOUSE_NUMBERS: &str = "
INSERT OR IGNORE INTO house_numbers (
node_id,
admin_level_id,
number,
wkb,
strategy
)
SELECT
node_id,
admin_level_id,
number,
wkb,
strategy
FROM merge_src.house_numbers
";
pub fn merge_source(conn: &Connection, source_path: &str) -> (usize, usize) {
let canonical = std::fs::canonicalize(source_path)
.map(|p| p.to_string_lossy().into_owned())
.unwrap_or_else(|_| source_path.to_string());
let uri = format!("file:{canonical}?mode=ro");
conn
.execute(SQL_ATTACH_SOURCE, [&uri])
.expect("failed to attach merge source");
let tracking = if super::has_column(conn, "merge_src", "admin_levels", "merged_way_ids") {
"merged_way_ids"
} else {
"NULL"
};
let admins = conn
.execute(
&SQL_MERGE_ADMIN_LEVELS.replace("{source_merged_way_ids}", tracking),
[],
)
.expect("failed to merge admin_levels");
let houses = conn
.execute(SQL_MERGE_HOUSE_NUMBERS, [])
.expect("failed to merge house_numbers");
conn
.execute(SQL_DETACH_SOURCE, [])
.expect("failed to detach merge source");
(admins, houses)
}