diff options
author | Marvin Bertin <marvin.bertin@gmail.com> | 2017-10-03 13:08:00 -0700 |
---|---|---|
committer | Marvin Bertin <marvin.bertin@gmail.com> | 2017-10-03 13:08:00 -0700 |
commit | 0653b90dddc294fddb0e81059aef00b202113d78 (patch) | |
tree | 3d8abb424b0f0495f1cbb18849184dd20d6897fc /src/main/scala/xyz/driver/pdsuicommon/synchronization/db/SlickDbDiff.scala | |
parent | 5750f2f3633e75f2f96d6a36264ab4b8f3fec7d2 (diff) | |
parent | a321a978353439fc516b0f2016c28fb32ba1b7ae (diff) | |
download | rest-query-0653b90dddc294fddb0e81059aef00b202113d78.tar.gz rest-query-0653b90dddc294fddb0e81059aef00b202113d78.tar.bz2 rest-query-0653b90dddc294fddb0e81059aef00b202113d78.zip |
Merge branch 'master' into add-slot-eligibility-arms
Diffstat (limited to 'src/main/scala/xyz/driver/pdsuicommon/synchronization/db/SlickDbDiff.scala')
-rw-r--r-- | src/main/scala/xyz/driver/pdsuicommon/synchronization/db/SlickDbDiff.scala | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/main/scala/xyz/driver/pdsuicommon/synchronization/db/SlickDbDiff.scala b/src/main/scala/xyz/driver/pdsuicommon/synchronization/db/SlickDbDiff.scala new file mode 100644 index 0000000..c226659 --- /dev/null +++ b/src/main/scala/xyz/driver/pdsuicommon/synchronization/db/SlickDbDiff.scala @@ -0,0 +1,52 @@ +package xyz.driver.pdsuicommon.synchronization.db + +import xyz.driver.pdsuicommon.synchronization.domain.FakeId +import xyz.driver.pdsuicommon.synchronization.utils.{FakeIdGen, Refiner} + +import scala.annotation.tailrec +import scala.collection.breakOut +import scala.collection.immutable.SortedSet + +object SlickDbDiff { + + /** + * Calculates DB-actions to synchronize origEntities with draftEntities. + */ + def calc[DraftT, OrigT](origEntities: Iterable[OrigT], draftEntities: Iterable[DraftT])( + implicit draftFakeIdGen: FakeIdGen[DraftT], + origFakeIdGen: FakeIdGen[OrigT], + refiner: Refiner[DraftT, OrigT]): List[SlickDbAction[OrigT]] = { + val origMap: Map[FakeId, OrigT] = origEntities.map(x => origFakeIdGen(x) -> x)(breakOut) + val uniqueDraftEntities = SortedSet.newBuilder[DraftT](Ordering.by[DraftT, FakeId](draftFakeIdGen)) + uniqueDraftEntities ++= draftEntities + + loop(origMap, uniqueDraftEntities.result(), List.empty) + } + + @tailrec private def loop[DraftT, OrigT](origEntitiesMap: Map[FakeId, OrigT], + draftEntities: Iterable[DraftT], + actions: List[SlickDbAction[OrigT]])( + implicit draftFakeIdGen: FakeIdGen[DraftT], + refiner: Refiner[DraftT, OrigT]): List[SlickDbAction[OrigT]] = { + draftEntities.headOption match { + case None => + // The rest original entities are not a part of draft, so we will delete them + val toDelete: List[SlickDbAction[OrigT]] = origEntitiesMap.values.map(x => SlickDbAction.Delete(x))(breakOut) + actions ++ toDelete + + case Some(currRaw) => + val rawCore = draftFakeIdGen.getFor(currRaw) + val action: Option[SlickDbAction[OrigT]] = origEntitiesMap.get(rawCore) match { + // It is a new entity, because it doesn't exist among originals + case None => Some(SlickDbAction.Create(refiner.refine(currRaw))) + case Some(orig) => + val draft = refiner.refresh(orig, currRaw) + if (draft == orig) None + else Some(SlickDbAction.Update(draft)) + } + + loop(origEntitiesMap - rawCore, draftEntities.tail, action.map(_ :: actions).getOrElse(actions)) + } + } + +} |