You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

db.js 9.0 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. let db;
  2. let openRequest;
  3. const indexedDB =
  4. window.indexedDB ||
  5. window.webkitIndexedDb ||
  6. window.mozIndexed ||
  7. window.msIndexedDB;
  8. // transaction 事务处理 意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
  9. // tableList [{tableName,keyPath,indexName}]
  10. /**
  11. * 初始化数据库
  12. * @param {string} dbName 数据库名
  13. * @param {Array} tableList 数据表列表
  14. */
  15. // 初始化
  16. export function init({ dbName, tableList }) {
  17. // 存在就打开 不存在新建 第二个参数为db 版本
  18. openRequest = indexedDB.open(dbName);
  19. // 新的数据库创建 或者数据库的版本号被更改会被触发
  20. openRequest.onupgradeneeded = function (e) {
  21. // 表的创建在这个回调里执行
  22. const thisDb = e.target.result;
  23. console.log('running onupgradeneeded' + thisDb);
  24. if (tableList?.length) {
  25. tableList.forEach((table) => {
  26. if (!thisDb.objectStoreNames.contains(table.tableName)) {
  27. console.log('I need to create the objectStore');
  28. // keyPath 主键 autoIncrement 是否自增
  29. const objectStore = thisDb.createObjectStore(table.tableName, {
  30. keyPath: table.keyPath,
  31. ...table.attr,
  32. // autoIncrement: true,
  33. });
  34. if (table.indexName) {
  35. // 创建表的时候 可以去指定那些字段是可以被索引的字段
  36. objectStore.createIndex(table.indexName, table.indexName, {
  37. unique: table.unique || false,
  38. });
  39. }
  40. }
  41. });
  42. } else {
  43. console.error('请传入数据表参数');
  44. }
  45. };
  46. // 已经创建好的数据库创建成功的时候
  47. openRequest.onsuccess = function (e) {
  48. db = e.target.result;
  49. window.db = e.target.result;
  50. db.onerror = function (event) {
  51. console.error('Database error: ' + event.target.errorCode);
  52. console.dir(event.target);
  53. };
  54. };
  55. // 打开失败时调用
  56. openRequest.onerror = function (e) {
  57. console.error('openRequest.onerror', e);
  58. };
  59. }
  60. /**
  61. * 添加一行
  62. * @param {string} tableName 表名
  63. * @param {object} data 数据
  64. * @returns {promise}
  65. */
  66. export function add({ tableName, data }) {
  67. console.log("add:",tableName,data)
  68. return new Promise((suc, fail) => {
  69. const request = window.db
  70. .transaction([tableName], 'readwrite')
  71. .objectStore(tableName)
  72. .add(data);
  73. request.onsuccess = function (event) {
  74. suc();
  75. console.log('数据写入成功', event);
  76. };
  77. request.onerror = function (event) {
  78. // fail();
  79. update({tableName, data })
  80. console.log('数据写入失败', event);
  81. };
  82. });
  83. }
  84. /**
  85. * 遍历所有数据 其实这里有点坑 真正readAll是下面readAllPC这个方法,因为低版本webview手机不兼容objectStore.getAll所以使用游标来实现
  86. * @param {string} tableName 表名
  87. * @returns {promise}
  88. */
  89. export function readAll(tableName) {
  90. return new Promise((suc, fail) => {
  91. const objectStore = db
  92. .transaction([tableName], 'readwrite')
  93. .objectStore(tableName);
  94. // 我这里做的是把所有的结果全部收集起来 当然我们可以做其他事情此处拿到的value是每条数据的结果、还有primaryKey主键、key、与direction
  95. const result = [];
  96. objectStore.openCursor().onsuccess = function (event) {
  97. const cursor = event.target.result;
  98. if (cursor) {
  99. result.push({ ...cursor.value });
  100. cursor.continue();
  101. } else {
  102. suc(result);
  103. console.log('readAll成功==>' , result);
  104. }
  105. };
  106. objectStore.openCursor().onerror = function (event) {
  107. console.dir(event);
  108. fail();
  109. };
  110. });
  111. }
  112. /**
  113. * 读取所有数据 仅在pc上或者版本高的手机浏览器中使用 readAllPC这个方法 这个在低版本weview的手机浏览器里面不兼容
  114. * @param {string} tableName
  115. * @returns {promise}
  116. */
  117. export function readAllForHighVersion(tableName) {
  118. return new Promise((suc, fail) => {
  119. const objectStore = db
  120. .transaction([tableName], 'readwrite')
  121. .objectStore(tableName);
  122. const request = objectStore.getAll();
  123. request.onerror = function (event) {
  124. fail();
  125. console.log('readAll--->读取表事务失败', event);
  126. };
  127. request.onsuccess = function () {
  128. suc(request.result || []);
  129. };
  130. });
  131. }
  132. /**
  133. * 根据主键查询对应数据
  134. * @param {string} tableName 表名
  135. * @param {string} key 主键
  136. * @returns {promise}
  137. */
  138. export function readByMainKey({ tableName, key }) {
  139. return new Promise((suc, fail) => {
  140. if (!key) {
  141. fail();
  142. return;
  143. }
  144. const objectStore = db
  145. .transaction([tableName], 'readwrite')
  146. .objectStore(tableName);
  147. const request = objectStore.get(key);
  148. request.onerror = function (event) {
  149. console.error('根据主键查询对应数据', event);
  150. fail();
  151. };
  152. request.onsuccess = function () {
  153. suc(request.result || {});
  154. };
  155. });
  156. }
  157. /**
  158. * 根据主键删除对应数据
  159. * @param {string} tableName 表名
  160. * @param {string} key 主键
  161. * @returns {promise}
  162. */
  163. export function remove({ tableName, key }) {
  164. return new Promise((suc, fail) => {
  165. const objectStore = db
  166. .transaction([tableName], 'readwrite')
  167. .objectStore(tableName);
  168. const request = objectStore.delete(key);
  169. request.onerror = function (event) {
  170. console.error('更新失败', event);
  171. fail();
  172. };
  173. request.onsuccess = function (event) {
  174. console.log('删除成功', event);
  175. suc();
  176. };
  177. });
  178. }
  179. /**
  180. * 根据主键更新对应数据
  181. * @param {object} data 对应的主键与值 和 数据
  182. * @param {string} tableName 表名
  183. * @returns {promise}
  184. */
  185. export function update({ tableName, data }) {
  186. return new Promise((suc, fail) => {
  187. const objectStore = db
  188. .transaction([tableName], 'readwrite')
  189. .objectStore(tableName);
  190. const request = objectStore.put(data);
  191. request.onerror = function (event) {
  192. console.error('更新失败', event);
  193. fail();
  194. };
  195. request.onsuccess = function (event) {
  196. console.log('更新成功', event);
  197. suc();
  198. };
  199. });
  200. }
  201. /**
  202. * 通过索引查找对应数据
  203. * @param {string} indexName 索引名称
  204. * @param {any} indexVal index 索引值
  205. * @param {string} tableName 表名
  206. * @returns {promise}
  207. */
  208. export function readByIndex({ tableName, indexName, indexVal }) {
  209. return new Promise((suc, fail) => {
  210. const objectStore = db
  211. .transaction([tableName], 'readwrite')
  212. .objectStore(tableName);
  213. // 假定新建表格的时候,对name字段建立了索引。
  214. // objectStore.createIndex('name', 'name', { unique: false });
  215. const index = objectStore.index(indexName);
  216. const request = index.get(indexVal);
  217. request.onerror = function (event) {
  218. console.log('事务失败', event);
  219. fail();
  220. };
  221. request.onsuccess = function (event) {
  222. if (request.result) {
  223. suc(request.result);
  224. } else {
  225. console.log('未获得数据记录', event);
  226. }
  227. };
  228. });
  229. }
  230. /**
  231. * 删除数据库
  232. * @param {string} DB_NAME 数据库名称
  233. * @returns
  234. */
  235. export async function deleteDB(DB_NAME) {
  236. return indexedDB.deleteDatabase(DB_NAME);
  237. }
  238. /**
  239. * 关闭数据库
  240. * @param {string} DB_NAME 数据库名称
  241. * @returns
  242. */
  243. export function closeDB(DB_NAME) {
  244. return indexedDB.close(DB_NAME);
  245. }
  246. /**
  247. * 清除表
  248. * @param {string} tableName
  249. * @returns {promise}
  250. */
  251. export function clearTable(tableName) {
  252. return new Promise((suc, fail) => {
  253. const objectStore = db
  254. .transaction([tableName], 'readwrite')
  255. .objectStore(tableName);
  256. const request = objectStore.clear();
  257. request.onerror = function (event) {
  258. console.log('事务失败', event);
  259. fail();
  260. };
  261. request.onsuccess = function (event) {
  262. console.log('清除成功', event);
  263. suc();
  264. };
  265. });
  266. }
  267. // export default {
  268. // deleteDB,
  269. // updateDB,
  270. // getDataByKey,
  271. // addData
  272. // }