Skip to content

Commit

Permalink
fix(map): remove linked connections when deleting signatures. this is…
Browse files Browse the repository at this point in the history
… a partial fix, more to come later
  • Loading branch information
updraft0 committed Jun 13, 2024
1 parent 56aff95 commit 4b5d17a
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 23 deletions.
81 changes: 67 additions & 14 deletions db/src/main/scala/org/updraft0/controltower/db/query/map.scala
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,36 @@ object map:
.run(quote { mapSystem.filter(ms => ms.mapId == lift(mapId) && ms.systemId == lift(systemId)) })
.map(_.headOption)

private inline def findWormholeMapSignatures(mapId: MapId, systemId: SystemId) =
quote(
mapSystemSignature
.filter(_.mapId == lift(mapId))
.filter(_.systemId == lift(systemId))
.filter(_.isDeleted == lift(false))
.filter(_.wormholeConnectionId.nonEmpty)
)

private inline def joinConnectionIds(inline mssq: Quoted[Query[MapSystemSignature]]) =
mssq
.join(mapWormholeConnection)
.on((mss, mwc) => mss.wormholeConnectionId.contains(mwc.id) && mwc.isDeleted == lift(false))
.map((_, mwc) => mwc.id)

def getSystemConnectionIdsInSignatures(
mapId: MapId,
systemId: SystemId,
sigIds: Option[Chunk[SigId]]
): DbOperation[List[ConnectionId]] =
sigIds match
case Some(sigIds) =>
ctx.run(
joinConnectionIds(
findWormholeMapSignatures(mapId, systemId).filter(mss => liftQuery(sigIds).contains(mss.signatureId))
)
)
case None =>
ctx.run(joinConnectionIds(findWormholeMapSignatures(mapId, systemId)))

// inserts
def insertMapWormholeConnection(value: MapWormholeConnection): DbOperation[MapWormholeConnection] =
ctx
Expand Down Expand Up @@ -304,32 +334,55 @@ object map:
)
.map(_.sum)

