From eee2d421365acd4e26b002b5cdf060c87aca11cd Mon Sep 17 00:00:00 2001 From: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:53:25 +0100 Subject: [PATCH] Split collection class --- Realm/Realm/Sync/MongoClient.cs | 62 +++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/Realm/Realm/Sync/MongoClient.cs b/Realm/Realm/Sync/MongoClient.cs index 04c3fefb90..76cc8048a7 100644 --- a/Realm/Realm/Sync/MongoClient.cs +++ b/Realm/Realm/Sync/MongoClient.cs @@ -49,16 +49,16 @@ public class MongoClient public string ServiceName { get; } //TODO Add documentation - //TODO Can we avoid reflection here? - public Collection GetCollection() + //TODO Should we have the same method on Database? + public RealmCollection GetCollection() where TDocument : class, IRealmObject { var schema = _schemas.GetOrAdd(typeof(TDocument), type => (ObjectSchema?)type.GetField("RealmSchema", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) ?? throw new NotSupportedException("This method is only supported for source-generated classes - i.e. ones that inherit from IRealmObject rather than RealmObject.")); - //TODO I think schema.Name isn't correct, because we don't know the eventual mapped name, need to check - return new Collection(this, schema.Name); + //TODO Need to check if the name is correct (to account for "MapTo") + return new RealmCollection(this, schema.Name); } internal MongoClient(User user, string serviceName) @@ -152,7 +152,7 @@ public Collection GetCollection(string name) /// An object representing a remote MongoDB collection. /// /// The managed type that matches the shape of the documents in the collection. - public class Collection + public class Collection : BaseCollection where TDocument : class { /// @@ -167,10 +167,45 @@ public class Collection /// The collection name. public string Name { get; } + protected override string[] BaseArguments { get; } + internal Collection(Database database, string name) + : base(database.Client) { Database = database; Name = name; + BaseArguments = new string[] { "database", Database.Name, "collection", Name }; + } + } + + //TODO Add docs + public class RealmCollection : BaseCollection + where TDocument : IRealmObjectBase + { + //TODO Docs + public MongoClient Client { get; } + + //TODO Docs + public string SchemaName { get; } + + protected override string[] BaseArguments { get; } + + internal RealmCollection(MongoClient client, string schemaName) + :base(client) + { + Client = client; + SchemaName = schemaName; + BaseArguments = new string[] { "schema_name", schemaName }; + } + } + + public abstract class BaseCollection + { + private MongoClient _client; + + internal BaseCollection(MongoClient client) + { + _client = client; } /// @@ -465,22 +500,27 @@ public Task FindOneAndDeleteAsync(object? filter = null, object? sort private async Task InvokeOperationAsync(string functionName, params object?[] args) { var jsonBuilder = new StringBuilder(); - jsonBuilder.Append($"[{{\"database\":\"{Database.Name}\",\"collection\":\"{Name}\""); - Debug.Assert(args.Length % 2 == 0, "args should be provided as key-value pairs"); + jsonBuilder.Append("[{"); + + var allArgs = BaseArguments.Concat(args).ToArray(); - for (var i = 0; i < args.Length; i += 2) + Debug.Assert(allArgs.Length % 2 == 0, "arguments should be provided as key-value pairs"); + + for (var i = 0; i < allArgs.Length; i += 2) { - if (args[i + 1] != null) + if (allArgs[i + 1] != null) { - jsonBuilder.Append($",\"{args[i]}\":{args[i + 1].ToNativeJson()}"); + jsonBuilder.Append($",\"{allArgs[i]}\":{allArgs[i + 1].ToNativeJson()}"); } } jsonBuilder.Append("}]"); - return await Database.Client.User.Functions.CallSerializedAsync(functionName, jsonBuilder.ToString(), Database.Client.ServiceName); + return await _client.User.Functions.CallSerializedAsync(functionName, jsonBuilder.ToString(), _client.ServiceName); } + + protected abstract string[] BaseArguments { get; } } ///