/// <summary>
        /// Acquire a lock with the specified <paramref name="name" /> and <paramref name="expiration" />.
        /// </summary>
        /// <param name="name">The name of the lock.</param>
        /// <param name="expiration">The amount of time before the lock will expire and be free to be acquired again.</param>
        /// <returns>
        ///   <c>true</c> if the lock was acquired; otherwise <c>false</c>
        /// </returns>
        public override bool Acquire(string name, TimeSpan expiration)
        {
            if (name == null)
                throw new ArgumentNullException(nameof(name));

            VerifyLock(name);

            // all locks that are expired
            Expression<Func<LockData, bool>> filter = m => (m.Id == name)
                && (m.Expire == null || m.Expire < DateTime.UtcNow);

            var update = Builders<LockData>.Update
                .Set(m => m.UserName, UserHelper.Current())
                .Set(m => m.MachineName, Environment.MachineName)
                .Set(m => m.Process, _process.Value)
                .Set(p => p.IsLocked, true)
                .Set(p => p.Updated, DateTime.UtcNow)
                .Set(p => p.Expire, DateTime.UtcNow.Add(expiration));

            var options = new FindOneAndUpdateOptions<LockData, LockData>
            {
                IsUpsert = false,
                ReturnDocument = ReturnDocument.After
            };


            var instance = Collection.FindOneAndUpdateAsync(filter, update, options).Result;
            return instance?.IsLocked == true;
        }
Example #2
0
         public async Task<Car> Patch([FromBody]CarPatch carInput)
         {

             var option = new FindOneAndUpdateOptions<Car, Car> { ReturnDocument = ReturnDocument.After };
             var update = Builders<Car>.Update.Set(c => c.Id, carInput.Id);
             if (carInput.Model != null) update = update.Set(c => c.Model, carInput.Model);
             if (carInput.Company != null) update = update.Set(c => c.Company, carInput.Company);
             if (carInput.Year != null) update = update.Set(c => c.Year, carInput.Year.Value);
             if (carInput.Owners != null) update = update.Set(c => c.Owners, carInput.Owners);
             return await Collection.FindOneAndUpdateAsync<Car>(c => c.Id == carInput.Id, update, option);

         }
Example #3
0
    public async Task <Player> IncrementPlayerWithoutFetch(Guid playerId, int incrementValue)
    {
        var options = new FindOneAndUpdateOptions <Player>()
        {
            ReturnDocument = ReturnDocument.After
        };

        return(await _playerCollection.FindOneAndUpdateAsync(
                   Builders <Player> .Filter.Eq(p => p.Id, playerId),
                   Builders <Player> .Update.Inc(p => p.Score, incrementValue),
                   options
                   ));
    }
Example #4
0
        public async Task <CheckList> Update(string owner, string repo, List <string> checks)
        {
            var options = new FindOneAndUpdateOptions <CheckList>
            {
                IsUpsert = true
            };

            var update = Builders <CheckList> .Update
                         .Set(r => r.CheckNames, checks)
                         .Set(d => d.UpdatedAt, DateTime.UtcNow);

            return(await collection.FindOneAndUpdateAsync <CheckList>(r => r.Owner == owner && r.Repo == repo, update, options));
        }
Example #5
0
 public UnifiedFindOneAndUpdateOperation(
     IMongoCollection <BsonDocument> collection,
     FilterDefinition <BsonDocument> filter,
     UpdateDefinition <BsonDocument> update,
     IClientSessionHandle session,
     FindOneAndUpdateOptions <BsonDocument> options)
 {
     _collection = collection;
     _filter     = filter;
     _update     = update;
     _session    = session;
     _options    = options;
 }
Example #6
0
        private int GetNextId()
        {
            var filter = Builders <CounterModel> .Filter.Eq("Id", "userId");

            var update = Builders <CounterModel> .Update.Inc(s => s.Value, 1);

            var options = new FindOneAndUpdateOptions <CounterModel> {
                IsUpsert = true, ReturnDocument = ReturnDocument.After
            };
            CounterModel c = counters.FindOneAndUpdate(filter, update, options);

            return(c.Value);
        }
