Browse Source

fix: skip removing already existing content in secondary to pick up where the transition left of

Karol Sójko 1 year ago
parent
commit
857c6af946

+ 44 - 21
packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.ts

@@ -31,19 +31,16 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
 
 
     let newRevisionsInSecondaryCount = 0
     let newRevisionsInSecondaryCount = 0
     let updatedRevisionsInSecondary: string[] = []
     let updatedRevisionsInSecondary: string[] = []
+    let alreadyIdenticalInSecondaryAndPrimary: string[] = []
     if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
     if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
-      const { alreadyExistingInPrimary, newRevisionsInSecondary, updatedInSecondary } =
+      const { alreadyExistingInSecondaryAndPrimary, newRevisionsInSecondary, updatedInSecondary } =
         await this.getNewRevisionsCreatedInSecondaryDatabase(userUuid)
         await this.getNewRevisionsCreatedInSecondaryDatabase(userUuid)
 
 
       this.logger.info(
       this.logger.info(
-        `[${dto.userUuid}] Removing ${alreadyExistingInPrimary.length} already existing revisions from secondary database`,
+        `[${dto.userUuid}] ${alreadyExistingInSecondaryAndPrimary.length} already existing identical revisions in primary and secondary.`,
       )
       )
-      for (const existingRevisionUuid of alreadyExistingInPrimary) {
-        await (this.secondRevisionsRepository as RevisionRepositoryInterface).removeOneByUuid(
-          Uuid.create(existingRevisionUuid).getValue(),
-          userUuid,
-        )
-      }
+
+      alreadyIdenticalInSecondaryAndPrimary = alreadyExistingInSecondaryAndPrimary
 
 
       if (newRevisionsInSecondary.length > 0) {
       if (newRevisionsInSecondary.length > 0) {
         this.logger.info(
         this.logger.info(
@@ -68,7 +65,11 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
 
 
     this.logger.info(`[${dto.userUuid}] Migrating revisions`)
     this.logger.info(`[${dto.userUuid}] Migrating revisions`)
 
 
-    const migrationResult = await this.migrateRevisionsForUser(userUuid, updatedRevisionsInSecondary)
+    const migrationResult = await this.migrateRevisionsForUser(
+      userUuid,
+      updatedRevisionsInSecondary,
+      alreadyIdenticalInSecondaryAndPrimary,
+    )
     if (migrationResult.isFailed()) {
     if (migrationResult.isFailed()) {
       if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
       if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
         const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.secondRevisionsRepository)
         const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.secondRevisionsRepository)
@@ -88,6 +89,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
       userUuid,
       userUuid,
       newRevisionsInSecondaryCount,
       newRevisionsInSecondaryCount,
       updatedRevisionsInSecondary,
       updatedRevisionsInSecondary,
+      alreadyIdenticalInSecondaryAndPrimary,
     )
     )
     if (integrityCheckResult.isFailed()) {
     if (integrityCheckResult.isFailed()) {
       if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
       if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
@@ -119,7 +121,11 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
     return Result.ok()
     return Result.ok()
   }
   }
 
 
-  private async migrateRevisionsForUser(userUuid: Uuid, updatedRevisionsInSecondary: string[]): Promise<Result<void>> {
+  private async migrateRevisionsForUser(
+    userUuid: Uuid,
+    updatedRevisionsInSecondary: string[],
+    alreadyExistingInSecondaryAndPrimary: string[],
+  ): Promise<Result<void>> {
     try {
     try {
       const totalRevisionsCountForUser = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
       const totalRevisionsCountForUser = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
       const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
       const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
@@ -146,6 +152,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
               continue
               continue
             }
             }
 
 
+            if (
+              alreadyExistingInSecondaryAndPrimary.find(
+                (alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
+              )
+            ) {
+              continue
+            }
+
             const didSave = await (this.secondRevisionsRepository as RevisionRepositoryInterface).insert(revision)
             const didSave = await (this.secondRevisionsRepository as RevisionRepositoryInterface).insert(revision)
             if (!didSave) {
             if (!didSave) {
               return Result.fail(`Failed to save revision ${revision.id.toString()} to secondary database`)
               return Result.fail(`Failed to save revision ${revision.id.toString()} to secondary database`)
@@ -200,7 +214,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
   }
   }
 
 
   private async getNewRevisionsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
   private async getNewRevisionsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
-    alreadyExistingInPrimary: string[]
+    alreadyExistingInSecondaryAndPrimary: string[]
     newRevisionsInSecondary: string[]
     newRevisionsInSecondary: string[]
     updatedInSecondary: string[]
     updatedInSecondary: string[]
   }> {
   }> {
@@ -211,7 +225,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
     ).countByUserUuid(userUuid)
     ).countByUserUuid(userUuid)
     const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
     const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
 
 
-    const alreadyExistingInPrimary: string[] = []
+    const alreadyExistingInSecondaryAndPrimary: string[] = []
     const newRevisionsInSecondary: string[] = []
     const newRevisionsInSecondary: string[] = []
     const updatedInSecondary: string[] = []
     const updatedInSecondary: string[] = []
 
 
@@ -224,17 +238,17 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
 
 
       const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query)
       const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query)
       for (const revision of revisions) {
       for (const revision of revisions) {
-        const { revisionInPrimary, newerRevisionInSecondary } =
+        const { identicalRevisionInPrimary, newerRevisionInSecondary } =
           await this.checkIfRevisionExistsInPrimaryDatabase(revision)
           await this.checkIfRevisionExistsInPrimaryDatabase(revision)
-        if (revisionInPrimary !== null) {
-          alreadyExistingInPrimary.push(revision.id.toString())
+        if (identicalRevisionInPrimary !== null) {
+          alreadyExistingInSecondaryAndPrimary.push(revision.id.toString())
           continue
           continue
         }
         }
         if (newerRevisionInSecondary !== null) {
         if (newerRevisionInSecondary !== null) {
           updatedInSecondary.push(newerRevisionInSecondary.id.toString())
           updatedInSecondary.push(newerRevisionInSecondary.id.toString())
           continue
           continue
         }
         }
-        if (revisionInPrimary === null && newerRevisionInSecondary === null) {
+        if (identicalRevisionInPrimary === null && newerRevisionInSecondary === null) {
           newRevisionsInSecondary.push(revision.id.toString())
           newRevisionsInSecondary.push(revision.id.toString())
           continue
           continue
         }
         }
@@ -242,7 +256,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
     }
     }
 
 
     return {
     return {
-      alreadyExistingInPrimary,
+      alreadyExistingInSecondaryAndPrimary,
       newRevisionsInSecondary,
       newRevisionsInSecondary,
       updatedInSecondary,
       updatedInSecondary,
     }
     }
@@ -250,7 +264,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
 
 
   private async checkIfRevisionExistsInPrimaryDatabase(
   private async checkIfRevisionExistsInPrimaryDatabase(
     revision: Revision,
     revision: Revision,
-  ): Promise<{ revisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
+  ): Promise<{ identicalRevisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
     const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(
     const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(
       Uuid.create(revision.id.toString()).getValue(),
       Uuid.create(revision.id.toString()).getValue(),
       revision.props.userUuid as Uuid,
       revision.props.userUuid as Uuid,
@@ -259,7 +273,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
 
 
     if (revisionInPrimary === null) {
     if (revisionInPrimary === null) {
       return {
       return {
-        revisionInPrimary: null,
+        identicalRevisionInPrimary: null,
         newerRevisionInSecondary: null,
         newerRevisionInSecondary: null,
       }
       }
     }
     }
@@ -273,14 +287,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
       )
       )
 
 
       return {
       return {
-        revisionInPrimary: null,
+        identicalRevisionInPrimary: null,
         newerRevisionInSecondary:
         newerRevisionInSecondary:
           revision.props.dates.updatedAt > revisionInPrimary.props.dates.updatedAt ? revision : null,
           revision.props.dates.updatedAt > revisionInPrimary.props.dates.updatedAt ? revision : null,
       }
       }
     }
     }
 
 
     return {
     return {
-      revisionInPrimary: revisionInPrimary,
+      identicalRevisionInPrimary: revisionInPrimary,
       newerRevisionInSecondary: null,
       newerRevisionInSecondary: null,
     }
     }
   }
   }
