/
temp-transaction.ts
54 lines (53 loc) · 2.54 KB
/
temp-transaction.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { PSD, rejection, newScope } from "../helpers/promise";
import { DexieOptions } from "../public/types/dexie-constructor";
import { exceptions } from "../errors";
import { nop } from "./chaining-functions";
import { Transaction } from "../classes/transaction";
import { Dexie } from '../classes/dexie';
/* Generate a temporary transaction when db operations are done outside a transaction scope.
*/
export function tempTransaction (
db: Dexie,
mode: IDBTransactionMode,
storeNames: string[],
fn: (resolve, reject, trans: Transaction) => any)
// Last argument is "writeLocked". But this doesnt apply to oneshot direct db operations, so we ignore it.
{
if (!db.idbdb || (!db._state.openComplete && (!PSD.letThrough && !db._vip))) {
if (db._state.openComplete) {
// db.idbdb is falsy but openComplete is true. Must have been an exception durin open.
// Don't wait for openComplete as it would lead to infinite loop.
return rejection(new exceptions.DatabaseClosed(db._state.dbOpenError));
}
if (!db._state.isBeingOpened) {
if (!db._options.autoOpen)
return rejection(new exceptions.DatabaseClosed());
db.open().catch(nop); // Open in background. If if fails, it will be catched by the final promise anyway.
}
return db._state.dbReadyPromise.then(() => tempTransaction(db, mode, storeNames, fn));
} else {
var trans = db._createTransaction(mode, storeNames, db._dbSchema);
try { trans.create(); } catch (ex) { return rejection(ex); }
return trans._promise(mode, (resolve, reject) => {
return newScope(() => { // OPTIMIZATION POSSIBLE? newScope() not needed because it's already done in _promise.
PSD.trans = trans;
return fn(resolve, reject, trans);
});
}).then(result => {
// Instead of resolving value directly, wait with resolving it until transaction has completed.
// Otherwise the data would not be in the DB if requesting it in the then() operation.
// Specifically, to ensure that the following expression will work:
//
// db.friends.put({name: "Arne"}).then(function () {
// db.friends.where("name").equals("Arne").count(function(count) {
// assert (count === 1);
// });
// });
//
return trans._completion.then(() => result);
});/*.catch(err => { // Don't do this as of now. If would affect bulk- and modify methods in a way that could be more intuitive. But wait! Maybe change in next major.
trans._reject(err);
return rejection(err);
});*/
}
}