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 }
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)); }
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); }
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); }
public void DeleteIndex() { ForestDBBridge.Check(err => Native.c4view_eraseIndex(IndexDB, err)); }
public void DeleteView() { _dbStorage.ForgetViewStorage(Name); ForestDBBridge.Check(err => Native.c4view_delete(IndexDB, err)); }