summaryrefslogtreecommitdiffstats
path: root/src/readline_possibilities.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/readline_possibilities.cc213
1 files changed, 197 insertions, 16 deletions
diff --git a/src/readline_possibilities.cc b/src/readline_possibilities.cc
index f0b8f17..0ba2d8f 100644
--- a/src/readline_possibilities.cc
+++ b/src/readline_possibilities.cc
@@ -32,12 +32,16 @@
#include "readline_possibilities.hh"
+#include "base/fs_util.hh"
#include "base/isc.hh"
#include "base/opt_util.hh"
#include "config.h"
#include "data_parser.hh"
+#include "date/tz.h"
#include "lnav.hh"
#include "lnav_config.hh"
+#include "log_data_helper.hh"
+#include "log_format_ext.hh"
#include "service_tags.hh"
#include "session_data.hh"
#include "sql_help.hh"
@@ -69,15 +73,57 @@ handle_db_list(void* ptr, int ncols, char** colvalues, char** colnames)
return 0;
}
+static size_t
+files_with_format(log_format* format)
+{
+ auto retval = size_t{0};
+ for (const auto& lf : lnav_data.ld_active_files.fc_files) {
+ if (lf->get_format_name() == format->get_name()) {
+ retval += 1;
+ }
+ }
+
+ return retval;
+}
+
static int
handle_table_list(void* ptr, int ncols, char** colvalues, char** colnames)
{
if (lnav_data.ld_rl_view != nullptr) {
std::string table_name = colvalues[0];
+ intern_string_t table_intern = intern_string::lookup(table_name);
+ auto format = log_format::find_root_format(table_name.c_str());
+ auto add_poss = true;
+
+ if (format != nullptr) {
+ if (files_with_format(format.get()) == 0) {
+ add_poss = false;
+ }
+ } else if (sqlite_function_help.count(table_name) != 0) {
+ add_poss = false;
+ } else {
+ for (const auto& lf : log_format::get_root_formats()) {
+ auto* elf = dynamic_cast<external_log_format*>(lf.get());
+ if (elf == nullptr) {
+ continue;
+ }
+
+ if (elf->elf_search_tables.find(table_intern)
+ != elf->elf_search_tables.end()
+ && files_with_format(lf.get()) == 0)
+ {
+ add_poss = false;
+ }
+ }
+ }
- if (sqlite_function_help.count(table_name) == 0) {
+ if (add_poss) {
lnav_data.ld_rl_view->add_possibility(
- ln_mode_t::SQL, "*", colvalues[0]);
+ ln_mode_t::SQL, "*", table_name);
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL,
+ "prql-table",
+ lnav::prql::quote_ident(std::move(table_name)));
}
lnav_data.ld_table_ddl[colvalues[0]] = colvalues[1];
@@ -152,9 +198,8 @@ add_text_possibilities(readline_curses* rlc,
switch (tq) {
case text_quoting::sql: {
auto token_value = tok_res->to_string();
- auto_mem<char, sqlite3_free> quoted_token;
-
- quoted_token = sqlite3_mprintf("%Q", token_value.c_str());
+ auto quoted_token
+ = lnav::sql::mprintf("%Q", token_value.c_str());
rlc->add_possibility(context, type, std::string(quoted_token));
break;
}
@@ -265,9 +310,7 @@ add_filter_expr_possibilities(readline_curses* rlc,
continue;
}
- auto_mem<char> ident(sqlite3_free);
-
- ident = sql_quote_ident(lv.lv_meta.lvm_name.get());
+ auto ident = sql_quote_ident(lv.lv_meta.lvm_name.get());
auto bound_name = fmt::format(FMT_STRING(":{}"), ident.in());
rlc->add_possibility(context, type, bound_name);
switch (lv.lv_meta.lvm_kind) {
@@ -377,15 +420,17 @@ add_file_possibilities()
rc->clear_possibilities(ln_mode_t::COMMAND, "visible-files");
rc->clear_possibilities(ln_mode_t::COMMAND, "hidden-files");
+ rc->clear_possibilities(ln_mode_t::COMMAND, "loaded-files");
for (const auto& lf : lnav_data.ld_active_files.fc_files) {
if (lf.get() == nullptr) {
continue;
}
- lnav_data.ld_log_source.find_data(lf) | [&lf, rc](auto ld) {
- auto escaped_fn
- = std::regex_replace(lf->get_filename(), sh_escape, R"(\\\1)");
+ auto escaped_fn = fmt::to_string(lf->get_filename());
+ rc->add_possibility(ln_mode_t::COMMAND, "loaded-files", escaped_fn);
+
+ lnav_data.ld_log_source.find_data(lf) | [&escaped_fn, rc](auto ld) {
rc->add_possibility(
ln_mode_t::COMMAND,
ld->is_visible() ? "visible-files" : "hidden-files",
@@ -420,7 +465,7 @@ add_config_possibilities()
std::set<std::string> visited;
auto cb = [rc, &visited](const json_path_handler_base& jph,
const std::string& path,
- void* mem) {
+ const void* mem) {
if (jph.jph_children) {
const auto named_caps = jph.jph_regex->get_named_captures();
@@ -481,10 +526,10 @@ add_tag_possibilities()
if (lnav_data.ld_view_stack.top().value_or(nullptr)
== &lnav_data.ld_views[LNV_LOG])
{
- logfile_sub_source& lss = lnav_data.ld_log_source;
+ auto& lss = lnav_data.ld_log_source;
if (lss.text_line_count() > 0) {
auto line_meta_opt = lss.find_bookmark_metadata(
- lnav_data.ld_views[LNV_LOG].get_top());
+ lnav_data.ld_views[LNV_LOG].get_selection());
if (line_meta_opt) {
rc->add_possibility(ln_mode_t::COMMAND,
"line-tags",
@@ -504,7 +549,143 @@ add_recent_netlocs_possibilities()
isc::to<tailer::looper&, services::remote_tailer_t>().send_and_wait(
[&netlocs](auto& tlooper) { netlocs = tlooper.active_netlocs(); });
- netlocs.insert(session_data.sd_recent_netlocs.begin(),
- session_data.sd_recent_netlocs.end());
+ netlocs.insert(recent_refs.rr_netlocs.begin(),
+ recent_refs.rr_netlocs.end());
rc->add_possibility(ln_mode_t::COMMAND, "recent-netlocs", netlocs);
}
+
+void
+add_tz_possibilities(ln_mode_t context)
+{
+ auto* rc = lnav_data.ld_rl_view;
+
+ rc->clear_possibilities(context, "timezone");
+ for (const auto& tz : date::get_tzdb().zones) {
+ rc->add_possibility(context, "timezone", tz.name());
+ }
+
+ {
+ static auto& safe_options_hier
+ = injector::get<lnav::safe_file_options_hier&>();
+
+ safe::ReadAccess<lnav::safe_file_options_hier> options_hier(
+ safe_options_hier);
+ rc->clear_possibilities(context, "file-with-zone");
+ for (const auto& hier_pair : options_hier->foh_path_to_collection) {
+ for (const auto& coll_pair :
+ hier_pair.second.foc_pattern_to_options)
+ {
+ rc->add_possibility(context, "file-with-zone", coll_pair.first);
+ }
+ }
+ }
+}
+
+void
+add_sqlite_possibilities()
+{
+ // Hidden columns don't show up in the table_info pragma.
+ static const char* hidden_table_columns[] = {
+ "log_time_msecs",
+ "log_path",
+ "log_text",
+ "log_body",
+
+ nullptr,
+ };
+
+ auto& log_view = lnav_data.ld_views[LNV_LOG];
+
+ add_env_possibilities(ln_mode_t::SQL);
+
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL, "prql-expr", lnav::sql::prql_keywords);
+ for (const auto& pair : lnav::sql::prql_functions) {
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL, "prql-expr", pair.first);
+ }
+
+ if (log_view.get_inner_height() > 0) {
+ log_data_helper ldh(lnav_data.ld_log_source);
+ auto vl = log_view.get_selection();
+ auto cl = lnav_data.ld_log_source.at_base(vl);
+
+ ldh.parse_line(cl);
+
+ for (const auto& jextra : ldh.ldh_extra_json) {
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL,
+ "*",
+ lnav::sql::mprintf("%Q", jextra.first.c_str()).in());
+ }
+ for (const auto& jpair : ldh.ldh_json_pairs) {
+ for (const auto& wt : jpair.second) {
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL,
+ "*",
+ lnav::sql::mprintf("%Q", wt.wt_ptr.c_str()).in());
+ }
+ }
+ for (const auto& xml_pair : ldh.ldh_xml_pairs) {
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL,
+ "*",
+ lnav::sql::mprintf("%Q", xml_pair.first.second.c_str()).in());
+ }
+ }
+
+ lnav_data.ld_rl_view->clear_possibilities(ln_mode_t::SQL, "*");
+ add_view_text_possibilities(lnav_data.ld_rl_view,
+ ln_mode_t::SQL,
+ "*",
+ &log_view,
+ text_quoting::sql);
+
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL, "*", std::begin(sql_keywords), std::end(sql_keywords));
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL, "*", sql_function_names);
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL, "*", hidden_table_columns);
+
+ for (int lpc = 0; sqlite_registration_funcs[lpc]; lpc++) {
+ struct FuncDef* basic_funcs;
+ struct FuncDefAgg* agg_funcs;
+
+ sqlite_registration_funcs[lpc](&basic_funcs, &agg_funcs);
+ for (int lpc2 = 0; basic_funcs && basic_funcs[lpc2].zName; lpc2++) {
+ const FuncDef& func_def = basic_funcs[lpc2];
+
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL,
+ "*",
+ std::string(func_def.zName) + (func_def.nArg ? "(" : "()"));
+ }
+ for (int lpc2 = 0; agg_funcs && agg_funcs[lpc2].zName; lpc2++) {
+ const FuncDefAgg& func_def = agg_funcs[lpc2];
+
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL,
+ "*",
+ std::string(func_def.zName) + (func_def.nArg ? "(" : "()"));
+ }
+ }
+
+ for (const auto& pair : sqlite_function_help) {
+ switch (pair.second->ht_context) {
+ case help_context_t::HC_SQL_FUNCTION:
+ case help_context_t::HC_SQL_TABLE_VALUED_FUNCTION: {
+ std::string poss = pair.first
+ + (pair.second->ht_parameters.empty() ? "()" : ("("));
+
+ lnav_data.ld_rl_view->add_possibility(
+ ln_mode_t::SQL, "*", poss);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ walk_sqlite_metadata(lnav_data.ld_db.in(), lnav_sql_meta_callbacks);
+}