diff --git a/database/database.go b/database/database.go index b02a8f9..75a8919 100644 --- a/database/database.go +++ b/database/database.go @@ -58,10 +58,7 @@ type Finisher interface { type Deleter interface { Inserter - // Delete deletes ID from tables that matched ProbeXxx - Delete(int64, interface{}) error - // DeleteElem deletes element from all tables - DeleteElem(element.OSMElem) error + Delete(int64, []mapping.Match) error } type Optimizer interface { diff --git a/database/postgis/postgis.go b/database/postgis/postgis.go index b87111a..f08582a 100644 --- a/database/postgis/postgis.go +++ b/database/postgis/postgis.go @@ -510,36 +510,13 @@ func (pg *PostGIS) InsertRelationMember(rel element.Relation, m element.Member, return nil } -func (pg *PostGIS) Delete(id int64, matches interface{}) error { - if matches, ok := matches.([]mapping.Match); ok { - for _, match := range matches { - pg.txRouter.Delete(match.Table.Name, id) - } - if pg.updateGeneralizedTables { - for _, generalizedTable := range pg.generalizedFromMatches(matches) { - pg.txRouter.Delete(generalizedTable.Name, id) - } - } +func (pg *PostGIS) Delete(id int64, matches []mapping.Match) error { + for _, match := range matches { + pg.txRouter.Delete(match.Table.Name, id) } - return nil -} - -func (pg *PostGIS) DeleteElem(elem element.OSMElem) error { - // handle deletes of geometries that did not match in ProbeXxx. - // we have to handle multipolygon relations that took the tags of the - // main-member. those tags are not avail. during delete. just try to - // delete from each polygon/relation table. - if _, ok := elem.Tags["type"]; ok { - for _, tableSpec := range pg.Tables { - if tableSpec.GeometryType != "polygon" && tableSpec.GeometryType != "geometry" && tableSpec.GeometryType != "relation" { - continue - } - pg.txRouter.Delete(tableSpec.Name, elem.Id) - if pg.updateGeneralizedTables { - for _, genTable := range tableSpec.Generalizations { - pg.txRouter.Delete(genTable.Name, elem.Id) - } - } + if pg.updateGeneralizedTables { + for _, generalizedTable := range pg.generalizedFromMatches(matches) { + pg.txRouter.Delete(generalizedTable.Name, id) } } return nil diff --git a/update/deleter.go b/update/deleter.go index 459108a..fb64c6e 100644 --- a/update/deleter.go +++ b/update/deleter.go @@ -16,6 +16,8 @@ type Deleter struct { tmPoints mapping.NodeMatcher tmLineStrings mapping.WayMatcher tmPolygons mapping.RelWayMatcher + tmRelation mapping.RelationMatcher + tmRelationMember mapping.RelationMatcher expireor expire.Expireor singleIdSpace bool deletedRelations map[int64]struct{} @@ -28,6 +30,8 @@ func NewDeleter(db database.Deleter, osmCache *cache.OSMCache, diffCache *cache. tmPoints mapping.NodeMatcher, tmLineStrings mapping.WayMatcher, tmPolygons mapping.RelWayMatcher, + tmRelation mapping.RelationMatcher, + tmRelationMember mapping.RelationMatcher, ) *Deleter { return &Deleter{ delDb: db, @@ -36,6 +40,8 @@ func NewDeleter(db database.Deleter, osmCache *cache.OSMCache, diffCache *cache. tmPoints: tmPoints, tmLineStrings: tmLineStrings, tmPolygons: tmPolygons, + tmRelation: tmRelation, + tmRelationMember: tmRelationMember, singleIdSpace: singleIdSpace, deletedRelations: make(map[int64]struct{}), deletedWays: make(map[int64]struct{}), @@ -82,12 +88,27 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool) if elem.Tags == nil { return nil } - // delete from all tables to handle relations with tags from members - // and relation_members - e := element.OSMElem(elem.OSMElem) - e.Id = d.RelId(e.Id) - if err := d.delDb.DeleteElem(e); err != nil { - return err + + deleted := false + deletedPolygon := false + if matches := d.tmPolygons.MatchRelation(elem); len(matches) > 0 { + if err := d.delDb.Delete(d.RelId(elem.Id), matches); err != nil { + return err + } + deleted = true + deletedPolygon = true + } + if matches := d.tmRelation.MatchRelation(elem); len(matches) > 0 { + if err := d.delDb.Delete(d.RelId(elem.Id), matches); err != nil { + return err + } + deleted = true + } + if matches := d.tmRelationMember.MatchRelation(elem); len(matches) > 0 { + if err := d.delDb.Delete(d.RelId(elem.Id), matches); err != nil { + return err + } + deleted = true } if deleteRefs { @@ -96,13 +117,19 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool) if err := d.diffCache.Ways.DeleteRef(m.Id, id); err != nil { return err } + } else if m.Type == element.NODE { + if err := d.diffCache.CoordsRel.DeleteRef(m.Id, id); err != nil { + return err + } } } } - if deleteMembers { + if deleteMembers && deletedPolygon { // delete members from db and force reinsert of members // use case: relation is deleted and member now stands for its own + + // TODO: still needed after old-style mp removal, remove when #148 is closed for _, member := range elem.Members { if member.Type == element.WAY { d.deletedMembers[member.Id] = struct{}{} @@ -124,7 +151,7 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool) if err := d.osmCache.InsertedWays.DeleteMembers(elem.Members); err != nil { return err } - if d.expireor != nil { + if deleted && d.expireor != nil { if err := d.osmCache.Ways.FillMembers(elem.Members); err != nil { return err } @@ -136,7 +163,7 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool) if err != nil { continue } - expire.ExpireProjectedNodes(d.expireor, m.Way.Nodes, 4326, true) + expire.ExpireProjectedNodes(d.expireor, m.Way.Nodes, 4326, deletedPolygon) } } return nil diff --git a/update/process.go b/update/process.go index 3b8aa3d..e59a0eb 100644 --- a/update/process.go +++ b/update/process.go @@ -148,6 +148,8 @@ func Update(oscFile string, geometryLimiter *limit.Limiter, expireor expire.Expi tagmapping.PointMatcher, tagmapping.LineStringMatcher, tagmapping.PolygonMatcher, + tagmapping.RelationMatcher, + tagmapping.RelationMemberMatcher, ) deleter.SetExpireor(expireor)