Example #7
0
        /// <summary>
        /// 找到并更新
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="updateEntity">更新实体</param>
        /// <param name="isUpsert"></param>
        /// <param name="sort"></param>
        /// <param name="writeConcern">访问设置</param>
        /// <returns></returns>
        public TEntity FindOneAndUpdate(FilterDefinition <TEntity> filter, TEntity updateEntity, bool isUpsert = false
                                        , SortDefinition <TEntity> sort = null
                                        , WriteConcern writeConcern     = null)
        {
            FindOneAndUpdateOptions <TEntity> option = new FindOneAndUpdateOptions <TEntity>();

            option.IsUpsert       = isUpsert;
            option.Sort           = sort;
            option.ReturnDocument = ReturnDocument.After;
            UpdateDefinition <TEntity> update = CreateUpdateDefinition(updateEntity, isUpsert);

            return(base.GetCollection(writeConcern).FindOneAndUpdate(filter, update, option));
        }
Example #8
0
        public async Task <int> GetNextId()
        {
            var update = Builders <Sequence> .Update.Inc(x => x.Value, 1);

            var options = new FindOneAndUpdateOptions <Sequence> {
                IsUpsert       = true,
                ReturnDocument = ReturnDocument.After
            };
            var value = await Database.GetCollection <Sequence>()
                        .FindOneAndUpdateAsync <Sequence>(x => x.Name == typeof(T).Name, update, options);

            return(value.Value);
        }
Example #9
0
        public async Task <MergeRequest> UpdateShaAndClearStatusChecks(string owner, string repo, int prId, string sha)
        {
            var options = new FindOneAndUpdateOptions <MergeRequest>
            {
                IsUpsert       = false,
                ReturnDocument = ReturnDocument.After
            };
            var update = Builders <MergeRequest> .Update.Set(r => r.Sha, sha).Set(r => r.Checks, new List <CheckStatus>());

            return(await collection.FindOneAndUpdateAsync <MergeRequest>(r => r.Owner == owner &&
                                                                         r.Repo == repo &&
                                                                         r.PrId == prId, update, options));
        }
        public TProjection FindOneAndUpdate <TProjection>(
            FilterDefinition <T> filter,
            UpdateDefinition <T> update,
            FindOneAndUpdateOptions <T, TProjection>?options = null,
            CancellationToken cancellationToken = default)
        {
            if (TryGetSession(out IClientSessionHandle? session))
            {
                return(FindOneAndUpdate(session, filter, update, options, cancellationToken));
            }

            return(_collection.FindOneAndUpdate(filter, update, options, cancellationToken));
        }
        public async Task <long> GenNewId()
        {
            var options = new FindOneAndUpdateOptions <UserIdGenInfo>
            {
                ReturnDocument = ReturnDocument.After
            };

            var update = Builders <UserIdGenInfo> .Update.Inc(nameof(UserIdGenInfo.UserId), 1);

            var ret = await _dbCol.FindOneAndUpdateAsync <UserIdGenInfo>(new BsonDocument(), update, options);

            return(ret.UserId);
        }
Example #12
0
        public async Task <long> GetSequenceValue(string sequenceName)
        {
            var filter = Builders <Sequence> .Filter.Eq(s => s.SequenceName, sequenceName);

            var update = Builders <Sequence> .Update.Inc(s => s.SequenceValue, 1);

            var options = new FindOneAndUpdateOptions <Sequence, Sequence> {
                IsUpsert = true, ReturnDocument = ReturnDocument.After
            };
            var result = await _context.Sequences.FindOneAndUpdateAsync(filter, update, options);

            return(result.SequenceValue);
        }
Example #13
0
        public async Task <Player> UpdatePlayerName(Guid id, string name)
        {
            var filter = Builders <Player> .Filter.Eq(p => p.Id, id);

            var update = Builders <Player> .Update.Set(p => p.Name, name);

            var options = new FindOneAndUpdateOptions <Player>()
            {
                ReturnDocument = ReturnDocument.After
            };

            return(await _playerCollection.FindOneAndUpdateAsync(filter, update, options));
        }
