Beispiel #1
0
        /// <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);
            }
        }
Beispiel #2
0
        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();
                            }
                        }
                    }
                }
            }
        }
Beispiel #3
0
        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);
                        }
                    }
                }
            }
        }