mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-10 18:49:02 -06:00
Changed multirepo env to use deterministic ordering and to initialize with nested repositories by default. Removed commit arg from sql command.
This commit is contained in:
@@ -70,7 +70,7 @@ const (
|
||||
|
||||
var sqlDocs = cli.CommandDocumentationContent{
|
||||
ShortDesc: "Runs a SQL query",
|
||||
LongDesc: `Runs a SQL query you specify. With no arguments, begins an interactive shell to run queries and view the results. With the {{.EmphasisLeft}}-q{{.EmphasisRight}} option, runs the given query and prints any results, then exits. If a commit is specified then only read queries are supported, and will run against the data at the specified commit.
|
||||
LongDesc: `Runs a SQL query you specify. With no arguments, begins an interactive shell to run queries and view the results. With the {{.EmphasisLeft}}-q{{.EmphasisRight}} option, runs the given query and prints any results, then exits.
|
||||
|
||||
By default, {{.EmphasisLeft}}-q{{.EmphasisRight}} executes a single statement. To execute multiple SQL statements separated by semicolons, use {{.EmphasisLeft}}-b{{.EmphasisRight}} to enable batch mode. Queries can be saved with {{.EmphasisLeft}}-s{{.EmphasisRight}}. Alternatively {{.EmphasisLeft}}-x{{.EmphasisRight}} can be used to execute a saved query by name. Pipe SQL statements to dolt sql (no {{.EmphasisLeft}}-q{{.EmphasisRight}}) to execute a SQL import or update script.
|
||||
|
||||
@@ -80,7 +80,7 @@ By default this command uses the dolt data repository in the current working dir
|
||||
"[--multi-db-dir {{.LessThan}}directory{{.GreaterThan}}] [-r {{.LessThan}}result format{{.GreaterThan}}]",
|
||||
"-q {{.LessThan}}query;query{{.GreaterThan}} [-r {{.LessThan}}result format{{.GreaterThan}}] -s {{.LessThan}}name{{.GreaterThan}} -m {{.LessThan}}message{{.GreaterThan}} [-b] [{{.LessThan}}commit{{.GreaterThan}}]",
|
||||
"-q {{.LessThan}}query;query{{.GreaterThan}} --multi-db-dir {{.LessThan}}directory{{.GreaterThan}} [-r {{.LessThan}}result format{{.GreaterThan}}] [-b]",
|
||||
"-x {{.LessThan}}name{{.GreaterThan}} [{{.LessThan}}commit{{.GreaterThan}}]",
|
||||
"-x {{.LessThan}}name{{.GreaterThan}}",
|
||||
"--list-saved",
|
||||
},
|
||||
}
|
||||
@@ -169,7 +169,6 @@ func (cmd SqlCmd) CreateMarkdown(wr io.Writer, commandStr string) error {
|
||||
|
||||
func (cmd SqlCmd) createArgParser() *argparser.ArgParser {
|
||||
ap := argparser.NewArgParser()
|
||||
ap.ArgListHelp = append(ap.ArgListHelp, [2]string{"commit", "Commit to run read only queries against."})
|
||||
ap.SupportsString(QueryFlag, "q", "SQL query to run", "Runs a single query and exits")
|
||||
ap.SupportsString(FormatFlag, "r", "result output format", "How to format result output. Valid values are tabular, csv, json. Defaults to tabular. ")
|
||||
ap.SupportsString(saveFlag, "s", "saved query name", "Used with --query, save the query to the query catalog with the name provided. Saved queries can be examined in the dolt_query_catalog system table.")
|
||||
@@ -211,84 +210,43 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
|
||||
|
||||
args = apr.Args
|
||||
|
||||
var verr errhand.VerboseError
|
||||
format := FormatTabular
|
||||
if formatSr, ok := apr.GetValue(FormatFlag); ok {
|
||||
var verr errhand.VerboseError
|
||||
format, verr = GetResultFormat(formatSr)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(verr), usage)
|
||||
}
|
||||
}
|
||||
|
||||
var mrEnv env.MultiRepoEnv
|
||||
var initialRoots map[string]*doltdb.RootValue
|
||||
var readOnly = false
|
||||
if multiDir, ok := apr.GetValue(multiDBDirFlag); !ok {
|
||||
if !cli.CheckEnvIsValid(dEnv) {
|
||||
return 2
|
||||
}
|
||||
|
||||
mrEnv, err = env.DoltEnvAsMultiEnv(dEnv)
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
|
||||
}
|
||||
|
||||
if apr.NArg() > 0 {
|
||||
cs, err := parseCommitSpec(dEnv, apr)
|
||||
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.BuildDError("Invalid commit %s", apr.Arg(0)).SetPrintUsage().Build(), usage)
|
||||
}
|
||||
|
||||
cm, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
|
||||
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.BuildDError("Invalid commit %s", apr.Arg(0)).SetPrintUsage().Build(), usage)
|
||||
}
|
||||
|
||||
root, err := cm.GetRootValue()
|
||||
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.BuildDError("Invalid commit %s", apr.Arg(0)).SetPrintUsage().Build(), usage)
|
||||
}
|
||||
|
||||
for dbname := range mrEnv {
|
||||
initialRoots = map[string]*doltdb.RootValue{dbname: root}
|
||||
}
|
||||
|
||||
readOnly = true
|
||||
} else {
|
||||
initialRoots, err = mrEnv.GetWorkingRoots(ctx)
|
||||
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var mrEnv *env.MultiRepoEnv
|
||||
multiDir, multiDbMode := apr.GetValue(multiDBDirFlag)
|
||||
if multiDbMode {
|
||||
if apr.NArg() > 0 {
|
||||
return HandleVErrAndExitCode(errhand.BuildDError("Specifying a commit is not compatible with the --multi-db-dir flag.").SetPrintUsage().Build(), usage)
|
||||
}
|
||||
|
||||
mrEnv, err = env.LoadMultiEnvFromDir(ctx, env.GetCurrentUserHomeDir, dEnv.FS, multiDir, cmd.VersionStr)
|
||||
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
|
||||
}
|
||||
} else {
|
||||
if !cli.CheckEnvIsValid(dEnv) {
|
||||
return 2
|
||||
}
|
||||
|
||||
initialRoots, err = mrEnv.GetWorkingRoots(ctx)
|
||||
|
||||
mrEnv, err = env.DoltEnvAsMultiEnv(ctx, dEnv)
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
|
||||
}
|
||||
}
|
||||
|
||||
roots := make(map[string]*doltdb.RootValue)
|
||||
initialRoots, err := mrEnv.GetWorkingRoots(ctx)
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
|
||||
}
|
||||
|
||||
var name string
|
||||
var root *doltdb.RootValue
|
||||
for name, root = range initialRoots {
|
||||
roots[name] = root
|
||||
}
|
||||
|
||||
var currentDB string
|
||||
if len(initialRoots) == 1 {
|
||||
@@ -302,13 +260,18 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
|
||||
|
||||
if multiStatementMode {
|
||||
batchInput := strings.NewReader(query)
|
||||
verr = execMultiStatements(ctx, dEnv, continueOnError, mrEnv, roots, readOnly, batchInput, format)
|
||||
verr := execMultiStatements(ctx, dEnv, continueOnError, mrEnv, batchInput, format)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
} else if batchMode {
|
||||
batchInput := strings.NewReader(query)
|
||||
verr = execBatch(ctx, dEnv, continueOnError, mrEnv, roots, readOnly, batchInput, format)
|
||||
verr := execBatch(ctx, dEnv, continueOnError, mrEnv, batchInput, format)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
} else {
|
||||
verr = execQuery(ctx, dEnv, mrEnv, roots, readOnly, query, format)
|
||||
|
||||
verr := execQuery(ctx, dEnv, mrEnv, query, format)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
@@ -317,21 +280,31 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
|
||||
|
||||
if saveName != "" {
|
||||
saveMessage := apr.GetValueOrDefault(messageFlag, "")
|
||||
roots[currentDB], verr = saveQuery(ctx, roots[currentDB], query, saveName, saveMessage)
|
||||
verr = UpdateWorkingWithVErr(mrEnv[currentDB], roots[currentDB])
|
||||
newRoot, verr := saveQuery(ctx, initialRoots[currentDB], query, saveName, saveMessage)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
|
||||
verr = UpdateWorkingWithVErr(mrEnv.GetEnv(currentDB), newRoot)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if savedQueryName, exOk := apr.GetValue(executeFlag); exOk {
|
||||
sq, err := dtables.RetrieveFromQueryCatalog(ctx, roots[currentDB], savedQueryName)
|
||||
sq, err := dtables.RetrieveFromQueryCatalog(ctx, initialRoots[currentDB], savedQueryName)
|
||||
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
|
||||
}
|
||||
|
||||
cli.PrintErrf("Executing saved query '%s':\n%s\n", savedQueryName, sq.Query)
|
||||
verr = execQuery(ctx, dEnv, mrEnv, roots, readOnly, sq.Query, format)
|
||||
verr := execQuery(ctx, dEnv, mrEnv, sq.Query, format)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
} else if apr.Contains(listSavedFlag) {
|
||||
hasQC, err := roots[currentDB].HasTable(ctx, doltdb.DoltQueryCatalogTableName)
|
||||
hasQC, err := initialRoots[currentDB].HasTable(ctx, doltdb.DoltQueryCatalogTableName)
|
||||
|
||||
if err != nil {
|
||||
verr := errhand.BuildDError("error: Failed to read from repository.").AddCause(err).Build()
|
||||
@@ -343,7 +316,10 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
|
||||
}
|
||||
|
||||
query := "SELECT * FROM " + doltdb.DoltQueryCatalogTableName
|
||||
verr = execQuery(ctx, dEnv, mrEnv, roots, readOnly, query, format)
|
||||
verr := execQuery(ctx, dEnv, mrEnv, query, format)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
} else {
|
||||
// Run in either batch mode for piped input, or shell mode for interactive
|
||||
runInBatchMode := true
|
||||
@@ -359,54 +335,42 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
|
||||
}
|
||||
|
||||
if multiStatementMode {
|
||||
verr = execMultiStatements(ctx, dEnv, continueOnError, mrEnv, roots, readOnly, os.Stdin, format)
|
||||
verr := execMultiStatements(ctx, dEnv, continueOnError, mrEnv, os.Stdin, format)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
} else if runInBatchMode {
|
||||
verr = execBatch(ctx, dEnv, continueOnError, mrEnv, roots, readOnly, os.Stdin, format)
|
||||
verr := execBatch(ctx, dEnv, continueOnError, mrEnv, os.Stdin, format)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
} else {
|
||||
verr = execShell(ctx, dEnv, mrEnv, roots, readOnly, format)
|
||||
verr := execShell(ctx, dEnv, mrEnv, format)
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if verr != nil {
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
|
||||
func parseCommitSpec(dEnv *env.DoltEnv, apr *argparser.ArgParseResults) (*doltdb.CommitSpec, error) {
|
||||
if apr.NArg() == 0 || apr.Arg(0) == "--" {
|
||||
return dEnv.RepoStateReader().CWBHeadSpec(), nil
|
||||
}
|
||||
|
||||
comSpecStr := apr.Arg(0)
|
||||
cs, err := doltdb.NewCommitSpec(comSpecStr)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid commit %s\n", comSpecStr)
|
||||
}
|
||||
|
||||
return cs, nil
|
||||
return 0
|
||||
}
|
||||
|
||||
func execShell(
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
mrEnv env.MultiRepoEnv,
|
||||
roots map[string]*doltdb.RootValue,
|
||||
readOnly bool,
|
||||
format resultFormat,
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
mrEnv *env.MultiRepoEnv,
|
||||
format resultFormat,
|
||||
) errhand.VerboseError {
|
||||
dbs, err := CollectDBs(ctx, mrEnv)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
se, err := newSqlEngine(ctx, dEnv, roots, readOnly, format, dbs...)
|
||||
se, err := newSqlEngine(ctx, dEnv, format, dbs...)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
|
||||
err = runShell(ctx, se, mrEnv, roots)
|
||||
err = runShell(ctx, se, mrEnv)
|
||||
if err != nil {
|
||||
return errhand.BuildDError(err.Error()).Build()
|
||||
}
|
||||
@@ -414,21 +378,19 @@ func execShell(
|
||||
}
|
||||
|
||||
func execBatch(
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
continueOnErr bool,
|
||||
mrEnv env.MultiRepoEnv,
|
||||
roots map[string]*doltdb.RootValue,
|
||||
readOnly bool,
|
||||
batchInput io.Reader,
|
||||
format resultFormat,
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
continueOnErr bool,
|
||||
mrEnv *env.MultiRepoEnv,
|
||||
batchInput io.Reader,
|
||||
format resultFormat,
|
||||
) errhand.VerboseError {
|
||||
dbs, err := CollectDBs(ctx, mrEnv)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
|
||||
se, err := newSqlEngine(ctx, dEnv, roots, readOnly, format, dbs...)
|
||||
se, err := newSqlEngine(ctx, dEnv, format, dbs...)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
@@ -460,20 +422,18 @@ func execBatch(
|
||||
}
|
||||
|
||||
func execMultiStatements(
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
continueOnErr bool,
|
||||
mrEnv env.MultiRepoEnv,
|
||||
roots map[string]*doltdb.RootValue,
|
||||
readOnly bool,
|
||||
batchInput io.Reader,
|
||||
format resultFormat,
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
continueOnErr bool,
|
||||
mrEnv *env.MultiRepoEnv,
|
||||
batchInput io.Reader,
|
||||
format resultFormat,
|
||||
) errhand.VerboseError {
|
||||
dbs, err := CollectDBs(ctx, mrEnv)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
se, err := newSqlEngine(ctx, dEnv, roots, readOnly, format, dbs...)
|
||||
se, err := newSqlEngine(ctx, dEnv, format, dbs...)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
@@ -500,19 +460,17 @@ func newDatabase(name string, dEnv *env.DoltEnv) dsqle.Database {
|
||||
}
|
||||
|
||||
func execQuery(
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
mrEnv env.MultiRepoEnv,
|
||||
roots map[string]*doltdb.RootValue,
|
||||
readOnly bool,
|
||||
query string,
|
||||
format resultFormat,
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
mrEnv *env.MultiRepoEnv,
|
||||
query string,
|
||||
format resultFormat,
|
||||
) errhand.VerboseError {
|
||||
dbs, err := CollectDBs(ctx, mrEnv)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
se, err := newSqlEngine(ctx, dEnv, roots, readOnly, format, dbs...)
|
||||
se, err := newSqlEngine(ctx, dEnv, format, dbs...)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
@@ -539,8 +497,8 @@ func execQuery(
|
||||
|
||||
// CollectDBs takes a MultiRepoEnv and creates Database objects from each environment and returns a slice of these
|
||||
// objects.
|
||||
func CollectDBs(ctx context.Context, mrEnv env.MultiRepoEnv) ([]dsqle.SqlDatabase, error) {
|
||||
dbs := make([]dsqle.SqlDatabase, 0, len(mrEnv))
|
||||
func CollectDBs(ctx context.Context, mrEnv *env.MultiRepoEnv) ([]dsqle.SqlDatabase, error) {
|
||||
var dbs []dsqle.SqlDatabase
|
||||
var db dsqle.SqlDatabase
|
||||
err := mrEnv.Iter(func(name string, dEnv *env.DoltEnv) (stop bool, err error) {
|
||||
postCommitHooks, err := env.GetCommitHooks(ctx, dEnv)
|
||||
@@ -824,7 +782,7 @@ func runBatchMode(ctx *sql.Context, se *sqlEngine, input io.Reader, continueOnEr
|
||||
|
||||
// runShell starts a SQL shell. Returns when the user exits the shell. The Root of the sqlEngine may
|
||||
// be updated by any queries which were processed.
|
||||
func runShell(ctx context.Context, se *sqlEngine, mrEnv env.MultiRepoEnv, initialRoots map[string]*doltdb.RootValue) error {
|
||||
func runShell(ctx context.Context, se *sqlEngine, mrEnv *env.MultiRepoEnv) error {
|
||||
_ = iohelp.WriteLine(cli.CliOut, welcomeMsg)
|
||||
|
||||
sqlCtx, err := se.newContext(ctx)
|
||||
@@ -833,7 +791,7 @@ func runShell(ctx context.Context, se *sqlEngine, mrEnv env.MultiRepoEnv, initia
|
||||
}
|
||||
|
||||
currentDB := sqlCtx.Session.GetCurrentDatabase()
|
||||
currEnv := mrEnv[currentDB]
|
||||
currEnv := mrEnv.GetEnv(currentDB)
|
||||
|
||||
historyFile := filepath.Join(".sqlhistory") // history file written to working dir
|
||||
initialPrompt := fmt.Sprintf("%s> ", sqlCtx.GetCurrentDatabase())
|
||||
@@ -1462,20 +1420,12 @@ var ErrDBNotFoundKind = errors.NewKind("database '%s' not found")
|
||||
|
||||
// sqlEngine packages up the context necessary to run sql queries against sqle.
|
||||
func newSqlEngine(
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
roots map[string]*doltdb.RootValue, // See TODO below
|
||||
readOnly bool,
|
||||
format resultFormat,
|
||||
dbs ...dsqle.SqlDatabase,
|
||||
ctx context.Context,
|
||||
dEnv *env.DoltEnv,
|
||||
format resultFormat,
|
||||
dbs ...dsqle.SqlDatabase,
|
||||
) (*sqlEngine, error) {
|
||||
var au auth.Auth
|
||||
|
||||
if readOnly {
|
||||
au = auth.NewNativeSingle("", "", auth.ReadPerm)
|
||||
} else {
|
||||
au = new(auth.None)
|
||||
}
|
||||
au := new(auth.None)
|
||||
|
||||
parallelism := runtime.GOMAXPROCS(0)
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ func Serve(ctx context.Context, version string, serverConfig ServerConfig, serve
|
||||
if len(dbNamesAndPaths) == 0 {
|
||||
if dEnv.Valid() {
|
||||
var err error
|
||||
mrEnv, err = env.DoltEnvAsMultiEnv(dEnv)
|
||||
mrEnv, err = env.DoltEnvAsMultiEnv(ctx, dEnv)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
|
||||
73
go/libraries/doltcore/env/multi_repo_env.go
vendored
73
go/libraries/doltcore/env/multi_repo_env.go
vendored
@@ -39,17 +39,40 @@ type EnvNameAndPath struct {
|
||||
}
|
||||
|
||||
// MultiRepoEnv is a type used to store multiple environments which can be retrieved by name
|
||||
type MultiRepoEnv map[string]*DoltEnv
|
||||
type MultiRepoEnv struct {
|
||||
envs []NamedEnv
|
||||
}
|
||||
|
||||
type NamedEnv struct {
|
||||
name string
|
||||
env *DoltEnv
|
||||
}
|
||||
|
||||
// AddEnv adds an environment to the MultiRepoEnv by name
|
||||
func (mrEnv MultiRepoEnv) AddEnv(name string, dEnv *DoltEnv) {
|
||||
mrEnv[name] = dEnv
|
||||
func (mrEnv *MultiRepoEnv) AddEnv(name string, dEnv *DoltEnv) {
|
||||
mrEnv.envs = append(mrEnv.envs, NamedEnv{
|
||||
name: name,
|
||||
env: dEnv,
|
||||
})
|
||||
}
|
||||
|
||||
// GetEnv returns the env with the name given, or nil if no such env exists
|
||||
func (mrEnv *MultiRepoEnv) GetEnv(name string) *DoltEnv {
|
||||
var found *DoltEnv
|
||||
mrEnv.Iter(func(n string, dEnv *DoltEnv) (stop bool, err error) {
|
||||
if n == name {
|
||||
found = dEnv
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
return found
|
||||
}
|
||||
|
||||
// Iter iterates over all environments in the MultiRepoEnv
|
||||
func (mrEnv MultiRepoEnv) Iter(cb func(name string, dEnv *DoltEnv) (stop bool, err error)) error {
|
||||
for name, dEnv := range mrEnv {
|
||||
stop, err := cb(name, dEnv)
|
||||
func (mrEnv *MultiRepoEnv) Iter(cb func(name string, dEnv *DoltEnv) (stop bool, err error)) error {
|
||||
for _, e := range mrEnv.envs {
|
||||
stop, err := cb(e.name, e.env)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -65,7 +88,7 @@ func (mrEnv MultiRepoEnv) Iter(cb func(name string, dEnv *DoltEnv) (stop bool, e
|
||||
|
||||
// GetWorkingRoots returns a map with entries for each environment name with a value equal to the working root
|
||||
// for that environment
|
||||
func (mrEnv MultiRepoEnv) GetWorkingRoots(ctx context.Context) (map[string]*doltdb.RootValue, error) {
|
||||
func (mrEnv *MultiRepoEnv) GetWorkingRoots(ctx context.Context) (map[string]*doltdb.RootValue, error) {
|
||||
roots := make(map[string]*doltdb.RootValue)
|
||||
err := mrEnv.Iter(func(name string, dEnv *DoltEnv) (stop bool, err error) {
|
||||
root, err := dEnv.WorkingRoot(ctx)
|
||||
@@ -122,7 +145,7 @@ func getRepoRootDir(path, pathSeparator string) string {
|
||||
}
|
||||
|
||||
// DoltEnvAsMultiEnv returns a MultiRepoEnv which wraps the DoltEnv and names it based on the directory DoltEnv refers to
|
||||
func DoltEnvAsMultiEnv(dEnv *DoltEnv) (MultiRepoEnv, error) {
|
||||
func DoltEnvAsMultiEnv(ctx context.Context, dEnv *DoltEnv) (*MultiRepoEnv, error) {
|
||||
dbName := "dolt"
|
||||
|
||||
if dEnv.RSLoadErr != nil {
|
||||
@@ -153,15 +176,38 @@ func DoltEnvAsMultiEnv(dEnv *DoltEnv) (MultiRepoEnv, error) {
|
||||
}
|
||||
}
|
||||
|
||||
mrEnv := make(MultiRepoEnv)
|
||||
mrEnv := &MultiRepoEnv{
|
||||
envs: make([]NamedEnv, 0),
|
||||
}
|
||||
mrEnv.AddEnv(dbName, dEnv)
|
||||
|
||||
// If there are other directories in the same root, try to load them as additional databases
|
||||
dEnv.FS.Iter(".", false, func(path string, size int64, isDir bool) (stop bool) {
|
||||
if !isDir {
|
||||
return false
|
||||
}
|
||||
|
||||
dir := filepath.Base(path)
|
||||
|
||||
newFs, err := dEnv.FS.WithWorkingDir(dir)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
newEnv := Load(ctx, GetCurrentUserHomeDir, newFs, doltdb.LocalDirDoltDB, dEnv.Version)
|
||||
if newEnv.Valid() {
|
||||
mrEnv.AddEnv(dirToDBName(dir), newEnv)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
return mrEnv, nil
|
||||
}
|
||||
|
||||
// LoadMultiEnv takes a variable list of EnvNameAndPath objects loads each of the environments, and returns a new
|
||||
// MultiRepoEnv
|
||||
func LoadMultiEnv(ctx context.Context, hdp HomeDirProvider, fs filesys.Filesys, version string, envNamesAndPaths ...EnvNameAndPath) (MultiRepoEnv, error) {
|
||||
func LoadMultiEnv(ctx context.Context, hdp HomeDirProvider, fs filesys.Filesys, version string, envNamesAndPaths ...EnvNameAndPath) (*MultiRepoEnv, error) {
|
||||
nameToPath := make(map[string]string)
|
||||
for _, nameAndPath := range envNamesAndPaths {
|
||||
existingPath, ok := nameToPath[nameAndPath.Name]
|
||||
@@ -177,7 +223,10 @@ func LoadMultiEnv(ctx context.Context, hdp HomeDirProvider, fs filesys.Filesys,
|
||||
nameToPath[nameAndPath.Name] = nameAndPath.Path
|
||||
}
|
||||
|
||||
mrEnv := make(MultiRepoEnv)
|
||||
mrEnv := &MultiRepoEnv{
|
||||
envs: make([]NamedEnv, 0),
|
||||
}
|
||||
|
||||
for name, path := range nameToPath {
|
||||
absPath, err := fs.Abs(path)
|
||||
|
||||
@@ -234,7 +283,7 @@ func DBNamesAndPathsFromDir(fs filesys.Filesys, path string) ([]EnvNameAndPath,
|
||||
// LoadMultiEnvFromDir looks at each subfolder of the given path as a Dolt repository and attempts to return a MultiRepoEnv
|
||||
// with initialized environments for each of those subfolder data repositories. subfolders whose name starts with '.' are
|
||||
// skipped.
|
||||
func LoadMultiEnvFromDir(ctx context.Context, hdp HomeDirProvider, fs filesys.Filesys, path, version string) (MultiRepoEnv, error) {
|
||||
func LoadMultiEnvFromDir(ctx context.Context, hdp HomeDirProvider, fs filesys.Filesys, path, version string) (*MultiRepoEnv, error) {
|
||||
envNamesAndPaths, err := DBNamesAndPathsFromDir(fs, path)
|
||||
|
||||
if err != nil {
|
||||
|
||||
16
go/libraries/doltcore/env/multi_repo_env_test.go
vendored
16
go/libraries/doltcore/env/multi_repo_env_test.go
vendored
@@ -103,13 +103,13 @@ func TestDoltEnvAsMultiEnv(t *testing.T) {
|
||||
envPath := filepath.Join(rootPath, " test---name _ 123")
|
||||
dEnv := initRepoWithRelativePath(t, envPath, hdp)
|
||||
|
||||
mrEnv, err := DoltEnvAsMultiEnv(dEnv)
|
||||
mrEnv, err := DoltEnvAsMultiEnv(context.Background(), dEnv)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, mrEnv, 1)
|
||||
|
||||
for k, v := range mrEnv {
|
||||
assert.Equal(t, "test_name_123", k)
|
||||
assert.Equal(t, dEnv, v)
|
||||
for _, e := range mrEnv.envs {
|
||||
assert.Equal(t, "test_name_123", e.name)
|
||||
assert.Equal(t, dEnv, e.env)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,8 @@ func TestLoadMultiEnv(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, name := range names {
|
||||
_, ok := mrEnv[name]
|
||||
assert.True(t, ok)
|
||||
e := mrEnv.GetEnv(name)
|
||||
assert.NotNil(t, e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ func TestLoadMultiEnvFromDir(t *testing.T) {
|
||||
dbName := dirNameToDBName[dirName]
|
||||
_, ok := envs[dirName]
|
||||
require.True(t, ok)
|
||||
_, ok = mrEnv[dbName]
|
||||
require.True(t, ok)
|
||||
e := mrEnv.GetEnv(dbName)
|
||||
require.NotNil(t, e)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user