refactor search function. rename -being and -end to -after and -before

This commit is contained in:
lawl
2021-06-05 22:41:34 +02:00
부모 a2c4c99af4
커밋 e5c1beb937
2개의 변경된 파일78개의 추가작업 그리고 78개의 파일을 삭제

파일 보기

@ -2,14 +2,9 @@ package main
import ( import (
"database/sql" "database/sql"
"fmt"
"io" "io"
"log" "log"
"os"
"strings" "strings"
"time"
"github.com/tj/go-naturaldate"
) )
type history struct { type history struct {
@ -17,15 +12,11 @@ type history struct {
} }
func (h *history) GetHistoryByPrefix(prefix string) (ph []string) { func (h *history) GetHistoryByPrefix(prefix string) (ph []string) {
beginTimestamp, err := naturaldate.Parse("50 years ago", time.Now()) opts := searchopts{}
if err != nil { opts.order = "DESC"
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error()) cmdqry := prefix + "%"
} opts.command = &cmdqry
endTimeStamp, err := naturaldate.Parse("now", time.Now()) results := search(h.conn, opts)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error())
}
results := search(h.conn, prefix+"%", "%", beginTimestamp, endTimeStamp, -9001)
for e := results.Front(); e != nil; e = e.Next() { for e := results.Front(); e != nil; e = e.Next() {
entry, ok := e.Value.(*HistoryEntry) entry, ok := e.Value.(*HistoryEntry)
if !ok { if !ok {
@ -36,21 +27,16 @@ func (h *history) GetHistoryByPrefix(prefix string) (ph []string) {
return return
} }
func (h *history) GetHistoryByPattern(pattern string) (ph []string, pos []int) { func (h *history) GetHistoryByPattern(pattern string) (ph []string, pos []int) {
beginTimestamp, err := naturaldate.Parse("50 years ago", time.Now()) opts := searchopts{}
if err != nil { opts.order = "DESC"
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error()) cmdqry := "%" + pattern + "%"
} opts.command = &cmdqry
endTimeStamp, err := naturaldate.Parse("now", time.Now()) results := search(h.conn, opts)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error())
}
results := search(h.conn, "%"+pattern+"%", "%", beginTimestamp, endTimeStamp, -9001)
for e := results.Front(); e != nil; e = e.Next() { for e := results.Front(); e != nil; e = e.Next() {
entry, ok := e.Value.(*HistoryEntry) entry, ok := e.Value.(*HistoryEntry)
if !ok { if !ok {
log.Panic("Failed to retrieve entries") log.Panic("Failed to retrieve entries")
} }
//mt.Printf("\nAppending: [%s] %s -- %d\n", pattern, entry.cmd, strings.Index(entry.cmd, pattern))
ph = append(ph, entry.cmd) ph = append(ph, entry.cmd)
pos = append(pos, strings.Index(strings.ToLower(entry.cmd), strings.ToLower(pattern))) pos = append(pos, strings.Index(strings.ToLower(entry.cmd), strings.ToLower(pattern)))
} }

122
main.go
파일 보기

@ -150,28 +150,47 @@ func importFromStdin(conn *sql.DB) {
} }
} }
func search(conn *sql.DB, q string, workdir string, beginTime time.Time, endTime time.Time, retval int) list.List { type searchopts struct {
command *string
workdir *string
after *time.Time
before *time.Time
retval *int
order string
}
func search(conn *sql.DB, opts searchopts) list.List {
args := make([]interface{}, 0)
var sb strings.Builder var sb strings.Builder
sb.WriteString("SELECT id, command, workdir, user, hostname, retval ") sb.WriteString("SELECT id, command, workdir, user, hostname, retval ")
sb.WriteString("FROM history ") sb.WriteString("FROM history ")
sb.WriteString("WHERE timestamp BETWEEN datetime(?, 'unixepoch') ") sb.WriteString("WHERE 1=1 ") //1=1 so we can append as many AND foo as we want, or none
sb.WriteString("AND datetime(?, 'unixepoch') ")
sb.WriteString("AND command LIKE ? ") if opts.command != nil {
sb.WriteString("AND workdir LIKE ? ") sb.WriteString("AND command LIKE ? ")
if retval != -9001 { args = append(args, opts.command)
sb.WriteString("AND retval = ? ")
} }
sb.WriteString("ORDER BY timestamp ASC ") if opts.workdir != nil {
sb.WriteString("AND workdir LIKE ? ")
args = append(args, opts.workdir)
}
if opts.after != nil {
sb.WriteString("AND timestamp > datetime(?, 'unixepoch') ")
args = append(args, opts.after.Unix())
}
if opts.before != nil {
sb.WriteString("AND timestamp < datetime(?, 'unixepoch') ")
args = append(args, opts.before.Unix())
}
if opts.retval != nil {
sb.WriteString("AND retval = ? ")
args = append(args, opts.retval)
}
sb.WriteString("ORDER BY timestamp ")
sb.WriteString("ASC ")
queryStmt := sb.String() queryStmt := sb.String()
args := make([]interface{}, 0)
args = append(args, beginTime.Unix())
args = append(args, endTime.Unix())
args = append(args, q)
args = append(args, workdir)
if retval != -9001 {
args = append(args, retval)
}
rows, err := conn.Query(queryStmt, args...) rows, err := conn.Query(queryStmt, args...)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
@ -273,25 +292,6 @@ func main() {
defer line.Close() defer line.Close()
line.SetCtrlCAborts(true) line.SetCtrlCAborts(true)
line.SetHistoryProvider(&history{conn: conn}) line.SetHistoryProvider(&history{conn: conn})
line.SetCompleter(func(line string) (c []string) {
beginTimestamp, err := naturaldate.Parse("50 years ago", time.Now())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error())
}
endTimeStamp, err := naturaldate.Parse("now", time.Now())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error())
}
results := search(conn, "%"+line+"%", "%", beginTimestamp, endTimeStamp, -9001)
for e := results.Front(); e != nil; e = e.Next() {
entry, ok := e.Value.(*HistoryEntry)
if !ok {
log.Panic("Failed to retrieve entries")
}
c = append(c, entry.cmd)
}
return
})
rdlineline := os.Getenv("READLINE_LINE") rdlineline := os.Getenv("READLINE_LINE")
rdlinepos := os.Getenv("READLINE_POS") rdlinepos := os.Getenv("READLINE_POS")
@ -333,13 +333,13 @@ func main() {
fallthrough fallthrough
case "delete": case "delete":
var workDir string var workDir string
var beginTime string var afterTime string
var endTime string var beforeTime string
var distinct bool = true var distinct bool = true
var retVal int var retVal int
searchCmd.StringVar(&workDir, "cwd", "%", "Search only within this workdir") searchCmd.StringVar(&workDir, "cwd", "", "Search only within this workdir")
searchCmd.StringVar(&beginTime, "begin", "50 years ago", "Start searching from this timeframe") searchCmd.StringVar(&afterTime, "after", "", "Start searching from this timeframe")
searchCmd.StringVar(&endTime, "end", "now", "End searching from this timeframe") searchCmd.StringVar(&beforeTime, "before", "", "End searching from this timeframe")
searchCmd.BoolVar(&distinct, "distinct", true, "Remove consecutive duplicate commands from output") searchCmd.BoolVar(&distinct, "distinct", true, "Remove consecutive duplicate commands from output")
searchCmd.IntVar(&retVal, "ret", -9001, "Only query commands that returned with this exit code. -9001=all (default)") searchCmd.IntVar(&retVal, "ret", -9001, "Only query commands that returned with this exit code. -9001=all (default)")
@ -347,25 +347,39 @@ func main() {
args := searchCmd.Args() args := searchCmd.Args()
beginTimestamp, err := naturaldate.Parse(beginTime, time.Now())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error())
}
endTimeStamp, err := naturaldate.Parse(endTime, time.Now())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error())
}
q := strings.Join(args, " ") q := strings.Join(args, " ")
if workDir != "%" {
workDir, err = filepath.Abs(workDir) opts := searchopts{}
opts.order = "ASC"
if q != "" {
cmd := "%" + q + "%"
opts.command = &cmd
}
if workDir != "" {
wd, err := filepath.Abs(workDir)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Failed parse working directory path: %s\n", err.Error()) fmt.Fprintf(os.Stderr, "Failed parse working directory path: %s\n", err.Error())
} }
opts.workdir = &wd
} }
if afterTime != "" {
results := search(conn, "%"+q+"%", workDir, beginTimestamp, endTimeStamp, retVal) afterTimestamp, err := naturaldate.Parse(afterTime, time.Now())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error())
}
opts.after = &afterTimestamp
}
if beforeTime != "" {
beforeTimestamp, err := naturaldate.Parse(beforeTime, time.Now())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to convert time string: %s\n", err.Error())
}
opts.before = &beforeTimestamp
}
if retVal != -9001 {
opts.retval = &retVal
}
results := search(conn, opts)
previousCmd := "" previousCmd := ""
for e := results.Front(); e != nil; e = e.Next() { for e := results.Front(); e != nil; e = e.Next() {