import { oss } from '@/modules/s3.ts'; import { db, schema } from '../src/app.ts'; import { eq } from 'drizzle-orm'; import { UserId } from '@/routes/user/modules/user-id.ts'; import { mvUserAToUserB } from '@/routes/file/index.ts'; // 迁移资源,原本的是 ${username}/appKey 改为 ${userId}/appKey // 第一步,迁移 表kv_app 和 kv_app_list, 对应的 data 中,把data 对应的 files 中path 去掉第一个前缀,比如 // { // "files": [ // { // "name": "README.md", // "path": "root/code-center/0.0.6/README.md" // }, // 把 path 中的 root 去掉,变成 code-center/0.0.6/README.md // ] // } type Data = { files: { name: string; path: string; }[]; } const BATCH_SIZE = 1000; // 迁移 kv_app; const firstMigration = async () => { let offset = 0; while (true) { const kvAppList = await db.select().from(schema.kvApp).limit(BATCH_SIZE).offset(offset); if (kvAppList.length === 0) break; for (const kvApp of kvAppList) { const data = kvApp.data as Data; const uid = kvApp.uid; const username = await UserId.getUserNameById(uid); if (!data.files) continue; for (const file of data.files) { // const pathParts = file.path.split('/'); // pathParts.shift(); // file.path = pathParts.join('/'); file.path = username + '/' + file.path; } await db.update(schema.kvApp).set({ data: { ...data } }).where(eq(schema.kvApp.id, kvApp.id)); } console.log(`Processed ${offset + kvAppList.length} records`); offset += BATCH_SIZE; } } // 迁移 kv_app_list const secondMigration = async () => { let offset = 0; while (true) { const kvAppList = await db.select().from(schema.kvAppList).limit(BATCH_SIZE).offset(offset); if (kvAppList.length === 0) break; for (const kvApp of kvAppList) { const data = kvApp.data as Data; const uid = kvApp.uid; const username = await UserId.getUserNameById(uid); if (!data.files) continue; for (const file of data.files) { // const pathParts = file.path.split('/'); // pathParts.shift(); // file.path = pathParts.join('/'); file.path = username + '/' + file.path; } await db.update(schema.kvAppList).set({ data: { ...data } }).where(eq(schema.kvAppList.id, kvApp.id)); } console.log(`Processed ${offset + kvAppList.length} records`); offset += BATCH_SIZE; } } /** * 迁移对象存储 */ const migrateOss = async () => { const list = await oss.listObjects('') const _names = list.filter(item => item.size === 0) type Name = { prefix: string; size: 0; id?: string; } const names: Name[] = _names as any; for (const name of names) { const username = name.prefix.split('/')[0]; const id = await UserId.getUserIdByName(username); if (id) { name.id = id; mvUserAToUserB(username, `data/${id}`, true); } } } // await firstMigration(); // await secondMigration(); await migrateOss(); console.log('Migration completed');