let _IDBDatabase;//数据库对象
/**
* 初始化或升级数据库(动态对比增删改上一版本对象仓库和索引)
*
* @param {String} dbName 数据库名称
* @param {Number} dbVersion 数据库版本
* @param {Array} objectStoreArr 对象仓库名称列表,格式如下:[{ name: 'userStore', index: [{ keys: 'name,age', unique: true }]}]
*
* @returns Promise对象,then(IDBDatabase)
*/
export let initDB = (dbName, dbVersion, objectStoreArr) => new Promise((resolve, reject) => {
let _IDBRequest = window.indexedDB.open(dbName, dbVersion);
_IDBRequest.onsuccess = event => {
_IDBDatabase = event.target.result;
resolve(_IDBDatabase);
};
_IDBRequest.onerror = event => reject(event);
_IDBRequest.onupgradeneeded = event => {
let oldObjectStoreNames = event.target.result.objectStoreNames;
let newObjectStoreNames = objectStoreArr.map(o => o.name);
if (oldObjectStoreNames.length === 0 && newObjectStoreNames && newObjectStoreNames.length > 0) //原对象仓库为空,新对象仓库不为空,直接添加新对象仓库
for (let newObjectStoreName of newObjectStoreNames) {
let newObjectStore = event.target.result.createObjectStore(newObjectStoreName, { keyPath: 'id' });
let newIndexArr = objectStoreArr.filter(o => o.name === newObjectStoreName)[0].index ?? [];
for (let index of newIndexArr)
newObjectStore.createIndex(index.keys, index.keys.split(','), { unique: index.unique ?? false });
}
else {//原对象仓库不为空,则需要根据新旧对象仓库对比情况,决定添加删除或编辑
for (let oldObjectStoreName of oldObjectStoreNames)
if (!newObjectStoreNames.some(newObjectStoreName => newObjectStoreName === oldObjectStoreName))//新对象仓库中不存在的就对象仓库,直接删除
event.target.result.deleteObjectStore(oldObjectStoreName);
newObjectStoreNames.forEach(newObjectStoreName => {
if (oldObjectStoreNames.contains(newObjectStoreName)) {//新旧对象仓库都存在的,编辑
let oldObjectStore = event.target.transaction.objectStore(newObjectStoreName);
let newIndexArr = objectStoreArr.filter(o => o.name === newObjectStoreName)[0].index ?? [];
let oldIndexNames = oldObjectStore.indexNames;
let newIndexNames = newIndexArr.map(o => o.keys);
for (let oldIndexName of oldIndexNames)//旧对象仓库中存在索引,新对象仓库中不存在的索引,删除
if (!newIndexNames.some(newIndexName => newIndexName === oldIndexName))
oldObjectStore.deleteIndex(oldIndexName);
for (let newIndexName of newIndexNames) //新对象仓库中存在索引,旧对象仓库中不存在索引,添加
if (!oldIndexNames.contains(newIndexName))
oldObjectStore.createIndex(newIndexName, newIndexName.split(','), { unique: newIndexArr.filter(o => o.keys === newIndexName)[0].unique ?? false });
} else {//新对象仓库有,旧对象仓库没有,添加
let newObjectStore = event.target.result.createObjectStore(newObjectStoreName, { keyPath: 'id' });
let newObjectStoreIndexs = objectStoreArr.filter(o => o.name === newObjectStoreName)[0].index ?? [];
for (let index of newObjectStoreIndexs)
newObjectStore.createIndex(index.keys, index.keys.split(','), { unique: index.unique ?? false });
}
})
}
};
});1.初始化或升级IDB,调用如下
//调用示例
initDB("testDB", 1, [{ name: 'userStore', index: [{ keys: 'name,age', unique: true }, { keys: 'age', unique: false }] }, { name: 'scoreStore' }]).then(res => { });2.添加数据
/**
* 添加数据
*
* @param {String} storeName 对象仓库名称
* @param {Object} data 对象数据
*
* @returns Promise对象,then(IDBRequest)
*/
export let adData = (storeName, data) => new Promise((resolve, reject) => {
let _IDBRequest = _IDBDatabase.transaction(storeName, 'readwrite').objectStore(storeName).add(data);
_IDBRequest.onsuccess = event => resolve(event.target);
_IDBRequest.onerror = event => reject(event);
});//调用示例
for (let i = 1; i <= 100; i++) {
adData('userStore', { id: i, name: '张三' + i, age: Math.floor((Math.random() * 10) + 10) })
}3.删除数据
/**
* 删除数据
*
* @param {String} storeName 对象仓库名称
* @param {Number} id 对象数据id
*
* @returns Promise对象,then(IDBRequest)
*/
export let rmDataById = (storeName, id) => new Promise((resolve, reject) => {
let _IDBRequest = _IDBDatabase.transaction(storeName, 'readwrite').objectStore(storeName).delete(id);
_IDBRequest.onsuccess = event => resolve(event.target);
_IDBRequest.onerror = event => reject(event);
});//调用示例
rmDataById('userStore', 3).then(res => console.log(res));4.清空对象数据
/**
* 清空对象数据
*
* @param {String} storeName 对象仓库名称
*
* @returns Promise对象,then(IDBRequest)
*/
export let clearData = (storeName) => new Promise((resolve, reject) => {
let _IDBRequest = _IDBDatabase.transaction(storeName, 'readwrite').objectStore(storeName).clear();
_IDBRequest.onsuccess = event => resolve(event.target);
_IDBRequest.onerror = event => reject(event);
});//调用示例
clearData('userStore').then(res => console.log(res));5.对象仓库记录数据
/**
* 对象仓库记录数
*
* @param {String} storeName 对象仓库名称
* @param {IDBKeyRange} query IDBKeyRange(可选)
* @param {String} indexKeys 索引keys(缺省为id,可选)
*
* @returns Promise对象,then(数据仓库记录数)
*/
export let countData = (storeName, query, indexKeys) => new Promise((resolve, reject) => {
let objectStore = _IDBDatabase.transaction(storeName, 'readwrite').objectStore(storeName);
if (indexKeys)
objectStore = objectStore.index(indexKeys);
let _IDBRequest = query ? objectStore.count(query) : objectStore.count();
_IDBRequest.onsuccess = event => resolve(event.target.result);
_IDBRequest.onerror = event => reject(event);
});//调用示例
countData('userStore', IDBKeyRange.bound([10], [12]), 'age').then(res => console.log(res));6.编辑数据
/**
* 编辑数据
*
* @param {String} storeName 对象仓库名称
* @param {Object} data 对象数据
* @returns Promise对象,then(IDBRequest)
*/
export let mdDataById = (storeName, data) => new Promise((resolve, reject) => {
let _IDBRequest = _IDBDatabase.transaction(storeName, 'readwrite').objectStore(storeName).put(data);
_IDBRequest.onsuccess = event => resolve(event.target);
_IDBRequest.onerror = event => reject(event);
});//调用示例
mdDataById('userStore', { id: 2, name: '李四222', age: 18 }).then(res => console.log(res))7.根据id查询数据
/**
* 根据id查询数据
*
* @param {String} storeName 对象仓库名称
* @param {Number} id 主键key
*
* @returns Promise对象,then(数据对象)
*/
export let getDataById = (storeName, id) => new Promise((resolve, reject) => {
let _IDBRequest = _IDBDatabase.transaction(storeName, 'readwrite').objectStore(storeName).get(id);
_IDBRequest.onsuccess = event => resolve(event.target.result);
_IDBRequest.onerror = event => reject(event);
});//调用示例
getDataById('userStore', 5).then(res => console.log(res))8.查询数据列表
/**
* 查询数据列表(自定义索引的query参数为数组格式,IDBKeyRange.bound([10], [20]))
*
* @param {String} storeName 对象仓库名称
* @param {IDBKeyRange} query IDBKeyRange(可选)
* @param {IDBCursorDirection} direction IDBCursorDirection枚举类型:"next","nextunique","prev","prevunique"(可选)
* @param {String} indexKeys 索引keys(缺省为id,可选)
*
* @returns Promise对象,then(数据对象数组)
*/
export let queryData = (storeName, query, direction, indexKeys) => new Promise((resolve, reject) => {
let objectStore = _IDBDatabase.transaction(storeName).objectStore(storeName);
if (indexKeys)
objectStore = objectStore.index(indexKeys);
let _IDBRequest = query ? (direction ? objectStore.openCursor(query, direction) : objectStore.openCursor(query)) : objectStore.openCursor();
let arr = [];
_IDBRequest.onsuccess = event => {
let cursor = event.target.result
if (cursor) {
arr.push(cursor.value);
cursor.continue();
} else
resolve(arr);
};
_IDBRequest.onerror = event => reject(event);
});//调用示例
queryData('userStore', IDBKeyRange.bound(1, 11, false, true)).then(res => console.log(res));9.分页查询
/**
* 分页查询
*
* @param {String} storeName 对象仓库名称
* @param {Number} pageNo 页码
* @param {Number} pageSize 页面大小
* @param {IDBKeyRange} query IDBKeyRange(可选)
* @param {IDBCursorDirection} direction IDBCursorDirection枚举类型:"next","nextunique","prev","prevunique"(可选)
* @param {String} indexKeys 索引keys(缺省为id,可选)
* @returns Promise对象,then(分页数据 total、pages、data)
*/
export let queryPage = (storeName, pageNo, pageSize, query, direction, indexKeys) => countData(storeName, query, indexKeys).then(total => new Promise((resolve, reject) => {
let pages = 0, data = [], objectStore = _IDBDatabase.transaction(storeName).objectStore(storeName);
if (indexKeys)
objectStore = objectStore.index(indexKeys);
let _IDBRequest = query ? (direction ? objectStore.openCursor(query, direction) : objectStore.openCursor(query)) : objectStore.openCursor();
let isAdvance = true;
_IDBRequest.onsuccess = event => {
let cursor = event.target.result
if (cursor) {
if (isAdvance && data.length === 0 && pageNo > 1) {
isAdvance = false;
cursor.advance((pageNo - 1) * pageSize);
} else {
data.push(cursor.value);
if (data.length === pageSize) {
resolve({
total: total,
pages: Math.ceil(total / pageSize),
data: data
})
return;
}
cursor.continue();
}
} else
resolve({
total: total,
pages: pages,
data: data
})
};
_IDBRequest.onerror = event => reject(event);
}));//调用示例
queryPage('userStore', 1, 9).then(res => console.log(res))10.关闭数据库
/**
* 关闭数据库
*
* @returns void
*/
export let closeDB = () => _IDBDatabase.close();//调用示例
closeDB() | 留言与评论(共有 0 条评论) “” |