fix: add sorting based on how common the datatype on side-panel (#651)

* fix: add sorting based on how common the datatype on side-panel

* fix type to new version

* remove colors

---------

Co-authored-by: Guy Ben-Aharon <baguy3@gmail.com>
This commit is contained in:
Jonathan Fishner
2025-04-23 11:48:31 +03:00
committed by GitHub
parent 46426e27b4
commit 3a1b8d1db1
9 changed files with 169 additions and 178 deletions

View File

@@ -345,7 +345,6 @@ export const SelectBox = React.forwardRef<HTMLInputElement, SelectBoxProps>(
? [option.regex]
: undefined
}
// value={option.value}
onSelect={() =>
handleSelect(
option.value,

View File

@@ -15,6 +15,7 @@ export interface DataType {
export interface DataTypeData extends DataType {
hasCharMaxLength?: boolean;
usageLevel?: 1 | 2; // Level 1 is most common, Level 2 is second most common
}
export const dataTypeSchema: z.ZodType<DataType> = z.object({
@@ -33,6 +34,45 @@ export const dataTypeMap: Record<DatabaseType, readonly DataTypeData[]> = {
[DatabaseType.COCKROACHDB]: postgresDataTypes,
} as const;
export const sortDataTypes = (dataTypes: DataTypeData[]): DataTypeData[] => {
const types = [...dataTypes];
return types.sort((a, b) => {
// First sort by usage level (lower numbers first)
if ((a.usageLevel || 3) < (b.usageLevel || 3)) return -1;
if ((a.usageLevel || 3) > (b.usageLevel || 3)) return 1;
// Then sort alphabetically by name
return a.name.localeCompare(b.name);
});
};
export const sortedDataTypeMap: Record<DatabaseType, readonly DataTypeData[]> =
{
[DatabaseType.GENERIC]: sortDataTypes([
...dataTypeMap[DatabaseType.GENERIC],
]),
[DatabaseType.POSTGRESQL]: sortDataTypes([
...dataTypeMap[DatabaseType.POSTGRESQL],
]),
[DatabaseType.MYSQL]: sortDataTypes([
...dataTypeMap[DatabaseType.MYSQL],
]),
[DatabaseType.SQL_SERVER]: sortDataTypes([
...dataTypeMap[DatabaseType.SQL_SERVER],
]),
[DatabaseType.MARIADB]: sortDataTypes([
...dataTypeMap[DatabaseType.MARIADB],
]),
[DatabaseType.SQLITE]: sortDataTypes([
...dataTypeMap[DatabaseType.SQLITE],
]),
[DatabaseType.CLICKHOUSE]: sortDataTypes([
...dataTypeMap[DatabaseType.CLICKHOUSE],
]),
[DatabaseType.COCKROACHDB]: sortDataTypes([
...dataTypeMap[DatabaseType.COCKROACHDB],
]),
} as const;
const compatibleTypes: Record<DatabaseType, Record<string, string[]>> = {
[DatabaseType.POSTGRESQL]: {
serial: ['integer'],

View File

@@ -1,27 +1,32 @@
import type { DataTypeData } from './data-types';
export const genericDataTypes: readonly DataTypeData[] = [
// Level 1 - Most commonly used types
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true, usageLevel: 1 },
{ name: 'int', id: 'int', usageLevel: 1 },
{ name: 'text', id: 'text', usageLevel: 1 },
{ name: 'boolean', id: 'boolean', usageLevel: 1 },
{ name: 'date', id: 'date', usageLevel: 1 },
{ name: 'timestamp', id: 'timestamp', usageLevel: 1 },
// Level 2 - Second most common types
{ name: 'decimal', id: 'decimal', usageLevel: 2 },
{ name: 'datetime', id: 'datetime', usageLevel: 2 },
{ name: 'json', id: 'json', usageLevel: 2 },
{ name: 'uuid', id: 'uuid', usageLevel: 2 },
// Less common types
{ name: 'bigint', id: 'bigint' },
{ name: 'binary', id: 'binary', hasCharMaxLength: true },
{ name: 'blob', id: 'blob' },
{ name: 'boolean', id: 'boolean' },
{ name: 'char', id: 'char', hasCharMaxLength: true },
{ name: 'date', id: 'date' },
{ name: 'datetime', id: 'datetime' },
{ name: 'decimal', id: 'decimal' },
{ name: 'double', id: 'double' },
{ name: 'enum', id: 'enum' },
{ name: 'float', id: 'float' },
{ name: 'int', id: 'int' },
{ name: 'json', id: 'json' },
{ name: 'numeric', id: 'numeric' },
{ name: 'real', id: 'real' },
{ name: 'set', id: 'set' },
{ name: 'smallint', id: 'smallint' },
{ name: 'text', id: 'text' },
{ name: 'time', id: 'time' },
{ name: 'timestamp', id: 'timestamp' },
{ name: 'uuid', id: 'uuid' },
{ name: 'varbinary', id: 'varbinary', hasCharMaxLength: true },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true },
] as const;

View File

@@ -1,30 +1,33 @@
import type { DataTypeData } from './data-types';
export const mariadbDataTypes: readonly DataTypeData[] = [
// Numeric Types
// Level 1 - Most commonly used types
{ name: 'int', id: 'int', usageLevel: 1 },
{ name: 'bigint', id: 'bigint', usageLevel: 1 },
{ name: 'decimal', id: 'decimal', usageLevel: 1 },
{ name: 'boolean', id: 'boolean', usageLevel: 1 },
{ name: 'datetime', id: 'datetime', usageLevel: 1 },
{ name: 'date', id: 'date', usageLevel: 1 },
{ name: 'timestamp', id: 'timestamp', usageLevel: 1 },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true, usageLevel: 1 },
{ name: 'text', id: 'text', usageLevel: 1 },
// Level 2 - Second most common types
{ name: 'json', id: 'json', usageLevel: 2 },
{ name: 'uuid', id: 'uuid', usageLevel: 2 },
// Less common types
{ name: 'tinyint', id: 'tinyint' },
{ name: 'smallint', id: 'smallint' },
{ name: 'mediumint', id: 'mediumint' },
{ name: 'int', id: 'int' },
{ name: 'bigint', id: 'bigint' },
{ name: 'decimal', id: 'decimal' },
{ name: 'numeric', id: 'numeric' },
{ name: 'float', id: 'float' },
{ name: 'double', id: 'double' },
{ name: 'bit', id: 'bit' },
{ name: 'bool', id: 'bool' },
{ name: 'boolean', id: 'boolean' },
// Date and Time Types
{ name: 'date', id: 'date' },
{ name: 'datetime', id: 'datetime' },
{ name: 'timestamp', id: 'timestamp' },
{ name: 'time', id: 'time' },
{ name: 'year', id: 'year' },
// String Types
{ name: 'char', id: 'char', hasCharMaxLength: true },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true },
{ name: 'binary', id: 'binary', hasCharMaxLength: true },
{ name: 'varbinary', id: 'varbinary', hasCharMaxLength: true },
{ name: 'tinyblob', id: 'tinyblob' },
@@ -32,13 +35,10 @@ export const mariadbDataTypes: readonly DataTypeData[] = [
{ name: 'mediumblob', id: 'mediumblob' },
{ name: 'longblob', id: 'longblob' },
{ name: 'tinytext', id: 'tinytext' },
{ name: 'text', id: 'text' },
{ name: 'mediumtext', id: 'mediumtext' },
{ name: 'longtext', id: 'longtext' },
{ name: 'enum', id: 'enum' },
{ name: 'set', id: 'set' },
// Spatial Types
{ name: 'geometry', id: 'geometry' },
{ name: 'point', id: 'point' },
{ name: 'linestring', id: 'linestring' },
@@ -47,8 +47,4 @@ export const mariadbDataTypes: readonly DataTypeData[] = [
{ name: 'multilinestring', id: 'multilinestring' },
{ name: 'multipolygon', id: 'multipolygon' },
{ name: 'geometrycollection', id: 'geometrycollection' },
// JSON Type
{ name: 'json', id: 'json' },
{ name: 'uuid', id: 'uuid' },
] as const;

View File

@@ -1,44 +1,41 @@
import type { DataTypeData } from './data-types';
export const mysqlDataTypes: readonly DataTypeData[] = [
// Numeric Types
// Level 1 - Most commonly used types
{ name: 'int', id: 'int', usageLevel: 1 },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true, usageLevel: 1 },
{ name: 'text', id: 'text', usageLevel: 1 },
{ name: 'boolean', id: 'boolean', usageLevel: 1 },
{ name: 'timestamp', id: 'timestamp', usageLevel: 1 },
{ name: 'date', id: 'date', usageLevel: 1 },
// Level 2 - Second most common types
{ name: 'bigint', id: 'bigint', usageLevel: 2 },
{ name: 'decimal', id: 'decimal', usageLevel: 2 },
{ name: 'datetime', id: 'datetime', usageLevel: 2 },
{ name: 'json', id: 'json', usageLevel: 2 },
// Less common types
{ name: 'tinyint', id: 'tinyint' },
{ name: 'smallint', id: 'smallint' },
{ name: 'mediumint', id: 'mediumint' },
{ name: 'int', id: 'int' },
{ name: 'bigint', id: 'bigint' },
{ name: 'decimal', id: 'decimal' },
{ name: 'numeric', id: 'numeric' },
{ name: 'float', id: 'float' },
{ name: 'double', id: 'double' },
{ name: 'bit', id: 'bit' },
{ name: 'bool', id: 'bool' },
{ name: 'boolean', id: 'boolean' },
// Date and Time Types
{ name: 'date', id: 'date' },
{ name: 'datetime', id: 'datetime' },
{ name: 'timestamp', id: 'timestamp' },
{ name: 'time', id: 'time' },
{ name: 'year', id: 'year' },
// String Types
{ name: 'char', id: 'char', hasCharMaxLength: true },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true },
{ name: 'binary', id: 'binary', hasCharMaxLength: true },
{ name: 'varbinary', id: 'varbinary', hasCharMaxLength: true },
{ name: 'tinytext', id: 'tinytext' },
{ name: 'mediumtext', id: 'mediumtext' },
{ name: 'longtext', id: 'longtext' },
{ name: 'binary', id: 'binary' },
{ name: 'varbinary', id: 'varbinary' },
{ name: 'tinyblob', id: 'tinyblob' },
{ name: 'blob', id: 'blob' },
{ name: 'mediumblob', id: 'mediumblob' },
{ name: 'longblob', id: 'longblob' },
{ name: 'tinytext', id: 'tinytext' },
{ name: 'text', id: 'text' },
{ name: 'mediumtext', id: 'mediumtext' },
{ name: 'longtext', id: 'longtext' },
{ name: 'enum', id: 'enum' },
{ name: 'set', id: 'set' },
// Spatial Types
{ name: 'time', id: 'time' },
{ name: 'year', id: 'year' },
{ name: 'geometry', id: 'geometry' },
{ name: 'point', id: 'point' },
{ name: 'linestring', id: 'linestring' },
@@ -47,7 +44,4 @@ export const mysqlDataTypes: readonly DataTypeData[] = [
{ name: 'multilinestring', id: 'multilinestring' },
{ name: 'multipolygon', id: 'multipolygon' },
{ name: 'geometrycollection', id: 'geometrycollection' },
// JSON Type
{ name: 'json', id: 'json' },
] as const;

View File

@@ -1,49 +1,48 @@
import type { DataTypeData } from './data-types';
export const postgresDataTypes: readonly DataTypeData[] = [
// Numeric Types
{ name: 'smallint', id: 'smallint' },
{ name: 'integer', id: 'integer' },
{ name: 'bigint', id: 'bigint' },
{ name: 'decimal', id: 'decimal' },
// Level 1 - Most commonly used types
{ name: 'integer', id: 'integer', usageLevel: 1 },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true, usageLevel: 1 },
{ name: 'text', id: 'text', usageLevel: 1 },
{ name: 'boolean', id: 'boolean', usageLevel: 1 },
{ name: 'timestamp', id: 'timestamp', usageLevel: 1 },
{ name: 'date', id: 'date', usageLevel: 1 },
// Level 2 - Second most common types
{ name: 'bigint', id: 'bigint', usageLevel: 2 },
{ name: 'decimal', id: 'decimal', usageLevel: 2 },
{ name: 'serial', id: 'serial', usageLevel: 2 },
{ name: 'json', id: 'json', usageLevel: 2 },
{ name: 'jsonb', id: 'jsonb', usageLevel: 2 },
{ name: 'uuid', id: 'uuid', usageLevel: 2 },
{
name: 'timestamp with time zone',
id: 'timestamp_with_time_zone',
usageLevel: 2,
},
// Less common types
{ name: 'numeric', id: 'numeric' },
{ name: 'real', id: 'real' },
{ name: 'double precision', id: 'double_precision' },
{ name: 'smallserial', id: 'smallserial' },
{ name: 'serial', id: 'serial' },
{ name: 'bigserial', id: 'bigserial' },
{ name: 'money', id: 'money' },
// Character Types
{ name: 'smallint', id: 'smallint' },
{ name: 'char', id: 'char', hasCharMaxLength: true },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true },
{
name: 'character varying',
id: 'character_varying',
hasCharMaxLength: true,
},
{ name: 'text', id: 'text' },
// Binary Data Types
{ name: 'bytea', id: 'bytea' },
// Date/Time Types
{ name: 'date', id: 'date' },
{ name: 'timestamp', id: 'timestamp' },
{ name: 'timestamp with time zone', id: 'timestamp_with_time_zone' },
{ name: 'timestamp without time zone', id: 'timestamp_without_time_zone' },
{ name: 'time', id: 'time' },
{ name: 'timestamp without time zone', id: 'timestamp_without_time_zone' },
{ name: 'time with time zone', id: 'time_with_time_zone' },
{ name: 'time without time zone', id: 'time_without_time_zone' },
{ name: 'interval', id: 'interval' },
// Boolean Type
{ name: 'boolean', id: 'boolean' },
// Enumerated Types
{ name: 'bytea', id: 'bytea' },
{ name: 'enum', id: 'enum' },
// Geometric Types
{ name: 'point', id: 'point' },
{ name: 'line', id: 'line' },
{ name: 'lseg', id: 'lseg' },
@@ -51,43 +50,22 @@ export const postgresDataTypes: readonly DataTypeData[] = [
{ name: 'path', id: 'path' },
{ name: 'polygon', id: 'polygon' },
{ name: 'circle', id: 'circle' },
// Network Address Types
{ name: 'cidr', id: 'cidr' },
{ name: 'inet', id: 'inet' },
{ name: 'macaddr', id: 'macaddr' },
{ name: 'macaddr8', id: 'macaddr8' },
// Bit String Types
{ name: 'bit', id: 'bit' },
{ name: 'bit varying', id: 'bit_varying' },
// Text Search Types
{ name: 'tsvector', id: 'tsvector' },
{ name: 'tsquery', id: 'tsquery' },
// UUID Type
{ name: 'uuid', id: 'uuid' },
// XML Type
{ name: 'xml', id: 'xml' },
// JSON Types
{ name: 'json', id: 'json' },
{ name: 'jsonb', id: 'jsonb' },
// Array Types
{ name: 'array', id: 'array' },
// Range Types
{ name: 'int4range', id: 'int4range' },
{ name: 'int8range', id: 'int8range' },
{ name: 'numrange', id: 'numrange' },
{ name: 'tsrange', id: 'tsrange' },
{ name: 'tstzrange', id: 'tstzrange' },
{ name: 'daterange', id: 'daterange' },
// Object Identifier Types
{ name: 'oid', id: 'oid' },
{ name: 'regproc', id: 'regproc' },
{ name: 'regprocedure', id: 'regprocedure' },
@@ -99,7 +77,5 @@ export const postgresDataTypes: readonly DataTypeData[] = [
{ name: 'regnamespace', id: 'regnamespace' },
{ name: 'regconfig', id: 'regconfig' },
{ name: 'regdictionary', id: 'regdictionary' },
// User Defined types
{ name: 'user-defined', id: 'user-defined' },
] as const;

View File

@@ -1,56 +1,44 @@
import type { DataTypeData } from './data-types';
export const sqlServerDataTypes: readonly DataTypeData[] = [
// Exact Numerics
{ name: 'bigint', id: 'bigint' },
{ name: 'bit', id: 'bit' },
{ name: 'decimal', id: 'decimal' },
{ name: 'int', id: 'int' },
{ name: 'money', id: 'money' },
// Level 1 - Most commonly used types
{ name: 'int', id: 'int', usageLevel: 1 },
{ name: 'bit', id: 'bit', usageLevel: 1 },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true, usageLevel: 1 },
{ name: 'nvarchar', id: 'nvarchar', hasCharMaxLength: true, usageLevel: 1 },
{ name: 'text', id: 'text', usageLevel: 1 },
{ name: 'datetime', id: 'datetime', usageLevel: 1 },
{ name: 'date', id: 'date', usageLevel: 1 },
// Level 2 - Second most common types
{ name: 'bigint', id: 'bigint', usageLevel: 2 },
{ name: 'decimal', id: 'decimal', usageLevel: 2 },
{ name: 'datetime2', id: 'datetime2', usageLevel: 2 },
{ name: 'uniqueidentifier', id: 'uniqueidentifier', usageLevel: 2 },
{ name: 'json', id: 'json', usageLevel: 2 },
// Less common types
{ name: 'numeric', id: 'numeric' },
{ name: 'smallint', id: 'smallint' },
{ name: 'smallmoney', id: 'smallmoney' },
{ name: 'tinyint', id: 'tinyint' },
// Approximate Numerics
{ name: 'money', id: 'money' },
{ name: 'float', id: 'float' },
{ name: 'real', id: 'real' },
// Date and Time
{ name: 'date', id: 'date' },
{ name: 'datetime2', id: 'datetime2' },
{ name: 'datetime', id: 'datetime' },
{ name: 'datetimeoffset', id: 'datetimeoffset' },
{ name: 'smalldatetime', id: 'smalldatetime' },
{ name: 'time', id: 'time' },
// Character Strings
{ name: 'char', id: 'char', hasCharMaxLength: true },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true },
{ name: 'text', id: 'text' },
// Unicode Character Strings
{ name: 'nchar', id: 'nchar', hasCharMaxLength: true },
{ name: 'nvarchar', id: 'nvarchar', hasCharMaxLength: true },
{ name: 'ntext', id: 'ntext' },
// Binary Strings
{ name: 'binary', id: 'binary', hasCharMaxLength: true },
{ name: 'varbinary', id: 'varbinary', hasCharMaxLength: true },
{ name: 'image', id: 'image' },
// Other Data Types
{ name: 'datetimeoffset', id: 'datetimeoffset' },
{ name: 'smalldatetime', id: 'smalldatetime' },
{ name: 'time', id: 'time' },
{ name: 'timestamp', id: 'timestamp' },
{ name: 'xml', id: 'xml' },
{ name: 'cursor', id: 'cursor' },
{ name: 'hierarchyid', id: 'hierarchyid' },
{ name: 'sql_variant', id: 'sql_variant' },
{ name: 'timestamp', id: 'timestamp' },
{ name: 'uniqueidentifier', id: 'uniqueidentifier' },
{ name: 'xml', id: 'xml' },
// Spatial Data Types
{ name: 'geometry', id: 'geometry' },
{ name: 'geography', id: 'geography' },
// JSON
{ name: 'json', id: 'json' },
] as const;

View File

@@ -1,27 +1,22 @@
import type { DataTypeData } from './data-types';
export const sqliteDataTypes: readonly DataTypeData[] = [
// Numeric Types
{ name: 'integer', id: 'integer' },
// Level 1 - Most commonly used types
{ name: 'integer', id: 'integer', usageLevel: 1 },
{ name: 'int', id: 'int', usageLevel: 1 },
{ name: 'text', id: 'text', usageLevel: 1 },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true, usageLevel: 1 },
{ name: 'date', id: 'date', usageLevel: 1 },
{ name: 'datetime', id: 'datetime', usageLevel: 1 },
{ name: 'boolean', id: 'boolean', usageLevel: 1 },
// Level 2 - Second most common types
{ name: 'decimal', id: 'decimal', usageLevel: 2 },
{ name: 'json', id: 'json', usageLevel: 2 },
// Less common types
{ name: 'real', id: 'real' },
{ name: 'numeric', id: 'numeric' },
// Text Type
{ name: 'text', id: 'text' },
// Blob Type
{ name: 'blob', id: 'blob' },
// Blob Type
{ name: 'json', id: 'json' },
// Date/Time Types (SQLite uses TEXT, REAL, or INTEGER types for dates and times)
{ name: 'date', id: 'date' },
{ name: 'datetime', id: 'datetime' },
{ name: 'int', id: 'int' },
{ name: 'float', id: 'float' },
{ name: 'boolean', id: 'boolean' },
{ name: 'varchar', id: 'varchar', hasCharMaxLength: true },
{ name: 'decimal', id: 'decimal' },
{ name: 'blob', id: 'blob' },
] as const;

View File

@@ -5,7 +5,7 @@ import type { DBField } from '@/lib/domain/db-field';
import { useChartDB } from '@/hooks/use-chartdb';
import {
dataTypeDataToDataType,
dataTypeMap,
sortedDataTypeMap,
} from '@/lib/data/data-types/data-types';
import {
Tooltip,
@@ -40,22 +40,20 @@ export const TableField: React.FC<TableFieldProps> = ({
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id: field.id });
const dataFieldOptions: SelectBoxOption[] = dataTypeMap[databaseType].map(
(type) => ({
const dataFieldOptions: SelectBoxOption[] = sortedDataTypeMap[
databaseType
].map((type) => ({
label: type.name,
value: type.id,
regex: type.hasCharMaxLength
? `^${type.name}\\(\\d+\\)$`
: undefined,
regex: type.hasCharMaxLength ? `^${type.name}\\(\\d+\\)$` : undefined,
extractRegex: type.hasCharMaxLength ? /\((\d+)\)/ : undefined,
})
);
}));
const onChangeDataType = useCallback<
NonNullable<SelectBoxProps['onChange']>
>(
(value, regexMatches) => {
const dataType = dataTypeMap[databaseType].find(
const dataType = sortedDataTypeMap[databaseType].find(
(v) => v.id === value
) ?? {
id: value as string,
@@ -141,9 +139,9 @@ export const TableField: React.FC<TableFieldProps> = ({
: ''
}
optionSuffix={(option) => {
const type = dataTypeMap[databaseType].find(
(v) => v.id === option.value
);
const type = sortedDataTypeMap[
databaseType
].find((v) => v.id === option.value);
if (!type) {
return '';