Exemple #1
0
        private static async Task SetupInitialDocuments()
        {
            var confExists = await _coll.ExistsAsync("dataLove2021");

            if (confExists.Exists)
            {
                return;
            }
            var confActivitiesExists = await _coll.ExistsAsync("dataLove2021::activities");

            if (confActivitiesExists.Exists)
            {
                return;
            }

            await _coll.InsertAsync("dataLove2021", new Conference
            {
                Name     = "Data Love 2021",
                Location = "https://datalove.konfy.care/"
            });

            await _coll.InsertAsync("dataLove2021::activities", new ConferenceActivities
            {
                ConferenceId = "dataLove2021",
                Events       = new List <ConferenceEvent>()
            });
        }
        public static Task <IMutationResult> InsertAsync <T>(this ICouchbaseCollection collection, string id, T content,
                                                             Action <InsertOptions> optionsAction)
        {
            var options = new InsertOptions();

            optionsAction(options);

            return(collection.InsertAsync(id, content, options));
        }
        protected override async Task Send(int streamIndex, IList <Message> messages)
        {
            _trace.TraceVerbose("Send called with stream index {0}.", streamIndex);

            var _msg = CouchbaseMessage.FromMessages(streamIndex, messages);

            try {
                await _collection.InsertAsync(_msg.Id, _msg);
            }
            catch (CouchbaseException exception)
            {
                _trace.TraceVerbose("Exception: {0}", exception);
            }
        }
Exemple #4
0
        public static async Task <DurabilityLevel> InsertAndVerifyDurability(ICouchbaseCollection defaultCollection, string docId,
                                                                             object sampleDoc)
        {
            var durability = DurabilityLevel.Majority;

            try
            {
                _ = await defaultCollection.InsertAsync(docId, sampleDoc, opts => opts.Durability(durability).Expiry(TimeSpan.FromMinutes(10)));
            }
            catch (DurabilityImpossibleException ex)
            {
                throw new InvalidOperationException("Bucket must support Durability.Majority, at least.", ex);
            }

            return(durability);
        }
Exemple #5
0
        public async Task GlobalSetup()
        {
            var options = new ClusterOptions()
                          .WithConnectionString("couchbase://localhost")
                          .WithCredentials("Administrator", "password");

            _cluster = await Cluster.ConnectAsync(options);

            var bucket = await _cluster.BucketAsync("default");

            _collection = bucket.DefaultCollection();

            _key = Guid.NewGuid().ToString();

            await _collection.InsertAsync(_key, new { name = "mike" }).ConfigureAwait(false);
        }
Exemple #6
0
        public async Task Does_data_access_retrieve_the_document()
        {
            // arrange - put a document in the database that can be retrieved
            var id             = "widget::" + Guid.NewGuid();
            var expectedWidget = new Widget {
                Name = "Matt's widget " + Guid.NewGuid()
            };
            await _collection.InsertAsync(id, expectedWidget);

            _documentsToDelete.Add(id);

            // act
            var actualWidget = await _dal.GetWidget(id);

            // assert
            Assert.That(actualWidget.Name, Is.EqualTo(expectedWidget.Name));
        }