Example #14
0
        /// <summary>
        /// 找到并更新
        /// </summary>
        /// <param name="filterExp"></param>
        /// <param name="updateExp"></param>
        /// <param name="isUpsert"></param>
        /// <param name="sort"></param>
        /// <param name="writeConcern">访问设置</param>
        /// <returns></returns>
        public TEntity FindOneAndUpdate(Expression <Func <TEntity, bool> > filterExp, Func <UpdateDefinitionBuilder <TEntity>, UpdateDefinition <TEntity> > updateExp, bool isUpsert = false
                                        , SortDefinition <TEntity> sort = null
                                        , WriteConcern writeConcern     = null)
        {
            var update = updateExp(Update);

            FindOneAndUpdateOptions <TEntity> option = new FindOneAndUpdateOptions <TEntity>();

            option.IsUpsert       = isUpsert;
            option.Sort           = sort;
            option.ReturnDocument = ReturnDocument.After;
            return(base.GetCollection(writeConcern).FindOneAndUpdate(filterExp, update, option));
        }
 public Task <TProjection> FindOneAndUpdateAsync <TProjection>(
     IClientSessionHandle session,
     FilterDefinition <T> filter,
     UpdateDefinition <T> update,
     FindOneAndUpdateOptions <T, TProjection>?options = null,
     CancellationToken cancellationToken = default)
 {
     return(_collection.FindOneAndUpdateAsync(session,
                                              filter,
                                              update,
                                              options,
                                              cancellationToken));
 }
Example #16
0
        public Task <TEntity> FindOneAndUpdateAsync(Expression <Func <TEntity, bool> > filterExp, UpdateDefinition <TEntity> update, bool isUpsert = false, Expression <Func <TEntity, object> > sortExp = null, SortType sortType = SortType.Ascending, WriteConcern writeConcern = null)
        {
            var options = new FindOneAndUpdateOptions <TEntity, TEntity>()
            {
                IsUpsert = isUpsert
            };

            if (sortExp != null)
            {
                options.Sort = sortType == SortType.Ascending ? Sort.Ascending(sortExp) : Sort.Descending(sortExp);
            }
            return(GetCollection(writeConcern).FindOneAndUpdateAsync(filterExp, update, options));
        }
Example #17
0
 /// <summary>
 /// 动态表查询更新单条(自动更新UpdateTime字段)
 /// </summary>
 /// <typeparam name="TForeign">文档类型</typeparam>
 /// <typeparam name="T">文档类型</typeparam>
 /// <param name="session">会话句柄(作用于事务)</param>
 /// <param name="foreignDocument">上级文档</param>
 /// <param name="filter">Lambda过滤器</param>
 /// <param name="update">更新定义</param>
 /// <param name="options">更新操作设置</param>
 /// <param name="cancellationToken">取消操作设置</param>
 /// <returns></returns>
 public T DynamicCollectionFindOneAndUpdateOne <TForeign, T>(
     IClientSessionHandle session,
     TForeign foreignDocument,
     Expression <Func <T, bool> > filter,
     UpdateDefinition <T> update,
     FindOneAndUpdateOptions <T> options = null,
     CancellationToken cancellationToken = default)
     where TForeign : BaseMongoEntity
     where T : BaseMongoEntity
 {
     return(Database.GetCollection <T>($"{typeof(T).Name}_{foreignDocument.Id}").FindOneAndUpdate(filter,
                                                                                                  update.Set(s => s.UpdateTime, DateTime.Now), options, cancellationToken));
 }
Example #18
0
        public async Task UpdateState(string owner, string repo, int prId, string state)
        {
            var options = new FindOneAndUpdateOptions <MergeRequest>
            {
                IsUpsert       = false,
                ReturnDocument = ReturnDocument.After
            };
            var update = Builders <MergeRequest> .Update.Set(r => r.State, state);

            await collection.FindOneAndUpdateAsync <MergeRequest>(r => r.Owner == owner &&
                                                                  r.Repo == repo &&
                                                                  r.PrId == prId, update, options);
        }
