ToDotPath() public static method

public static ToDotPath ( IEnumerable keys ) : string
keys IEnumerable
return string
        public async Task <TrackableDictionary <TKey, TValue> > LoadAsync(IMongoCollection <BsonDocument> collection,
                                                                          params object[] keyValues)
        {
            if (keyValues.Length == 0)
            {
                throw new ArgumentException("At least 1 keyValue required.");
            }

            BsonDocument doc;

            if (keyValues.Length == 1)
            {
                doc = await collection.Find(Builders <BsonDocument> .Filter.Eq("_id", keyValues[0])).FirstOrDefaultAsync();
            }
            else
            {
                // partial query

                var partialKeys = keyValues.Skip(1);
                var partialPath = DocumentHelper.ToDotPath(partialKeys);
                var partialDoc  = await collection.Find(Builders <BsonDocument> .Filter.Eq("_id", keyValues[0]))
                                  .Project(Builders <BsonDocument> .Projection.Include(partialPath))
                                  .FirstOrDefaultAsync();

                doc = DocumentHelper.QueryValue(partialDoc, partialKeys) as BsonDocument;
            }

            if (doc == null)
            {
                return(null);
            }

            return(ConvertToTrackableDictionary(doc));
        }
Esempio n. 2
0
        public async Task <TrackableList <T> > LoadAsync(IMongoCollection <BsonDocument> collection,
                                                         params object[] keyValues)
        {
            if (keyValues.Length < 2)
            {
                throw new ArgumentException("At least 2 keyValue required.");
            }

            // partial query

            var keyPath    = keyValues.Length > 1 ? DocumentHelper.ToDotPath(keyValues.Skip(1)) : "";
            var partialDoc = await collection.Find(Builders <BsonDocument> .Filter.Eq("_id", keyValues[0]))
                             .Project(Builders <BsonDocument> .Projection.Include(keyPath))
                             .FirstOrDefaultAsync();

            if (partialDoc == null)
            {
                return(null);
            }

            var doc = DocumentHelper.QueryValue(partialDoc, keyValues.Skip(1));

            if (doc == null)
            {
                return(null);
            }

            if (doc.IsBsonArray == false)
            {
                throw new Exception($"Data should be an array. ({doc.BsonType})");
            }

            return(ConvertToTrackableList(doc.AsBsonArray));
        }
        // CreateAsync

        public Task CreateAsync(IMongoCollection <BsonDocument> collection, IDictionary <TKey, TValue> dictionary,
                                params object[] keyValues)
        {
            if (keyValues.Length == 0)
            {
                throw new ArgumentException("At least 1 keyValue required.");
            }

            if (keyValues.Length == 1)
            {
                var bson = ConvertToBsonDocument(dictionary);
                bson.InsertAt(0, new BsonElement("_id", BsonValue.Create(keyValues[0])));
                return(collection.InsertOneAsync(bson));
            }
            else
            {
                var subKeys = keyValues.Skip(1).ToArray();
                var update  = BuildUpdatesForCreate(null, dictionary, subKeys);
                return(collection.UpdateOneAsync(
                           Builders <BsonDocument> .Filter.And(
                               Builders <BsonDocument> .Filter.Eq("_id", keyValues[0]),
                               Builders <BsonDocument> .Filter.Exists(DocumentHelper.ToDotPath(subKeys), false)),
                           update,
                           new UpdateOptions {
                    IsUpsert = true
                }));
            }
        }
Esempio n. 4
0
        public List <UpdateDefinition <BsonDocument> > BuildUpdatesForSave(
            UpdateDefinition <BsonDocument> update, TrackableSetTracker <T> tracker, params object[] keyValues)
        {
            var updates      = new List <UpdateDefinition <BsonDocument> >();
            var keyNamespace = DocumentHelper.ToDotPath(keyValues);

            if (tracker.AddValues.Any())
            {
                updates.Add(update == null
                    ? Builders <BsonDocument> .Update.AddToSetEach(keyNamespace, tracker.AddValues)
                    : update.AddToSetEach(keyNamespace, tracker.AddValues));
                update = null;
            }

            if (tracker.RemoveValues.Any())
            {
                updates.Add(update == null
                    ? Builders <BsonDocument> .Update.PullAll(keyNamespace, tracker.RemoveValues)
                    : update.PullAll(keyNamespace, tracker.RemoveValues));
                update = null;
            }

            if (update != null)
            {
                updates.Add(update);
            }

            return(updates);
        }
