dbviewer 0.5.7 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3385fea543f18e7af2bd9a924b5095f76235612d569fc1e1a828222b8b1a3b53
4
- data.tar.gz: 762f1ee1b3774c9186cbdac735beb0717c6a3feb64ffecd7833ec8732ce91898
3
+ metadata.gz: d46526c59b9c355c9e717e76ebe81299bbdb051be58fb1b789fbe2fa1c50c0e4
4
+ data.tar.gz: 713277fda9b00b0fe4a48b2e8324632f2c7920b25cbaad369afe2d159c2bcf29
5
5
  SHA512:
6
- metadata.gz: a1552e63407dd92eb3bfa821a4712f6cb57b5c68462c6028a9e3debe14f2e72ce073c631ec1616aa50a5158939ae667899ef4999c2ac5feff8a6f22edd783b08
7
- data.tar.gz: 2852a40ddec1a2a86d2b9764bf527fd21dd140aa57a7ef36da6d7dcf312362c6b24b753c6badd04aee89328557136c954adbad95a442540a233f53affac5489c
6
+ metadata.gz: 77444f6cf1b7d847d114bdef9f965d9c90e4e216666db1fccb7de5652f92950cae7793bab07da982e473517f4c350d0dc186e094291138258c9a589de983bf5c
7
+ data.tar.gz: fc6801c693d632bf8a4bfe26d0aa4b0614ba8570867cf14575f279813c2b8599e5f3288f1bc0175d2db108d62ec2362d484c47a2e0059d5eb28c1a4d4a091d52
@@ -16,6 +16,61 @@ module Dbviewer
16
16
  render_success(total_relationships: total_relationships)
17
17
  end
18
18
 
19
+ def relationship_counts
20
+ table_name = params[:id]
21
+ record_id = params[:record_id]
22
+
23
+ unless table_name.present? && record_id.present?
24
+ render_error("Table name and record ID are required", 400)
25
+ return
26
+ end
27
+
28
+ begin
29
+ # Get table metadata to find relationships
30
+ metadata = fetch_table_metadata(table_name)
31
+
32
+ unless metadata
33
+ render_error("Table not found", 404)
34
+ return
35
+ end
36
+
37
+ # Get reverse foreign keys (has_many relationships)
38
+ reverse_foreign_keys = metadata.dig(:reverse_foreign_keys) || []
39
+
40
+ relationship_counts = reverse_foreign_keys.map do |rel|
41
+ begin
42
+ # Count records in the related table that reference this record
43
+ count_query = "SELECT COUNT(*) as count FROM #{rel[:from_table]} WHERE #{rel[:column]} = ?"
44
+ result = database_manager.connection.exec_query(count_query, "Count Query", [ record_id ])
45
+ count = result.rows.first&.first || 0
46
+
47
+ {
48
+ table: rel[:from_table],
49
+ foreign_key: rel[:column],
50
+ count: count.to_i
51
+ }
52
+ rescue => e
53
+ Rails.logger.error "Error counting relationships for #{rel[:from_table]}: #{e.message}"
54
+ {
55
+ table: rel[:from_table],
56
+ foreign_key: rel[:column],
57
+ count: 0,
58
+ error: e.message
59
+ }
60
+ end
61
+ end
62
+
63
+ render_success({
64
+ table_name: table_name,
65
+ record_id: record_id,
66
+ relationships: relationship_counts
67
+ })
68
+ rescue => e
69
+ Rails.logger.error "Error fetching relationship counts: #{e.message}"
70
+ render_error("Error fetching relationship counts: #{e.message}", 500)
71
+ end
72
+ end
73
+
19
74
  private
20
75
 
21
76
  def fetch_tables_count
@@ -777,7 +777,11 @@
777
777
  const primaryKeyValue = recordData[Object.keys(recordData).find(key => key === 'id') || Object.keys(recordData)[0]];
778
778
 
779
779
  if (primaryKeyValue !== null && primaryKeyValue !== undefined && primaryKeyValue !== '') {
780
- relationshipsContent.appendChild(createRelationshipSection('Has Many', reverseForeignKeys, recordData, 'has_many', primaryKeyValue));
780
+ const hasManySection = createRelationshipSection('Has Many', reverseForeignKeys, recordData, 'has_many', primaryKeyValue);
781
+ relationshipsContent.appendChild(hasManySection);
782
+
783
+ // Fetch relationship counts asynchronously
784
+ fetchRelationshipCounts('<%= @table_name %>', primaryKeyValue, reverseForeignKeys, hasManySection);
781
785
  }
782
786
  }
783
787
 
@@ -1433,6 +1437,55 @@
1433
1437
  });
1434
1438
 
1435
1439
  // Helper function to create relationship sections
