feat(mongodb): show and sort collection sizes in objects view
This commit is contained in:
8 files changed
+180
-11
No files matched your search
@@ -290,10 +290,15 @@ const effectiveDatabaseType = computed(() => effectiveDatabaseTypeForConnection(
|
||||
const isGaussdbM = computed(() => effectiveDatabaseType.value === "gaussdb" && props.connection.driver_profile?.toLowerCase() === "gaussdb-m");
|
||||
const isVictoriaMetrics = computed(() => effectiveDatabaseType.value === "victoriametrics");
|
||||
const isMongodb = computed(() => props.connection.db_type === "mongodb");
|
||||
const supportsObjectRowStats = computed(() => !isMongodb.value);
|
||||
const supportsObjectSizeStats = computed(() => !isVictoriaMetrics.value && !isMongodb.value);
|
||||
// Victoria Metrics reports series instead of rows and has no byte size to show;
|
||||
// every other engine (MongoDB collections included, via `collStats`) fills both
|
||||
// the row and size columns.
|
||||
const supportsObjectSizeStats = computed(() => !isVictoriaMetrics.value);
|
||||
// The batch table toolbar (export/copy/truncate/empty/drop selected) is SQL-only:
|
||||
// MongoDB collections are not dropped or truncated through it.
|
||||
const supportsBatchTableActions = computed(() => !isVictoriaMetrics.value && !isMongodb.value);
|
||||
const showTableStatistics = computed(() => objectFilter.value === "all" || objectFilter.value === "tables");
|
||||
const showObjectRowStats = computed(() => supportsObjectRowStats.value && showTableStatistics.value);
|
||||
const showObjectRowStats = computed(() => showTableStatistics.value);
|
||||
const showObjectSizeStats = computed(() => supportsObjectSizeStats.value && showTableStatistics.value);
|
||||
const objectRowsLabel = computed(() => t(isVictoriaMetrics.value ? "objects.series" : "objects.rows"));
|
||||
|
||||
@@ -2940,7 +2945,7 @@ async function loadObjects(options?: { allowCached?: boolean; preserveExistingRo
|
||||
if (!objectBrowserRowsLoadGuard.isCurrent(request)) return;
|
||||
applyObjectBrowserRows(nextRows);
|
||||
const cachedAt = cacheObjectBrowserRows(cacheWriteToken, nextRows);
|
||||
if (props.connection.db_type !== "mongodb") void loadObjectStatistics(request, cacheWriteToken, cachedAt);
|
||||
void loadObjectStatistics(request, cacheWriteToken, cachedAt);
|
||||
} catch (e: any) {
|
||||
if (!objectBrowserRowsLoadGuard.isCurrent(request)) return;
|
||||
// Keep visible rows on a background revalidate failure — surface a lightweight
|
||||
@@ -3503,23 +3508,23 @@ function getObjectBrowserMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
|
||||
<div class="min-w-0 flex-1 truncate text-muted-foreground">
|
||||
{{ t("objects.selectedTables", { count: selectedTableCount }) }}
|
||||
</div>
|
||||
<Button v-if="supportsObjectSizeStats" variant="ghost" size="sm" class="h-7 px-2 text-xs" @click="openBatchDatabaseExport">
|
||||
<Button v-if="supportsBatchTableActions" variant="ghost" size="sm" class="h-7 px-2 text-xs" @click="openBatchDatabaseExport">
|
||||
<Upload class="mr-1.5 h-3.5 w-3.5" />
|
||||
{{ t("objects.exportSelected") }}
|
||||
</Button>
|
||||
<Button v-if="supportsObjectSizeStats" variant="ghost" size="sm" class="h-7 px-2 text-xs" @click="copySelectedTablesToClipboard">
|
||||
<Button v-if="supportsBatchTableActions" variant="ghost" size="sm" class="h-7 px-2 text-xs" @click="copySelectedTablesToClipboard">
|
||||
<Clipboard class="mr-1.5 h-3.5 w-3.5" />
|
||||
{{ t("objects.copyTableSelected") }}
|
||||
</Button>
|
||||
<Button v-if="supportsObjectSizeStats && supportsTruncateTable" variant="ghost" size="sm" class="h-7 px-2 text-xs text-destructive" @click="requestBatchTruncateTables">
|
||||
<Button v-if="supportsBatchTableActions && supportsTruncateTable" variant="ghost" size="sm" class="h-7 px-2 text-xs text-destructive" @click="requestBatchTruncateTables">
|
||||
<Scissors class="mr-1.5 h-3.5 w-3.5" />
|
||||
{{ t("objects.truncateSelected") }}
|
||||
</Button>
|
||||
<Button v-if="supportsObjectSizeStats" variant="ghost" size="sm" class="h-7 px-2 text-xs text-destructive" @click="requestBatchEmptyTables">
|
||||
<Button v-if="supportsBatchTableActions" variant="ghost" size="sm" class="h-7 px-2 text-xs text-destructive" @click="requestBatchEmptyTables">
|
||||
<Eraser class="mr-1.5 h-3.5 w-3.5" />
|
||||
{{ t("contextMenu.batchEmpty", { count: selectedTableCount }) }}
|
||||
</Button>
|
||||
<Button v-if="supportsObjectSizeStats" variant="ghost" size="sm" class="h-7 px-2 text-xs text-destructive" @click="requestBatchDropTables">
|
||||
<Button v-if="supportsBatchTableActions" variant="ghost" size="sm" class="h-7 px-2 text-xs text-destructive" @click="requestBatchDropTables">
|
||||
<Trash2 class="mr-1.5 h-3.5 w-3.5" />
|
||||
{{ t("objects.dropSelected") }}
|
||||
</Button>
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const objectBrowserSource = readFileSync(new URL("../ObjectBrowser.vue", import.meta.url), "utf8");
|
||||
|
||||
describe("ObjectBrowser MongoDB collection statistics (#9705)", () => {
|
||||
it("requests table statistics for every engine, MongoDB included", () => {
|
||||
// The loader used to skip MongoDB wholesale, so the columns below stayed
|
||||
// empty even though the backend can now answer `collStats` per collection.
|
||||
expect(objectBrowserSource).not.toContain('if (props.connection.db_type !== "mongodb") void loadObjectStatistics');
|
||||
expect(objectBrowserSource).toContain("void loadObjectStatistics(request, cacheWriteToken, cachedAt);");
|
||||
});
|
||||
|
||||
it("renders the row/size columns and their sort keys for MongoDB", () => {
|
||||
expect(objectBrowserSource).toContain("const showObjectRowStats = computed(() => showTableStatistics.value);");
|
||||
expect(objectBrowserSource).toContain("const supportsObjectSizeStats = computed(() => !isVictoriaMetrics.value);");
|
||||
});
|
||||
|
||||
it("keeps the batch table toolbar SQL-only", () => {
|
||||
expect(objectBrowserSource).toContain("const supportsBatchTableActions = computed(() => !isVictoriaMetrics.value && !isMongodb.value);");
|
||||
for (const handler of ["openBatchDatabaseExport", "copySelectedTablesToClipboard", "requestBatchTruncateTables", "requestBatchEmptyTables", "requestBatchDropTables"]) {
|
||||
const button = new RegExp(`v-if="supportsBatchTableActions[^"]*"[^>]*@click="${handler}"`);
|
||||
expect(objectBrowserSource).toMatch(button);
|
||||
}
|
||||
// No toolbar action may key off the stats-column flag any more.
|
||||
expect(objectBrowserSource).not.toContain('v-if="supportsObjectSizeStats');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user