-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcompletion.go
129 lines (110 loc) · 2.79 KB
/
completion.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package main
import (
"strings"
"github.com/c-bata/go-prompt"
"github.com/jmoiron/sqlx"
)
type completer struct {
db *sqlx.DB
dbType string
dbName string
keywordsSuggests []prompt.Suggest
tablesSuggests []prompt.Suggest
columnsSuggests []prompt.Suggest
}
func newCompleter(db *sqlx.DB, dbType, dbName string) *completer {
return &completer{
db: db,
dbName: dbName,
dbType: dbType,
}
}
func (c *completer) init() {
for k := range keywords {
c.keywordsSuggests = append(c.keywordsSuggests, prompt.Suggest{
Text: k,
Description: "keyword",
})
}
if c.dbType == "mysql" {
c.initMysql()
} else {
c.initPostgres()
}
}
func (c *completer) initMysql() {
var tableNames []string
_ = c.db.Select(&tableNames, `show tables`)
for _, t := range tableNames {
c.tablesSuggests = append(c.tablesSuggests, prompt.Suggest{
Text: t,
Description: "table",
})
}
var columns []struct {
Column string `db:"column_name"`
Table string `db:"table_name"`
}
_ = c.db.Select(&columns, `SELECT column_name as column_name, table_name as table_name
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ?`, c.dbName)
for _, co := range columns {
c.columnsSuggests = append(c.columnsSuggests, prompt.Suggest{
Text: co.Column,
Description: co.Table,
})
}
}
func (c *completer) initPostgres() {
var tableNames []string
_ = c.db.Select(&tableNames, `SELECT tablename
FROM pg_catalog.pg_tables
WHERE schemaname != 'pg_catalog'
AND schemaname != 'information_schema'`)
for _, t := range tableNames {
c.tablesSuggests = append(c.tablesSuggests, prompt.Suggest{
Text: t,
Description: "table",
})
}
var columns []struct {
Column string `db:"column_name"`
Table string `db:"table_name"`
}
_ = c.db.Select(&columns,
`SELECT column_name, table_name
FROM information_schema.columns
WHERE table_schema != 'pg_catalog'
AND table_schema != 'information_schema'`)
for _, co := range columns {
c.columnsSuggests = append(c.columnsSuggests, prompt.Suggest{
Text: co.Column,
Description: co.Table,
})
}
}
func (c *completer) suggest(d prompt.Document) []prompt.Suggest {
currentLine := d.CurrentLine()
if currentLine == "" {
return nil
}
fields := strings.Fields(currentLine)
var lastKeyword string
for i := len(fields) - 1; i >= 0; i-- {
if _, ok := keywords[strings.ToUpper(fields[i])]; ok {
lastKeyword = strings.ToUpper(fields[i])
break
}
}
var s []prompt.Suggest
switch lastKeyword {
case "SELECT", "WHERE":
s = append(s, c.columnsSuggests...)
case "FROM", "INTO", "DESCRIBE":
s = append(s, c.tablesSuggests...)
default:
}
s = append(s, c.keywordsSuggests...)
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}
var tableNames []string
var columns []string