import type { SQLiteDatabase } from 'expo-sqlite'; import { CREATE_MESSAGES_TABLE, CREATE_MESSAGES_INDEXES, MIGRATE_MESSAGES_TABLE, } from './MessageSchema'; import { CREATE_CONVERSATIONS_TABLE, CREATE_CONVERSATION_CACHE_TABLE, CREATE_CONVERSATION_LIST_CACHE_TABLE, MIGRATE_CONVERSATIONS_TABLE, } from './ConversationSchema'; import { CREATE_USERS_TABLE, CREATE_CURRENT_USER_CACHE_TABLE, } from './UserSchema'; import { CREATE_GROUPS_TABLE, CREATE_GROUP_MEMBERS_TABLE, CREATE_GROUP_INDEXES, } from './GroupSchema'; import { CREATE_POSTS_CACHE_TABLE, } from './PostSchema'; async function execWithRetry(db: SQLiteDatabase, sql: string, maxRetries = 5): Promise { for (let i = 0; i < maxRetries; i++) { try { await db.execAsync(sql); return; } catch (error) { const msg = String(error); if (msg.includes('database is locked') && i < maxRetries - 1) { const delay = 200 * (i + 1); console.warn(`[MigrationManager] 数据库锁定,${delay}ms 后重试 (${i + 1}/${maxRetries})`); await new Promise(r => setTimeout(r, delay)); continue; } throw error; } } } export async function runMigrations(db: SQLiteDatabase): Promise { await execWithRetry(db, 'PRAGMA busy_timeout = 10000;'); await execWithRetry(db, CREATE_MESSAGES_TABLE); await execWithRetry(db, CREATE_CONVERSATIONS_TABLE); await execWithRetry(db, CREATE_CONVERSATION_CACHE_TABLE); await execWithRetry(db, CREATE_CONVERSATION_LIST_CACHE_TABLE); await execWithRetry(db, CREATE_USERS_TABLE); await execWithRetry(db, CREATE_CURRENT_USER_CACHE_TABLE); await execWithRetry(db, CREATE_GROUPS_TABLE); await execWithRetry(db, CREATE_GROUP_MEMBERS_TABLE); await execWithRetry(db, CREATE_POSTS_CACHE_TABLE); for (const indexSql of CREATE_MESSAGES_INDEXES) { await execWithRetry(db, indexSql); } for (const indexSql of CREATE_GROUP_INDEXES) { await execWithRetry(db, indexSql); } await MIGRATE_MESSAGES_TABLE(db); await MIGRATE_CONVERSATIONS_TABLE(db); }