github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/sqle/dprocedures/dolt_fetch.go (about) 1 // Copyright 2022 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package dprocedures 16 17 import ( 18 "fmt" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 22 "github.com/dolthub/dolt/go/cmd/dolt/cli" 23 "github.com/dolthub/dolt/go/libraries/doltcore/branch_control" 24 "github.com/dolthub/dolt/go/libraries/doltcore/dbfactory" 25 "github.com/dolthub/dolt/go/libraries/doltcore/env" 26 "github.com/dolthub/dolt/go/libraries/doltcore/env/actions" 27 "github.com/dolthub/dolt/go/libraries/doltcore/ref" 28 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" 29 "github.com/dolthub/dolt/go/libraries/utils/argparser" 30 ) 31 32 // doltFetch is the stored procedure version for the CLI command `dolt fetch`. 33 func doltFetch(ctx *sql.Context, args ...string) (sql.RowIter, error) { 34 res, err := doDoltFetch(ctx, args) 35 if err != nil { 36 return nil, err 37 } 38 return rowToIter(int64(res)), nil 39 } 40 41 func doDoltFetch(ctx *sql.Context, args []string) (int, error) { 42 dbName := ctx.GetCurrentDatabase() 43 44 if len(dbName) == 0 { 45 return cmdFailure, fmt.Errorf("empty database name") 46 } 47 if err := branch_control.CheckAccess(ctx, branch_control.Permissions_Write); err != nil { 48 return cmdFailure, err 49 } 50 51 sess := dsess.DSessFromSess(ctx.Session) 52 dbData, ok := sess.GetDbData(ctx, dbName) 53 if !ok { 54 return cmdFailure, fmt.Errorf("Could not load database %s", dbName) 55 } 56 57 apr, err := cli.CreateFetchArgParser().Parse(args) 58 if err != nil { 59 return cmdFailure, err 60 } 61 62 remote, refSpecArgs, err := env.RemoteForFetchArgs(apr.Args, dbData.Rsr) 63 if err != nil { 64 return cmdFailure, err 65 } 66 67 validationErr := validateFetchArgs(apr, refSpecArgs) 68 if validationErr != nil { 69 return cmdFailure, validationErr 70 } 71 72 refSpecs, err := env.ParseRefSpecs(refSpecArgs, dbData.Rsr, remote) 73 if err != nil { 74 return cmdFailure, err 75 } 76 77 if user, hasUser := apr.GetValue(cli.UserFlag); hasUser { 78 remote = remote.WithParams(map[string]string{ 79 dbfactory.GRPCUsernameAuthParam: user, 80 }) 81 } 82 83 srcDB, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb.ValueReadWriter().Format(), remote, false) 84 if err != nil { 85 return 1, err 86 } 87 88 prune := apr.Contains(cli.PruneFlag) 89 mode := ref.UpdateMode{Force: true, Prune: prune} 90 err = actions.FetchRefSpecs(ctx, dbData, srcDB, refSpecs, &remote, mode, runProgFuncs, stopProgFuncs) 91 if err != nil { 92 return cmdFailure, fmt.Errorf("fetch failed: %w", err) 93 } 94 return cmdSuccess, nil 95 } 96 97 // validateFetchArgs returns an error if the arguments provided aren't valid. 98 func validateFetchArgs(apr *argparser.ArgParseResults, refSpecArgs []string) error { 99 if len(refSpecArgs) > 0 && apr.Contains(cli.PruneFlag) { 100 // The current prune implementation assumes that we're processing branch specs, which 101 return fmt.Errorf("--prune option cannot be provided with a ref spec") 102 } 103 104 return nil 105 }