public async Task<BatchSet> GetChanges(string bucketName, Filter query, int limit, string anchor, string uploadAnchor) { var db = client.GetDatabase("local"); var collection = db.GetCollection<BsonDocument>("oplog.rs"); var filterBuilder = Builders<BsonDocument>.Filter; FilterDefinition<BsonDocument> filter = filterBuilder.Eq("ns", DbName + "." + bucketName); if (anchor != null) { filter = filter & filterBuilder.Gt("ts", new BsonTimestamp(Convert.ToInt64(anchor))); } var docs = await collection.Find(filter).Limit(limit).ToListAsync(); BatchSet bs = new BatchSet(); SyncLogItem logItem = null; if (docs != null && docs.Count > 0 && !string.IsNullOrEmpty(uploadAnchor)) { logItem = await GetSyncLogItem(uploadAnchor); } int i = 0; foreach (var doc in docs) { if (i == docs.Count - 1) { bs.Anchor = doc["ts"].AsBsonTimestamp.ToString(); } i++; if (doc["op"] == "i" || doc["op"] == "u") { this.AddChangedDoc(bs, doc, logItem, query); } else if (doc["op"] == "d") { this.AddDeletedDoc(bs, doc, logItem); } } return bs; }
private bool OutOfFilter(Filter query, BsonDocument nestedDoc) { if (query == null) return false; string tagName = query.TagName; if (query.TagName == "key") { tagName = "_id"; } if (!nestedDoc.Names.Contains(tagName)) { return true; } IComparable docValue = (IComparable)BsonTypeMapper.MapToDotNetValue(nestedDoc[tagName]); if (query.Value != null && docValue.CompareTo((IComparable)query.Value) != 0) { return true; } if (query.Start != null && docValue.CompareTo((IComparable)query.Start) < 0) return true; if (query.End != null && docValue.CompareTo((IComparable)query.End) > 0) return true; return false; }
private void AddChangedDoc(BatchSet bs, BsonDocument doc, SyncLogItem logItem, Filter query) { if (bs.ChangedDocuments == null) bs.ChangedDocuments = new List<SiaqodbDocument>(); var nestedDoc = doc["o"].AsBsonDocument; if (logItem != null && logItem.KeyVersion != null && logItem.KeyVersion.ContainsKey(nestedDoc["_id"].AsString) && logItem.KeyVersion[nestedDoc["_id"].AsString] == nestedDoc["_rev"].AsString) return; if (OutOfFilter(query, nestedDoc)) return; SiaqodbDocument siaqodbDoc = Mapper.ToSiaqodbDocument(nestedDoc); bs.ChangedDocuments.Add(siaqodbDoc); }
private bool OutOfFilter(Filter query, CouchDBDocument co) { if (query == null) return false; string tagName = query.TagName; if (query.TagName == "key") { tagName = "_id"; } else if (!co.tags.Keys.Contains(tagName)) { return true; } IComparable docValue = null; if (query.TagName == "key") { docValue = co._id; } else { docValue = co.tags[tagName] as IComparable; } if (query.Value != null && docValue.CompareTo((IComparable)query.Value) != 0) { return true; } if (query.Start != null && docValue.CompareTo((IComparable)query.Start) < 0) return true; if (query.End != null && docValue.CompareTo((IComparable)query.End) > 0) return true; return false; }
private void AddChangedDoc(BatchSet changeSet, ChangesResponse<string>.Row row, SyncLogItem logItem, Filter query, MyCouch.Serialization.ISerializer serializer) { if (changeSet.ChangedDocuments == null) changeSet.ChangedDocuments = new List<SiaqodbDocument>(); CouchDBDocument co = serializer.Deserialize<CouchDBDocument>(row.IncludedDoc); if (co._id.StartsWith("_design/")) return; //check uploaded anchor- means cliet just uploaded this record and we should not return back if (logItem != null && logItem.KeyVersion != null && logItem.KeyVersion.ContainsKey(co._id) && logItem.KeyVersion[co._id] == co._rev) return; if (OutOfFilter(query, co)) return; changeSet.ChangedDocuments.Add(Mapper.ToSiaqodbDocument(co)); }
public async Task<BatchSet> GetChanges(string bucketName, Filter query, int limit, string anchor,string uploadAnchor) { using (var client = new MyCouchClient(DbServerUrl, bucketName)) { GetChangesRequest changesReq = new GetChangesRequest(); changesReq.Since = anchor; changesReq.Limit = limit; changesReq.IncludeDocs = true; var response = await client.Changes.GetAsync(changesReq); if (response.IsSuccess) { BatchSet changeSet = new BatchSet(); if (response.Results != null) { SyncLogItem logItem = await this.GetSyncLogItem(uploadAnchor); foreach (var row in response.Results) { if (row.Deleted) { this.AddDeletedDoc(changeSet, row, logItem); } else { this.AddChangedDoc(changeSet, row, logItem, query,client.Serializer ); } } changeSet.Anchor = response.LastSeq; } return changeSet; } else CheckBucketNotFound(bucketName, response); return null; } }