From 4dd8a9a893bf6ababa5e9d52de95bacc549ad21b Mon Sep 17 00:00:00 2001 From: Liran Zairi Date: Sun, 4 Feb 2024 18:00:16 +0200 Subject: [PATCH 1/2] Add batch API --- .../document_reference_test.dart | 44 ++ .../example/lib/integration.g.dart | 84 +++ .../example/lib/integration/enums.g.dart | 79 +++ .../example/lib/integration/freezed.g.dart | 71 +++ .../lib/integration/named_query.g.dart | 29 + .../example/lib/integration/query.g.dart | 146 +++++ .../example/lib/movie.g.dart | 152 +++++ .../lib/src/firestore_reference.dart | 17 + .../lib/freezed.g.dart | 71 +++ .../lib/simple.g.dart | 527 ++++++++++++++++++ .../lib/src/templates/document_reference.dart | 12 + 11 files changed, 1232 insertions(+) diff --git a/packages/cloud_firestore_odm/example/integration_test/document_reference_test.dart b/packages/cloud_firestore_odm/example/integration_test/document_reference_test.dart index 1ae925f..465faaf 100644 --- a/packages/cloud_firestore_odm/example/integration_test/document_reference_test.dart +++ b/packages/cloud_firestore_odm/example/integration_test/document_reference_test.dart @@ -50,6 +50,50 @@ void main() { ); }); + test('batch', () async { + final collection = await initializeTest(MovieCollectionReference()); + + const movieToUpdate = '123'; + const movieToSet = '456'; + const movieToDelete = '789'; + + await collection.doc(movieToUpdate).set(createMovie(title: 'title1')); + await collection.doc(movieToSet).set(createMovie(title: 'title2')); + await collection.doc(movieToDelete).set(createMovie(title: 'title3')); + + expect( + await Future.wait([ + collection.doc(movieToUpdate).get().then((e) => e.exists), + collection.doc(movieToSet).get().then((e) => e.exists), + collection.doc(movieToDelete).get().then((e) => e.exists), + ]), + [true, true, true], + ); + + const updatedTitle = 'updatedTitle'; + const newTitle = 'newTitle'; + final newMovie = createMovie(title: newTitle); + + final batch = FirebaseFirestore.instance.batch(); + collection.doc(movieToUpdate).batchUpdate(batch, title: updatedTitle); + collection.doc(movieToSet).batchSet(batch, newMovie); + collection.doc(movieToDelete).batchDelete(batch); + await batch.commit(); + + expect( + await Future.wait([ + collection.doc(movieToUpdate).get().then((e) => e.data?.title), + collection.doc(movieToSet).get().then((e) => e.data), + collection.doc(movieToDelete).get().then((e) => e.exists), + ]), + [ + updatedTitle, + isA().having((e) => e.title, newTitle, newTitle), + false, + ], + ); + }); + test('delete', () async { final collection = await initializeTest(MovieCollectionReference()); diff --git a/packages/cloud_firestore_odm/example/lib/integration.g.dart b/packages/cloud_firestore_odm/example/lib/integration.g.dart index 0128029..bbec02c 100644 --- a/packages/cloud_firestore_odm/example/lib/integration.g.dart +++ b/packages/cloud_firestore_odm/example/lib/integration.g.dart @@ -150,6 +150,17 @@ abstract class AdvancedJsonDocumentReference extends FirestoreDocumentReference< String? lastName, FieldValue lastNameFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String? firstName, + FieldValue firstNameFieldValue, + String? lastName, + FieldValue lastNameFieldValue, + }); } class _$AdvancedJsonDocumentReference extends FirestoreDocumentReference< @@ -241,6 +252,37 @@ class _$AdvancedJsonDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? firstName = _sentinel, + FieldValue? firstNameFieldValue, + Object? lastName = _sentinel, + FieldValue? lastNameFieldValue, + }) { + assert( + firstName == _sentinel || firstNameFieldValue == null, + "Cannot specify both firstName and firstNameFieldValue", + ); + assert( + lastName == _sentinel || lastNameFieldValue == null, + "Cannot specify both lastName and lastNameFieldValue", + ); + final json = { + if (firstName != _sentinel) + _$AdvancedJsonFieldMap['firstName']!: + _$AdvancedJsonPerFieldToJson.firstName(firstName as String?), + if (firstNameFieldValue != null) + _$AdvancedJsonFieldMap['firstName']!: firstNameFieldValue, + if (lastName != _sentinel) + _$AdvancedJsonFieldMap['lastName']!: + _$AdvancedJsonPerFieldToJson.lastName(lastName as String?), + if (lastNameFieldValue != null) + _$AdvancedJsonFieldMap['lastName']!: lastNameFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is AdvancedJsonDocumentReference && @@ -1136,6 +1178,17 @@ abstract class _PrivateAdvancedJsonDocumentReference String? lastName, FieldValue lastNameFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String? firstName, + FieldValue firstNameFieldValue, + String? lastName, + FieldValue lastNameFieldValue, + }); } class _$_PrivateAdvancedJsonDocumentReference @@ -1231,6 +1284,37 @@ class _$_PrivateAdvancedJsonDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? firstName = _sentinel, + FieldValue? firstNameFieldValue, + Object? lastName = _sentinel, + FieldValue? lastNameFieldValue, + }) { + assert( + firstName == _sentinel || firstNameFieldValue == null, + "Cannot specify both firstName and firstNameFieldValue", + ); + assert( + lastName == _sentinel || lastNameFieldValue == null, + "Cannot specify both lastName and lastNameFieldValue", + ); + final json = { + if (firstName != _sentinel) + _$PrivateAdvancedJsonFieldMap['firstName']!: + _$PrivateAdvancedJsonPerFieldToJson.firstName(firstName as String?), + if (firstNameFieldValue != null) + _$PrivateAdvancedJsonFieldMap['firstName']!: firstNameFieldValue, + if (lastName != _sentinel) + _$PrivateAdvancedJsonFieldMap['lastName']!: + _$PrivateAdvancedJsonPerFieldToJson.lastName(lastName as String?), + if (lastNameFieldValue != null) + _$PrivateAdvancedJsonFieldMap['lastName']!: lastNameFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is _PrivateAdvancedJsonDocumentReference && diff --git a/packages/cloud_firestore_odm/example/lib/integration/enums.g.dart b/packages/cloud_firestore_odm/example/lib/integration/enums.g.dart index 78a0a66..3e94ec5 100644 --- a/packages/cloud_firestore_odm/example/lib/integration/enums.g.dart +++ b/packages/cloud_firestore_odm/example/lib/integration/enums.g.dart @@ -159,6 +159,23 @@ abstract class EnumsDocumentReference List? nullableEnumList, FieldValue nullableEnumListFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String id, + FieldValue idFieldValue, + TestEnum enumValue, + FieldValue enumValueFieldValue, + TestEnum? nullableEnumValue, + FieldValue nullableEnumValueFieldValue, + List enumList, + FieldValue enumListFieldValue, + List? nullableEnumList, + FieldValue nullableEnumListFieldValue, + }); } class _$EnumsDocumentReference @@ -312,6 +329,68 @@ class _$EnumsDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? id = _sentinel, + FieldValue? idFieldValue, + Object? enumValue = _sentinel, + FieldValue? enumValueFieldValue, + Object? nullableEnumValue = _sentinel, + FieldValue? nullableEnumValueFieldValue, + Object? enumList = _sentinel, + FieldValue? enumListFieldValue, + Object? nullableEnumList = _sentinel, + FieldValue? nullableEnumListFieldValue, + }) { + assert( + id == _sentinel || idFieldValue == null, + "Cannot specify both id and idFieldValue", + ); + assert( + enumValue == _sentinel || enumValueFieldValue == null, + "Cannot specify both enumValue and enumValueFieldValue", + ); + assert( + nullableEnumValue == _sentinel || nullableEnumValueFieldValue == null, + "Cannot specify both nullableEnumValue and nullableEnumValueFieldValue", + ); + assert( + enumList == _sentinel || enumListFieldValue == null, + "Cannot specify both enumList and enumListFieldValue", + ); + assert( + nullableEnumList == _sentinel || nullableEnumListFieldValue == null, + "Cannot specify both nullableEnumList and nullableEnumListFieldValue", + ); + final json = { + if (id != _sentinel) + _$EnumsFieldMap['id']!: _$EnumsPerFieldToJson.id(id as String), + if (idFieldValue != null) _$EnumsFieldMap['id']!: idFieldValue, + if (enumValue != _sentinel) + _$EnumsFieldMap['enumValue']!: + _$EnumsPerFieldToJson.enumValue(enumValue as TestEnum), + if (enumValueFieldValue != null) + _$EnumsFieldMap['enumValue']!: enumValueFieldValue, + if (nullableEnumValue != _sentinel) + _$EnumsFieldMap['nullableEnumValue']!: _$EnumsPerFieldToJson + .nullableEnumValue(nullableEnumValue as TestEnum?), + if (nullableEnumValueFieldValue != null) + _$EnumsFieldMap['nullableEnumValue']!: nullableEnumValueFieldValue, + if (enumList != _sentinel) + _$EnumsFieldMap['enumList']!: + _$EnumsPerFieldToJson.enumList(enumList as List), + if (enumListFieldValue != null) + _$EnumsFieldMap['enumList']!: enumListFieldValue, + if (nullableEnumList != _sentinel) + _$EnumsFieldMap['nullableEnumList']!: _$EnumsPerFieldToJson + .nullableEnumList(nullableEnumList as List?), + if (nullableEnumListFieldValue != null) + _$EnumsFieldMap['nullableEnumList']!: nullableEnumListFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is EnumsDocumentReference && diff --git a/packages/cloud_firestore_odm/example/lib/integration/freezed.g.dart b/packages/cloud_firestore_odm/example/lib/integration/freezed.g.dart index f250d2e..c39c30b 100644 --- a/packages/cloud_firestore_odm/example/lib/integration/freezed.g.dart +++ b/packages/cloud_firestore_odm/example/lib/integration/freezed.g.dart @@ -147,6 +147,17 @@ abstract class PersonDocumentReference String lastName, FieldValue lastNameFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String firstName, + FieldValue firstNameFieldValue, + String lastName, + FieldValue lastNameFieldValue, + }); } class _$PersonDocumentReference @@ -238,6 +249,37 @@ class _$PersonDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? firstName = _sentinel, + FieldValue? firstNameFieldValue, + Object? lastName = _sentinel, + FieldValue? lastNameFieldValue, + }) { + assert( + firstName == _sentinel || firstNameFieldValue == null, + "Cannot specify both firstName and firstNameFieldValue", + ); + assert( + lastName == _sentinel || lastNameFieldValue == null, + "Cannot specify both lastName and lastNameFieldValue", + ); + final json = { + if (firstName != _sentinel) + _$$PersonImplFieldMap['firstName']!: + _$$PersonImplPerFieldToJson.firstName(firstName as String), + if (firstNameFieldValue != null) + _$$PersonImplFieldMap['firstName']!: firstNameFieldValue, + if (lastName != _sentinel) + _$$PersonImplFieldMap['lastName']!: + _$$PersonImplPerFieldToJson.lastName(lastName as String), + if (lastNameFieldValue != null) + _$$PersonImplFieldMap['lastName']!: lastNameFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is PersonDocumentReference && @@ -1116,6 +1158,15 @@ abstract class PublicRedirectedDocumentReference String value, FieldValue valueFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String value, + FieldValue valueFieldValue, + }); } class _$PublicRedirectedDocumentReference extends FirestoreDocumentReference< @@ -1186,6 +1237,26 @@ class _$PublicRedirectedDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + final json = { + if (value != _sentinel) + _$$PublicRedirected2ImplFieldMap['value']!: + _$$PublicRedirected2ImplPerFieldToJson.value(value as String), + if (valueFieldValue != null) + _$$PublicRedirected2ImplFieldMap['value']!: valueFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is PublicRedirectedDocumentReference && diff --git a/packages/cloud_firestore_odm/example/lib/integration/named_query.g.dart b/packages/cloud_firestore_odm/example/lib/integration/named_query.g.dart index b969a64..0c2b571 100644 --- a/packages/cloud_firestore_odm/example/lib/integration/named_query.g.dart +++ b/packages/cloud_firestore_odm/example/lib/integration/named_query.g.dart @@ -162,6 +162,15 @@ abstract class ConflictDocumentReference num number, FieldValue numberFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + num number, + FieldValue numberFieldValue, + }); } class _$ConflictDocumentReference @@ -231,6 +240,26 @@ class _$ConflictDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? number = _sentinel, + FieldValue? numberFieldValue, + }) { + assert( + number == _sentinel || numberFieldValue == null, + "Cannot specify both number and numberFieldValue", + ); + final json = { + if (number != _sentinel) + _$ConflictFieldMap['number']!: + _$ConflictPerFieldToJson.number(number as num), + if (numberFieldValue != null) + _$ConflictFieldMap['number']!: numberFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is ConflictDocumentReference && diff --git a/packages/cloud_firestore_odm/example/lib/integration/query.g.dart b/packages/cloud_firestore_odm/example/lib/integration/query.g.dart index 76b531f..cb0a785 100644 --- a/packages/cloud_firestore_odm/example/lib/integration/query.g.dart +++ b/packages/cloud_firestore_odm/example/lib/integration/query.g.dart @@ -148,6 +148,15 @@ abstract class DurationQueryDocumentReference Duration duration, FieldValue durationFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + Duration duration, + FieldValue durationFieldValue, + }); } class _$DurationQueryDocumentReference extends FirestoreDocumentReference< @@ -218,6 +227,26 @@ class _$DurationQueryDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? duration = _sentinel, + FieldValue? durationFieldValue, + }) { + assert( + duration == _sentinel || durationFieldValue == null, + "Cannot specify both duration and durationFieldValue", + ); + final json = { + if (duration != _sentinel) + _$DurationQueryFieldMap['duration']!: + _$DurationQueryPerFieldToJson.duration(duration as Duration), + if (durationFieldValue != null) + _$DurationQueryFieldMap['duration']!: durationFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is DurationQueryDocumentReference && @@ -959,6 +988,15 @@ abstract class DateTimeQueryDocumentReference DateTime time, FieldValue timeFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + DateTime time, + FieldValue timeFieldValue, + }); } class _$DateTimeQueryDocumentReference extends FirestoreDocumentReference< @@ -1029,6 +1067,26 @@ class _$DateTimeQueryDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? time = _sentinel, + FieldValue? timeFieldValue, + }) { + assert( + time == _sentinel || timeFieldValue == null, + "Cannot specify both time and timeFieldValue", + ); + final json = { + if (time != _sentinel) + _$DateTimeQueryFieldMap['time']!: + _$DateTimeQueryPerFieldToJson.time(time as DateTime), + if (timeFieldValue != null) + _$DateTimeQueryFieldMap['time']!: timeFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is DateTimeQueryDocumentReference && @@ -1772,6 +1830,15 @@ abstract class TimestampQueryDocumentReference Timestamp time, FieldValue timeFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + Timestamp time, + FieldValue timeFieldValue, + }); } class _$TimestampQueryDocumentReference extends FirestoreDocumentReference< @@ -1842,6 +1909,26 @@ class _$TimestampQueryDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? time = _sentinel, + FieldValue? timeFieldValue, + }) { + assert( + time == _sentinel || timeFieldValue == null, + "Cannot specify both time and timeFieldValue", + ); + final json = { + if (time != _sentinel) + _$TimestampQueryFieldMap['time']!: + _$TimestampQueryPerFieldToJson.time(time as Timestamp), + if (timeFieldValue != null) + _$TimestampQueryFieldMap['time']!: timeFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is TimestampQueryDocumentReference && @@ -2586,6 +2673,15 @@ abstract class GeoPointQueryDocumentReference GeoPoint point, FieldValue pointFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + GeoPoint point, + FieldValue pointFieldValue, + }); } class _$GeoPointQueryDocumentReference extends FirestoreDocumentReference< @@ -2656,6 +2752,26 @@ class _$GeoPointQueryDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? point = _sentinel, + FieldValue? pointFieldValue, + }) { + assert( + point == _sentinel || pointFieldValue == null, + "Cannot specify both point and pointFieldValue", + ); + final json = { + if (point != _sentinel) + _$GeoPointQueryFieldMap['point']!: + _$GeoPointQueryPerFieldToJson.point(point as GeoPoint), + if (pointFieldValue != null) + _$GeoPointQueryFieldMap['point']!: pointFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is GeoPointQueryDocumentReference && @@ -3402,6 +3518,15 @@ abstract class DocumentReferenceQueryDocumentReference DocumentReference> ref, FieldValue refFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + DocumentReference> ref, + FieldValue refFieldValue, + }); } class _$DocumentReferenceQueryDocumentReference @@ -3479,6 +3604,27 @@ class _$DocumentReferenceQueryDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? ref = _sentinel, + FieldValue? refFieldValue, + }) { + assert( + ref == _sentinel || refFieldValue == null, + "Cannot specify both ref and refFieldValue", + ); + final json = { + if (ref != _sentinel) + _$DocumentReferenceQueryFieldMap['ref']!: + _$DocumentReferenceQueryPerFieldToJson + .ref(ref as DocumentReference>), + if (refFieldValue != null) + _$DocumentReferenceQueryFieldMap['ref']!: refFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is DocumentReferenceQueryDocumentReference && diff --git a/packages/cloud_firestore_odm/example/lib/movie.g.dart b/packages/cloud_firestore_odm/example/lib/movie.g.dart index 2e234cb..2505ff4 100644 --- a/packages/cloud_firestore_odm/example/lib/movie.g.dart +++ b/packages/cloud_firestore_odm/example/lib/movie.g.dart @@ -175,6 +175,29 @@ abstract class MovieDocumentReference Set? tags, FieldValue tagsFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String poster, + FieldValue posterFieldValue, + int likes, + FieldValue likesFieldValue, + String title, + FieldValue titleFieldValue, + int year, + FieldValue yearFieldValue, + String runtime, + FieldValue runtimeFieldValue, + String rated, + FieldValue ratedFieldValue, + List? genre, + FieldValue genreFieldValue, + Set? tags, + FieldValue tagsFieldValue, + }); } class _$MovieDocumentReference @@ -382,6 +405,93 @@ class _$MovieDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? poster = _sentinel, + FieldValue? posterFieldValue, + Object? likes = _sentinel, + FieldValue? likesFieldValue, + Object? title = _sentinel, + FieldValue? titleFieldValue, + Object? year = _sentinel, + FieldValue? yearFieldValue, + Object? runtime = _sentinel, + FieldValue? runtimeFieldValue, + Object? rated = _sentinel, + FieldValue? ratedFieldValue, + Object? genre = _sentinel, + FieldValue? genreFieldValue, + Object? tags = _sentinel, + FieldValue? tagsFieldValue, + }) { + assert( + poster == _sentinel || posterFieldValue == null, + "Cannot specify both poster and posterFieldValue", + ); + assert( + likes == _sentinel || likesFieldValue == null, + "Cannot specify both likes and likesFieldValue", + ); + assert( + title == _sentinel || titleFieldValue == null, + "Cannot specify both title and titleFieldValue", + ); + assert( + year == _sentinel || yearFieldValue == null, + "Cannot specify both year and yearFieldValue", + ); + assert( + runtime == _sentinel || runtimeFieldValue == null, + "Cannot specify both runtime and runtimeFieldValue", + ); + assert( + rated == _sentinel || ratedFieldValue == null, + "Cannot specify both rated and ratedFieldValue", + ); + assert( + genre == _sentinel || genreFieldValue == null, + "Cannot specify both genre and genreFieldValue", + ); + assert( + tags == _sentinel || tagsFieldValue == null, + "Cannot specify both tags and tagsFieldValue", + ); + final json = { + if (poster != _sentinel) + _$MovieFieldMap['poster']!: + _$MoviePerFieldToJson.poster(poster as String), + if (posterFieldValue != null) + _$MovieFieldMap['poster']!: posterFieldValue, + if (likes != _sentinel) + _$MovieFieldMap['likes']!: _$MoviePerFieldToJson.likes(likes as int), + if (likesFieldValue != null) _$MovieFieldMap['likes']!: likesFieldValue, + if (title != _sentinel) + _$MovieFieldMap['title']!: _$MoviePerFieldToJson.title(title as String), + if (titleFieldValue != null) _$MovieFieldMap['title']!: titleFieldValue, + if (year != _sentinel) + _$MovieFieldMap['year']!: _$MoviePerFieldToJson.year(year as int), + if (yearFieldValue != null) _$MovieFieldMap['year']!: yearFieldValue, + if (runtime != _sentinel) + _$MovieFieldMap['runtime']!: + _$MoviePerFieldToJson.runtime(runtime as String), + if (runtimeFieldValue != null) + _$MovieFieldMap['runtime']!: runtimeFieldValue, + if (rated != _sentinel) + _$MovieFieldMap['rated']!: _$MoviePerFieldToJson.rated(rated as String), + if (ratedFieldValue != null) _$MovieFieldMap['rated']!: ratedFieldValue, + if (genre != _sentinel) + _$MovieFieldMap['genre']!: + _$MoviePerFieldToJson.genre(genre as List?), + if (genreFieldValue != null) _$MovieFieldMap['genre']!: genreFieldValue, + if (tags != _sentinel) + _$MovieFieldMap['tags']!: + _$MoviePerFieldToJson.tags(tags as Set?), + if (tagsFieldValue != null) _$MovieFieldMap['tags']!: tagsFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is MovieDocumentReference && @@ -2121,6 +2231,17 @@ abstract class CommentDocumentReference String message, FieldValue messageFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String authorName, + FieldValue authorNameFieldValue, + String message, + FieldValue messageFieldValue, + }); } class _$CommentDocumentReference @@ -2217,6 +2338,37 @@ class _$CommentDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? authorName = _sentinel, + FieldValue? authorNameFieldValue, + Object? message = _sentinel, + FieldValue? messageFieldValue, + }) { + assert( + authorName == _sentinel || authorNameFieldValue == null, + "Cannot specify both authorName and authorNameFieldValue", + ); + assert( + message == _sentinel || messageFieldValue == null, + "Cannot specify both message and messageFieldValue", + ); + final json = { + if (authorName != _sentinel) + _$CommentFieldMap['authorName']!: + _$CommentPerFieldToJson.authorName(authorName as String), + if (authorNameFieldValue != null) + _$CommentFieldMap['authorName']!: authorNameFieldValue, + if (message != _sentinel) + _$CommentFieldMap['message']!: + _$CommentPerFieldToJson.message(message as String), + if (messageFieldValue != null) + _$CommentFieldMap['message']!: messageFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is CommentDocumentReference && diff --git a/packages/cloud_firestore_odm/lib/src/firestore_reference.dart b/packages/cloud_firestore_odm/lib/src/firestore_reference.dart index 5adda8a..705f286 100644 --- a/packages/cloud_firestore_odm/lib/src/firestore_reference.dart +++ b/packages/cloud_firestore_odm/lib/src/firestore_reference.dart @@ -76,6 +76,11 @@ abstract class FirestoreDocumentReference? nullableEnumList, FieldValue nullableEnumListFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + Nested? value, + FieldValue valueFieldValue, + int? simple, + FieldValue simpleFieldValue, + List? valueList, + FieldValue valueListFieldValue, + List? boolList, + FieldValue boolListFieldValue, + List? stringList, + FieldValue stringListFieldValue, + List? numList, + FieldValue numListFieldValue, + List? objectList, + FieldValue objectListFieldValue, + List? dynamicList, + FieldValue dynamicListFieldValue, + Set? boolSet, + FieldValue boolSetFieldValue, + TestEnum enumValue, + FieldValue enumValueFieldValue, + TestEnum? nullableEnumValue, + FieldValue nullableEnumValueFieldValue, + List enumList, + FieldValue enumListFieldValue, + List? nullableEnumList, + FieldValue nullableEnumListFieldValue, + }); } class _$NestedDocumentReference @@ -2118,6 +2207,157 @@ class _$NestedDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + Object? simple = _sentinel, + FieldValue? simpleFieldValue, + Object? valueList = _sentinel, + FieldValue? valueListFieldValue, + Object? boolList = _sentinel, + FieldValue? boolListFieldValue, + Object? stringList = _sentinel, + FieldValue? stringListFieldValue, + Object? numList = _sentinel, + FieldValue? numListFieldValue, + Object? objectList = _sentinel, + FieldValue? objectListFieldValue, + Object? dynamicList = _sentinel, + FieldValue? dynamicListFieldValue, + Object? boolSet = _sentinel, + FieldValue? boolSetFieldValue, + Object? enumValue = _sentinel, + FieldValue? enumValueFieldValue, + Object? nullableEnumValue = _sentinel, + FieldValue? nullableEnumValueFieldValue, + Object? enumList = _sentinel, + FieldValue? enumListFieldValue, + Object? nullableEnumList = _sentinel, + FieldValue? nullableEnumListFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + assert( + simple == _sentinel || simpleFieldValue == null, + "Cannot specify both simple and simpleFieldValue", + ); + assert( + valueList == _sentinel || valueListFieldValue == null, + "Cannot specify both valueList and valueListFieldValue", + ); + assert( + boolList == _sentinel || boolListFieldValue == null, + "Cannot specify both boolList and boolListFieldValue", + ); + assert( + stringList == _sentinel || stringListFieldValue == null, + "Cannot specify both stringList and stringListFieldValue", + ); + assert( + numList == _sentinel || numListFieldValue == null, + "Cannot specify both numList and numListFieldValue", + ); + assert( + objectList == _sentinel || objectListFieldValue == null, + "Cannot specify both objectList and objectListFieldValue", + ); + assert( + dynamicList == _sentinel || dynamicListFieldValue == null, + "Cannot specify both dynamicList and dynamicListFieldValue", + ); + assert( + boolSet == _sentinel || boolSetFieldValue == null, + "Cannot specify both boolSet and boolSetFieldValue", + ); + assert( + enumValue == _sentinel || enumValueFieldValue == null, + "Cannot specify both enumValue and enumValueFieldValue", + ); + assert( + nullableEnumValue == _sentinel || nullableEnumValueFieldValue == null, + "Cannot specify both nullableEnumValue and nullableEnumValueFieldValue", + ); + assert( + enumList == _sentinel || enumListFieldValue == null, + "Cannot specify both enumList and enumListFieldValue", + ); + assert( + nullableEnumList == _sentinel || nullableEnumListFieldValue == null, + "Cannot specify both nullableEnumList and nullableEnumListFieldValue", + ); + final json = { + if (value != _sentinel) + _$NestedFieldMap['value']!: + _$NestedPerFieldToJson.value(value as Nested?), + if (valueFieldValue != null) _$NestedFieldMap['value']!: valueFieldValue, + if (simple != _sentinel) + _$NestedFieldMap['simple']!: + _$NestedPerFieldToJson.simple(simple as int?), + if (simpleFieldValue != null) + _$NestedFieldMap['simple']!: simpleFieldValue, + if (valueList != _sentinel) + _$NestedFieldMap['valueList']!: + _$NestedPerFieldToJson.valueList(valueList as List?), + if (valueListFieldValue != null) + _$NestedFieldMap['valueList']!: valueListFieldValue, + if (boolList != _sentinel) + _$NestedFieldMap['boolList']!: + _$NestedPerFieldToJson.boolList(boolList as List?), + if (boolListFieldValue != null) + _$NestedFieldMap['boolList']!: boolListFieldValue, + if (stringList != _sentinel) + _$NestedFieldMap['stringList']!: + _$NestedPerFieldToJson.stringList(stringList as List?), + if (stringListFieldValue != null) + _$NestedFieldMap['stringList']!: stringListFieldValue, + if (numList != _sentinel) + _$NestedFieldMap['numList']!: + _$NestedPerFieldToJson.numList(numList as List?), + if (numListFieldValue != null) + _$NestedFieldMap['numList']!: numListFieldValue, + if (objectList != _sentinel) + _$NestedFieldMap['objectList']!: + _$NestedPerFieldToJson.objectList(objectList as List?), + if (objectListFieldValue != null) + _$NestedFieldMap['objectList']!: objectListFieldValue, + if (dynamicList != _sentinel) + _$NestedFieldMap['dynamicList']!: + _$NestedPerFieldToJson.dynamicList(dynamicList as List?), + if (dynamicListFieldValue != null) + _$NestedFieldMap['dynamicList']!: dynamicListFieldValue, + if (boolSet != _sentinel) + _$NestedFieldMap['boolSet']!: + _$NestedPerFieldToJson.boolSet(boolSet as Set?), + if (boolSetFieldValue != null) + _$NestedFieldMap['boolSet']!: boolSetFieldValue, + if (enumValue != _sentinel) + _$NestedFieldMap['enumValue']!: + _$NestedPerFieldToJson.enumValue(enumValue as TestEnum), + if (enumValueFieldValue != null) + _$NestedFieldMap['enumValue']!: enumValueFieldValue, + if (nullableEnumValue != _sentinel) + _$NestedFieldMap['nullableEnumValue']!: _$NestedPerFieldToJson + .nullableEnumValue(nullableEnumValue as TestEnum?), + if (nullableEnumValueFieldValue != null) + _$NestedFieldMap['nullableEnumValue']!: nullableEnumValueFieldValue, + if (enumList != _sentinel) + _$NestedFieldMap['enumList']!: + _$NestedPerFieldToJson.enumList(enumList as List), + if (enumListFieldValue != null) + _$NestedFieldMap['enumList']!: enumListFieldValue, + if (nullableEnumList != _sentinel) + _$NestedFieldMap['nullableEnumList']!: _$NestedPerFieldToJson + .nullableEnumList(nullableEnumList as List?), + if (nullableEnumListFieldValue != null) + _$NestedFieldMap['nullableEnumList']!: nullableEnumListFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is NestedDocumentReference && @@ -5230,6 +5470,15 @@ abstract class OptionalJsonDocumentReference extends FirestoreDocumentReference< int value, FieldValue valueFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + int value, + FieldValue valueFieldValue, + }); } class _$OptionalJsonDocumentReference extends FirestoreDocumentReference< @@ -5299,6 +5548,26 @@ class _$OptionalJsonDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + final json = { + if (value != _sentinel) + _$OptionalJsonFieldMap['value']!: + _$OptionalJsonPerFieldToJson.value(value as int), + if (valueFieldValue != null) + _$OptionalJsonFieldMap['value']!: valueFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is OptionalJsonDocumentReference && @@ -6033,6 +6302,15 @@ abstract class MixedJsonDocumentReference int value, FieldValue valueFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + int value, + FieldValue valueFieldValue, + }); } class _$MixedJsonDocumentReference @@ -6102,6 +6380,26 @@ class _$MixedJsonDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + final json = { + if (value != _sentinel) + _$MixedJsonFieldMap['value']!: + _$MixedJsonPerFieldToJson.value(value as int), + if (valueFieldValue != null) + _$MixedJsonFieldMap['value']!: valueFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is MixedJsonDocumentReference && @@ -6853,6 +7151,17 @@ abstract class RootDocumentReference int? nullable, FieldValue nullableFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String nonNullable, + FieldValue nonNullableFieldValue, + int? nullable, + FieldValue nullableFieldValue, + }); } class _$RootDocumentReference @@ -6963,6 +7272,37 @@ class _$RootDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? nonNullable = _sentinel, + FieldValue? nonNullableFieldValue, + Object? nullable = _sentinel, + FieldValue? nullableFieldValue, + }) { + assert( + nonNullable == _sentinel || nonNullableFieldValue == null, + "Cannot specify both nonNullable and nonNullableFieldValue", + ); + assert( + nullable == _sentinel || nullableFieldValue == null, + "Cannot specify both nullable and nullableFieldValue", + ); + final json = { + if (nonNullable != _sentinel) + _$RootFieldMap['nonNullable']!: + _$RootPerFieldToJson.nonNullable(nonNullable as String), + if (nonNullableFieldValue != null) + _$RootFieldMap['nonNullable']!: nonNullableFieldValue, + if (nullable != _sentinel) + _$RootFieldMap['nullable']!: + _$RootPerFieldToJson.nullable(nullable as int?), + if (nullableFieldValue != null) + _$RootFieldMap['nullable']!: nullableFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is RootDocumentReference && @@ -7842,6 +8182,17 @@ abstract class SubDocumentReference int? nullable, FieldValue nullableFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + String nonNullable, + FieldValue nonNullableFieldValue, + int? nullable, + FieldValue nullableFieldValue, + }); } class _$SubDocumentReference @@ -7938,6 +8289,37 @@ class _$SubDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? nonNullable = _sentinel, + FieldValue? nonNullableFieldValue, + Object? nullable = _sentinel, + FieldValue? nullableFieldValue, + }) { + assert( + nonNullable == _sentinel || nonNullableFieldValue == null, + "Cannot specify both nonNullable and nonNullableFieldValue", + ); + assert( + nullable == _sentinel || nullableFieldValue == null, + "Cannot specify both nullable and nullableFieldValue", + ); + final json = { + if (nonNullable != _sentinel) + _$SubFieldMap['nonNullable']!: + _$SubPerFieldToJson.nonNullable(nonNullable as String), + if (nonNullableFieldValue != null) + _$SubFieldMap['nonNullable']!: nonNullableFieldValue, + if (nullable != _sentinel) + _$SubFieldMap['nullable']!: + _$SubPerFieldToJson.nullable(nullable as int?), + if (nullableFieldValue != null) + _$SubFieldMap['nullable']!: nullableFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is SubDocumentReference && @@ -8818,6 +9200,15 @@ abstract class AsCamelCaseDocumentReference extends FirestoreDocumentReference< num value, FieldValue valueFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + num value, + FieldValue valueFieldValue, + }); } class _$AsCamelCaseDocumentReference @@ -8892,6 +9283,26 @@ class _$AsCamelCaseDocumentReference transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + final json = { + if (value != _sentinel) + _$AsCamelCaseFieldMap['value']!: + _$AsCamelCasePerFieldToJson.value(value as num), + if (valueFieldValue != null) + _$AsCamelCaseFieldMap['value']!: valueFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is AsCamelCaseDocumentReference && @@ -9643,6 +10054,15 @@ abstract class CustomSubNameDocumentReference num value, FieldValue valueFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + num value, + FieldValue valueFieldValue, + }); } class _$CustomSubNameDocumentReference extends FirestoreDocumentReference< @@ -9718,6 +10138,26 @@ class _$CustomSubNameDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + final json = { + if (value != _sentinel) + _$CustomSubNameFieldMap['value']!: + _$CustomSubNamePerFieldToJson.value(value as num), + if (valueFieldValue != null) + _$CustomSubNameFieldMap['value']!: valueFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is CustomSubNameDocumentReference && @@ -10471,6 +10911,15 @@ abstract class ThisIsACustomPrefixDocumentReference num value, FieldValue valueFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + num value, + FieldValue valueFieldValue, + }); } class _$ThisIsACustomPrefixDocumentReference extends FirestoreDocumentReference< @@ -10548,6 +10997,26 @@ class _$ThisIsACustomPrefixDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + final json = { + if (value != _sentinel) + _$CustomClassPrefixFieldMap['value']!: + _$CustomClassPrefixPerFieldToJson.value(value as num), + if (valueFieldValue != null) + _$CustomClassPrefixFieldMap['value']!: valueFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is ThisIsACustomPrefixDocumentReference && @@ -11298,6 +11767,15 @@ abstract class ExplicitPathDocumentReference extends FirestoreDocumentReference< num value, FieldValue valueFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + num value, + FieldValue valueFieldValue, + }); } class _$ExplicitPathDocumentReference extends FirestoreDocumentReference< @@ -11372,6 +11850,26 @@ class _$ExplicitPathDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + final json = { + if (value != _sentinel) + _$ExplicitPathFieldMap['value']!: + _$ExplicitPathPerFieldToJson.value(value as num), + if (valueFieldValue != null) + _$ExplicitPathFieldMap['value']!: valueFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is ExplicitPathDocumentReference && @@ -12124,6 +12622,15 @@ abstract class ExplicitSubPathDocumentReference num value, FieldValue valueFieldValue, }); + + /// Updates fields in the current document using the batch API. + /// + /// The update will fail if applied to a document that does not exist. + void batchUpdate( + WriteBatch batch, { + num value, + FieldValue valueFieldValue, + }); } class _$ExplicitSubPathDocumentReference extends FirestoreDocumentReference< @@ -12199,6 +12706,26 @@ class _$ExplicitSubPathDocumentReference extends FirestoreDocumentReference< transaction.update(reference, json); } + void batchUpdate( + WriteBatch batch, { + Object? value = _sentinel, + FieldValue? valueFieldValue, + }) { + assert( + value == _sentinel || valueFieldValue == null, + "Cannot specify both value and valueFieldValue", + ); + final json = { + if (value != _sentinel) + _$ExplicitSubPathFieldMap['value']!: + _$ExplicitSubPathPerFieldToJson.value(value as num), + if (valueFieldValue != null) + _$ExplicitSubPathFieldMap['value']!: valueFieldValue, + }; + + batch.update(reference, json); + } + @override bool operator ==(Object other) { return other is ExplicitSubPathDocumentReference && diff --git a/packages/cloud_firestore_odm_generator/lib/src/templates/document_reference.dart b/packages/cloud_firestore_odm_generator/lib/src/templates/document_reference.dart index 27ecbdb..de6b643 100644 --- a/packages/cloud_firestore_odm_generator/lib/src/templates/document_reference.dart +++ b/packages/cloud_firestore_odm_generator/lib/src/templates/document_reference.dart @@ -89,6 +89,11 @@ Future update({${parameters.join()}}); /// /// The update will fail if applied to a document that does not exist. void transactionUpdate(Transaction transaction, {${parameters.join()}}); + +/// Updates fields in the current document using the batch API. +/// +/// The update will fail if applied to a document that does not exist. +void batchUpdate(WriteBatch batch, {${parameters.join()}}); '''; } @@ -139,6 +144,13 @@ void transactionUpdate(Transaction transaction, {${parameters.join()}}) { transaction.update(reference, json); } + +void batchUpdate(WriteBatch batch, {${parameters.join()}}) { + $asserts + final json = {${json.join()}}; + + batch.update(reference, json); +} '''; } From decd4c7ddfcc4a7b6f3f6264eacdcacb669d9492 Mon Sep 17 00:00:00 2001 From: Liran Zairi Date: Mon, 4 Mar 2024 18:35:42 +0200 Subject: [PATCH 2/2] Update changelog --- packages/cloud_firestore_odm/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/cloud_firestore_odm/CHANGELOG.md b/packages/cloud_firestore_odm/CHANGELOG.md index aacb68c..7594b6c 100644 --- a/packages/cloud_firestore_odm/CHANGELOG.md +++ b/packages/cloud_firestore_odm/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.0-dev.85 - 2024-03-04 + +- **FEAT**: Add batch API ([#12](https://github.com/FirebaseExtended/firestoreodm-flutter/issues/12)). ([4dd8a9a8](https://github.com/FirebaseExtended/firestoreodm-flutter/commit/4dd8a9a893bf6ababa5e9d52de95bacc549ad21b)) + ## 1.0.0-dev.84 - 2024-03-04 - Bumped minimum cloud_firestore version to `4.15.0`