fix: skip removing already existing content in secondary to pick up where the transition left of
This commit is contained in:
parent
de081fe786
commit
857c6af946
2 changed files with 79 additions and 41 deletions
|
@ -31,19 +31,16 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
|
||||
let newRevisionsInSecondaryCount = 0
|
||||
let updatedRevisionsInSecondary: string[] = []
|
||||
let alreadyIdenticalInSecondaryAndPrimary: string[] = []
|
||||
if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
|
||||
const { alreadyExistingInPrimary, newRevisionsInSecondary, updatedInSecondary } =
|
||||
const { alreadyExistingInSecondaryAndPrimary, newRevisionsInSecondary, updatedInSecondary } =
|
||||
await this.getNewRevisionsCreatedInSecondaryDatabase(userUuid)
|
||||
|
||||
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) {
|
||||
this.logger.info(
|
||||
|
@ -68,7 +65,11 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
|
||||
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 (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
|
||||
const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.secondRevisionsRepository)
|
||||
|
@ -88,6 +89,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
userUuid,
|
||||
newRevisionsInSecondaryCount,
|
||||
updatedRevisionsInSecondary,
|
||||
alreadyIdenticalInSecondaryAndPrimary,
|
||||
)
|
||||
if (integrityCheckResult.isFailed()) {
|
||||
if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
|
||||
|
@ -119,7 +121,11 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
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 {
|
||||
const totalRevisionsCountForUser = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
|
||||
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
|
||||
|
@ -146,6 +152,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
continue
|
||||
}
|
||||
|
||||
if (
|
||||
alreadyExistingInSecondaryAndPrimary.find(
|
||||
(alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
|
||||
)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
const didSave = await (this.secondRevisionsRepository as RevisionRepositoryInterface).insert(revision)
|
||||
if (!didSave) {
|
||||
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<{
|
||||
alreadyExistingInPrimary: string[]
|
||||
alreadyExistingInSecondaryAndPrimary: string[]
|
||||
newRevisionsInSecondary: string[]
|
||||
updatedInSecondary: string[]
|
||||
}> {
|
||||
|
@ -211,7 +225,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
).countByUserUuid(userUuid)
|
||||
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
|
||||
|
||||
const alreadyExistingInPrimary: string[] = []
|
||||
const alreadyExistingInSecondaryAndPrimary: string[] = []
|
||||
const newRevisionsInSecondary: string[] = []
|
||||
const updatedInSecondary: string[] = []
|
||||
|
||||
|
@ -224,17 +238,17 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
|
||||
const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query)
|
||||
for (const revision of revisions) {
|
||||
const { revisionInPrimary, newerRevisionInSecondary } =
|
||||
const { identicalRevisionInPrimary, newerRevisionInSecondary } =
|
||||
await this.checkIfRevisionExistsInPrimaryDatabase(revision)
|
||||
if (revisionInPrimary !== null) {
|
||||
alreadyExistingInPrimary.push(revision.id.toString())
|
||||
if (identicalRevisionInPrimary !== null) {
|
||||
alreadyExistingInSecondaryAndPrimary.push(revision.id.toString())
|
||||
continue
|
||||
}
|
||||
if (newerRevisionInSecondary !== null) {
|
||||
updatedInSecondary.push(newerRevisionInSecondary.id.toString())
|
||||
continue
|
||||
}
|
||||
if (revisionInPrimary === null && newerRevisionInSecondary === null) {
|
||||
if (identicalRevisionInPrimary === null && newerRevisionInSecondary === null) {
|
||||
newRevisionsInSecondary.push(revision.id.toString())
|
||||
continue
|
||||
}
|
||||
|
@ -242,7 +256,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
}
|
||||
|
||||
return {
|
||||
alreadyExistingInPrimary,
|
||||
alreadyExistingInSecondaryAndPrimary,
|
||||
newRevisionsInSecondary,
|
||||
updatedInSecondary,
|
||||
}
|
||||
|
@ -250,7 +264,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
|
||||
private async checkIfRevisionExistsInPrimaryDatabase(
|
||||
revision: Revision,
|
||||
): Promise<{ revisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
|
||||
): Promise<{ identicalRevisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
|
||||
const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(
|
||||
Uuid.create(revision.id.toString()).getValue(),
|
||||
revision.props.userUuid as Uuid,
|
||||
|
@ -259,7 +273,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
|
||||
if (revisionInPrimary === null) {
|
||||
return {
|
||||
revisionInPrimary: null,
|
||||
identicalRevisionInPrimary: null,
|
||||
newerRevisionInSecondary: null,
|
||||
}
|
||||
}
|
||||
|
@ -273,14 +287,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
)
|
||||
|
||||
return {
|
||||
revisionInPrimary: null,
|
||||
identicalRevisionInPrimary: null,
|
||||
newerRevisionInSecondary:
|
||||
revision.props.dates.updatedAt > revisionInPrimary.props.dates.updatedAt ? revision : null,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
revisionInPrimary: revisionInPrimary,
|
||||
identicalRevisionInPrimary: revisionInPrimary,
|
||||
newerRevisionInSecondary: null,
|
||||
}
|
||||
}
|
||||
|
@ -289,6 +303,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
userUuid: Uuid,
|
||||
newRevisionsInSecondaryCount: number,
|
||||
updatedRevisionsInSecondary: string[],
|
||||
alreadyExistingInSecondaryAndPrimary: string[],
|
||||
): Promise<Result<boolean>> {
|
||||
try {
|
||||
const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
|
||||
|
@ -329,6 +344,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
|||
continue
|
||||
}
|
||||
|
||||
if (
|
||||
alreadyExistingInSecondaryAndPrimary.find(
|
||||
(alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
|
||||
)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (!revision.isIdenticalTo(revisionInSecondary)) {
|
||||
return Result.fail(
|
||||
`Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in primary database: ${JSON.stringify(
|
||||
|
|
|
@ -32,19 +32,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
|
||||
let newItemsInSecondaryCount = 0
|
||||
let updatedItemsInSecondary: string[] = []
|
||||
let alreadyIdenticalInSecondaryAndPrimary: string[] = []
|
||||
if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
|
||||
const { alreadyExistingInPrimary, newItemsInSecondary, updatedInSecondary } =
|
||||
const { alreadyExistingInSecondaryAndPrimary, newItemsInSecondary, updatedInSecondary } =
|
||||
await this.getNewItemsCreatedInSecondaryDatabase(userUuid)
|
||||
|
||||
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) {
|
||||
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`)
|
||||
|
||||
const migrationResult = await this.migrateItemsForUser(userUuid, updatedItemsInSecondary)
|
||||
const migrationResult = await this.migrateItemsForUser(
|
||||
userUuid,
|
||||
updatedItemsInSecondary,
|
||||
alreadyIdenticalInSecondaryAndPrimary,
|
||||
)
|
||||
if (migrationResult.isFailed()) {
|
||||
if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
|
||||
const cleanupResult = await this.deleteItemsForUser(userUuid, this.secondaryItemRepository)
|
||||
|
@ -86,6 +87,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
userUuid,
|
||||
newItemsInSecondaryCount,
|
||||
updatedItemsInSecondary,
|
||||
alreadyIdenticalInSecondaryAndPrimary,
|
||||
)
|
||||
if (integrityCheckResult.isFailed()) {
|
||||
if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
|
||||
|
@ -136,13 +138,13 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
}
|
||||
|
||||
private async getNewItemsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
|
||||
alreadyExistingInPrimary: string[]
|
||||
alreadyExistingInSecondaryAndPrimary: string[]
|
||||
newItemsInSecondary: string[]
|
||||
updatedInSecondary: string[]
|
||||
}> {
|
||||
this.logger.info(`[${userUuid.value}] Checking for new items in secondary database`)
|
||||
|
||||
const alreadyExistingInPrimary: string[] = []
|
||||
const alreadyExistingInSecondaryAndPrimary: string[] = []
|
||||
const updatedInSecondary: string[] = []
|
||||
const newItemsInSecondary: string[] = []
|
||||
|
||||
|
@ -161,16 +163,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
|
||||
const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll(query)
|
||||
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
|
||||
}
|
||||
if (newerItemInSecondary !== null) {
|
||||
updatedInSecondary.push(newerItemInSecondary.id.toString())
|
||||
continue
|
||||
}
|
||||
if (itemInPrimary === null && newerItemInSecondary === null) {
|
||||
if (identicalItemInPrimary === null && newerItemInSecondary === null) {
|
||||
newItemsInSecondary.push(item.id.toString())
|
||||
continue
|
||||
}
|
||||
|
@ -178,7 +180,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
}
|
||||
|
||||
return {
|
||||
alreadyExistingInPrimary,
|
||||
alreadyExistingInSecondaryAndPrimary,
|
||||
newItemsInSecondary,
|
||||
updatedInSecondary,
|
||||
}
|
||||
|
@ -186,11 +188,11 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
|
||||
private async checkIfItemExistsInPrimaryDatabase(
|
||||
item: Item,
|
||||
): Promise<{ itemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
|
||||
): Promise<{ identicalItemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
|
||||
const itemInPrimary = await this.primaryItemRepository.findByUuid(item.uuid)
|
||||
|
||||
if (itemInPrimary === null) {
|
||||
return { itemInPrimary: null, newerItemInSecondary: null }
|
||||
return { identicalItemInPrimary: null, newerItemInSecondary: null }
|
||||
}
|
||||
|
||||
if (!item.isIdenticalTo(itemInPrimary)) {
|
||||
|
@ -203,15 +205,19 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
)
|
||||
|
||||
return {
|
||||
itemInPrimary: null,
|
||||
identicalItemInPrimary: 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 {
|
||||
const totalItemsCountForUser = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
|
||||
const totalPages = Math.ceil(totalItemsCountForUser / this.pageSize)
|
||||
|
@ -234,6 +240,10 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
|
||||
continue
|
||||
}
|
||||
if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
|
||||
continue
|
||||
}
|
||||
|
||||
await (this.secondaryItemRepository as ItemRepositoryInterface).save(item)
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +268,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
userUuid: Uuid,
|
||||
newItemsInSecondaryCount: number,
|
||||
updatedItemsInSecondary: string[],
|
||||
alreadyExistingInSecondaryAndPrimary: string[],
|
||||
): Promise<Result<boolean>> {
|
||||
try {
|
||||
const totalItemsCountForUserInPrimary = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
|
||||
|
@ -298,6 +309,10 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
|||
continue
|
||||
}
|
||||
|
||||
if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (!item.isIdenticalTo(itemInSecondary)) {
|
||||
return Result.fail(
|
||||
`Item ${
|
||||
|
|
Loading…
Reference in a new issue