Skip to content

Commit

Permalink
feat: updated data manipulation for database detail page
Browse files Browse the repository at this point in the history
  • Loading branch information
tikazyq committed Sep 27, 2024
1 parent 68def56 commit 3fb33a1
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 12 deletions.
32 changes: 20 additions & 12 deletions src/components/core/database/tables/DatabaseTableDetailData.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { TableColumnCtx } from 'element-plus/es/components/table/src/table/
import useRequest from '@/services/request';
import { ClEditTable, ClTableEditCell } from '@/components';
import { getMd5, plainClone, translate } from '@/utils';
import { normalizeDataType } from '@/utils/database';
const props = defineProps<{
loading?: boolean;
Expand Down Expand Up @@ -196,25 +197,28 @@ const onDeleteDataRows = () => {
const rollback = () => {
tableData.value = plainClone(originalTableData.value);
tablePagination.value = { page: 1, size: 10 };
tableRef.value?.clearSelection?.();
};
const commit = async () => {
await post(`/databases/${props.activeId}/tables/data`, {
database: props.databaseName,
table: props.activeTable?.name,
database_name: props.databaseName,
table_name: props.activeTable?.name,
rows: tableData.value
.filter(row => !!row.__status__)
.filter(row => getDataRowStatus(row))
.map(row => {
const d: any = {
status: row.__status__,
};
switch (row.__status__) {
switch (getDataRowStatus(row)) {
case 'new':
const d: any = {};
props.activeTable?.columns?.forEach(column => {
const colName = column.name as string;
d[colName] = row[colName];
d[colName] = normalizeDataType(
row[colName],
column.type as string
);
});
return { row: d };
return { row: d, status: 'new' };
case 'updated':
const updateFilter: any = {};
const update: any = {};
Expand All @@ -224,7 +228,10 @@ const commit = async () => {
originalTableDataMap.value[getRowHash(row)]?.[colName];
const currentValue = row[colName];
if (currentValue !== originalValue) {
update[colName] = currentValue;
update[colName] = normalizeDataType(
currentValue,
column.type as string
);
}
});
if (primaryColumnName.value) {
Expand All @@ -235,7 +242,7 @@ const commit = async () => {
} else {
throw new Error('Primary column not found');
}
return { filter: updateFilter, update };
return { filter: updateFilter, update, status: 'updated' };
case 'deleted':
const deleteFilter: any = {};
if (primaryColumnName.value) {
Expand All @@ -246,10 +253,11 @@ const commit = async () => {
} else {
throw new Error('Primary column not found');
}
return { filter: deleteFilter };
return { filter: deleteFilter, status: 'deleted' };
}
}),
});
await getTableData();
};
const hasChanges = computed(() => {
Expand Down
89 changes: 89 additions & 0 deletions src/utils/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,92 @@ export const isDefaultIndexName = (
export const canColumnAutoIncrement = (column: DatabaseColumn) => {
return column.primary && column.type?.match(/int/i);
};

export const normalizeDataType = (value: any, type: string) => {
if (!type) return value;

const lowerType = type.toLowerCase();

// Helper function for fuzzy matching
const fuzzyMatch = (pattern: string) =>
new RegExp(pattern, 'i').test(lowerType);

// Integer types
if (fuzzyMatch('int|integer|smallint|bigint|tinyint|mediumint')) {
return Number.isInteger(Number(value))
? Number(value)
: Math.floor(Number(value));
}

// Floating point types
if (fuzzyMatch('float|real|double|numeric|decimal')) {
return isNaN(parseFloat(value)) ? null : parseFloat(value);
}

// Boolean type
if (fuzzyMatch('bool|bit')) {
if (typeof value === 'boolean') return value;
if (typeof value === 'string')
return value.toLowerCase() === 'true' || value === '1';
return Boolean(value);
}

// String types
if (fuzzyMatch('char|text|string')) {
return value !== null && value !== undefined ? String(value) : null;
}

// Date type
if (/^date$/.test(lowerType)) {
return value ? new Date(value).toISOString().split('T')[0] : null;
}

// Time type
if (/^time$/.test(lowerType)) {
return value
? new Date(`1970-01-01T${value}`)
.toISOString()
.split('T')[1]
.split('.')[0]
: null;
}

// Timestamp/DateTime types
if (/^(timestamp|datetime|timestamptz)$/.test(lowerType)) {
return value ? new Date(value).toISOString() : null;
}

// JSON types
if (/^(json|jsonb)$/.test(lowerType)) {
if (typeof value === 'object') return value;
try {
return JSON.parse(value);
} catch {
return null;
}
}

// Array type
if (/^array$/.test(lowerType) || lowerType.endsWith('[]')) {
return Array.isArray(value) ? value : [value];
}

// UUID type
if (/^(uuid|uniqueidentifier)$/.test(lowerType)) {
return value !== null && value !== undefined ? String(value) : null;
}

// Binary data type
if (/^(bytea|blob|binary|varbinary|image)$/.test(lowerType)) {
// For binary data, we might need to handle this differently depending on the frontend requirements
return value;
}

// MongoDB-specific types
if (/^(objectid|long|decimal128)$/.test(lowerType)) {
return value; // These types are typically handled by MongoDB drivers
}

// Default case
return value;
};

0 comments on commit 3fb33a1

Please sign in to comment.