From 84c8828e8ceb7c2bd5981b39bf7624d7785d6609 Mon Sep 17 00:00:00 2001 From: Mirone Date: Mon, 26 Jun 2023 12:16:30 +0800 Subject: [PATCH] feat: add migration script for database (#2854) --- .../env/src/blocksuite/subdoc-migration.ts | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/packages/env/src/blocksuite/subdoc-migration.ts b/packages/env/src/blocksuite/subdoc-migration.ts index 976828ae42..fdcf33d9d5 100644 --- a/packages/env/src/blocksuite/subdoc-migration.ts +++ b/packages/env/src/blocksuite/subdoc-migration.ts @@ -1,5 +1,84 @@ import * as Y from 'yjs'; +function migrateDatabase(data: Y.Map) { + data.delete('prop:mode'); + data.set('prop:views', new Y.Array()); + const columns = (data.get('prop:columns') as Y.Array).toJSON() as { + id: string; + name: string; + hide: boolean; + type: string; + width: number; + selection?: unknown[]; + }[]; + const views = [ + { + id: 'default', + name: 'Table', + columns: columns.map(col => ({ + id: col.id, + width: col.width, + hide: col.hide, + })), + filter: { type: 'group', op: 'and', conditions: [] }, + mode: 'table', + }, + ]; + const cells = (data.get('prop:cells') as Y.Map).toJSON() as Record< + string, + Record< + string, + { + id: string; + value: unknown; + } + > + >; + const convertColumn = ( + id: string, + update: (cell: { id: string; value: unknown }) => void + ) => { + Object.values(cells).forEach(row => { + update(row[id]); + }); + }; + const newColumns = columns.map(v => { + let data: Record = {}; + if (v.type === 'select' || v.type === 'multi-select') { + data = { options: v.selection }; + if (v.type === 'select') { + convertColumn(v.id, cell => { + if (Array.isArray(cell.value)) { + cell.value = cell.value[0]?.id; + } + }); + } else { + convertColumn(v.id, cell => { + if (Array.isArray(cell.value)) { + cell.value = cell.value.map(v => v.id); + } + }); + } + } + if (v.type === 'number') { + convertColumn(v.id, cell => { + if (typeof cell.value === 'string') { + cell.value = Number.parseFloat(cell.value.toString()); + } + }); + } + return { + id: v.id, + type: v.type, + name: v.name, + data, + }; + }); + data.set('prop:columns', newColumns); + data.set('prop:views', views); + data.set('prop:cells', cells); +} + function runBlockMigration( flavour: string, data: Y.Map, @@ -18,6 +97,9 @@ function runBlockMigration( data.set('sys:flavour', 'affine:image'); data.delete('prop:type'); } + if (flavour === 'affine:database' && version < 2) { + migrateDatabase(data); + } } function updateBlockVersions(versions: Y.Map) { @@ -31,6 +113,10 @@ function updateBlockVersions(versions: Y.Map) { versions.set('affine:image', embedVersion); versions.delete('affine:embed'); } + const databaseVersion = versions.get('affine:database'); + if (databaseVersion !== undefined && databaseVersion < 2) { + versions.set('affine:database', 2); + } } function migrateMeta(oldDoc: Y.Doc, newDoc: Y.Doc) {