Esempio n. 5
0
        public async Task CreateAsync(IMongoCollection <BsonDocument> collection, T container, params object[] keyValues)
        {
            if (keyValues.Length == 0)
            {
                throw new ArgumentException("At least 1 keyValue required.");
            }

            var bson = ConvertToBsonDocument(container);

            if (keyValues.Length == 1)
            {
                bson.InsertAt(0, new BsonElement("_id", BsonValue.Create(keyValues[0])));
                await collection.InsertOneAsync(bson);
            }
            else
            {
                var setPath = DocumentHelper.ToDotPath(keyValues.Skip(1));
                await collection.UpdateOneAsync(
                    Builders <BsonDocument> .Filter.And(
                        Builders <BsonDocument> .Filter.Eq("_id", keyValues[0]),
                        Builders <BsonDocument> .Filter.Exists(setPath, false)),
                    Builders <BsonDocument> .Update.Set(setPath, bson),
                    new UpdateOptions { IsUpsert = true });
            }
        }
Esempio n. 6
0
        public UpdateDefinition <BsonDocument> BuildUpdatesForCreate(
            UpdateDefinition <BsonDocument> update, IList <T> list, params object[] keyValues)
        {
            var valuePath = DocumentHelper.ToDotPath(keyValues);
            var bson      = ConvertToBsonArray(list);

            return(update == null
                       ? Builders <BsonDocument> .Update.Set(valuePath, bson)
                       : update.Set(valuePath, bson));
        }
        public UpdateDefinition <BsonDocument> BuildUpdatesForCreate(
            UpdateDefinition <BsonDocument> update, T poco, params object[] keyValues)
        {
            var keyPath = DocumentHelper.ToDotPath(keyValues);
            var bson    = ConvertToBsonDocument(poco);

            return((update == null)
                       ? Builders <BsonDocument> .Update.Set(keyPath, bson)
                       : update.Set(keyPath, bson));
        }
        public UpdateDefinition <BsonDocument> BuildUpdatesForCreate(UpdateDefinition <BsonDocument> update,
                                                                     IDictionary <TKey, TValue> dictionary,
                                                                     params object[] keyValues)
        {
            var valuePath = DocumentHelper.ToDotPath(keyValues);
            var bson      = ConvertToBsonDocument(dictionary);

            return(update == null
                       ? Builders <BsonDocument> .Update.Set(valuePath, bson)
                       : update.Set(valuePath, bson));
        }
        public async Task CreateAsync(IMongoCollection <BsonDocument> collection, T value, params object[] keyValues)
        {
            var bson = ConvertToBsonDocument(value);

            if (_idProperty != null)
            {
                if (keyValues.Length == 0)
                {
                    // ConvertToBsonDocument uses BsonDocumentWrapper to serialize T
                    // but it cannot handle returned _id property.
                    // To workaround this limitation, force value to be serailized directly.
                    bson = value.ToBsonDocument(_trackableType);

                    await collection.InsertOneAsync(bson);

                    var idValue = Convert.ChangeType(bson["_id"], _idProperty.PropertyType);
                    _idProperty.SetValue(value, idValue);
                }
                else
                {
                    var keyPath = keyValues.Length > 1 ? DocumentHelper.ToDotPath(keyValues.Skip(1)) + "." : "";
                    var setPath = keyPath + _idProperty.GetValue(value);
                    await collection.UpdateOneAsync(
                        Builders <BsonDocument> .Filter.And(
                            Builders <BsonDocument> .Filter.Eq("_id", keyValues[0]),
                            Builders <BsonDocument> .Filter.Exists(setPath, false)),
                        Builders <BsonDocument> .Update.Set(setPath, bson),
                        new UpdateOptions { IsUpsert = true });
                }
            }
            else
            {
                if (keyValues.Length == 0)
                {
                    await collection.InsertOneAsync(bson);
                }
                else if (keyValues.Length == 1)
                {
                    bson["_id"] = BsonValue.Create(keyValues[0]);
                    await collection.InsertOneAsync(bson);
                }
                else
                {
                    var setPath = DocumentHelper.ToDotPath(keyValues.Skip(1));
                    await collection.UpdateOneAsync(
                        Builders <BsonDocument> .Filter.And(
                            Builders <BsonDocument> .Filter.Eq("_id", keyValues[0]),
                            Builders <BsonDocument> .Filter.Exists(setPath, false)),
                        Builders <BsonDocument> .Update.Set(setPath, bson),
                        new UpdateOptions { IsUpsert = true });
                }
            }
        }
