Skip to content

Commit

Permalink
test(client): add a test function to validate the TableStructure method
Browse files Browse the repository at this point in the history
46
  • Loading branch information
danvergara committed Jun 10, 2021
1 parent 5a032a4 commit a83cfe7
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 6 deletions.
48 changes: 46 additions & 2 deletions pkg/client/client.go
@@ -1,6 +1,7 @@
package client

import (
"errors"
"fmt"

// mysql driver.
Expand Down Expand Up @@ -39,11 +40,11 @@ func New(opts command.Options) (*Client, error) {
}

// Query returns performs the query and returns the result set and the colum names.
func (c *Client) Query(q string) ([][]string, []string, error) {
func (c *Client) Query(q string, args ...interface{}) ([][]string, []string, error) {
resultSet := [][]string{}

// Runs the query extracting the content of the view calling the Buffer method.
rows, err := c.db.Queryx(q)
rows, err := c.db.Queryx(q, args...)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -126,6 +127,49 @@ func (c *Client) TableContent(tableName string) ([][]string, []string, error) {
return c.Query(query)
}

// TableStructure returns the structure of the table columns.
func (c *Client) TableStructure(tableName string) ([][]string, []string, error) {
var query string

switch c.driver {
case "postgres":
fallthrough
case "postgresql":
query = `
SELECT
c.column_name,
c.is_nullable,
c.data_type,
c.character_maximum_length,
c.numeric_precision,
c.numeric_scale,
c.ordinal_position,
tc.constraint_type pkey
FROM
information_schema.columns c
LEFT JOIN
information_schema.constraint_column_usage AS ccu
ON
c.table_schema = ccu.table_schema
AND c.table_name = ccu.table_name
AND c.column_name = ccu.column_name
LEFT JOIN
information_schema.table_constraints AS tc
ON
ccu.constraint_schema = tc.constraint_schema
and ccu.constraint_name = tc.constraint_name
WHERE
c.table_schema = 'public'
AND c.table_name = $1;`
return c.Query(query, tableName)
case "mysql":
query = fmt.Sprintf("DESCRIBE %s;", tableName)
return c.Query(query)
default:
return nil, nil, errors.New("not supported driver")
}
}

// DB Return the db attribute.
func (c *Client) DB() *sqlx.DB {
return c.db
Expand Down
26 changes: 25 additions & 1 deletion pkg/client/client_test.go
Expand Up @@ -156,7 +156,7 @@ func TestTableContent(t *testing.T) {

c, _ := New(opts)

r, co, err := c.TableContent("products;")
r, co, err := c.TableContent("products")

assert.Equal(t, 100, len(r))
assert.Equal(t, 3, len(co))
Expand Down Expand Up @@ -185,3 +185,27 @@ func TestShowTables(t *testing.T) {
assert.Equal(t, 4, len(tables))
assert.NoError(t, err)
}

func TestTableStructure(t *testing.T) {
if testing.Short() {
t.Skip("skipping short mode")
}

opts := command.Options{
Driver: driver,
User: user,
Pass: password,
Host: host,
Port: port,
DBName: name,
SSL: "disable",
}

c, _ := New(opts)

r, co, err := c.TableStructure("products")

assert.Equal(t, 3, len(r))
assert.Equal(t, 8, len(co))
assert.NoError(t, err)
}
32 changes: 32 additions & 0 deletions pkg/gui/database_helpers.go
Expand Up @@ -96,3 +96,35 @@ func (gui *Gui) selectTable(g *gocui.Gui, v *gocui.View) error {

return nil
}

func (gui *Gui) renderStructure(g *gocui.Gui, v *gocui.View) error {
v.Rewind()

_, cy := v.Cursor()

t, err := v.Line(cy)
if err != nil {
return err
}

resultSet, columnNames, err := gui.c.TableStructure(t)
if err != nil {
return err
}

ov, err := gui.g.View("structure")
if err != nil {
return err
}

// Cleans the view.
ov.Clear()

if err := ov.SetCursor(0, 0); err != nil {
return err
}

renderTable(ov, columnNames, resultSet)

return nil
}
46 changes: 43 additions & 3 deletions pkg/gui/keybindings.go
Expand Up @@ -14,33 +14,49 @@ func (gui *Gui) keybindings() error {
return err
}

if err := gui.g.SetKeybinding("query", gocui.KeyCtrlJ, gocui.ModNone, nextView("query", "rows")); err != nil {
if err := gui.g.SetKeybinding("query", gocui.KeyCtrlJ, gocui.ModNone, moveDown); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", gocui.KeyCtrlK, gocui.ModNone, nextView("rows", "query")); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", gocui.KeyCtrlH, gocui.ModNone, nextView("rows", "tables")); err != nil {
return err
}

if err := gui.g.SetKeybinding("structure", gocui.KeyCtrlH, gocui.ModNone, nextView("structure", "tables")); err != nil {
return err
}

if err := gui.g.SetKeybinding("structure", gocui.KeyCtrlK, gocui.ModNone, nextView("structure", "query")); err != nil {
return err
}

// SQL helpers
if err := gui.g.SetKeybinding("query", gocui.KeyCtrlSpace, gocui.ModNone, gui.inputQuery()); err != nil {
return err
}

if err := gui.g.SetKeybinding("tables", gocui.KeyEnter, gocui.ModNone, gui.renderStructure); err != nil {
return err
}

if err := gui.g.SetKeybinding("tables", gocui.KeyEnter, gocui.ModNone, gui.selectTable); err != nil {
return err
}

// navigation directives for the tables panel.
if err := gui.g.SetKeybinding("tables", gocui.KeyCtrlK, gocui.ModNone, cursorUp); err != nil {
if err := gui.g.SetKeybinding("tables", 'k', gocui.ModNone, cursorUp); err != nil {
return err
}

if err := gui.g.SetKeybinding("tables", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil {
return err
}

if err := gui.g.SetKeybinding("tables", gocui.KeyCtrlJ, gocui.ModNone, cursorDown); err != nil {
if err := gui.g.SetKeybinding("tables", 'j', gocui.ModNone, cursorDown); err != nil {
return err
}

Expand All @@ -53,18 +69,42 @@ func (gui *Gui) keybindings() error {
return err
}

if err := gui.g.SetKeybinding("rows", 'k', gocui.ModNone, cursorUp); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", 'j', gocui.ModNone, cursorDown); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", gocui.KeyArrowRight, gocui.ModNone, cursorRight); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", 'l', gocui.ModNone, cursorRight); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", gocui.KeyArrowLeft, gocui.ModNone, cursorLeft); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", 'h', gocui.ModNone, cursorLeft); err != nil {
return err
}

if err := gui.g.SetKeybinding("structure", gocui.KeyCtrlS, gocui.ModNone, setViewOnTop); err != nil {
return err
}

if err := gui.g.SetKeybinding("rows", gocui.KeyCtrlS, gocui.ModNone, setViewOnTop); err != nil {
return err
}

// quit function event.
if err := gui.g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
return err
Expand Down

0 comments on commit a83cfe7

Please sign in to comment.