BaseTable.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import Logger from "./Logger.js"
  2. const logger = new Logger('db')
  3. export default class BaseTable {
  4. constructor(dbName, dbVersion) {
  5. this.db = null
  6. this.isCreatingTable = !1
  7. this.hasCleared = !1
  8. this.dbName = dbName,
  9. this.dbVersion = dbVersion
  10. }
  11. async clearDataBase(e) {
  12. if(!this.hasCleared){
  13. e && (this.hasCleared = !0)
  14. if(!window.indexedDB.databases){
  15. return Promise.resolve()
  16. }
  17. else{
  18. return new Promise((resolve,reject)=>{
  19. const dBDeleteRequest = window.indexedDB.deleteDatabase(this.dbName);
  20. dBDeleteRequest.onsuccess = ()=>{
  21. resolve()
  22. },
  23. dBDeleteRequest.onerror = reject
  24. })
  25. }
  26. }
  27. }
  28. tableName() {
  29. throw new Error("Derived class have to override 'tableName', and set a proper table name!")
  30. }
  31. keyPath() {
  32. throw new Error("Derived class have to override 'keyPath', and set a proper index name!")
  33. }
  34. index() {
  35. throw new Error("Derived class have to override 'index', and set a proper index name!")
  36. }
  37. async checkAndOpenDatabase() {
  38. if(this.db){
  39. return Promise.resolve(this.db)
  40. }
  41. else{
  42. return new Promise((resolve,reject)=>{
  43. const timeoutId = setTimeout(()=>{
  44. logger.info("wait db to open for", 200);
  45. if(this.db){
  46. resolve(this.db);
  47. }
  48. else{
  49. resolve(this.checkAndOpenDatabase());
  50. }
  51. clearTimeout(timeoutId)
  52. }
  53. , 200);
  54. this.openDatabase(this.dbName, this.dbVersion || 1, ()=>{
  55. this.db && !this.isCreatingTable && resolve(this.db);
  56. logger.info(`successCallback called, this.db: ${!!this.db}, this.isCreatingStore: ${this.isCreatingTable}`);
  57. clearTimeout(timeoutId);
  58. }
  59. , ()=>{
  60. reject(new Error("Failed to open database!"));
  61. clearTimeout(timeoutId);
  62. }
  63. , ()=>{
  64. this.db && resolve(this.db);
  65. clearTimeout(timeoutId);
  66. logger.info(`successCallback called, this.db: ${!!this.db}, this.isCreatingStore: ${this.isCreatingTable}`);
  67. }
  68. )
  69. }
  70. )
  71. }
  72. }
  73. openDatabase(dbName, version, resolve, reject, complete) {
  74. if (this.isCreatingTable)
  75. {
  76. return;
  77. }
  78. this.isCreatingTable = !0;
  79. logger.info(dbName, version);
  80. const dBOpenRequest = window.indexedDB.open(dbName, version);
  81. const tableName = this.tableName();
  82. dBOpenRequest.onsuccess = _event=>{
  83. this.db = dBOpenRequest.result;
  84. logger.info(`IndexedDb ${dbName} is opened.`);
  85. this.db.objectStoreNames.contains(tableName) && (this.isCreatingTable = !1);
  86. resolve && resolve(_event)
  87. };
  88. dBOpenRequest.onerror = _event=>{
  89. var u;
  90. logger.error("Failed to open database", (u = _event == null ? void 0 : _event.srcElement) == null ? void 0 : u.error);
  91. this.isCreatingTable = !1;
  92. reject && reject(_event);
  93. this.clearDataBase(!0);
  94. };
  95. dBOpenRequest.onupgradeneeded = _event=>{
  96. const u = _event.target.result;
  97. const _index = this.index();
  98. logger.info(`Creating table ${tableName}.`);
  99. let h = u.objectStoreNames.contains(tableName);
  100. if (h)
  101. h = u.transaction([tableName], "readwrite").objectStore(tableName);
  102. else {
  103. const keyPath = this.keyPath();
  104. h = u.createObjectStore(tableName, {
  105. keyPath: keyPath
  106. })
  107. }
  108. _index.map(f=>{
  109. h.createIndex(f, f, {
  110. unique: !1
  111. })
  112. });
  113. this.isCreatingTable = !1;
  114. logger.info(`Table ${tableName} opened`);
  115. complete && complete(_event);
  116. };
  117. }
  118. async add(e) {
  119. const tableName = this.tableName();
  120. const promise = (await this.checkAndOpenDatabase()).transaction([tableName], "readwrite").objectStore(tableName).add(e);
  121. return new Promise(function(resolve, reject) {
  122. promise.onsuccess = l=>{
  123. resolve(l)
  124. }
  125. ,
  126. promise.onerror = l=>{
  127. var u;
  128. logger.error((u = l.srcElement) == null ? void 0 : u.error),
  129. reject(l)
  130. }
  131. }
  132. )
  133. }
  134. async put(e) {
  135. const tableName = this.tableName();
  136. const promise = (await this.checkAndOpenDatabase()).transaction([tableName], "readwrite").objectStore(tableName).put(e);
  137. return new Promise(function(resolve, reject) {
  138. promise.onsuccess = l=>{
  139. resolve(l)
  140. }
  141. ,
  142. promise.onerror = l=>{
  143. var u;
  144. logger.error("db put error", (u = l.srcElement) == null ? void 0 : u.error),
  145. reject(l)
  146. }
  147. }
  148. )
  149. }
  150. delete(e, resolve, reject) {
  151. const tableName = this.tableName();
  152. this.checkAndOpenDatabase().then(promise=>{
  153. const s = promise.transaction([tableName], "readwrite").objectStore(tableName).delete(e);
  154. s.onsuccess = resolve,
  155. s.onerror = reject
  156. }
  157. )
  158. }
  159. update() {
  160. this.checkAndOpenDatabase().then(promise=>{}
  161. )
  162. }
  163. async getAllKeys() {
  164. const tableName = this.tableName()
  165. const promise = await this.checkAndOpenDatabase();
  166. return new Promise((resolve, reject)=>{
  167. const a = promise.transaction([tableName], "readonly").objectStore(tableName).getAllKeys();
  168. a.onsuccess = s=>{
  169. resolve(s.target.result)
  170. }
  171. ,
  172. a.onerror = s=>{
  173. logger.error("db getAllKeys error", s),
  174. reject(s)
  175. }
  176. }
  177. )
  178. }
  179. async query(keyName, filesrc) {
  180. const tableName = this.tableName()
  181. const promise = await this.checkAndOpenDatabase();
  182. return new Promise((resolve, reject)=>{
  183. const u = promise.transaction([tableName], "readonly").objectStore(tableName).index(keyName).get(filesrc);
  184. u.onsuccess = function(c) {
  185. var f;
  186. const h = (f = c == null ? void 0 : c.target) == null ? void 0 : f.result;
  187. resolve && resolve(h)
  188. }
  189. ,
  190. u.onerror = c=>{
  191. logger.error("db query error", c),
  192. reject(c)
  193. }
  194. }
  195. )
  196. }
  197. async sleep(e) {
  198. return new Promise(t=>{
  199. setTimeout(()=>{
  200. t("")
  201. }
  202. , e)
  203. }
  204. )
  205. }
  206. }