Example #19
0
        public async Task <UrlMapping> FindAndExtend(UrlMapping entity)
        {
            var filter = Builders <UrlMappingDocument> .Filter.Eq("LongLink", entity.LongLink);

            var options = new FindOneAndUpdateOptions <UrlMappingDocument> {
                ReturnDocument = ReturnDocument.After
            };
            var documentBefore = await Collection.FindOneAndUpdateAsync(filter,
                                                                        Builders <UrlMappingDocument> .Update.Set(s => s.ExpireAt, entity.ExpireAt),
                                                                        options);

            return(documentBefore?.AsEntity());
        }
        private void Acquire(TimeSpan timeout)
        {
            try
            {
                // If result is null, then it means we acquired the lock
                var isLockAcquired  = false;
                var now             = DateTime.Now;
                var lockTimeoutTime = now.Add(timeout);

                while (!isLockAcquired && (lockTimeoutTime >= now))
                {
                    // Acquire the lock if it does not exist - Notice: ReturnDocument.Before
                    var filter = Builders <DistributedLockDto> .Filter.Eq(_ => _.Resource, _resource);

                    var update = Builders <DistributedLockDto> .Update.SetOnInsert(_ => _.ExpireAt, DateTime.UtcNow.Add(_storageOptions.DistributedLockLifetime));

                    var options = new FindOneAndUpdateOptions <DistributedLockDto>
                    {
                        IsUpsert       = true,
                        ReturnDocument = ReturnDocument.Before
                    };
                    var result = _database.DistributedLock.FindOneAndUpdate(filter, update, options);

                    // If result is null, it means we acquired the lock
                    if (result == null)
                    {
                        isLockAcquired = true;
                    }
                    else
                    {
                        var waitTime = (int)timeout.TotalMilliseconds / 10;
                        // Sleep for a while and then check if the lock has been released.
                        Thread.Sleep(waitTime);
                        now = DateTime.Now;
                    }
                }

                if (!isLockAcquired)
                {
                    throw new DistributedLockTimeoutException($"Could not place a lock on the resource \'{_resource}\': The lock request timed out.");
                }
            }
            catch (DistributedLockTimeoutException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new MongoDistributedLockException($"Could not place a lock on the resource \'{_resource}\': Check inner exception for details.", ex);
            }
        }
        public static int GetNextSequence <T>() where T : IBaseApiModel
        {
            var collection = MongoDbProvider.db.GetCollection <Counter>("counter");
            var update     = Builders <Counter> .Update.Inc("seq", 1); //seq:1

            var options = new FindOneAndUpdateOptions <Counter>()
            {
                IsUpsert       = true,
                ReturnDocument = ReturnDocument.After
            };
            var ret = collection.FindOneAndUpdate <Counter>(x => x._id == typeof(T).Name.ToLower(), update, options);

            return(ret.seq);
        }
        public async Task <Player> IncrementPlayerScore(Guid id, int increment)
        {
            var filter = Builders <Player> .Filter.Eq(p => p.Id, id);

            var scoreIncrementUpdate = Builders <Player> .Update.Inc(p => p.Score, increment);

            var options = new FindOneAndUpdateOptions <Player>()
            {
                ReturnDocument = ReturnDocument.After
            };
            Player p = await playersCollection.FindOneAndUpdateAsync(filter, scoreIncrementUpdate, options);

            return(p);
        }
        public void FindOneAndUpdateAsync_with_an_expression_and_result_options_should_call_collection_with_the_correct_filter()
        {
            var subject = CreateSubject();
            var update  = new BsonDocument();
            var options = new FindOneAndUpdateOptions <Person, BsonDocument>();

            subject.FindOneAndUpdateAsync(x => x.FirstName == "Jack", update, options);

            subject.Received().FindOneAndUpdateAsync <BsonDocument>(
                Arg.Any <ExpressionFilterDefinition <Person> >(),
                Arg.Is <BsonDocumentUpdateDefinition <Person> >(x => x.Document == update),
                options,
                default(CancellationToken));
        }
Example #24
0
        public User AddUserContacts(string userId, Contact contact)
        {
            var filter = Builders <User> .Filter.Eq(u => u.Id, userId);

            var update = Builders <User> .Update.AddToSet <Contact>(u => u.Contacts, contact);

            var opts = new FindOneAndUpdateOptions <User>()
            {
                IsUpsert       = false,
                ReturnDocument = ReturnDocument.After
            };

            return(_users.FindOneAndUpdate(filter, update, opts));
        }
    public async Task <Player> UpdateSessionCount(string id)
    {
        var filter = Builders <Player> .Filter.Eq(p => p.Id, id);

        var sessionUpdate = Builders <Player> .Update.Inc(p => p.Sessions, 1);

        var options = new FindOneAndUpdateOptions <Player>()
        {
            ReturnDocument = ReturnDocument.After
        };
        Player p = await _playerCollection.FindOneAndUpdateAsync(filter, sessionUpdate, options);

        return(p);
    }
        public async Task <Player> UpdatePlayerScore(string name, int newScoreNumber)
        {
            var filter = Builders <Player> .Filter.Eq(p => p.Name, name);

            var scoreNumberUpdate = Builders <Player> .Update.Set(p => p.Score, newScoreNumber);

            var options = new FindOneAndUpdateOptions <Player>()
            {
                ReturnDocument = ReturnDocument.After
            };
            Player player = await playersCollection.FindOneAndUpdateAsync(filter, scoreNumberUpdate, options);

            return(player);
        }
