indexDB TS二次封装
indexDB 数据存储封装
源码
const win: { [k: string]: any } = window || globalThis;
const indexedDB =
win.indexedDB || win.mozIndexedDB || win.webkitIndexedDB || win.msIndexedDB;
const dbs: { [k: string]: IDBDatabase } = {};
let databaseName: string;
let request: IDBOpenDBRequest;
interface AnyEvent {
[k: string]: any;
}
export interface TableOption {
storeName: string;
option: { [K: string]: any };
index: { [K: string]: any }[];
}
export const createDB = (
name: string,
version?: string,
options?: TableOption[],
) =>
new Promise<IDBDatabase>((resolve, reject) => {
if (!indexedDB) reject('浏览器不支持indexedDB');
// eslint-disable-next-line @typescript-eslint/no-unused-vars
databaseName = name;
if (dbs?.[name]) {
resolve(dbs[name]);
return;
}
request = indexedDB.open(name, version);
createTable(options)?.then((db: IDBDatabase) => resolve(db));
request.onsuccess = (event: AnyEvent) => {
// IDBDatabase
const db = event.target.result;
// 缓存起来
dbs[name] = db;
resolve(db);
};
request.onerror = (event: AnyEvent) => reject(event);
});
export const createTable = (options?: TableOption[]) => {
if (!options) return;
return new Promise<IDBDatabase>((resolve) => {
request.onupgradeneeded = (event: AnyEvent) => {
const db = event.target.result;
dbs[databaseName] = db;
for (const i in options) {
// 判断是否存在表
if (!db.objectStoreNames.contains(options[i].storeName)) {
const objectStore = db.createObjectStore(
options[i].storeName,
options[i].option,
);
for (const j of options[i].index) {
objectStore.createIndex(j.name, j.keyPath, {
unique: j.unique,
});
}
}
}
resolve(db);
};
});
};
const getTransaction = async (name: string, version?: string) => {
let db: IDBDatabase;
// 先从缓存获取
if (dbs[databaseName]) {
db = dbs[databaseName];
} else {
db = await createDB(databaseName, version);
}
return db.transaction(name, 'readwrite');
};
const getObjectStore = async (
name: string,
version?: string,
): Promise<IDBObjectStore> => {
const transaction = await getTransaction(name, version);
return transaction.objectStore(name);
};
const getStore = (name: string, type: string, data: any) =>
new Promise<IDBDatabase>((resolve) => {
getObjectStore(name).then((objectStore: IDBObjectStore | any) => {
const request = objectStore[type](data);
request.onsuccess = (event: AnyEvent) =>
resolve(event.target.result);
// request.onerror = (event: AnyEvent) => Promise.reject(event);
});
});
const findStore = (
name: string,
start: any,
end: any,
startInclude: any,
endInclude: any,
) =>
new Promise<IDBDatabase>((resolve, reject) => {
getObjectStore(name).then((objectStore: IDBObjectStore) => {
const request = objectStore.openCursor(
IDBKeyRange.bound(start, end, startInclude, endInclude),
);
request.onsuccess = (event: AnyEvent) =>
resolve(event.target.result);
request.onerror = (event: AnyEvent) => reject(event);
});
});
export interface DBSelect {
add: (data: any) => Promise<IDBDatabase>;
get: (data: any) => Promise<IDBDatabase>;
del: (data: any) => Promise<IDBDatabase>;
clear: (data: any) => Promise<IDBDatabase>;
put: (key: string, data: any) => Promise<IDBDatabase>;
find: (
start: any,
end: any,
startInclude: any,
endInclude: any,
) => Promise<IDBDatabase>;
}
// 获取一个store
export const onDBSelect = async (
name: string,
version: string,
callback: (options: DBSelect) => void,
): Promise<DBSelect> => {
const add = (data: any) => getStore(name, 'add', data);
const get = (data: any) => getStore(name, 'get', data);
const del = (data: any) => getStore(name, 'delete', data);
const clear = (data: any) => getStore(name, 'clear', data);
const put = (data: any) => getStore(name, 'put', data);
const find = (start: any, end: any, startInclude: any, endInclude: any) =>
findStore(name, start, end, startInclude, endInclude);
const options: DBSelect = { add, get, clear, del, put, find };
getObjectStore(name, version);
callback(options);
return options;
};
使用
import { createDB, onDBSelect } from "IDB";
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
id: i,
name: `test_${i}`,
email: `test_${i}@test.com`
});
}
createDB('myTest', '1', [
{
storeName: "test1",
option: {
keyPath: "id"
},
index: [
{
name: 'id', keyPath: "id", unique: true
},
{
name: 'name', keyPath: "name", unique: false
},
{
name: 'emial', keyPath: "emial", unique: true
}
]
}
]);
onDBSelect('databaseName', '1', ({ add, get, del }) => {
add(data[0]);
get(data[0].id).then((result) => {
console.log(result);
});
add(data[1]);
add(data[2]);
del(data[0].id)
});
Events
创建 IndexDB
createDB: (name: string, version?: string, options?: TableOption[]) => Promise<IDBDatabase>
参数
参数 | 说明 | 类型 | 可选值 | 必填 | 默认值 |
---|---|---|---|---|---|
name | 库名称 | string | - | yes | - |
version | 库版本号 | string | - | - | - |
options | 表集合 | Array<TableOption> | - | - | - |
TableOption
参数 | 说明 | 类型 | 可选值 | 必填 | 默认值 |
---|---|---|---|---|---|
storeName | 表名称 | string | - | yes | - |
option | 键对 | Object | - | yes | - |
index | 表字段 | Array<Object> | - | yes | - |
创建表
createTable: createTable: (options?: TableOption[]) => Promise<IDBDatabase> | undefined
参数
参数 | 说明 | 类型 | 可选值 | 必填 | 默认值 |
---|---|---|---|---|---|
options | 表集合 | Array<TableOption> | - | - | - |
TableOption
参数 | 说明 | 类型 | 可选值 | 必填 | 默认值 |
---|---|---|---|---|---|
storeName | 表名称 | string | - | yes | - |
option | 键对 | Object | - | yes | - |
index | 表字段 | Array<Object> | - | yes | - |
选择表
onDBSelect: (name: string, version: string, callback: (db: IDBDatabase) => void) => Promise<IDBDatabase>
参数
参数 | 说明 | 类型 | 可选值 | 必填 | 默认值 |
---|---|---|---|---|---|
name | 表名称 | string | - | yes | - |
version | 版本号 | string | - | yes | - |
callback | 执行函数,必须在callback执行表的各种操作 | (options: DBSelect) => void | yes | - | - |
DBSelect
- 在表中添加数据
add: (data: any) => Promise<IDBDatabase>
- 获取表中指定数据
get: (data: any) => Promise<IDBDatabase>
- 删除表中指定数据
del: (data: any) => Promise<IDBDatabase>
- 清空表
clear: (data: any) => Promise<IDBDatabase>
- 修改指定数据
put: (data: any) => Promise<IDBDatabase>
- 通过游标获取数据
find: (start: any, end: any, startInclude: any, endInclude: any) => Promise<IDBDatabase>