mirror of
https://github.com/nalgeon/redka.git
synced 2025-11-01 20:02:39 +08:00
111 lines
3.4 KiB
Go
111 lines
3.4 KiB
Go
// Package rstring is a database-backed string repository.
|
|
// It provides methods to interact with strings in the database.
|
|
package rstring
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
|
|
"github.com/nalgeon/redka/internal/core"
|
|
"github.com/nalgeon/redka/internal/sqlx"
|
|
)
|
|
|
|
// DB is a database-backed string repository.
|
|
// A string is a slice of bytes associated with a key.
|
|
// Use the string repository to work with individual strings.
|
|
type DB struct {
|
|
dialect sqlx.Dialect
|
|
ro *sql.DB
|
|
rw *sql.DB
|
|
update func(f func(tx *Tx) error) error
|
|
}
|
|
|
|
// New connects to the string repository.
|
|
// Does not create the database schema.
|
|
func New(db *sqlx.DB) *DB {
|
|
actor := sqlx.NewTransactor(db, NewTx)
|
|
return &DB{dialect: db.Dialect, ro: db.RO, rw: db.RW, update: actor.Update}
|
|
}
|
|
|
|
// Get returns the value of the key.
|
|
// If the key does not exist or is not a string, returns ErrNotFound.
|
|
func (d *DB) Get(key string) (core.Value, error) {
|
|
tx := NewTx(d.dialect, d.ro)
|
|
return tx.Get(key)
|
|
}
|
|
|
|
// GetMany returns a map of values for given keys.
|
|
// Ignores keys that do not exist or not strings,
|
|
// and does not return them in the map.
|
|
func (d *DB) GetMany(keys ...string) (map[string]core.Value, error) {
|
|
tx := NewTx(d.dialect, d.ro)
|
|
return tx.GetMany(keys...)
|
|
}
|
|
|
|
// Incr increments the integer key value by the specified amount.
|
|
// Returns the value after the increment.
|
|
// If the key does not exist, sets it to 0 before the increment.
|
|
// If the key value is not an integer, returns ErrValueType.
|
|
// If the key exists but is not a string, returns ErrKeyType.
|
|
func (d *DB) Incr(key string, delta int) (int, error) {
|
|
var val int
|
|
err := d.update(func(tx *Tx) error {
|
|
var err error
|
|
val, err = tx.Incr(key, delta)
|
|
return err
|
|
})
|
|
return val, err
|
|
}
|
|
|
|
// IncrFloat increments the float key value by the specified amount.
|
|
// Returns the value after the increment.
|
|
// If the key does not exist, sets it to 0 before the increment.
|
|
// If the key value is not an float, returns ErrValueType.
|
|
// If the key exists but is not a string, returns ErrKeyType.
|
|
func (d *DB) IncrFloat(key string, delta float64) (float64, error) {
|
|
var val float64
|
|
err := d.update(func(tx *Tx) error {
|
|
var err error
|
|
val, err = tx.IncrFloat(key, delta)
|
|
return err
|
|
})
|
|
return val, err
|
|
}
|
|
|
|
// Set sets the key value that will not expire.
|
|
// Overwrites the value if the key already exists.
|
|
// If the key exists but is not a string, returns ErrKeyType.
|
|
func (d *DB) Set(key string, value any) error {
|
|
err := d.update(func(tx *Tx) error {
|
|
return tx.Set(key, value)
|
|
})
|
|
return err
|
|
}
|
|
|
|
// SetExpire sets the key value with an optional expiration time (if ttl > 0).
|
|
// Overwrites the value and ttl if the key already exists.
|
|
// If the key exists but is not a string, returns ErrKeyType.
|
|
func (d *DB) SetExpire(key string, value any, ttl time.Duration) error {
|
|
err := d.update(func(tx *Tx) error {
|
|
return tx.SetExpire(key, value, ttl)
|
|
})
|
|
return err
|
|
}
|
|
|
|
// SetMany sets the values of multiple keys.
|
|
// Overwrites values for keys that already exist and
|
|
// creates new keys/values for keys that do not exist.
|
|
// Removes the TTL for existing keys.
|
|
// If any of the keys exists but is not a string, returns ErrKeyType.
|
|
func (d *DB) SetMany(items map[string]any) error {
|
|
err := d.update(func(tx *Tx) error {
|
|
return tx.SetMany(items)
|
|
})
|
|
return err
|
|
}
|
|
|
|
// SetWith sets the key value with additional options.
|
|
func (d *DB) SetWith(key string, value any) SetCmd {
|
|
return SetCmd{db: d, key: key, val: value}
|
|
}
|