mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-17 02:42:06 +08:00
23
frontend/src/components/SidebarDamengTableCount.test.ts
Normal file
23
frontend/src/components/SidebarDamengTableCount.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { buildSidebarTableStatusSQL } from './sidebar/sidebarMetadataLoaders';
|
||||
|
||||
const loaderSource = readFileSync(new URL('./sidebar/useSidebarTreeLoaders.tsx', import.meta.url), 'utf8');
|
||||
|
||||
describe('Sidebar Dameng table count regression', () => {
|
||||
it('keeps oracle-like table metadata schema-aware for schema-grouped sidebars', () => {
|
||||
const damengSql = buildSidebarTableStatusSQL({ config: { type: 'dameng' } } as any, 'APP');
|
||||
const oracleSql = buildSidebarTableStatusSQL({ config: { type: 'oracle' } } as any, 'APP');
|
||||
|
||||
expect(damengSql).toContain('owner AS schema_name');
|
||||
expect(damengSql).toContain('comments AS table_comment');
|
||||
expect(oracleSql).toContain('owner AS schema_name');
|
||||
|
||||
expect(loaderSource).toContain('const tableSchemaMap = new Map<string, string>();');
|
||||
expect(loaderSource).toContain("getCaseInsensitiveValue(row, ['schema_name', 'SCHEMA_NAME', 'owner', 'OWNER'])");
|
||||
expect(loaderSource).toContain('const normalizedSchemaRows = schemaRows');
|
||||
expect(loaderSource).toContain('normalizedSchemaRows.length !== 1');
|
||||
expect(loaderSource).toContain('schemaName: mappedSchemaName');
|
||||
});
|
||||
});
|
||||
@@ -308,7 +308,7 @@ const buildSidebarTableStatusSQL = (
|
||||
case "dm": {
|
||||
const owner = escapeSQLLiteral(dbName).toUpperCase();
|
||||
return [
|
||||
"SELECT table_name, comments AS table_comment, num_rows AS table_rows",
|
||||
"SELECT owner AS schema_name, table_name, comments AS table_comment, num_rows AS table_rows",
|
||||
"FROM all_tab_comments JOIN all_tables USING (table_name, owner)",
|
||||
`WHERE owner = '${owner}'`,
|
||||
"ORDER BY table_name",
|
||||
|
||||
@@ -487,14 +487,25 @@ export const useSidebarTreeLoaders = ({
|
||||
: { success: false, data: [] as any[] };
|
||||
const tableRowCountMap = new Map<string, number>();
|
||||
const tableCommentMap = new Map<string, string>();
|
||||
const putTableComment = (rawTableName: string, rawComment: string) => {
|
||||
const tableSchemaMap = new Map<string, string>();
|
||||
const buildTableMetadataKeys = (rawTableName: string, rawSchemaName = ''): string[] => {
|
||||
const tableName = String(rawTableName || '').trim();
|
||||
const comment = String(rawComment || '').trim();
|
||||
if (!tableName || !comment) return;
|
||||
const keys = new Set<string>([tableName.toLowerCase()]);
|
||||
if (!tableName) return [];
|
||||
const parsed = splitQualifiedName(tableName);
|
||||
if (parsed.objectName) keys.add(parsed.objectName.toLowerCase());
|
||||
keys.forEach((metadataKey) => tableCommentMap.set(metadataKey, comment));
|
||||
const schemaName = String(rawSchemaName || parsed.schemaName || '').trim();
|
||||
const objectName = String(parsed.objectName || tableName).trim();
|
||||
const keys = new Set<string>([tableName.toLowerCase()]);
|
||||
if (objectName) keys.add(objectName.toLowerCase());
|
||||
const qualifiedName = buildQualifiedName(schemaName, objectName || tableName);
|
||||
if (qualifiedName) keys.add(qualifiedName.toLowerCase());
|
||||
return Array.from(keys);
|
||||
};
|
||||
const putTableComment = (rawTableName: string, rawComment: string, rawSchemaName = '') => {
|
||||
const comment = String(rawComment || '').trim();
|
||||
if (!comment) return;
|
||||
buildTableMetadataKeys(rawTableName, rawSchemaName).forEach((metadataKey) => {
|
||||
tableCommentMap.set(metadataKey, comment);
|
||||
});
|
||||
};
|
||||
if (tableStatsResult?.success && Array.isArray(tableStatsResult.data)) {
|
||||
tableStatsResult.data.forEach((row: Record<string, any>) => {
|
||||
@@ -504,6 +515,12 @@ export const useSidebarTreeLoaders = ({
|
||||
|| ''
|
||||
).trim();
|
||||
if (!rawTableName) return;
|
||||
const rawSchemaName = getCaseInsensitiveValue(row, ['schema_name', 'SCHEMA_NAME', 'owner', 'OWNER']);
|
||||
buildTableMetadataKeys(rawTableName, rawSchemaName).forEach((metadataKey) => {
|
||||
if (rawSchemaName) {
|
||||
tableSchemaMap.set(metadataKey, rawSchemaName);
|
||||
}
|
||||
});
|
||||
putTableComment(rawTableName, getCaseInsensitiveValue(row, [
|
||||
'table_comment',
|
||||
'TABLE_COMMENT',
|
||||
@@ -512,15 +529,22 @@ export const useSidebarTreeLoaders = ({
|
||||
'comments',
|
||||
'COMMENTS',
|
||||
'MS_Description',
|
||||
]));
|
||||
]), rawSchemaName);
|
||||
const rowCount = parseMetadataRowCount(row);
|
||||
if (rowCount === undefined) return;
|
||||
tableRowCountMap.set(rawTableName.toLowerCase(), rowCount);
|
||||
buildTableMetadataKeys(rawTableName, rawSchemaName).forEach((metadataKey) => {
|
||||
tableRowCountMap.set(metadataKey, rowCount);
|
||||
});
|
||||
});
|
||||
}
|
||||
const tableEntries = tableRows.map((row: any) => {
|
||||
const tableName = Object.values(row)[0] as string;
|
||||
const parsed = splitQualifiedName(tableName);
|
||||
const metadataKeys = buildTableMetadataKeys(tableName);
|
||||
const rowSchemaName = getCaseInsensitiveValue(row, ['schema_name', 'SCHEMA_NAME', 'owner', 'OWNER']);
|
||||
const mappedSchemaName = rowSchemaName
|
||||
|| metadataKeys.map((metadataKey) => tableSchemaMap.get(metadataKey)).find((value): value is string => !!value)
|
||||
|| parsed.schemaName;
|
||||
const rowComment = getCaseInsensitiveValue(row, [
|
||||
'table_comment',
|
||||
'TABLE_COMMENT',
|
||||
@@ -531,12 +555,15 @@ export const useSidebarTreeLoaders = ({
|
||||
]);
|
||||
return {
|
||||
tableName,
|
||||
schemaName: parsed.schemaName,
|
||||
schemaName: mappedSchemaName,
|
||||
displayName: getSidebarTableDisplayName(conn, tableName),
|
||||
rowCount: tableRowCountMap.get(String(tableName || '').trim().toLowerCase()),
|
||||
rowCount: metadataKeys
|
||||
.map((metadataKey) => tableRowCountMap.get(metadataKey))
|
||||
.find((value) => value !== undefined),
|
||||
tableComment: rowComment
|
||||
|| tableCommentMap.get(String(tableName || '').trim().toLowerCase())
|
||||
|| tableCommentMap.get(String(parsed.objectName || '').trim().toLowerCase())
|
||||
|| metadataKeys
|
||||
.map((metadataKey) => tableCommentMap.get(metadataKey))
|
||||
.find((value) => !!value)
|
||||
|| '',
|
||||
};
|
||||
});
|
||||
@@ -559,6 +586,18 @@ export const useSidebarTreeLoaders = ({
|
||||
const packageRows: any[] = Array.isArray(packagesResult.packages) ? packagesResult.packages : [];
|
||||
const eventRows: any[] = Array.isArray(eventsResult.events) ? eventsResult.events : [];
|
||||
const schemaRows: string[] = Array.isArray(schemasResult.schemas) ? schemasResult.schemas : [];
|
||||
const normalizedSchemaRows = schemaRows
|
||||
.map((schemaName) => String(schemaName || '').trim())
|
||||
.filter((schemaName) => schemaName !== '');
|
||||
const normalizedTableEntries = tableEntries.map((entry) => {
|
||||
if (entry.schemaName || normalizedSchemaRows.length !== 1) {
|
||||
return entry;
|
||||
}
|
||||
return {
|
||||
...entry,
|
||||
schemaName: normalizedSchemaRows[0],
|
||||
};
|
||||
});
|
||||
|
||||
const viewEntries = viewRows.map((entry: SidebarViewMetadataEntry) => {
|
||||
const parsed = splitQualifiedName(entry.viewName);
|
||||
@@ -666,7 +705,7 @@ export const useSidebarTreeLoaders = ({
|
||||
const sortPreferenceKey = `${conn.id}-${conn.dbName}`;
|
||||
const sortBy = currentTableSortPreference[sortPreferenceKey] || 'name';
|
||||
|
||||
const sortedTableEntries = sortSidebarTableEntries(tableEntries, {
|
||||
const sortedTableEntries = sortSidebarTableEntries(normalizedTableEntries, {
|
||||
connectionId: conn.id,
|
||||
dbName: conn.dbName,
|
||||
sortBy,
|
||||
|
||||
Reference in New Issue
Block a user