1440
+ // Function to fetch relationship counts from API
1441
+ async function fetchRelationshipCounts(tableName, recordId, relationships, hasManySection) {
1442
+ try {
1443
+ const response = await fetch(`/dbviewer/api/tables/${tableName}/relationship_counts?record_id=${recordId}`);
1444
+ if (!response.ok) {
1445
+ throw new Error(`HTTP error! status: ${response.status}`);
1446
+ }
1447
+
1448
+ const data = await response.json();
1449
+
1450
+ // Update each count in the UI
1451
+ const countSpans = hasManySection.querySelectorAll('.relationship-count');
1452
+
1453
+ relationships.forEach((relationship, index) => {
1454
+ const countSpan = countSpans[index];
1455
+ if (countSpan) {
1456
+ const relationshipData = data.relationships.find(r =>
1457
+ r.table === relationship.from_table && r.foreign_key === relationship.column
1458
+ );
1459
+
1460
+ if (relationshipData) {
1461
+ const count = relationshipData.count;
1462
+ let badgeClass = 'bg-secondary';
1463
+ let badgeText = `${count} record${count !== 1 ? 's' : ''}`;
1464
+
1465
+ // Use different colors based on count
1466
+ if (count > 0) {
1467
+ badgeClass = count > 10 ? 'bg-warning' : 'bg-success';
1468
+ }
1469
+
1470
+ countSpan.innerHTML = `<span class="badge ${badgeClass}">${badgeText}</span>`;
1471
+ } else {
1472
+ // Fallback if no data found
1473
+ countSpan.innerHTML = '<span class="badge bg-danger">Error</span>';
1474
+ }
1475
+ }
1476
+ });
1477
+
1478
+ } catch (error) {
1479
+ console.error('Error fetching relationship counts:', error);
1480
+
1481
+ // Show error state in UI
1482
+ const countSpans = hasManySection.querySelectorAll('.relationship-count');
1483
+ countSpans.forEach(span => {
1484
+ span.innerHTML = '<span class="badge bg-danger">Error</span>';
1485
+ });
1486
+ }
1487
+ }
1488
+
1436
1489
  function createRelationshipSection(title, relationships, recordData, type, primaryKeyValue = null) {
1437
1490
  const section = document.createElement('div');
1438
1491
  section.className = 'relationship-section mb-4';
@@ -1503,7 +1556,12 @@
1503
1556
  <span class="text-muted">${fk.from_table}.</span><strong>${fk.column}</strong>
1504
1557
  </td>
1505
1558
  <td>
1506
- <span class="badge bg-secondary">View All</span>
1559
+ <span class="relationship-count">
1560
+ <span class="badge bg-secondary">
1561
+ <span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>
1562
+ Loading...
1563
+ </span>
1564
+ </span>
1507
1565
  </td>
1508
1566
  <td>
1509
1567
  <a href="/dbviewer/tables/${fk.from_table}?column_filters[${fk.column}]=${encodeURIComponent(primaryKeyValue)}"
@@ -2108,12 +2166,6 @@
2108
2166
  background: transparent !important;
2109
2167
  }
2110
2168
 
2111
- [data-bs-theme="dark"] .flatpickr-day.disabled:hover {
2112
- background: transparent !important;
2113
- color: #6c757d !important;
2114
- cursor: not-allowed;
2115
- }
2116
-
2117
2169
  /* Dark mode other day states */
2118
2170
  [data-bs-theme="dark"] .flatpickr-day.nextMonthDay,
2119
2171
  [data-bs-theme="dark"] .flatpickr-day.prevMonthDay {
@@ -2263,6 +2315,19 @@
2263
2315
  .flatpickr-next-month:hover {
2264
2316
  background: rgba(var(--bs-primary-rgb), 0.1);
2265
2317
  }
2318
+
2319
+ /* Relationship count styling */
2320
+ .relationship-count .badge {
2321
+ min-width: 80px;
2322
+ display: inline-flex;
2323
+ align-items: center;
2324
+ justify-content: center;
2325
+ }
2326
+
2327
+ .relationship-count .spinner-border-sm {
2328
+ width: 0.875rem;
2329
+ height: 0.875rem;
2330
+ }
2266
2331
  </style>
2267
2332
 
2268
2333
  <script>
data/config/routes.rb CHANGED
@@ -25,6 +25,9 @@ Dbviewer::Engine.routes.draw do
25
25
  get "records"
26
26
  get "relationships_count"
27
27
  end
28
+ member do
29
+ get "relationship_counts"
30
+ end
28
31
  end
29
32
 
30
33
  resources :entity_relationship_diagrams, only: [] do
@@ -1,3 +1,3 @@
1
1
  module Dbviewer
2
- VERSION = "0.5.7"
2
+ VERSION = "0.5.8"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbviewer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.7
4
+ version: 0.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wailan Tirajoh