Introduce HistoryEntry struct ; refactor search and delete

This commit is contained in:
Albert S. 2021-04-05 12:49:13 +02:00
parent 776dcebb04
commit 88362e99a9
1 changed files with 57 additions and 29 deletions

86
main.go
View File

@ -2,6 +2,7 @@ package main
import ( import (
"bufio" "bufio"
"container/list"
"database/sql" "database/sql"
"flag" "flag"
"fmt" "fmt"
@ -14,6 +15,14 @@ import (
_ "modernc.org/sqlite" _ "modernc.org/sqlite"
) )
type HistoryEntry struct {
id uint32
cmd string
cwd string
hostname string
user string
}
func databaseLocation() string { func databaseLocation() string {
envOverride := os.Getenv("HS9001_DB_PATH") envOverride := os.Getenv("HS9001_DB_PATH")
if envOverride != "" { if envOverride != "" {
@ -109,38 +118,34 @@ func importFromStdin(conn *sql.DB) {
} }
} }
func search(conn *sql.DB, q string) { func search(conn *sql.DB, q string) list.List {
queryStmt := "SELECT command FROM history WHERE command LIKE ? ORDER BY timestamp ASC" queryStmt := "SELECT id, command, workdir, user, hostname FROM history WHERE command LIKE ? ORDER BY timestamp ASC"
rows, err := conn.Query(queryStmt, "%"+q+"%") rows, err := conn.Query(queryStmt, "%"+q+"%")
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
var result list.List
defer rows.Close() defer rows.Close()
for rows.Next() { for rows.Next() {
var command string var entry HistoryEntry
err = rows.Scan(&command) err = rows.Scan(&entry.id, &entry.cmd, &entry.cwd, &entry.user, &entry.hostname)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
fmt.Printf("%s\n", command) result.PushBack(&entry)
} }
return result
} }
func delete(conn *sql.DB, q string) { func delete(conn *sql.DB, entryId uint32) {
queryStmt := "DELETE FROM history WHERE command LIKE ?" queryStmt := "DELETE FROM history WHERE id = ?"
_, err := conn.Exec(queryStmt, "%"+q+"%") _, err := conn.Exec(queryStmt, entryId)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
_, err = conn.Exec("VACUUM")
if err != nil {
log.Panic(err)
}
} }
func add(conn *sql.DB, cmd string, cwd string) { func add(conn *sql.DB, cmd string, cwd string) {
@ -192,7 +197,6 @@ func printUsage() {
func main() { func main() {
addCmd := flag.NewFlagSet("add", flag.ExitOnError) addCmd := flag.NewFlagSet("add", flag.ExitOnError)
searchCmd := flag.NewFlagSet("search", flag.ExitOnError) searchCmd := flag.NewFlagSet("search", flag.ExitOnError)
deleteCmd := flag.NewFlagSet("delete", flag.ExitOnError)
if len(os.Args) < 2 { if len(os.Args) < 2 {
printUsage() printUsage()
@ -242,31 +246,55 @@ func main() {
} }
add(conn, rs[1], wd) add(conn, rs[1], wd)
} }
case "search": case "search": fallthrough;
case "delete":
searchCmd.Parse(globalargs) searchCmd.Parse(globalargs)
args := searchCmd.Args() args := searchCmd.Args()
if len(args) < 1 { if len(args) < 1 {
fmt.Fprint(os.Stderr, "Please provide the search query\n") fmt.Fprint(os.Stderr, "Please provide the query\n")
os.Exit(1) os.Exit(1)
} }
q := strings.Join(args, " ") q := strings.Join(args, " ")
search(conn, q) results := search(conn, q)
os.Exit(23)
case "delete": for e := results.Front(); e != nil; e = e.Next() {
deleteCmd.Parse(globalargs) entry, ok := e.Value.(*HistoryEntry)
args := deleteCmd.Args() if !ok {
if len(args) < 1 { log.Panic("Failed to retrieve entries")
fmt.Fprint(os.Stderr, "Error: You need to provide a search query for records to delete") }
fmt.Printf("%s\n", entry.cmd)
}
if cmd == "delete" {
_, err := conn.Exec("BEGIN;")
if err != nil {
log.Panic(err)
}
for e := results.Front(); e != nil; e = e.Next() {
entry, ok := e.Value.(*HistoryEntry)
if !ok {
log.Panic("Failed to retrieve entries")
}
delete(conn, entry.id)
}
_, err = conn.Exec("END;")
if err != nil {
log.Panic(err)
}
_, err = conn.Exec("VACUUM")
if err != nil {
log.Panic(err)
}
} }
q := strings.Join(args, " ")
delete(conn, q)
//we do not want to leak what we just deleted :^)
os.Exit(23) os.Exit(23)
case "import": case "import":
importFromStdin(conn) importFromStdin(conn)
default: default: