mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-04 02:37:50 +08:00
parent
cec194c537
commit
92fb6e5161
|
@ -349,6 +349,8 @@ func (ev *Evaler) Global() Namespace {
|
|||
return map[string]Variable(ev.global)
|
||||
}
|
||||
|
||||
var ErrStoreUnconnected = errors.New("store unconnected")
|
||||
|
||||
// ResolveVar resolves a variable. When the variable cannot be found, nil is
|
||||
// returned.
|
||||
func (ec *EvalCtx) ResolveVar(ns, name string) Variable {
|
||||
|
@ -372,6 +374,11 @@ func (ec *EvalCtx) ResolveVar(ns, name string) Variable {
|
|||
return NewRoVariable(ExternalCmd{name[len(FnPrefix):]})
|
||||
}
|
||||
return envVariable{name}
|
||||
case "shared":
|
||||
if ec.store == nil {
|
||||
throw(ErrStoreUnconnected)
|
||||
}
|
||||
return sharedVariable{ec.store, name}
|
||||
default:
|
||||
use(ec, ns, nil)
|
||||
return ec.modules[ns][name]
|
||||
|
|
19
eval/shared.go
Normal file
19
eval/shared.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package eval
|
||||
|
||||
import "github.com/elves/elvish/store"
|
||||
|
||||
type sharedVariable struct {
|
||||
store *store.Store
|
||||
name string
|
||||
}
|
||||
|
||||
func (sv sharedVariable) Set(val Value) {
|
||||
err := sv.store.SetSharedVar(sv.name, ToString(val))
|
||||
maybeThrow(err)
|
||||
}
|
||||
|
||||
func (sv sharedVariable) Get() Value {
|
||||
value, err := sv.store.GetSharedVar(sv.name)
|
||||
maybeThrow(err)
|
||||
return String(value)
|
||||
}
|
35
store/sharedVar.go
Normal file
35
store/sharedVar.go
Normal file
|
@ -0,0 +1,35 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var ErrNoVar = errors.New("no such variable")
|
||||
|
||||
func init() {
|
||||
initTable["shared"] = func(db *sql.DB) error {
|
||||
_, err := db.Exec(`create table if not exists shared_var (name text unique primary key, value text)`)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) GetSharedVar(n string) (string, error) {
|
||||
row := s.db.QueryRow(`select value from shared_var where name = ?`, n)
|
||||
var value string
|
||||
err := row.Scan(&value)
|
||||
if err == sql.ErrNoRows {
|
||||
err = ErrNoVar
|
||||
}
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (s *Store) SetSharedVar(n, v string) error {
|
||||
_, err := s.db.Exec(`insert or replace into shared_var (name, value) values (?, ?)`, n, v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) DelSharedVar(n string) error {
|
||||
_, err := s.db.Exec(`delete from shared_var where name = ?`, n)
|
||||
return err
|
||||
}
|
45
store/sharedVar_test.go
Normal file
45
store/sharedVar_test.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package store
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSharedVar(t *testing.T) {
|
||||
varname := "foo"
|
||||
value1 := "lorem ipsum"
|
||||
value2 := "o mores, o tempora"
|
||||
|
||||
// Getting an nonexistent variable should return ErrNoVar.
|
||||
_, err := tStore.GetSharedVar(varname)
|
||||
if err != ErrNoVar {
|
||||
t.Error("want ErrNoVar, got", err)
|
||||
}
|
||||
|
||||
// Setting a variable for the first time creates it.
|
||||
err = tStore.SetSharedVar(varname, value1)
|
||||
if err != nil {
|
||||
t.Error("want no error, got", err)
|
||||
}
|
||||
v, err := tStore.GetSharedVar(varname)
|
||||
if v != value1 || err != nil {
|
||||
t.Errorf("want %q and no error, got %q and %v", value1, v, err)
|
||||
}
|
||||
|
||||
// Setting an existing variable updates its value.
|
||||
err = tStore.SetSharedVar(varname, value2)
|
||||
if err != nil {
|
||||
t.Error("want no error, got", err)
|
||||
}
|
||||
v, err = tStore.GetSharedVar(varname)
|
||||
if v != value2 || err != nil {
|
||||
t.Errorf("want %q and no error, got %q and %v", value2, v, err)
|
||||
}
|
||||
|
||||
// After deleting a variable, access to it cause ErrNoVar.
|
||||
err = tStore.DelSharedVar(varname)
|
||||
if err != nil {
|
||||
t.Error("want no error, got", err)
|
||||
}
|
||||
_, err = tStore.GetSharedVar(varname)
|
||||
if err != ErrNoVar {
|
||||
t.Error("want ErrNoVar, got", err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user