dbviewer 0.6.6 → 0.6.8
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 +4 -4
- data/README.md +12 -36
- data/app/assets/javascripts/dbviewer/entity_relationship_diagram.js +553 -0
- data/app/assets/javascripts/dbviewer/home.js +287 -0
- data/app/assets/javascripts/dbviewer/layout.js +194 -0
- data/app/assets/javascripts/dbviewer/query.js +277 -0
- data/app/assets/javascripts/dbviewer/table.js +1563 -0
- data/app/assets/stylesheets/dbviewer/application.css +1460 -21
- data/app/assets/stylesheets/dbviewer/entity_relationship_diagram.css +181 -0
- data/app/assets/stylesheets/dbviewer/home.css +229 -0
- data/app/assets/stylesheets/dbviewer/logs.css +64 -0
- data/app/assets/stylesheets/dbviewer/query.css +171 -0
- data/app/assets/stylesheets/dbviewer/table.css +1144 -0
- data/app/views/dbviewer/connections/index.html.erb +0 -30
- data/app/views/dbviewer/entity_relationship_diagrams/index.html.erb +14 -713
- data/app/views/dbviewer/home/index.html.erb +9 -499
- data/app/views/dbviewer/logs/index.html.erb +22 -221
- data/app/views/dbviewer/tables/index.html.erb +0 -65
- data/app/views/dbviewer/tables/query.html.erb +129 -565
- data/app/views/dbviewer/tables/show.html.erb +4 -2429
- data/app/views/layouts/dbviewer/application.html.erb +13 -1544
- data/lib/dbviewer/version.rb +1 -1
- metadata +12 -7
- data/app/assets/javascripts/dbviewer/connections.js +0 -70
- data/app/assets/stylesheets/dbviewer/dbviewer.css +0 -0
- data/app/assets/stylesheets/dbviewer/enhanced.css +0 -0
- data/app/views/dbviewer/connections/new.html.erb +0 -79
- data/app/views/dbviewer/tables/mini_erd.html.erb +0 -517
@@ -1,6 +1,22 @@
|
|
1
1
|
<% content_for :title, "SQL Query Logs" %>
|
2
2
|
|
3
|
+
<% content_for :head do %>
|
4
|
+
<%= stylesheet_link_tag "dbviewer/logs", "data-turbo-track": "reload" %>
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
|
3
8
|
<div class="container-fluid">
|
9
|
+
<% unless Rails.env.development? %>
|
10
|
+
<div class="alert alert-warning mb-3">
|
11
|
+
<div class="d-flex align-items-center">
|
12
|
+
<i class="bi bi-exclamation-triangle-fill me-2 fs-5"></i>
|
13
|
+
<div>
|
14
|
+
<strong>Warning:</strong> SQL Query logs are disabled in non-development environments.
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
19
|
+
|
4
20
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
5
21
|
<h1>
|
6
22
|
<i class="bi bi-journal-code me-2"></i>SQL Query Logs
|
@@ -378,7 +394,12 @@
|
|
378
394
|
<td colspan="6" class="text-center py-5 empty-data-message">
|
379
395
|
<i class="bi bi-database-x fs-2 d-block mb-2"></i>
|
380
396
|
No SQL queries logged yet.
|
381
|
-
|
397
|
+
<% if Rails.env.development? %>
|
398
|
+
<p class="mt-2">Navigate through the application to see queries being logged here.</p>
|
399
|
+
<% else %>
|
400
|
+
<p class="mt-2">SQL Query logs are disabled in non-development environments.</p>
|
401
|
+
<small class="text-muted d-block">To enable logs in this environment, set <code>enable_query_logging = true</code> in your configuration.</small>
|
402
|
+
<% end %>
|
382
403
|
</td>
|
383
404
|
</tr>
|
384
405
|
<% end %>
|
@@ -388,223 +409,3 @@
|
|
388
409
|
</div>
|
389
410
|
</div>
|
390
411
|
</div>
|
391
|
-
|
392
|
-
<% if @stats[:tables_queried].present? %>
|
393
|
-
<script>
|
394
|
-
document.addEventListener('DOMContentLoaded', function() {
|
395
|
-
const ctx = document.getElementById('tablesChart').getContext('2d');
|
396
|
-
const tableData = <%= raw @stats[:tables_queried].to_json %>;
|
397
|
-
const labels = Object.keys(tableData);
|
398
|
-
const values = Object.values(tableData);
|
399
|
-
|
400
|
-
// Get theme-compatible colors
|
401
|
-
const isDarkMode = document.documentElement.getAttribute('data-bs-theme') === 'dark';
|
402
|
-
const chartBgColor = isDarkMode ? 'rgba(75, 192, 192, 0.4)' : 'rgba(75, 192, 192, 0.6)';
|
403
|
-
const chartBorderColor = isDarkMode ? 'rgba(75, 192, 192, 0.8)' : 'rgba(75, 192, 192, 1)';
|
404
|
-
|
405
|
-
const chart = new Chart(ctx, {
|
406
|
-
type: 'bar',
|
407
|
-
data: {
|
408
|
-
labels: labels,
|
409
|
-
datasets: [{
|
410
|
-
label: 'Query Count',
|
411
|
-
data: values,
|
412
|
-
backgroundColor: chartBgColor,
|
413
|
-
borderColor: chartBorderColor,
|
414
|
-
borderWidth: 1
|
415
|
-
}]
|
416
|
-
},
|
417
|
-
options: {
|
418
|
-
scales: {
|
419
|
-
y: {
|
420
|
-
beginAtZero: true,
|
421
|
-
ticks: {
|
422
|
-
precision: 0,
|
423
|
-
color: getComputedStyle(document.documentElement).getPropertyValue('--bs-body-color')
|
424
|
-
},
|
425
|
-
grid: {
|
426
|
-
color: getComputedStyle(document.documentElement).getPropertyValue('--bs-border-color-translucent')
|
427
|
-
}
|
428
|
-
},
|
429
|
-
x: {
|
430
|
-
ticks: {
|
431
|
-
color: getComputedStyle(document.documentElement).getPropertyValue('--bs-body-color')
|
432
|
-
},
|
433
|
-
grid: {
|
434
|
-
color: getComputedStyle(document.documentElement).getPropertyValue('--bs-border-color-translucent')
|
435
|
-
}
|
436
|
-
}
|
437
|
-
},
|
438
|
-
plugins: {
|
439
|
-
legend: {
|
440
|
-
display: false,
|
441
|
-
labels: {
|
442
|
-
color: getComputedStyle(document.documentElement).getPropertyValue('--bs-body-color')
|
443
|
-
}
|
444
|
-
},
|
445
|
-
title: {
|
446
|
-
display: true,
|
447
|
-
text: 'Number of Queries by Table',
|
448
|
-
color: getComputedStyle(document.documentElement).getPropertyValue('--bs-body-color')
|
449
|
-
},
|
450
|
-
tooltip: {
|
451
|
-
callbacks: {
|
452
|
-
label: function(context) {
|
453
|
-
return `${context.parsed.y} queries`;
|
454
|
-
}
|
455
|
-
}
|
456
|
-
}
|
457
|
-
}
|
458
|
-
});
|
459
|
-
|
460
|
-
// Update chart when theme changes
|
461
|
-
document.addEventListener('dbviewerThemeChanged', function(e) {
|
462
|
-
const isDarkMode = e.detail.theme === 'dark';
|
463
|
-
const chartBgColor = isDarkMode ? 'rgba(75, 192, 192, 0.4)' : 'rgba(75, 192, 192, 0.6)';
|
464
|
-
const chartBorderColor = isDarkMode ? 'rgba(75, 192, 192, 0.8)' : 'rgba(75, 192, 192, 1)';
|
465
|
-
|
466
|
-
chart.data.datasets[0].backgroundColor = chartBgColor;
|
467
|
-
chart.data.datasets[0].borderColor = chartBorderColor;
|
468
|
-
|
469
|
-
// Update text colors
|
470
|
-
chart.options.scales.y.ticks.color = getComputedStyle(document.documentElement).getPropertyValue('--bs-body-color');
|
471
|
-
chart.options.scales.x.ticks.color = getComputedStyle(document.documentElement).getPropertyValue('--bs-body-color');
|
472
|
-
chart.options.scales.y.grid.color = getComputedStyle(document.documentElement).getPropertyValue('--bs-border-color-translucent');
|
473
|
-
chart.options.scales.x.grid.color = getComputedStyle(document.documentElement).getPropertyValue('--bs-border-color-translucent');
|
474
|
-
chart.options.plugins.title.color = getComputedStyle(document.documentElement).getPropertyValue('--bs-body-color');
|
475
|
-
|
476
|
-
chart.update();
|
477
|
-
});
|
478
|
-
});
|
479
|
-
</script>
|
480
|
-
<% end %>
|
481
|
-
|
482
|
-
<style>
|
483
|
-
.sql-query {
|
484
|
-
white-space: pre-wrap;
|
485
|
-
word-wrap: break-word;
|
486
|
-
max-height: 100px;
|
487
|
-
overflow-y: auto;
|
488
|
-
font-size: 0.85rem;
|
489
|
-
background-color: #f8f9fa;
|
490
|
-
border-radius: 3px;
|
491
|
-
padding: 0.5rem;
|
492
|
-
}
|
493
|
-
|
494
|
-
.request-group-header {
|
495
|
-
border-top: 2px solid #dee2e6;
|
496
|
-
}
|
497
|
-
|
498
|
-
.request-group-header:first-child {
|
499
|
-
border-top: none;
|
500
|
-
}
|
501
|
-
|
502
|
-
details summary {
|
503
|
-
cursor: pointer;
|
504
|
-
}
|
505
|
-
|
506
|
-
.cursor-pointer {
|
507
|
-
cursor: pointer;
|
508
|
-
}
|
509
|
-
|
510
|
-
/* Rotate icon when expanded */
|
511
|
-
.collapsed-section[aria-expanded="true"] .bi-chevron-down {
|
512
|
-
transform: rotate(180deg);
|
513
|
-
transition: transform 0.3s ease;
|
514
|
-
}
|
515
|
-
|
516
|
-
.collapsed-section[aria-expanded="false"] .bi-chevron-down {
|
517
|
-
transform: rotate(0deg);
|
518
|
-
transition: transform 0.3s ease;
|
519
|
-
}
|
520
|
-
</style>
|
521
|
-
|
522
|
-
<style>
|
523
|
-
/* SQL query styling with dark mode support */
|
524
|
-
.sql-query {
|
525
|
-
white-space: pre-wrap;
|
526
|
-
word-wrap: break-word;
|
527
|
-
max-height: 100px;
|
528
|
-
overflow-y: auto;
|
529
|
-
font-size: 0.85rem;
|
530
|
-
border-radius: 3px;
|
531
|
-
padding: 0.5rem;
|
532
|
-
}
|
533
|
-
|
534
|
-
/* Dark mode compatible styling */
|
535
|
-
.sql-code-block {
|
536
|
-
background-color: var(--bs-secondary-bg);
|
537
|
-
}
|
538
|
-
|
539
|
-
[data-bs-theme="dark"] .sql-code-block {
|
540
|
-
background-color: var(--bs-tertiary-bg);
|
541
|
-
}
|
542
|
-
|
543
|
-
/* Request group header styling */
|
544
|
-
.request-group-header {
|
545
|
-
border-top: 2px solid var(--bs-border-color);
|
546
|
-
}
|
547
|
-
|
548
|
-
.request-header-bg {
|
549
|
-
background-color: var(--bs-secondary-bg);
|
550
|
-
}
|
551
|
-
|
552
|
-
.request-group-header:first-child {
|
553
|
-
border-top: none;
|
554
|
-
}
|
555
|
-
|
556
|
-
/* Collapsed section styling */
|
557
|
-
details summary {
|
558
|
-
cursor: pointer;
|
559
|
-
}
|
560
|
-
|
561
|
-
.cursor-pointer {
|
562
|
-
cursor: pointer;
|
563
|
-
}
|
564
|
-
|
565
|
-
/* Rotate icon when expanded */
|
566
|
-
.collapsed-section[aria-expanded="true"] .bi-chevron-down {
|
567
|
-
transform: rotate(180deg);
|
568
|
-
transition: transform 0.3s ease;
|
569
|
-
}
|
570
|
-
|
571
|
-
.collapsed-section[aria-expanded="false"] .bi-chevron-down {
|
572
|
-
transform: rotate(0deg);
|
573
|
-
transition: transform 0.3s ease;
|
574
|
-
}
|
575
|
-
|
576
|
-
/* Code styling */
|
577
|
-
.pattern-code, .query-binds {
|
578
|
-
background-color: var(--bs-secondary-bg);
|
579
|
-
border: 1px solid var(--bs-border-color);
|
580
|
-
}
|
581
|
-
|
582
|
-
/* Empty data message */
|
583
|
-
.empty-data-message {
|
584
|
-
color: var(--bs-secondary-color);
|
585
|
-
}
|
586
|
-
</style>
|
587
|
-
|
588
|
-
<script>
|
589
|
-
document.addEventListener('DOMContentLoaded', function() {
|
590
|
-
// Add Bootstrap collapse event handlers to animate icons
|
591
|
-
const n1CollapseTrigger = document.querySelector('[data-bs-target="#n1QueriesCollapse"]');
|
592
|
-
const slowestCollapseTrigger = document.querySelector('[data-bs-target="#slowestQueriesCollapse"]');
|
593
|
-
|
594
|
-
if (n1CollapseTrigger) {
|
595
|
-
n1CollapseTrigger.classList.add('collapsed-section');
|
596
|
-
n1CollapseTrigger.addEventListener('click', function() {
|
597
|
-
const isExpanded = this.getAttribute('aria-expanded') === 'true';
|
598
|
-
this.setAttribute('aria-expanded', !isExpanded);
|
599
|
-
});
|
600
|
-
}
|
601
|
-
|
602
|
-
if (slowestCollapseTrigger) {
|
603
|
-
slowestCollapseTrigger.classList.add('collapsed-section');
|
604
|
-
slowestCollapseTrigger.addEventListener('click', function() {
|
605
|
-
const isExpanded = this.getAttribute('aria-expanded') === 'true';
|
606
|
-
this.setAttribute('aria-expanded', !isExpanded);
|
607
|
-
});
|
608
|
-
}
|
609
|
-
});
|
610
|
-
</script>
|
@@ -49,68 +49,3 @@
|
|
49
49
|
</div>
|
50
50
|
</div>
|
51
51
|
</div>
|
52
|
-
|
53
|
-
<script>
|
54
|
-
document.addEventListener('DOMContentLoaded', function() {
|
55
|
-
// Table search functionality
|
56
|
-
const searchInput = document.getElementById('tableSearch');
|
57
|
-
if (searchInput) {
|
58
|
-
searchInput.addEventListener('keyup', function() {
|
59
|
-
const filter = this.value.toLowerCase();
|
60
|
-
const tableRows = document.querySelectorAll('tbody tr');
|
61
|
-
|
62
|
-
tableRows.forEach(function(row) {
|
63
|
-
const tableName = row.querySelector('td:first-child').textContent.toLowerCase();
|
64
|
-
if (tableName.includes(filter)) {
|
65
|
-
row.style.display = '';
|
66
|
-
} else {
|
67
|
-
row.style.display = 'none';
|
68
|
-
}
|
69
|
-
});
|
70
|
-
});
|
71
|
-
}
|
72
|
-
|
73
|
-
// Update table styling when theme changes
|
74
|
-
function updateTableStyling() {
|
75
|
-
const isDarkMode = document.documentElement.getAttribute('data-bs-theme') === 'dark';
|
76
|
-
const tables = document.querySelectorAll('.table');
|
77
|
-
|
78
|
-
tables.forEach(table => {
|
79
|
-
if (isDarkMode) {
|
80
|
-
table.classList.add('table-dark');
|
81
|
-
} else {
|
82
|
-
table.classList.remove('table-dark');
|
83
|
-
}
|
84
|
-
});
|
85
|
-
}
|
86
|
-
|
87
|
-
// Initial styling
|
88
|
-
updateTableStyling();
|
89
|
-
|
90
|
-
// Listen for theme changes
|
91
|
-
document.addEventListener('dbviewerThemeChanged', function(event) {
|
92
|
-
updateTableStyling();
|
93
|
-
});
|
94
|
-
});
|
95
|
-
</script>
|
96
|
-
|
97
|
-
<style>
|
98
|
-
/* Dark mode table styles */
|
99
|
-
[data-bs-theme="dark"] .table {
|
100
|
-
--bs-table-striped-bg: rgba(255, 255, 255, 0.05);
|
101
|
-
--bs-table-hover-bg: rgba(255, 255, 255, 0.075);
|
102
|
-
}
|
103
|
-
|
104
|
-
/* Fix badge styling for dark mode */
|
105
|
-
[data-bs-theme="dark"] .bg-secondary-subtle {
|
106
|
-
background-color: rgba(255, 255, 255, 0.15) !important;
|
107
|
-
color: #e9ecef !important;
|
108
|
-
}
|
109
|
-
|
110
|
-
[data-bs-theme="light"] .bg-secondary-subtle {
|
111
|
-
background-color: #e9ecef !important;
|
112
|
-
color: #212529 !important;
|
113
|
-
}
|
114
|
-
</style>
|
115
|
-
|
116
|
-
|