Esempio n. 1
0
        public IEnumerable <QueryRow> RegularQuery(QueryOptions options)
        {
            var optionsCopy = options.Copy(); // Needed because Count() and ElementAt() will share this
            var filter      = optionsCopy.Filter;
            var limit       = Int32.MaxValue;
            var skip        = 0;

            if (filter != null)
            {
                // If a filter is present, these need to be applied to the filter
                // and not the query
                limit             = optionsCopy.Limit;
                skip              = optionsCopy.Skip;
                optionsCopy.Limit = Int32.MaxValue;
                optionsCopy.Skip  = 0;
            }

            var enumerator = QueryEnumeratorWithOptions(optionsCopy);

            foreach (var next in enumerator)
            {
                var key         = CouchbaseBridge.DeserializeKey <object>(next.Key);
                var value       = (next.Value as IEnumerable <byte>).ToArray();
                var docRevision = default(RevisionInternal);
                if (value.Length == 1 && value[0] == 42)
                {
                    docRevision = _dbStorage.GetDocument(next.DocID, null, true);
                }
                else
                {
                    docRevision = _dbStorage.GetDocument(next.DocID, null, optionsCopy.IncludeDocs);
                }

                var row = new QueryRow(next.DocID, next.DocSequence, key, value, docRevision, this);
                if (filter != null)
                {
                    if (!filter(row))
                    {
                        continue;
                    }

                    if (skip > 0)
                    {
                        skip--;
                        continue;
                    }

                    if (limit-- == 0)
                    {
                        yield break;
                    }
                }

                Log.To.Query.V(Tag, "Query {0} found row with key={1}, value={2}, id={3}", Name,
                               new SecureLogJsonString(key, LogMessageSensitivity.PotentiallyInsecure),
                               new SecureLogString(value, LogMessageSensitivity.PotentiallyInsecure),
                               new SecureLogString(next.DocID, LogMessageSensitivity.PotentiallyInsecure));
                yield return(row);
            }
        }
Esempio n. 2
0
        public static void WithC4Keys(object[] keySources, bool writeNull, C4KeyActionDelegate action)
        {
            if (keySources == null)
            {
                action(null);
                return;
            }

            var c4Keys = new C4Key *[keySources.Length];

            for (int i = 0; i < keySources.Length; i++)
            {
                if (keySources[i] == null && !writeNull)
                {
                    c4Keys[i] = null;
                }
                else
                {
                    c4Keys[i] = CouchbaseBridge.SerializeToKey(keySources[i]);
                }
            }

            try {
                action(c4Keys);
            } finally {
                foreach (C4Key *key in c4Keys)
                {
                    Native.c4key_free(key);
                }
            }
        }
Esempio n. 3
0
        public IEnumerable <QueryRow> ReducedQuery(QueryOptions options)
        {
            var groupLevel = options.GroupLevel;
            var group      = options.Group || groupLevel > 0;

            var reduce = Delegate == null ? null : Delegate.Reduce;

            if (options.ReduceSpecified)
            {
                if (!options.Reduce)
                {
                    reduce = null;
                }
                else if (reduce == null)
                {
                    throw Misc.CreateExceptionAndLog(Log.To.Query, StatusCode.BadParam, Tag,
                                                     "Cannot use reduce option in view {0} which has no reduce block defined", Name);
                }
            }

            var lastKey      = default(object);
            var filter       = options.Filter;
            var keysToReduce = default(IList <object>);
            var valsToReduce = default(IList <object>);

            if (reduce != null)
            {
                keysToReduce = new List <object>(100);
                valsToReduce = new List <object>(100);
            }

            var enumerator = QueryEnumeratorWithOptions(options);

            var row = default(QueryRow);

            foreach (var next in enumerator)
            {
                var key   = CouchbaseBridge.DeserializeKey <object>(next.Key);
                var value = default(object);
                if (lastKey != null && (key == null || (group && !GroupTogether(lastKey, key, groupLevel))))
                {
                    // key doesn't match lastKey; emit a grouped/reduced row for what came before:
                    row = CreateReducedRow(lastKey, group, groupLevel, reduce, filter, keysToReduce, valsToReduce);
                    keysToReduce.Clear();
                    valsToReduce.Clear();
                    if (row != null)
                    {
                        var rowCopy = row;
                        Log.To.Query.V(Tag, "Query {0} reduced row with key={1} value={2}", Name,
                                       new SecureLogJsonString(key, LogMessageSensitivity.PotentiallyInsecure),
                                       new SecureLogJsonString(value, LogMessageSensitivity.PotentiallyInsecure));
                        row = null;
                        yield return(rowCopy);
                    }
                }

                if (key != null && reduce != null)
                {
                    // Add this key/value to the list to be reduced:
                    keysToReduce.Add(key);
                    var nextVal = next.Value;
                    if (nextVal.size == 1 && nextVal.ElementAt(0) == (byte)'*')
                    {
                        try {
                            var rev = _dbStorage.GetDocument(next.DocID, next.DocSequence);
                            value = rev.GetProperties();
                        } catch (CouchbaseLiteException e) {
                            Log.To.Query.W(Tag, "Couldn't load doc for row value: status {0}", e.CBLStatus.Code);
                        } catch (Exception e) {
                            Log.To.Query.W(Tag, "Couldn't load doc for row value", e);
                        }
                    }
                    else
                    {
                        value = Manager.GetObjectMapper().ReadValue <object>(next.Value);
                    }

                    valsToReduce.Add(value);
                }

                lastKey = key;
            }

            row = CreateReducedRow(lastKey, group, groupLevel, reduce, filter, keysToReduce, valsToReduce);
            if (row != null)
            {
                yield return(row);
            }
        }