/// <summary> /// Queries the specified view using the specified options /// </summary> /// <returns>The HTTP response containing the results of the query</returns> /// <param name="context">The request context</param> /// <param name="view">The view to query</param> /// <param name="options">The options to apply to the query</param> public static CouchbaseLiteResponse QueryView(ICouchbaseListenerContext context, Database db, View view, QueryOptions options) { var result = view.QueryWithOptions(options); object updateSeq = options.UpdateSeq ? (object)view.LastSequenceIndexed : null; var mappedResult = new List <object>(); foreach (var row in result) { row.Database = db; var dict = row.AsJSONDictionary(); if (context.ContentOptions != DocumentContentOptions.None) { var doc = dict.Get("doc").AsDictionary <string, object>(); if (doc != null) { // Add content options: RevisionInternal rev = new RevisionInternal(doc); var status = new Status(); rev = DocumentMethods.ApplyOptions(context.ContentOptions, rev, context, db, status); if (rev != null) { dict["doc"] = rev.GetProperties(); } } } mappedResult.Add(dict); } var body = new Body(new NonNullDictionary <string, object> { { "rows", mappedResult }, { "total_rows", view.TotalRows }, { "offset", options.Skip }, { "update_seq", updateSeq } }); var retVal = context.CreateResponse(); retVal.JsonBody = body; return(retVal); }
/// <summary> /// Creates a dictionary of metadata for one specific revision /// </summary> /// <returns>The metadata dictionary</returns> /// <param name="rev">The revision to examine</param> /// <param name="responseState">The current response state</param> public static IDictionary <string, object> ChangesDictForRev(RevisionInternal rev, DBMonitorCouchbaseResponseState responseState) { if (responseState.ChangesIncludeDocs) { var status = new Status(); var rev2 = DocumentMethods.ApplyOptions(responseState.ContentOptions, rev, responseState.Context, responseState.Db, status); if (rev2 != null) { rev2.SetSequence(rev.GetSequence()); rev = rev2; } } return(new NonNullDictionary <string, object> { { "seq", rev.GetSequence() }, { "id", rev.GetDocId() }, { "changes", new List <object> { new Dictionary <string, object> { { "rev", rev.GetRevId() } } } }, { "deleted", rev.IsDeleted() ? (object)true : null }, { "doc", responseState.ChangesIncludeDocs ? rev.GetProperties() : null } }); }
/// <summary> /// Create and update multiple documents at the same time within a single request. /// </summary> /// <returns>The response state for further HTTP processing</returns> /// <param name="context">The context of the Couchbase Lite HTTP request</param> /// <remarks> /// http://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_bulk_docs /// <remarks> public static ICouchbaseResponseState ProcessDocumentChangeOperations(ICouchbaseListenerContext context) { return(PerformLogicWithDatabase(context, true, db => { var postBody = context.BodyAs <Dictionary <string, object> >(); if (postBody == null) { return context.CreateResponse(StatusCode.BadJson); } if (!postBody.ContainsKey("docs")) { return context.CreateResponse(StatusCode.BadParam); } var docs = postBody["docs"].AsList <IDictionary <string, object> >(); bool allOrNothing; postBody.TryGetValue <bool>("all_or_nothing", out allOrNothing); bool newEdits; postBody.TryGetValue <bool>("new_edits", out newEdits); var response = context.CreateResponse(); StatusCode status = StatusCode.Ok; bool success = db.RunInTransaction(() => { List <IDictionary <string, object> > results = new List <IDictionary <string, object> >(docs.Count); foreach (var doc in docs) { string docId = doc.GetCast <string>("_id"); RevisionInternal rev = null; Body body = new Body(doc); if (!newEdits) { if (!RevisionInternal.IsValid(body)) { status = StatusCode.BadParam; } else { rev = new RevisionInternal(body); var history = Database.ParseCouchDBRevisionHistory(doc); try { db.ForceInsert(rev, history, null); } catch (CouchbaseLiteException e) { status = e.Code; } } } else { status = DocumentMethods.UpdateDocument(context, db, docId, body, false, allOrNothing, out rev); } IDictionary <string, object> result = null; if ((int)status < 300) { Debug.Assert(rev != null && rev.GetRevId() != null); if (newEdits) { result = new Dictionary <string, object> { { "id", rev.GetDocId() }, { "rev", rev.GetRevId() }, { "status", (int)status } }; } } else if ((int)status >= 500) { return false; // abort the whole thing if something goes badly wrong } else if (allOrNothing) { return false; // all_or_nothing backs out if there's any error } else { var info = Status.ToHttpStatus(status); result = new Dictionary <string, object> { { "id", docId }, { "error", info.Item2 }, { "status", info.Item1 } }; } if (result != null) { results.Add(result); } } response.JsonBody = new Body(results.Cast <object>().ToList()); return true; }); if (!success) { response.InternalStatus = status; } return response; }).AsDefaultState()); }