Skip to content

Commit c503126

Browse files
committed
feat: Add column renaming support and enhance data editor with type-specific inputs and a 'commit & add another' option.
1 parent 5e1ee53 commit c503126

File tree

6 files changed

+61
-12
lines changed

6 files changed

+61
-12
lines changed

database/mysql_driver.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,15 @@ func (d *MySQLDriver) BuildAlterTableQuery(database, table string, alteration Ta
266266
if col.Default != "" {
267267
defaultStr = fmt.Sprintf(" DEFAULT '%s'", col.Default)
268268
}
269-
statements = append(statements, fmt.Sprintf("ALTER TABLE `%s`.`%s` MODIFY COLUMN `%s` %s %s%s %s",
270-
database, table, col.Name, col.Type, nullStr, defaultStr, col.Extra))
269+
270+
// Use CHANGE COLUMN if renaming, otherwise MODIFY COLUMN
271+
if col.OldName != "" && col.OldName != col.Name {
272+
statements = append(statements, fmt.Sprintf("ALTER TABLE `%s`.`%s` CHANGE COLUMN `%s` `%s` %s %s%s %s",
273+
database, table, col.OldName, col.Name, col.Type, nullStr, defaultStr, col.Extra))
274+
} else {
275+
statements = append(statements, fmt.Sprintf("ALTER TABLE `%s`.`%s` MODIFY COLUMN `%s` %s %s%s %s",
276+
database, table, col.Name, col.Type, nullStr, defaultStr, col.Extra))
277+
}
271278
}
272279

273280
return statements, nil

database/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ type ColumnInfo struct {
7070
Key string `json:"key"`
7171
Default string `json:"default"`
7272
Extra string `json:"extra"`
73+
OldName string `json:"oldName,omitempty"` // For renaming columns
7374
}
7475

7576
// IndexInfo represents an index

frontend/src/components/DataEditor.tsx

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ import { Badge } from "@/components/ui/badge";
3737
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
3838
import { Card, CardContent } from "@/components/ui/card";
3939
import { Separator } from "@/components/ui/separator";
40+
import {
41+
Select,
42+
SelectContent,
43+
SelectItem,
44+
SelectTrigger,
45+
SelectValue,
46+
} from "@/components/ui/select";
4047
import { cn } from '@/lib/utils';
4148
import { toast } from "sonner";
4249
import {
@@ -170,7 +177,7 @@ export function DataEditor({ database, table, onClose }: Props) {
170177
}
171178
};
172179

