@@ -4,6 +4,8 @@ package sqlbase
44
55import (
66 "database/sql"
7+ "errors"
8+ "fmt"
79
810 "github.com/btcsuite/btcwallet/walletdb"
911)
@@ -230,3 +232,62 @@ func (c *readWriteCursor) Delete() error {
230232
231233 return err
232234}
235+
236+ // Delete removes the current key/value pair the cursor is at without
237+ // invalidating the cursor. Returns ErrIncompatibleValue if attempted when the
238+ // cursor points to a nested bucket.
239+ func (c * readWriteCursor ) Delete () error {
240+ if c .currKey == nil {
241+ // Cursor might not be positioned on a valid key.
242+ return errors .New ("cursor not positioned on a key" )
243+ }
244+
245+ // Attempt to delete the key the cursor is pointing at, but only if it's
246+ // a value.
247+ result , err := c .bucket .tx .Exec (
248+ "DELETE FROM " + c .bucket .table + " WHERE " +
249+ parentSelector (c .bucket .id )+
250+ " AND key=$1 AND value IS NOT NULL" ,
251+ c .currKey ,
252+ )
253+ if err != nil {
254+ panic (err )
255+ }
256+
257+ rows , err := result .RowsAffected ()
258+ if err != nil {
259+ return fmt .Errorf ("error getting rows affected " +
260+ "for cursor key %x: %w" , c .currKey , err )
261+ }
262+
263+ // If deletion succeeded, we are done.
264+ if rows == 1 {
265+ return nil
266+ }
267+
268+ // If rows == 0, the key either didn't exist anymore (concurrent
269+ // delete?) or it was a bucket. Check if it's a bucket.
270+ var existsAsBucket int
271+ rowCheck , cancelCheck := c .bucket .tx .QueryRow (
272+ "SELECT 1 FROM " + c .bucket .table + " WHERE " +
273+ parentSelector (c .bucket .id )+
274+ " AND key=$1 AND value IS NULL" , c .currKey ,
275+ )
276+ defer cancelCheck ()
277+
278+ errCheck := rowCheck .Scan (& existsAsBucket )
279+ if errCheck == nil {
280+ // Found it, and value IS NULL -> It's a bucket.
281+ return walletdb .ErrIncompatibleValue
282+ }
283+
284+ if errCheck == sql .ErrNoRows {
285+ return nil
286+ }
287+
288+ // Some other error during the check.
289+ //
290+ // TODO(roasbeef): panic here like above/
291+ return fmt .Errorf ("error checking if cursor key %x is " +
292+ "bucket: %w" , c .currKey , errCheck )
293+ }
0 commit comments