private CBForestQueryEnumerator QueryEnumeratorWithOptions(QueryOptions options)
        {
            var enumerator = default(C4QueryEnumerator *);

            var startKey = options.StartKey;
            var endKey   = options.EndKey;

            if (options.Descending)
            {
                startKey = Misc.KeyForPrefixMatch(startKey, options.PrefixMatchLevel);
            }
            else
            {
                endKey = Misc.KeyForPrefixMatch(options.EndKey, options.PrefixMatchLevel);
            }
            using (var startkeydocid_ = new C4String(options.StartKeyDocId))
                using (var endkeydocid_ = new C4String(options.EndKeyDocId)) {
                    WithC4Keys(new object[] { startKey, endKey }, false, startEndKey =>
                               WithC4Keys(options.Keys == null ? null : options.Keys.ToArray(), true, c4keys =>
                    {
                        var opts            = C4QueryOptions.DEFAULT;
                        opts.descending     = options.Descending;
                        opts.endKey         = startEndKey[1];
                        opts.endKeyDocID    = endkeydocid_.AsC4Slice();
                        opts.inclusiveEnd   = options.InclusiveEnd;
                        opts.inclusiveStart = options.InclusiveStart;
                        if (c4keys != null)
                        {
                            opts.keysCount = (uint)c4keys.Length;
                        }

                        if (!options.Reduce)
                        {
                            opts.limit = (ulong)options.Limit;
                            opts.skip  = (ulong)options.Skip;
                        }

                        opts.startKey          = startEndKey[0];
                        opts.startKeyDocID     = startkeydocid_.AsC4Slice();
                        fixed(C4Key * *keysPtr = c4keys)
                        {
                            opts.keys  = keysPtr;
                            enumerator = (C4QueryEnumerator *)ForestDBBridge.Check(err => {
                                var localOpts = opts;
                                return(Native.c4view_query(IndexDB, &localOpts, err));
                            });
                        }
                    })
                               );
                }

            return(new CBForestQueryEnumerator(enumerator));
        }
        private void CloseIndex()
        {
#if CONNECTION_PER_THREAD
            var connections = _fdbConnections.Values.ToArray();
            _fdbConnections.Clear();
            foreach (var connection in connections)
            {
                ForestDBBridge.Check(err => Native.c4view_close((C4View *)connection.ToPointer(), err));
            }
#else
            var indexDb = _indexDB;
            _indexDB = null;
            ForestDBBridge.Check(err => Native.c4view_close(indexDb, err));
#endif
        }
Esempio n. 3
0
        public AtomicAction ActionToChangeEncryptionKey(SymmetricKey newKey)
        {
            return(new AtomicAction(() => {
                ForestDBBridge.Check(err =>
                {
                    var newc4key = default(C4EncryptionKey);
                    if (newKey != null)
                    {
                        newc4key = new C4EncryptionKey(newKey.KeyData);
                    }

                    return Native.c4view_rekey(IndexDB, &newc4key, err);
                });

                CloseIndex();
            }, null, null));
        }
Esempio n. 4
0
        public void DeleteView()
        {
            _dbStorage.ForgetViewStorage(Name);
#if CONNECTION_PER_THREAD
            var connections = _fdbConnections.Values.ToArray();
            var current     = IndexDB;
            _fdbConnections.Clear();
            foreach (var connection in connections)
            {
                if (connection.ToPointer() != current)
                {
                    ForestDBBridge.Check(err => Native.c4view_close((C4View *)connection.ToPointer(), err));
                    Native.c4view_free((C4View *)connection.ToPointer());
                }
            }

            ForestDBBridge.Check(err => Native.c4view_delete(current, err));
#else
            ForestDBBridge.Check(err => Native.c4view_delete(IndexDB, err));
#endif
        }
        private C4View *OpenIndexWithOptions(C4DatabaseFlags options, bool dryRun = false)
        {
            var retVal = (C4View *)ForestDBBridge.Check(err =>
            {
                var encryptionKey = default(C4EncryptionKey);
                if (_dbStorage.EncryptionKey != null)
                {
                    encryptionKey = new C4EncryptionKey(_dbStorage.EncryptionKey.KeyData);
                }

                return(Native.c4view_open(_dbStorage.Forest, _path, Name, dryRun  ? "0" : Delegate.MapVersion, options,
                                          &encryptionKey, err));
            });

            if (dryRun)
            {
                ForestDBBridge.Check(err => Native.c4view_close(retVal, err));
            }

            return(retVal);
        }
