1 | /* |
2 | Copyright - 2017 2023 - wwwouaiebe - Contact: https://www.ouaie.be/ |
3 | |
4 | This program is free software; |
5 | you can redistribute it and/or modify it under the terms of the |
6 | GNU General Public License as published by the Free Software Foundation; |
7 | either version 3 of the License, or any later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | /* |
19 | Changes: |
20 | - v4.0.0: |
21 | - created from v3.6.0 |
22 | Doc reviewed 202208 |
23 | */ |
24 | |
25 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
26 | /** |
27 | This class contains methods for accessing the window.indexedDb. |
28 | See theIndexedDb for the one and only one instance of this class |
29 | */ |
30 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
31 | |
32 | class IndexedDb { |
33 | |
34 | /** |
35 | A reference to the opened indexedDB |
36 | @type {IDBFactory} |
37 | */ |
38 | |
39 | #indexedDb; |
40 | |
41 | /** |
42 | The UUID of the current travel |
43 | @type {String} |
44 | */ |
45 | |
46 | #UUID; |
47 | |
48 | /** |
49 | A temp variable used to store the data to write in the indexedDb |
50 | @type {String} |
51 | */ |
52 | |
53 | #data; |
54 | |
55 | /** |
56 | The version of the db to use |
57 | @type {Number} |
58 | */ |
59 | |
60 | // eslint-disable-next-line no-magic-numbers |
61 | static get #DB_VERSION ( ) { return 1; } |
62 | |
63 | /** |
64 | Perform the open operations |
65 | @param {function} onOk the Ok handler for the Promise |
66 | @param {function} onError the error handler for the Promise |
67 | */ |
68 | |
69 | #open ( onOk, onError ) { |
70 | if ( this.#indexedDb ) { |
71 | onOk ( ); |
72 | return; |
73 | } |
74 | const openRequest = window.indexedDB.open ( 'TravelNotesDb', IndexedDb.#DB_VERSION ); |
75 | openRequest.onerror = ( ) => { |
76 | this.#indexedDb = null; |
77 | onError ( new Error ( 'Not possible to open the db' ) ); |
78 | }; |
79 | openRequest.onsuccess = successEvent => { |
80 | this.#indexedDb = successEvent.target.result; |
81 | onOk ( ); |
82 | }; |
83 | openRequest.onupgradeneeded = upgradeEvent => { |
84 | this.#indexedDb = upgradeEvent.target.result; |
85 | this.#indexedDb.createObjectStore ( 'Travels', { keyPath : 'UUID' } ); |
86 | }; |
87 | } |
88 | |
89 | /** |
90 | Perform the read operations |
91 | @param {function} onOk the Ok handler for the Promise |
92 | @param {function} onError the error handler for the Promise |
93 | */ |
94 | |
95 | #read ( onOk, onError ) { |
96 | if ( ! this.#indexedDb ) { |
97 | onError ( new Error ( 'Database not opened' ) ); |
98 | return; |
99 | } |
100 | const transaction = this.#indexedDb.transaction ( [ 'Travels' ], 'readonly' ); |
101 | transaction.onerror = ( ) => onError ( new Error ( 'Transaction error' ) ); |
102 | |
103 | const travelsObjectStore = transaction.objectStore ( 'Travels' ); |
104 | const getRequest = travelsObjectStore.get ( this.#UUID ); |
105 | getRequest.onsuccess = successEvent => onOk ( successEvent.target.result ? successEvent.target.result.data : null ); |
106 | } |
107 | |
108 | /** |
109 | Perform the write operations |
110 | @param {function} onOk the Ok handler for the Promise |
111 | @param {function} onError the error handler for the Promise |
112 | */ |
113 | |
114 | #write ( onOk, onError ) { |
115 | if ( ! this.#indexedDb ) { |
116 | onError ( new Error ( 'Database not opened' ) ); |
117 | return; |
118 | } |
119 | const transaction = this.#indexedDb.transaction ( [ 'Travels' ], 'readwrite' ); |
120 | transaction.onerror = ( ) => onError ( new Error ( 'Transaction error' ) ); |
121 | const travelsObjectStore = transaction.objectStore ( 'Travels' ); |
122 | const putRequest = travelsObjectStore.put ( { UUID : this.#UUID, data : this.#data } ); |
123 | putRequest.onsuccess = ( ) => onOk ( ); |
124 | } |
125 | |
126 | /** |
127 | Perform the close operations |
128 | */ |
129 | |
130 | #close ( ) { |
131 | this.#indexedDb.close ( ); |
132 | this.#indexedDb = null; |
133 | } |
134 | |
135 | /** |
136 | constructor |
137 | */ |
138 | |
139 | constructor ( ) { |
140 | Object.freeze ( this ); |
141 | } |
142 | |
143 | /** |
144 | Open the indexedDb |
145 | @return {Promise} A Promise that fullfil when the indexedDb is opened or reject when a problem occurs |
146 | */ |
147 | |
148 | getOpenPromise ( ) { |
149 | return new Promise ( ( onOk, onError ) => this.#open ( onOk, onError ) ); |
150 | } |
151 | |
152 | /** |
153 | Read data in the indexedDb. |
154 | @param {String} UUID An UUID used to identify the data in the indexedDb |
155 | @return {Promise} A promise that fullfil when the data are read or reject when a problem occurs |
156 | The success handler receive the data as parameter |
157 | */ |
158 | |
159 | getReadPromise ( UUID ) { |
160 | this.#UUID = UUID; |
161 | return new Promise ( ( onOk, onError ) => this.#read ( onOk, onError ) ); |
162 | } |
163 | |
164 | /** |
165 | Write data in the indexedDb. |
166 | @param {String} UUID An UUID used to identify the data in the indexedDb |
167 | @param {String} data The data to put in the indexedDb |
168 | @return {Promise} A promise that fullfil when the data are written or reject when a problem occurs |
169 | */ |
170 | |
171 | getWritePromise ( UUID, data ) { |
172 | this.#UUID = UUID; |
173 | this.#data = data; |
174 | |
175 | return new Promise ( ( onOk, onError ) => this.#write ( onOk, onError ) ); |
176 | } |
177 | |
178 | /** |
179 | Remove the data in the indexedDb and close it |
180 | @param {String} UUID An UUID used to identify the data in the indexedDb |
181 | */ |
182 | |
183 | closeDb ( UUID ) { |
184 | if ( ! this.#indexedDb ) { |
185 | return; |
186 | } |
187 | if ( ! UUID ) { |
188 | this.#close ( ); |
189 | return; |
190 | } |
191 | |
192 | const transaction = this.#indexedDb.transaction ( [ 'Travels' ], 'readwrite' ); |
193 | transaction.onerror = ( ) => { }; |
194 | const travelsObjectStore = transaction.objectStore ( 'Travels' ); |
195 | |
196 | const deleteRequest = travelsObjectStore.delete ( UUID ); |
197 | deleteRequest.onerror = ( ) => this.#close ( ); |
198 | deleteRequest.onsuccess = ( ) => this.#close ( ); |
199 | } |
200 | } |
201 | |
202 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
203 | /** |
204 | The one and only one instance of IndexedDb class |
205 | @type {IndexedDb} |
206 | */ |
207 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
208 | |
209 | const theIndexedDb = new IndexedDb ( ); |
210 | |
211 | export default theIndexedDb; |
212 | |
213 | /* --- End of file --------------------------------------------------------------------------------------------------------- */ |
214 |