def deleteMapSystemSignatures(
def deleteSignaturesWithConnectionIds(ids: Chunk[ConnectionId], byCharacterId: CharacterId): DbOperation[Long] =
ctx
.run(
quote(
liftQuery(ids).foreach(id =>
mapSystemSignature
.filter(_.wormholeConnectionId.exists(_ == id))
.update(
_.isDeleted -> lift(true),
_.updatedByCharacterId -> lift(byCharacterId),
_.updatedAt -> unixepoch
)
)
)
)
.map(_.sum)

def deleteMapSystemSignaturesAll(
mapId: MapId,
systemId: SystemId,
now: Instant,
byCharacterId: CharacterId
): DbOperation[Long] =
ctx.run(
mapSystemSignature
.filter(_.mapId == lift(mapId))
.filter(_.systemId == lift(systemId))
.update(_.isDeleted -> lift(true), _.updatedByCharacterId -> lift(byCharacterId), _.updatedAt -> lift(now))
quote(
mapSystemSignature
.filter(_.mapId == lift(mapId))
.filter(_.systemId == lift(systemId))
.update(_.isDeleted -> lift(true), _.updatedByCharacterId -> lift(byCharacterId), _.updatedAt -> lift(now))
)
)

def deleteMapSystemSignature(
def deleteMapSystemSignatures(
mapId: MapId,
systemId: SystemId,
signatureId: SigId,
signatureIds: Chunk[SigId],
byCharacterId: CharacterId
): DbOperation[Long] =
ctx.run(
mapSystemSignature
.filter(_.mapId == lift(mapId))
.filter(_.systemId == lift(systemId))
.filter(_.signatureId == lift(signatureId))
.update(_.isDeleted -> lift(true), _.updatedByCharacterId -> lift(byCharacterId), _.updatedAt -> unixepoch)
)
ctx
.run(
liftQuery(signatureIds).foreach(sigId =>
mapSystemSignature
.filter(_.mapId == lift(mapId))
.filter(_.systemId == lift(systemId))
.filter(_.signatureId == sigId)
.update(_.isDeleted -> lift(true), _.updatedByCharacterId -> lift(byCharacterId), _.updatedAt -> unixepoch)
)
)
.map(_.sum)

def deleteMapSystemNote(id: Long, byCharacterId: CharacterId): DbOperation[Long] =
ctx.run(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,20 +576,20 @@ object MapEntity extends ReactiveEntity[MapEnv, MapId, MapState, Identified[MapR
) =
// TODO: signature updates cannot currently change connection ids so only a single system needs to be reloaded
for
_ <-
if (uss.replaceAll) query.map.deleteMapSystemSignatures(mapId, uss.systemId, now, sessionId.characterId)
else ZIO.succeed(0)
_ <- query.map.deleteMapSystemSignaturesAll(mapId, uss.systemId, now, sessionId.characterId).when(uss.replaceAll)
mapSystemId = (mapId, uss.systemId)
mapSystem = state.getSystem(uss.systemId).get
_ <- ZIO.foreachDiscard(
uss.scanned
.map(lookupExisting(mapSystem, _))
.map((prevOpt, newSig) => toModelSignature(now, sessionId, mapSystemId, prevOpt, newSig))
)(query.map.upsertMapSystemSignature)
// reload the whole system
sys <- loadSingleSystem(mapId, uss.systemId)
conns <- MapQueries.getWormholeConnectionsWithSigsBySystemId(mapId, uss.systemId)
yield withState(state.updateOne(sys.sys.systemId, sys, conns, Nil))(nextState =>
nextState -> broadcast(nextState.systemSnapshot(sys.sys.systemId))
ranks <- MapQueries.getWormholeConnectionRanksForSystem(mapId, uss.systemId)
yield withState(state.updateOne(sys.sys.systemId, sys, conns, ranks))(s =>
s -> broadcast(s.systemSnapshot(sys.sys.systemId))
)

private def removeSystemAndConnection(
Expand All @@ -605,6 +605,8 @@ object MapEntity extends ReactiveEntity[MapEnv, MapId, MapState, Identified[MapR
for
// mark connections as removed
_ <- query.map.deleteMapWormholeConnections(connectionIds, sessionId.characterId)
// remove signatures that have those connections
_ <- query.map.deleteSignaturesWithConnectionIds(connectionIds, sessionId.characterId)
// remove the display of the system
_ <- query.map.deleteMapSystemDisplay(mapId, rs.systemId)
// recompute all the connection ranks
Expand Down Expand Up @@ -651,14 +653,19 @@ object MapEntity extends ReactiveEntity[MapEnv, MapId, MapState, Identified[MapR
now: Instant,
rss: MapRequest.RemoveSystemSignatures
) =
// TODO need to recompute state for all the connection ids :) <-- aka if the connection is being deleted,
// remove the whole connection on both sides!
for
connectionIds <- query.map.getSystemConnectionIdsInSignatures(mapId, rss.systemId, rss.signatures.map(_.toChunk))
_ <- query.map.deleteMapWormholeConnections(Chunk.fromIterable(connectionIds), sessionId.characterId)
_ <- rss.signatures match
case None => query.map.deleteMapSystemSignatures(mapId, rss.systemId, now, sessionId.characterId)
case Some(ids) =>
ZIO.foreach(ids)(id => query.map.deleteMapSystemSignature(mapId, rss.systemId, id, sessionId.characterId))
case None => query.map.deleteMapSystemSignaturesAll(mapId, rss.systemId, now, sessionId.characterId)
case Some(ids) => query.map.deleteMapSystemSignatures(mapId, rss.systemId, ids, sessionId.characterId)
// reload the whole system
sys <- loadSingleSystem(mapId, rss.systemId)
conns <- MapQueries.getWormholeConnectionsWithSigsBySystemId(mapId, rss.systemId)
yield withState(state.updateOne(sys.sys.systemId, sys, conns, Nil))(s =>
ranks <- MapQueries.getWormholeConnectionRanksForSystem(mapId, rss.systemId)
yield withState(state.updateOne(sys.sys.systemId, sys, conns, ranks))(s =>
s -> broadcast(s.systemSnapshot(sys.sys.systemId))
)

Expand Down

0 comments on commit 4b5d17a

Please sign in to comment.