Esempio n. 10
0
        public Task CreateAsync(IMongoCollection <BsonDocument> collection, IList <T> list, params object[] keyValues)
        {
            if (keyValues.Length < 2)
            {
                throw new ArgumentException("At least 2 keyValue required.");
            }

            var subKeys = keyValues.Skip(1).ToArray();
            var update  = BuildUpdatesForCreate(null, list, subKeys);

            return(collection.UpdateOneAsync(
                       Builders <BsonDocument> .Filter.And(
                           Builders <BsonDocument> .Filter.Eq("_id", keyValues[0]),
                           Builders <BsonDocument> .Filter.Exists(DocumentHelper.ToDotPath(subKeys), false)),
                       update,
                       new UpdateOptions {
                IsUpsert = true
            }));
        }
Esempio n. 11
0
        public List <UpdateDefinition <BsonDocument> > BuildUpdatesForSave(
            UpdateDefinition <BsonDocument> update, TrackableListTracker <T> tracker, params object[] keyValues)
        {
            var keyNamespace = DocumentHelper.ToDotPath(keyValues);

            // Multiple push-back batching optimization
            if (tracker.ChangeList.Count > 1 &&
                tracker.ChangeList.All(c => c.Operation == TrackableListOperation.PushBack))
            {
                var newValues = tracker.ChangeList.Select(c => c.NewValue);
                return(new List <UpdateDefinition <BsonDocument> >
                {
                    update == null
                        ? Builders <BsonDocument> .Update.PushEach(keyNamespace, newValues)
                        : update.PushEach(keyNamespace, newValues)
                });
            }

            // Multiple push-front batching optimization
            if (tracker.ChangeList.Count > 1 &&
                tracker.ChangeList.All(c => c.Operation == TrackableListOperation.PushFront))
            {
                var newValues = tracker.ChangeList.Select(c => c.NewValue).Reverse();
                return(new List <UpdateDefinition <BsonDocument> >
                {
                    update == null
                        ? Builders <BsonDocument> .Update.PushEach(keyNamespace, newValues, position : 0)
                        : update.PushEach(keyNamespace, newValues, position: 0)
                });
            }

            // List update can process only one change each time
            var updates = new List <UpdateDefinition <BsonDocument> >();

            foreach (var change in tracker.ChangeList)
            {
                switch (change.Operation)
                {
                case TrackableListOperation.Insert:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.PushEach(keyNamespace, new[] { change.NewValue }, position: change.Index)
                            : update.PushEach(keyNamespace, new[] { change.NewValue }, position: change.Index));
                    update = null;
                    break;

                case TrackableListOperation.Remove:
                    throw new Exception("Remove operation is not supported!");

                case TrackableListOperation.Modify:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.Set(keyNamespace + "." + change.Index, change.NewValue)
                            : update.Set(keyNamespace + "." + change.Index, change.NewValue));
                    break;

                case TrackableListOperation.PushFront:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.PushEach(keyNamespace, new[] { change.NewValue }, position: 0)
                            : update.PushEach(keyNamespace, new[] { change.NewValue }, position: 0));
                    break;

                case TrackableListOperation.PushBack:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.Push(keyNamespace, change.NewValue)
                            : update.Push(keyNamespace, change.NewValue));
                    break;

                case TrackableListOperation.PopFront:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.PopFirst(keyNamespace)
                            : update.PopFirst(keyNamespace));
                    break;

                case TrackableListOperation.PopBack:
                    updates.Add(update == null
                            ? Builders <BsonDocument> .Update.PopLast(keyNamespace)
                            : update.PopLast(keyNamespace));
                    break;
                }
            }

            if (update != null)
            {
                updates.Add(update);
            }

            return(updates);
        }