Chat / static /js /db.js
Jan2000's picture
Add files via upload
2717123 unverified
raw
history blame
7.07 kB
// 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("پاکسازی فایل‌های قدیمی ناموفق بود.");
};
});
}