Example #27
0
        public async Task <Player> IncrementPlayerScore(Guid playerId, int added)
        {
            var filter = Builders <Player> .Filter.Eq("_id", playerId);

            var temp = Builders <Player> .Update.Inc(p => p.Score, added);

            var settings = new FindOneAndUpdateOptions <Player>()
            {
                ReturnDocument = ReturnDocument.After
            };
            Player player = await _collection.FindOneAndUpdateAsync(filter, temp, settings);

            return(player);
        }
Example #28
0
        public async Task <PostViewModel> IncViewsAsync(string id)
        {
            var builder = Builders <Post> .Filter;
            var filter  = builder.Eq(el => el.Id, id);

            var update  = new UpdateDefinitionBuilder <Post>().Inc(el => el.Views, 1);
            var options = new FindOneAndUpdateOptions <Post>();

            options.ReturnDocument = ReturnDocument.After;
            options.Projection     = new ProjectionDefinitionBuilder <Post>().Include(el => el.Likes);
            var result = await _context.Posts.FindOneAndUpdateAsync <Post>(filter, update, options);

            return(_mapper.Map <PostViewModel>(result));
        }
Example #29
0
        public async Task <Player> IncrementPlayerScore(string id, int increment)
        {
            var filter = Builders <Player> .Filter.Eq("_id", id);

            var incrementScoreUpdate = Builders <Player> .Update.Inc(p => p.Score, increment);

            var options = new FindOneAndUpdateOptions <Player>()
            {
                ReturnDocument = ReturnDocument.After
            };
            Player player = await _collection.FindOneAndUpdateAsync(filter, incrementScoreUpdate, options);

            return(player);
        }
Example #30
0
        /// <summary>
        /// 找到并更新
        /// </summary>
        /// <param name="filterExp"></param>
        /// <param name="updateEntity">更新实体</param>
        /// <param name="isUpsert"></param>
        /// <param name="sortExp"></param>
        /// <param name="sortType"></param>
        /// <param name="writeConcern">访问设置</param>
        /// <returns></returns>
        public TEntity FindOneAndUpdate(Expression <Func <TEntity, bool> > filterExp, TEntity updateEntity, bool isUpsert = false
                                        , Expression <Func <TEntity, object> > sortExp = null, SortType sortType = SortType.Ascending
                                        , WriteConcern writeConcern = null)
        {
            FindOneAndUpdateOptions <TEntity> option = new FindOneAndUpdateOptions <TEntity>();

            option.IsUpsert       = isUpsert;
            option.Sort           = base.CreateSortDefinition(sortExp, sortType);
            option.ReturnDocument = ReturnDocument.After;

            UpdateDefinition <TEntity> update = CreateUpdateDefinition(updateEntity, isUpsert);

            return(base.GetCollection(writeConcern).FindOneAndUpdate(filterExp, update, option));
        }
Example #31
0
        public async Task <ParkModel> Update(Guid guid, ParkModel park)
        {
            var updateOptions = new FindOneAndUpdateOptions <ParkModel>()
            {
                ReturnDocument = ReturnDocument.After
            };

            var filterDefinition = Builders <ParkModel> .Filter.Eq("_id", guid.ToString());

            var updateDefinition = Builders <ParkModel> .Update.Set("name", park.Name).
                                   Set("address", park.Address);

            return(await _collection.FindOneAndUpdateAsync(filterDefinition, updateDefinition, updateOptions));
        }
