/// <summary>
        /// Drop a table from the database schema
        /// </summary>
        /// <param name="table">Name of table to drop</param>
        public async Task DropAsync(string table)
        {
            var totalTimer = ScopeTiming.StartTiming();

            try
            {
                NameValues.ClearCaches();

                int tableId = await Tables.GetIdAsync(Ctxt, table, noCreate : true, noException : true).ConfigureAwait(false);

                if (tableId < 0)
                {
                    return;
                }

                await Ctxt.Db.ExecuteSqlAsync($"DELETE FROM itemnamevalues WHERE nameid IN (SELECT id FROM names WHERE tableid = {tableId})").ConfigureAwait(false);

                await Ctxt.Db.ExecuteSqlAsync($"DELETE FROM names WHERE tableid = {tableId}").ConfigureAwait(false);

                await Ctxt.Db.ExecuteSqlAsync($"DELETE FROM items WHERE tableid = {tableId}").ConfigureAwait(false);

                await Ctxt.Db.ExecuteSqlAsync($"DELETE FROM tables WHERE id = {tableId}").ConfigureAwait(false);

                NameValues.ClearCaches();
            }
            finally
            {
                ScopeTiming.RecordScope("Cmd.Drop", totalTimer);
            }
        }
        /// <summary>
        /// Reset the metastrings database
        /// Only used internally for testing, should not be used in a production environment
        /// </summary>
        /// <param name="reset">Reset request object</param>
        public void Reset(bool includeNameValues = false)
        {
            if (includeNameValues)
            {
                NameValues.Reset(Ctxt);
            }
            else
            {
                Items.Reset(Ctxt);
            }

            NameValues.ClearCaches();
        }
Exemple #3
0
        public static Context GetCtxt() // start from scratch
        {
            string dbFilePath = Context.DbConnStrToFilePath("Data Source=[UserRoaming]/metastrings-tests.db");

            if (File.Exists(dbFilePath))
            {
                File.Delete(dbFilePath);
            }

            var ctxt = new Context("Data Source=" + dbFilePath);

            NameValues.Reset(ctxt);
            return(ctxt);
        }
        /// <summary>
        /// Query for the metadata for a set of items.
        /// </summary>
        /// <param name="request">NoSQL query for items to get</param>
        /// <returns>Metadata of found items</returns>
        public async Task <GetResponse> QueryGetAsync(QueryGetRequest request)
        {
            var totalTimer = ScopeTiming.StartTiming();

            try
            {
                var itemValues = new Dictionary <long, object>();
                {
                    Select select = new Select();
                    select.select = new List <string> {
                        "id", "value"
                    };
                    select.from      = request.from;
                    select.where     = request.where;
                    select.orderBy   = request.orderBy;
                    select.limit     = request.limit;
                    select.cmdParams = request.cmdParams;
                    using (var reader = await Ctxt.ExecSelectAsync(select).ConfigureAwait(false))
                    {
                        while (await reader.ReadAsync().ConfigureAwait(false))
                        {
                            itemValues.Add(reader.GetInt64(0), reader.GetValue(1));
                        }
                    }
                }

                var responses = new List <Dictionary <string, object> >(itemValues.Count);
                foreach (var itemId in itemValues.Keys)
                {
                    var metaIds = await Items.GetItemDataAsync(Ctxt, itemId).ConfigureAwait(false);

                    var metaStrings = await NameValues.GetMetadataValuesAsync(Ctxt, metaIds).ConfigureAwait(false);

                    metaStrings["id"]    = (double)itemId;
                    metaStrings["value"] = itemValues[itemId];

                    responses.Add(metaStrings);
                }

                GetResponse response = new GetResponse()
                {
                    metadata = responses
                };
                return(response);
            }
            finally
            {
                ScopeTiming.RecordScope("Cmd.QueryGet", totalTimer);
            }
        }
Exemple #5
0
        /// <summary>
        /// Internal use, get a summary of a text of an item and its metadata
        /// </summary>
        /// <param name="ctxt">Database connection</param>
        /// <param name="itemId">The item to summarize</param>
        /// <returns>Summary of item</returns>
        public static async Task <string> SummarizeItemAsync(Context ctxt, long itemId)
        {
            var sb = new StringBuilder();

            sb.AppendLine($"Item: {itemId}");

            int tableId =
                Utils.ConvertDbInt32(await ctxt.Db.ExecuteScalarAsync($"SELECT tableid FROM items WHERE id = {itemId}"));

            if (tableId < 0)
            {
                throw new MetaStringsException("Item not found: " + itemId);
            }

            string tableName = (await Tables.GetTableAsync(ctxt, tableId)).name;

            sb.AppendLine($"Table: {tableName} ({tableId})");

            long valueId =
                Utils.ConvertDbInt64(await ctxt.Db.ExecuteScalarAsync($"SELECT valueid FROM items WHERE id = {itemId}"));
            object value = await Values.GetValueAsync(ctxt, valueId);

            sb.AppendLine($"Value: {value} ({valueId})\n");

            sb.AppendLine("Metadata:");
            var metadata = await NameValues.GetMetadataValuesAsync(ctxt, GetItemDataAsync(ctxt, itemId).Result);

            foreach (var kvp in metadata)
            {
                sb.AppendLine($"{kvp.Key}: {kvp.Value}");
            }

            sb.AppendLine("Long Strings:");
            using (var reader = await ctxt.Db.ExecuteReaderAsync($"SELECT name, longstring FROM longstrings WHERE itemid = {itemId}"))
            {
                while (await reader.ReadAsync())
                {
                    sb.AppendLine($"{reader.GetString(0)}:\n{reader.GetString(1)}\n");
                }
            }

            return(sb.ToString());
        }
        /// <summary>
        /// Get the metadata for a set of items
        /// </summary>
        /// <param name="request">List of values to get metadata for</param>
        /// <returns>Metadata for the items</returns>
        public async Task <GetResponse> GetAsync(GetRequest request)
        {
            var totalTimer = ScopeTiming.StartTiming();

            try
            {
                var responses = new List <Dictionary <string, object> >(request.values.Count);

                int tableId = await Tables.GetIdAsync(Ctxt, request.table, noCreate : true).ConfigureAwait(false);

                foreach (var value in request.values)
                {
                    long valueId = await Values.GetIdAsync(Ctxt, value).ConfigureAwait(false);

                    long itemId = await Items.GetIdAsync(Ctxt, tableId, valueId, noCreate : true).ConfigureAwait(false);

                    if (itemId < 0)
                    {
                        responses.Add(null);
                        continue;
                    }

                    var metaIds = await Items.GetItemDataAsync(Ctxt, itemId).ConfigureAwait(false);

                    var metaStrings = await NameValues.GetMetadataValuesAsync(Ctxt, metaIds).ConfigureAwait(false);

                    responses.Add(metaStrings);
                }

                GetResponse response = new GetResponse()
                {
                    metadata = responses
                };
                return(response);
            }
            finally
            {
                ScopeTiming.RecordScope("Cmd.Get", totalTimer);
            }
        }
Exemple #7
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();
                            }
                        }
                    }
                }
            }
        }