[sql] preview table definition

Defect Number:
    Reviewed By:
   Testing Done:
pull/111/merge
Timothy Stack 7 years ago
parent d2514773ae
commit fea3cb83d9

@ -53,7 +53,8 @@ lnav v0.8.2:
commands will also display a preview of the command results. For
example, the ':open' command will display the first ten lines of the
file to be opened and the ':filter-out' command will highlight text
that matches in the current view.
that matches in the current view. The preview pane can be shown/hidden
by pressing CTRL-P.
* The color used for text colored via ":highlight" is now based on the
the regex instead of randomly picked so that colors are consistent
across invocations.

@ -216,6 +216,9 @@ Display
terminal without any decorations so they can be copied easily.
* - |ks| Ctrl |ke| + |ks| w |ke|
- Toggle word-wrap.
* - |ks| Ctrl |ke| + |ks| p |ke|
- Show/hide the data preview panel that may be opened when entering
commands or SQL queries.
* - |ks| x |ke|
- Toggle the hiding of log message fields. The hidden fields will be
replaced with three bullets and highlighted in yellow.

@ -43,7 +43,7 @@ public:
this->alv_schema_name = intern_string::lookup("log_msg_schema");
}
void get_columns(std::vector<vtab_column> &cols) {
void get_columns(std::vector<vtab_column> &cols) const {
cols.push_back(vtab_column(this->alv_value_name.get()));
cols.push_back(vtab_column(this->alv_msg_name.get()));
cols.push_back(vtab_column(this->alv_schema_name.get(), SQLITE3_TEXT, NULL, true));

@ -207,6 +207,20 @@ find_string_attr(const string_attrs_t &sa, string_attr_type_t type, int start =
return iter;
}
inline string_attrs_t::const_iterator
find_string_attr_containing(const string_attrs_t &sa, string_attr_type_t type, int x)
{
string_attrs_t::const_iterator iter;
for (iter = sa.begin(); iter != sa.end(); ++iter) {
if (iter->sa_type == type && iter->sa_range.contains(x)) {
break;
}
}
return iter;
}
inline string_attrs_t::iterator
find_string_attr(string_attrs_t &sa, const struct line_range &lr)
{

@ -347,6 +347,9 @@ Display options
CTRL-W Toggle word-wrapping.
CTRL-P Show/hide the data preview panel that may be opened when
entering commands or SQL queries.
x Toggle the hiding of log message fields. The hidden fields
will be replaced with three bullets and highlighted in
yellow.

@ -1189,6 +1189,10 @@ void handle_paging_key(int ch)
"disable-word-wrap" : "enable-word-wrap");
break;
case KEY_CTRL_P:
lnav_data.ld_preview_hidden = !lnav_data.ld_preview_hidden;
break;
default:
log_warning("unhandled %d", ch);
lnav_data.ld_rl_view->set_value("Unrecognized keystroke, press "

@ -66,20 +66,20 @@ INSERT INTO http_status_codes VALUES (510, "Not Extended");
INSERT INTO http_status_codes VALUES (511, "Network Authentication Required");
CREATE TABLE lnav_example_log (
log_line integer PRIMARY KEY,
log_part text collate naturalnocase,
log_time datetime,
log_line integer PRIMARY KEY,
log_part text collate naturalnocase,
log_time datetime,
log_actual_time datetime hidden,
log_idle_msecs int,
log_level text collate loglevel,
log_mark boolean,
log_idle_msecs int,
log_level text collate loglevel,
log_mark boolean,
ex_procname text collate 'BINARY',
ex_duration integer,
ex_procname text collate 'BINARY',
ex_duration integer,
log_path text hidden collate naturalnocase,
log_text text hidden,
log_body text hidden
log_path text hidden collate naturalnocase,
log_text text hidden,
log_body text hidden
);
INSERT INTO lnav_example_log VALUES

@ -1026,18 +1026,19 @@ vis_line_t search_forward_from(textview_curses *tc)
static void handle_rl_key(int ch)
{
switch (ch) {
case KEY_PPAGE:
case KEY_NPAGE:
handle_paging_key(ch);
break;
case KEY_PPAGE:
case KEY_NPAGE:
case KEY_CTRL_P:
handle_paging_key(ch);
break;
case KEY_CTRL_RBRACKET:
lnav_data.ld_rl_view->abort();
break;
case KEY_CTRL_RBRACKET:
lnav_data.ld_rl_view->abort();
break;
default:
lnav_data.ld_rl_view->handle_key(ch);
break;
default:
lnav_data.ld_rl_view->handle_key(ch);
break;
}
}
@ -1880,14 +1881,17 @@ static void layout_views()
lnav_data.ld_example_source.text_line_count();
}
int preview_height = lnav_data.ld_preview_source.text_line_count();
int preview_height = lnav_data.ld_preview_hidden ? 0 :
lnav_data.ld_preview_source.text_line_count();
int match_rows = lnav_data.ld_match_source.text_line_count();
int match_height = min((unsigned long)match_rows, (height - 4) / 2);
lnav_data.ld_match_view.set_height(vis_line_t(match_height));
if (doc_height + 10 > (height - match_height)) {
if (doc_height + 14 > (height - match_height - preview_height - 2)) {
doc_height = 0;
preview_height = 0;
preview_status_open = false;
}
bool doc_open = doc_height > 0;
@ -2578,6 +2582,7 @@ static void setup_highlights(textview_curses::highlight_map_t &hm)
"\\bBEFORE\\b|"
"\\bBEGIN\\b|"
"\\bBETWEEN\\b|"
"\\bBOOLEAN\\b|"
"\\bBY\\b|"
"\\bCASCADE\\b|"
"\\bCASE\\b|"
@ -2594,6 +2599,7 @@ static void setup_highlights(textview_curses::highlight_map_t &hm)
"\\bCURRENT_TIME\\b|"
"\\bCURRENT_TIMESTAMP\\b|"
"\\bDATABASE\\b|"
"\\bDATETIME\\b|"
"\\bDEFAULT\\b|"
"\\bDEFERRABLE\\b|"
"\\bDEFERRED\\b|"
@ -2611,6 +2617,7 @@ static void setup_highlights(textview_curses::highlight_map_t &hm)
"\\bEXISTS\\b|"
"\\bEXPLAIN\\b|"
"\\bFAIL\\b|"
"\\bFLOAT\\b|"
"\\bFOR\\b|"
"\\bFOREIGN\\b|"
"\\bFROM\\b|"
@ -2618,6 +2625,7 @@ static void setup_highlights(textview_curses::highlight_map_t &hm)
"\\bGLOB\\b|"
"\\bGROUP\\b|"
"\\bHAVING\\b|"
"\\bHIDDEN\\b|"
"\\bIF\\b|"
"\\bIGNORE\\b|"
"\\bIMMEDIATE\\b|"
@ -2628,6 +2636,7 @@ static void setup_highlights(textview_curses::highlight_map_t &hm)
"\\bINNER\\b|"
"\\bINSERT\\b|"
"\\bINSTEAD\\b|"
"\\bINTEGER\\b|"
"\\bINTERSECT\\b|"
"\\bINTO\\b|"
"\\bIS\\b|"
@ -2671,6 +2680,7 @@ static void setup_highlights(textview_curses::highlight_map_t &hm)
"\\bTABLE\\b|"
"\\bTEMP\\b|"
"\\bTEMPORARY\\b|"
"\\bTEXT\\b|"
"\\bTHEN\\b|"
"\\bTO\\b|"
"\\bTRANSACTION\\b|"
@ -2719,6 +2729,10 @@ static void setup_highlights(textview_curses::highlight_map_t &hm)
hm["$comment"] = highlighter(xpcre_compile(
"(?<=[\\s;])//.*|/\\*.*\\*/|\\(\\*.*\\*\\)|^#.*|\\s+#.*|dnl.*"))
.with_role(view_colors::VCR_COMMENT);
hm["$sqlcomment"] = highlighter(xpcre_compile(
"(?<=[\\s;])--.*"))
.with_text_format(TF_SQL)
.with_role(view_colors::VCR_COMMENT);
hm["$javadoc"] = static_highlighter(
"@(?:author|deprecated|exception|file|param|return|see|since|throws|todo|version)");
hm["$var"] = highlighter(xpcre_compile(

@ -242,6 +242,7 @@ struct _lnav_data {
bottom_status_source ld_bottom_source;
doc_status_source ld_doc_status_source;
preview_status_source ld_preview_status_source;
bool ld_preview_hidden;
listview_curses::action::broadcaster ld_scroll_broadcaster;
listview_curses::action::broadcaster ld_view_stack_broadcaster;
@ -289,6 +290,8 @@ struct _lnav_data {
log_vtab_manager * ld_vtab_manager;
auto_mem<sqlite3, sqlite_close_wrapper> ld_db;
std::unordered_map<std::string, std::string> ld_table_ddl;
std::list<pid_t> ld_children;
std::list<std::shared_ptr<piper_proc>> ld_pipers;
xterm_mouse ld_mouse;

@ -54,9 +54,10 @@ public:
this->vi_supports_indexes = false;
this->ldt_format_impl = lnav_data.ld_vtab_manager->lookup_impl(format->get_name());
this->get_columns_int(this->ldt_cols);
};
void get_columns(std::vector<vtab_column> &cols)
void get_columns_int(std::vector<vtab_column> &cols)
{
content_line_t cl_copy = this->ldt_template_line;
logfile * lf = lnav_data.ld_log_source.find(cl_copy);
@ -94,10 +95,7 @@ public:
std::string colname = cn.add_column(key_str);
int sql_type = SQLITE3_TEXT;
const char *collator = NULL;
char * name;
/* XXX LEAK */
name = strdup(colname.c_str());
switch (pair_iter->e_sub_elements->back().value_token()) {
case DT_IPV4_ADDRESS:
case DT_IPV6_ADDRESS:
@ -112,11 +110,15 @@ public:
collator = "naturalnocase";
break;
}
cols.push_back(vtab_column(name, sql_type, collator));
cols.emplace_back(colname, sql_type, collator);
}
this->ldt_schema_id = dp.dp_schema_id;
};
void get_columns(std::vector<vtab_column> &cols) const {
cols = this->ldt_cols;
};
void get_foreign_keys(std::vector<std::string> &keys_inout) const
{
log_vtab_impl::get_foreign_keys(keys_inout);
@ -238,5 +240,6 @@ private:
log_vtab_impl *ldt_format_impl;
int ldt_parent_column_count;
int64_t ldt_instance;
std::vector<vtab_column> ldt_cols;
};
#endif

@ -1823,7 +1823,7 @@ public:
log_format_vtab_impl(elf), elt_format(elf) {
};
void get_columns(vector<vtab_column> &cols) {
void get_columns(vector<vtab_column> &cols) const {
const external_log_format &elf = this->elt_format;
cols.resize(elf.elf_column_count);
@ -1859,6 +1859,7 @@ public:
cols[vd.vd_column].vc_name = vd.vd_name.get();
cols[vd.vd_column].vc_type = type;
cols[vd.vd_column].vc_collator = vd.vd_collate.c_str();
cols[vd.vd_column].vc_comment = vd.vd_description;
}
};

@ -51,9 +51,10 @@ public:
lst_regex(regex, PCRE_CASELESS),
lst_instance(-1) {
this->vi_supports_indexes = false;
this->get_columns_int(this->lst_cols);
};
void get_columns(std::vector<vtab_column> &cols)
void get_columns_int(std::vector<vtab_column> &cols)
{
column_namer cn;
@ -89,6 +90,10 @@ public:
}
};
void get_columns(std::vector<vtab_column> &cols) const {
cols = this->lst_cols;
}
void get_foreign_keys(std::vector<std::string> &keys_inout) const
{
log_vtab_impl::get_foreign_keys(keys_inout);
@ -177,6 +182,7 @@ private:
pcre_context_static<128> lst_match_context;
std::vector<logline_value::kind_t> lst_column_types;
int64_t lst_instance;
std::vector<vtab_column> lst_cols;
};
#endif

@ -64,34 +64,48 @@ std::string log_vtab_impl::get_table_statement(void)
std::vector<log_vtab_impl::vtab_column> cols;
std::vector<log_vtab_impl::vtab_column>::const_iterator iter;
std::ostringstream oss;
size_t max_name_len = 15;
oss << "CREATE TABLE " << this->get_name().to_string() << " (\n"
<< " log_line INTEGER PRIMARY KEY,\n"
<< " log_part TEXT COLLATE naturalnocase,\n"
<< " log_time DATETIME,\n"
<< " log_line INTEGER PRIMARY KEY,\n"
<< " log_part TEXT COLLATE naturalnocase,\n"
<< " log_time DATETIME,\n"
<< " log_actual_time DATETIME HIDDEN,\n"
<< " log_idle_msecs INTEGER,\n"
<< " log_level TEXT COLLATE loglevel,\n"
<< " log_mark BOOLEAN,\n";
<< " log_idle_msecs INTEGER,\n"
<< " log_level TEXT COLLATE loglevel,\n"
<< " log_mark BOOLEAN,\n"
<< " -- BEGIN Format-specific fields:\n";
this->get_columns(cols);
this->vi_column_count = cols.size();
for (iter = cols.begin(); iter != cols.end(); iter++) {
max_name_len = std::max(max_name_len, iter->vc_name.length());
}
for (iter = cols.begin(); iter != cols.end(); iter++) {
auto_mem<char, sqlite3_free> coldecl;
auto_mem<char, sqlite3_free> colname;
string comment;
if (!iter->vc_comment.empty()) {
comment.append(" -- ")
.append(iter->vc_comment);
}
colname = sql_quote_ident(iter->vc_name.c_str());
coldecl = sqlite3_mprintf(" %s %s %s COLLATE %Q,\n",
coldecl = sqlite3_mprintf(" %-*s %-7s %s COLLATE %-15Q,%s\n",
max_name_len,
colname.in(),
type_to_string(iter->vc_type),
iter->vc_hidden ? "hidden" : "",
(iter->vc_collator == NULL ||
iter->vc_collator[0] == '\0') ?
"BINARY" : iter->vc_collator);
"BINARY" : iter->vc_collator,
comment.c_str());
oss << coldecl;
}
oss << " log_path TEXT HIDDEN COLLATE naturalnocase,\n"
<< " log_text TEXT HIDDEN,\n"
<< " log_body TEXT HIDDEN\n"
oss << " -- END Format-specific fields\n"
<< " log_path TEXT HIDDEN COLLATE naturalnocase,\n"
<< " log_text TEXT HIDDEN,\n"
<< " log_body TEXT HIDDEN\n"
<< ");\n";
log_debug("log_vtab_impl.get_table_statement() -> %s", oss.str().c_str());

@ -74,13 +74,20 @@ public:
vtab_column(const std::string name = "",
int type = SQLITE3_TEXT,
const char *collator = NULL,
bool hidden = false)
: vc_name(name), vc_type(type), vc_collator(collator), vc_hidden(hidden) { };
bool hidden = false,
const std::string comment = "")
: vc_name(name),
vc_type(type),
vc_collator(collator),
vc_hidden(hidden),
vc_comment(comment) {
};
std::string vc_name;
int vc_type;
const char *vc_collator;
bool vc_hidden;
std::string vc_comment;
};
log_vtab_impl(const intern_string_t name) : vi_supports_indexes(true), vi_name(name) {
@ -97,7 +104,7 @@ public:
virtual bool next(log_cursor &lc, logfile_sub_source &lss) = 0;
virtual void get_columns(std::vector<vtab_column> &cols) { };
virtual void get_columns(std::vector<vtab_column> &cols) const { };
virtual void get_foreign_keys(std::vector<std::string> &keys_inout) const
{

@ -42,11 +42,14 @@ public:
TSF_TITLE,
TSF_STITCH_TITLE,
TSF_DESCRIPTION,
TSF_TOGGLE,
TSF__MAX
} field_t;
preview_status_source() {
static const char TOGGLE_MSG[] = "Press CTRL+P to show/hide";
this->tss_fields[TSF_TITLE].set_width(14);
this->tss_fields[TSF_TITLE].set_role(view_colors::VCR_VIEW_STATUS);
this->tss_fields[TSF_TITLE].set_value(" Preview Data ");
@ -54,6 +57,9 @@ public:
this->tss_fields[TSF_STITCH_TITLE].set_stitch_value(
view_colors::ansi_color_pair_index(COLOR_BLUE, COLOR_WHITE));
this->tss_fields[TSF_DESCRIPTION].set_share(1);
this->tss_fields[TSF_TOGGLE].set_width(strlen(TOGGLE_MSG) + 1);
this->tss_fields[TSF_TOGGLE].set_value(TOGGLE_MSG);
this->tss_fields[TSF_TOGGLE].set_left_pad(1);
};
size_t statusview_fields(void) { return TSF__MAX; };

@ -241,6 +241,10 @@ static void rl_search_internal(void *dummy, readline_curses *rc, bool complete =
x -= 1;
}
while (x > 0 && isspace(al.get_string()[x])) {
x -= 1;
}
auto iter = rfind_string_attr_if(sa, x, [](auto sa) {
return (sa.sa_type == &SQL_FUNCTION_ATTR ||
sa.sa_type == &SQL_KEYWORD_ATTR);
@ -288,6 +292,35 @@ static void rl_search_internal(void *dummy, readline_curses *rc, bool complete =
}
}
auto ident_iter = find_string_attr_containing(sa, &SQL_IDENTIFIER_ATTR, x);
if (ident_iter != sa.end()) {
string ident = al.get_substring(ident_iter->sa_range);
auto vtab = lnav_data.ld_vtab_manager->lookup_impl(
intern_string::lookup(ident));
string ddl;
if (vtab != nullptr) {
ddl = trim(vtab->get_table_statement());
} else {
auto table_ddl_iter = lnav_data.ld_table_ddl.find(ident);
if (table_ddl_iter != lnav_data.ld_table_ddl.end()) {
ddl = table_ddl_iter->second;
}
}
if (!ddl.empty()) {
lnav_data.ld_preview_source.replace_with(ddl)
.set_text_format(TF_SQL)
.truncate_to(20);
lnav_data.ld_preview_status_source.get_description()
.set_value("Definition for table -- %s",
ident.c_str());
}
}
if (!has_doc) {
lnav_data.ld_doc_source.clear();
lnav_data.ld_example_source.clear();

@ -74,6 +74,8 @@ static int handle_table_list(void *ptr,
{
if (lnav_data.ld_rl_view != NULL) {
lnav_data.ld_rl_view->add_possibility(LNM_SQL, "*", colvalues[0]);
lnav_data.ld_table_ddl[colvalues[0]] = colvalues[1];
}
return 0;

@ -65,6 +65,7 @@
#define KEY_CTRL_G 7
#define KEY_CTRL_L 12
#define KEY_CTRL_P 16
#define KEY_CTRL_R 18
#define KEY_CTRL_W 23
#define KEY_CTRL_RBRACKET 0x1d

Loading…
Cancel
Save