Clamp OSM import field values to their column widths

addr:housenumber / addr:postcode etc. are free-text in OSM and occasionally
exceed the entity's VARCHAR limits (e.g. housenumber "12-14, 16, 18"), which
aborted the whole --tiled run with a 1406 "Data too long" error. firstTag()
now takes a max length and each field is clamped to its real column size.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Frank
2026-08-31 00:24:03 +02:00
co-authored by Claude Sonnet 5
parent 008887ab60
commit 28f7e9809e
@@ -235,7 +235,7 @@ final class ImportEscapeRoomsFromOsmCommand extends Command
private function upsert(array $element, bool $dryRun): string private function upsert(array $element, bool $dryRun): string
{ {
$tags = $element['tags'] ?? []; $tags = $element['tags'] ?? [];
$name = trim((string) ($tags['name'] ?? '')); $name = mb_substr(trim((string) ($tags['name'] ?? '')), 0, 255);
if ($name === '') { if ($name === '') {
return 'noname'; return 'noname';
} }
@@ -263,16 +263,18 @@ final class ImportEscapeRoomsFromOsmCommand extends Command
->setOsmId($osmId); ->setOsmId($osmId);
} }
// Clamp each value to its column width - OSM address tags are free text
// and occasionally blow past these (e.g. addr:housenumber "12-14, 16, 18").
$room $room
->setName($name) ->setName($name)
->setVenue($this->firstTag($tags, ['brand', 'operator'])) ->setVenue($this->firstTag($tags, ['brand', 'operator'], 255))
->setStreet($this->firstTag($tags, ['addr:street'])) ->setStreet($this->firstTag($tags, ['addr:street'], 255))
->setHouseNumber($this->firstTag($tags, ['addr:housenumber'])) ->setHouseNumber($this->firstTag($tags, ['addr:housenumber'], 32))
->setPostcode($this->firstTag($tags, ['addr:postcode'])) ->setPostcode($this->firstTag($tags, ['addr:postcode'], 32))
->setCity($this->firstTag($tags, ['addr:city', 'addr:town', 'addr:suburb'])) ->setCity($this->firstTag($tags, ['addr:city', 'addr:town', 'addr:suburb'], 128))
->setCountry($this->normaliseCountry($this->firstTag($tags, ['addr:country']))) ->setCountry($this->normaliseCountry($this->firstTag($tags, ['addr:country'], 8)))
->setWebsite($this->firstTag($tags, ['website', 'contact:website', 'url'])) ->setWebsite($this->firstTag($tags, ['website', 'contact:website', 'url'], 511))
->setPhone($this->firstTag($tags, ['phone', 'contact:phone'])) ->setPhone($this->firstTag($tags, ['phone', 'contact:phone'], 64))
->setLatitude($lat) ->setLatitude($lat)
->setLongitude($lng); ->setLongitude($lng);
@@ -306,15 +308,17 @@ final class ImportEscapeRoomsFromOsmCommand extends Command
} }
/** /**
* First non-empty value among $keys, trimmed and clamped to $maxLen chars.
*
* @param array<string, mixed> $tags * @param array<string, mixed> $tags
* @param string[] $keys * @param string[] $keys
*/ */
private function firstTag(array $tags, array $keys): ?string private function firstTag(array $tags, array $keys, int $maxLen = 255): ?string
{ {
foreach ($keys as $key) { foreach ($keys as $key) {
$value = trim((string) ($tags[$key] ?? '')); $value = trim((string) ($tags[$key] ?? ''));
if ($value !== '') { if ($value !== '') {
return mb_substr($value, 0, 500); return mb_substr($value, 0, $maxLen);
} }
} }