update-userdata-devtool #58
| @ -52,7 +52,6 @@ func SearchDomains() []string { | ||||
| 	return ParsedDomains | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| func Language() string { | ||||
| 	return viseconfig.DefaultLanguage | ||||
| } | ||||
|  | ||||
| @ -7,6 +7,7 @@ import ( | ||||
| 	"os" | ||||
| 	"path" | ||||
| 
 | ||||
| 	"git.defalsify.org/vise.git/engine" | ||||
| 	"git.defalsify.org/vise.git/logging" | ||||
| 
 | ||||
| 	"git.grassecon.net/grassrootseconomics/sarafu-vise/config" | ||||
| @ -18,6 +19,7 @@ import ( | ||||
| var ( | ||||
| 	logg          = logging.NewVanilla().WithContextKey("SessionId") | ||||
| 	scriptDir     = path.Join("services", "registration") | ||||
| 	menuSeparator = ": " | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| @ -25,6 +27,8 @@ func main() { | ||||
| 
 | ||||
| 	override := config.NewOverride() | ||||
| 	var sessionId string | ||||
| 	var size uint | ||||
| 	var engineDebug bool | ||||
| 
 | ||||
| 	flag.StringVar(&sessionId, "session-id", "075xx2123", "session id") | ||||
| 	flag.StringVar(&override.DbConn, "c", "?", "default connection string (replaces all unspecified strings)") | ||||
| @ -32,6 +36,8 @@ func main() { | ||||
| 
 | ||||
| 	flag.StringVar(&override.UserConn, "userdata", "?", "userdata store connection string") | ||||
| 	flag.StringVar(&override.StateConn, "state", "?", "state store connection string") | ||||
| 	flag.BoolVar(&engineDebug, "d", false, "use engine debug output") | ||||
| 	flag.UintVar(&size, "s", 160, "max size of output") | ||||
| 	flag.Parse() | ||||
| 
 | ||||
| 	config.Apply(override) | ||||
| @ -50,13 +56,23 @@ func main() { | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
| 
 | ||||
| 	cfg := engine.Config{ | ||||
| 		Root:              "root", | ||||
| 		SessionId:         sessionId, | ||||
| 		OutputSize:        uint32(size), | ||||
| 		FlagCount:         uint32(128), | ||||
| 		MenuSeparator:     menuSeparator, | ||||
| 		EngineDebug:       engineDebug, | ||||
| 		ResetOnEmptyInput: true, | ||||
| 	} | ||||
| 
 | ||||
| 	x := cmd.NewCmd(sessionId, flagParser) | ||||
| 	x = x.WithEngine(cfg) | ||||
| 	err = x.Parse(flag.Args()) | ||||
| 	if err != nil { | ||||
| 		fmt.Fprintf(os.Stderr, "cmd parse fail: %v\n", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
| 
 | ||||
| 	logg.Infof("start command", "conn", conns, "subcmd", x) | ||||
| 
 | ||||
| 	menuStorageService := storage.NewMenuStorageService(conns) | ||||
| @ -70,5 +86,4 @@ func main() { | ||||
| 		fmt.Fprintf(os.Stderr, "cmd exec error: %v\n", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -24,7 +24,7 @@ func formatItem(k []byte, v []byte, sessionId string) (string, error) { | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	s := fmt.Sprintf("%v\t%v\n", o.Label, string(v)) | ||||
| 	s := fmt.Sprintf("%v\n\t%v\n", o.Label, string(v)) | ||||
| 
 | ||||
| 	return s, nil | ||||
| } | ||||
|  | ||||
| @ -3,14 +3,27 @@ package cmd | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 
 | ||||
| 	"git.defalsify.org/vise.git/db" | ||||
| 	"git.defalsify.org/vise.git/engine" | ||||
| 	"git.defalsify.org/vise.git/logging" | ||||
| 	"git.defalsify.org/vise.git/persist" | ||||
| 	"git.defalsify.org/vise.git/resource" | ||||
| 	"git.defalsify.org/vise.git/state" | ||||
| 	"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/application" | ||||
| 	"git.grassecon.net/grassrootseconomics/visedriver/storage" | ||||
| ) | ||||
| 
 | ||||
| var argc map[string]int = map[string]int{ | ||||
| 	"reset": 0, | ||||
| 	"admin": 1, | ||||
| 	"clone": 1, | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	logg             = logging.NewVanilla().WithDomain("cmd").WithContextKey("SessionId") | ||||
| 	cloneTargetRegex = `^\+000` | ||||
| ) | ||||
| 
 | ||||
| type Cmd struct { | ||||
| @ -19,7 +32,10 @@ type Cmd struct { | ||||
| 	flagParser   *application.FlagManager | ||||
| 	cmd          int | ||||
| 	enable       bool | ||||
| 	param        string | ||||
| 	exec         func(ctx context.Context, ss storage.StorageService) error | ||||
| 	engineConfig *engine.Config | ||||
| 	st           *state.State | ||||
| } | ||||
| 
 | ||||
| func NewCmd(sessionId string, flagParser *application.FlagManager) *Cmd { | ||||
| @ -29,10 +45,115 @@ func NewCmd(sessionId string, flagParser *application.FlagManager) *Cmd { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) WithEngine(engineConfig engine.Config) *Cmd { | ||||
| 	c.engineConfig = &engineConfig | ||||
| 	return c | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) Exec(ctx context.Context, ss storage.StorageService) error { | ||||
| 	return c.exec(ctx, ss) | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) engine(ctx context.Context, rs resource.Resource, pe *persist.Persister) (engine.Engine, error) { | ||||
| 	if c.engineConfig == nil { | ||||
| 		return nil, fmt.Errorf("engine config missing") | ||||
| 	} | ||||
| 	en := engine.NewEngine(*c.engineConfig, rs) | ||||
| 
 | ||||
| 	st := pe.GetState() | ||||
| 	if st == nil { | ||||
| 		return nil, fmt.Errorf("persister state fail") | ||||
| 	} | ||||
| 	en = en.WithState(st) | ||||
| 	st.UseDebug() | ||||
| 	ca := pe.GetMemory() | ||||
| 	if ca == nil { | ||||
| 		return nil, fmt.Errorf("persister cache fail") | ||||
| 	} | ||||
| 	en = en.WithMemory(ca) | ||||
| 	logg.DebugCtxf(ctx, "state loaded", "state", st) | ||||
| 	return en, nil | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) execClone(ctx context.Context, ss storage.StorageService) error { | ||||
| 	re := regexp.MustCompile(cloneTargetRegex) | ||||
| 	if !re.MatchString(c.param) { | ||||
| 		return fmt.Errorf("Clone sessionId must match target: %s", c.param) | ||||
| 	} | ||||
| 
 | ||||
| 	pe, err := ss.GetPersister(ctx) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("get persister error: %v", err) | ||||
| 	} | ||||
| 	err = pe.Load(c.engineConfig.SessionId) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("persister load error: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	/// TODO consider DRY with devtools/store/dump
 | ||||
| 	store, err := ss.GetUserdataDb(ctx) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("store retrieve error: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	store.SetSession(c.engineConfig.SessionId) | ||||
| 	store.SetPrefix(db.DATATYPE_USERDATA) | ||||
| 	dmp, err := store.Dump(ctx, []byte("")) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("store dump fail: %v\n", err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	for true { | ||||
| 		store.SetSession(c.engineConfig.SessionId) | ||||
| 		k, v := dmp.Next(ctx) | ||||
| 		if k == nil { | ||||
| 			break | ||||
| 		} | ||||
| 		store.SetSession(c.param) | ||||
| 		err = store.Put(ctx, k, v) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("user data store clone failed on key: %x", k) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return pe.Save(c.param) | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) execReset(ctx context.Context, ss storage.StorageService) error { | ||||
| 	pe, err := ss.GetPersister(ctx) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("get persister error: %v", err) | ||||
| 	} | ||||
| 	rs, err := ss.GetResource(ctx) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("get resource error: %v", err) | ||||
| 	} | ||||
| 	dbResource, ok := rs.(*resource.DbResource) | ||||
| 	if !ok { | ||||
| 		return fmt.Errorf("get dbresource error: %v", err) | ||||
| 	} | ||||
| 	err = pe.Load(c.engineConfig.SessionId) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("persister load error: %v", err) | ||||
| 	} | ||||
| 	en, err := c.engine(ctx, dbResource, pe) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	_, err = en.(*engine.DefaultEngine).Reset(ctx, false) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	st := pe.GetState() | ||||
| 	logg.DebugCtxf(ctx, "state after reset", "state", st) | ||||
| 
 | ||||
| 	err = pe.Save(c.engineConfig.SessionId) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) execAdmin(ctx context.Context, ss storage.StorageService) error { | ||||
| 	pe, err := ss.GetPersister(ctx) | ||||
| 	if err != nil { | ||||
| @ -76,13 +197,43 @@ func (c *Cmd) parseCmdAdmin(cmd string, param string, more []string) (bool, erro | ||||
| 	return false, nil | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) parseCmdReset(cmd string, param string, more []string) (bool, error) { | ||||
| 	if cmd == "reset" { | ||||
| 		c.enable = false | ||||
| 		c.exec = c.execReset | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return false, nil | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) parseCmdClone(cmd string, param string, more []string) (bool, error) { | ||||
| 	if cmd == "clone" { | ||||
| 		c.enable = false | ||||
| 		c.param = param | ||||
| 		c.exec = c.execClone | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return false, nil | ||||
| } | ||||
| 
 | ||||
| func (c *Cmd) Parse(args []string) error { | ||||
| 	if len(args) < 2 { | ||||
| 	var param string | ||||
| 	if len(args) < 1 { | ||||
| 		return fmt.Errorf("Wrong number of arguments: %v", args) | ||||
| 	} | ||||
| 	cmd := args[0] | ||||
| 	param := args[1] | ||||
| 
 | ||||
| 	n, ok := argc[cmd] | ||||
| 	if !ok { | ||||
| 		return fmt.Errorf("invalid command: %v", cmd) | ||||
| 	} | ||||
| 	if n > 0 { | ||||
| 		if len(args) < n+1 { | ||||
| 			return fmt.Errorf("Wrong number of arguments, need: %d", n) | ||||
| 		} | ||||
| 		param = args[1] | ||||
| 		args = args[2:] | ||||
| 	} | ||||
| 
 | ||||
| 	r, err := c.parseCmdAdmin(cmd, param, args) | ||||
| 	if err != nil { | ||||
| @ -92,5 +243,21 @@ func (c *Cmd) Parse(args []string) error { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	r, err = c.parseCmdReset(cmd, param, args) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if r { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	r, err = c.parseCmdClone(cmd, param, args) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if r { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return fmt.Errorf("unknown subcommand: %s", cmd) | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user