@@ -67,10 +67,12 @@ export class InMemoryProvider extends DbProvider {
67
67
68
68
private _lockHelper : TransactionLockHelper | undefined ;
69
69
private readonly _mapType ?: OrderedMapType ;
70
+ private readonly _supportsRollback ?: boolean ;
70
71
71
- constructor ( mapType ?: OrderedMapType ) {
72
+ constructor ( mapType ?: OrderedMapType , supportsRollback = false ) {
72
73
super ( ) ;
73
74
this . _mapType = mapType ;
75
+ this . _supportsRollback = supportsRollback ;
74
76
}
75
77
76
78
open (
@@ -105,7 +107,13 @@ export class InMemoryProvider extends DbProvider {
105
107
) : Promise < DbTransaction > {
106
108
return this . _lockHelper ! ! ! . openTransaction ( storeNames , writeNeeded ) . then (
107
109
( token : any ) =>
108
- new InMemoryTransaction ( this , this . _lockHelper ! ! ! , token , writeNeeded )
110
+ new InMemoryTransaction (
111
+ this ,
112
+ this . _lockHelper ! ! ! ,
113
+ token ,
114
+ writeNeeded ,
115
+ this . _supportsRollback !
116
+ )
109
117
) ;
110
118
}
111
119
@@ -128,19 +136,20 @@ class InMemoryTransaction implements DbTransaction {
128
136
private _prov : InMemoryProvider ,
129
137
private _lockHelper : TransactionLockHelper ,
130
138
private _transToken : TransactionToken ,
131
- writeNeeded : boolean
139
+ private _writeNeeded : boolean ,
140
+ private _supportsRollback : boolean
132
141
) {
133
142
// Close the transaction on the next tick. By definition, anything is completed synchronously here, so after an event tick
134
143
// goes by, there can't have been anything pending.
135
- if ( writeNeeded ) {
144
+ if ( this . _writeNeeded ) {
136
145
this . _openTimer = setTimeout ( ( ) => {
137
146
this . _openTimer = undefined ;
138
147
this . _commitTransaction ( ) ;
139
148
this . _lockHelper . transactionComplete ( this . _transToken ) ;
140
149
} , 0 ) as any as number ;
141
150
} else {
151
+ // read-only
142
152
this . _openTimer = undefined ;
143
- this . _commitTransaction ( ) ;
144
153
this . _lockHelper . transactionComplete ( this . _transToken ) ;
145
154
}
146
155
}
@@ -156,6 +165,11 @@ class InMemoryTransaction implements DbTransaction {
156
165
}
157
166
158
167
abort ( ) : void {
168
+ if ( ! this . _supportsRollback ) {
169
+ throw new Error (
170
+ "Unable to abort transaction since provider doesn't support rollback"
171
+ ) ;
172
+ }
159
173
this . _stores . forEach ( ( store ) => {
160
174
store . internal_rollbackPendingData ( ) ;
161
175
} ) ;
@@ -188,7 +202,11 @@ class InMemoryTransaction implements DbTransaction {
188
202
if ( ! store ) {
189
203
throw new Error ( "Store not found: " + storeName ) ;
190
204
}
191
- const ims = new InMemoryStore ( this , store ) ;
205
+ const ims = new InMemoryStore (
206
+ this ,
207
+ store ,
208
+ this . _writeNeeded && this . _supportsRollback
209
+ ) ;
192
210
this . _stores . set ( storeName , ims ) ;
193
211
return ims ;
194
212
}
@@ -199,27 +217,40 @@ class InMemoryTransaction implements DbTransaction {
199
217
}
200
218
201
219
class InMemoryStore implements DbStore {
202
- private _committedStoreData : Map < string , ItemType > ;
220
+ private _committedStoreData ? : Map < string , ItemType > ;
203
221
private _mergedData : Map < string , ItemType > ;
204
222
private _storeSchema : StoreSchema ;
205
223
private _indices : Map < string , InMemoryIndex > ;
206
224
private _mapType ?: OrderedMapType ;
207
- constructor ( private _trans : InMemoryTransaction , storeInfo : StoreData ) {
225
+ constructor (
226
+ private _trans : InMemoryTransaction ,
227
+ storeInfo : StoreData ,
228
+ private _supportsRollback : boolean
229
+ ) {
208
230
this . _storeSchema = storeInfo . schema ;
209
- this . _committedStoreData = new Map ( storeInfo . data ) ;
231
+ if ( this . _supportsRollback ) {
232
+ this . _committedStoreData = new Map ( storeInfo . data ) ;
233
+ }
210
234
this . _indices = storeInfo . indices ;
211
235
this . _mergedData = storeInfo . data ;
212
236
this . _mapType = storeInfo . mapType ;
213
237
}
214
238
215
239
internal_commitPendingData ( ) : void {
216
- this . _committedStoreData = new Map ( this . _mergedData ) ;
240
+ if ( this . _supportsRollback ) {
241
+ this . _committedStoreData = new Map ( this . _mergedData ) ;
242
+ }
217
243
// Indices were already updated, theres no need to update them now.
218
244
}
219
245
220
246
internal_rollbackPendingData ( ) : void {
247
+ if ( ! this . _supportsRollback ) {
248
+ throw new Error (
249
+ "Unable to rollback since InMemoryStore was created with supportsRollback = false"
250
+ ) ;
251
+ }
221
252
this . _mergedData . clear ( ) ;
222
- this . _committedStoreData . forEach ( ( val , key ) => {
253
+ this . _committedStoreData ? .forEach ( ( val , key ) => {
223
254
this . _mergedData . set ( key , val ) ;
224
255
} ) ;
225
256
// Recreate all indexes on a roll back.
0 commit comments