Compare commits

..

2 Commits

Author SHA1 Message Date
e1375f237c Consider return code when checking if command was already printed 2022-09-27 17:01:20 +02:00
ac9aab63bd Change 'timestamp' to simple unix epoch
Subjectively, 6d4e7a96dc increases
lag on a years-old production database with ~240k entries when searching
with CTRL+R.

So change timestamp column from datetime type (which is a string)
to integer, storing unix epoch now. As we deal with those primarily,
we also avoid conversions now.

Mentioned database shrinks by 2MB compared to previously (both VACCUMed)...

DROP unused count_by_date VIEW.
2021-09-28 18:27:39 +02:00

17
main.go
View File

@ -66,6 +66,11 @@ func migrateDatabase(conn *sql.DB, currentVersion int) {
migrations := []string{ migrations := []string{
"ALTER TABLE history ADD COLUMN workdir varchar(4096) DEFAULT ''", "ALTER TABLE history ADD COLUMN workdir varchar(4096) DEFAULT ''",
"ALTER TABLE history ADD COLUMN retval integer DEFAULT -9001", "ALTER TABLE history ADD COLUMN retval integer DEFAULT -9001",
"ALTER TABLE history ADD COLUMN unix_tmp integer",
"UPDATE history SET unix_tmp = strftime('%s', timestamp)",
"DROP VIEW count_by_date",
"ALTER TABLE history DROP COLUMN timestamp",
"ALTER TABLE history RENAME COLUMN unix_tmp TO timestamp",
} }
if !(len(migrations) > currentVersion) { if !(len(migrations) > currentVersion) {
@ -164,7 +169,7 @@ type searchopts struct {
func search(conn *sql.DB, opts searchopts) list.List { func search(conn *sql.DB, opts searchopts) list.List {
args := make([]interface{}, 0) args := make([]interface{}, 0)
var sb strings.Builder var sb strings.Builder
sb.WriteString("SELECT id, command, workdir, user, hostname, retval, strftime(\"%s\", timestamp) ") sb.WriteString("SELECT id, command, workdir, user, hostname, retval, timestamp ")
sb.WriteString("FROM history ") sb.WriteString("FROM history ")
sb.WriteString("WHERE 1=1 ") //1=1 so we can append as many AND foo as we want, or none sb.WriteString("WHERE 1=1 ") //1=1 so we can append as many AND foo as we want, or none
@ -177,11 +182,11 @@ func search(conn *sql.DB, opts searchopts) list.List {
args = append(args, opts.workdir) args = append(args, opts.workdir)
} }
if opts.after != nil { if opts.after != nil {
sb.WriteString("AND timestamp > datetime(?, 'unixepoch') ") sb.WriteString("AND timestamp > ? ")
args = append(args, opts.after.Unix()) args = append(args, opts.after.Unix())
} }
if opts.before != nil { if opts.before != nil {
sb.WriteString("AND timestamp < datetime(?, 'unixepoch') ") sb.WriteString("AND timestamp < ? ")
args = append(args, opts.before.Unix()) args = append(args, opts.before.Unix())
} }
if opts.retval != nil { if opts.retval != nil {
@ -234,7 +239,7 @@ func delete(conn *sql.DB, entryId uint32) {
} }
func add(conn *sql.DB, entry HistoryEntry) { func add(conn *sql.DB, entry HistoryEntry) {
stmt, err := conn.Prepare("INSERT INTO history (user, command, hostname, workdir, timestamp, retval) VALUES (?, ?, ?, ?, datetime(?, 'unixepoch'),?)") stmt, err := conn.Prepare("INSERT INTO history (user, command, hostname, workdir, timestamp, retval) VALUES (?, ?, ?, ?, ?,?)")
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
@ -406,6 +411,7 @@ func main() {
results := search(conn, opts) results := search(conn, opts)
previousCmd := "" previousCmd := ""
previousReturn := -1
fi, err := os.Stdout.Stat() fi, err := os.Stdout.Stat()
if err != nil { if err != nil {
@ -423,7 +429,7 @@ func main() {
if !ok { if !ok {
log.Panic("Failed to retrieve entries") log.Panic("Failed to retrieve entries")
} }
if !distinct || previousCmd != entry.cmd { if !distinct || !(previousCmd == entry.cmd && previousReturn == entry.retval) {
prefix := "" prefix := ""
postfix := "" postfix := ""
if printColors && entry.retval != 0 { if printColors && entry.retval != 0 {
@ -433,6 +439,7 @@ func main() {
fmt.Printf("%s%s%s\n", prefix, entry.cmd, postfix) fmt.Printf("%s%s%s\n", prefix, entry.cmd, postfix)
} }
previousCmd = entry.cmd previousCmd = entry.cmd
previousReturn = entry.retval
} }
if cmd == "delete" { if cmd == "delete" {