mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-06 20:03:05 +08:00
Merge pull request #385 from Jonclex/dev
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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 = `
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user