2018-02-11 23:37:21 +00:00
|
|
|
/**
|
|
|
|
* @flow
|
|
|
|
* Firestore Transaction representation wrapper
|
|
|
|
*/
|
2018-03-20 16:07:37 +00:00
|
|
|
import { parseUpdateArgs } from './utils';
|
2018-02-11 23:37:21 +00:00
|
|
|
import { buildNativeMap } from './utils/serialize';
|
|
|
|
|
|
|
|
import type Firestore from './';
|
|
|
|
import type { TransactionMeta } from './TransactionHandler';
|
|
|
|
import type DocumentReference from './DocumentReference';
|
2018-02-23 03:02:17 +00:00
|
|
|
import DocumentSnapshot from './DocumentSnapshot';
|
2018-02-11 23:37:21 +00:00
|
|
|
import { getNativeModule } from '../../utils/native';
|
|
|
|
|
|
|
|
type Command = {
|
|
|
|
type: 'set' | 'update' | 'delete',
|
|
|
|
path: string,
|
2018-03-08 11:13:21 +00:00
|
|
|
data?: { [string]: any },
|
|
|
|
options?: SetOptions | {},
|
2018-02-11 23:37:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
type SetOptions = {
|
|
|
|
merge: boolean,
|
|
|
|
};
|
|
|
|
|
2018-02-23 03:02:17 +00:00
|
|
|
// TODO docs state all get requests must be made FIRST before any modifications
|
|
|
|
// TODO so need to validate that
|
|
|
|
|
2018-02-11 23:37:21 +00:00
|
|
|
/**
|
|
|
|
* @class Transaction
|
|
|
|
*/
|
|
|
|
export default class Transaction {
|
|
|
|
_pendingResult: ?any;
|
|
|
|
_firestore: Firestore;
|
|
|
|
_meta: TransactionMeta;
|
|
|
|
_commandBuffer: Array<Command>;
|
|
|
|
|
|
|
|
constructor(firestore: Firestore, meta: TransactionMeta) {
|
|
|
|
this._meta = meta;
|
|
|
|
this._commandBuffer = [];
|
|
|
|
this._firestore = firestore;
|
|
|
|
this._pendingResult = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* -------------
|
|
|
|
* INTERNAL API
|
|
|
|
* -------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears the command buffer and any pending result in prep for
|
|
|
|
* the next transaction iteration attempt.
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_prepare() {
|
|
|
|
this._commandBuffer = [];
|
|
|
|
this._pendingResult = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* -------------
|
|
|
|
* PUBLIC API
|
|
|
|
* -------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads the document referenced by the provided DocumentReference.
|
|
|
|
*
|
|
|
|
* @param documentRef DocumentReference A reference to the document to be retrieved. Value must not be null.
|
|
|
|
*
|
|
|
|
* @returns Promise<DocumentSnapshot>
|
|
|
|
*/
|
|
|
|
get(documentRef: DocumentReference): Promise<DocumentSnapshot> {
|
|
|
|
// todo validate doc ref
|
2018-02-23 03:02:17 +00:00
|
|
|
return getNativeModule(this._firestore)
|
|
|
|
.transactionGetDocument(this._meta.id, documentRef.path)
|
|
|
|
.then(result => new DocumentSnapshot(this._firestore, result));
|
2018-02-11 23:37:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Writes to the document referred to by the provided DocumentReference.
|
|
|
|
* If the document does not exist yet, it will be created. If you pass options,
|
|
|
|
* the provided data can be merged into the existing document.
|
|
|
|
*
|
|
|
|
* @param documentRef DocumentReference A reference to the document to be created. Value must not be null.
|
|
|
|
* @param data Object An object of the fields and values for the document.
|
|
|
|
* @param options SetOptions An object to configure the set behavior.
|
|
|
|
* Pass {merge: true} to only replace the values specified in the data argument.
|
|
|
|
* Fields omitted will remain untouched.
|
|
|
|
*
|
|
|
|
* @returns {Transaction}
|
|
|
|
*/
|
|
|
|
set(
|
|
|
|
documentRef: DocumentReference,
|
|
|
|
data: Object,
|
|
|
|
options?: SetOptions
|
|
|
|
): Transaction {
|
|
|
|
// todo validate doc ref
|
|
|
|
// todo validate data is object
|
|
|
|
this._commandBuffer.push({
|
|
|
|
type: 'set',
|
|
|
|
path: documentRef.path,
|
|
|
|
data: buildNativeMap(data),
|
2018-02-23 03:02:17 +00:00
|
|
|
options: options || {},
|
2018-02-11 23:37:21 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates fields in the document referred to by this DocumentReference.
|
|
|
|
* The update will fail if applied to a document that does not exist. Nested
|
|
|
|
* fields can be updated by providing dot-separated field path strings or by providing FieldPath objects.
|
|
|
|
*
|
|
|
|
* @param documentRef DocumentReference A reference to the document to be updated. Value must not be null.
|
|
|
|
* @param args any Either an object containing all of the fields and values to update,
|
|
|
|
* or a series of arguments alternating between fields (as string or FieldPath
|
|
|
|
* objects) and values.
|
|
|
|
*
|
|
|
|
* @returns {Transaction}
|
|
|
|
*/
|
|
|
|
update(documentRef: DocumentReference, ...args: Array<any>): Transaction {
|
|
|
|
// todo validate doc ref
|
2018-03-20 16:07:37 +00:00
|
|
|
const data = parseUpdateArgs(args, 'Transaction.update');
|
2018-02-11 23:37:21 +00:00
|
|
|
this._commandBuffer.push({
|
|
|
|
type: 'update',
|
|
|
|
path: documentRef.path,
|
|
|
|
data: buildNativeMap(data),
|
|
|
|
});
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deletes the document referred to by the provided DocumentReference.
|
|
|
|
*
|
|
|
|
* @param documentRef DocumentReference A reference to the document to be deleted. Value must not be null.
|
|
|
|
*
|
|
|
|
* @returns {Transaction}
|
|
|
|
*/
|
|
|
|
delete(documentRef: DocumentReference): Transaction {
|
|
|
|
// todo validate doc ref
|
|
|
|
this._commandBuffer.push({
|
|
|
|
type: 'delete',
|
|
|
|
path: documentRef.path,
|
|
|
|
});
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
}
|