Skip to content

Latest commit

 

History

History
331 lines (280 loc) · 9.05 KB

use-kv-pair.md

File metadata and controls

331 lines (280 loc) · 9.05 KB

How to use key/value pairs

Basics

To save a key/value pair to a bucket, use the tx.Put:

if err := db.Update(
    func(tx *nutsdb.Tx) error {
    key := []byte("name1")
    val := []byte("val1")
    bucket := "bucket1"
    if err := tx.Put(bucket, key, val, 0); err != nil {
        return err
    }
    return nil
}); err != nil {
    log.Fatal(err)
}

This will set the value of the "name1" key to "val1" in the bucket1 bucket.

To update the the value of the "name1" key,we can still use the tx.Put:

if err := db.Update(
    func(tx *nutsdb.Tx) error {
    key := []byte("name1")
    val := []byte("val1-modify") // Update the value
    bucket := "bucket1"
    if err := tx.Put(bucket, key, val, 0); err != nil {
        return err
    }
    return nil
}); err != nil {
    log.Fatal(err)
}

To retrieve this value, we can use the tx.Get:

if err := db.View(
func(tx *nutsdb.Tx) error {
    key := []byte("name1")
    bucket := "bucket1"
    if value, err := tx.Get(bucket, key); err != nil {
        return err
    } else {
        fmt.Println(string(value)) // "val1-modify"
    }
    return nil
}); err != nil {
    log.Println(err)
}

To retrieve the value and set the new value, we can use the Tx.GetSet:

err := db.Update(
    func(tx *nutsdb.Tx) error {
        bucket := "bucket1"
        key := []byte("name1")
        val := []byte("val3")
        oldValue, err := tx.GetSet(bucket, key, val)
        if err != nil {
            return err
        }

        fmt.Println("old value :", string(oldValue))

        return nil
    },
); 
if err != nil {
    log.Println(err)
}

Use the tx.Delete() to delete a key from the bucket:

if err := db.Update(
    func(tx *nutsdb.Tx) error {
    key := []byte("name1")
    bucket := "bucket1"
    if err := tx.Delete(bucket, key); err != nil {
        return err
    }
    return nil
}); err != nil {
    log.Fatal(err)
}

Use tx.ValueLen() to retrieve the length of the value stored by the key

err := db.View(
    func(tx *nutsdb.Tx) error {
        key := []byte("name1")
        bucket := "bucket1"
        if length, err := tx.ValueLen(bucket, key); err != nil {
            return err
        } else {
            fmt.Println(length);
        }
        return nil
    },
);
if err != nil {
    log.Fatal(err)
}

Bit operations

  • Use tx.GetBit() retrieves the value of a key at a certain offset. When the corresponding key exists, it returns the value at the position corresponding to the offset in the parameter. When the offset exceeds the original data range, it returns 0 without reporting an error; When the corresponding key does not exist, an error message will appear indicating that the key does not exist.
if err := db.View(func(tx *nutsdb.Tx) error {
	bucket := "bucket"
	key := []byte("key")
	offset := 2
    bit, err := tx.GetBit(bucket, key, offset)
    if err != nil {
        return err
    }
    log.Println("get bit:", bit)
    return nil
}); err != nil {
    log.Println(err)
}
  • Use tx.SetBit() method adds the value corresponding to a key at a certain offset. When the corresponding key exists, the value on the bit corresponding to the offset will be modified; When the corresponding key does not exist or the offset exceeds the original data range, the original value will be expanded until it can be modified at the position corresponding to the offset. Except for the position corresponding to the offset, the values of the bits generated by automatic expansion are all 0.
if err := db.Update(func(tx *nutsdb.Tx) error {
	bucket := "bucket"
	key := []byte("key")
	offset := 2
	bit := 1
	return tx.SetBit(bucket, key, offset, bit)
}); err != nil {
    log.Println(err)
}

Increments and Decrements

The key needs to be present for increment and decrement operations on values, otherwise an error will be reported indicating that the key does not exist. When the result of incrementing and decrementing a value will be outside the range of int64, a string-based large number calculation will be used, so you don't have to worry about the range of the value being too large.

  • Use the tx.Incr() method to make the value corresponding to a key increment itself by 1
