private unsafe void SaveProperties(IDictionary <string, object> props, string docID) { Db.InBatch(() => { var tricky = (C4Document *)LiteCoreBridge.Check(err => Native.c4doc_get(Db.c4db, docID, true, err)); var put = new C4DocPutRequest { docID = tricky->docID, history = &tricky->revID, historyCount = 1, save = true }; var enc = Native.c4db_getSharedFleeceEncoder(Db.c4db); props.FLEncode(enc); var body = NativeRaw.FLEncoder_Finish(enc, null); put.body = (C4Slice)body; LiteCoreBridge.Check(err => { var localPut = put; var retVal = Native.c4doc_put(Db.c4db, &localPut, null, err); Native.FLSliceResult_Free(body); return(retVal); }); }); }
public override void Flush() { FLError err; Result = NativeRaw.FLEncoder_Finish(_encoder, &err); if (Result.buf == null) { throw new LiteCoreException(new C4Error(err)); } }
public void TestLegacyProperties() { RunTestVariants(() => { Native.c4doc_isOldMetaProperty("_attachments").Should().BeTrue(); Native.c4doc_isOldMetaProperty("@type").Should().BeFalse(); var enc = Native.c4db_getSharedFleeceEncoder(Db); LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err)); try { Native.FLEncoder_BeginDict(enc, 2); Native.FLEncoder_WriteKey(enc, "@type"); Native.FLEncoder_WriteString(enc, "blob"); Native.FLEncoder_WriteKey(enc, "digest"); Native.FLEncoder_WriteString(enc, String.Empty); Native.FLEncoder_EndDict(enc); } finally { LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err)); } var result = NativeRaw.FLEncoder_Finish(enc, null); ((long)result.buf).Should().NotBe(0); try { var val = NativeRaw.FLValue_FromTrustedData((FLSlice)result); var d = Native.FLValue_AsDict(val); ((long)d).Should().NotBe(0); var key = Native.c4db_initFLDictKey(Db, "@type"); var keyStr = Native.FLDictKey_GetString(&key); keyStr.Should().Be("@type"); var testVal = Native.FLDict_GetWithKey(d, &key); Native.FLValue_AsString(testVal).Should().Be("blob"); Native.c4doc_dictContainsBlobs(d, Native.c4db_getFLSharedKeys(Db)).Should().BeTrue(); } finally { Native.FLSliceResult_Free(result); } enc = Native.c4db_getSharedFleeceEncoder(Db); Native.FLEncoder_BeginDict(enc, 0); Native.FLEncoder_EndDict(enc); result = NativeRaw.FLEncoder_Finish(enc, null); ((long)result.buf).Should().NotBe(0); try { var val = NativeRaw.FLValue_FromTrustedData((FLSlice)result); var d = Native.FLValue_AsDict(val); ((long)d).Should().NotBe(0); Native.c4doc_dictContainsBlobs(d, Native.c4db_getFLSharedKeys(Db)).Should().BeFalse(); } finally { Native.FLSliceResult_Free(result); } }); }
static Test() { var enc = Native.FLEncoder_New(); Native.FLEncoder_BeginDict(enc, 1); Native.FLEncoder_WriteKey(enc, "answer"); Native.FLEncoder_WriteInt(enc, 42); Native.FLEncoder_EndDict(enc); var result = NativeRaw.FLEncoder_Finish(enc, null); FleeceBody = result; }
internal void AddPersonInState(string docID, string state, string firstName = null) { LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err)); C4Error error; var enc = Native.c4db_getSharedFleeceEncoder(Db); try { Native.FLEncoder_BeginDict(enc, 3); Native.FLEncoder_WriteKey(enc, "custom"); Native.FLEncoder_WriteBool(enc, true); if (!string.IsNullOrEmpty(firstName)) { Native.FLEncoder_WriteKey(enc, "name"); Native.FLEncoder_BeginDict(enc, 2); Native.FLEncoder_WriteKey(enc, "first"); Native.FLEncoder_WriteString(enc, firstName); Native.FLEncoder_WriteKey(enc, "last"); Native.FLEncoder_WriteString(enc, "lastname"); Native.FLEncoder_EndDict(enc); } Native.FLEncoder_WriteKey(enc, "contact"); Native.FLEncoder_BeginDict(enc, 1); Native.FLEncoder_WriteKey(enc, "address"); Native.FLEncoder_BeginDict(enc, 1); Native.FLEncoder_WriteKey(enc, "state"); Native.FLEncoder_WriteString(enc, state); Native.FLEncoder_EndDict(enc); Native.FLEncoder_EndDict(enc); Native.FLEncoder_EndDict(enc); // Save document: FLSliceResult body = NativeRaw.FLEncoder_Finish(enc, null); //REQUIRE(body.buf); using (var docID_ = new C4String(docID)){ var rq = new C4DocPutRequest { allowConflict = false, docID = docID_.AsFLSlice(), allocedBody = body, save = true }; C4Document *doc; doc = Native.c4doc_put(Db, &rq, null, &error); ((long)doc).Should().NotBe(0, "because otherwise the put failed"); Native.c4doc_release(doc); Native.FLSliceResult_Release(body); } } finally { LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err)); } }
static Test() { #if NETCOREAPP2_0 Couchbase.Lite.Support.NetDesktop.Activate(); #endif var enc = Native.FLEncoder_New(); Native.FLEncoder_BeginDict(enc, 1); Native.FLEncoder_WriteKey(enc, "answer"); Native.FLEncoder_WriteInt(enc, 42); Native.FLEncoder_EndDict(enc); var result = NativeRaw.FLEncoder_Finish(enc, null); FleeceBody = (C4Slice)result; }
static Test() { #if NETCOREAPP2_1 && !CBL_NO_VERSION_CHECK Couchbase.Lite.Support.NetDesktop.CheckVersion(); #endif var enc = Native.FLEncoder_New(); Native.FLEncoder_BeginDict(enc, 1); Native.FLEncoder_WriteKey(enc, "ans*wer"); Native.FLEncoder_WriteInt(enc, 42); Native.FLEncoder_EndDict(enc); var result = NativeRaw.FLEncoder_Finish(enc, null); FleeceBody = (FLSlice)result; }
static Test() { #if NETCOREAPP1_0 LoadDLL(); #endif var enc = Native.FLEncoder_New(); Native.FLEncoder_BeginDict(enc, 1); Native.FLEncoder_WriteKey(enc, "answer"); Native.FLEncoder_WriteInt(enc, 42); Native.FLEncoder_EndDict(enc); var result = NativeRaw.FLEncoder_Finish(enc, null); FleeceBody = result; }
public FLSliceResult Encode() { var enc = Native.FLEncoder_New(); FLEncode(enc); FLError error; var result = NativeRaw.FLEncoder_Finish(enc, &error); if (result.buf == null) { throw new CouchbaseFleeceException(error); } return(result); }
public override MutableDocument ToMutable() => new MutableDocument(this); // MutableDocument constructor is different, so this override is needed internal override byte[] Encode() { Debug.Assert(Database != null); var body = new FLSliceResult(); Database.ThreadSafety.DoLocked(() => { FLEncoder *encoder = null; try { encoder = Database.SharedEncoder; } catch (Exception) { body = new FLSliceResult(null, 0UL); } #if CBL_LINQ if (_model != null) { return((FLSlice)EncodeModel(encoder)); } #endif var handle = GCHandle.Alloc(this); Native.FLEncoder_SetExtraInfo(encoder, (void *)GCHandle.ToIntPtr(handle)); try { _dict.FLEncode(encoder); } catch (Exception) { Native.FLEncoder_Reset(encoder); throw; } finally { handle.Free(); } FLError err; body = NativeRaw.FLEncoder_Finish(encoder, &err); if (body.buf == null) { throw new CouchbaseFleeceException(err); } }); var retVal = ((FLSlice)body).ToArrayFast(); Native.FLSliceResult_Release(body); return(retVal); }
public FLSliceResult EncodeDelta() { var enc = Native.FLEncoder_New(); NativeRaw.FLEncoder_MakeDelta(enc, Context.Data, true); FLEncode(enc); FLError error; var result = NativeRaw.FLEncoder_Finish(enc, &error); if (result.buf == null) { throw new LiteCoreException(new C4Error(error)); } return(result); }
internal override byte[] Encode() { Debug.Assert(Database != null); var body = new FLSliceResult(); Database.ThreadSafety.DoLocked(() => { var encoder = Database.SharedEncoder; #if CBL_LINQ if (_model != null) { return((FLSlice)EncodeModel(encoder)); } #endif var guid = Guid.NewGuid(); _NativeCacheMap[guid] = this; Native.FLEncoder_SetExtraInfo(encoder, &guid); try { _dict.FLEncode(encoder); } catch (Exception) { Native.FLEncoder_Reset(encoder); throw; } finally { _NativeCacheMap.Remove(guid); } FLError err; body = NativeRaw.FLEncoder_Finish(encoder, &err); if (body.buf == null) { throw new LiteCoreException(new C4Error(err)); } }); var retVal = ((C4Slice)body).ToArrayFast(); Native.FLSliceResult_Free(body); return(retVal); }
protected uint ImportJSONFile(string path, string idPrefix, TimeSpan timeout, bool verbose) { WriteLine($"Reading {path} ..."); var st = Stopwatch.StartNew(); #if WINDOWS_UWP var url = $"ms-appx:///Assets/{path}"; var file = Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri(url)) .AsTask() .ConfigureAwait(false) .GetAwaiter() .GetResult(); var buffer = Windows.Storage.FileIO.ReadBufferAsync(file).AsTask().ConfigureAwait(false).GetAwaiter() .GetResult(); var jsonData = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(buffer); #elif __ANDROID__ var ctx = global::Couchbase.Lite.Tests.Android.MainActivity.ActivityContext; byte[] jsonData; using (var stream = ctx.Assets.Open(path)) using (var ms = new MemoryStream()) { stream.CopyTo(ms); jsonData = ms.ToArray(); } #elif __IOS__ var bundlePath = ios::Foundation.NSBundle.MainBundle.PathForResource(Path.GetFileNameWithoutExtension(path), Path.GetExtension(path)); byte[] jsonData; using (var stream = File.Open(bundlePath, FileMode.Open, FileAccess.Read)) using (var ms = new MemoryStream()) { stream.CopyTo(ms); jsonData = ms.ToArray(); } #else var jsonData = File.ReadAllBytes(path); #endif FLError error; FLSliceResult fleeceData; fixed(byte *jsonData_ = jsonData) { fleeceData = NativeRaw.FLData_ConvertJSON(new FLSlice(jsonData_, (ulong)jsonData.Length), &error); } ((long)fleeceData.buf).Should().NotBe(0, "because otherwise the conversion failed"); var root = Native.FLValue_AsArray(NativeRaw.FLValue_FromTrustedData((FLSlice)fleeceData)); ((long)root).Should().NotBe(0, "because otherwise the value is not of the expected type"); LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err)); try { FLArrayIterator iter; FLValue * item; uint numDocs = 0; for (Native.FLArrayIterator_Begin(root, &iter); null != (item = Native.FLArrayIterator_GetValue(&iter)); Native.FLArrayIterator_Next(&iter)) { var docID = idPrefix != null ? $"{idPrefix}{numDocs + 1:D7}" : $"doc{numDocs + 1:D7}"; var enc = Native.c4db_getSharedFleeceEncoder(Db); Native.FLEncoder_WriteValue(enc, item); var body = NativeRaw.FLEncoder_Finish(enc, &error); var rq = new C4DocPutRequest { docID = C4Slice.Allocate(docID), body = (C4Slice)body, save = true }; var doc = (C4Document *)LiteCoreBridge.Check(err => { var localPut = rq; return(Native.c4doc_put(Db, &localPut, null, err)); }); Native.c4doc_free(doc); Native.FLSliceResult_Free(body); C4Slice.Free(rq.docID); ++numDocs; if ((numDocs % 1000) == 0 && st.Elapsed > timeout) { WriteLine($"WARNING: Stopping JSON import after {st.Elapsed}"); return(numDocs); } if (verbose && (numDocs % 100000) == 0) { WriteLine($"{numDocs} "); } } if (verbose) { st.PrintReport("Importing", numDocs, "doc", _output); } return(numDocs); } finally { Native.FLSliceResult_Free(fleeceData); LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err)); } }
// Read a file that contains a JSON document per line. Every line becomes a document. protected uint ImportJSONLines(string path, TimeSpan timeout, bool verbose) { if (verbose) { WriteLine($"Reading {path}..."); } var st = Stopwatch.StartNew(); uint numDocs = 0; LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err)); try { var encoder = Native.FLEncoder_New(); ReadFileByLines(path, line => { FLError error; NativeRaw.FLEncoder_ConvertJSON(encoder, line); var body = NativeRaw.FLEncoder_Finish(encoder, &error); ((long)body.buf).Should().NotBe(0, "because otherwise the encode failed"); Native.FLEncoder_Reset(encoder); var docID = (numDocs + 1).ToString("D7"); // Save document: using (var docID_ = new C4String(docID)) { var rq = new C4DocPutRequest { docID = docID_.AsC4Slice(), body = (C4Slice)body, save = true }; var doc = (C4Document *)LiteCoreBridge.Check(err => { var localRq = rq; return(Native.c4doc_put(Db, &localRq, null, err)); }); Native.c4doc_free(doc); } Native.FLSliceResult_Free(body); ++numDocs; if (numDocs % 1000 == 0 && st.Elapsed >= timeout) { Console.Write($"Stopping JSON import after {st.Elapsed.TotalSeconds:F3} sec "); return(false); } if (verbose && numDocs % 10000 == 0) { Console.Write($"{numDocs} "); } return(true); }); if (verbose) { WriteLine("Committing..."); } } finally { LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err)); } if (verbose) { st.PrintReport("Importing", numDocs, "doc", _output); } return(numDocs); }
private uint InsertDocs(FLArray *docs) { var typeKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Track Type"), true); var idKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Persistent ID"), true); var nameKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Name"), true); var albumKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Album"), true); var artistKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Artist"), true); var timeKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Total Time"), true); var genreKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Genre"), true); var yearKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Year"), true); var trackNoKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Track Number"), true); var compKey = NativeRaw.FLDictKey_Init(FLSlice.Constant("Compilation"), true); LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err)); try { var enc = Native.FLEncoder_New(); FLArrayIterator iter; Native.FLArrayIterator_Begin(docs, &iter); uint numDocs = 0; while (Native.FLArrayIterator_Next(&iter)) { // Check that track is correct type: var track = Native.FLValue_AsDict(Native.FLArrayIterator_GetValue(&iter)); var trackType = NativeRaw.FLValue_AsString(Native.FLDict_GetWithKey(track, &typeKey)); if (!trackType.Equals(FLSlice.Constant("File")) && !trackType.Equals(FLSlice.Constant("Remote"))) { continue; } var trackID = NativeRaw.FLValue_AsString(Native.FLDict_GetWithKey(track, &idKey)); ((long)trackID.buf).Should().NotBe(0, "because otherwise the data was not read correctly"); // Encode doc body: Native.FLEncoder_BeginDict(enc, 0); CopyValue(track, &nameKey, enc).Should().BeTrue("because otherwise the copy failed"); CopyValue(track, &albumKey, enc); CopyValue(track, &artistKey, enc); CopyValue(track, &timeKey, enc); CopyValue(track, &genreKey, enc); CopyValue(track, &yearKey, enc); CopyValue(track, &trackNoKey, enc); CopyValue(track, &compKey, enc); Native.FLEncoder_EndDict(enc); FLError err; var body = NativeRaw.FLEncoder_Finish(enc, &err); body.Should().NotBeNull("because otherwise the encoding process failed"); Native.FLEncoder_Reset(enc); // Save Document: var rq = new C4DocPutRequest(); rq.docID = (C4Slice)trackID; rq.body = body; rq.save = true; var doc = (C4Document *)LiteCoreBridge.Check(c4err => { var localRq = rq; return(Native.c4doc_put(Db, &localRq, null, c4err)); }); Native.c4doc_free(doc); ++numDocs; } Native.FLEncoder_Free(enc); return(numDocs); } finally { LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err)); } }
private void IndexViews() { var nameKey = Native.FLDictKey_Init("Name", true); var albumKey = Native.FLDictKey_Init("Album", true); var artistKey = Native.FLDictKey_Init("Artist", true); var timeKey = Native.FLDictKey_Init("Total Time", true); var trackNoKey = Native.FLDictKey_Init("Track Number", true); var compKey = Native.FLDictKey_Init("Compilation", true); var enc = Native.FLEncoder_New(); var key = Native.c4key_new(); C4Error error; if (_artistsView == null) { var config = Native.c4db_getConfig(Db); _artistsView = (C4View *)LiteCoreBridge.Check(err => Native.c4view_open(Db, null, "Artists", "1", Native.c4db_getConfig(Db), err)); } if (_albumsView == null) { _albumsView = (C4View *)LiteCoreBridge.Check(err => Native.c4view_open(Db, null, "Albums", "1", Native.c4db_getConfig(Db), err)); } var views = new[] { _artistsView, _albumsView }; var indexer = (C4Indexer *)LiteCoreBridge.Check(err => Native.c4indexer_begin(Db, views, err)); var e = (C4DocEnumerator *)LiteCoreBridge.Check(err => Native.c4indexer_enumerateDocuments(indexer, err)); while (Native.c4enum_next(e, &error)) { var doc = Native.c4enum_getDocument(e, &error); var body = Native.FLValue_AsDict(NativeRaw.FLValue_FromTrustedData((FLSlice)doc->selectedRev.body)); ((long)body).Should().NotBe(0, "because otherwise the data got corrupted somehow"); FLSlice artist; if (Native.FLValue_AsBool(Native.FLDict_GetWithKey(body, &compKey))) { artist = FLSlice.Constant("-Compilations-"); } else { artist = NativeRaw.FLValue_AsString(Native.FLDict_GetWithKey(body, &artistKey)); } var name = NativeRaw.FLValue_AsString(Native.FLDict_GetWithKey(body, &nameKey)); var album = Native.FLValue_AsString(Native.FLDict_GetWithKey(body, &albumKey)); var trackNo = Native.FLValue_AsInt(Native.FLDict_GetWithKey(body, &trackNoKey)); var time = Native.FLDict_GetWithKey(body, &timeKey); // Generate Value: Native.FLEncoder_WriteValue(enc, time); FLError flError; var fval = NativeRaw.FLEncoder_Finish(enc, &flError); Native.FLEncoder_Reset(enc); ((long)fval.buf).Should().NotBe(0, "because otherwise the encoding failed"); var value = (C4Slice)fval; // Emit to artists view: uint nKeys = 0; if (!artist.Equals(FLSlice.Null) && !name.Equals(FLSlice.Null)) { nKeys = 1; // Generate key: Native.c4key_beginArray(key); NativeRaw.c4key_addString(key, (C4Slice)artist); if (album != null) { Native.c4key_addString(key, album); } else { Native.c4key_addNull(key); } Native.c4key_addNumber(key, trackNo); NativeRaw.c4key_addString(key, (C4Slice)name); Native.c4key_addNumber(key, 1.0); Native.c4key_endArray(key); } Native.c4indexer_emit(indexer, doc, 0, nKeys, new[] { key }, new[] { value }, &error).Should() .BeTrue("because otherwise the emit to the artists view failed"); Native.c4key_reset(key); // Emit to albums view: nKeys = 0; if (album != null) { nKeys = 1; Native.c4key_beginArray(key); Native.c4key_addString(key, album); if (!artist.Equals(FLSlice.Null)) { NativeRaw.c4key_addString(key, (C4Slice)artist); } else { Native.c4key_addNull(key); } Native.c4key_addNumber(key, trackNo); if (name.buf == null) { name = FLSlice.Constant(""); } NativeRaw.c4key_addString(key, (C4Slice)name); Native.c4key_addNumber(key, 1.0); Native.c4key_endArray(key); } Native.c4indexer_emit(indexer, doc, 1, nKeys, new[] { key }, new[] { value }, &error).Should() .BeTrue("because otherwise the emit to the artists view failed"); Native.c4key_reset(key); Native.FLSliceResult_Free(fval); Native.c4doc_free(doc); } Native.c4enum_free(e); error.Code.Should().Be(0, "because otherwise an error occurred"); Native.c4indexer_end(indexer, true, &error).Should().BeTrue("because otherwise the indexer failed to end"); Native.FLEncoder_Free(enc); Native.c4key_free(key); }