github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/envtestutils/history.go (about) 1 // Copyright 2019 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 envtestutils 16 17 import ( 18 "context" 19 "testing" 20 21 "github.com/stretchr/testify/require" 22 23 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 24 "github.com/dolthub/dolt/go/libraries/doltcore/env" 25 "github.com/dolthub/dolt/go/libraries/doltcore/ref" 26 "github.com/dolthub/dolt/go/libraries/doltcore/row" 27 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 28 "github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding" 29 "github.com/dolthub/dolt/go/store/types" 30 ) 31 32 // TableUpdate defines a list of modifications that should be made to a table 33 type TableUpdate struct { 34 // NewSch is an updated schema for this table. It overwrites the existing value. If not provided the existing value 35 // will not change 36 NewSch schema.Schema 37 38 // NewRowData if provided overwrites the entirety of the row data in the table. 39 NewRowData *types.Map 40 41 // RowUpdates are new values for rows that should be set in the map. They can be updates or inserts. 42 RowUpdates []row.Row 43 } 44 45 // HistoryNode represents a commit to be made 46 type HistoryNode struct { 47 // Branch the branch that the commit should be on 48 Branch string 49 50 // CommitMessag is the commit message that should be applied 51 CommitMsg string 52 53 // Updates are the changes that should be made to the table's states before committing 54 Updates map[string]TableUpdate 55 56 // Children are the child commits of this commit 57 Children []HistoryNode 58 } 59 60 // InitializeWithHistory will go through the provided historyNodes and create the intended commit graph 61 func InitializeWithHistory(t *testing.T, ctx context.Context, dEnv *env.DoltEnv, historyNodes ...HistoryNode) { 62 for _, node := range historyNodes { 63 cs, err := doltdb.NewCommitSpec("master") 64 require.NoError(t, err) 65 66 cm, err := dEnv.DoltDB.Resolve(ctx, cs, nil) 67 require.NoError(t, err) 68 69 processNode(t, ctx, dEnv, node, cm) 70 } 71 } 72 73 func processNode(t *testing.T, ctx context.Context, dEnv *env.DoltEnv, node HistoryNode, parent *doltdb.Commit) { 74 branchRef := ref.NewBranchRef(node.Branch) 75 ok, err := dEnv.DoltDB.HasRef(ctx, branchRef) 76 require.NoError(t, err) 77 78 if !ok { 79 err = dEnv.DoltDB.NewBranchAtCommit(ctx, branchRef, parent) 80 require.NoError(t, err) 81 } 82 83 cs, err := doltdb.NewCommitSpec(branchRef.String()) 84 require.NoError(t, err) 85 86 cm, err := dEnv.DoltDB.Resolve(ctx, cs, nil) 87 require.NoError(t, err) 88 89 root, err := cm.GetRootValue() 90 require.NoError(t, err) 91 92 root = UpdateTables(t, ctx, root, node.Updates) 93 h, err := dEnv.DoltDB.WriteRootValue(ctx, root) 94 require.NoError(t, err) 95 96 meta, err := doltdb.NewCommitMeta("Ash Ketchum", "ash@poke.mon", node.CommitMsg) 97 require.NoError(t, err) 98 99 cm, err = dEnv.DoltDB.Commit(ctx, h, branchRef, meta) 100 require.NoError(t, err) 101 102 for _, child := range node.Children { 103 processNode(t, ctx, dEnv, child, cm) 104 } 105 } 106 107 func UpdateTables(t *testing.T, ctx context.Context, root *doltdb.RootValue, tblUpdates map[string]TableUpdate) *doltdb.RootValue { 108 for tblName, updates := range tblUpdates { 109 tbl, ok, err := root.GetTable(ctx, tblName) 110 require.NoError(t, err) 111 112 var sch schema.Schema 113 if updates.NewSch != nil { 114 sch = updates.NewSch 115 } else { 116 sch, err = tbl.GetSchema(ctx) 117 require.NoError(t, err) 118 } 119 120 var rowData types.Map 121 if updates.NewRowData == nil { 122 if ok { 123 rowData, err = tbl.GetRowData(ctx) 124 require.NoError(t, err) 125 } else { 126 rowData, err = types.NewMap(ctx, root.VRW()) 127 require.NoError(t, err) 128 } 129 } else { 130 rowData = *updates.NewRowData 131 } 132 133 if updates.RowUpdates != nil { 134 me := rowData.Edit() 135 136 for _, r := range updates.RowUpdates { 137 me = me.Set(r.NomsMapKey(sch), r.NomsMapValue(sch)) 138 } 139 140 rowData, err = me.Map(ctx) 141 require.NoError(t, err) 142 } 143 144 schVal, err := encoding.MarshalSchemaAsNomsValue(ctx, root.VRW(), sch) 145 require.NoError(t, err) 146 147 indexData, err := types.NewMap(ctx, root.VRW()) 148 require.NoError(t, err) 149 if tbl != nil { 150 indexData, err = tbl.GetIndexData(ctx) 151 require.NoError(t, err) 152 } 153 tbl, err = doltdb.NewTable(ctx, root.VRW(), schVal, rowData, indexData, nil) 154 require.NoError(t, err) 155 156 root, err = root.PutTable(ctx, tblName, tbl) 157 require.NoError(t, err) 158 } 159 160 return root 161 }