@@ -289,6 +303,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
     userUuid: Uuid,
     userUuid: Uuid,
     newRevisionsInSecondaryCount: number,
     newRevisionsInSecondaryCount: number,
     updatedRevisionsInSecondary: string[],
     updatedRevisionsInSecondary: string[],
+    alreadyExistingInSecondaryAndPrimary: string[],
   ): Promise<Result<boolean>> {
   ): Promise<Result<boolean>> {
     try {
     try {
       const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
       const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
@@ -329,6 +344,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
             continue
             continue
           }
           }
 
 
+          if (
+            alreadyExistingInSecondaryAndPrimary.find(
+              (alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
+            )
+          ) {
+            continue
+          }
+
           if (!revision.isIdenticalTo(revisionInSecondary)) {
           if (!revision.isIdenticalTo(revisionInSecondary)) {
             return Result.fail(
             return Result.fail(
               `Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in primary database: ${JSON.stringify(
               `Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in primary database: ${JSON.stringify(

+ 35 - 20
packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.ts

@@ -32,19 +32,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
 
 
     let newItemsInSecondaryCount = 0
     let newItemsInSecondaryCount = 0
     let updatedItemsInSecondary: string[] = []
     let updatedItemsInSecondary: string[] = []
+    let alreadyIdenticalInSecondaryAndPrimary: string[] = []
     if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
     if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
-      const { alreadyExistingInPrimary, newItemsInSecondary, updatedInSecondary } =
+      const { alreadyExistingInSecondaryAndPrimary, newItemsInSecondary, updatedInSecondary } =
         await this.getNewItemsCreatedInSecondaryDatabase(userUuid)
         await this.getNewItemsCreatedInSecondaryDatabase(userUuid)
 
 
       this.logger.info(
       this.logger.info(
-        `[${dto.userUuid}] Removing ${alreadyExistingInPrimary.length} already existing items from secondary database.`,
+        `[${dto.userUuid}] ${alreadyExistingInSecondaryAndPrimary.length} already existing identical items in primary and secondary.`,
       )
       )
 
 
-      for (const existingItemUuid of alreadyExistingInPrimary) {
-        await (this.secondaryItemRepository as ItemRepositoryInterface).removeByUuid(
-          Uuid.create(existingItemUuid).getValue(),
-        )
-      }
+      alreadyIdenticalInSecondaryAndPrimary = alreadyExistingInSecondaryAndPrimary
 
 
       if (newItemsInSecondary.length > 0) {
       if (newItemsInSecondary.length > 0) {
         this.logger.info(`[${dto.userUuid}] Found ${newItemsInSecondary.length} new items in secondary database.`)
         this.logger.info(`[${dto.userUuid}] Found ${newItemsInSecondary.length} new items in secondary database.`)
@@ -66,7 +63,11 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
 
 
     this.logger.info(`[${dto.userUuid}] Migrating items`)
     this.logger.info(`[${dto.userUuid}] Migrating items`)
 
 
-    const migrationResult = await this.migrateItemsForUser(userUuid, updatedItemsInSecondary)
+    const migrationResult = await this.migrateItemsForUser(
+      userUuid,
+      updatedItemsInSecondary,
+      alreadyIdenticalInSecondaryAndPrimary,
+    )
     if (migrationResult.isFailed()) {
     if (migrationResult.isFailed()) {
       if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
       if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
         const cleanupResult = await this.deleteItemsForUser(userUuid, this.secondaryItemRepository)
         const cleanupResult = await this.deleteItemsForUser(userUuid, this.secondaryItemRepository)
@@ -86,6 +87,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
       userUuid,
       userUuid,
       newItemsInSecondaryCount,
       newItemsInSecondaryCount,
       updatedItemsInSecondary,
       updatedItemsInSecondary,
+      alreadyIdenticalInSecondaryAndPrimary,
     )
     )
     if (integrityCheckResult.isFailed()) {
     if (integrityCheckResult.isFailed()) {
       if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
       if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
@@ -136,13 +138,13 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
   }
   }
 
 
   private async getNewItemsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
   private async getNewItemsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
-    alreadyExistingInPrimary: string[]
+    alreadyExistingInSecondaryAndPrimary: string[]
     newItemsInSecondary: string[]
     newItemsInSecondary: string[]
     updatedInSecondary: string[]
     updatedInSecondary: string[]
   }> {
   }> {
     this.logger.info(`[${userUuid.value}] Checking for new items in secondary database`)
     this.logger.info(`[${userUuid.value}] Checking for new items in secondary database`)
 
 
-    const alreadyExistingInPrimary: string[] = []
+    const alreadyExistingInSecondaryAndPrimary: string[] = []
     const updatedInSecondary: string[] = []
     const updatedInSecondary: string[] = []
     const newItemsInSecondary: string[] = []
     const newItemsInSecondary: string[] = []
 
 
@@ -161,16 +163,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
 
 
       const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll(query)
       const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll(query)
       for (const item of items) {
       for (const item of items) {
-        const { itemInPrimary, newerItemInSecondary } = await this.checkIfItemExistsInPrimaryDatabase(item)
-        if (itemInPrimary !== null) {
-          alreadyExistingInPrimary.push(item.id.toString())
+        const { identicalItemInPrimary, newerItemInSecondary } = await this.checkIfItemExistsInPrimaryDatabase(item)
+        if (identicalItemInPrimary !== null) {
+          alreadyExistingInSecondaryAndPrimary.push(item.id.toString())
           continue
           continue
         }
         }
         if (newerItemInSecondary !== null) {
         if (newerItemInSecondary !== null) {
           updatedInSecondary.push(newerItemInSecondary.id.toString())
           updatedInSecondary.push(newerItemInSecondary.id.toString())
           continue
           continue
         }
         }
-        if (itemInPrimary === null && newerItemInSecondary === null) {
+        if (identicalItemInPrimary === null && newerItemInSecondary === null) {
           newItemsInSecondary.push(item.id.toString())
           newItemsInSecondary.push(item.id.toString())
           continue
           continue
         }
         }
@@ -178,7 +180,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
     }
     }
 
 
     return {
     return {
-      alreadyExistingInPrimary,
+      alreadyExistingInSecondaryAndPrimary,
       newItemsInSecondary,
       newItemsInSecondary,
       updatedInSecondary,
       updatedInSecondary,
     }
     }
@@ -186,11 +188,11 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
 
 
   private async checkIfItemExistsInPrimaryDatabase(
   private async checkIfItemExistsInPrimaryDatabase(
     item: Item,
     item: Item,
-  ): Promise<{ itemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
+  ): Promise<{ identicalItemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
     const itemInPrimary = await this.primaryItemRepository.findByUuid(item.uuid)
     const itemInPrimary = await this.primaryItemRepository.findByUuid(item.uuid)
 
 
     if (itemInPrimary === null) {
     if (itemInPrimary === null) {
-      return { itemInPrimary: null, newerItemInSecondary: null }
+      return { identicalItemInPrimary: null, newerItemInSecondary: null }
     }
     }
 
 
     if (!item.isIdenticalTo(itemInPrimary)) {
     if (!item.isIdenticalTo(itemInPrimary)) {
@@ -203,15 +205,19 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
       )
       )
 
 
       return {
       return {
-        itemInPrimary: null,
+        identicalItemInPrimary: null,
         newerItemInSecondary: item.props.timestamps.updatedAt > itemInPrimary.props.timestamps.updatedAt ? item : null,
         newerItemInSecondary: item.props.timestamps.updatedAt > itemInPrimary.props.timestamps.updatedAt ? item : null,
       }
       }
     }
     }
 
 
-    return { itemInPrimary: itemInPrimary, newerItemInSecondary: null }
+    return { identicalItemInPrimary: itemInPrimary, newerItemInSecondary: null }
   }
   }
 
 
-  private async migrateItemsForUser(userUuid: Uuid, updatedItemsInSecondary: string[]): Promise<Result<void>> {
+  private async migrateItemsForUser(
+    userUuid: Uuid,
+    updatedItemsInSecondary: string[],
+    alreadyExistingInSecondaryAndPrimary: string[],
+  ): Promise<Result<void>> {
     try {
     try {
       const totalItemsCountForUser = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
       const totalItemsCountForUser = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
       const totalPages = Math.ceil(totalItemsCountForUser / this.pageSize)
       const totalPages = Math.ceil(totalItemsCountForUser / this.pageSize)
@@ -234,6 +240,10 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
 
 
             continue
             continue
           }
           }
+          if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
+            continue
+          }
+
           await (this.secondaryItemRepository as ItemRepositoryInterface).save(item)
           await (this.secondaryItemRepository as ItemRepositoryInterface).save(item)
         }
         }
       }
       }
@@ -258,6 +268,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
     userUuid: Uuid,
     userUuid: Uuid,
     newItemsInSecondaryCount: number,
     newItemsInSecondaryCount: number,
     updatedItemsInSecondary: string[],
     updatedItemsInSecondary: string[],
+    alreadyExistingInSecondaryAndPrimary: string[],
   ): Promise<Result<boolean>> {
   ): Promise<Result<boolean>> {
     try {
     try {
       const totalItemsCountForUserInPrimary = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
       const totalItemsCountForUserInPrimary = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
@@ -298,6 +309,10 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
             continue
             continue
           }
           }
 
 
+          if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
+            continue
+          }
+
           if (!item.isIdenticalTo(itemInSecondary)) {
           if (!item.isIdenticalTo(itemInSecondary)) {
             return Result.fail(
             return Result.fail(
               `Item ${
               `Item ${