Skip to content

Commit cd2cc48

Browse files
committed
Merge branch 'master' into develop
2 parents 0a85d60 + 410bcbc commit cd2cc48

18 files changed

Lines changed: 248 additions & 98 deletions

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ Features:
5454
## lnav v0.14.1
5555

5656
Features:
57+
* Added the `:reload-view` command, bound to `F5`, that
58+
re-runs the operation that populated the current view.
59+
In the DB view, this re-executes the last SQL query; in
60+
the TIMELINE view, it rebuilds the index. Views that
61+
don't have a meaningful reload report an error.
5762
* The DB view now shows a status bar above the bottom
5863
status bar with the SQL query that populated the view,
5964
the relative time when it was run, and how long it took.

docs/source/hotkeys.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ Display
317317
- Close the current text file or log file.
318318
* - :kbd:`F2`
319319
- Toggle mouse support.
320+
* - :kbd:`F5`
321+
- Reload the current view. Re-runs the SQL query for the DB view
322+
or rebuilds the index for the TIMELINE view.
320323

321324
Session
322325
-------

docs/source/ui.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,9 @@ PRQL [#]_ statement.
430430
Press :kbd:`v` to switch to the database result view.
431431

432432
A status bar above the bottom status bar shows the query that populated
433-
the view, how long ago it ran, and how long it took. Clicking
434-
the reload icon (↻) at the left of the bar re-runs the query.
433+
the view, how long ago it ran, and how long it took. Clicking the reload
434+
icon (↻) at the left of the bar — or pressing :kbd:`F5` — re-runs the
435+
query via the :code:`:reload-view` command.
435436

436437
If the query reads from log-backed tables (:code:`all_logs`,
437438
per-format tables like :code:`syslog_log`, :code:`all_opids`, etc.),
@@ -486,6 +487,10 @@ The timeline view [#]_ visualizes operations, log files, threads, tags, and
486487
partitions over time. The items are ordered top-to-bottom by their start time.
487488
So, scrolling down will move forward in time.
488489

490+
The timeline index is not refreshed automatically as new log data arrives.
491+
Press :kbd:`F5` (or run :code:`:reload-view`) to rebuild the index with the
492+
latest data.
493+
489494
An operation is identified by an ID that can come from multiple sources:
490495

491496
* If the ID is in the log message, the log format can set the

src/command_executor.cc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ bind_sql_parameters(exec_context& ec, sqlite3_stmt* stmt)
211211
std::map<std::string, scoped_value_t> retval;
212212
auto param_count = sqlite3_bind_parameter_count(stmt);
213213
for (int lpc = 0; lpc < param_count; lpc++) {
214-
std::map<std::string, std::string>::iterator ov_iter;
215214
const auto* name = sqlite3_bind_parameter_name(stmt, lpc + 1);
216215
if (name == nullptr) {
217216
auto um
@@ -479,6 +478,17 @@ execute_sql(exec_context& ec, const std::string& sql, std::string& alt_msg)
479478
if (!ec.ec_label_source_stack.empty()) {
480479
auto& dls = *ec.ec_label_source_stack.back();
481480
dls.dls_user_query = sql;
481+
if (!ec.ec_source.empty()) {
482+
dls.dls_user_query_src_loc
483+
= ec.ec_source.back().s_location;
484+
} else {
485+
dls.dls_user_query_src_loc = std::nullopt;
486+
}
487+
if (!ec.ec_local_vars.empty()) {
488+
dls.dls_user_query_vars = ec.ec_local_vars.top();
489+
} else {
490+
dls.dls_user_query_vars.clear();
491+
}
482492
dls.dls_query_start = std::chrono::system_clock::now();
483493
auto* vtab_mgr = injector::get<log_vtab_manager*>();
484494
dls.dls_query_touches_log_data

src/db_status_source.cc

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@
3131

3232
#include "base/attr_line.hh"
3333
#include "base/humanize.time.hh"
34+
#include "base/injector.hh"
3435
#include "base/intern_string.hh"
3536
#include "base/string_attr_type.hh"
3637
#include "base/time_util.hh"
3738
#include "command_executor.hh"
3839
#include "db_sub_source.hh"
3940
#include "fmt/format.h"
40-
#include "lnav.hh"
41+
#include "logfile_sub_source.hh"
4142
#include "readline_highlighters.hh"
42-
#include "sql.formatter.hh"
4343

4444
using namespace lnav::roles::literals;
4545

@@ -53,22 +53,6 @@ db_status_source::db_status_source()
5353
role_t::VCR_STATUS_STITCH_TITLE_TO_NORMAL,
5454
role_t::VCR_STATUS_STITCH_NORMAL_TO_TITLE);
5555
this->dss_fields[DSF_RELOAD].set_width(3);
56-
this->dss_fields[DSF_RELOAD].on_click = [](status_field&) {
57-
auto query = lnav_data.ld_db_row_source.dls_user_query;
58-
if (query.empty()) {
59-
return;
60-
}
61-
std::string alt_msg;
62-
auto& ec = lnav_data.ld_exec_context;
63-
auto src_guard = ec.enter_source(intern_string::lookup("db-reload"),
64-
1,
65-
fmt::format(FMT_STRING(";{}"), query));
66-
auto result = execute_sql(ec, query, alt_msg);
67-
if (result.isErr()) {
68-
auto um = result.unwrapErr();
69-
ec.ec_msg_callback_stack.back()(um);
70-
}
71-
};
7256
this->dss_fields[DSF_QUERY].set_share(3);
7357
this->dss_fields[DSF_TIMING].right_justify(true);
7458
this->dss_fields[DSF_TIMING].set_width(80);
@@ -77,7 +61,8 @@ db_status_source::db_status_source()
7761
bool
7862
db_status_source::update_from_db_source()
7963
{
80-
const auto& dls = lnav_data.ld_db_row_source;
64+
static const auto& dls = injector::get<db_label_source&>();
65+
static auto& lss = injector::get<logfile_sub_source&>();
8166
auto changed = false;
8267

8368
if (dls.dls_user_query.empty()) {
@@ -111,11 +96,9 @@ db_status_source::update_from_db_source()
11196
.to_string();
11297
timing_al.append("ran ").append(lnav::roles::time_ago(ago));
11398
if (dls.dls_query_touches_log_data) {
114-
auto& lss = lnav_data.ld_log_source;
11599
bool is_stale
116100
= lss.lss_index_generation != dls.dls_log_gen_at_query
117-
|| lss.text_line_count()
118-
!= dls.dls_log_line_count_at_query;
101+
|| lss.text_line_count() != dls.dls_log_line_count_at_query;
119102
timing_al.append(" on ").append(
120103
is_stale ? lnav::roles::warning("old log data")
121104
: lnav::roles::ok("current log data"));

src/db_sub_source.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,18 @@
3434

3535
#include "base/ansi_scrubber.hh"
3636
#include "base/date_time_scanner.hh"
37+
#include "base/func_util.hh"
3738
#include "base/humanize.hh"
3839
#include "base/itertools.enumerate.hh"
3940
#include "base/itertools.hh"
4041
#include "base/map_util.hh"
4142
#include "base/math_util.hh"
4243
#include "base/time_util.hh"
4344
#include "base/types.hh"
45+
#include "command_executor.hh"
4446
#include "config.h"
4547
#include "hist_source_T.hh"
48+
#include "lnav_util.hh"
4649
#include "log_level.hh"
4750
#include "scn/scan.h"
4851
#include "yajlpp/json_ptr.hh"
@@ -663,6 +666,8 @@ db_label_source::clear()
663666
{
664667
this->dls_generation += 1;
665668
this->dls_user_query.clear();
669+
this->dls_user_query_src_loc = std::nullopt;
670+
this->dls_user_query_vars.clear();
666671
this->dls_query_start = std::nullopt;
667672
this->dls_query_end = std::nullopt;
668673
this->dls_query_touches_log_data = false;
@@ -850,6 +855,30 @@ db_label_source::text_row_details(const textview_curses& tc)
850855
return std::nullopt;
851856
}
852857

858+
Result<std::string, lnav::console::user_message>
859+
db_label_source::text_reload_data(exec_context& ec)
860+
{
861+
if (this->dls_user_query.empty()) {
862+
return ec.make_error("no previous query to re-run");
863+
}
864+
865+
auto prev_query = this->dls_user_query;
866+
auto prev_loc = this->dls_user_query_src_loc.value_or(INTERNAL_SRC_LOC);
867+
auto prev_vars = this->dls_user_query_vars;
868+
std::string alt_msg;
869+
870+
auto src_guard = ec.enter_source(
871+
prev_loc, fmt::format(FMT_STRING(";{}"), prev_query));
872+
auto db_guard = ec.enter_db_source(this);
873+
auto cb_guard = ec.push_callback(sql_callback);
874+
875+
ec.ec_local_vars.emplace(std::move(prev_vars));
876+
auto vars_guard
877+
= finally([&ec]() { ec.ec_local_vars.pop(); });
878+
879+
return execute_sql(ec, prev_query, alt_msg);
880+
}
881+
853882
std::optional<std::string>
854883
db_label_source::text_view_details() const
855884
{

src/db_sub_source.hh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include "ArenaAlloc/arenaalloc.h"
4343
#include "base/cell_container.hh"
44+
#include "base/file_range.hh"
4445
#include "base/lnav.resolver.hh"
4546
#include "base/sparse_cursor_container.hh"
4647
#include "digestible/digestible.h"
@@ -118,6 +119,9 @@ public:
118119

119120
std::optional<std::string> text_view_details() const override;
120121

122+
Result<std::string, lnav::console::user_message> text_reload_data(
123+
exec_context& ec) override;
124+
121125
std::string get_cell_as_string(vis_line_t row, size_t col);
122126
std::optional<int64_t> get_cell_as_int64(vis_line_t row, size_t col) const;
123127
std::optional<double> get_cell_as_double(vis_line_t row, size_t col) const;
@@ -182,6 +186,8 @@ public:
182186

183187
uint32_t dls_generation{0};
184188
std::string dls_user_query;
189+
std::optional<source_location> dls_user_query_src_loc;
190+
std::map<std::string, scoped_value_t> dls_user_query_vars;
185191
std::optional<std::chrono::system_clock::time_point> dls_query_start;
186192
std::optional<std::chrono::system_clock::time_point> dls_query_end;
187193
bool dls_query_touches_log_data{false};

src/internals/cmd-ref.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,19 @@
14491449
----
14501450

14511451

1452+
.. _reload_view:
1453+
1454+
:reload-view
1455+
^^^^^^^^^^^^
1456+
1457+
Re-run the operation that populated the current view
1458+
1459+
**See Also**
1460+
1461+
1462+
----
1463+
1464+
14521465
.. _reset_config:
14531466

14541467
:reset-config *option*

src/keymaps/default-keymap.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
"f1": {
2424
"command": ":help"
2525
},
26+
"f5": {
27+
"command": ":reload-view"
28+
},
2629
"f7": {
2730
"command": "|lnav-moveto-breakpoint prev"
2831
},

src/lnav.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ static auto bound_lnav_flags
239239
static auto bound_lnav_exec_context
240240
= injector::bind<exec_context>::to_instance(&lnav_data.ld_exec_context);
241241

242+
static auto bound_db_row_source
243+
= injector::bind<db_label_source>::to_instance(&lnav_data.ld_db_row_source);
244+
242245
static auto bound_log_source
243246
= injector::bind<logfile_sub_source>::to_instance(&lnav_data.ld_log_source);
244247

@@ -1766,6 +1769,17 @@ VALUES ('org.lnav.mouse-support', -1, DATETIME('now', '+1 minute'),
17661769

17671770
execute_command(lnav_data.ld_exec_context, cmd);
17681771
};
1772+
lnav_data.ld_db_status_source
1773+
.statusview_value_for_field(db_status_source::DSF_RELOAD)
1774+
.on_click = [](status_field&) {
1775+
auto& ec = lnav_data.ld_exec_context;
1776+
auto prov_guard = ec.with_provenance(exec_context::mouse_input{});
1777+
auto res = ec.execute(INTERNAL_SRC_LOC, ":reload-view");
1778+
if (res.isErr()) {
1779+
auto um = res.unwrapErr();
1780+
ec.ec_msg_callback_stack.back()(um);
1781+
}
1782+
};
17691783

17701784
lnav_data.ld_status[LNS_TOP].set_title("top");
17711785
lnav_data.ld_status[LNS_TOP].set_y(0);

0 commit comments

Comments
 (0)