Skip to content

Commit

Permalink
feat: read-only mode (#31)
Browse files Browse the repository at this point in the history
Fixes #30.
  • Loading branch information
nalgeon authored Jul 22, 2024
1 parent 3bd13a6 commit 6ceaa64
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
37 changes: 35 additions & 2 deletions redka.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -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.
Expand All @@ -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{
Expand All @@ -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
}

Expand Down Expand Up @@ -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
Expand Down
28 changes: 28 additions & 0 deletions redka_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 6ceaa64

Please sign in to comment.