Пример #1
0
        /// <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);
        }
Пример #2
0
 /// <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 }
     });
 }
Пример #3
0
        /// <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());
        }