Merge pull request #385 from Jonclex/dev

This commit is contained in:
Syngnat
2026-04-15 15:17:46 +08:00
6 changed files with 70 additions and 16 deletions

View File

@@ -31,7 +31,7 @@ import { v4 as generateUuid } from 'uuid';
import 'react-resizable/css/styles.css';
import { buildOrderBySQL, buildPaginatedSelectSQL, buildWhereSQL, escapeLiteral, hasExplicitSort, quoteIdentPart, quoteQualifiedIdent, withSortBufferTuningSQL, type FilterCondition } from '../utils/sql';
import { isMacLikePlatform, normalizeOpacityForPlatform, resolveAppearanceValues } from '../utils/appearance';
import { getDataSourceCapabilities } from '../utils/dataSourceCapabilities';
import { getDataSourceCapabilities, resolveDataSourceType } from '../utils/dataSourceCapabilities';
import { buildRpcConnectionConfig } from '../utils/connectionRpcConfig';
import {
resolveDataTableColumnWidth,
@@ -4002,7 +4002,7 @@ const DataGrid: React.FC<DataGridProps> = ({
return;
}
const dbType = config.type || '';
const dbType = resolveDataSourceType(config);
const pkWhere = buildPkWhereSql(records, dbType);
if (!pkWhere) {
await exportData(records, format);
@@ -4071,7 +4071,7 @@ const DataGrid: React.FC<DataGridProps> = ({
return;
}
const sql = buildCurrentPageSql(config.type || '');
const sql = buildCurrentPageSql(resolveDataSourceType(config));
if (!sql) {
await exportData(displayData, format);
return;

View File

@@ -7,7 +7,7 @@ import DataGrid, { GONAVI_ROW_KEY } from './DataGrid';
import { buildOrderBySQL, buildPaginatedSelectSQL, buildWhereSQL, hasExplicitSort, quoteIdentPart, quoteQualifiedIdent, withSortBufferTuningSQL, type FilterCondition } from '../utils/sql';
import { buildMongoCountCommand, buildMongoFilter, buildMongoFindCommand, buildMongoSort } from '../utils/mongodb';
import { buildOracleApproximateTotalSql, parseApproximateTableCountRow, resolveApproximateTableCountStrategy } from '../utils/approximateTableCount';
import { getDataSourceCapabilities } from '../utils/dataSourceCapabilities';
import { getDataSourceCapabilities, resolveDataSourceType } from '../utils/dataSourceCapabilities';
import { resolveDataViewerAutoFetchAction } from '../utils/dataViewerAutoFetch';
import { buildRpcConnectionConfig } from '../utils/connectionRpcConfig';
@@ -396,7 +396,7 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAct
ssh: conn.config.ssh || { host: "", port: 22, user: "", password: "", keyPath: "" }
};
const dbType = config.type || '';
const dbType = resolveDataSourceType(config);
const dbTypeLower = String(dbType || '').trim().toLowerCase();
const isMySQLFamily = dbTypeLower === 'mysql' || dbTypeLower === 'mariadb' || dbTypeLower === 'diros';
@@ -855,7 +855,7 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAct
const exportSqlWithFilter = useMemo(() => {
const tableName = String(tab.tableName || '').trim();
const dbType = String(currentConnConfig?.type || '').trim();
const dbType = resolveDataSourceType(currentConnConfig);
if (!tableName || !dbType) return '';
const whereSQL = buildWhereSQL(dbType, filterConditions);
@@ -869,7 +869,7 @@ const DataViewer: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAct
sql = withSortBufferTuningSQL(normalizedType, sql, 32 * 1024 * 1024);
}
return sql;
}, [tab.tableName, currentConnConfig?.type, filterConditions, sortInfo, pkColumns]);
}, [tab.tableName, currentConnConfig?.type, currentConnConfig?.driver, filterConditions, sortInfo, pkColumns]);
useEffect(() => {
const action = resolveDataViewerAutoFetchAction({

View File

@@ -55,10 +55,23 @@ const getMetadataDialect = (connType: string, driver?: string): string => {
};
const buildTableStatusSQL = (dialect: string, dbName: string, schemaName?: string): string => {
const escapeLiteral = (s: string) => s.replace(/'/g, "''");
switch (dialect) {
const escapeLiteral = (s: string) => s.replace(/'/g, "''");
switch (dialect) {
case 'mysql':
return `SHOW TABLE STATUS FROM \`${dbName.replace(/`/g, '``')}\``;
return `
SELECT
TABLE_NAME AS table_name,
TABLE_COMMENT AS table_comment,
TABLE_ROWS AS table_rows,
DATA_LENGTH AS data_length,
INDEX_LENGTH AS index_length,
ENGINE AS engine,
CREATE_TIME AS create_time,
UPDATE_TIME AS update_time
FROM information_schema.tables
WHERE table_schema = '${escapeLiteral(dbName)}'
AND table_type = 'BASE TABLE'
ORDER BY table_name`;
case 'postgres':
case 'kingbase':
case 'vastbase':

View File

@@ -114,6 +114,38 @@ func (c *CustomDB) GetDatabases() ([]string, error) {
// We'll try a generic query or return empty.
// Users using custom might know their DB context is single.
if c.driver == "mysql" {
data, _, err := c.Query("SHOW DATABASES")
if err == nil {
var dbs []string
for _, row := range data {
for _, v := range row {
name := strings.TrimSpace(fmt.Sprintf("%v", v))
if name != "" {
dbs = append(dbs, name)
}
break
}
}
if len(dbs) > 0 {
return dbs, nil
}
}
// Fallback for restricted accounts: at least expose current database.
data, _, fallbackErr := c.Query("SELECT DATABASE() AS database_name")
if fallbackErr == nil {
for _, row := range data {
for _, v := range row {
name := strings.TrimSpace(fmt.Sprintf("%v", v))
if name != "" && !strings.EqualFold(name, "<nil>") && !strings.EqualFold(name, "null") {
return []string{name}, nil
}
}
}
}
}
// Best effort:
return []string{}, nil
}
@@ -123,9 +155,12 @@ func (c *CustomDB) GetTables(dbName string) ([]string, error) {
query := "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"
// If mysql-like
if c.driver == "mysql" {
query = "SHOW TABLES"
query = "SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = DATABASE() AND TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME"
if dbName != "" {
query = fmt.Sprintf("SHOW TABLES FROM `%s`", dbName)
query = fmt.Sprintf(
"SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = '%s' AND TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME",
strings.ReplaceAll(dbName, "'", "''"),
)
}
} else if c.driver == "postgres" || c.driver == "kingbase" {
query = `

View File

@@ -185,9 +185,12 @@ func (m *MariaDB) GetDatabases() ([]string, error) {
}
func (m *MariaDB) GetTables(dbName string) ([]string, error) {
query := "SHOW TABLES"
query := "SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = DATABASE() AND TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME"
if dbName != "" {
query = fmt.Sprintf("SHOW TABLES FROM `%s`", dbName)
query = fmt.Sprintf(
"SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = '%s' AND TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME",
strings.ReplaceAll(dbName, "'", "''"),
)
}
data, _, err := m.Query(query)

View File

@@ -424,9 +424,12 @@ func (m *MySQLDB) GetDatabases() ([]string, error) {
}
func (m *MySQLDB) GetTables(dbName string) ([]string, error) {
query := "SHOW TABLES"
query := "SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = DATABASE() AND TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME"
if dbName != "" {
query = fmt.Sprintf("SHOW TABLES FROM `%s`", dbName)
query = fmt.Sprintf(
"SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = '%s' AND TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME",
strings.ReplaceAll(dbName, "'", "''"),
)
}
data, _, err := m.Query(query)