Exemple #7
0
        /// <summary>
        /// Inserts a document into a collection of a bucket, and returns the ID of the new document.
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        private static async Task <string> InsertDocument(ICouchbaseCollection collection)
        {
            // hiába kezdődnek nagy betűvel a property nevek, a CB-be beírt JSON-ban kis betűvel kezdődnek; minden CB művelet kis-nagybetű érzékeny!
            var person = new
            {
                Name      = "András",
                Sex       = "male",
                BirthDate = "1981-01-13"
            };
            string personId = $"person_{DateTime.UtcNow:yyyyMMddHHmmssfff}";
            // a válaszban van egy Cas property: ez a NoSQL compare and swap ID-je, ami az SQL optimistic concurrency ID-nek felel meg, vagyis csak akkor hajtja végre
            // a szerver az írást, ha a dokumentumhoz tartozó CAS érték nem változott a CAS kiolvasása (a doksi lekérése) óta
            var mutationResult = await collection.InsertAsync(
                personId,
                person,
                new InsertOptions().Timeout(TimeSpan.FromSeconds(3)));

            return(personId);
        }
        public async Task <(ulong updatedCas, MutationToken?mutationToken)> UnstageInsertOrReplace(ICouchbaseCollection collection, string docId, ulong cas, object finalDoc, bool insertMode)
        {
            if (insertMode)
            {
                var opts         = new InsertOptions().Defaults(_durability, _keyValueTimeout);
                var mutateResult = await collection.InsertAsync(docId, finalDoc, opts).CAF();

                return(mutateResult.Cas, mutateResult?.MutationToken);
            }
            else
            {
                var opts         = GetMutateInOptions(StoreSemantics.Replace).Cas(cas);
                var mutateResult = await collection.MutateInAsync(docId, specs =>
                                                                  specs.Upsert(TransactionFields.TransactionInterfacePrefixOnly, string.Empty,
                                                                               isXattr : true, createPath : true)
                                                                  .Remove(TransactionFields.TransactionInterfacePrefixOnly, isXattr : true)
                                                                  .SetDoc(finalDoc), opts).CAF();

                return(mutateResult.Cas, mutateResult?.MutationToken);
            }
        }
 public async Task CreateWidget(string widgetId, Widget widget)
 {
     await _collection.InsertAsync(widgetId, widget);
 }
 public static Task <IMutationResult> InsertAsync <T>(this ICouchbaseCollection collection, string id, T content)
 {
     return(collection.InsertAsync(id, content, InsertOptions.Default));
 }
        /// <inheritdoc/>
        public async Task Renew(TimeSpan expiration, CancellationToken cancellationToken = default)
        {
            if (expiration <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(expiration), "Value must be positive.");
            }

            var key      = LockDocument.GetKey(Name);
            var document = new LockDocument
            {
                Holder            = Holder,
                RequestedDateTime = DateTime.UtcNow
            };

            bool            lockAcquired = false;
            IMutationResult?result       = null;

            try
            {
                if (_cas == 0)
                {
                    // We're creating a new lock
                    _logger.LogDebug("Requesting lock '{name}' for holder '{holder}' for {expiration}", Name, Holder,
                                     expiration);
                    result = await _collection.InsertAsync(key, document,
                                                           new InsertOptions().Expiry(expiration).CancellationToken(cancellationToken))
                             .ConfigureAwait(false);
                }
                else
                {
                    _logger.LogDebug("Renewing lock '{name}' for holder '{holder}' for {expiration}", Name, Holder,
                                     expiration);
                    result = await _collection.ReplaceAsync(key, document,
                                                            new ReplaceOptions().Expiry(expiration).CancellationToken(cancellationToken).Cas(_cas))
                             .ConfigureAwait(false);
                }

                lockAcquired = true;
            }
            catch (CasMismatchException)
            {
                // This is a valid case, trap the exception
                _logger.LogDebug("CAS mismatch updating lock '{name}'", Name);
            }
            catch (DocumentExistsException)
            {
                // This is a valid case, trap the exception
                _logger.LogDebug("Lock document already exists for lock '{name}'", Name);
            }
            catch (DocumentNotFoundException)
            {
                // This is a valid, but rare, case where the document being renewed expired before
                // the renewal. In this case, we'll let the logic move on, which will recreate the document.
                _logger.LogDebug("Lock document missing for lock '{name}'", Name);
            }

            if (lockAcquired)
            {
                _logger.LogDebug("Lock '{name}' issued to holder '{holder}'", Name, Holder);

                _expirationInterval = expiration;
                _cas = result !.Cas;

                return;
            }

            if (!lockAcquired)
            {
                _logger.LogDebug("Lock '{name}' unavailable, getting lock info", Name);

                IGetResult getResult;
                try
                {
                    getResult = await _collection.GetAsync(key).ConfigureAwait(false);
                }
                catch (DocumentNotFoundException)
                {
                    try
                    {
                        // Couldn't find the lock, must have expired between Insert and Get, try one more time
                        result = await _collection.InsertAsync(key, document,
                                                               new InsertOptions().Expiry(expiration).CancellationToken(cancellationToken))
                                 .ConfigureAwait(false);
                    }
                    catch (DocumentExistsException)
                    {
                        throw new CouchbaseLockUnavailableException(Name);
                    }

                    _logger.LogDebug("Lock '{name}' issued to holder '{holder}'", Name, Holder);

                    _expirationInterval = expiration;
                    _cas = result.Cas;
                    return;
                }

                _logger.LogDebug("Unable to acquire lock '{name}' for holder '{holder}'", Name, Holder);

                throw new CouchbaseLockUnavailableException(Name)
                      {
                          Holder = getResult.ContentAs <LockDocument>().Holder
                      };
            }
        }
        /// <summary>
        /// Executes a query and ingests the results as documents into Couchbase server for further analytics.
        /// <para>
        /// NOTE: This is an experimental API and may change in the future.
        /// </para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cluster"></param>
        /// <param name="collection"></param>
        /// <param name="statement"></param>
        /// <param name="ingestOptions"></param>
        /// <returns></returns>
        public static async Task <IEnumerable <IMutationResult> > IngestAsync <T>(this ICluster cluster, string statement, ICouchbaseCollection collection, IngestOptions ingestOptions = null)
        {
            //use defaults if not options not explicitly passed
            ingestOptions ??= new IngestOptions();

            if (ingestOptions.TokenValue.IsCancellationRequested)
            {
                ingestOptions.TokenValue.ThrowIfCancellationRequested();
            }

            //execute the analytics query
            var result = await cluster.AnalyticsQueryAsync <T>(
                statement,
                options => options.CancellationToken(ingestOptions.TokenValue)
                ).ConfigureAwait(false);

            // ingest result into collection
            var results = new ConcurrentBag <Task <IMutationResult> >();

            await foreach (var row in result.WithCancellation(ingestOptions.TokenValue).ConfigureAwait(false))
            {
                Task <IMutationResult> op;
                switch (ingestOptions.IngestMethodValue)
                {
                case IngestMethod.Insert:
                    op = collection.InsertAsync(
                        ingestOptions.IdGeneratorValue(row),
                        row,
                        options =>
                    {
                        options.Expiry(ingestOptions.ExpiryValue);
                        options.Timeout(ingestOptions.TimeoutValue);
                    });
                    break;

                case IngestMethod.Upsert:
                    op = collection.UpsertAsync(
                        ingestOptions.IdGeneratorValue(row),
                        row,
                        options =>
                    {
                        options.Expiry(ingestOptions.ExpiryValue);
                        options.Timeout(ingestOptions.TimeoutValue);
                    });
                    break;

                case IngestMethod.Replace:
                    op = collection.ReplaceAsync(
                        ingestOptions.IdGeneratorValue(row),
                        row,
                        options =>
                    {
                        options.Expiry(ingestOptions.ExpiryValue);
                        options.Timeout(ingestOptions.TimeoutValue);
                    });
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                results.Add(op);
            }

            return(await Task.WhenAll(results).ConfigureAwait(false));
        }
        // use this method so that the document will get removed
        // when the test is over
        protected async Task InsertTestDocument <T>(string id, T content)
        {
            await Collection.InsertAsync(id, content);

            DocumentsToRemove.Add(id);
        }