Skip to content

Commit

Permalink
Merge pull request #110 from jorgerojas26/set-value-modal
Browse files Browse the repository at this point in the history
Add support for NULL, EMPTY and DEFAULT values
  • Loading branch information
jorgerojas26 authored Oct 27, 2024
2 parents 44619e6 + 9bbda7b commit cc376a9
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 63 deletions.
2 changes: 2 additions & 0 deletions app/Keymap.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ var Keymaps = KeymapSystem{
Bind{Key: Key{Char: 'o'}, Cmd: cmd.AppendNewRow, Description: "Append new row"},
Bind{Key: Key{Char: 'J'}, Cmd: cmd.SortDesc, Description: "Sort descending"},
Bind{Key: Key{Char: 'K'}, Cmd: cmd.SortAsc, Description: "Sort ascending"},
Bind{Key: Key{Char: 'C'}, Cmd: cmd.SetValue, Description: "Toggle value menu to put values like NULL, EMPTY or DEFAULT"},
// Tabs
Bind{Key: Key{Char: '['}, Cmd: cmd.TabPrev, Description: "Switch to previous tab"},
Bind{Key: Key{Char: ']'}, Cmd: cmd.TabNext, Description: "Switch to next tab"},
Expand Down Expand Up @@ -130,6 +131,7 @@ var Keymaps = KeymapSystem{
Bind{Key: Key{Char: 'c'}, Cmd: cmd.Edit, Description: "Edit field"},
Bind{Key: Key{Code: tcell.KeyEnter}, Cmd: cmd.CommitEdit, Description: "Add edit to pending changes"},
Bind{Key: Key{Code: tcell.KeyEscape}, Cmd: cmd.DiscardEdit, Description: "Discard edit"},
Bind{Key: Key{Char: 'C'}, Cmd: cmd.SetValue, Description: "Toggle value menu to put values like NULL, EMPTY or DEFAULT"},
},
},
}
4 changes: 4 additions & 0 deletions commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const (
PreviousFoundNode
TreeCollapseAll
ExpandAll
SetValue
FocusSidebar
UnfocusSidebar
ToggleSidebar
Expand Down Expand Up @@ -184,6 +185,8 @@ func (c Command) String() string {
return "TreeCollapseAll"
case ExpandAll:
return "ExpandAll"
case SetValue:
return "SetValue"
case FocusSidebar:
return "FocusSidebar"
case ToggleSidebar:
Expand All @@ -195,5 +198,6 @@ func (c Command) String() string {
case DiscardEdit:
return "DiscardEdit"
}

return "Unknown"
}
81 changes: 67 additions & 14 deletions components/ResultsTable.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func NewResultsTable(listOfDbChanges *[]models.DbDmlChange, tree *Tree, dbdriver

pagination := NewPagination()

sidebar := NewSidebar()
sidebar := NewSidebar(dbdriver.GetProvider())

table := &ResultsTable{
Table: tview.NewTable(),
Expand Down Expand Up @@ -221,7 +221,7 @@ func (table *ResultsTable) subscribeToSidebarChanges() {
tableCell.SetText(params.NewValue)

cellValue := models.CellValue{
Type: models.String,
Type: params.Type,
Column: params.ColumnName,
Value: params.NewValue,
TableColumnIndex: changedColumnIndex,
Expand All @@ -240,11 +240,17 @@ func (table *ResultsTable) AddRows(rows [][]string) {
for i, row := range rows {
for j, cell := range row {
tableCell := tview.NewTableCell(cell)
tableCell.SetTextColor(app.Styles.PrimaryTextColor)

if cell == "EMPTY&" || cell == "NULL&" || cell == "DEFAULT&" {
tableCell.SetText(strings.Replace(cell, "&", "", 1))
tableCell.SetStyle(table.GetItalicStyle())
tableCell.SetReference(cell)
}

tableCell.SetSelectable(i > 0)
tableCell.SetExpansion(1)

tableCell.SetTextColor(app.Styles.PrimaryTextColor)

table.SetCell(i, j, tableCell)
}
}
Expand Down Expand Up @@ -278,7 +284,7 @@ func (table *ResultsTable) AddInsertedRows() {
tableCell.SetExpansion(1)
tableCell.SetReference(inserts[i].PrimaryKeyValue)

tableCell.SetTextColor(tcell.ColorWhite.TrueColor())
tableCell.SetTextColor(app.Styles.PrimaryTextColor)
tableCell.SetBackgroundColor(colorTableInsert)

table.SetCell(rowIndex, j, tableCell)
Expand All @@ -295,13 +301,15 @@ func (table *ResultsTable) AppendNewRow(cells []models.CellValue, index int, UUI
tableCell.SetBackgroundColor(tcell.ColorDarkGreen)

switch cell.Type {
case models.Null:
case models.Default:
case models.String:
tableCell.SetText("")
case models.Null, models.Empty, models.Default:
tableCell.SetText(strings.Replace(cell.Value.(string), "&", "", 1))
tableCell.SetStyle(table.GetItalicStyle())
// tableCell.SetText("")

tableCell.SetTextColor(app.Styles.InverseTextColor)
}

tableCell.SetBackgroundColor(colorTableInsert)
table.SetCell(index, i, tableCell)
}

Expand Down Expand Up @@ -400,7 +408,7 @@ func (table *ResultsTable) tableInputCapture(event *tcell.EventKey) *tcell.Event
for i, insertedRow := range *table.state.listOfDbChanges {
cellReference := table.GetCell(selectedRowIndex, 0).GetReference()

if cellReference != nil && insertedRow.PrimaryKeyValue == cellReference.(string) {
if cellReference != nil && insertedRow.PrimaryKeyValue == cellReference {
isAnInsertedRow = true
indexOfInsertedRow = i
}
Expand All @@ -421,6 +429,24 @@ func (table *ResultsTable) tableInputCapture(event *tcell.EventKey) *tcell.Event
}

}
} else if command == commands.SetValue {
table.SetIsEditing(true)
table.SetInputCapture(nil)

cell := table.GetCell(selectedRowIndex, selectedColumnIndex)
x, y, _ := cell.GetLastPosition()

list := NewSetValueList(table.DBDriver.GetProvider())

list.OnFinish(func(selection models.CellValueType, value string) {
table.FinishSettingValue()

if selection >= 0 {
table.AppendNewChange(models.DmlUpdateType, selectedRowIndex, selectedColumnIndex, models.CellValue{Type: selection, Value: value, Column: table.GetColumnNameByIndex(selectedColumnIndex)})
}
})

list.Show(x, y, 30)
} else if command == commands.ToggleSidebar {
table.ShowSidebar(!table.GetShowSidebar())
} else if command == commands.FocusSidebar {
Expand Down Expand Up @@ -471,7 +497,13 @@ func (table *ResultsTable) UpdateRowsColor(headerColor tcell.Color, rowColor tce
if i == 0 && headerColor != 0 {
cell.SetTextColor(headerColor)
} else {
cell.SetTextColor(rowColor)
cellReference := cell.GetReference()

if cellReference != nil && (cellReference == "EMPTY&" || cellReference == "NULL&" || cellReference == "DEFAULT&") && (cell.BackgroundColor != colorTableDelete && cell.BackgroundColor != colorTableChange && cell.BackgroundColor != colorTableInsert) {
cell.SetStyle(table.GetItalicStyle())
} else {
cell.SetTextColor(rowColor)
}
}
}
}
Expand Down Expand Up @@ -563,6 +595,7 @@ func (table *ResultsTable) subscribeToEditorChanges() {
if strings.Contains(queryLower, "select") {
table.SetLoading(true)
App.Draw()

rows, err := table.DBDriver.ExecuteQuery(query)
table.Pagination.SetTotalRecords(len(rows))
table.Pagination.SetLimit(len(rows))
Expand Down Expand Up @@ -992,7 +1025,7 @@ func (table *ResultsTable) AppendNewChange(changeType models.DmlType, rowIndex i
tableCell := table.GetCell(rowIndex, colIndex)
tableCellReference := tableCell.GetReference()

isAnInsertedRow := tableCellReference != nil
isAnInsertedRow := tableCellReference != nil && tableCellReference.(string) != "NULL&" && tableCellReference.(string) != "EMPTY&" && tableCellReference.(string) != "DEFAULT&"

if isAnInsertedRow {
table.MutateInsertedRowCell(tableCellReference.(string), value)
Expand All @@ -1001,6 +1034,15 @@ func (table *ResultsTable) AppendNewChange(changeType models.DmlType, rowIndex i

primaryKeyValue, primaryKeyColumnName := table.GetPrimaryKeyValue(rowIndex)

if changeType == models.DmlUpdateType {
switch value.Type {
case models.Null, models.Empty, models.Default:
tableCell.SetText(value.Value.(string))
tableCell.SetStyle(tcell.StyleDefault.Italic(true))
tableCell.SetReference(value.Value.(string) + "&")
}
}

for i, dmlChange := range *table.state.listOfDbChanges {
if dmlChange.Table == tableName && dmlChange.Type == changeType && dmlChange.PrimaryKeyValue == primaryKeyValue {
dmlChangeAlreadyExists = true
Expand Down Expand Up @@ -1046,10 +1088,11 @@ func (table *ResultsTable) AppendNewChange(changeType models.DmlType, rowIndex i
if !dmlChangeAlreadyExists {

switch changeType {
case models.DmlUpdateType:
table.SetCellColor(rowIndex, colIndex, colorTableChange)
case models.DmlDeleteType:
table.SetRowColor(rowIndex, colorTableDelete)
case models.DmlUpdateType:
tableCell.SetStyle(tcell.StyleDefault.Background(colorTableChange))
table.SetCellColor(rowIndex, colIndex, colorTableChange)
}

newDmlChange := models.DbDmlChange{
Expand Down Expand Up @@ -1305,6 +1348,16 @@ func (table *ResultsTable) search() {
table.SetInputCapture(nil)
}

func (table *ResultsTable) FinishSettingValue() {
table.SetIsEditing(false)
table.SetInputCapture(table.tableInputCapture)
App.SetFocus(table)
}

func (table *ResultsTable) GetItalicStyle() tcell.Style {
return tcell.StyleDefault.Foreground(tview.Styles.InverseTextColor).Italic(true)
}

func (table *ResultsTable) ShowSidebar(show bool) {
table.state.showSidebar = show

Expand Down
90 changes: 90 additions & 0 deletions components/SetValueList.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package components

import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"

"github.com/jorgerojas26/lazysql/app"
"github.com/jorgerojas26/lazysql/commands"
"github.com/jorgerojas26/lazysql/drivers"
"github.com/jorgerojas26/lazysql/models"
)

type SetValueList struct {
*tview.List
}

type value struct {
value string
key rune
}

var VALUES = []value{}

func NewSetValueList(dbProvider string) *SetValueList {
list := tview.NewList()
list.SetBorder(true)

if dbProvider == drivers.DriverSqlite {
VALUES = []value{
{value: "NULL", key: 'n'},
{value: "EMPTY", key: 'e'},
}
} else {
VALUES = []value{
{value: "NULL", key: 'n'},
{value: "EMPTY", key: 'e'},
{value: "DEFAULT", key: 'd'},
}
}

for _, value := range VALUES {
list.AddItem(value.value, "", value.key, nil)
}

return &SetValueList{List: list}
}

func (list *SetValueList) OnFinish(callback func(selection models.CellValueType, value string)) {
list.SetDoneFunc(func() {
list.Hide()
callback(-1, "")
})

list.SetSelectedFunc(func(_ int, _ string, _ string, shortcut rune) {
list.Hide()
switch shortcut {
case 'n':
callback(models.Null, "NULL")
case 'e':
callback(models.Empty, "EMPTY")
case 'd':
callback(models.Default, "DEFAULT")
}
})

list.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
command := app.Keymaps.Group(app.TableGroup).Resolve(event)

if command == commands.SetValue {
list.Hide()
callback(-1, "")
return nil
}

return event
})
}

func (list *SetValueList) Show(x, y, width int) {
list.SetRect(x, y, width, len(VALUES)*2+1)
MainPages.AddPage(pageNameSetValue, list, false, true)
App.SetFocus(list)
App.ForceDraw()
}

func (list *SetValueList) Hide() {
MainPages.RemovePage(pageNameSetValue)
App.SetFocus(list)
App.ForceDraw()
}
33 changes: 31 additions & 2 deletions components/Sidebar.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
)

type SidebarState struct {
dbProvider string
currentFieldIndex int
}

Expand All @@ -28,7 +29,7 @@ type Sidebar struct {
subscribers []chan models.StateChange
}

func NewSidebar() *Sidebar {
func NewSidebar(dbProvider string) *Sidebar {
flex := tview.NewFlex().SetDirection(tview.FlexColumnCSS)
frame := tview.NewFrame(flex)
frame.SetBackgroundColor(app.Styles.PrimitiveBackgroundColor)
Expand All @@ -37,6 +38,7 @@ func NewSidebar() *Sidebar {

sidebarState := &SidebarState{
currentFieldIndex: 0,
dbProvider: dbProvider,
}

newSidebar := &Sidebar{
Expand Down Expand Up @@ -242,7 +244,7 @@ func (sidebar *Sidebar) inputCapture(event *tcell.EventKey) *tcell.EventKey {
sidebar.SetDisabledStyles(item)
} else {
sidebar.SetEditedStyles(item)
sidebar.Publish(models.StateChange{Key: eventSidebarCommitEditing, Value: models.SidebarEditingCommitParams{ColumnName: columnName, NewValue: newText}})
sidebar.Publish(models.StateChange{Key: eventSidebarCommitEditing, Value: models.SidebarEditingCommitParams{ColumnName: columnName, Type: models.String, NewValue: newText}})
}

return nil
Expand All @@ -259,6 +261,33 @@ func (sidebar *Sidebar) inputCapture(event *tcell.EventKey) *tcell.EventKey {

sidebar.EditTextCurrentField()

return nil
case commands.SetValue:
currentItemIndex := sidebar.GetCurrentFieldIndex()
item := sidebar.Flex.GetItem(currentItemIndex).(*tview.TextArea)
x, y, _, _ := item.GetRect()

columnName := item.GetTitle()
columnNameSplit := strings.Split(columnName, "[")
columnName = columnNameSplit[0]

list := NewSetValueList(sidebar.state.dbProvider)

sidebar.Publish(models.StateChange{Key: eventSidebarEditing, Value: true})

list.OnFinish(func(selection models.CellValueType, value string) {
sidebar.Publish(models.StateChange{Key: eventSidebarEditing, Value: false})
App.SetFocus(item)

if selection >= 0 {
sidebar.SetEditedStyles(item)
item.SetText(value, true)
sidebar.Publish(models.StateChange{Key: eventSidebarCommitEditing, Value: models.SidebarEditingCommitParams{ColumnName: columnName, Type: selection, NewValue: value}})
}
})

list.Show(x, y, 30)

return nil
}
return event
Expand Down
3 changes: 3 additions & 0 deletions components/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const (
// Connections
pageNameConnectionSelection string = "ConnectionSelection"
pageNameConnectionForm string = "ConnectionForm"

// SetValueList
pageNameSetValue string = "SetValue"
)

// Tabs
Expand Down
Loading

0 comments on commit cc376a9

Please sign in to comment.