mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-21 05:53:46 +08:00
- 修复手动隐藏结果区后快捷键无法再次显示的问题 - 补全 Dameng/Oracle-like 字段长度、精度和可空标识 - 增加 SQL 编辑器、字段元数据和对象设计回归测试
177 lines
5.7 KiB
TypeScript
177 lines
5.7 KiB
TypeScript
import type { ColumnDefinition } from '../types';
|
|
|
|
const readStringProperty = (value: unknown, keys: string[]): string => {
|
|
const source = value as Record<string, unknown> | null | undefined;
|
|
if (!source || typeof source !== 'object') return '';
|
|
|
|
for (const key of keys) {
|
|
const raw = source[key];
|
|
if (raw !== undefined && raw !== null) {
|
|
return String(raw).trim();
|
|
}
|
|
}
|
|
|
|
for (const [sourceKey, raw] of Object.entries(source)) {
|
|
if (keys.some((key) => sourceKey.toLowerCase() === key.toLowerCase())) {
|
|
return raw === undefined || raw === null ? '' : String(raw).trim();
|
|
}
|
|
}
|
|
|
|
return '';
|
|
};
|
|
|
|
const readProperty = (value: unknown, keys: string[]): unknown => {
|
|
const source = value as Record<string, unknown> | null | undefined;
|
|
if (!source || typeof source !== 'object') return undefined;
|
|
|
|
for (const key of keys) {
|
|
if (source[key] !== undefined && source[key] !== null) {
|
|
return source[key];
|
|
}
|
|
}
|
|
|
|
for (const [sourceKey, raw] of Object.entries(source)) {
|
|
if (keys.some((key) => sourceKey.toLowerCase() === key.toLowerCase())) {
|
|
return raw;
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
};
|
|
|
|
const readBooleanProperty = (value: unknown, keys: string[]): boolean => {
|
|
const raw = readProperty(value, keys);
|
|
if (raw === undefined || raw === null) return false;
|
|
if (typeof raw === 'boolean') return raw;
|
|
if (typeof raw === 'number') return raw !== 0;
|
|
const text = String(raw).trim().toLowerCase();
|
|
return text === '1' || text === 't' || text === 'true' || text === 'y' || text === 'yes' || text === 'pri' || text === 'primary';
|
|
};
|
|
|
|
const readNumberProperty = (value: unknown, keys: string[]): number => {
|
|
const raw = readProperty(value, keys);
|
|
if (raw === undefined || raw === null || raw === '') return 0;
|
|
const parsed = Number(raw);
|
|
return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : 0;
|
|
};
|
|
|
|
const normalizeNullable = (value: string): string => {
|
|
const normalized = String(value || '').trim();
|
|
if (!normalized) return '';
|
|
const upper = normalized.toUpperCase();
|
|
if (upper === 'N' || upper === 'NO' || upper === 'FALSE' || upper === '0' || upper === 'NOT NULL') {
|
|
return 'NO';
|
|
}
|
|
if (upper === 'Y' || upper === 'YES' || upper === 'TRUE' || upper === '1' || upper === 'NULL' || upper === 'NULLABLE') {
|
|
return 'YES';
|
|
}
|
|
return normalized;
|
|
};
|
|
|
|
export const getColumnDefinitionName = (column: unknown): string => (
|
|
readStringProperty(column, ['name', 'Name', 'COLUMN_NAME', 'column_name', 'field', 'Field'])
|
|
);
|
|
|
|
export const getColumnDefinitionType = (column: unknown): string => {
|
|
const fullType = readStringProperty(column, [
|
|
'COLUMN_TYPE',
|
|
'column_type',
|
|
'FULL_TYPE',
|
|
'full_type',
|
|
'FULL_DATA_TYPE',
|
|
'full_data_type',
|
|
'TYPE_NAME',
|
|
'type_name',
|
|
'Type',
|
|
'type',
|
|
]);
|
|
if (fullType) return fullType;
|
|
|
|
const dataType = readStringProperty(column, ['DATA_TYPE', 'data_type']);
|
|
if (!dataType || /\(.+\)/.test(dataType)) return dataType;
|
|
|
|
const upperType = dataType.toUpperCase();
|
|
const charLength = readNumberProperty(column, [
|
|
'CHARACTER_MAXIMUM_LENGTH',
|
|
'character_maximum_length',
|
|
'CHARACTER_MAX_LENGTH',
|
|
'character_max_length',
|
|
'CHAR_LENGTH',
|
|
'char_length',
|
|
'DATA_LENGTH',
|
|
'data_length',
|
|
'LENGTH',
|
|
'length',
|
|
]);
|
|
if (charLength > 0 && /(CHAR|VARCHAR|BINARY|VARBINARY|NCHAR|NVARCHAR)/.test(upperType)) {
|
|
return `${dataType}(${charLength})`;
|
|
}
|
|
|
|
const precision = readNumberProperty(column, [
|
|
'NUMERIC_PRECISION',
|
|
'numeric_precision',
|
|
'DATA_PRECISION',
|
|
'data_precision',
|
|
'PRECISION',
|
|
'precision',
|
|
]);
|
|
if (precision > 0 && /(DECIMAL|NUMERIC|NUMBER)/.test(upperType)) {
|
|
const scale = readNumberProperty(column, [
|
|
'NUMERIC_SCALE',
|
|
'numeric_scale',
|
|
'DATA_SCALE',
|
|
'data_scale',
|
|
'SCALE',
|
|
'scale',
|
|
]);
|
|
return scale > 0 ? `${dataType}(${precision},${scale})` : `${dataType}(${precision})`;
|
|
}
|
|
|
|
return dataType;
|
|
};
|
|
|
|
export const getColumnDefinitionKey = (column: unknown): string => {
|
|
const key = readStringProperty(column, ['key', 'Key', 'COLUMN_KEY', 'column_key']);
|
|
if (key) {
|
|
const normalized = key.trim();
|
|
const lowered = normalized.toLowerCase();
|
|
if (lowered === 'pri' || lowered === 'primary' || lowered === 'primary key') return 'PRI';
|
|
if (lowered === 'uni' || lowered === 'unique') return 'UNI';
|
|
if (lowered === 'mul' || lowered === 'multiple') return 'MUL';
|
|
return normalized;
|
|
}
|
|
if (readBooleanProperty(column, ['primaryKey', 'primary_key', 'isPrimary', 'is_primary', 'IS_PRIMARY', 'pk', 'PK'])) {
|
|
return 'PRI';
|
|
}
|
|
if (readBooleanProperty(column, ['unique', 'isUnique', 'is_unique', 'UNIQUE', 'IS_UNIQUE'])) {
|
|
return 'UNI';
|
|
}
|
|
return '';
|
|
};
|
|
|
|
export const getColumnDefinitionExtra = (column: unknown): string => (
|
|
readStringProperty(column, ['extra', 'Extra'])
|
|
);
|
|
|
|
export const getColumnDefinitionComment = (column: unknown): string => (
|
|
readStringProperty(column, ['comment', 'Comment', 'COMMENTS', 'comments', 'COLUMN_COMMENT', 'column_comment'])
|
|
);
|
|
|
|
export const normalizeColumnDefinition = (column: unknown): ColumnDefinition => {
|
|
const source = (column && typeof column === 'object' ? column : {}) as Partial<ColumnDefinition>;
|
|
return {
|
|
...source,
|
|
name: getColumnDefinitionName(column),
|
|
type: getColumnDefinitionType(column),
|
|
nullable: normalizeNullable(readStringProperty(column, ['nullable', 'Nullable', 'NULLABLE', 'is_nullable', 'IS_NULLABLE', 'Null', 'null'])),
|
|
key: getColumnDefinitionKey(column),
|
|
default: source.default,
|
|
extra: getColumnDefinitionExtra(column),
|
|
comment: getColumnDefinitionComment(column),
|
|
};
|
|
};
|
|
|
|
export const normalizeColumnDefinitions = (columns: unknown): ColumnDefinition[] => (
|
|
Array.isArray(columns) ? columns.map(normalizeColumnDefinition) : []
|
|
);
|