if err := db.Update(func(tx *nutsdb.Tx) error {
	bucket := "bucket"
	key := []byte("key")
    return tx.Incr(bucket, key)
}); err != nil {
    log.Println(err)
}
  • Use the tx.IncrBy() method to have the value corresponding to a key self-increment by the specified value
if err := db.Update(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    key := []byte("key")
    return tx.IncrBy(bucket, key, 10)
}); err != nil {
    log.Println(err)
}
  • Use the tx.Decr() method to make the value corresponding to a key self-decrease by 1
if err := db.Update(func(tx *nutsdb.Tx) error {
	bucket := "bucket"
	key := []byte("key")
    return tx.Decr(bucket, key)
}); err != nil {
    log.Println(err)
}
  • Use the tx.DecrBy() method to make the value corresponding to a key subtract itself from the specified value
if err := db.Update(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    key := []byte("key")
    return tx.DecrBy(bucket, key, 10)
}); err != nil {
    log.Println(err)
}

PutIfNotExists and PutIfExits

  • Use PutIfNotExists set the value for a key in bucket only if the key doesn't exist in the bucket already.
if err := db.Update(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    key := []byte("key")
    value := []byte("value")
    ttl := unit32(100)
    return tx.PutIfNotExists(bucket, key, value, ttl)
}); err != nil {
    log.Println(err)
}
  • Use `PutIfExits`` set the value for a key in bucket only if the key already exits in the bucket.
if err := db.Update(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    key := []byte("key")
    value := []byte("value")
    ttl := unit32(100)
    return tx.PutIfExists(bucket, key, value, ttl)
}); err != nil {
    log.Println(err)
}

Multi-operations on keys

  • Set key-value pairs multiple times in succession using the tx.MSet() method. When using tx.MSet() it is necessary to pass several key-value pairs as ... []byte type to pass in several key-value pairs. Here the total number of parameters is required to be an even number, let i be an even number starting from 0. The ith parameter and the i+1th parameter will be the key and value of a key-value pair respectively.
if err := db.Update(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    args := [][]byte{
        []byte("1"), []byte("2"), []byte("3"), []byte("4"),
    }
    return tx.MSet(bucket, nutsdb.Persistent, args...)
}); err != nil {
    log.Println(err)
}
  • Use the tx.MGet() method to take values multiple times in succession. When using tx.MGet() requires passing in several keys of type ... []byte type is passed several keys, a key not found error is returned if any of the keys do not exist. The return value is a slice, of the same length as the passed parameters, and corresponding one-to-one according to the slice index.
if err := db.View(func(tx *nutsdb.Tx) error {
	bucket := "bucket"
	key := [][]byte{
		[]byte("1"), []byte("2"), []byte("3"), []byte("4"),
    }
    values, err := tx.MGet(bucket, key...)
    if err != nil {
        return err
    }
    for i, value := range values {
        log.Printf("get value by MGet, the %d value is '%s'", i, string(value))
    }
    return nil
}); err != nil {
    log.Println(err)
}

GetTTL and Persist

  • Use GetTTL to get remaining TTL of a value by key. It returns (-1, nil) if TTL is Persistent, (0, ErrBucketNotFound|ErrKeyNotFound) If expired or bucket/key not found and (remaining TTL and nil) if the record exits.
if err := db.View(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    key := []byte("key")
    ttl, err := tx.GetTTL(bucket, key)
    if err != nil {
        return err
    }
    log.Println(ttl)
  • Use Persist to update record's TTL as Persistent if the record exits.
if err := db.Update(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    key := []byte("key")
    return tx.Persist(bucket, key, value, ttl)
}); err != nil {
    log.Println(err)
}

Append operation for a value

  • Use the tx.Append() method to append values.
if err := db.Update(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    key := "key"
    appendage := "appendage"
    return tx.Append(bucket, []byte(key), []byte(appendage))
}); err != nil {
    log.Println(err)
}

Get part of a value by a closed interval

  • Use the tx.GetRange() method to get a portion of a value based on a given index. A closed interval is determined by two parameters of type int, and the value of the portion corresponding to the closed interval is returned.
if err := db.View(func(tx *nutsdb.Tx) error {
    bucket := "bucket"
    key := "key"
    start := 0
    end := 2
    value, err := tx.GetRange(bucket, []byte(key), start, end)
    if err != nil {
        return err
    }
    log.Printf("got value: '%s'", string(value))
    return nil
}); err != nil {
    log.Println(err)
}