public static CouchDBDocument ToCouchDBDoc(SiaqodbDocument cobj)
 {
     var doc = new CouchDBDocument() { _id = cobj.Key, doc = cobj.Content, tags = cobj.Tags };
     if (cobj.Version == string.Empty)
         doc._rev = null;
     else doc._rev = cobj.Version;
     return doc;
 }
 public static BsonDocument ToBsonDoc(SiaqodbDocument cobj)
 {
     var doc = new BsonDocument();
     doc["_id"] = cobj.Key;
     doc["_rev"] = BsonTypeMapper.MapToBsonValue(cobj.Version);
     doc["doc"] = cobj.Content;
     if (cobj.Tags != null)
     {
         foreach (string tagName in cobj.Tags.Keys)
         {
             doc[tagName] = BsonTypeMapper.MapToBsonValue(cobj.Tags[tagName]);
         }
     }
     return doc;
 }
        public async Task<StoreResponse> Store(string bucketName, SiaqodbDocument document)
        {
           
            var db = client.GetDatabase(DbName);

            var collection = db.GetCollection<BsonDocument>(bucketName);
            var newDoc = Mapper.ToBsonDoc(document);
            newDoc["_rev"] = this.GenerateNewVersion();
            try
            {
                var result = await collection.ReplaceOneAsync(filter: new BsonDocument { { "_id", document.Key }, { "_rev", BsonTypeMapper.MapToBsonValue(document.Version) } },
                                                                options: new UpdateOptions { IsUpsert = true },
                                                                 replacement: newDoc);
                var cnorResponse = new StoreResponse();
                cnorResponse.Version = newDoc["_rev"].AsString;
                cnorResponse.Key = document.Key;
                return cnorResponse;
            }
            catch (MongoWriteException ex)
            {
                if (ex.Message.Contains("duplicate key"))//conflict
                {
                    throw new ConflictException("There is a document with the same key and another version already stored");
                }
                throw ex;
            }

        }
        private async Task StartRebuildViews(MyCouchClient client, SiaqodbDocument crObjForUpdateViews)
        {
            //force building the index at Store time avoiding to wait on Query time
            if (crObjForUpdateViews.Tags != null)
            {
                foreach (string tagName in crObjForUpdateViews.Tags.Keys)
                {
                    string viewName = "tags_" + tagName;
                    QueryViewRequest query = new QueryViewRequest(viewName, viewName);
                    query.Stale = Stale.UpdateAfter;
                    query.Limit = 1;
                    var res = await client.Views.QueryAsync(query);

                }
            }
        }
        public async Task<StoreResponse> Store(string bucketName, SiaqodbDocument document)
        {
            using (var client = new MyCouchClient(DbServerUrl, bucketName))
            {
                
                await CheckTagsViews(client, bucketName, document.Tags);
                CouchDBDocument doc = Mapper.ToCouchDBDoc(document);
                var serializedObj = client.Serializer.Serialize<CouchDBDocument>(doc);

                var response = await client.Documents.PostAsync(serializedObj);
                if (response.IsSuccess)
                {
                    var cnorResponse = new StoreResponse();
                    cnorResponse.Version = response.Rev;
                    cnorResponse.Key = response.Id;

                    await this.StartRebuildViews(client, document);
                    
                    return cnorResponse;
                }
                else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    throw new BucketNotFoundException(bucketName);
                }
                else if (response.StatusCode == System.Net.HttpStatusCode.Conflict)
                {
                    throw new ConflictException(response.Reason);
                }
                else throw new GenericCouchDBException(response.Reason, response.StatusCode);
            }
        }