| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- export default class IndexedDB {
- private dbName: string;
- private storeName: string;
- private dbVersion: number = 1;
- constructor(dbName: string, storeName: string, version?: number) {
- this.dbName = dbName;
- this.storeName = storeName;
- if (version) this.dbVersion = version;
- }
- //打开数据库
- private openDatabase(retryCount: number = 3, delay: number = 300): Promise<IDBDatabase> {
- return new Promise<IDBDatabase>((resolve, reject) => {
- const tryOpen = (attempt: number) => {
- const request = window.indexedDB.open(this.dbName, this.dbVersion);
- request.onupgradeneeded = (event) => {
- const target = event.target as IDBOpenDBRequest;
- const db = target.result;
- if (!db.objectStoreNames.contains(this.storeName)) {
- const store = db.createObjectStore(this.storeName, { keyPath: 'key' });
- store.createIndex('valueIndex', 'value', { unique: false });
- }
- };
- request.onsuccess = (event) => {
- const target = event.target as IDBOpenDBRequest;
- resolve(target.result);
- };
- request.onerror = (event) => {
- const target = event.target as IDBOpenDBRequest;
- if (attempt < retryCount) {
- console.warn(`数据库打开失败,第${attempt}次重试...`);
- setTimeout(() => tryOpen(attempt + 1), delay);
- } else {
- reject(new Error(`数据库打开失败(重试${retryCount}次): ${target.error}`));
- }
- };
- };
- tryOpen(1);
- });
- }
- /**
- * 设置数据 (使用字符串key)
- */
- // 在setData等方法中添加事务错误处理
- setData(key: string, value: any): Promise<void> {
- return new Promise<void>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readwrite');
- transaction.onerror = () => reject(new Error('Transaction failed: ' + transaction.error));
- const objectStore = transaction.objectStore(this.storeName);
- const request = objectStore.put({ key, value });
- request.onsuccess = () => resolve();
- request.onerror = () => reject(new Error('Failed to set data: ' + request.error));
- })
- .catch(reject);
- });
- }
- /**
- * 批量设置数据
- * @param items 键值对数组,格式为 {key: string, value: any}[]
- */
- setBatchData(items: { key: string, value: any }[]): Promise<void> {
- return new Promise<void>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readwrite');
- const objectStore = transaction.objectStore(this.storeName);
- // 批量添加/更新数据
- items.forEach(item => {
- objectStore.put({ key: item.key, value: item.value });
- });
- transaction.oncomplete = () => resolve();
- transaction.onerror = () =>
- reject(new Error('Failed to set batch data: ' + transaction.error));
- })
- .catch(reject);
- });
- }
- /**
- * 获取数据 (使用字符串key)
- */
- getData(key: string): Promise<any> {
- return new Promise<any>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readonly');
- const objectStore = transaction.objectStore(this.storeName);
- const request = objectStore.get(key);
- request.onsuccess = () => resolve(request.result?.value);
- request.onerror = () => reject(new Error('Failed to get data: ' + request.error));
- })
- .catch(reject);
- });
- }
- /**
- * 删除数据 (使用字符串key)
- * @param key
- * @returns
- */
- deleteData(key: string): Promise<void> {
- return new Promise<void>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readwrite');
- const objectStore = transaction.objectStore(this.storeName);
- const request = objectStore.delete(key);
- request.onsuccess = () => resolve();
- request.onerror = () => reject(new Error('Failed to delete data: ' + request.error));
- })
- .catch(reject);
- });
- }
- /**
- *清空表数据
- * @returns
- */
- clearAll(): Promise<void> {
- return new Promise<void>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readwrite');
- const objectStore = transaction.objectStore(this.storeName);
- const request = objectStore.clear();
- request.onsuccess = () => resolve();
- request.onerror = () => reject(new Error('Failed to clear all data: ' + request.error));
- })
- .catch(reject);
- });
- }
- /**
- * 按索引查询数据
- * @param indexName 索引名称
- * @param value 索引值
- */
- getDataByIndex(indexName: string, value: any): Promise<any[]> {
- return new Promise<any[]>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readonly');
- const objectStore = transaction.objectStore(this.storeName);
- const index = objectStore.index(indexName);
- const request = index.getAll(value);
- request.onsuccess = () => resolve(request.result);
- request.onerror = () => reject(new Error('Failed to get data by index: ' + request.error));
- })
- .catch(reject);
- });
- }
- /**
- * 获取所有数据
- */
- getAllData(): Promise<any[]> {
- return new Promise<any[]>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readonly');
- const objectStore = transaction.objectStore(this.storeName);
- const request = objectStore.getAll();
- request.onsuccess = () => resolve(request.result);
- request.onerror = () => reject(new Error('Failed to get all data: ' + request.error));
- })
- .catch(reject);
- });
- }
- /**
- * 获取数据总数
- */
- count(): Promise<number> {
- return new Promise<number>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readonly');
- const objectStore = transaction.objectStore(this.storeName);
- const request = objectStore.count();
- request.onsuccess = () => resolve(request.result);
- request.onerror = () => reject(new Error('Count error: ' + request.error));
- })
- .catch(reject);
- });
- }
- /**
- * 使用游标遍历所有数据
- * @param callback 处理每条数据的回调函数
- */
- forEach(callback: (value: any, key: string) => boolean | void): Promise<void> {
- return new Promise<void>((resolve, reject) => {
- this.openDatabase()
- .then((db) => {
- const transaction = db.transaction([this.storeName], 'readonly');
- const objectStore = transaction.objectStore(this.storeName);
- const request = objectStore.openCursor();
- request.onsuccess = (event) => {
- const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;
- if (cursor) {
- const shouldContinue = callback(cursor.value.value, cursor.value.key);
- if (shouldContinue !== false) {
- cursor.continue();
- }
- } else {
- resolve();
- }
- };
- request.onerror = () => reject(new Error('Cursor error: ' + request.error));
- })
- .catch(reject);
- });
- }
- }
- /*
- // 使用示例
- const storage = new IndexedDB('myDatabase', 'myStore');
- // 清空表数据
- storage.clearAll()
- .then(() => console.log('All data cleared successfully'))
- .catch(err => console.error('Error clearing data:', err));
- // 保存数据
- storage.setData('user1', { name: 'John', age: 30 })
- .then(() => console.log('Data saved successfully'))
- .catch(err => console.error('Error saving data:', err));
- // 获取数据
- storage.getData('user1')
- .then(data => console.log('Retrieved data:', data))
- .catch(err => console.error('Error retrieving data:', err));
- */
|