Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NULL, EMPTY and DEFAULT values #110

Merged
merged 12 commits into from
Oct 27, 2024
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