mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-04 10:57:50 +08:00
parent
cec194c537
commit
92fb6e5161
|
@ -349,6 +349,8 @@ func (ev *Evaler) Global() Namespace {
|
||||||
return map[string]Variable(ev.global)
|
return map[string]Variable(ev.global)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrStoreUnconnected = errors.New("store unconnected")
|
||||||
|
|
||||||
// ResolveVar resolves a variable. When the variable cannot be found, nil is
|
// ResolveVar resolves a variable. When the variable cannot be found, nil is
|
||||||
// returned.
|
// returned.
|
||||||
func (ec *EvalCtx) ResolveVar(ns, name string) Variable {
|
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 NewRoVariable(ExternalCmd{name[len(FnPrefix):]})
|
||||||
}
|
}
|
||||||
return envVariable{name}
|
return envVariable{name}
|
||||||
|
case "shared":
|
||||||
|
if ec.store == nil {
|
||||||
|
throw(ErrStoreUnconnected)
|
||||||
|
}
|
||||||
|
return sharedVariable{ec.store, name}
|
||||||
default:
|
default:
|
||||||
use(ec, ns, nil)
|
use(ec, ns, nil)
|
||||||
return ec.modules[ns][name]
|
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