Esempio n. 6
0
        public bool UpdateIndexes(IEnumerable <IViewStore> views)
        {
            Log.To.Query.V(Tag, "Checking indexes of ({0}) for {1}", ViewNames(views), Name);

            // Creates an array of tuples -> [[view1, view1 last sequence, view1 native handle],
            // [view2, view2 last sequence, view2 native handle], ...]
            var viewsArray = views.Where(x => {
                var viewDelegate = x.Delegate;
                if (viewDelegate == null || viewDelegate.Map == null)
                {
                    Log.To.Query.V(Tag, "    {0} has no map block; skipping it", x.Name);
                    return(false);
                }

                return(true);
            }).Cast <ForestDBViewStore> ().ToArray();

            var nativeViews = new C4View *[viewsArray.Length];

            for (int i = 0; i < viewsArray.Length; i++)
            {
                nativeViews[i] = viewsArray[i].IndexDB;
            }

            var indexer = (C4Indexer *)ForestDBBridge.Check(err => Native.c4indexer_begin(_dbStorage.Forest, nativeViews, err));

            var enumerator = new CBForestDocEnumerator(indexer);

            var commit = false;

            try {
                foreach (var next in enumerator)
                {
                    var seq = next.Sequence;

                    for (int i = 0; i < viewsArray.Length; i++)
                    {
                        var info = viewsArray [i];
                        if (seq <= info.LastSequenceIndexed)
                        {
                            continue; // This view has already indexed this sequence
                        }

                        var rev    = new ForestRevisionInternal(next, true);
                        var keys   = new List <object>();
                        var values = new List <string>();

                        var conflicts = default(List <string>);
                        foreach (var leaf in new CBForestHistoryEnumerator(_dbStorage.Forest, next.Sequence, true))
                        {
                            if (leaf.SelectedRev.revID.Equals(leaf.CurrentRevID))
                            {
                                continue;
                            }

                            if (leaf.IsDeleted)
                            {
                                break;
                            }

                            if (conflicts == null)
                            {
                                conflicts = new List <string>();
                            }

                            conflicts.Add((string)leaf.SelectedRev.revID);
                        }

                        if (conflicts != null)
                        {
                            rev.SetPropertyForKey("_conflicts", conflicts);
                        }

                        try {
                            var props = rev.GetProperties();
                            info.Delegate.Map(props, (key, value) =>
                            {
                                if (key == null)
                                {
                                    Log.To.Query.W(Tag, "Emit function called with a null key; ignoring");
                                    return;
                                }

                                keys.Add(key);
                                if (props == value)
                                {
                                    values.Add("*");
                                }
                                else
                                {
                                    values.Add(Manager.GetObjectMapper().WriteValueAsString(value));
                                }
                            });
                        } catch (Exception e) {
                            Log.To.Query.W(Tag, String.Format("Exception thrown in map function of {0}, continuing", info.Name), e);
                            continue;
                        }

                        WithC4Keys(keys.ToArray(), true, c4keys =>
                                   ForestDBBridge.Check(err => Native.c4indexer_emit(indexer, next.GetDocument(), (uint)i, c4keys, values.ToArray(), err))
                                   );
                    }
                }

                commit = true;
            } catch (Exception e) {
                Log.To.Query.W(Tag, "Error updates indexes, returning false", e);
                return(false);
            } finally {
                ForestDBBridge.Check(err => Native.c4indexer_end(indexer, commit, err));
            }

            return(true);
        }
Esempio n. 7
0
 public void DeleteIndex()
 {
     ForestDBBridge.Check(err => Native.c4view_eraseIndex(IndexDB, err));
 }
Esempio n. 8
0
 public void DeleteView()
 {
     _dbStorage.ForgetViewStorage(Name);
     ForestDBBridge.Check(err => Native.c4view_delete(IndexDB, err));
 }