File size: 7,065 Bytes
2717123
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// static/js/db.js

const DB_NAME = 'AlphaChatFileStore';
const STORE_NAME = 'files';
// *** قدم 1: نسخه دیتابیس را افزایش می‌دهیم تا فرآیند ارتقا فعال شود ***
const DB_VERSION = 2;

let db;

// 1. مقداردهی اولیه و باز کردن دیتابیس
export function initDB() {
    return new Promise((resolve, reject) => {
        console.log(`در حال تلاش برای باز کردن دیتابیس ${DB_NAME} با نسخه ${DB_VERSION}...`);
        const request = indexedDB.open(DB_NAME, DB_VERSION);

        request.onerror = (event) => {
            console.error("خطای حیاتی در باز کردن IndexedDB:", event.target.error);
            reject("خطای دیتابیس. لطفا از فعال بودن کوکی‌ها و فضای ذخیره‌سازی مرورگر اطمینان حاصل کنید.");
        };

        request.onsuccess = (event) => {
            db = event.target.result;
            console.log("IndexedDB با موفقیت باز و آماده استفاده است.");
            resolve(db);
        };

        // این تابع فقط زمانی اجرا می‌شود که دیتابیس برای اولین بار ساخته شود یا نسخه آن (DB_VERSION) افزایش یابد.
        request.onupgradeneeded = (event) => {
            console.log("رویداد onupgradeneeded فعال شد. در حال ارتقا ساختار دیتابیس...");
            const db = event.target.result;
            
            // *** قدم 2: منطق ارتقا را هوشمند می‌کنیم ***
            // ابتدا بررسی می‌کنیم که آیا ساختار قدیمی (و اشتباه) وجود دارد یا نه
            if (db.objectStoreNames.contains(STORE_NAME)) {
                // اگر وجود داشت، آن را حذف می‌کنیم تا راه برای ساختار جدید باز شود.
                db.deleteObjectStore(STORE_NAME);
                console.log("Object store قدیمی 'files' پیدا و برای ارتقا حذف شد.");
            }
            
            // حالا ساختار جدید و صحیح را ایجاد می‌کنیم.
            // با حذف keyPath، به IndexedDB اجازه می‌دهیم کلید را به صورت خودکار و خارج از آبجکت مدیریت کند.
            // این کار مشکل اصلی شما را به طور قطعی حل می‌کند.
            const store = db.createObjectStore(STORE_NAME, { autoIncrement: true });
            
            // یک ایندکس برای جستجوی فایل‌ها بر اساس زمان ایجاد می‌کنیم.
            store.createIndex('timestamp', 'timestamp', { unique: false });
            console.log("Object store جدید و صحیح 'files' با موفقیت ساخته شد.");
        };
    });
}

// 2. ذخیره کردن یک فایل در دیتابیس
export function storeFile(file) {
    return new Promise((resolve, reject) => {
        if (!db) {
            // این حالت نباید رخ دهد چون main.js منتظر اتمام initDB می‌ماند.
            reject("دیتابیس هنوز مقداردهی اولیه نشده است.");
            return;
        }
        const transaction = db.transaction([STORE_NAME], 'readwrite');
        const store = transaction.objectStore(STORE_NAME);
        const fileRecord = {
            file: file,
            name: file.name,
            type: file.type,
            timestamp: Date.now()
        };
        
        const request = store.add(fileRecord);

        request.onsuccess = (event) => {
            // event.target.result حاوی کلید (ID) اختصاص داده شده به رکورد جدید است.
            resolve(event.target.result); 
        };

        request.onerror = (event) => {
            console.error("خطا در ذخیره فایل در IndexedDB:", event.target.error);
            reject("ذخیره فایل در دیتابیس محلی ناموفق بود.");
        };
    });
}

// 3. بازیابی یک فایل از دیتابیس با استفاده از ID
export function getFile(id) {
    return new Promise((resolve, reject) => {
        if (!db) {
            reject("دیتابیس مقداردهی اولیه نشده است.");
            return;
        }
        
        // کلیدهای تولید شده توسط autoIncrement همیشه عددی هستند.
        // این تبدیل، اطمینان می‌دهد که حتی اگر ID به صورت رشته ذخیره شده باشد، به درستی بازیابی شود.
        const numericId = typeof id === 'string' ? parseInt(id, 10) : id;
        if (isNaN(numericId)) {
            reject("ID فایل برای بازیابی نامعتبر است.");
            return;
        }
        
        const transaction = db.transaction([STORE_NAME], 'readonly');
        const store = transaction.objectStore(STORE_NAME);
        const request = store.get(numericId);

        request.onsuccess = (event) => {
            if (event.target.result) {
                // خود فایل که یک Blob است را باز می‌گردانیم.
                resolve(event.target.result.file); 
            } else {
                reject("فایلی با این ID در دیتابیس محلی یافت نشد.");
            }
        };

        request.onerror = (event) => {
            console.error("خطا در بازیابی فایل:", event.target.error);
            reject("بازیابی فایل ناموفق بود.");
        };
    });
}

// 4. پاک کردن فایل‌های قدیمی‌تر از یک هفته
export function cleanupOldFiles() {
    return new Promise((resolve, reject) => {
        if (!db) {
            reject("دیتابیس مقداردهی اولیه نشده است.");
            return;
        }
        const transaction = db.transaction([STORE_NAME], 'readwrite');
        const store = transaction.objectStore(STORE_NAME);
        const index = store.index('timestamp');
        
        const oneWeekAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);
        const range = IDBKeyRange.upperBound(oneWeekAgo);
        
        const request = index.openCursor(range);
        let deletedCount = 0;

        request.onsuccess = (event) => {
            const cursor = event.target.result;
            if (cursor) {
                cursor.delete();
                deletedCount++;
                cursor.continue();
            } else {
                if(deletedCount > 0) console.log(`${deletedCount} فایل قدیمی و منقضی شده از IndexedDB پاک شد.`);
                resolve();
            }
        };

        request.onerror = (event) => {
            console.error("خطا در پاکسازی فایل‌های قدیمی:", event.target.error);
            reject("پاکسازی فایل‌های قدیمی ناموفق بود.");
        };
    });
}