Skip to content
This repository has been archived by the owner on Jun 11, 2021. It is now read-only.

Commit

Permalink
[cloud_firestore][wip] migrate to present #2
Browse files Browse the repository at this point in the history
  • Loading branch information
long1eu committed Feb 16, 2021
1 parent ed5b632 commit 4e78f22
Show file tree
Hide file tree
Showing 16 changed files with 518 additions and 407 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import 'package:cloud_firestore_vm/src/firebase/firestore/document_reference.dar
import 'package:cloud_firestore_vm/src/firebase/firestore/field_path.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/firestore.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/geo_point.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/model/database_id.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/model/document.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/model/document_key.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/model/field_path.dart' as model;
import 'package:cloud_firestore_vm/src/firebase/firestore/server_timestamp_behavior.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/snapshot_metadata.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/user_data_writer.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/util/assert.dart';
import 'package:cloud_firestore_vm/src/firebase/timestamp.dart';
import 'package:cloud_firestore_vm/src/proto/google/firestore/v1/document.pb.dart' show Value;
import 'package:meta/meta.dart';

/// A [DocumentSnapshot] contains data read from a document in your [Firestore] database. The data can be extracted with
Expand Down Expand Up @@ -186,14 +187,8 @@ class DocumentSnapshot {
serverTimestampBehavior ??= ServerTimestampBehavior.none;
checkNotNull(field, 'Provided field path must not be null.');
checkNotNull(serverTimestampBehavior, 'Provided serverTimestampBehavior value must not be null.');
final Object maybeDate = _getInternal(
FieldPath.fromDotSeparatedPath(field).internalPath,
_FieldValueOptions(
serverTimestampBehavior: serverTimestampBehavior,
timestampsInSnapshotsEnabled: false,
),
);
return _castTypedValue(maybeDate, field);
final Timestamp timestamp = getTimestamp(field, serverTimestampBehavior);
return timestamp?.toDate();
}

/// Returns the value of the field as a [Timestamp].
Expand All @@ -208,10 +203,8 @@ class DocumentSnapshot {
serverTimestampBehavior ??= ServerTimestampBehavior.none;
checkNotNull(field, 'Provided field path must not be null.');
checkNotNull(serverTimestampBehavior, 'Provided serverTimestampBehavior value must not be null.');
final Object maybeTimestamp = _getInternal(
FieldPath.fromDotSeparatedPath(field).internalPath,
_FieldValueOptions(serverTimestampBehavior: serverTimestampBehavior),
);
final Object maybeTimestamp =
_getInternal(FieldPath.fromDotSeparatedPath(field).internalPath, serverTimestampBehavior);
return _castTypedValue(maybeTimestamp, field);
}

Expand Down Expand Up @@ -258,82 +251,17 @@ class DocumentSnapshot {
try {
final T result = value;
return result;
} on CastError catch (_) {
} on TypeError catch (_) {
throw StateError('Field \'$field\' is not a $T, but it is ${value.runtimeType}');
}
}

Object _convertValue(FieldValue value, _FieldValueOptions options) {
if (value is ObjectValue) {
return _convertObject(value, options);
} else if (value is ArrayValue) {
return _convertArray(value, options);
} else if (value is ReferenceValue) {
return _convertReference(value);
} else if (value is TimestampValue) {
return _convertTimestamp(value, options);
} else if (value is ServerTimestampValue) {
return _convertServerTimestamp(value, options);
} else {
return value.value;
}
}

Object _convertServerTimestamp(ServerTimestampValue value, _FieldValueOptions options) {
switch (options.serverTimestampBehavior) {
case ServerTimestampBehavior.previous:
return value.previousValue;
case ServerTimestampBehavior.estimate:
return value.localWriteTime;
default:
return value.value;
}
}

Object _convertTimestamp(TimestampValue value, _FieldValueOptions options) {
final Timestamp timestamp = value.value;
if (options.timestampsInSnapshotsEnabled) {
return timestamp;
} else {
return timestamp.toDate();
}
}

Object _convertReference(ReferenceValue value) {
final DocumentKey key = value.value;
final DatabaseId refDatabase = value.databaseId;
final DatabaseId database = _firestore.databaseId;
if (refDatabase != database) {
// TODO(long1eu): Somehow support foreign references.
Log.w('$DocumentSnapshot',
'Document ${key.path} contains a document reference within a different database (${refDatabase.projectId}/${refDatabase.databaseId}) which is not supported. It will be treated as a reference in the current database (${database.projectId}/${database.databaseId}) instead.');
}
return DocumentReference(key, _firestore);
}

