/// <summary> /// This is the main UPSERT method to populate the database. /// </summary> /// <param name="define">Info about metadata to apply to the key</param> public async Task DefineAsync(Define define) { var totalTimer = ScopeTiming.StartTiming(); try { var localTimer = ScopeTiming.StartTiming(); bool isKeyNumeric = !(define.key is string); int tableId = await Tables.GetIdAsync(Ctxt, define.table, isKeyNumeric).ConfigureAwait(false); long valueId = await Values.GetIdAsync(Ctxt, define.key).ConfigureAwait(false); long itemId = await Items.GetIdAsync(Ctxt, tableId, valueId).ConfigureAwait(false); ScopeTiming.RecordScope("Define.Setup", localTimer); if (define.metadata != null) { // name => nameid var nameValueIds = new Dictionary <int, long>(); foreach (var kvp in define.metadata) { bool isMetadataNumeric = !(kvp.Value is string); int nameId = await Names.GetIdAsync(Ctxt, tableId, kvp.Key, isMetadataNumeric).ConfigureAwait(false); if (kvp.Value == null) // erase value { nameValueIds[nameId] = -1; continue; } bool isNameNumeric = await Names.GetNameIsNumericAsync(Ctxt, nameId).ConfigureAwait(false); bool isValueNumeric = !(kvp.Value is string); if (isValueNumeric != isNameNumeric) { throw new MetaStringsException ( $"Data numeric does not match name: {kvp.Key}" + $"\n - value is numeric: {isValueNumeric} - {kvp.Value}" + $"\n - name is numeric: {isNameNumeric}" ); } nameValueIds[nameId] = await Values.GetIdAsync(Ctxt, kvp.Value).ConfigureAwait(false); } ScopeTiming.RecordScope("Define.NameIds", localTimer); Items.SetItemData(Ctxt, itemId, nameValueIds); ScopeTiming.RecordScope("Define.ItemsCommit", localTimer); } await Ctxt.ProcessPostOpsAsync().ConfigureAwait(false); ScopeTiming.RecordScope("Define.PostOps", localTimer); } #if !DEBUG catch { Ctxt.ClearPostOps(); throw; } #endif finally { ScopeTiming.RecordScope("Define", totalTimer); } }
public void TestDefine() { using (var ctxt = TestUtils.GetCtxt()) { { var define = new Define("fun", "some"); define.Set("num", 42).Set("str", "foobar").Set("multi", "blet\nmonkey"); ctxt.Cmd.DefineAsync(define).Wait(); } { var define = new Define("fun", "another"); define.Set("num", 69).Set("str", "boofar").Set("multi", "ape\nagony"); ctxt.Cmd.DefineAsync(define).Wait(); } { var define = new Define("fun", "yetsome"); define.Set("num", 19).Set("str", "playful").Set("multi", "balloni\nbeats"); ctxt.Cmd.DefineAsync(define).Wait(); } long itemId = Items.GetIdAsync(ctxt, Tables.GetIdAsync(ctxt, "fun").Result, Values.GetIdAsync(ctxt, "some").Result).Result; var itemData = NameValues.GetMetadataValuesAsync(ctxt, Items.GetItemDataAsync(ctxt, itemId).Result).Result; Assert.AreEqual(42.0, itemData["num"]); Assert.AreEqual("foobar", itemData["str"]); Assert.AreEqual("blet\nmonkey", itemData["multi"]); { Select select = Sql.Parse ( "SELECT value, multi\n" + $"FROM fun\n" + "WHERE multi MATCHES @search" ); select.AddParam("@search", "monkey"); using (var reader = ctxt.ExecSelectAsync(select).Result) { if (!reader.ReadAsync().Result) { Assert.Fail(); } var val = reader.GetString(0); var str = reader.GetString(1); Assert.AreEqual("some", val); Assert.AreEqual("blet\nmonkey", str); if (reader.ReadAsync().Result) { Assert.Fail(); } } } { Define define = new Define("fun", "some"); define.Set("num", 43.0); define.Set("str", null); // remove the metadata ctxt.Cmd.DefineAsync(define).Wait(); } itemData = NameValues.GetMetadataValuesAsync(ctxt, Items.GetItemDataAsync(ctxt, itemId).Result).Result; Assert.IsTrue(!itemData.ContainsKey("str")); Assert.AreEqual(43.0, itemData["num"]); Assert.IsTrue(!itemData.ContainsKey("str")); ctxt.Cmd.DeleteAsync("fun", new[] { "some", "another", "yetsome" }).Wait(); { Select select = new Select() { from = "fun", select = new List <string> { "value" } }; using (var reader = ctxt.ExecSelectAsync(select).Result) { if (reader.ReadAsync().Result) // should be gone { Assert.Fail(); } } } { Define numsFirst = new Define("numsFirst", 1); numsFirst.Set("foo", 12); numsFirst.Set("blet", "79"); ctxt.Cmd.DefineAsync(numsFirst).Wait(); Define numsNext = new Define("numsFirst", 2); numsNext.Set("foo", 15).Set("blet", "63"); ctxt.Cmd.DefineAsync(numsNext).Wait(); Select select = Sql.Parse("SELECT value, foo, blet\nFROM numsFirst"); using (var reader = ctxt.ExecSelectAsync(select).Result) { while (reader.Read()) { if (reader.GetInt64(0) == 1) { Assert.AreEqual(12, reader.GetDouble(1)); Assert.AreEqual("79", reader.GetString(2)); } else if (reader.GetInt64(0) == 2) { Assert.AreEqual(15, reader.GetDouble(1)); Assert.AreEqual("63", reader.GetString(2)); } else { Assert.Fail(); } } } } } }
public void TestItemData() { using (var ctxt = TestUtils.GetCtxt()) { int tableId = Tables.GetIdAsync(ctxt, "blet").Result; long itemId = Items.GetIdAsync(ctxt, tableId, Values.GetIdAsync(ctxt, "monkey").Result).Result; { var itemData = new Dictionary <int, long>(); itemData[Names.GetIdAsync(ctxt, tableId, "foo").Result] = Values.GetIdAsync(ctxt, "bar").Result; itemData[Names.GetIdAsync(ctxt, tableId, "something").Result] = Values.GetIdAsync(ctxt, "else").Result; Items.SetItemData(ctxt, itemId, itemData); ctxt.ProcessPostOpsAsync().Wait(); var metadata = Items.GetItemDataAsync(ctxt, itemId).Result; Console.WriteLine($"metadata1 Dict contents ({metadata.Count}):"); Console.WriteLine(string.Join("\n", metadata.Select(kvp => $"{kvp.Key}: {kvp.Value}"))); foreach (var kvp in metadata) { string nameVal = Names.GetNameAsync(ctxt, kvp.Key).Result.name; string valueVal = Values.GetValueAsync(ctxt, kvp.Value).Result.ToString(); if (nameVal == "foo") { Assert.AreEqual("bar", valueVal); } else if (nameVal == "something") { Assert.AreEqual("else", valueVal); } else { Assert.Fail("Name not recognized: " + nameVal); } } } { var itemData = new Dictionary <int, long>(); itemData[Names.GetIdAsync(ctxt, tableId, "foo").Result] = Values.GetIdAsync(ctxt, "blet").Result; itemData[Names.GetIdAsync(ctxt, tableId, "something").Result] = Values.GetIdAsync(ctxt, "monkey").Result; Items.SetItemData(ctxt, itemId, itemData); ctxt.ProcessPostOpsAsync().Wait(); var metadata = Items.GetItemDataAsync(ctxt, itemId).Result; Console.WriteLine($"metadata2 Dict contents ({metadata.Count}):"); Console.WriteLine(string.Join("\n", metadata.Select(kvp => $"{kvp.Key}: {kvp.Value}"))); foreach (var kvp in metadata) { string nameVal = Names.GetNameAsync(ctxt, kvp.Key).Result.name; string valueVal = Values.GetValueAsync(ctxt, kvp.Value).Result.ToString(); if (nameVal == "foo") { Assert.AreEqual("blet", valueVal); } else if (nameVal == "something") { Assert.AreEqual("monkey", valueVal); } else { Assert.Fail("Name not recognized: " + nameVal); } } } } }