-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
transaction.dart
111 lines (95 loc) 路 3.44 KB
/
transaction.dart
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2020, the Chromium project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of cloud_firestore;
/// The [TransactionHandler] may be executed multiple times; it should be able
/// to handle multiple executions.
typedef TransactionHandler<T> = Future<T> Function(Transaction transaction);
/// Transaction class which is created from a call to [runTransaction()].
class Transaction {
final FirebaseFirestore _firestore;
final TransactionPlatform _delegate;
Transaction._(this._firestore, this._delegate) {
TransactionPlatform.verify(_delegate);
}
/// Reads the document referenced by the provided [DocumentReference].
///
/// If the document changes whilst the transaction is in progress, it will
/// be re-tried up to five times.
Future<DocumentSnapshot<T>> get<T extends Object?>(
DocumentReference<T> documentReference,
) async {
DocumentSnapshotPlatform documentSnapshotPlatform =
await _delegate.get(documentReference.path);
final snapshot =
_JsonDocumentSnapshot(_firestore, documentSnapshotPlatform);
if (snapshot is DocumentSnapshot<T>) {
return snapshot as DocumentSnapshot<T>;
}
final withConverterDocRef =
documentReference as _WithConverterDocumentReference<T>;
return _WithConverterDocumentSnapshot<T>(
snapshot,
withConverterDocRef._fromFirestore,
withConverterDocRef._toFirestore,
);
}
/// Deletes the document referred to by the provided [documentReference].
Transaction delete(DocumentReference documentReference) {
assert(
documentReference.firestore == _firestore,
'the document provided is from a different Firestore instance',
);
return Transaction._(
_firestore,
_delegate.delete(documentReference.path),
);
}
/// Updates fields in the document referred to by [documentReference].
/// The update will fail if applied to a document that does not exist.
Transaction update(
DocumentReference documentReference,
Map<String, dynamic> data,
) {
assert(
documentReference.firestore == _firestore,
'the document provided is from a different Firestore instance',
);
return Transaction._(
_firestore,
_delegate.update(
documentReference.path,
_CodecUtility.replaceValueWithDelegatesInMap(data)!,
),
);
}
/// Writes to the document referred to by the provided [DocumentReference].
/// If the document does not exist yet, it will be created. If you pass
/// [SetOptions], the provided data can be merged into the existing document.
Transaction set<T>(
DocumentReference<T> documentReference,
T data, [
SetOptions? options,
]) {
assert(
documentReference.firestore == _firestore,
'the document provided is from a different Firestore instance',
);
Map<String, dynamic> firestoreData;
if (documentReference is _JsonDocumentReference) {
firestoreData = data as Map<String, dynamic>;
} else {
final withConverterDoc =
documentReference as _WithConverterDocumentReference<T>;
firestoreData = withConverterDoc._toFirestore(data, options);
}
return Transaction._(
_firestore,
_delegate.set(
documentReference.path,
_CodecUtility.replaceValueWithDelegatesInMap(firestoreData)!,
options,
),
);
}
}