Example #32
0
        public void FindOneAndUpdateAsync_should_include_the_filter()
        {
            var subject = CreateSubject();
            var update  = new BsonDocument("$set", new BsonDocument("x", 5));
            var options = new FindOneAndUpdateOptions <B>();

            subject.FindOneAndUpdateAsync(_providedFilter, update, options, CancellationToken.None);

            _derivedCollection.Received().FindOneAndUpdateAsync(
                Arg.Is <FilterDefinition <B> >(f => RenderFilter(f).Equals(_expectedFilter)),
                Arg.Is <UpdateDefinition <B> >(u => RenderUpdate(u).Equals(BsonDocument.Parse("{$set: {x: 5}}"))),
                options,
                CancellationToken.None);
        }
        /// <summary>
        /// Acquire a lock with the specified <paramref name="name" /> and <paramref name="expiration" />.
        /// </summary>
        /// <param name="name">The name of the lock.</param>
        /// <param name="expiration">The amount of time before the lock will expire and be free to be acquired again.</param>
        /// <param name="wait">The wait.</param>
        /// <returns>
        ///   <c>true</c> if the lock was acquired; otherwise <c>false</c></returns>
        public bool Acquire(string name, TimeSpan expiration, TimeSpan wait)
        {
            if (name == null)
                throw new ArgumentNullException(nameof(name));

            VerifyLock(name);

            // all locks that are not locked or expired
            Expression<Func<LockData, bool>> filter = m => (m.Id == name)
                && (m.IsLocked == false || (m.Expire.HasValue && m.Expire < DateTime.UtcNow));

            var update = Builders<LockData>.Update
                .Set(m => m.UserName, UserHelper.Current())
                .Set(m => m.MachineName, Environment.MachineName)
                .Set(m => m.Process, _process.Value)
                .Set(p => p.IsLocked, true)
                .Set(p => p.Updated, DateTime.UtcNow)
                .Set(p => p.Expire, DateTime.UtcNow.Add(expiration));

            var options = new FindOneAndUpdateOptions<LockData, LockData>();
            options.IsUpsert = false;
            options.ReturnDocument = ReturnDocument.After;


            var timeout = DateTime.UtcNow.Add(wait);
            do
            {
                var instance = Collection.FindOneAndUpdateAsync(filter, update, options).Result;
                if (instance?.IsLocked == true)
                    return true;

                // keep trying till timeout
                var delay = (int) (wait.TotalMilliseconds * .1);
                Thread.Sleep(delay);

            } while (timeout > DateTime.UtcNow);


            return false;
        }
        /// <summary>
        /// Schedules the message with specified identifier for processing on the <paramref name="scheduled"/> date and time.
        /// </summary>
        /// <param name="id">The message identifier to schedule.</param>
        /// <param name="scheduled">The date and time of the scheduled processing.</param>
        /// <returns>
        /// The <see cref="Task" /> representing the asynchronous operation.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="id"/> is <see langword="null" />.</exception>
        public Task<Message> Schedule(string id, DateTime scheduled)
        {
            if (id == null)
                throw new ArgumentNullException("id");

            var filter = Builders<Message>.Filter
                .Eq(p => p.Id, id);

            var update = Builders<Message>.Update
                .Set(p => p.State, MessageState.Scheduled)
                .Set(p => p.Scheduled, scheduled.ToUniversalTime())
                .Set(p => p.Updated, DateTime.UtcNow)
                .Unset(p => p.Expire);  


            var options = new FindOneAndUpdateOptions<Message, Message>();
            options.IsUpsert = false;
            options.ReturnDocument = ReturnDocument.After;

            return _collection.FindOneAndUpdateAsync(filter, update, options);
        }
        public void FindOneAndUpdateAsync_with_an_expression_and_result_options_should_call_collection_with_the_correct_filter(
            [Values(false, true)] bool async)
        {
            var subject = CreateSubject();
            var update = new BsonDocument();
            var options = new FindOneAndUpdateOptions<Person, BsonDocument>();

            if (async)
            {
                subject.FindOneAndUpdateAsync(x => x.FirstName == "Jack", update, options);

                subject.Received().FindOneAndUpdateAsync<BsonDocument>(
                    Arg.Any<ExpressionFilterDefinition<Person>>(),
                    Arg.Is<BsonDocumentUpdateDefinition<Person>>(x => x.Document == update),
                    options,
                    default(CancellationToken));
            }
            else
            {
                subject.FindOneAndUpdate(x => x.FirstName == "Jack", update, options);

                subject.Received().FindOneAndUpdate<BsonDocument>(
                    Arg.Any<ExpressionFilterDefinition<Person>>(),
                    Arg.Is<BsonDocumentUpdateDefinition<Person>>(x => x.Document == update),
                    options,
                    default(CancellationToken));
            }
        }
        public BsonDocument UpdateShirt(ShirtEditViewModel model)
        {
            var images = new BsonArray(model.sources);

            var filter = new BsonDocument("id", new ObjectId(model.Id));
            var update = Builders<BsonDocument>.Update
                .Set("title", model.title)
                .Set("type", model.series)
                .Set("handle", model.title.ToLower().Replace(' ', '-'))
                .Set("price", model.price)
                .Set("images", images)
                .Set("description", model.description ?? model.series);
            var options = new FindOneAndUpdateOptions<BsonDocument>
            {
                ReturnDocument = ReturnDocument.After
            };
            return collection.FindOneAndUpdateAsync(filter, update, options).Result;
        }
 public BsonDocument UpdateShirt(string id, string field, string value)
 {
     var filter = new BsonDocument("id", new ObjectId(id));
     var update = Builders<BsonDocument>.Update
         .Set(field, value);
     var options = new FindOneAndUpdateOptions<BsonDocument>
     {
         ReturnDocument = ReturnDocument.After
     };
     return collection.FindOneAndUpdateAsync(filter, update, options).Result;
 }
        /// <summary>
        /// Dequeues the next queued message for processing as an asynchronous operation.
        /// </summary>
        /// <returns>
        /// The <see cref="Task" /> representing the asynchronous operation.
        /// </returns>
        public Task<Message> Dequeue()
        {
            var filter = Builders<Message>.Filter
                .Eq(m => m.State, MessageState.Queued);

            var update = Builders<Message>.Update
                .Set(m => m.State, MessageState.Processing)
                .Set(p => p.Status, "Begin processing ...")
                .Set(p => p.StartTime, DateTime.UtcNow)
                .Set(p => p.Updated, DateTime.UtcNow);

            // sort by priority then by insert order
            var sort = Builders<Message>.Sort
                .Ascending(m => m.Priority)
                .Ascending(m => m.Id);

            var options = new FindOneAndUpdateOptions<Message, Message>();
            options.IsUpsert = false;
            options.ReturnDocument = ReturnDocument.After;
            options.Sort = sort;

            return _collection.FindOneAndUpdateAsync(filter, update, options);
        }
        /// <summary>
        /// Updates the status of the message with specified <paramref name="id" /> as an asynchronous operation..
        /// </summary>
        /// <param name="id">The identifier of the message.</param>
        /// <param name="status">The status display mesage.</param>
        /// <param name="step">The current processing step.</param>
        /// <returns>
        /// The <see cref="Task" /> representing the asynchronous operation.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="id"/> is <see langword="null" />.</exception>
        public Task<Message> UpdateStatus(string id, string status, int? step = null)
        {
            if (id == null)
                throw new ArgumentNullException("id");

            var filter = Builders<Message>.Filter
                .Eq(p => p.Id, id);

            var update = Builders<Message>.Update
                .Set(p => p.Updated, DateTime.UtcNow);

            if (!string.IsNullOrEmpty(status))
                update.Set(p => p.Status, status);

            if (step.HasValue)
                update.Set(p => p.Step, step.Value);

            var options = new FindOneAndUpdateOptions<Message, Message>();
            options.IsUpsert = false;
            options.ReturnDocument = ReturnDocument.After;

            return _collection.FindOneAndUpdateAsync(filter, update, options);
        }
        /// <summary>
        /// Marks the processing complete for the message with specified <paramref name="id" /> as an asynchronous operation..
        /// </summary>
        /// <param name="id">The identifier of the message.</param>
        /// <param name="messageResult">The result of the processing.</param>
        /// <param name="status">The status display mesage.</param>
        /// <param name="expireDate">The expire date.</param>
        /// <returns>
        /// The <see cref="Task" /> representing the asynchronous operation.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="id"/> is <see langword="null" />.</exception>
        public Task<Message> MarkComplete(string id, MessageResult messageResult, string status = null, DateTime? expireDate = null)
        {
            if (id == null)
                throw new ArgumentNullException("id");

            var filter = Builders<Message>.Filter
                .Eq(p => p.Id, id);

            var update = Builders<Message>.Update
                .Set(p => p.State, MessageState.Complete)
                .Set(p => p.Result, messageResult)
                .Set(p => p.EndTime, DateTime.UtcNow)
                .Set(p => p.Updated, DateTime.UtcNow);

            update = expireDate.HasValue 
                ? update.Set(p => p.Expire, expireDate.Value) 
                : update.Unset(p => p.Expire);

            if (!string.IsNullOrEmpty(status))
                update = update.Set(p => p.Status, status);

            if (messageResult == MessageResult.Error)
                update = update.Inc(p => p.ErrorCount, 1);

            var options = new FindOneAndUpdateOptions<Message, Message>();
            options.IsUpsert = false;
            options.ReturnDocument = ReturnDocument.After;

            return _collection.FindOneAndUpdateAsync(filter, update, options);
        }