blob: 9b7af86554ce687c1789726f35e093378f4901fb [file] [log] [blame]
// Copyright 2018, 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;
/// A [WriteBatch] is a series of write operations to be performed as one unit.
///
/// Operations done on a [WriteBatch] do not take effect until you [commit].
///
/// Once committed, no further operations can be performed on the [WriteBatch],
/// nor can it be committed again.
class WriteBatch {
WriteBatch._(this._firestore)
: _handle = Firestore.channel.invokeMethod(
'WriteBatch#create', <String, dynamic>{'app': _firestore.app.name});
final Firestore _firestore;
Future<dynamic> _handle;
final List<Future<dynamic>> _actions = <Future<dynamic>>[];
/// Indicator to whether or not this [WriteBatch] has been committed.
bool _committed = false;
/// Commits all of the writes in this write batch as a single atomic unit.
///
/// Calling this method prevents any future operations from being added.
Future<Null> commit() async {
if (!_committed) {
_committed = true;
await Future.wait<dynamic>(_actions);
return await Firestore.channel.invokeMethod(
'WriteBatch#commit', <String, dynamic>{'handle': await _handle});
} else {
throw new StateError("This batch has already been committed.");
}
}
/// Deletes the document referred to by [document].
void delete(DocumentReference document) {
if (!_committed) {
_handle.then((dynamic handle) {
_actions.add(
Firestore.channel.invokeMethod(
'WriteBatch#delete',
<String, dynamic>{
'app': _firestore.app.name,
'handle': handle,
'path': document.path,
},
),
);
});
} else {
throw new StateError(
"This batch has been committed and can no longer be changed.");
}
}
/// Writes to the document referred to by [document].
///
/// If the document does not yet exist, it will be created.
///
/// If [merge] is true, the provided data will be merged into an
/// existing document instead of overwriting.
void setData(DocumentReference document, Map<String, dynamic> data,
{bool merge: false}) {
if (!_committed) {
_handle.then((dynamic handle) {
_actions.add(
Firestore.channel.invokeMethod(
'WriteBatch#setData',
<String, dynamic>{
'app': _firestore.app.name,
'handle': handle,
'path': document.path,
'data': data,
'options': <String, bool>{'merge': merge},
},
),
);
});
} else {
throw new StateError(
"This batch has been committed and can no longer be changed.");
}
}
/// Updates fields in the document referred to by [document].
///
/// If the document does not exist, the operation will fail.
void updateData(DocumentReference document, Map<String, dynamic> data) {
if (!_committed) {
_handle.then((dynamic handle) {
_actions.add(
Firestore.channel.invokeMethod(
'WriteBatch#updateData',
<String, dynamic>{
'app': _firestore.app.name,
'handle': handle,
'path': document.path,
'data': data,
},
),
);
});
} else {
throw new StateError(
"This batch has been committed and can no longer be changed.");
}
}
}