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 // 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.AddButton("Save", func() { // Apply changes using dataops se.UpdateColumn(schemaIndex, tableIndex, originalName, newName, newType, newIsPK, newIsNotNull, newDefault, newDescription) 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) }