diff --git a/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.spec.ts b/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.spec.ts index 3f4244e0a..fe09112c7 100644 --- a/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.spec.ts +++ b/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.spec.ts @@ -131,7 +131,7 @@ describe('TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser', () => { expect(result.isFailed()).toBeFalsy() - expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledTimes(2) + expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledTimes(3) expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledWith( Uuid.create('00000000-0000-0000-0000-000000000000').getValue(), ) @@ -344,7 +344,7 @@ describe('TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser', () => { 'Total revisions count for user 00000000-0000-0000-0000-000000000000 in primary database (2) does not match total revisions count in secondary database (1)', ) - expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledTimes(2) + expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledTimes(3) expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledWith( Uuid.create('00000000-0000-0000-0000-000000000000').getValue(), ) @@ -368,7 +368,7 @@ describe('TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser', () => { expect(result.isFailed()).toBeTruthy() expect(result.getError()).toEqual('Revision 00000000-0000-0000-0000-000000000001 not found in secondary database') - expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledTimes(2) + expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledTimes(3) expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledWith( Uuid.create('00000000-0000-0000-0000-000000000000').getValue(), ) @@ -413,4 +413,25 @@ describe('TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser', () => { expect((secondaryRevisionRepository as RevisionRepositoryInterface).removeByUserUuid).toHaveBeenCalledTimes(1) }) }) + + it('should not migrate revisions if there are no revisions in the primary database', async () => { + primaryRevisionRepository.countByUserUuid = jest.fn().mockResolvedValue(0) + + const useCase = createUseCase() + + const result = await useCase.execute({ + userUuid: '00000000-0000-0000-0000-000000000000', + }) + + expect(result.isFailed()).toBeFalsy() + + expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledTimes(1) + expect(primaryRevisionRepository.countByUserUuid).toHaveBeenCalledWith( + Uuid.create('00000000-0000-0000-0000-000000000000').getValue(), + ) + expect(primaryRevisionRepository.findByUserUuid).not.toHaveBeenCalled() + expect((secondaryRevisionRepository as RevisionRepositoryInterface).insert).not.toHaveBeenCalled() + expect(primaryRevisionRepository.removeByUserUuid).not.toHaveBeenCalled() + expect((secondaryRevisionRepository as RevisionRepositoryInterface).removeByUserUuid).not.toHaveBeenCalled() + }) }) diff --git a/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.ts b/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.ts index ce29d802e..5f78c7c79 100644 --- a/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.ts +++ b/packages/revisions/src/Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser.ts @@ -24,6 +24,12 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements } const userUuid = userUuidOrError.getValue() + if (await this.isAlreadyMigrated(userUuid)) { + this.logger.info(`Revisions for user ${userUuid.value} are already migrated`) + + return Result.ok() + } + const migrationTimeStart = this.timer.getTimestampInMicroseconds() this.logger.debug(`Transitioning revisions for user ${userUuid.value}`) @@ -137,6 +143,12 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements await this.timer.sleep(twoSecondsInMilliseconds) } + private async isAlreadyMigrated(userUuid: Uuid): Promise { + const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid) + + return totalRevisionsCountForUserInPrimary === 0 + } + private async checkIntegrityBetweenPrimaryAndSecondaryDatabase(userUuid: Uuid): Promise> { try { const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid) diff --git a/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.spec.ts b/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.spec.ts index 16c576550..d79813005 100644 --- a/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.spec.ts @@ -138,7 +138,7 @@ describe('TransitionItemsFromPrimaryToSecondaryDatabaseForUser', () => { expect(result.isFailed()).toBeFalsy() - expect(primaryItemRepository.countAll).toHaveBeenCalledTimes(2) + expect(primaryItemRepository.countAll).toHaveBeenCalledTimes(3) expect(primaryItemRepository.countAll).toHaveBeenCalledWith({ userUuid: '00000000-0000-0000-0000-000000000000' }) expect(primaryItemRepository.findAll).toHaveBeenCalledTimes(4) expect(primaryItemRepository.findAll).toHaveBeenNthCalledWith(1, { @@ -329,7 +329,7 @@ describe('TransitionItemsFromPrimaryToSecondaryDatabaseForUser', () => { 'Total items count for user 00000000-0000-0000-0000-000000000000 in primary database (2) does not match total items count in secondary database (1)', ) - expect(primaryItemRepository.countAll).toHaveBeenCalledTimes(2) + expect(primaryItemRepository.countAll).toHaveBeenCalledTimes(3) expect(primaryItemRepository.countAll).toHaveBeenCalledWith({ userUuid: '00000000-0000-0000-0000-000000000000' }) expect((secondaryItemRepository as ItemRepositoryInterface).countAll).toHaveBeenCalledTimes(1) expect(primaryItemRepository.deleteByUserUuid).not.toHaveBeenCalled() @@ -351,7 +351,7 @@ describe('TransitionItemsFromPrimaryToSecondaryDatabaseForUser', () => { expect(result.isFailed()).toBeTruthy() expect(result.getError()).toEqual('Item 00000000-0000-0000-0000-000000000001 not found in secondary database') - expect(primaryItemRepository.countAll).toHaveBeenCalledTimes(2) + expect(primaryItemRepository.countAll).toHaveBeenCalledTimes(3) expect(primaryItemRepository.countAll).toHaveBeenCalledWith({ userUuid: '00000000-0000-0000-0000-000000000000' }) expect((secondaryItemRepository as ItemRepositoryInterface).countAll).toHaveBeenCalledTimes(1) expect(primaryItemRepository.deleteByUserUuid).not.toHaveBeenCalled() @@ -374,4 +374,23 @@ describe('TransitionItemsFromPrimaryToSecondaryDatabaseForUser', () => { expect((secondaryItemRepository as ItemRepositoryInterface).deleteByUserUuid).toHaveBeenCalledTimes(1) }) }) + + it('should not migrate items if there are no items in the primary database', async () => { + primaryItemRepository.countAll = jest.fn().mockResolvedValue(0) + + const useCase = createUseCase() + + const result = await useCase.execute({ + userUuid: '00000000-0000-0000-0000-000000000000', + }) + + expect(result.isFailed()).toBeFalsy() + + expect(primaryItemRepository.countAll).toHaveBeenCalledTimes(1) + expect(primaryItemRepository.countAll).toHaveBeenCalledWith({ userUuid: '00000000-0000-0000-0000-000000000000' }) + expect(primaryItemRepository.findAll).not.toHaveBeenCalled() + expect((secondaryItemRepository as ItemRepositoryInterface).save).not.toHaveBeenCalled() + expect(primaryItemRepository.deleteByUserUuid).not.toHaveBeenCalled() + expect((secondaryItemRepository as ItemRepositoryInterface).deleteByUserUuid).not.toHaveBeenCalled() + }) }) diff --git a/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.ts b/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.ts index d91818609..63d4fabe0 100644 --- a/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.ts +++ b/packages/syncing-server/src/Domain/UseCase/Transition/TransitionItemsFromPrimaryToSecondaryDatabaseForUser/TransitionItemsFromPrimaryToSecondaryDatabaseForUser.ts @@ -25,6 +25,12 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use } const userUuid = userUuidOrError.getValue() + if (await this.isAlreadyMigrated(userUuid)) { + this.logger.info(`Items for user ${userUuid.value} are already migrated`) + + return Result.ok() + } + const migrationTimeStart = this.timer.getTimestampInMicroseconds() const migrationResult = await this.migrateItemsForUser(userUuid) @@ -72,6 +78,12 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use return Result.ok() } + private async isAlreadyMigrated(userUuid: Uuid): Promise { + const totalItemsCountForUser = await this.primaryItemRepository.countAll({ userUuid: userUuid.value }) + + return totalItemsCountForUser === 0 + } + private async allowForSecondaryDatabaseToCatchUp(): Promise { const twoSecondsInMilliseconds = 2_000 await this.timer.sleep(twoSecondsInMilliseconds)