Skip to content

Commit 4fc524d

Browse files
Compat class for WriteBatch
1 parent f676f67 commit 4fc524d

File tree

6 files changed

+69
-161
lines changed

6 files changed

+69
-161
lines changed

packages/firestore/exp/src/api/write_batch.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { FirebaseFirestore } from './database';
2020
import { executeWrite } from './reference';
2121
import { ensureFirestoreConfigured } from '../../../src/api/database';
2222

23+
export { WriteBatch };
24+
2325
/**
2426
* Creates a write batch, used for performing multiple writes as a single
2527
* atomic operation. The maximum number of writes allowed in a single WriteBatch

packages/firestore/exp/test/shim.ts

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -127,63 +127,6 @@ export class Transaction
127127
}
128128
}
129129

130-
export class WriteBatch
131-
extends Compat<exp.WriteBatch>
132-
implements legacy.WriteBatch {
133-
set<T>(
134-
documentRef: DocumentReference<T>,
135-
data: T,
136-
options?: legacy.SetOptions
137-
): WriteBatch {
138-
if (options) {
139-
validateSetOptions('WriteBatch.set', options);
140-
this._delegate.set(documentRef._delegate, unwrap(data), options);
141-
} else {
142-
this._delegate.set(documentRef._delegate, unwrap(data));
143-
}
144-
return this;
145-
}
146-
147-
update(
148-
documentRef: DocumentReference<any>,
149-
data: legacy.UpdateData
150-
): WriteBatch;
151-
update(
152-
documentRef: DocumentReference<any>,
153-
field: string | FieldPath,
154-
value: any,
155-
...moreFieldsAndValues: any[]
156-
): WriteBatch;
157-
update(
158-
documentRef: DocumentReference<any>,
159-
dataOrField: any,
160-
value?: any,
161-
...moreFieldsAndValues: any[]
162-
): WriteBatch {
163-
if (arguments.length === 2) {
164-
this._delegate.update(documentRef._delegate, unwrap(dataOrField));
165-
} else {
166-
this._delegate.update(
167-
documentRef._delegate,
168-
unwrap(dataOrField),
169-
unwrap(value),
170-
...unwrap(moreFieldsAndValues)
171-
);
172-
}
173-
174-
return this;
175-
}
176-
177-
delete(documentRef: DocumentReference<any>): WriteBatch {
178-
this._delegate.delete(documentRef._delegate);
179-
return this;
180-
}
181-
182-
commit(): Promise<void> {
183-
return this._delegate.commit();
184-
}
185-
}
186-
187130
export class DocumentSnapshot<T = legacy.DocumentData>
188131
extends Compat<exp.DocumentSnapshot<T>>
189132
implements legacy.DocumentSnapshot<T> {

packages/firestore/lite/src/api/reference.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import {
7878
import { newSerializer } from '../../../src/platform/serializer';
7979
import { Code, FirestoreError } from '../../../src/util/error';
8080
import { getDatastore } from './components';
81+
import { Compat } from '../../../src/compat/compat';
8182

8283
/**
8384
* Document data (for use with {@link setDoc()}) consists of fields mapped to
@@ -1086,6 +1087,12 @@ export function updateDoc(
10861087
): Promise<void> {
10871088
const dataReader = newUserDataReader(reference.firestore);
10881089

1090+
// For Compat types, we have to "extract" the underlying types before
1091+
// performing validation.
1092+
if (fieldOrUpdateData instanceof Compat) {
1093+
fieldOrUpdateData = fieldOrUpdateData._delegate;
1094+
}
1095+
10891096
let parsed: ParsedUpdateData;
10901097
if (
10911098
typeof fieldOrUpdateData === 'string' ||

packages/firestore/lite/src/api/transaction.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
} from './reference';
4444
import { FieldPath } from './field_path';
4545
import { getDatastore } from './components';
46+
import { Compat } from '../../../src/compat/compat';
4647

4748
// TODO(mrschmidt) Consider using `BaseTransaction` as the base class in the
4849
// legacy SDK.
@@ -194,6 +195,12 @@ export class Transaction {
194195
): this {
195196
const ref = validateReference(documentRef, this._firestore);
196197

198+
// For Compat types, we have to "extract" the underlying types before
199+
// performing validation.
200+
if (fieldOrUpdateData instanceof Compat) {
201+
fieldOrUpdateData = fieldOrUpdateData._delegate;
202+
}
203+
197204
let parsed;
198205
if (
199206
typeof fieldOrUpdateData === 'string' ||

packages/firestore/lite/src/api/write_batch.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { FirebaseFirestore } from './database';
3838
import { invokeCommitRpc } from '../../../src/remote/datastore';
3939
import { FieldPath } from './field_path';
4040
import { getDatastore } from './components';
41+
import { Compat } from '../../../src/compat/compat';
4142

4243
/**
4344
* A write batch, used to perform multiple writes as a single atomic unit.
@@ -155,8 +156,13 @@ export class WriteBatch {
155156
this.verifyNotCommitted();
156157
const ref = validateReference(documentRef, this._firestore);
157158

158-
let parsed;
159+
// For Compat types, we have to "extract" the underlying types before
160+
// performing validation.
161+
if (fieldOrUpdateData instanceof Compat) {
162+
fieldOrUpdateData = fieldOrUpdateData._delegate;
163+
}
159164

165+
let parsed;
160166
if (
161167
typeof fieldOrUpdateData === 'string' ||
162168
fieldOrUpdateData instanceof FieldPath
@@ -233,9 +239,12 @@ export class WriteBatch {
233239
}
234240

235241
export function validateReference<T>(
236-
documentRef: DocumentReference<T>,
242+
documentRef: DocumentReference<T> | Compat<DocumentReference<T>>,
237243
firestore: FirebaseFirestore
238244
): DocumentReference<T> {
245+
if (documentRef instanceof Compat) {
246+
documentRef = documentRef._delegate;
247+
}
239248
if (documentRef.firestore !== firestore) {
240249
throw new FirestoreError(
241250
Code.INVALID_ARGUMENT,

packages/firestore/src/api/database.ts

Lines changed: 42 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ import {
2727
firestoreClientGetDocumentsFromLocalCache,
2828
firestoreClientGetDocumentsViaSnapshotListener,
2929
firestoreClientListen,
30-
firestoreClientTransaction,
31-
firestoreClientWrite
30+
firestoreClientTransaction
3231
} from '../core/firestore_client';
3332
import {
3433
Bound,
@@ -59,7 +58,6 @@ import { Transaction as InternalTransaction } from '../core/transaction';
5958
import { ChangeType, ViewSnapshot } from '../core/view_snapshot';
6059
import { Document, MaybeDocument, NoDocument } from '../model/document';
6160
import { DocumentKey } from '../model/document_key';
62-
import { DeleteMutation, Mutation, Precondition } from '../model/mutation';
6361
import { FieldPath, ResourcePath } from '../model/path';
6462
import { isServerTimestamp } from '../model/server_timestamps';
6563
import { refValue } from '../model/values';
@@ -118,11 +116,13 @@ import {
118116
getDocFromCache,
119117
getDocFromServer,
120118
getDoc,
121-
onSnapshot
119+
onSnapshot,
120+
executeWrite
122121
} from '../../exp/src/api/reference';
123122
import { DocumentSnapshot as ExpDocumentSnapshot } from '../../exp/src/api/snapshot';
124123
import { LRU_COLLECTION_DISABLED } from '../local/lru_garbage_collector';
125124
import { Compat } from '../compat/compat';
125+
import { WriteBatch as ExpWriteBatch } from '../../exp/src/api/write_batch';
126126

127127
import {
128128
CollectionReference as PublicCollectionReference,
@@ -399,7 +399,11 @@ export class Firestore
399399

400400
batch(): PublicWriteBatch {
401401
ensureFirestoreConfigured(this._delegate);
402-
return new WriteBatch(this);
402+
return new WriteBatch(
403+
new ExpWriteBatch(this._delegate, mutations =>
404+
executeWrite(this._delegate, mutations)
405+
)
406+
);
403407
}
404408
}
405409

@@ -590,15 +594,9 @@ export class Transaction implements PublicTransaction {
590594
}
591595
}
592596

593-
export class WriteBatch implements PublicWriteBatch {
594-
private _mutations = [] as Mutation[];
595-
private _committed = false;
596-
private _dataReader: UserDataReader;
597-
598-
constructor(private _firestore: Firestore) {
599-
this._dataReader = newUserDataReader(this._firestore._delegate);
600-
}
601-
597+
export class WriteBatch
598+
extends Compat<ExpWriteBatch>
599+
implements PublicWriteBatch {
602600
set<T>(
603601
documentRef: DocumentReference<T>,
604602
data: Partial<T>,
@@ -607,38 +605,22 @@ export class WriteBatch implements PublicWriteBatch {
607605
set<T>(documentRef: DocumentReference<T>, data: T): WriteBatch;
608606
set<T>(
609607
documentRef: PublicDocumentReference<T>,
610-
value: T | Partial<T>,
608+
data: T | Partial<T>,
611609
options?: PublicSetOptions
612610
): WriteBatch {
613-
this.verifyNotCommitted();
614-
const ref = validateReference(
615-
'WriteBatch.set',
616-
documentRef,
617-
this._firestore
618-
);
619-
options = validateSetOptions('WriteBatch.set', options);
620-
const convertedValue = applyFirestoreDataConverter(
621-
ref._converter,
622-
value,
623-
options
624-
);
625-
const parsed = parseSetData(
626-
this._dataReader,
627-
'WriteBatch.set',
628-
ref._key,
629-
convertedValue,
630-
ref._converter !== null,
631-
options
632-
);
633-
this._mutations = this._mutations.concat(
634-
parsed.toMutations(ref._key, Precondition.none())
635-
);
611+
const ref = castReference(documentRef);
612+
if (options) {
613+
validateSetOptions('WriteBatch.set', options);
614+
this._delegate.set(ref, data, options);
615+
} else {
616+
this._delegate.set(ref, data);
617+
}
636618
return this;
637619
}
638620

639621
update(
640622
documentRef: PublicDocumentReference<unknown>,
641-
value: PublicUpdateData
623+
data: PublicUpdateData
642624
): WriteBatch;
643625
update(
644626
documentRef: PublicDocumentReference<unknown>,
@@ -648,83 +630,32 @@ export class WriteBatch implements PublicWriteBatch {
648630
): WriteBatch;
649631
update(
650632
documentRef: PublicDocumentReference<unknown>,
651-
fieldOrUpdateData: string | PublicFieldPath | PublicUpdateData,
633+
dataOrField: string | PublicFieldPath | PublicUpdateData,
652634
value?: unknown,
653635
...moreFieldsAndValues: unknown[]
654636
): WriteBatch {
655-
this.verifyNotCommitted();
656-
const ref = validateReference(
657-
'WriteBatch.update',
658-
documentRef,
659-
this._firestore
660-
);
661-
662-
// For Compat types, we have to "extract" the underlying types before
663-
// performing validation.
664-
if (fieldOrUpdateData instanceof Compat) {
665-
fieldOrUpdateData = (fieldOrUpdateData as Compat<ExpFieldPath>)._delegate;
666-
}
667-
668-
let parsed;
669-
if (
670-
typeof fieldOrUpdateData === 'string' ||
671-
fieldOrUpdateData instanceof ExpFieldPath
672-
) {
673-
parsed = parseUpdateVarargs(
674-
this._dataReader,
675-
'WriteBatch.update',
676-
ref._key,
677-
fieldOrUpdateData,
678-
value,
679-
moreFieldsAndValues
680-
);
637+
const ref = castReference(documentRef);
638+
if (arguments.length === 2) {
639+
this._delegate.update(ref, dataOrField as PublicUpdateData);
681640
} else {
682-
parsed = parseUpdateData(
683-
this._dataReader,
684-
'WriteBatch.update',
685-
ref._key,
686-
fieldOrUpdateData
641+
this._delegate.update(
642+
ref,
643+
dataOrField as string | ExpFieldPath,
644+
value,
645+
...moreFieldsAndValues
687646
);
688647
}
689-
690-
this._mutations = this._mutations.concat(
691-
parsed.toMutations(ref._key, Precondition.exists(true))
692-
);
693648
return this;
694649
}
695650

696651
delete(documentRef: PublicDocumentReference<unknown>): WriteBatch {
697-
this.verifyNotCommitted();
698-
const ref = validateReference(
699-
'WriteBatch.delete',
700-
documentRef,
701-
this._firestore
702-
);
703-
this._mutations = this._mutations.concat(
704-
new DeleteMutation(ref._key, Precondition.none())
705-
);
652+
const ref = castReference(documentRef);
653+
this._delegate.delete(ref);
706654
return this;
707655
}
708656

709657
commit(): Promise<void> {
710-
this.verifyNotCommitted();
711-
this._committed = true;
712-
if (this._mutations.length > 0) {
713-
const client = ensureFirestoreConfigured(this._firestore._delegate);
714-
return firestoreClientWrite(client, this._mutations);
715-
}
716-
717-
return Promise.resolve();
718-
}
719-
720-
private verifyNotCommitted(): void {
721-
if (this._committed) {
722-
throw new FirestoreError(
723-
Code.FAILED_PRECONDITION,
724-
'A write batch can no longer be used after commit() ' +
725-
'has been called.'
726-
);
727-
}
658+
return this._delegate.commit();
728659
}
729660
}
730661

@@ -2030,6 +1961,15 @@ export class CollectionReference<T = PublicDocumentData>
20301961
}
20311962
}
20321963

1964+
function castReference<T>(
1965+
documentRef: PublicDocumentReference<T>
1966+
): ExpDocumentReference<T> {
1967+
if (documentRef instanceof Compat) {
1968+
documentRef = documentRef._delegate;
1969+
}
1970+
return cast<ExpDocumentReference<T>>(documentRef, ExpDocumentReference);
1971+
}
1972+
20331973
function validateReference<T>(
20341974
methodName: string,
20351975
documentRef: PublicDocumentReference<T>,

0 commit comments

Comments
 (0)