SimpleIDB
// ==UserScript==
// @name indexedDB 操作封装
// @namespace https://scriptcat.org/
// @version 1.1.3
// @description 针对indexedDB的链式调用封装,支持批量操作。
// @author 仙灵天使
// @match http://*/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// ==/UserScript==
class SimpleIDB {
constructor(dbName = 'defaultDB', defaultTable = 'defaultTable') {
this.dbName = dbName;
this.storeName = defaultTable; // 初始化时使用默认表名
this.operationsQueue = []; // 存储操作队列
this.dbConnection = null;
this.key = null;
this.value = null;
// 打开数据库连接并设置连接对象
const request = indexedDB.open(this.dbName);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains(this.storeName)) {
db.createObjectStore(this.storeName, { keyPath: 'id' });
}
};
request.onsuccess = (event) => {
this.dbConnection = event.target.result;
};
request.onerror = (event) => {
console.error('Database error:', event.target.error);
};
}
// 设置表名
useTable(storeName) {
if (!storeName || !storeName.trim()) {
throw new Error('Store name cannot be empty or whitespace.');
}
this.storeName = storeName;
return this;
}
// 存储JS对象
set(key, object) {
this.key = key;
this.value = object;
this.operationsQueue.push((conn, table, key, value) => {
return new Promise((resolve, reject) => {
const transaction = conn.transaction([table], 'readwrite');
const store = transaction.objectStore(table);
const request = store.put({ id: key, ...value });
request.onsuccess = () => resolve();
request.onerror = (event) => reject(event.target.error);
});
});
return this;
}
// 获取所有key
getKeys(){
this.operationsQueue.push((conn, table, key, value) => {
return new Promise((resolve, reject) => {
const transaction = conn.transaction([table], 'readonly');
const store = transaction.objectStore(table);
const request = store.getAllKeys();
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(event.target.error);
});
});
return this;
}
// 获取下一个key
getNextKey(){
this.operationsQueue.push((conn, table, key, value) => {
return new Promise((resolve, reject) => {
const transaction = conn.transaction([table], 'readonly');
const store = transaction.objectStore(table);
// 使用游标获取下一个键
const request = store.openCursor();
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
// 找到第一个键,停止游标遍历
resolve(cursor.key);
return;
}
reject('No key found in the object store.');
};
request.onerror = (event) => reject(event.target.error);
});
})
return this;
}
// 读取JS对象
get(key) {
this.key = key;
this.operationsQueue.push((conn, table, key, value) => {
return new Promise((resolve, reject) => {
const transaction = conn.transaction([table], 'readonly');
const store = transaction.objectStore(table);
const request = store.get(key);
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(event.target.error);
});
});
return this;
}
// 移除某key数据
remove(key) {
this.key = key
this.operationsQueue.push((conn, table, key, value) => {
return new Promise((resolve, reject) => {
const transaction = conn.transaction([table], 'readwrite');
const store = transaction.objectStore(table);
const request = store.delete(key);
request.onsuccess = () => resolve();
request.onerror = (event) => reject(event.target.error);
});
});
return this;
}
clear() {
this.operationsQueue.push((conn, table, key, value) => {
return new Promise((resolve, reject) => {
const transaction = conn.transaction([table], 'readwrite');
const store = transaction.objectStore(table);
const request = store.clear();
request.onsuccess = () => resolve();
request.onerror = (event) => reject(event.target.error);
});
});
// 清空立即执行
this.execute()
}
// 执行所有队列中的操作
async execute() {
const operationsToExecute = [...this.operationsQueue]; // 复制当前队列并清空原队列
this.operationsQueue = [];
// 初始值是一个已解析的空数组Promise
return await operationsToExecute.reduce(async (promiseChain, operation) => {
const accumulatedResults = await promiseChain; // 等待前面所有操作的结果
const operationResult = await operation(this.dbConnection, this.storeName, this.key, this.value); // 等待当前操作的结果
return [...accumulatedResults, operationResult]; // 将当前操作的结果添加到累积结果中
}, Promise.resolve([])); // 直接返回结果数组,不需要再用扩展运算符
}
}