@@ -21,7 +21,7 @@ const bucketKey = "b"
2121
2222func main () {
2323 if len (os .Args ) < 2 {
24- log .Fatalf ("please provide a command <store|list|decode|delete>" )
24+ log .Fatalf ("please provide a command <store|list|decode|delete|delete-stdin >" )
2525 }
2626 switch command := os .Args [1 ]; command {
2727 case "store" :
@@ -43,6 +43,10 @@ func main() {
4343 if err := delete ([]byte (os .Args [2 ])); err != nil {
4444 log .Fatalf ("error deleting: %v" , err )
4545 }
46+ case "delete-stdin" :
47+ if err := deleteStdin (); err != nil {
48+ log .Fatalf ("error deleting: %v" , err )
49+ }
4650 default :
4751 log .Fatalf ("unknown command %q" , command )
4852 }
@@ -218,6 +222,47 @@ func delete(query []byte) error {
218222 return nil
219223}
220224
225+ func deleteStdin () error {
226+ db , err := initDB (nil )
227+ if err != nil {
228+ return fmt .Errorf ("creating db: %w" , err )
229+ }
230+ defer db .Close ()
231+
232+ input , err := io .ReadAll (os .Stdin )
233+ if err != nil {
234+ return fmt .Errorf ("read stdin: %w" , err )
235+ }
236+ if len (input ) <= 2 {
237+ return fmt .Errorf ("input too short to decode" )
238+ }
239+ matches := decodeID .FindSubmatch (input )
240+ if len (matches ) != 2 {
241+ return fmt .Errorf ("input not prefixed with id" )
242+ }
243+ idStr := string (matches [1 ])
244+ id , err := strconv .Atoi (idStr )
245+ if err != nil {
246+ return fmt .Errorf ("converting id: %w" , err )
247+ }
248+
249+ tx , err := db .Begin (true )
250+ if err != nil {
251+ return fmt .Errorf ("begin tx: %w" , err )
252+ }
253+ defer tx .Rollback ()
254+
255+ b := tx .Bucket ([]byte (bucketKey ))
256+ if err := b .Delete (itob (uint64 (id ))); err != nil {
257+ return fmt .Errorf ("delete key: %w" , err )
258+ }
259+
260+ if err := tx .Commit (); err != nil {
261+ return fmt .Errorf ("commit tx: %w" , err )
262+ }
263+ return nil
264+ }
265+
221266func initDB (opts * bolt.Options ) (* bolt.DB , error ) {
222267 userCacheDir , err := os .UserCacheDir ()
223268 if err != nil {
0 commit comments