Map<String, Object> _convertObject(ObjectValue objectValue, _FieldValueOptions options) {
final Map<String, Object> result = <String, Object>{};
for (MapEntry<String, FieldValue> entry in objectValue.internalValue) {
result[entry.key] = _convertValue(entry.value, options);
}
return result;
}

List<Object> _convertArray(ArrayValue arrayValue, _FieldValueOptions options) {
final List<Object> result = List<Object>(arrayValue.internalValue.length);
int i = 0;
for (FieldValue v in arrayValue.internalValue) {
result[i] = _convertValue(v, options);
i++;
}
return result;
}

Object _getInternal(model.FieldPath fieldPath, _FieldValueOptions options) {
Object _getInternal(model.FieldPath fieldPath, ServerTimestampBehavior serverTimestampBehavior) {
if (document != null) {
final FieldValue val = document.getField(fieldPath);
final Value val = document.getField(fieldPath);
if (val != null) {
return _convertValue(val, options);
final UserDataWriter userDataWriter = UserDataWriter(_firestore, serverTimestampBehavior);
return userDataWriter.convertValue(val);
}
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import 'package:cloud_firestore_vm/src/firebase/firestore/model/database_id.dart
import 'package:cloud_firestore_vm/src/firebase/firestore/model/resource_path.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/query.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/transaction.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/user_data_converter.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/user_data_reader.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/user_data_writer.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/util/assert.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/util/async_task.dart';
import 'package:cloud_firestore_vm/src/firebase/firestore/util/database.dart';
Expand All @@ -38,13 +39,13 @@ import 'package:meta/meta.dart';
class Firestore {
@visibleForTesting
Firestore(this.databaseId, this.firebaseApp, this.client, this._scheduler)
: userDataReader = UserDataConverter(databaseId);
: userDataReader = UserDataReader(databaseId);

static const String _tag = 'FirebaseFirestore';

final DatabaseId databaseId;
final FirebaseApp firebaseApp;
final UserDataConverter userDataReader;
final UserDataReader userDataReader;
final FirestoreClient client;
final AsyncQueue _scheduler;

Expand Down Expand Up @@ -212,7 +213,7 @@ class Firestore {
return updateFunction(Transaction(internalTransaction, this));
}

return client.transaction(wrappedUpdateFunction, 5);
return client.transaction(wrappedUpdateFunction);
}

/// Creates a write batch, used for performing multiple writes as a single
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,20 @@ class FirestoreMultiDbComponent {
settings: settings,
);
}

/// Remove the instance of a given database ID from this component, such that if [FirestoreMultiDbComponent.get]
/// is called again with the same name, a new instance of [Firestore] is created.
///
/// <p>It is a no-op if there is no instance associated with the given database name.
Future<void> remove(String databaseId) async {
instances.remove(databaseId);
}

void onDeleted(String firebaseAppName, FirebaseOptions options) {
// Shuts down all database instances and remove them from registry map when App is deleted.
for (MapEntry<String, Firestore> entry in instances.entries) {
entry.value.shutdown();
instances.remove(entry.key);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final Value NULL_VALUE = Value(nullValue: NullValue.NULL_VALUE);
/// support server timestamps.
const int TYPE_ORDER_NULL = 0;

const int TYPE_ORDER_bool = 1;
const int TYPE_ORDER_BOOL = 1;
const int TYPE_ORDER_NUMBER = 2;
const int TYPE_ORDER_TIMESTAMP = 3;
const int TYPE_ORDER_SERVER_TIMESTAMP = 4;
Expand All @@ -40,7 +40,7 @@ int typeOrder(Value value) {
case Value_ValueType.nullValue:
return TYPE_ORDER_NULL;
case Value_ValueType.booleanValue:
return TYPE_ORDER_bool;
return TYPE_ORDER_BOOL;
case Value_ValueType.integerValue:
return TYPE_ORDER_NUMBER;
case Value_ValueType.doubleValue:
Expand Down Expand Up @@ -161,7 +161,7 @@ int compare(Value left, Value right) {
switch (leftType) {
case TYPE_ORDER_NULL:
return 0;
case TYPE_ORDER_bool:
case TYPE_ORDER_BOOL:
return compareBools(left.booleanValue, right.booleanValue);
case TYPE_ORDER_NUMBER:
return _compareNumbers(left, right);
Expand Down
Loading

0 comments on commit 4e78f22

Please sign in to comment.