Skip to content

Commit

Permalink
Merge pull request #1 from subsetpark/hashes
Browse files Browse the repository at this point in the history
Skip updates if checksum matches
  • Loading branch information
subsetpark authored Aug 14, 2017
2 parents e91aa4d + 28adf6c commit 2ecd171
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 33 deletions.
75 changes: 44 additions & 31 deletions usha.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,32 @@ import ushapkg/[db, logger]
const
programName = "usha"
help = """
hist: search your command-line history.
$1: search your command-line history.
Usage:
$1 init [-v]
$1 clean [DAYS]
$1 update [-v] CMD
$1 update [-v] CMD [-c CHECKSUM]
$1 [DIR] [-n N] [-tvrs SEARCHSTRING]
Options:
DIR Directory to search within.
CMD Insert command into database.
DAYS Number of days of history to preserve. [default: 60]
CMD Insert command into database.
DAYS Number of days of history to preserve. [default: 60]
-n N Retrieve the N most common commands. [default: 5]
-s SEARCHSTRING Search for commands containing a string.
-t Order by most recently entered.
-v Verbose.
-r Recurse current directory.
-c CHECKSUM Optional argument to update to prevent duplication.
""" % programName

proc filter(stopWords: HashSet[string], cmd: string): bool =
proc filter(ignorePath, cmd: string): bool =
## Verify that a command is not 0-length and is not in the ignore
## list.
if not existsFile(ignorePath):
return true
let stopWords = toSeq(lines(ignorePath)).toSet
case cmd
of "":
false
Expand Down Expand Up @@ -57,15 +61,32 @@ proc historyInit() {.raises: [].} =
except ValueError:
quit "Unknown failure during database initialization."

proc historyUpdate(cwd, cmd: string, stopWords: HashSet[string]) {.raises: [].} =
if stopWords.filter(cmd):
proc historyUpdate(args: Table[string, docopt.Value]) {.raises: [].} =
const
ignoreFile = ".$1ignore" % programName
genericErrorMessage = "Unknown failure during database insertion."

try:
let
cwd = getCurrentDir()
cmd = $args["CMD"]
checksum = if args["-c"]: $args["-c"] else: nil
ignorePath = getHomeDir() / ignoreFile

if not ignorePath.filter(cmd):
log "Skipping update; value in stop words: " & cmd
elif not checksum.isNil and not dbChecksum(checksum):
log "Skipping update; checksum matches: " & checksum
else:
dbInsert(cwd, cmd, checksum)

except DbError as e:
try:
dbInsert(cwd, cmd)
except DbError as e:
try:
handleDbError(e, "Could not insert command into $1 database." % programName)
except ValueError:
quit "Unknown failure during database insertion."
handleDbError(e, "Could not insert command into $1 database." % programName)
except ValueError:
quit genericErrorMessage
except Exception, AssertionError, IOError:
quit genericErrorMessage

proc historyClean(args: Table[string, docopt.Value]) {.raises: [] .} =
try:
Expand Down Expand Up @@ -110,31 +131,23 @@ proc historySearch(args: Table[string, docopt.Value]) {.raises: [].} =
except ValueError:
quit "Unknown error during database search."

when isMainModule:
var args = docopt(help)

proc processArgs(args: Table[string, Value]) =
if args["-v"]:
setLogLevel vVerbose

discard dbOpen()
defer: dbClose()

if args["init"]:
historyInit()

elif args["update"]:
var ignoreLines: HashSet[string]
const ignoreFile = ".ushaignore"

let
ignorePath = getHomeDir() / ignoreFile
if existsFile(ignorePath):
ignoreLines = toSeq(lines(ignorePath)).toSet

historyUpdate(getCurrentDir(), $args["CMD"], ignoreLines)

historyUpdate(args)
elif args["clean"]:
historyClean(args)

else:
historySearch(args)

when isMainModule:
var args = docopt(help)

discard dbOpen()
defer: dbClose()

processArgs(args)
2 changes: 1 addition & 1 deletion usha.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "0.1.0"
version = "0.2"
author = "Zach Smith"
description = "untitled shell history application"
license = "MIT"
Expand Down
26 changes: 25 additions & 1 deletion ushapkg/db.nim
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ proc dbInit*() =
db.exec sql"CREATE UNIQUE INDEX IF NOT EXISTS command_idx ON ? (cwd, cmd)", tableName
db.exec sql"CREATE INDEX IF NOT EXISTS count_order_idx ON ? (count)", tableName
db.exec sql"CREATE INDEX IF NOT EXISTS entered_order_idx ON ? (entered_on)", tableName
db.exec sql"""
CREATE TABLE IF NOT EXISTS checksum (
hash VARCHAR(256)
)"""
db.exec sql"""
INSERT INTO checksum
SELECT "" WHERE NOT EXISTS (
SELECT 1 FROM checksum
)"""

type SearchResponse* = object
cmd, count, timestamp: string
Expand Down Expand Up @@ -142,13 +151,28 @@ proc dbSearch*(
timestamp: if orderByTimeStamp: it[2] else: nil
))

proc dbInsert*(cwd, cmd: string) =
proc dbChecksum*(checksum: string): bool =
log "Checking checksum against value: " & checksum

let currentValue = db.getValue sql"""
SELECT hash FROM checksum LIMIT 1
"""
log "Current checksum value: " & currentValue

currentValue != checksum

proc dbInsert*(cwd, cmd, checksum: string) =
db.exec sql"""
INSERT OR REPLACE INTO ?
(cwd, cmd, count) VALUES
(?, ?, COALESCE(
(SELECT count FROM ? WHERE cwd=? AND cmd=?), 0) + 1)
""", tableName, cwd, cmd, tableName, cwd, cmd
if not checksum.isNil:
log "Updating checksum with value: " & checksum
db.exec sql"""
UPDATE checksum SET hash = ?
""", checksum

proc dbClean*(days: string) =
let
Expand Down

0 comments on commit 2ecd171

Please sign in to comment.