github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/dfunctions/commit.go (about)

     1  // Copyright 2020 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 dfunctions
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/dolthub/go-mysql-server/sql"
    22  
    23  	"github.com/dolthub/dolt/go/cmd/dolt/cli"
    24  	"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
    25  	"github.com/dolthub/dolt/go/libraries/doltcore/sqle"
    26  )
    27  
    28  const CommitFuncName = "commit"
    29  
    30  type CommitFunc struct {
    31  	children []sql.Expression
    32  }
    33  
    34  // NewCommitFunc creates a new CommitFunc expression.
    35  func NewCommitFunc(ctx *sql.Context, args ...sql.Expression) (sql.Expression, error) {
    36  	return &CommitFunc{children: args}, nil
    37  }
    38  
    39  // Eval implements the Expression interface.
    40  func (cf *CommitFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
    41  	dbName := ctx.GetCurrentDatabase()
    42  	dSess := sqle.DSessFromSess(ctx.Session)
    43  
    44  	//  Get the params associated with COMMIT.
    45  	ap := cli.CreateCommitArgParser()
    46  	args, err := getDoltArgs(ctx, row, cf.Children())
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	apr, err := ap.Parse(args)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	var name, email string
    57  	if authorStr, ok := apr.GetValue(cli.AuthorParam); ok {
    58  		name, email, err = cli.ParseAuthor(authorStr)
    59  		if err != nil {
    60  			return nil, err
    61  		}
    62  	} else {
    63  		name = dSess.Username
    64  		email = dSess.Email
    65  	}
    66  
    67  	// Get the commit message.
    68  	commitMessage, msgOk := apr.GetValue(cli.CommitMessageArg)
    69  	if !msgOk {
    70  		return nil, fmt.Errorf("Must provide commit message.")
    71  	}
    72  
    73  	parent, _, err := dSess.GetHeadCommit(ctx, dbName)
    74  
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  
    79  	root, ok := dSess.GetRoot(dbName)
    80  	if !ok {
    81  		return nil, fmt.Errorf("unknown database '%s'", dbName)
    82  	}
    83  
    84  	// Update the superschema to with any new information from the table map.
    85  	tblNames, err := root.GetTableNames(ctx)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	root, err = root.UpdateSuperSchemasFromOther(ctx, tblNames, root)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	ddb, ok := dSess.GetDoltDB(dbName)
    96  
    97  	if !ok {
    98  		return nil, sql.ErrDatabaseNotFound.New(dbName)
    99  	}
   100  
   101  	h, err := ddb.WriteRootValue(ctx, root)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	meta, err := doltdb.NewCommitMeta(name, email, commitMessage)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  
   111  	cm, err := ddb.CommitDanglingWithParentCommits(ctx, h, []*doltdb.Commit{parent}, meta)
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  
   116  	h, err = cm.HashOf()
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	return h.String(), nil
   122  }
   123  
   124  // String implements the Stringer interface.
   125  func (cf *CommitFunc) String() string {
   126  	childrenStrings := make([]string, len(cf.children))
   127  
   128  	for i, child := range cf.children {
   129  		childrenStrings[i] = child.String()
   130  	}
   131  
   132  	return fmt.Sprintf("COMMIT(%s)", strings.Join(childrenStrings, ","))
   133  }
   134  
   135  // IsNullable implements the Expression interface.
   136  func (cf *CommitFunc) IsNullable() bool {
   137  	return false
   138  }
   139  
   140  func (cf *CommitFunc) Resolved() bool {
   141  	for _, child := range cf.Children() {
   142  		if !child.Resolved() {
   143  			return false
   144  		}
   145  	}
   146  	return true
   147  }
   148  
   149  func (cf *CommitFunc) Children() []sql.Expression {
   150  	return cf.children
   151  }
   152  
   153  // WithChildren implements the Expression interface.
   154  func (cf *CommitFunc) WithChildren(ctx *sql.Context, children ...sql.Expression) (sql.Expression, error) {
   155  	return NewCommitFunc(ctx, children...)
   156  }
   157  
   158  func (cf *CommitFunc) Type() sql.Type {
   159  	return sql.Text
   160  }