dbviewer 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 648be97f775ec9c5d18dabf9ebe90e164d760fde2b1e3c9c9ff2442eb6dba9fe
4
- data.tar.gz: f0510fd50eabd5ba176d99e9dd3b66d074d1ccaf6cf15aa43a82beec0e45e923
3
+ metadata.gz: 151a189372c94a737108969cd768ab9dbc4e16a2abc608f07026d1a6b7ee65a5
4
+ data.tar.gz: a5fa3a4f4aa8e1acd606f60c2264412a261beec6b6889675ef941d05d1e593cb
5
5
  SHA512:
6
- metadata.gz: 84bdca42e27ed6dbcf2dfdcdb2756558796b0e2ecc727fa46ffe7fd734bf66d21d5fd76c47d9ae632a003292048c78151a412fcc98c6b33954d2f23cd7b71c19
7
- data.tar.gz: 9f1204704614413b211b1814c96660656e03579712015152b3323f9dff0d64caaff5b96017cbbe203ed9a77ce15bc23e0e1d9473143edca14824f1380b925a25
6
+ metadata.gz: e8345197920cf8c6a006d3faecd9a0b9f2a6ef4c972226707203ba43b121e05c3a02195eec4d38a699231ae488741802a9dff5c7317ddc576f4e27381ad897e7
7
+ data.tar.gz: b9a8ff1804963de25e85f9a288c198ee4aaa23cf25253ff99f0ce84f3e470e2e35a47c304ff24b2cbd962d9c913fb69b08f11d6bbd2d213af52113ce4d048e18
data/README.md CHANGED
@@ -24,6 +24,7 @@ It's designed for development, debugging, and database analysis, offering a clea
24
24
  - Navigate through large datasets with an intuitive pagination interface
25
25
  - Scrollable table with fixed headers for improved navigation
26
26
  - Single-line cell display with ellipsis for wide content (tooltips on hover)
27
+ - Export table data to CSV format (configurable via `enable_data_export` option)
27
28
  - **SQL Queries**:
28
29
  - Run custom SELECT queries against your database in a secure, read-only environment
29
30
  - View table structure reference while writing queries
@@ -179,6 +180,7 @@ Dbviewer.configure do |config|
179
180
  config.query_timeout = 30 # SQL query timeout in seconds
180
181
 
181
182
  # Query logging options
183
+ config.enable_query_logging = true # Enable or disable query logging completely (default: true)
182
184
  config.query_logging_mode = :memory # Storage mode for SQL queries (:memory or :file)
183
185
  config.query_log_path = "log/dbviewer.log" # Path for query log file when in :file mode
184
186
  config.max_memory_queries = 1000 # Maximum number of queries to store in memory
@@ -194,6 +196,14 @@ The configuration is accessed through `Dbviewer.configuration` throughout the co
194
196
 
195
197
  DBViewer includes a powerful SQL query logging system that captures and analyzes database queries. You can access this log through the `/dbviewer/logs` endpoint. The logging system offers two storage backends:
196
198
 
199
+ ### Disabling Query Logging
200
+
201
+ You can completely disable query logging if you don't need this feature:
202
+
203
+ ```ruby
204
+ config.enable_query_logging = false # Disable query logging completely
205
+ ```
206
+
197
207
  ### In-Memory Storage (Default)
198
208
 
199
209
  By default, queries are stored in memory. This provides fast access but queries are lost when the application restarts:
@@ -1,6 +1,7 @@
1
1
  module Dbviewer
2
2
  class LogsController < ApplicationController
3
3
  before_action :set_filters, only: [ :index ]
4
+ before_action :check_logging_enabled
4
5
 
5
6
  def index
