This commit is contained in:
VinaiRachakonda
2020-11-24 20:14:17 -05:00
parent 9fa4235a81
commit 0718406bd7
13 changed files with 230 additions and 47 deletions

View File

@@ -123,7 +123,7 @@ func (cmd CommitCmd) Exec(ctx context.Context, commandStr string, args []string,
}
}
err = actions.CommitStaged(ctx, dEnv, actions.CommitStagedProps{
err = actions.CommitStaged(ctx, dEnv.DoltDB, nil, dEnv.RepoStateWriter(), actions.CommitStagedProps{
Message: msg,
Date: t,
AllowEmpty: apr.Contains(allowEmptyFlag),

View File

@@ -42,7 +42,7 @@ func TestParseDate(t *testing.T) {
for _, test := range tests {
t.Run(test.dateStr, func(t *testing.T) {
result, err := parseDate(test.dateStr)
result, err := ParseDate(test.dateStr)
if test.expErr {
assert.Error(t, err)

View File

@@ -114,7 +114,7 @@ func (cmd InitCmd) Exec(ctx context.Context, commandStr string, args []string, d
t := time.Now()
if commitTimeStr, ok := apr.GetValue(dateParam); ok {
var err error
t, err = parseDate(commitTimeStr)
t, err = ParseDate(commitTimeStr)
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError("error: invalid date").AddCause(err).Build(), usage)

View File

@@ -249,7 +249,7 @@ func execNoFFMerge(ctx context.Context, apr *argparser.ArgParseResults, dEnv *en
t := doltdb.CommitNowFunc()
if commitTimeStr, ok := apr.GetValue(dateParam); ok {
var err error
t, err = parseDate(commitTimeStr)
t, err = ParseDate(commitTimeStr)
if err != nil {
return errhand.BuildDError("error: invalid date").AddCause(err).Build()

View File

@@ -77,4 +77,6 @@ require (
replace github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi => ./gen/proto/dolt/services/eventsapi
//replace github.com/dolthub/go-mysql-server => ../../go-mysql-server
go 1.13

View File

@@ -85,7 +85,7 @@ func (rvu RootValueUnreadable) Error() string {
}
// NewDocDiffs returns DocDiffs for Dolt Docs between two roots.
func NewDocDiffs(ctx context.Context, dEnv *env.DoltEnv, older *doltdb.RootValue, newer *doltdb.RootValue, docDetails []doltdb.DocDetails) (*DocDiffs, error) {
func NewDocDiffs(ctx context.Context, older *doltdb.RootValue, newer *doltdb.RootValue, docDetails []doltdb.DocDetails) (*DocDiffs, error) {
var added []string
var modified []string
var removed []string
@@ -136,33 +136,33 @@ func (nd *DocDiffs) Len() int {
}
// GetDocDiffs retrieves staged and unstaged DocDiffs.
func GetDocDiffs(ctx context.Context, dEnv *env.DoltEnv) (*DocDiffs, *DocDiffs, error) {
docDetails, err := dEnv.GetAllValidDocDetails()
func GetDocDiffs(ctx context.Context, ddb *doltdb.DoltDB, reader env.RepoStateReader) (*DocDiffs, *DocDiffs, error) {
docDetails, err := dEnv.GetAllValidDocDetails() // TODO: Doc diffs
if err != nil {
return nil, nil, err
}
workingRoot, err := dEnv.WorkingRoot(ctx)
workingRoot, err := env.WorkingRoot(ctx, ddb, reader)
if err != nil {
return nil, nil, err
}
notStagedDocDiffs, err := NewDocDiffs(ctx, dEnv, workingRoot, nil, docDetails)
notStagedDocDiffs, err := NewDocDiffs(ctx, workingRoot, nil, docDetails)
if err != nil {
return nil, nil, err
}
headRoot, err := dEnv.HeadRoot(ctx)
headRoot, err := env.HeadRoot(ctx, ddb, reader)
if err != nil {
return nil, nil, err
}
stagedRoot, err := dEnv.StagedRoot(ctx)
stagedRoot, err := env.StagedRoot(ctx, ddb, reader)
if err != nil {
return nil, nil, err
}
stagedDocDiffs, err := NewDocDiffs(ctx, dEnv, headRoot, stagedRoot, nil)
stagedDocDiffs, err := NewDocDiffs(ctx, headRoot, stagedRoot, nil)
if err != nil {
return nil, nil, err
}
@@ -288,18 +288,18 @@ func GetTableDeltas(ctx context.Context, fromRoot, toRoot *doltdb.RootValue) (de
return deltas, nil
}
func GetStagedUnstagedTableDeltas(ctx context.Context, dEnv *env.DoltEnv) (staged, unstaged []TableDelta, err error) {
headRoot, err := dEnv.HeadRoot(ctx)
func GetStagedUnstagedTableDeltas(ctx context.Context, ddb *doltdb.DoltDB, reader env.RepoStateReader) (staged, unstaged []TableDelta, err error) {
headRoot, err := env.HeadRoot(ctx, ddb, reader)
if err != nil {
return nil, nil, RootValueUnreadable{HeadRoot, err}
}
stagedRoot, err := dEnv.StagedRoot(ctx)
stagedRoot, err := env.StagedRoot(ctx, ddb, reader)
if err != nil {
return nil, nil, RootValueUnreadable{StagedRoot, err}
}
workingRoot, err := dEnv.WorkingRoot(ctx)
workingRoot, err := env.WorkingRoot(ctx, ddb, reader)
if err != nil {
return nil, nil, RootValueUnreadable{WorkingRoot, err}
}

View File

@@ -222,7 +222,6 @@ func (t *Table) NumRowsInConflict(ctx context.Context) (uint64, error) {
if err != nil {
return 0, err
}
confMap = v.(types.Map)
}

View File

@@ -61,12 +61,16 @@ func GetNameAndEmail(cfg config.ReadableConfig) (string, string, error) {
return name, email, nil
}
func CommitStaged(ctx context.Context, dEnv *env.DoltEnv, props CommitStagedProps) error {
// TODO: Might need to pass in a repo state writer
// Should be able to refer to it
// swap to a rsw
func CommitStaged(ctx context.Context, ddb *doltdb.DoltDB, reader env.RepoStateReader, writer env.RepoStateWriter, props CommitStagedProps) error {
//rsw := dEnv.RepoStateWriter()
if props.Message == "" {
return ErrEmptyCommitMessage
}
staged, notStaged, err := diff.GetStagedUnstagedTableDeltas(ctx, dEnv)
staged, notStaged, err := diff.GetStagedUnstagedTableDeltas(ctx, ddb, reader)
if err != nil {
return err
}
@@ -80,8 +84,8 @@ func CommitStaged(ctx context.Context, dEnv *env.DoltEnv, props CommitStagedProp
stagedTblNames = append(stagedTblNames, n)
}
if len(staged) == 0 && !dEnv.IsMergeActive() && !props.AllowEmpty {
_, notStagedDocs, err := diff.GetDocDiffs(ctx, dEnv)
if len(staged) == 0 && !reader.IsMergeActive() && !props.AllowEmpty {
_, notStagedDocs, err := diff.GetDocDiffs(ctx, ddb, reader)
if err != nil {
return err
}
@@ -89,8 +93,8 @@ func CommitStaged(ctx context.Context, dEnv *env.DoltEnv, props CommitStagedProp
}
var mergeCmSpec []*doltdb.CommitSpec
if dEnv.IsMergeActive() {
root, err := dEnv.WorkingRoot(ctx)
if reader.IsMergeActive() {
root, err := env.WorkingRoot(ctx, ddb, reader)
if err != nil {
return err
}
@@ -102,7 +106,7 @@ func CommitStaged(ctx context.Context, dEnv *env.DoltEnv, props CommitStagedProp
return NewTblInConflictError(inConflict)
}
spec, err := doltdb.NewCommitSpec(dEnv.RepoState.Merge.Commit)
spec, err := doltdb.NewCommitSpec(reader.GetMergeCommit())
if err != nil {
panic("Corrupted repostate. Active merge state is not valid.")
@@ -111,7 +115,7 @@ func CommitStaged(ctx context.Context, dEnv *env.DoltEnv, props CommitStagedProp
mergeCmSpec = []*doltdb.CommitSpec{spec}
}
srt, err := dEnv.StagedRoot(ctx)
srt, err := env.StagedRoot(ctx, ddb, reader)
if err != nil {
return err
@@ -130,13 +134,13 @@ func CommitStaged(ctx context.Context, dEnv *env.DoltEnv, props CommitStagedProp
}
}
h, err := dEnv.UpdateStagedRoot(ctx, srt)
h, err := writer.UpdateStagedRoot(ctx, srt)
if err != nil {
return err
}
wrt, err := dEnv.WorkingRoot(ctx)
wrt, err := env.WorkingRoot(ctx, ddb, reader)
if err != nil {
return err
@@ -148,23 +152,24 @@ func CommitStaged(ctx context.Context, dEnv *env.DoltEnv, props CommitStagedProp
return err
}
err = dEnv.UpdateWorkingRoot(ctx, wrt)
err = env.UpdateWorkingRoot(ctx, ddb, writer, wrt)
if err != nil {
return err
}
meta, noCommitMsgErr := doltdb.NewCommitMetaWithUserTS(props.Name, props.Email, props.Message, props.Date)
if noCommitMsgErr != nil {
return ErrEmptyCommitMessage
}
// DoltDB resolves the current working branch head ref to provide a parent commit.
// Any commit specs in mergeCmSpec are also resolved and added.
_, err = dEnv.DoltDB.CommitWithParentSpecs(ctx, h, dEnv.RepoState.CWBHeadRef(), mergeCmSpec, meta)
_, err = ddb.CommitWithParentSpecs(ctx, h, reader.CWBHeadRef(), mergeCmSpec, meta)
if err == nil {
dEnv.RepoState.ClearMerge(dEnv.FS)
err = writer.ClearMerge()
}
return err

View File

@@ -367,6 +367,32 @@ func (dEnv *DoltEnv) UpdateWorkingRoot(ctx context.Context, newRoot *doltdb.Root
return dEnv.RepoStateWriter().SetWorkingHash(ctx, h)
}
//type repoStateReader struct {
// dEnv *DoltEnv
//}
//
////
////func (r* repoStateReader) CWBHeadRef() ref.DoltRef {
//// return r.dEnv.RepoState.CWBHeadRef()
////}
////
////func (r* repoStateReader) CWBHeadSpec() *doltdb.CommitSpec {
//// return r.dEnv.RepoState.CWBHeadSpec()
////}
////
////func (r* repoStateReader) WorkingHash() hash.Hash {
//// return r.dEnv.RepoState.WorkingHash()
////}
////
////func (r* repoStateReader) StagedHash() hash.Hash {
//// return d.Env.
////}
////
////func (r* repoStateReader) IsMergeActive() bool {
////
////}
type repoStateWriter struct {
dEnv *DoltEnv
}
@@ -382,6 +408,14 @@ func (r *repoStateWriter) SetWorkingHash(ctx context.Context, h hash.Hash) error
return nil
}
func (r *repoStateWriter) UpdateStagedRoot(ctx context.Context, newRoot *doltdb.RootValue) (hash.Hash, error) {
return r.dEnv.UpdateStagedRoot(ctx, newRoot)
}
func (r *repoStateWriter) ClearMerge() error {
return r.dEnv.RepoState.ClearMerge(r.dEnv.FS)
}
func (dEnv *DoltEnv) RepoStateWriter() RepoStateWriter {
return &repoStateWriter{dEnv}
}

View File

@@ -29,12 +29,16 @@ type RepoStateReader interface {
CWBHeadSpec() *doltdb.CommitSpec
WorkingHash() hash.Hash
StagedHash() hash.Hash
IsMergeActive() bool
GetMergeCommit() string
}
type RepoStateWriter interface {
// SetCWBHeadRef(context.Context, ref.DoltRef) error
// SetCWBHeadSpec(context.Context, *doltdb.CommitSpec) error
SetWorkingHash(context.Context, hash.Hash) error
UpdateStagedRoot(ctx context.Context, newRoot *doltdb.RootValue) (hash.Hash, error)
ClearMerge() error
// SetStagedHash(context.Context, hash.Hash) error
}
@@ -169,3 +173,40 @@ func (rs *RepoState) WorkingHash() hash.Hash {
func (rs *RepoState) StagedHash() hash.Hash {
return hash.Parse(rs.Staged)
}
func (rs* RepoState) IsMergeActive() bool {
return rs.Merge != nil
}
func (rs* RepoState) GetMergeCommit() string {
return rs.Merge.Commit
}
func HeadRoot(ctx context.Context, ddb *doltdb.DoltDB, reader RepoStateReader) (*doltdb.RootValue, error) {
commit, err := ddb.ResolveRef(ctx, reader.CWBHeadRef())
if err != nil {
return nil, err
}
return commit.GetRootValue()
}
func StagedRoot(ctx context.Context, ddb *doltdb.DoltDB, reader RepoStateReader) (*doltdb.RootValue, error) {
return ddb.ReadRootValue(ctx, reader.StagedHash())
}
func WorkingRoot(ctx context.Context, ddb *doltdb.DoltDB, reader RepoStateReader) (*doltdb.RootValue, error) {
return ddb.ReadRootValue(ctx, reader.WorkingHash())
}
func UpdateWorkingRoot(ctx context.Context, ddb *doltdb.DoltDB, writer RepoStateWriter, newRoot *doltdb.RootValue) error {
h, err := ddb.WriteRootValue(ctx, newRoot)
if err != nil {
return doltdb.ErrNomsIO
}
return writer.SetWorkingHash(ctx, h)
}

View File

@@ -1,7 +1,10 @@
package dfunctions
import (
"fmt"
"github.com/dolthub/dolt/go/libraries/utils/argparser"
"github.com/dolthub/go-mysql-server/sql"
"strings"
)
const DoltCommitFuncName = "dolt_commit"
@@ -15,31 +18,133 @@ func NewDoltCommitFunc(args ...sql.Expression) (sql.Expression, error) {
return &DoltCommitFunc{children: args}, nil
}
const (
allowEmptyFlag = "allow-empty"
dateParam = "date"
commitMessageArg = "message"
forceFlag = "force"
)
func createArgParser() *argparser.ArgParser {
ap := argparser.NewArgParser()
ap.SupportsString(commitMessageArg, "m", "msg", "Use the given {{.LessThan}}msg{{.GreaterThan}} as the commit message.")
ap.SupportsFlag(allowEmptyFlag, "", "Allow recording a commit that has the exact same data as its sole parent. This is usually a mistake, so it is disabled by default. This option bypasses that safety.")
ap.SupportsString(dateParam, "", "date", "Specify the date used in the commit. If not specified the current system time is used.")
ap.SupportsFlag(forceFlag, "f", "Ignores any foreign key warnings and proceeds with the commit.")
return ap
}
func (d DoltCommitFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
//ap := createArgParser()
// TODO: Ask connection limit here what's up (autocommit disableb? )
// TODO: Help and usage?
// Get the args from the children
//var args []string
//for i := range d.children {
// str := d.children[i].String() // TODO: Do we need to eval here?
// args = append(args, str)
//}
//
//apr := cli.ParseArgs(ap, args, nil) // TODO: Fix usage printer
//
//msg, msgOk := apr.GetValue(commitMessageArg)
//if !msgOk {
// return nil, fmt.Errorf("Must provide commit message.")
//}
//
//t := time.Now()
//if commitTimeStr, ok := apr.GetValue(dateParam); ok {
// var err error
// t, err = commands.ParseDate(commitTimeStr)
//
// if err != nil {
// return nil, fmt.Errorf(err.Error())
// }
//}
//
//dbName := ctx.GetCurrentDatabase()
//dSess := sqle.DSessFromSess(ctx.Session)
// sessions have different dbs. Have different ways of updating. You need to to figure out that
// interaction. Why are we not using denv instead of RepoStateWriter.
// Might need to implement new methods to commit data. After changing methods, change actions
// to take in a repo state writer instead of an environment.
//db, _ := dSess.GetDoltDB(dbName)
//
//err := actions.CommitStaged(ctx, dEnv, actions.CommitStagedProps{
// Message: msg,
// Date: t,
// AllowEmpty: apr.Contains(allowEmptyFlag),
// CheckForeignKeys: !apr.Contains(forceFlag),
//})
// watch how code based from sql engine through debugger all the way to dolt commit
// give myself a couple days. Want to get in with laser focus.
// Spend a couple of days top down. Need to better understand the code base.
// dolt and mysql server are totally. Go-mysql-server is a query planner. The engine has a
// way to say this has a schema.
// core.go in go-mysql-interface (Read this!). Wants to integrate with the query engine
// mysql layer sits on a dolt layer. Dolt implements go-mysql-layer. One capability is
// defining user function. Way to plug in that. Defining these custom functions that hook into
// go-mysql-server.
// dolt layer is independent of the sql layer .
// 1. First job is to a deep dive into a command line function. Look at what happens. See what
// happens when you run these things. Get a feel for how these works. Understand this layer and can't do anything
// above.
/*
* How they change from above them. We'll
*/
// want to flush things to disk.
return "", nil
}
func (d DoltCommitFunc) String() string {
panic("implement me")
childrenStrings := make([]string, len(d.children))
for _, child := range d.children {
childrenStrings = append(childrenStrings, child.String())
}
return fmt.Sprintf("DOLT_COMMIT(%s)", strings.Join(childrenStrings, " "))
}
func (d DoltCommitFunc) Type() sql.Type {
panic("implement me")
return sql.Text
}
func (d DoltCommitFunc) IsNullable() bool {
panic("implement me")
return false
}
func (d DoltCommitFunc) Eval(context *sql.Context, row sql.Row) (interface{}, error) {
panic("implement me")
func (d DoltCommitFunc) WithChildren(children ...sql.Expression) (sql.Expression, error) {
return NewDoltCommitFunc(children...)
}
func (d DoltCommitFunc) WithChildren(expression ...sql.Expression) (sql.Expression, error) {
panic("implement me")
}
func (d DoltCommitFunc) Resolved() bool {
panic("implement me")
//for _, child := range d.children {
// if !child.Resolved() {
// return false
// }
//}
return true
}
func (d DoltCommitFunc) Children() []sql.Expression {
panic("implement me")
return d.children
}

View File

@@ -24,6 +24,3 @@ var DoltFunctions = []sql.Function{
sql.Function0{Name: VersionFuncName, Fn: NewVersion},
sql.FunctionN{Name: DoltCommitFuncName, Fn: NewDoltCommitFunc},
}
// TODO: Add dolt_commit to DoltFunctions

View File

@@ -38,7 +38,7 @@ type dbData struct {
var _ sql.Session = &DoltSession{}
// DoltSession is the sql.Session implementation used by dolt. It is accessible through a *sql.Context instance
type DoltSession struct {
type DoltSession struct {
sql.Session
dbRoots map[string]dbRoot
dbDatas map[string]dbData