Improve SQLite batching and diagnostics visibility
This commit is contained in:
@@ -56,6 +56,21 @@ type AdminDiagnosticsPanelProps = {
|
||||
embedded?: boolean
|
||||
}
|
||||
|
||||
type DatabaseDiagnosticDetail = {
|
||||
integrity_check?: string
|
||||
database_path?: string
|
||||
database_size_bytes?: number
|
||||
wal_size_bytes?: number
|
||||
shm_size_bytes?: number
|
||||
page_size_bytes?: number
|
||||
page_count?: number
|
||||
freelist_pages?: number
|
||||
allocated_bytes?: number
|
||||
free_bytes?: number
|
||||
row_counts?: Record<string, number>
|
||||
timings_ms?: Record<string, number>
|
||||
}
|
||||
|
||||
const REFRESH_INTERVAL_MS = 30000
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
@@ -85,6 +100,54 @@ function statusLabel(status: string) {
|
||||
return STATUS_LABELS[status] ?? status
|
||||
}
|
||||
|
||||
function formatBytes(value?: number) {
|
||||
if (typeof value !== 'number' || Number.isNaN(value) || value < 0) {
|
||||
return '0 B'
|
||||
}
|
||||
if (value >= 1024 * 1024 * 1024) {
|
||||
return `${(value / (1024 * 1024 * 1024)).toFixed(2)} GB`
|
||||
}
|
||||
if (value >= 1024 * 1024) {
|
||||
return `${(value / (1024 * 1024)).toFixed(2)} MB`
|
||||
}
|
||||
if (value >= 1024) {
|
||||
return `${(value / 1024).toFixed(1)} KB`
|
||||
}
|
||||
return `${value} B`
|
||||
}
|
||||
|
||||
function formatDetailLabel(value: string) {
|
||||
return value
|
||||
.replace(/_/g, ' ')
|
||||
.replace(/\b\w/g, (character) => character.toUpperCase())
|
||||
}
|
||||
|
||||
function asDatabaseDiagnosticDetail(detail: unknown): DatabaseDiagnosticDetail | null {
|
||||
if (!detail || typeof detail !== 'object' || Array.isArray(detail)) {
|
||||
return null
|
||||
}
|
||||
return detail as DatabaseDiagnosticDetail
|
||||
}
|
||||
|
||||
function renderDatabaseMetricGroup(title: string, values: Array<[string, string]>) {
|
||||
if (values.length === 0) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<div className="diagnostic-detail-group">
|
||||
<h4>{title}</h4>
|
||||
<div className="diagnostic-detail-grid">
|
||||
{values.map(([label, value]) => (
|
||||
<div key={`${title}-${label}`} className="diagnostic-detail-item">
|
||||
<span>{label}</span>
|
||||
<strong>{value}</strong>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function AdminDiagnosticsPanel({ embedded = false }: AdminDiagnosticsPanelProps) {
|
||||
const router = useRouter()
|
||||
const [loading, setLoading] = useState(true)
|
||||
@@ -405,6 +468,43 @@ export default function AdminDiagnosticsPanel({ embedded = false }: AdminDiagnos
|
||||
<span className="system-dot" />
|
||||
<span>{isRunning ? 'Running diagnostic...' : check.message}</span>
|
||||
</div>
|
||||
|
||||
{check.key === 'database'
|
||||
? (() => {
|
||||
const detail = asDatabaseDiagnosticDetail(check.detail)
|
||||
if (!detail) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<div className="diagnostic-detail-panel">
|
||||
{renderDatabaseMetricGroup('Storage', [
|
||||
['Database file', formatBytes(detail.database_size_bytes)],
|
||||
['WAL file', formatBytes(detail.wal_size_bytes)],
|
||||
['Shared memory', formatBytes(detail.shm_size_bytes)],
|
||||
['Allocated bytes', formatBytes(detail.allocated_bytes)],
|
||||
['Free bytes', formatBytes(detail.free_bytes)],
|
||||
['Page size', formatBytes(detail.page_size_bytes)],
|
||||
['Page count', `${detail.page_count?.toLocaleString() ?? 0}`],
|
||||
['Freelist pages', `${detail.freelist_pages?.toLocaleString() ?? 0}`],
|
||||
])}
|
||||
{renderDatabaseMetricGroup(
|
||||
'Tables',
|
||||
Object.entries(detail.row_counts ?? {}).map(([key, value]) => [
|
||||
formatDetailLabel(key),
|
||||
value.toLocaleString(),
|
||||
]),
|
||||
)}
|
||||
{renderDatabaseMetricGroup(
|
||||
'Timings',
|
||||
Object.entries(detail.timings_ms ?? {}).map(([key, value]) => [
|
||||
formatDetailLabel(key),
|
||||
`${value.toFixed(1)} ms`,
|
||||
]),
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})()
|
||||
: null}
|
||||
</article>
|
||||
)
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user