private async Task ApplyPostMatchModifierAsync(SearchQueryResult result, string modifier)
        {
            int    split_index = modifier.IndexOf(':');
            string name        = modifier.Substring(0, split_index).Trim();
            string value       = modifier.Substring(split_index + 1, modifier.Length - split_index - 1).Trim();
            bool   subtract    = name.Length > 0 ? name[0] == '-' : false;

            if (name.StartsWith("-"))
            {
                name = name.Substring(1, name.Length - 1);
            }

            // Trim outer quotes from the value.

            if (value.Length > 0 && value.First() == '"' && value.Last() == '"')
            {
                value = value.Trim('"');
            }

            switch (name)
            {
            case "groupby":
            case "group":

                // Applies grouping to the species based on the given attribute.

                switch (value.ToLower())
                {
                case "z":
                case "zones":
                case "zone":
                    await result.GroupByAsync(async (x) => {
                        return((await BotUtils.GetZonesFromDb(x.Id)).Select(z => z.GetFullName()).ToArray());
                    });

                    break;

                case "g":
                case "genus":
                    await result.GroupByAsync((x) => {
                        return(Task.FromResult(new string[] { x.GenusName }));
                    });

                    break;

                case "f":
                case "family":
                    await result.GroupByAsync(async (x) => {
                        Taxon taxon = (await BotUtils.GetFullTaxaFromDb(x)).Family;

                        return(new string[] { taxon is null ? "N/A" : taxon.GetName() });
                    });

                    break;
        private async Task <SearchQueryResult> ApplyPostMatchModifiersAsync(List <Species> matches)
        {
            SearchQueryResult result = new SearchQueryResult();

            result.Add(DefaultGroupName, matches.ToArray());

            foreach (string modifier in searchModifiers)
            {
                await ApplyPostMatchModifierAsync(result, modifier);
            }

            return(result);
        }
        public async Task <SearchQueryResult> GetResultAsync()
        {
            // Build up a list of conditions to query for.

            List <string> conditions = new List <string>();

            // Create a condition for each basic search term.

            for (int i = 0; i < searchTerms.Count(); ++i)
            {
                conditions.Add(string.Format("(name LIKE {0} OR description LIKE {0} OR common_name LIKE {0})", string.Format("$term{0}", i)));
            }

            // Build the SQL query.
            string sql_command_str;

            if (conditions.Count > 0)
            {
                sql_command_str = string.Format("SELECT * FROM Species WHERE {0};", string.Join(" AND ", conditions));
            }
            else
            {
                sql_command_str = "SELECT * FROM Species;";
            }

            List <Species> matches = new List <Species>();

            using (SQLiteCommand cmd = new SQLiteCommand(sql_command_str)) {
                // Replace all parameters with their respective terms.

                for (int i = 0; i < searchTerms.Count(); ++i)
                {
                    string term = "%" + searchTerms[i].Trim() + "%";
                    cmd.Parameters.AddWithValue(string.Format("$term{0}", i), term);
                }

                // Execute the query, and add all matching species to the list.

                using (DataTable rows = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in rows.Rows)
                    {
                        matches.Add(await SpeciesUtils.SpeciesFromDataRow(row));
                    }
            }

            // Apply any post-match modifiers (e.g. groupings), and return the result.
            SearchQueryResult result = await ApplyPostMatchModifiersAsync(matches);

            // Return the result.
            return(result);
        }
示例#4
0
        public static List <EmbedBuilder> SearchQueryResultToEmbedPages(Taxa.SearchQueryResult result, int itemsPerField = 10)
        {
            List <EmbedBuilder> pages = new List <EmbedBuilder>();
            int fields_per_page       = 6;

            foreach (Taxa.SearchQueryResult.Group group in result.Groups)
            {
                List <string> items = group.ToStringArray().ToList();

                List <List <string> > columns = ListToColumns(items, itemsPerField);
                int column_index = 1;

                foreach (List <string> column in columns)
                {
                    // Create the field for this column.

                    string title = group.Name.Length > 25 ? group.Name.Substring(0, 22) + "..." : group.Name;

                    EmbedFieldBuilder field = new EmbedFieldBuilder {
                        Name     = column_index == 1 ? string.Format("{0} ({1})", StringUtils.ToTitleCase(title), items.Count()) : string.Format("...", StringUtils.ToTitleCase(title)),
                        Value    = string.Join(Environment.NewLine, column),
                        IsInline = true
                    };

                    ++column_index;

                    // Add the field to the embed, creating a new page if needed.

                    int field_length = field.Name.ToString().Length + field.Value.ToString().Length;

                    if (pages.Count() <= 0 || pages.Last().Fields.Count() >= fields_per_page || pages.Last().Length + field_length > Bot.DiscordUtils.MaxEmbedLength)
                    {
                        pages.Add(new EmbedBuilder());
                    }

                    pages.Last().Fields.Add(field);
                }
            }

            return(pages);
        }