UBERF-10413: Migration (#8770)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2025-04-29 22:58:28 +07:00 committed by GitHub
parent b1847443a7
commit f5919fad70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -21,12 +21,14 @@ import core, {
DOMAIN_STATUS, DOMAIN_STATUS,
DOMAIN_TX, DOMAIN_TX,
generateId, generateId,
groupByArray,
makeCollabJsonId, makeCollabJsonId,
makeCollabYdocId, makeCollabYdocId,
makeDocCollabId, makeDocCollabId,
MeasureMetricsContext, MeasureMetricsContext,
RateLimiter, RateLimiter,
type AnyAttribute, type AnyAttribute,
type AttachedDoc,
type Blob, type Blob,
type Class, type Class,
type Doc, type Doc,
@ -36,7 +38,8 @@ import core, {
type Space, type Space,
type Status, type Status,
type TxCreateDoc, type TxCreateDoc,
type TxCUD type TxCUD,
type TxMixin
} from '@hcengineering/core' } from '@hcengineering/core'
import { import {
createDefaultSpace, createDefaultSpace,
@ -255,6 +258,41 @@ async function processMigrateContentFor (
} }
} }
async function migrateBackupMixins (client: MigrationClient): Promise<void> {
// Go via classes with domain and check if mixin exists and need to flush %hash%
const hierarchy = client.hierarchy
const curHash = Date.now().toString(16) // Current hash value
const txIterator = await client.traverse<TxMixin<Doc, AttachedDoc>>(DOMAIN_TX, { _class: core.class.TxMixin })
while (true) {
const mixinOps = await txIterator.next(500)
if (mixinOps === null || mixinOps.length === 0) break
const _classes = groupByArray(mixinOps, (it) => it.objectClass)
for (const [_class, ops] of _classes.entries()) {
const domain = hierarchy.findDomain(_class)
if (domain === undefined) continue
let docs = await client.find(domain, { _id: { $in: ops.map((it) => it.objectId) } })
docs = docs.filter((it) => {
// Check if mixin is last operation by modifiedOn
const mops = ops.filter((mi) => mi.objectId === it._id)
if (mops.length === 0) return false
return mops.some((mi) => mi.modifiedOn === it.modifiedOn && mi.modifiedBy === it.modifiedBy)
})
if (docs.length > 0) {
// Check if docs has mixins from list
const toUpdate = docs.filter((it) => hierarchy.findAllMixins(it).length > 0)
if (toUpdate.length > 0) {
await client.update(domain, { _id: { $in: toUpdate.map((it) => it._id) } }, { '%hash%': curHash })
}
}
}
}
}
async function migrateCollaborativeDocsToJson (client: MigrationClient): Promise<void> { async function migrateCollaborativeDocsToJson (client: MigrationClient): Promise<void> {
const ctx = new MeasureMetricsContext('migrateCollaborativeDocsToJson', {}) const ctx = new MeasureMetricsContext('migrateCollaborativeDocsToJson', {})
const storageAdapter = client.storageAdapter const storageAdapter = client.storageAdapter
@ -494,6 +532,11 @@ export const coreOperation: MigrateOperation = {
state: 'collaborative-docs-to-json', state: 'collaborative-docs-to-json',
mode: 'upgrade', mode: 'upgrade',
func: migrateCollaborativeDocsToJson func: migrateCollaborativeDocsToJson
},
{
state: 'migrate-backup-mixins',
mode: 'upgrade',
func: migrateBackupMixins
} }
]) ])
}, },