Skip to content

WIP Remove Mutation types from Lite SDK #3327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changeset/serious-tables-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
12 changes: 8 additions & 4 deletions packages/firestore/exp/src/api/reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import * as firestore from '../../index';
import { Firestore } from './database';
import {
DocumentKeyReference,
ParsedUpdateData
ParsedUpdateData,
convertSetToMutations,
convertUpdateToMutations
} from '../../../src/api/user_data_reader';
import { debugAssert } from '../../../src/util/assert';
import { cast } from '../../../lite/src/api/util';
Expand Down Expand Up @@ -185,7 +187,9 @@ export function setDoc<T>(
return firestore
._getFirestoreClient()
.then(firestoreClient =>
firestoreClient.write(parsed.toMutations(ref._key, Precondition.none()))
firestoreClient.write(
convertSetToMutations(parsed, ref._key, Precondition.none())
)
);
}

Expand Down Expand Up @@ -233,7 +237,7 @@ export function updateDoc(
._getFirestoreClient()
.then(firestoreClient =>
firestoreClient.write(
parsed.toMutations(ref._key, Precondition.exists(true))
convertUpdateToMutations(parsed, ref._key, Precondition.exists(true))
)
);
}
Expand Down Expand Up @@ -272,7 +276,7 @@ export function addDoc<T>(
._getFirestoreClient()
.then(firestoreClient =>
firestoreClient.write(
parsed.toMutations(docRef._key, Precondition.exists(false))
convertSetToMutations(parsed, docRef._key, Precondition.exists(false))
)
)
.then(() => docRef);
Expand Down
141 changes: 135 additions & 6 deletions packages/firestore/exp/src/api/write_batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,145 @@
import * as firestore from '../../index';

import { cast } from '../../../lite/src/api/util';
import { WriteBatch } from '../../../lite/src/api/write_batch';
import { Firestore } from './database';
import {
DeleteMutation,
Mutation,
Precondition
} from '../../../src/model/mutation';
import { Code, FirestoreError } from '../../../src/util/error';
import { applyFirestoreDataConverter } from '../../../src/api/database';
import {
convertSetToMutations,
convertUpdateToMutations,
UserDataReader
} from '../../../src/api/user_data_reader';
import { newUserDataReader } from '../../../lite/src/api/reference';
import { FieldPath } from '../../../lite/src/api/field_path';
import { validateReference } from '../../../lite/src/api/write_batch';

export class WriteBatch implements firestore.WriteBatch {
private readonly _dataReader: UserDataReader;
private _mutations = [] as Mutation[];
private _committed = false;

constructor(private readonly _firestore: Firestore) {
this._dataReader = newUserDataReader(_firestore);
}

set<T>(documentRef: firestore.DocumentReference<T>, value: T): WriteBatch;
set<T>(
documentRef: firestore.DocumentReference<T>,
value: Partial<T>,
options: firestore.SetOptions
): WriteBatch;
set<T>(
documentRef: firestore.DocumentReference<T>,
value: T,
options?: firestore.SetOptions
): WriteBatch {
this.verifyNotCommitted();
const ref = validateReference(documentRef, this._firestore);

const convertedValue = applyFirestoreDataConverter(
ref._converter,
value,
options
);
const parsed = this._dataReader.parseSetData(
'WriteBatch.set',
ref._key,
convertedValue,
ref._converter !== null,
options
);
this._mutations = this._mutations.concat(
convertSetToMutations(parsed, ref._key, Precondition.none())
);
return this;
}

update(
documentRef: firestore.DocumentReference<unknown>,
value: firestore.UpdateData
): WriteBatch;
update(
documentRef: firestore.DocumentReference<unknown>,
field: string | firestore.FieldPath,
value: unknown,
...moreFieldsAndValues: unknown[]
): WriteBatch;
update(
documentRef: firestore.DocumentReference<unknown>,
fieldOrUpdateData: string | firestore.FieldPath | firestore.UpdateData,
value?: unknown,
...moreFieldsAndValues: unknown[]
): WriteBatch {
this.verifyNotCommitted();
const ref = validateReference(documentRef, this._firestore);

let parsed;

if (
typeof fieldOrUpdateData === 'string' ||
fieldOrUpdateData instanceof FieldPath
) {
parsed = this._dataReader.parseUpdateVarargs(
'WriteBatch.update',
ref._key,
fieldOrUpdateData,
value,
moreFieldsAndValues
);
} else {
parsed = this._dataReader.parseUpdateData(
'WriteBatch.update',
ref._key,
fieldOrUpdateData
);
}

this._mutations = this._mutations.concat(
convertUpdateToMutations(parsed, ref._key, Precondition.exists(true))
);
return this;
}

delete(documentRef: firestore.DocumentReference<unknown>): WriteBatch {
this.verifyNotCommitted();
const ref = validateReference(documentRef, this._firestore);
this._mutations = this._mutations.concat(
new DeleteMutation(ref._key, Precondition.none())
);
return this;
}

commit(): Promise<void> {
this.verifyNotCommitted();
this._committed = true;
if (this._mutations.length > 0) {
return this._firestore
._getFirestoreClient()
.then(firestoreClient => firestoreClient.write(this._mutations));
}

return Promise.resolve();
}

private verifyNotCommitted(): void {
if (this._committed) {
throw new FirestoreError(
Code.FAILED_PRECONDITION,
'A write batch can no longer be used after commit() ' +
'has been called.'
);
}
}
}

export function writeBatch(
firestore: firestore.FirebaseFirestore
): firestore.WriteBatch {
const firestoreImpl = cast(firestore, Firestore);
return new WriteBatch(firestoreImpl, writes =>
firestoreImpl
._getFirestoreClient()
.then(firestoreClient => firestoreClient.write(writes))
);
return new WriteBatch(firestoreImpl);
}
38 changes: 30 additions & 8 deletions packages/firestore/lite/src/api/reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import { Firestore } from './database';
import {
DocumentKeyReference,
ParsedUpdateData,
UserDataReader
convertSetToWrites,
convertUpdateToWrites,
UserDataReader,
convertDeleteToWrite
} from '../../../src/api/user_data_reader';
import {
Bound,
Expand All @@ -35,17 +38,17 @@ import { ResourcePath } from '../../../src/model/path';
import { AutoId } from '../../../src/util/misc';
import {
DocumentSnapshot,
fieldPathFromArgument,
QueryDocumentSnapshot,
QuerySnapshot,
fieldPathFromArgument
QuerySnapshot
} from './snapshot';
import {
invokeBatchGetDocumentsRpc,
invokeCommitRpc,
invokeRunQueryRpc
} from '../../../src/remote/datastore';
import { hardAssert } from '../../../src/util/assert';
import { DeleteMutation, Precondition } from '../../../src/model/mutation';
import { Precondition } from '../../../src/model/mutation';
import {
applyFirestoreDataConverter,
BaseQuery,
Expand Down Expand Up @@ -477,7 +480,12 @@ export function setDoc<T>(
.then(datastore =>
invokeCommitRpc(
datastore,
parsed.toMutations(ref._key, Precondition.none())
convertSetToWrites(
parsed,
datastore.serializer,
ref._key,
Precondition.none()
)
)
);
}
Expand Down Expand Up @@ -526,7 +534,12 @@ export function updateDoc(
.then(datastore =>
invokeCommitRpc(
datastore,
parsed.toMutations(ref._key, Precondition.exists(true))
convertUpdateToWrites(
parsed,
datastore.serializer,
ref._key,
Precondition.exists(true)
)
)
);
}
Expand All @@ -539,7 +552,11 @@ export function deleteDoc(
._getDatastore()
.then(datastore =>
invokeCommitRpc(datastore, [
new DeleteMutation(ref._key, Precondition.none())
convertDeleteToWrite(
datastore.serializer,
ref._key,
Precondition.none()
)
])
);
}
Expand Down Expand Up @@ -567,7 +584,12 @@ export function addDoc<T>(
.then(datastore =>
invokeCommitRpc(
datastore,
parsed.toMutations(docRef._key, Precondition.exists(false))
convertSetToWrites(
parsed,
datastore.serializer,
docRef._key,
Precondition.exists(false)
)
)
)
.then(() => docRef);
Expand Down
55 changes: 32 additions & 23 deletions packages/firestore/lite/src/api/write_batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as api from '../../../src/protos/firestore_proto_api';

import * as firestore from '../../index';
import {
DeleteMutation,
Mutation,
Precondition
} from '../../../src/model/mutation';
import { Precondition } from '../../../src/model/mutation';
import { Code, FirestoreError } from '../../../src/util/error';
import { applyFirestoreDataConverter } from '../../../src/api/database';
import {
DocumentKeyReference,
convertDeleteToWrite,
convertSetToWrites,
convertUpdateToWrites,
UserDataReader
} from '../../../src/api/user_data_reader';
import { cast } from './util';
import { DocumentReference, newUserDataReader } from './reference';
import { Firestore } from './database';
import { invokeCommitRpc } from '../../../src/remote/datastore';
import { FieldPath } from './field_path';
import { JsonProtoSerializer } from '../../../src/remote/serializer';
import { newSerializer } from '../../../src/platform/serializer';

export class WriteBatch implements firestore.WriteBatch {
// This is the lite version of the WriteBatch API used in the legacy SDK. The
// class is a close copy but takes different input types.

private readonly _dataReader: UserDataReader;
private _mutations = [] as Mutation[];
private readonly _serializer: JsonProtoSerializer;
private _writes = [] as api.Write[];
private _committed = false;

constructor(
private readonly _firestore: Firestore,
private readonly _commitHandler: (m: Mutation[]) => Promise<void>
) {
constructor(private readonly _firestore: Firestore) {
this._dataReader = newUserDataReader(_firestore);
this._serializer = newSerializer(_firestore._databaseId);
}

set<T>(documentRef: firestore.DocumentReference<T>, value: T): WriteBatch;
Expand Down Expand Up @@ -74,8 +75,13 @@ export class WriteBatch implements firestore.WriteBatch {
ref._converter !== null,
options
);
this._mutations = this._mutations.concat(
parsed.toMutations(ref._key, Precondition.none())
this._writes = this._writes.concat(
convertSetToWrites(
parsed,
this._serializer,
ref._key,
Precondition.none()
)
);
return this;
}
Expand Down Expand Up @@ -120,26 +126,33 @@ export class WriteBatch implements firestore.WriteBatch {
);
}

this._mutations = this._mutations.concat(
parsed.toMutations(ref._key, Precondition.exists(true))
this._writes = this._writes.concat(
convertUpdateToWrites(
parsed,
this._serializer,
ref._key,
Precondition.exists(true)
)
);
return this;
}

delete(documentRef: firestore.DocumentReference<unknown>): WriteBatch {
this.verifyNotCommitted();
const ref = validateReference(documentRef, this._firestore);
this._mutations = this._mutations.concat(
new DeleteMutation(ref._key, Precondition.none())
this._writes = this._writes.concat(
convertDeleteToWrite(this._serializer, ref._key, Precondition.none())
);
return this;
}

commit(): Promise<void> {
this.verifyNotCommitted();
this._committed = true;
if (this._mutations.length > 0) {
return this._commitHandler(this._mutations);
if (this._writes.length > 0) {
return this._firestore
._getDatastore()
.then(datastore => invokeCommitRpc(datastore, this._writes));
}

return Promise.resolve();
Expand Down Expand Up @@ -174,9 +187,5 @@ export function writeBatch(
firestore: firestore.FirebaseFirestore
): firestore.WriteBatch {
const firestoreImpl = cast(firestore, Firestore);
return new WriteBatch(firestoreImpl, writes =>
firestoreImpl
._getDatastore()
.then(datastore => invokeCommitRpc(datastore, writes))
);
return new WriteBatch(firestoreImpl);
}
Loading