mirror of
https://github.com/nalgeon/redka.git
synced 2025-12-24 12:38:00 +08:00
37
redka.go
37
redka.go
@@ -58,6 +58,9 @@ type Options struct {
|
||||
Pragma map[string]string
|
||||
// Logger for the database. If nil, uses a silent logger.
|
||||
Logger *slog.Logger
|
||||
|
||||
// If true, opens the database in read-only mode.
|
||||
readonly bool
|
||||
}
|
||||
|
||||
var defaultOptions = Options{
|
||||
@@ -118,6 +121,24 @@ func Open(path string, opts *Options) (*DB, error) {
|
||||
return new(sdb, opts)
|
||||
}
|
||||
|
||||
// OpenRead opens an existing database at the given path in read-only mode.
|
||||
func OpenRead(path string, opts *Options) (*DB, error) {
|
||||
// Apply the default options if necessary.
|
||||
opts = applyOptions(defaultOptions, opts)
|
||||
opts.readonly = true
|
||||
|
||||
// Open the read-only database handle.
|
||||
dataSource := sqlx.DataSource(path, false, opts.Pragma)
|
||||
db, err := sql.Open(opts.DriverName, dataSource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create the database-backed repository.
|
||||
sdb := sqlx.New(db, db, newTx)
|
||||
return new(sdb, opts)
|
||||
}
|
||||
|
||||
// OpenDB connects to an existing SQL database.
|
||||
// Creates the database schema if necessary.
|
||||
// The opts parameter is optional. If nil, uses default options.
|
||||
@@ -130,6 +151,14 @@ func OpenDB(rw *sql.DB, ro *sql.DB, opts *Options) (*DB, error) {
|
||||
return new(sdb, opts)
|
||||
}
|
||||
|
||||
// OpenReadDB connects to an existing SQL database in read-only mode.
|
||||
func OpenReadDB(db *sql.DB, opts *Options) (*DB, error) {
|
||||
opts = applyOptions(defaultOptions, opts)
|
||||
opts.readonly = true
|
||||
sdb := sqlx.New(db, db, newTx)
|
||||
return new(sdb, opts)
|
||||
}
|
||||
|
||||
// new creates a new database.
|
||||
func new(sdb *sqlx.DB[*Tx], opts *Options) (*DB, error) {
|
||||
rdb := &DB{
|
||||
@@ -142,7 +171,9 @@ func new(sdb *sqlx.DB[*Tx], opts *Options) (*DB, error) {
|
||||
zsetDB: rzset.New(sdb.RW, sdb.RO),
|
||||
log: opts.Logger,
|
||||
}
|
||||
rdb.bg = rdb.startBgManager()
|
||||
if !opts.readonly {
|
||||
rdb.bg = rdb.startBgManager()
|
||||
}
|
||||
return rdb, nil
|
||||
}
|
||||
|
||||
@@ -228,7 +259,9 @@ func (db *DB) ViewContext(ctx context.Context, f func(tx *Tx) error) error {
|
||||
// Close closes the database.
|
||||
// It's safe for concurrent use by multiple goroutines.
|
||||
func (db *DB) Close() error {
|
||||
db.bg.Stop()
|
||||
if db.bg != nil {
|
||||
db.bg.Stop()
|
||||
}
|
||||
var allErr error
|
||||
if err := db.RW.Close(); err != nil {
|
||||
allErr = err
|
||||
|
||||
@@ -20,6 +20,34 @@ func ExampleOpen() {
|
||||
// ...
|
||||
}
|
||||
|
||||
func ExampleOpenRead() {
|
||||
// open a writable database
|
||||
db, err := redka.Open("data.db", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
db.Str().Set("name", "alice")
|
||||
db.Close()
|
||||
|
||||
// open a read-only database
|
||||
db, err = redka.OpenRead("data.db", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// read operations work fine
|
||||
name, _ := db.Str().Get("name")
|
||||
fmt.Println(name)
|
||||
// write operations will fail
|
||||
err = db.Str().Set("name", "bob")
|
||||
fmt.Println(err)
|
||||
// attempt to write a readonly database
|
||||
db.Close()
|
||||
|
||||
// Output:
|
||||
// alice
|
||||
// attempt to write a readonly database
|
||||
}
|
||||
|
||||
func ExampleDB_Close() {
|
||||
db, err := redka.Open("file:/data.db?vfs=memdb", nil)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user