feat: add auto increment support for fields with database-specific export (#851)

* feat: add auto increment support for fields with database-specific export

* fix

---------

Co-authored-by: Guy Ben-Aharon <baguy3@gmail.com>
This commit is contained in:
Jonathan Fishner
2025-08-19 11:39:26 +03:00
committed by GitHub
parent 0aaa451479
commit c77c983989
28 changed files with 100 additions and 18 deletions

View File

@@ -143,6 +143,7 @@ export const ar: LanguageTranslation = {
field_actions: {
title: 'خصائص الحقل',
unique: 'فريد',
auto_increment: 'زيادة تلقائية',
comments: 'تعليقات',
no_comments: 'لا يوجد تعليقات',
delete_field: 'حذف الحقل',

View File

@@ -144,6 +144,7 @@ export const bn: LanguageTranslation = {
field_actions: {
title: 'ফিল্ড কর্ম',
unique: 'অদ্বিতীয়',
auto_increment: 'স্বয়ংক্রিয় বৃদ্ধি',
comments: 'মন্তব্য',
no_comments: 'কোনো মন্তব্য নেই',
delete_field: 'ফিল্ড মুছুন',

View File

@@ -145,6 +145,7 @@ export const de: LanguageTranslation = {
field_actions: {
title: 'Feldattribute',
unique: 'Eindeutig',
auto_increment: 'Automatisch hochzählen',
comments: 'Kommentare',
no_comments: 'Keine Kommentare',
delete_field: 'Feld löschen',

View File

@@ -140,6 +140,7 @@ export const en = {
field_actions: {
title: 'Field Attributes',
unique: 'Unique',
auto_increment: 'Auto Increment',
character_length: 'Max Length',
precision: 'Precision',
scale: 'Scale',

View File

@@ -143,6 +143,7 @@ export const es: LanguageTranslation = {
field_actions: {
title: 'Atributos del Campo',
unique: 'Único',
auto_increment: 'Autoincremento',
comments: 'Comentarios',
no_comments: 'Sin comentarios',
delete_field: 'Eliminar Campo',

View File

@@ -141,6 +141,7 @@ export const fr: LanguageTranslation = {
field_actions: {
title: 'Attributs du Champ',
unique: 'Unique',
auto_increment: 'Auto-incrément',
comments: 'Commentaires',
no_comments: 'Pas de commentaires',
delete_field: 'Supprimer le Champ',

View File

@@ -145,6 +145,7 @@ export const gu: LanguageTranslation = {
field_actions: {
title: 'ફીલ્ડ લક્ષણો',
unique: 'અદ્વિતીય',
auto_increment: 'ઑટો ઇન્ક્રિમેન્ટ',
comments: 'ટિપ્પણીઓ',
no_comments: 'કોઈ ટિપ્પણીઓ નથી',
delete_field: 'ફીલ્ડ કાઢી નાખો',

View File

@@ -144,6 +144,7 @@ export const hi: LanguageTranslation = {
field_actions: {
title: 'फ़ील्ड विशेषताएँ',
unique: 'अद्वितीय',
auto_increment: 'ऑटो इंक्रीमेंट',
comments: 'टिप्पणियाँ',
no_comments: 'कोई टिप्पणी नहीं',
delete_field: 'फ़ील्ड हटाएँ',

View File

@@ -141,6 +141,7 @@ export const hr: LanguageTranslation = {
field_actions: {
title: 'Atributi polja',
unique: 'Jedinstven',
auto_increment: 'Automatsko povećavanje',
character_length: 'Maksimalna dužina',
precision: 'Preciznost',
scale: 'Skala',

View File

@@ -143,6 +143,7 @@ export const id_ID: LanguageTranslation = {
field_actions: {
title: 'Atribut Kolom',
unique: 'Unik',
auto_increment: 'Kenaikan Otomatis',
comments: 'Komentar',
no_comments: 'Tidak ada komentar',
delete_field: 'Hapus Kolom',

View File

@@ -147,6 +147,7 @@ export const ja: LanguageTranslation = {
field_actions: {
title: 'フィールド属性',
unique: 'ユニーク',
auto_increment: 'オートインクリメント',
comments: 'コメント',
no_comments: 'コメントがありません',
delete_field: 'フィールドを削除',

View File

@@ -143,6 +143,7 @@ export const ko_KR: LanguageTranslation = {
field_actions: {
title: '필드 속성',
unique: '유니크 여부',
auto_increment: '자동 증가',
comments: '주석',
no_comments: '주석 없음',
delete_field: '필드 삭제',

View File

@@ -146,6 +146,7 @@ export const mr: LanguageTranslation = {
field_actions: {
title: 'फील्ड गुणधर्म',
unique: 'युनिक',
auto_increment: 'ऑटो इंक्रिमेंट',
comments: 'टिप्पण्या',
no_comments: 'कोणत्याही टिप्पणी नाहीत',
delete_field: 'फील्ड हटवा',

View File

@@ -144,6 +144,7 @@ export const ne: LanguageTranslation = {
field_actions: {
title: 'क्षेत्र विशेषताहरू',
unique: 'अनन्य',
auto_increment: 'स्वचालित वृद्धि',
comments: 'टिप्पणीहरू',
no_comments: 'कुनै टिप्पणीहरू छैनन्',
delete_field: 'क्षेत्र हटाउनुहोस्',

View File

@@ -144,6 +144,7 @@ export const pt_BR: LanguageTranslation = {
field_actions: {
title: 'Atributos do Campo',
unique: 'Único',
auto_increment: 'Incremento Automático',
comments: 'Comentários',
no_comments: 'Sem comentários',
delete_field: 'Excluir Campo',

View File

@@ -141,6 +141,7 @@ export const ru: LanguageTranslation = {
field_actions: {
title: 'Атрибуты поля',
unique: 'Уникальный',
auto_increment: 'Автоинкремент',
comments: 'Комментарии',
no_comments: 'Нет комментария',
delete_field: 'Удалить поле',

View File

@@ -144,6 +144,7 @@ export const te: LanguageTranslation = {
field_actions: {
title: 'ఫీల్డ్ గుణాలు',
unique: 'అద్వితీయ',
auto_increment: 'ఆటో ఇంక్రిమెంట్',
comments: 'వ్యాఖ్యలు',
no_comments: 'వ్యాఖ్యలు లేవు',
delete_field: 'ఫీల్డ్ తొలగించు',

View File

@@ -143,6 +143,7 @@ export const tr: LanguageTranslation = {
field_actions: {
title: 'Alan Özellikleri',
unique: 'Tekil',
auto_increment: 'Otomatik Artış',
comments: 'Yorumlar',
no_comments: 'Yorum yok',
delete_field: 'Alanı Sil',

View File

@@ -142,6 +142,7 @@ export const uk: LanguageTranslation = {
field_actions: {
title: 'Атрибути полів',
unique: 'Унікальне',
auto_increment: 'Автоінкремент',
comments: 'Коментарі',
no_comments: 'Немає коментарів',
delete_field: 'Видалити поле',

View File

@@ -143,6 +143,7 @@ export const vi: LanguageTranslation = {
field_actions: {
title: 'Thuộc tính trường',
unique: 'Giá trị duy nhất',
auto_increment: 'Tự động tăng',
comments: 'Bình luận',
no_comments: 'Không có bình luận',
delete_field: 'Xóa trường',

View File

@@ -140,6 +140,7 @@ export const zh_CN: LanguageTranslation = {
field_actions: {
title: '字段属性',
unique: '唯一',
auto_increment: '自动递增',
comments: '注释',
no_comments: '空',
delete_field: '删除字段',

View File

@@ -140,6 +140,7 @@ export const zh_TW: LanguageTranslation = {
field_actions: {
title: '欄位屬性',
unique: '唯一',
auto_increment: '自動遞增',
comments: '註解',
no_comments: '無註解',
delete_field: '刪除欄位',

View File

@@ -146,3 +146,22 @@ export const findDataTypeDataById = (
return dataTypesOptions.find((dataType) => dataType.id === id);
};
export const supportsAutoIncrementDataType = (
dataTypeName: string
): boolean => {
return [
'integer',
'int',
'bigint',
'smallint',
'tinyint',
'mediumint',
'serial',
'bigserial',
'smallserial',
'number',
'numeric',
'decimal',
].includes(dataTypeName.toLocaleLowerCase());
};

View File

@@ -156,11 +156,11 @@ export function exportMSSQL({
const notNull = field.nullable ? '' : ' NOT NULL';
// Check if identity column
const identity = field.default
?.toLowerCase()
.includes('identity')
? ' IDENTITY(1,1)'
: '';
const identity =
field.increment ||
field.default?.toLowerCase().includes('identity')
? ' IDENTITY(1,1)'
: '';
const unique =
!field.primaryKey && field.unique ? ' UNIQUE' : '';
@@ -168,6 +168,7 @@ export function exportMSSQL({
// Handle default value using SQL Server specific parser
const defaultValue =
field.default &&
!field.increment &&
!field.default.toLowerCase().includes('identity')
? ` DEFAULT ${parseMSSQLDefault(field)}`
: '';

View File

@@ -274,14 +274,15 @@ export function exportMySQL({
// Handle auto_increment - MySQL uses AUTO_INCREMENT keyword
let autoIncrement = '';
if (
field.primaryKey &&
(field.default
?.toLowerCase()
.includes('identity') ||
field.default
field.increment ||
(field.primaryKey &&
(field.default
?.toLowerCase()
.includes('autoincrement') ||
field.default?.includes('nextval'))
.includes('identity') ||
field.default
?.toLowerCase()
.includes('autoincrement') ||
field.default?.includes('nextval')))
) {
autoIncrement = ' AUTO_INCREMENT';
}
@@ -290,9 +291,10 @@ export function exportMySQL({
const unique =
!field.primaryKey && field.unique ? ' UNIQUE' : '';
// Handle default value
// Handle default value - skip if auto increment
const defaultValue =
field.default &&
!field.increment &&
!field.default.toLowerCase().includes('identity') &&
!field.default
.toLowerCase()

View File

@@ -343,9 +343,10 @@ export function exportSQLite({
if (
field.primaryKey &&
singleIntegerPrimaryKey &&
(field.default
?.toLowerCase()
.includes('identity') ||
(field.increment ||
field.default
?.toLowerCase()
.includes('identity') ||
field.default
?.toLowerCase()
.includes('autoincrement') ||
@@ -362,6 +363,7 @@ export function exportSQLite({
let defaultValue = '';
if (
field.default &&
!field.increment &&
!field.default.toLowerCase().includes('identity') &&
!field.default
.toLowerCase()

View File

@@ -274,8 +274,13 @@ export const exportBaseSQL = ({
sqlScript += ` UNIQUE`;
}
// Handle AUTO INCREMENT - add as a comment for AI to process
if (field.increment) {
sqlScript += ` /* AUTO_INCREMENT */`;
}
// Handle DEFAULT value
if (field.default) {
if (field.default && !field.increment) {
// Temp remove default user-define value when it have it
let fieldDefault = field.default;

View File

@@ -5,7 +5,10 @@ import { Button } from '@/components/button/button';
import { Separator } from '@/components/separator/separator';
import type { DBField } from '@/lib/domain/db-field';
import type { FieldAttributeRange } from '@/lib/data/data-types/data-types';
import { findDataTypeDataById } from '@/lib/data/data-types/data-types';
import {
findDataTypeDataById,
supportsAutoIncrementDataType,
} from '@/lib/data/data-types/data-types';
import {
Popover,
PopoverContent,
@@ -83,6 +86,7 @@ export const TableFieldPopover: React.FC<TableFieldPopoverProps> = ({
scale: localField.scale,
unique: localField.unique,
default: localField.default,
increment: localField.increment,
});
}
prevFieldRef.current = localField;
@@ -93,6 +97,11 @@ export const TableFieldPopover: React.FC<TableFieldPopoverProps> = ({
[field.type.id, databaseType]
);
const supportsAutoIncrement = useMemo(
() => supportsAutoIncrementDataType(field.type.name),
[field.type.name]
);
return (
<Popover
open={isOpen}
@@ -137,6 +146,28 @@ export const TableFieldPopover: React.FC<TableFieldPopoverProps> = ({
}
/>
</div>
{supportsAutoIncrement ? (
<div className="flex items-center justify-between">
<Label
htmlFor="increment"
className="text-subtitle"
>
{t(
'side_panel.tables_section.table.field_actions.auto_increment'
)}
</Label>
<Checkbox
checked={localField.increment ?? false}
disabled={!localField.primaryKey}
onCheckedChange={(value) =>
setLocalField((current) => ({
...current,
increment: !!value,
}))
}
/>
</div>
) : null}
<div className="flex flex-col gap-2">
<Label htmlFor="default" className="text-subtitle">
{t(