173-
const handleAddRow = async () => {
180+
const handleAddRow = async (keepOpen = false) => {
174181
if (!data) return;
175182

176183
const rowData: Record<string, any> = {};
@@ -183,7 +190,9 @@ export function DataEditor({ database, table, onClose }: Props) {
183190
try {
184191
await InsertRow(database, table, rowData);
185192
setNewRowData({});
186-
setShowAddRow(false);
193+
if (!keepOpen) {
194+
setShowAddRow(false);
195+
}
187196
toast.success("New row inserted successfully");
188197
await loadData();
189198
} catch (err: any) {
@@ -437,18 +446,43 @@ export function DataEditor({ database, table, onClose }: Props) {
437446
<span className="text-[8px] opacity-40 uppercase">{col.type}</span>
438447
</div>
439448
</div>
440-
<Input
441-
className="h-7 text-xs bg-background"
442-
value={newRowData[col.name] || ''}
443-
onChange={(e) => setNewRowData({ ...newRowData, [col.name]: e.target.value })}
444-
placeholder={col.nullable ? 'NULL' : col.name}
445-
/>
449+
{col.type.includes('bool') || col.type.includes('tinyint(1)') ? (
450+
<Select
451+
value={newRowData[col.name]}
452+
onValueChange={(val) => setNewRowData({ ...newRowData, [col.name]: val })}
453+
>
454+
<SelectTrigger className="h-7 text-xs bg-background">
455+
<SelectValue placeholder={col.nullable ? "NULL" : "Select..."} />
456+
</SelectTrigger>
457+
<SelectContent>
458+
{col.nullable && <SelectItem value="">NULL</SelectItem>}
459+
<SelectItem value="1">TRUE</SelectItem>
460+
<SelectItem value="0">FALSE</SelectItem>
461+
</SelectContent>
462+
</Select>
463+
) : (
464+
<Input
465+
className="h-7 text-xs bg-background"
466+
value={newRowData[col.name] || ''}
467+
onChange={(e) => setNewRowData({ ...newRowData, [col.name]: e.target.value })}
468+
placeholder={col.nullable ? 'NULL' : col.name}
469+
type={col.type.includes('int') || col.type.includes('decimal') || col.type.includes('float') ? 'number' : 'text'}
470+
/>
471+
)}
446472
</div>
447473
))}
448474
</div>
449475
<div className="flex justify-end gap-2 mt-6">
450476
<Button variant="ghost" size="sm" className="h-8 text-[11px] font-bold" onClick={() => setShowAddRow(false)}>CANCEL</Button>
451-
<Button size="sm" className="h-8 px-6 text-[11px] font-bold uppercase" onClick={handleAddRow}>Commit Row</Button>
477+
<Button
478+
variant="outline"
479+
size="sm"
480+
className="h-8 px-4 text-[11px] font-bold uppercase border-primary/20 text-primary hover:bg-primary/5"
481+
onClick={() => handleAddRow(true)}
482+
>
483+
Commit & Add Another
484+
</Button>
485+
<Button size="sm" className="h-8 px-6 text-[11px] font-bold uppercase" onClick={() => handleAddRow(false)}>Commit Row</Button>
452486
</div>
453487
</CardContent>
454488
</Card>

frontend/src/components/ModifyTableModal.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export function ModifyTableModal({ database, table, columns, onSave, onClose, lo
9090
const handleSave = async () => {
9191
const alteration: TableAlteration = {
9292
addColumns: columnStates.filter(c => c.isNew && !c.isDeleted).map(({ isNew, isDeleted, isModified, oldName, ...c }) => c),
93-
modifyColumns: columnStates.filter(c => !c.isNew && c.isModified && !c.isDeleted).map(({ isNew, isDeleted, isModified, oldName, ...c }) => c),
93+
modifyColumns: columnStates.filter(c => !c.isNew && c.isModified && !c.isDeleted).map(({ isNew, isDeleted, isModified, ...c }) => ({ ...c, oldName: c.oldName })),
9494
dropColumns: columnStates.filter(c => !c.isNew && c.isDeleted).map(c => c.oldName || c.name),
9595
renameTo: table // For now, keep table name same
9696
};
@@ -171,6 +171,10 @@ export function ModifyTableModal({ database, table, columns, onSave, onClose, lo
171171
<SelectValue />
172172
</SelectTrigger>
173173
<SelectContent>
174+
{/* Ensure current type is always an option */}
175+
{!mysqlTypes.includes(col.type) && (
176+
<SelectItem value={col.type} className="text-[11px] font-mono">{col.type.toUpperCase()}</SelectItem>
177+
)}
174178
{mysqlTypes.map(t => (
175179
<SelectItem key={t} value={t} className="text-[11px]">{t.toUpperCase()}</SelectItem>
176180
))}

frontend/src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export interface ColumnInfo {
6363
key: string;
6464
default: string;
6565
extra: string;
66+
oldName?: string;
6667
}
6768

6869
export interface IndexInfo {

frontend/wailsjs/go/models.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export namespace database {
77
key: string;
88
default: string;
99
extra: string;
10+
oldName?: string;
1011

1112
static createFrom(source: any = {}) {
1213
return new ColumnInfo(source);
@@ -20,6 +21,7 @@ export namespace database {
2021
this.key = source["key"];
2122
this.default = source["default"];
2223
this.extra = source["extra"];
24+
this.oldName = source["oldName"];
2325
}
2426
}
2527
export class ConnectionConfig {

0 commit comments

Comments
 (0)