215 lines
6.5 KiB
Go
215 lines
6.5 KiB
Go
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/gdamore/tcell/v2"
|
|
"github.com/rivo/tview"
|
|
|
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
|
)
|
|
|
|
// showColumnEditor shows editor for a specific column
|
|
func (se *SchemaEditor) showColumnEditor(schemaIndex, tableIndex, colIndex int, column *models.Column) {
|
|
form := tview.NewForm()
|
|
|
|
// Store original name to handle renames
|
|
originalName := column.Name
|
|
|
|
// Local variables to collect changes
|
|
newName := column.Name
|
|
newType := column.Type
|
|
newIsPK := column.IsPrimaryKey
|
|
newIsNotNull := column.NotNull
|
|
newDefault := column.Default
|
|
newDescription := column.Description
|
|
newGUID := column.GUID
|
|
|
|
// Column type options: PostgreSQL, MySQL, SQL Server, and common SQL types
|
|
columnTypes := []string{
|
|
// Numeric Types
|
|
"SMALLINT", "INTEGER", "BIGINT", "INT", "TINYINT", "FLOAT", "REAL", "DOUBLE PRECISION",
|
|
"DECIMAL(10,2)", "NUMERIC", "DECIMAL", "NUMERIC(10,2)",
|
|
// Character Types
|
|
"CHAR", "VARCHAR", "VARCHAR(255)", "TEXT", "NCHAR", "NVARCHAR", "NVARCHAR(255)",
|
|
// Boolean
|
|
"BOOLEAN", "BOOL", "BIT",
|
|
// Date/Time Types
|
|
"DATE", "TIME", "TIMESTAMP", "TIMESTAMP WITH TIME ZONE", "INTERVAL",
|
|
"DATETIME", "DATETIME2", "DATEFIRST",
|
|
// UUID and JSON
|
|
"UUID", "GUID", "JSON", "JSONB",
|
|
// Binary Types
|
|
"BYTEA", "BLOB", "IMAGE", "VARBINARY", "VARBINARY(MAX)", "BINARY",
|
|
// PostgreSQL Special Types
|
|
"int4range", "int8range", "numrange", "tsrange", "tstzrange", "daterange",
|
|
"HSTORE", "CITEXT", "INET", "MACADDR", "POINT", "LINE", "LSEG", "BOX", "PATH", "POLYGON", "CIRCLE",
|
|
// Array Types
|
|
"INTEGER ARRAY", "VARCHAR ARRAY", "TEXT ARRAY", "BIGINT ARRAY",
|
|
// MySQL Specific
|
|
"MEDIUMINT", "DOUBLE", "FLOAT(10,2)",
|
|
// SQL Server Specific
|
|
"MONEY", "SMALLMONEY", "SQL_VARIANT",
|
|
}
|
|
selectedTypeIndex := 0
|
|
|
|
// Add existing type if not already in the list
|
|
typeExists := false
|
|
for i, opt := range columnTypes {
|
|
if opt == column.Type {
|
|
selectedTypeIndex = i
|
|
typeExists = true
|
|
break
|
|
}
|
|
}
|
|
if !typeExists && column.Type != "" {
|
|
columnTypes = append(columnTypes, column.Type)
|
|
selectedTypeIndex = len(columnTypes) - 1
|
|
}
|
|
|
|
form.AddInputField("Column Name", column.Name, 40, nil, func(value string) {
|
|
newName = value
|
|
})
|
|
|
|
form.AddDropDown("Type", columnTypes, selectedTypeIndex, func(option string, index int) {
|
|
newType = option
|
|
})
|
|
|
|
form.AddCheckbox("Primary Key", column.IsPrimaryKey, func(checked bool) {
|
|
newIsPK = checked
|
|
})
|
|
|
|
form.AddCheckbox("Not Null", column.NotNull, func(checked bool) {
|
|
newIsNotNull = checked
|
|
})
|
|
|
|
defaultStr := ""
|
|
if column.Default != nil {
|
|
defaultStr = fmt.Sprintf("%v", column.Default)
|
|
}
|
|
form.AddInputField("Default Value", defaultStr, 40, nil, func(value string) {
|
|
newDefault = value
|
|
})
|
|
|
|
form.AddTextArea("Description", column.Description, 40, 5, 0, func(value string) {
|
|
newDescription = value
|
|
})
|
|
|
|
form.AddInputField("GUID", column.GUID, 40, nil, func(value string) {
|
|
newGUID = value
|
|
})
|
|
|
|
form.AddButton("Save", func() {
|
|
// Apply changes using dataops
|
|
se.UpdateColumn(schemaIndex, tableIndex, originalName, newName, newType, newIsPK, newIsNotNull, newDefault, newDescription)
|
|
se.db.Schemas[schemaIndex].Tables[tableIndex].Columns[newName].GUID = newGUID
|
|
|
|
se.pages.RemovePage("column-editor")
|
|
se.pages.SwitchToPage("table-editor")
|
|
})
|
|
|
|
form.AddButton("Delete", func() {
|
|
se.showDeleteColumnConfirm(schemaIndex, tableIndex, originalName)
|
|
})
|
|
|
|
form.AddButton("Back", func() {
|
|
// Discard changes - don't apply them
|
|
se.pages.RemovePage("column-editor")
|
|
se.pages.SwitchToPage("table-editor")
|
|
})
|
|
|
|
form.SetBorder(true).SetTitle(" Edit Column ").SetTitleAlign(tview.AlignLeft)
|
|
form.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
|
if event.Key() == tcell.KeyEscape {
|
|
se.showExitConfirmation("column-editor", "table-editor")
|
|
return nil
|
|
}
|
|
return event
|
|
})
|
|
|
|
se.pages.AddPage("column-editor", form, true, true)
|
|
}
|
|
|
|
// showNewColumnDialog shows dialog to create a new column
|
|
func (se *SchemaEditor) showNewColumnDialog(schemaIndex, tableIndex int) {
|
|
form := tview.NewForm()
|
|
|
|
columnName := ""
|
|
dataType := "VARCHAR(255)"
|
|
|
|
// Column type options: PostgreSQL, MySQL, SQL Server, and common SQL types
|
|
columnTypes := []string{
|
|
// Numeric Types
|
|
"SMALLINT", "INTEGER", "BIGINT", "INT", "TINYINT", "FLOAT", "REAL", "DOUBLE PRECISION",
|
|
"DECIMAL(10,2)", "NUMERIC", "DECIMAL", "NUMERIC(10,2)",
|
|
// Character Types
|
|
"CHAR", "VARCHAR", "VARCHAR(255)", "TEXT", "NCHAR", "NVARCHAR", "NVARCHAR(255)",
|
|
// Boolean
|
|
"BOOLEAN", "BOOL", "BIT",
|
|
// Date/Time Types
|
|
"DATE", "TIME", "TIMESTAMP", "TIMESTAMP WITH TIME ZONE", "INTERVAL",
|
|
"DATETIME", "DATETIME2", "DATEFIRST",
|
|
// UUID and JSON
|
|
"UUID", "GUID", "JSON", "JSONB",
|
|
// Binary Types
|
|
"BYTEA", "BLOB", "IMAGE", "VARBINARY", "VARBINARY(MAX)", "BINARY",
|
|
// PostgreSQL Special Types
|
|
"int4range", "int8range", "numrange", "tsrange", "tstzrange", "daterange",
|
|
"HSTORE", "CITEXT", "INET", "MACADDR", "POINT", "LINE", "LSEG", "BOX", "PATH", "POLYGON", "CIRCLE",
|
|
// Array Types
|
|
"INTEGER ARRAY", "VARCHAR ARRAY", "TEXT ARRAY", "BIGINT ARRAY",
|
|
// MySQL Specific
|
|
"MEDIUMINT", "DOUBLE", "FLOAT(10,2)",
|
|
// SQL Server Specific
|
|
"MONEY", "SMALLMONEY", "SQL_VARIANT",
|
|
}
|
|
selectedTypeIndex := 0
|
|
|
|
form.AddInputField("Column Name", "", 40, nil, func(value string) {
|
|
columnName = value
|
|
})
|
|
|
|
form.AddDropDown("Data Type", columnTypes, selectedTypeIndex, func(option string, index int) {
|
|
dataType = option
|
|
})
|
|
|
|
form.AddCheckbox("Primary Key", false, nil)
|
|
form.AddCheckbox("Not Null", false, nil)
|
|
form.AddCheckbox("Unique", false, nil)
|
|
|
|
form.AddButton("Save", func() {
|
|
if columnName == "" {
|
|
return
|
|
}
|
|
|
|
// Get form values
|
|
isPK := form.GetFormItemByLabel("Primary Key").(*tview.Checkbox).IsChecked()
|
|
isNotNull := form.GetFormItemByLabel("Not Null").(*tview.Checkbox).IsChecked()
|
|
|
|
se.CreateColumn(schemaIndex, tableIndex, columnName, dataType, isPK, isNotNull)
|
|
|
|
table := se.db.Schemas[schemaIndex].Tables[tableIndex]
|
|
se.pages.RemovePage("new-column")
|
|
se.pages.RemovePage("table-editor")
|
|
se.showTableEditor(schemaIndex, tableIndex, table)
|
|
})
|
|
|
|
form.AddButton("Back", func() {
|
|
table := se.db.Schemas[schemaIndex].Tables[tableIndex]
|
|
se.pages.RemovePage("new-column")
|
|
se.pages.RemovePage("table-editor")
|
|
se.showTableEditor(schemaIndex, tableIndex, table)
|
|
})
|
|
|
|
form.SetBorder(true).SetTitle(" New Column ").SetTitleAlign(tview.AlignLeft)
|
|
form.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
|
if event.Key() == tcell.KeyEscape {
|
|
se.showExitConfirmation("new-column", "table-editor")
|
|
return nil
|
|
}
|
|
return event
|
|
})
|
|
|
|
se.pages.AddPage("new-column", form, true, true)
|
|
}
|