6
7
  @queries = dbviewer_logger.recent_queries(
@@ -28,6 +29,13 @@ module Dbviewer
28
29
 
29
30
  private
30
31
 
32
+ def check_logging_enabled
33
+ unless Dbviewer.configuration.enable_query_logging
34
+ flash[:warning] = "Query logging is disabled. Enable it in the configuration to use this feature."
35
+ redirect_to root_path
36
+ end
37
+ end
38
+
31
39
  def set_filters
32
40
  @table_filter = params[:table_filter]
33
41
  @request_id = params[:request_id]
@@ -62,6 +62,12 @@ module Dbviewer
62
62
  end
63
63
 
64
64
  def export_csv
65
+ unless Dbviewer.configuration.enable_data_export
66
+ flash[:alert] = "Data export is disabled in the configuration"
67
+ redirect_to table_path(params[:id])
68
+ return
69
+ end
70
+
65
71
  table_name = params[:id]
66
72
  limit = (params[:limit] || 10000).to_i
67
73
  include_headers = params[:include_headers] != "0"
@@ -94,46 +94,55 @@
94
94
  <div class="card shadow-sm">
95
95
  <div class="card-header d-flex justify-content-between align-items-center">
96
96
  <h5 class="card-title mb-0">Recent SQL Queries</h5>
97
- <a href="<%= dbviewer.logs_path %>" class="btn btn-sm btn-primary">View All Logs</a>
97
+ <% if Dbviewer.configuration.enable_query_logging %>
98
+ <a href="<%= dbviewer.logs_path %>" class="btn btn-sm btn-primary">View All Logs</a>
99
+ <% end %>
98
100
  </div>
99
101
  <div class="card-body p-0">
100
102
  <% begin %>
101
103
  <% require_dependency "dbviewer/logger" %>
102
- <% queries = Dbviewer::Logger.instance.recent_queries(limit: 10) %>
103
-
104
- <% if queries.any? %>
105
- <div class="table-responsive">
106
- <table class="table table-sm table-hover mb-0">
104
+ <% if Dbviewer.configuration.enable_query_logging %>
105
+ <% queries = Dbviewer::Logger.instance.recent_queries(limit: 10) %>
106
+
107
+ <% if queries.any? %>
108
+ <div class="table-responsive">
109
+ <table class="table table-sm table-hover mb-0">
107
110
 
108
- <thead>
109
- <tr>
110
- <th>Query</th>
111
- <th class="text-end" style="width: 120px">Duration</th>
112
- <th class="text-end" style="width: 180px">Time</th>
113
- </tr>
114
- </thead>
115
- <tbody>
116
- <% queries.each do |query| %>
111
+ <thead>
117
112
  <tr>
118
- <td class="text-truncate" style="max-width: 500px;">
119
- <code class="sql-query-code"><%= query[:sql] %></code>
120
- </td>
121
- <td class="text-end">
122
- <span class="<%= query[:duration_ms] > 100 ? 'query-duration-slow' : 'query-duration' %>">
123
- <%= query[:duration_ms] %> ms
124
- </span>
125
- </td>
126
- <td class="text-end query-timestamp">
127
- <small><%= query[:timestamp].strftime("%H:%M:%S") %></small>
128
- </td>
113
+ <th>Query</th>
114
+ <th class="text-end" style="width: 120px">Duration</th>
115
+ <th class="text-end" style="width: 180px">Time</th>
129
116
  </tr>
130
- <% end %>
131
- </tbody>
132
- </table>
133
- </div>
117
+ </thead>
118
+ <tbody>
119
+ <% queries.each do |query| %>
120
+ <tr>
121
+ <td class="text-truncate" style="max-width: 500px;">
122
+ <code class="sql-query-code"><%= query[:sql] %></code>
123
+ </td>
124
+ <td class="text-end">
125
+ <span class="<%= query[:duration_ms] > 100 ? 'query-duration-slow' : 'query-duration' %>">
126
+ <%= query[:duration_ms] %> ms
127
+ </span>
128
+ </td>
129
+ <td class="text-end query-timestamp">
130
+ <small><%= query[:timestamp].strftime("%H:%M:%S") %></small>
131
+ </td>
132
+ </tr>
133
+ <% end %>
134
+ </tbody>
135
+ </table>
136
+ </div>
137
+ <% else %>
138
+ <div class="text-center my-4 empty-data-message">
139
+ <p>No queries recorded yet</p>
140
+ </div>
141
+ <% end %>
134
142
  <% else %>
135
143
  <div class="text-center my-4 empty-data-message">
136
- <p>No queries recorded yet</p>
144
+ <p>Query logging is disabled</p>
145
+ <small class="text-muted">Enable it in the configuration to see SQL queries here</small>
137
146
  </div>
138
147
  <% end %>
139
148
  <% rescue => e %>
@@ -11,53 +11,57 @@
11
11
  <div class="d-flex justify-content-between align-items-center mb-4">
12
12
  <h1>Table: <%= @table_name %></h1>
13
13
  <div class="d-flex gap-2">
14
- <button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#csvExportModal">
15
- <i class="bi bi-file-earmark-spreadsheet me-1"></i> Export CSV
16
- </button>
14
+ <% if Dbviewer.configuration.enable_data_export %>
15
+ <button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#csvExportModal">
16
+ <i class="bi bi-file-earmark-spreadsheet me-1"></i> Export CSV
17
+ </button>
18
+ <% end %>
17
19
  <%= link_to query_table_path(@table_name), class: "btn btn-primary" do %>
18
20
  <i class="bi bi-code-square me-1"></i> Run SQL Query
19
21
  <% end %>
20
22
  </div>
21
23
  </div>
22
24
 
23
- <!-- CSV Export Modal -->
24
- <div class="modal fade" id="csvExportModal" tabindex="-1" aria-labelledby="csvExportModalLabel" aria-hidden="true">
25
- <div class="modal-dialog">
26
- <div class="modal-content">
27
- <div class="modal-header">
28
- <h5 class="modal-title" id="csvExportModalLabel">Export <strong><%= @table_name %></strong> to CSV</h5>
29
- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
30
- </div>
31
- <div class="modal-body">
32
- <%= form_with url: export_csv_table_path(@table_name), method: :get, id: "csvExportForm" do |form| %>
33
- <div class="mb-3">
34
- <label for="limit" class="form-label">Maximum number of records</label>
35
- <input type="number" class="form-control" id="limit" name="limit" value="10000" min="1" max="100000">
36
- <div class="form-text">Limit the number of records to export. Large exports may take some time.</div>
37
- </div>
38
-
39
- <% if @total_count > 10000 %>
40
- <div class="alert alert-warning">
41
- <i class="bi bi-exclamation-triangle-fill me-2"></i>
42
- This table has <%= number_with_delimiter(@total_count) %> records. Exporting all records may be slow.
25
+ <% if Dbviewer.configuration.enable_data_export %>
26
+ <!-- CSV Export Modal -->
27
+ <div class="modal fade" id="csvExportModal" tabindex="-1" aria-labelledby="csvExportModalLabel" aria-hidden="true">
28
+ <div class="modal-dialog">
29
+ <div class="modal-content">
30
+ <div class="modal-header">
31
+ <h5 class="modal-title" id="csvExportModalLabel">Export <strong><%= @table_name %></strong> to CSV</h5>
32
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
33
+ </div>
34
+ <div class="modal-body">
35
+ <%= form_with url: export_csv_table_path(@table_name), method: :get, id: "csvExportForm" do |form| %>
36
+ <div class="mb-3">
37
+ <label for="limit" class="form-label">Maximum number of records</label>
38
+ <input type="number" class="form-control" id="limit" name="limit" value="10000" min="1" max="100000">
39
+ <div class="form-text">Limit the number of records to export. Large exports may take some time.</div>
40
+ </div>
41
+
42
+ <% if @total_count > 10000 %>
43
+ <div class="alert alert-warning">
44
+ <i class="bi bi-exclamation-triangle-fill me-2"></i>
45
+ This table has <%= number_with_delimiter(@total_count) %> records. Exporting all records may be slow.
46
+ </div>
47
+ <% end %>
48
+
49
+ <div class="mb-3 form-check">
50
+ <input type="checkbox" class="form-check-input" id="includeHeaders" name="include_headers" checked>
51
+ <label class="form-check-label" for="includeHeaders">Include column headers</label>
43
52
  </div>
44
53
  <% end %>
45
-
46
- <div class="mb-3 form-check">
47
- <input type="checkbox" class="form-check-input" id="includeHeaders" name="include_headers" checked>
48
- <label class="form-check-label" for="includeHeaders">Include column headers</label>
49
- </div>
50
- <% end %>
51
- </div>
52
- <div class="modal-footer">
53
- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
54
- <button type="submit" form="csvExportForm" class="btn btn-success">
55
- <i class="bi bi-download me-1"></i> Export CSV
56
- </button>
54
+ </div>
55
+ <div class="modal-footer">
56
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
57
+ <button type="submit" form="csvExportForm" class="btn btn-success">
58
+ <i class="bi bi-download me-1"></i> Export CSV
59
+ </button>
60
+ </div>
57
61
  </div>
58
62
  </div>
59
63
  </div>
60
- </div>
64
+ <% end %>
61
65
 
62
66
  <!-- Records Section -->
63
67
  <div class="dbviewer-card card mb-4">
@@ -571,9 +571,11 @@
571
571
  <li class="nav-item">
572
572
  <%= link_to raw('<i class="bi bi-diagram-3"></i> ERD'), dbviewer.entity_relationship_diagrams_path, class: "nav-link #{erd_nav_class}" %>
573
573
  </li>
574
- <li class="nav-item">
575
- <%= link_to raw('<i class="bi bi-journal-code"></i> SQL Logs'), dbviewer.logs_path, class: "nav-link #{logs_nav_class}" %>
576
- </li>
574
+ <% if Dbviewer.configuration.enable_query_logging %>
575
+ <li class="nav-item">
576
+ <%= link_to raw('<i class="bi bi-journal-code"></i> SQL Logs'), dbviewer.logs_path, class: "nav-link #{logs_nav_class}" %>
577
+ </li>
578
+ <% end %>
577
579
  </ul>
578
580
  <ul class="navbar-nav ms-auto">
579
581
  <li class="nav-item">
@@ -603,6 +605,17 @@
603
605
  <!-- Main Content Area -->
604
606
  <div class="dbviewer-main">
605
607
  <div class="dbviewer-main-content">
608
+ <!-- Flash Messages -->
609
+ <% if flash.any? %>
610
+ <% flash.each do |type, message| %>
611
+ <% alert_class = type.to_s == 'notice' ? 'alert-info' : 'alert-danger' %>
612
+ <div class="alert <%= alert_class %> alert-dismissible fade show mb-3" role="alert">
613
+ <%= message %>
614
+ <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
615
+ </div>
616
+ <% end %>
617
+ <% end %>
618
+
606
619
  <div class="d-flex d-lg-none align-items-center mb-3">
607
620
  <button class="btn btn-sm btn-outline-primary dbviewer-sidebar-toggle" type="button">
608
621
  <i class="bi bi-list me-1"></i> Tables
@@ -31,6 +31,9 @@ module Dbviewer
31
31
  # Maximum number of queries to keep in memory
32
32
  attr_accessor :max_memory_queries
33
33
 
34
+ # Enable or disable query logging completely
35
+ attr_accessor :enable_query_logging
36
+
34
37
  # Admin access credentials hash with :username and :password keys
35
38
  # @example { username: 'admin', password: 'secret' }
36
39
  attr_accessor :admin_credentials
@@ -46,6 +49,7 @@ module Dbviewer
46
49
  @query_logging_mode = :memory
47
50
  @query_log_path = "log/dbviewer.log"
48
51
  @max_memory_queries = 1000
52
+ @enable_query_logging = true
49
53
  @admin_credentials = nil
50
54
  end
51
55
  end
@@ -10,6 +10,8 @@ module Dbviewer
10
10
 
11
11
  # Add a new SQL event query to the logger
12
12
  def add(event)
13
+ # Return early if query logging is disabled
14
+ return unless Dbviewer.configuration.enable_query_logging
13
15
  return if QueryParser.should_skip_query?(event)
14
16
 
15
17
  current_time = Time.now
@@ -1,3 +1,3 @@
1
1
  module Dbviewer
2
- VERSION = "0.3.5"
2
+ VERSION = "0.3.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbviewer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wailan Tirajoh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-19 00:00:00.000000000 Z
11
+ date: 2025-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails