Skip to content

Commit e89d437

Browse files
Compat class for Transaction
1 parent 6c6c49a commit e89d437

File tree

3 files changed

+41
-220
lines changed

3 files changed

+41
-220
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export function runTransaction<T>(
103103
firestore._queue.enqueueAndForget(async () => {
104104
const datastore = await getDatastore(firestore);
105105
new TransactionRunner<T>(
106-
new AsyncQueue(),
106+
firestore._queue,
107107
datastore,
108108
internalTransaction =>
109109
updateFunction(new Transaction(firestore, internalTransaction)),

packages/firestore/exp/test/shim.ts

Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,11 @@ import {
4040
Bytes as BytesExp
4141
} from '../../exp/index';
4242
import { UntypedFirestoreDataConverter } from '../../src/api/user_data_reader';
43-
import {
44-
isPlainObject,
45-
validateSetOptions
46-
} from '../../src/util/input_validation';
43+
import { isPlainObject } from '../../src/util/input_validation';
4744
import { Compat } from '../../src/compat/compat';
4845
import {
4946
Firestore,
5047
DocumentReference,
51-
DocumentSnapshot,
5248
QuerySnapshot,
5349
wrapObserver,
5450
extractSnapshotOptions
@@ -62,72 +58,6 @@ export { GeoPoint, Timestamp } from '../index';
6258
// of the experimental SDK. This shim is used to run integration tests against
6359
// both SDK versions.
6460

65-
export class Transaction
66-
extends Compat<exp.Transaction>
67-
implements legacy.Transaction {
68-
constructor(
69-
private readonly _firestore: Firestore,
70-
delegate: exp.Transaction
71-
) {
72-
super(delegate);
73-
}
74-
75-
get<T>(documentRef: DocumentReference<T>): Promise<DocumentSnapshot<T>> {
76-
return this._delegate
77-
.get(documentRef._delegate)
78-
.then(result => new DocumentSnapshot(this._firestore, result));
79-
}
80-
81-
set<T>(
82-
documentRef: DocumentReference<T>,
83-
data: T,
84-
options?: legacy.SetOptions
85-
): Transaction {
86-
if (options) {
87-
validateSetOptions('Transaction.set', options);
88-
this._delegate.set(documentRef._delegate, unwrap(data), options);
89-
} else {
90-
this._delegate.set(documentRef._delegate, unwrap(data));
91-
}
92-
return this;
93-
}
94-
95-
update(
96-
documentRef: DocumentReference<any>,
97-
data: legacy.UpdateData
98-
): Transaction;
99-
update(
100-
documentRef: DocumentReference<any>,
101-
field: string | FieldPath,
102-
value: any,
103-
...moreFieldsAndValues: any[]
104-
): Transaction;
105-
update(
106-
documentRef: DocumentReference<any>,
107-
dataOrField: any,
108-
value?: any,
109-
...moreFieldsAndValues: any[]
110-
): Transaction {
111-
if (arguments.length === 2) {
112-
this._delegate.update(documentRef._delegate, unwrap(dataOrField));
113-
} else {
114-
this._delegate.update(
115-
documentRef._delegate,
116-
unwrap(dataOrField),
117-
unwrap(value),
118-
...unwrap(moreFieldsAndValues)
119-
);
120-
}
121-
122-
return this;
123-
}
124-
125-
delete(documentRef: DocumentReference<any>): Transaction {
126-
this._delegate.delete(documentRef._delegate);
127-
return this;
128-
}
129-
}
130-
13161
export class Query<T = legacy.DocumentData>
13262
extends Compat<exp.Query<T>>
13363
implements legacy.Query<T> {

packages/firestore/src/api/database.ts

Lines changed: 39 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ import {
2727
firestoreClientGetDocumentsViaSnapshotListener,
2828
firestoreClientGetNamedQuery,
2929
firestoreClientListen,
30-
firestoreClientLoadBundle,
31-
firestoreClientTransaction
30+
firestoreClientLoadBundle
3231
} from '../core/firestore_client';
3332
import {
3433
Bound,
@@ -54,14 +53,13 @@ import {
5453
queryWithLimit,
5554
queryWithStartAt
5655
} from '../core/query';
57-
import { Transaction as InternalTransaction } from '../core/transaction';
5856
import { ViewSnapshot } from '../core/view_snapshot';
59-
import { Document, MaybeDocument, NoDocument } from '../model/document';
57+
import { Document } from '../model/document';
6058
import { DocumentKey } from '../model/document_key';
6159
import { FieldPath, ResourcePath } from '../model/path';
6260
import { isServerTimestamp } from '../model/server_timestamps';
6361
import { refValue } from '../model/values';
64-
import { debugAssert, fail } from '../util/assert';
62+
import { debugAssert } from '../util/assert';
6563
import { Code, FirestoreError } from '../util/error';
6664
import {
6765
cast,
@@ -85,9 +83,6 @@ import {
8583
import {
8684
fieldPathFromArgument,
8785
parseQueryValue,
88-
parseSetData,
89-
parseUpdateData,
90-
parseUpdateVarargs,
9186
UntypedFirestoreDataConverter,
9287
UserDataReader
9388
} from './user_data_reader';
@@ -125,6 +120,10 @@ import {
125120
import { LRU_COLLECTION_DISABLED } from '../local/lru_garbage_collector';
126121
import { Compat } from '../compat/compat';
127122
import { WriteBatch as ExpWriteBatch } from '../../exp/src/api/write_batch';
123+
import {
124+
runTransaction,
125+
Transaction as ExpTransaction
126+
} from '../../exp/src/api/transaction';
128127

129128
import {
130129
CollectionReference as PublicCollectionReference,
@@ -392,12 +391,8 @@ export class Firestore
392391
runTransaction<T>(
393392
updateFunction: (transaction: PublicTransaction) => Promise<T>
394393
): Promise<T> {
395-
const client = ensureFirestoreConfigured(this._delegate);
396-
return firestoreClientTransaction(
397-
client,
398-
(transaction: InternalTransaction) => {
399-
return updateFunction(new Transaction(this, transaction));
400-
}
394+
return runTransaction(this._delegate, transaction =>
395+
updateFunction(new Transaction(this, transaction))
401396
);
402397
}
403398

@@ -478,68 +473,23 @@ export function namedQuery(
478473
/**
479474
* A reference to a transaction.
480475
*/
481-
export class Transaction implements PublicTransaction {
482-
private _dataReader: UserDataReader;
483-
476+
export class Transaction
477+
extends Compat<ExpTransaction>
478+
implements PublicTransaction {
484479
constructor(
485-
private _firestore: Firestore,
486-
private _transaction: InternalTransaction
480+
private readonly _firestore: Firestore,
481+
delegate: ExpTransaction
487482
) {
488-
this._dataReader = newUserDataReader(this._firestore._delegate);
483+
super(delegate);
489484
}
490485

491486
get<T>(
492487
documentRef: PublicDocumentReference<T>
493488
): Promise<PublicDocumentSnapshot<T>> {
494-
const ref = validateReference(
495-
'Transaction.get',
496-
documentRef,
497-
this._firestore
498-
);
499-
const userDataWriter = new UserDataWriter(this._firestore);
500-
return this._transaction
501-
.lookup([ref._key])
502-
.then((docs: MaybeDocument[]) => {
503-
if (!docs || docs.length !== 1) {
504-
return fail('Mismatch in docs returned from document lookup.');
505-
}
506-
const doc = docs[0];
507-
if (doc instanceof NoDocument) {
508-
return new DocumentSnapshot<T>(
509-
this._firestore,
510-
new ExpDocumentSnapshot(
511-
this._firestore._delegate,
512-
userDataWriter,
513-
ref._key,
514-
null,
515-
new SnapshotMetadata(
516-
/*hasPendingWrites= */ false,
517-
/* fromCache= */ false
518-
),
519-
ref._converter
520-
)
521-
);
522-
} else if (doc instanceof Document) {
523-
return new DocumentSnapshot<T>(
524-
this._firestore,
525-
new ExpDocumentSnapshot(
526-
this._firestore._delegate,
527-
userDataWriter,
528-
ref._key,
529-
doc,
530-
new SnapshotMetadata(
531-
/*hasPendingWrites= */ false,
532-
/* fromCache= */ false
533-
),
534-
ref._converter
535-
)
536-
);
537-
} else {
538-
throw fail(
539-
`BatchGetDocumentsRequest returned unexpected document type: ${doc.constructor.name}`
540-
);
541-
}
542-
});
489+
const ref = castReference(documentRef);
490+
return this._delegate
491+
.get(ref)
492+
.then(result => new DocumentSnapshot(this._firestore, result));
543493
}
544494

545495
set<T>(
@@ -550,35 +500,22 @@ export class Transaction implements PublicTransaction {
550500
set<T>(documentRef: DocumentReference<T>, data: T): Transaction;
551501
set<T>(
552502
documentRef: PublicDocumentReference<T>,
553-
value: T | Partial<T>,
503+
data: T | Partial<T>,
554504
options?: PublicSetOptions
555505
): Transaction {
556-
const ref = validateReference(
557-
'Transaction.set',
558-
documentRef,
559-
this._firestore
560-
);
561-
options = validateSetOptions('Transaction.set', options);
562-
const convertedValue = applyFirestoreDataConverter(
563-
ref._converter,
564-
value,
565-
options
566-
);
567-
const parsed = parseSetData(
568-
this._dataReader,
569-
'Transaction.set',
570-
ref._key,
571-
convertedValue,
572-
ref._converter !== null,
573-
options
574-
);
575-
this._transaction.set(ref._key, parsed);
506+
const ref = castReference(documentRef);
507+
if (options) {
508+
validateSetOptions('Transaction.set', options);
509+
this._delegate.set(ref, data, options);
510+
} else {
511+
this._delegate.set(ref, data);
512+
}
576513
return this;
577514
}
578515

579516
update(
580517
documentRef: PublicDocumentReference<unknown>,
581-
value: PublicUpdateData
518+
data: PublicUpdateData
582519
): Transaction;
583520
update(
584521
documentRef: PublicDocumentReference<unknown>,
@@ -588,55 +525,28 @@ export class Transaction implements PublicTransaction {
588525
): Transaction;
589526
update(
590527
documentRef: PublicDocumentReference<unknown>,
591-
fieldOrUpdateData: string | PublicFieldPath | PublicUpdateData,
528+
dataOrField: unknown,
592529
value?: unknown,
593530
...moreFieldsAndValues: unknown[]
594531
): Transaction {
595-
const ref = validateReference(
596-
'Transaction.update',
597-
documentRef,
598-
this._firestore
599-
);
600-
601-
// For Compat types, we have to "extract" the underlying types before
602-
// performing validation.
603-
if (fieldOrUpdateData instanceof Compat) {
604-
fieldOrUpdateData = (fieldOrUpdateData as Compat<ExpFieldPath>)._delegate;
605-
}
606-
607-
let parsed;
608-
if (
609-
typeof fieldOrUpdateData === 'string' ||
610-
fieldOrUpdateData instanceof ExpFieldPath
611-
) {
612-
parsed = parseUpdateVarargs(
613-
this._dataReader,
614-
'Transaction.update',
615-
ref._key,
616-
fieldOrUpdateData,
617-
value,
618-
moreFieldsAndValues
619-
);
532+
const ref = castReference(documentRef);
533+
if (arguments.length === 2) {
534+
this._delegate.update(ref, dataOrField as PublicUpdateData);
620535
} else {
621-
parsed = parseUpdateData(
622-
this._dataReader,
623-
'Transaction.update',
624-
ref._key,
625-
fieldOrUpdateData
536+
this._delegate.update(
537+
ref,
538+
dataOrField as string,
539+
value,
540+
...moreFieldsAndValues
626541
);
627542
}
628543

629-
this._transaction.update(ref._key, parsed);
630544
return this;
631545
}
632546

633547
delete(documentRef: PublicDocumentReference<unknown>): Transaction {
634-
const ref = validateReference(
635-
'Transaction.delete',
636-
documentRef,
637-
this._firestore
638-
);
639-
this._transaction.delete(ref._key);
548+
const ref = castReference(documentRef);
549+
this._delegate.delete(ref);
640550
return this;
641551
}
642552
}
@@ -1956,25 +1866,6 @@ function castReference<T>(
19561866
return cast<ExpDocumentReference<T>>(documentRef, ExpDocumentReference);
19571867
}
19581868

1959-
function validateReference<T>(
1960-
methodName: string,
1961-
documentRef: PublicDocumentReference<T>,
1962-
firestore: Firestore
1963-
): ExpDocumentReference<T> {
1964-
const reference = cast<ExpDocumentReference<T>>(
1965-
documentRef,
1966-
ExpDocumentReference
1967-
);
1968-
if (reference.firestore !== firestore._delegate) {
1969-
throw new FirestoreError(
1970-
Code.INVALID_ARGUMENT,
1971-
'Provided document reference is from a different Firestore instance.'
1972-
);
1973-
} else {
1974-
return reference;
1975-
}
1976-
}
1977-
19781869
/**
19791870
* Converts custom model object of type T into DocumentData by applying the
19801871
* converter if it exists.

0 commit comments

Comments
 (0)