- Deleted `import-data.ts` and `import-life.ts` scripts for importing short-link and life JSON data into the database. - Removed `ncode-list.json` containing short-link data. - Added new script `mv-resources.ts` for migrating resources from username-based paths to userId-based paths in the database and object storage. - Introduced `UserId` module for fetching user IDs and usernames from the database with caching. - Updated `UserApp` class to use user IDs instead of usernames for resource paths. - Modified routes to include a new endpoint for retrieving user IDs based on usernames.
106 lines
3.0 KiB
TypeScript
106 lines
3.0 KiB
TypeScript
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'); |