Vinai/refactor docs (#1210)

This pr does a massive refactor of the internal state management with docs.
This commit is contained in:
Vinai Rachakonda
2021-01-25 17:00:27 -05:00
committed by GitHub
parent 223d3bedfc
commit 3342b8d58f
38 changed files with 1349 additions and 1229 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ teardown() {
teardown_common
}
@test "dolt status and ls to view valid docs on dolt init" {
@test "dolt status and ls to view supported docs on dolt init" {
echo license-text > LICENSE.md
echo readme-text > README.md
run ls
+3 -2
View File
@@ -21,6 +21,7 @@ import (
"github.com/dolthub/dolt/go/cmd/dolt/errhand"
eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/env/actions"
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
@@ -121,7 +122,7 @@ func (cmd CheckoutCmd) Exec(ctx context.Context, commandStr string, args []strin
return HandleVErrAndExitCode(verr, usagePrt)
}
tbls, docs, err := actions.GetTblsAndDocDetails(dEnv.DocsReadWriter(), args)
tbls, docs, err := actions.GetTablesOrDocs(dEnv.DocsReadWriter(), args)
if err != nil {
verr := errhand.BuildDError("error: unable to parse arguments.").AddCause(err).Build()
return HandleVErrAndExitCode(verr, usagePrt)
@@ -189,7 +190,7 @@ func checkoutNewBranch(ctx context.Context, dEnv *env.DoltEnv, newBranch string,
return checkoutBranch(ctx, dEnv, newBranch)
}
func checkoutTablesAndDocs(ctx context.Context, dEnv *env.DoltEnv, tables []string, docs []doltdb.DocDetails) errhand.VerboseError {
func checkoutTablesAndDocs(ctx context.Context, dEnv *env.DoltEnv, tables []string, docs doltdocs.Docs) errhand.VerboseError {
err := actions.CheckoutTablesAndDocs(ctx, dEnv, tables, docs)
if err != nil {
+41 -40
View File
@@ -30,6 +30,7 @@ import (
eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1"
"github.com/dolthub/dolt/go/libraries/doltcore/diff"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/env/actions"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
@@ -244,7 +245,7 @@ func parseDiffArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
dArgs.docSet = set.NewStrSet(nil)
for _, arg := range leftover {
if arg == doltdb.ReadmePk || arg == doltdb.LicensePk {
if arg == doltdocs.ReadmeDoc || arg == doltdocs.LicenseDoc {
dArgs.docSet.Add(arg)
continue
}
@@ -275,7 +276,7 @@ func parseDiffArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
return nil, nil, nil, err
}
dArgs.tableSet.Add(utn...)
dArgs.docSet.Add(doltdb.ReadmePk, doltdb.LicensePk)
dArgs.docSet.Add(doltdocs.ReadmeDoc, doltdocs.LicenseDoc)
}
return from, to, dArgs, nil
@@ -283,7 +284,21 @@ func parseDiffArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
func getDiffRoots(ctx context.Context, dEnv *env.DoltEnv, args []string) (from, to *doltdb.RootValue, leftover []string, err error) {
headRoot, err := dEnv.StagedRoot(ctx)
workingRoot, err := dEnv.WorkingRootWithDocs(ctx)
if err != nil {
return nil, nil, nil, err
}
workingRoot, err := dEnv.WorkingRoot(ctx)
if err != nil {
return nil, nil, nil, err
}
docs, err := dEnv.DocsReadWriter().GetDocsOnDisk()
if err != nil {
return nil, nil, nil, err
}
workingRoot, err = doltdocs.UpdateRootWithDocs(ctx, workingRoot, docs)
if err != nil {
return nil, nil, nil, err
}
@@ -876,59 +891,45 @@ func createSplitter(ctx context.Context, vrw types.ValueReadWriter, fromSch sche
}
func diffDoltDocs(ctx context.Context, dEnv *env.DoltEnv, from, to *doltdb.RootValue, dArgs *diffArgs) error {
_, docDetails, err := actions.GetTblsAndDocDetails(dEnv.DocsReadWriter(), dArgs.docSet.AsSlice())
_, docs, err := actions.GetTablesOrDocs(dEnv.DocsReadWriter(), dArgs.docSet.AsSlice())
if err != nil {
return err
}
fromDocTable, _, err := from.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return err
}
toDocTable, _, err := to.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return err
}
printDocDiffs(ctx, dEnv, fromDocTable, toDocTable, docDetails)
return nil
return printDocDiffs(ctx, from, to, docs)
}
func printDocDiffs(ctx context.Context, dEnv *env.DoltEnv, fromTbl, toTbl *doltdb.Table, docDetails []doltdb.DocDetails) {
func printDocDiffs(ctx context.Context, from, to *doltdb.RootValue, docsFilter doltdocs.Docs) error {
bold := color.New(color.Bold)
if docDetails == nil {
docDetails, _ = dEnv.GetAllValidDocDetails()
comparisons, err := diff.DocsDiffToComparisons(ctx, from, to, docsFilter)
if err != nil {
return err
}
for _, doc := range docDetails {
if toTbl != nil {
sch1, _ := toTbl.GetSchema(ctx)
doc, _ = doltdb.AddNewerTextToDocFromTbl(ctx, toTbl, &sch1, doc)
for _, doc := range docsFilter {
for _, comparison := range comparisons {
if doc.DocPk == comparison.DocName {
if comparison.OldText == nil && comparison.CurrentText != nil {
printAddedDoc(bold, comparison.DocName)
} else if comparison.OldText != nil {
older := string(comparison.OldText)
newer := string(comparison.CurrentText)
}
if fromTbl != nil {
sch2, _ := fromTbl.GetSchema(ctx)
doc, _ = doltdb.AddValueToDocFromTbl(ctx, fromTbl, &sch2, doc)
}
lines := textdiff.LineDiffAsLines(older, newer)
if doc.Value != nil {
newer := string(doc.NewerText)
older, _ := strconv.Unquote(doc.Value.HumanReadableString())
lines := textdiff.LineDiffAsLines(older, newer)
if doc.NewerText == nil {
printDeletedDoc(bold, doc.DocPk, lines)
} else if len(lines) > 0 && newer != older {
printModifiedDoc(bold, doc.DocPk, lines)
if comparison.CurrentText == nil {
printDeletedDoc(bold, comparison.DocName, lines)
} else if len(lines) > 0 && newer != older {
printModifiedDoc(bold, comparison.DocName, lines)
}
}
}
} else if doc.Value == nil && doc.NewerText != nil {
printAddedDoc(bold, doc.DocPk)
}
}
return nil
}
func printDiffLines(bold *color.Color, lines []string) {
+2 -2
View File
@@ -322,7 +322,7 @@ func executeFFMerge(ctx context.Context, squash bool, dEnv *env.DoltEnv, cm2 *do
}
}
unstagedDocs, err := actions.GetUnstagedDocs(ctx, dEnv)
unstagedDocs, err := actions.GetUnstagedDocs(ctx, dEnv.DbData())
if err != nil {
return errhand.BuildDError("error: unable to determine unstaged docs").AddCause(err).Build()
}
@@ -401,7 +401,7 @@ func mergedRootToWorking(ctx context.Context, squash bool, dEnv *env.DoltEnv, me
}
}
unstagedDocs, err := actions.GetUnstagedDocs(ctx, dEnv)
unstagedDocs, err := actions.GetUnstagedDocs(ctx, dEnv.DbData())
if err != nil {
return errhand.BuildDError("error: failed to determine unstaged docs").AddCause(err).Build()
}
+1 -1
View File
@@ -94,7 +94,7 @@ func (cmd ResetCmd) Exec(ctx context.Context, commandStr string, args []string,
} else if apr.Contains(HardResetParam) {
err = actions.ResetHard(ctx, dEnv, apr, workingRoot, stagedRoot, headRoot)
} else {
stagedRoot, err = actions.ResetSoft(ctx, dEnv, apr, stagedRoot, headRoot)
stagedRoot, err = actions.ResetSoft(ctx, dEnv.DbData(), apr, stagedRoot, headRoot)
if err != nil {
return handleResetError(err, usage)
@@ -0,0 +1,174 @@
// Copyright 2020 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package diff
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
"github.com/dolthub/dolt/go/store/types"
)
func TestDocDiff(t *testing.T) {
ctx := context.Background()
ddb, _ := doltdb.LoadDoltDB(ctx, types.Format_7_18, doltdb.InMemDoltDB)
ddb.WriteEmptyRepo(ctx, "billy bob", "bigbillieb@fake.horse")
cs, _ := doltdb.NewCommitSpec("master")
cm, _ := ddb.Resolve(ctx, cs, nil)
root, err := cm.GetRootValue()
assert.NoError(t, err)
docs := doltdocs.Docs{
{DocPk: doltdocs.LicenseDoc},
{DocPk: doltdocs.ReadmeDoc},
}
// DocsDiff between a root and itself should return no added, modified or removed docs.
added, modified, removed, err := DocsDiff(ctx, root, root, docs)
assert.NoError(t, err)
if len(added)+len(modified)+len(removed) != 0 {
t.Error("Bad doc diff when comparing two repos")
}
// Create tbl1 with one license row
sch := createTestDocsSchema()
licRow := makeDocRow(t, sch, doltdocs.LicenseDoc, types.String("license row"))
m, _ := createTestRows(t, ddb.ValueReadWriter(), sch, []row.Row{licRow})
tbl1, err := CreateTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// Create root2 with tbl1 on it (one doc: license)
root2, err := root.PutTable(ctx, doltdb.DocTableName, tbl1)
assert.NoError(t, err)
// DocsDiff between root and root2 should return one added doc, LICENSE.md
added, modified, removed, err = DocsDiff(ctx, root, root2, docs)
assert.NoError(t, err)
if len(added) != 1 || added[0] != "LICENSE.md" || len(modified)+len(removed) != 0 {
t.Error("Bad table diff after adding a single table")
}
// Create tbl2 with one readme row
readmeRow := makeDocRow(t, sch, doltdocs.ReadmeDoc, types.String("readme row"))
m, _ = createTestRows(t, ddb.ValueReadWriter(), sch, []row.Row{readmeRow})
tbl2, err := CreateTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// Create root3 with tbl2 on it (one doc: readme)
root3, err := root.PutTable(ctx, doltdb.DocTableName, tbl2)
assert.NoError(t, err)
// DocsDiff between root2 and root3 should return one removed doc (license) and one added doc (readme).
added, modified, removed, err = DocsDiff(ctx, root2, root3, docs)
assert.NoError(t, err)
if len(removed) != 1 || removed[0] != "LICENSE.md" || len(added) != 1 || added[0] != "README.md" || len(modified) != 0 {
t.Error("Bad table diff after adding a single table")
}
// Create tbl3 with 2 doc rows (readme, license)
readmeRowUpdated := makeDocRow(t, sch, doltdocs.ReadmeDoc, types.String("a different readme"))
m, _ = createTestRows(t, ddb.ValueReadWriter(), sch, []row.Row{readmeRowUpdated, licRow})
tbl3, err := CreateTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// Create root4 with tbl3 on it (two docs: readme and license)
root4, err := root3.PutTable(ctx, doltdb.DocTableName, tbl3)
assert.NoError(t, err)
// DocsDiff between root3 and root4 should return one added doc (license) and one modified doc (readme).
added, modified, removed, err = DocsDiff(ctx, root3, root4, nil)
assert.NoError(t, err)
if len(added) != 1 || added[0] != "LICENSE.md" || len(modified) != 1 || modified[0] != "README.md" || len(removed) != 0 {
t.Error("Bad table diff after adding a single table")
}
// DocsDiff between root4 and root shows 2 remove docs (license, readme)
added, modified, removed, err = DocsDiff(ctx, root4, root, nil)
assert.NoError(t, err)
if len(removed) != 2 || len(modified) != 0 || len(added) != 0 {
t.Error("Bad table diff after adding a single table")
}
}
func CreateTestTable(vrw types.ValueReadWriter, tSchema schema.Schema, rowData types.Map) (*doltdb.Table, error) {
schemaVal, err := encoding.MarshalSchemaAsNomsValue(context.Background(), vrw, tSchema)
if err != nil {
return nil, err
}
empty, _ := types.NewMap(context.Background(), vrw)
tbl, err := doltdb.NewTable(context.Background(), vrw, schemaVal, rowData, empty)
if err != nil {
return nil, err
}
return tbl, nil
}
func createTestDocsSchema() schema.Schema {
typedColColl, _ := schema.NewColCollection(
schema.NewColumn(doltdb.DocPkColumnName, schema.DocNameTag, types.StringKind, true, schema.NotNullConstraint{}),
schema.NewColumn(doltdb.DocTextColumnName, schema.DocTextTag, types.StringKind, false),
)
sch, err := schema.SchemaFromCols(typedColColl)
if err != nil {
panic(err)
}
return sch
}
func makeDocRow(t *testing.T, sch schema.Schema, pk string, rowVal types.Value) row.Row {
row, err := row.New(types.Format_7_18, sch, row.TaggedValues{
schema.DocNameTag: types.String(pk),
schema.DocTextTag: rowVal,
})
assert.NoError(t, err)
return row
}
func createTestRows(t *testing.T, vrw types.ValueReadWriter, sch schema.Schema, rows []row.Row) (types.Map, []row.Row) {
ctx := context.Background()
var err error
m, err := types.NewMap(ctx, vrw)
assert.NoError(t, err)
ed := m.Edit()
for _, r := range rows {
ed = ed.Set(r.NomsMapKey(sch), r.NomsMapValue(sch))
}
m, err = ed.Map(ctx)
assert.NoError(t, err)
return m, rows
}
+144
View File
@@ -0,0 +1,144 @@
// Copyright 2020 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package diff
import (
"context"
"strconv"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
)
type docComparison struct {
DocName string
CurrentText []byte
OldText []byte
}
// DocsDiff returns the added, modified and removed docs when comparing a root value with an other (newer) value. If the other value,
// is not provided, then we compare the docs on the root value to the docs provided.
func DocsDiff(ctx context.Context, root *doltdb.RootValue, other *doltdb.RootValue, docs doltdocs.Docs) (added, modified, removed []string, err error) {
docComparisons, err := DocsDiffToComparisons(ctx, root, other, docs)
if err != nil {
return nil, nil, nil, err
}
a, m, r := computeDiffsFromDocComparisons(docComparisons)
return a, m, r, nil
}
// DocsDiffToComparisons returns the docComparisons between an old root, a new root, and a set of docs. It is exported
// due to the cli usage of doc diffs.
func DocsDiffToComparisons(ctx context.Context, root *doltdb.RootValue, other *doltdb.RootValue, docs doltdocs.Docs) ([]docComparison, error) {
if other == nil {
return compareRootWithDocs(ctx, root, docs)
} else {
return compareDocsBtwnRoots(ctx, root, other)
}
}
// compareRootWithDocs compares a root and set of new docs.
func compareRootWithDocs(ctx context.Context, root *doltdb.RootValue, docs doltdocs.Docs) ([]docComparison, error) {
oldDocs, found, err := doltdocs.GetAllDocs(ctx, root)
if err != nil {
return nil, err
}
if !found {
oldDocs = make(doltdocs.Docs, 0)
}
return getDocComparisons(oldDocs, docs), nil
}
// compareDocsBtwnRoots takes an oldRoot and a newRoot and compares the docs tables between the two.
func compareDocsBtwnRoots(ctx context.Context, oldRoot *doltdb.RootValue, newRoot *doltdb.RootValue) ([]docComparison, error) {
oldDocs, found, err := doltdocs.GetAllDocs(ctx, oldRoot)
if err != nil {
return nil, err
}
if !found {
oldDocs = make(doltdocs.Docs, 0)
}
newDocs, found, err := doltdocs.GetAllDocs(ctx, newRoot)
if err != nil {
return nil, err
}
if !found {
newDocs = make(doltdocs.Docs, 0)
}
return getDocComparisons(oldDocs, newDocs), nil
}
// getDocComparisons compares two sets of docs looking for modifications, removals, and additions as docComparisons
func getDocComparisons(oldDocs doltdocs.Docs, newDocs doltdocs.Docs) []docComparison {
docComparisons := make([]docComparison, 0)
// First case is looking at the old docs and seeing what was modified or removed
for _, oldDoc := range oldDocs {
dc := docComparison{DocName: oldDoc.DocPk, OldText: oldDoc.Text, CurrentText: getMatchingText(oldDoc, newDocs)}
docComparisons = append(docComparisons, dc)
}
// Second case is looking back at the old docs and seeing what was added
for _, newDoc := range newDocs {
oldText := getMatchingText(newDoc, oldDocs)
if oldText == nil {
dc := docComparison{DocName: newDoc.DocPk, OldText: nil, CurrentText: newDoc.Text}
docComparisons = append(docComparisons, dc)
}
}
return docComparisons
}
// getMatchingText matches a doc in a set of other docs and returns the relevant text.
func getMatchingText(doc doltdocs.Doc, docs doltdocs.Docs) []byte {
for _, toCompare := range docs {
if doc.DocPk == toCompare.DocPk {
return toCompare.Text
}
}
return nil
}
// computeDiffsFromDocComparisons takes the docComparisons and returns the final add, modified, removed count.
func computeDiffsFromDocComparisons(docComparisons []docComparison) (added, modified, removed []string) {
added = []string{}
modified = []string{}
removed = []string{}
for _, doc := range docComparisons {
added, modified, removed = appendDocDiffs(added, modified, removed, doc.OldText, doc.CurrentText, doc.DocName)
}
return added, modified, removed
}
func appendDocDiffs(added, modified, removed []string, olderVal []byte, newerVal []byte, docPk string) (add, mod, rem []string) {
if olderVal == nil && newerVal != nil {
added = append(added, docPk)
} else if olderVal != nil {
if newerVal == nil {
removed = append(removed, docPk)
} else if strconv.Quote(string(olderVal)) != strconv.Quote(string(newerVal)) {
modified = append(modified, docPk)
}
}
return added, modified, removed
}
+14 -13
View File
@@ -19,11 +19,12 @@ import (
"fmt"
"sort"
"github.com/dolthub/dolt/go/libraries/utils/set"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/utils/set"
"github.com/dolthub/dolt/go/store/hash"
"github.com/dolthub/dolt/go/store/types"
)
@@ -88,13 +89,13 @@ func (rvu RootValueUnreadable) Error() string {
}
// NewDocDiffs returns DocDiffs for Dolt Docs between two roots.
func NewDocDiffs(ctx context.Context, older *doltdb.RootValue, newer *doltdb.RootValue, docDetails []doltdb.DocDetails) (*DocDiffs, error) {
func NewDocDiffs(ctx context.Context, older *doltdb.RootValue, newer *doltdb.RootValue, docs doltdocs.Docs) (*DocDiffs, error) {
var added []string
var modified []string
var removed []string
if older != nil {
if newer == nil {
a, m, r, err := older.DocDiff(ctx, nil, docDetails)
a, m, r, err := DocsDiff(ctx, older, nil, docs)
if err != nil {
return nil, err
}
@@ -102,7 +103,7 @@ func NewDocDiffs(ctx context.Context, older *doltdb.RootValue, newer *doltdb.Roo
modified = m
removed = r
} else {
a, m, r, err := older.DocDiff(ctx, newer, docDetails)
a, m, r, err := DocsDiff(ctx, older, newer, docs)
if err != nil {
return nil, err
}
@@ -111,11 +112,11 @@ func NewDocDiffs(ctx context.Context, older *doltdb.RootValue, newer *doltdb.Roo
removed = r
}
}
var docs []string
docs = append(docs, added...)
docs = append(docs, modified...)
docs = append(docs, removed...)
sort.Strings(docs)
var docNames []string
docNames = append(docNames, added...)
docNames = append(docNames, modified...)
docNames = append(docNames, removed...)
sort.Strings(docNames)
docsToType := make(map[string]DocDiffType)
for _, nt := range added {
@@ -130,7 +131,7 @@ func NewDocDiffs(ctx context.Context, older *doltdb.RootValue, newer *doltdb.Roo
docsToType[nt] = RemovedDoc
}
return &DocDiffs{len(added), len(modified), len(removed), docsToType, docs}, nil
return &DocDiffs{len(added), len(modified), len(removed), docsToType, docNames}, nil
}
// Len returns the number of docs in a DocDiffs
@@ -140,7 +141,7 @@ func (nd *DocDiffs) Len() int {
// GetDocDiffs retrieves staged and unstaged DocDiffs.
func GetDocDiffs(ctx context.Context, ddb *doltdb.DoltDB, rsr env.RepoStateReader, drw env.DocsReadWriter) (*DocDiffs, *DocDiffs, error) {
docDetails, err := drw.GetAllValidDocDetails()
docsOnDisk, err := drw.GetDocsOnDisk()
if err != nil {
return nil, nil, err
}
@@ -150,7 +151,7 @@ func GetDocDiffs(ctx context.Context, ddb *doltdb.DoltDB, rsr env.RepoStateReade
return nil, nil, err
}
notStagedDocDiffs, err := NewDocDiffs(ctx, workingRoot, nil, docDetails)
notStagedDocDiffs, err := NewDocDiffs(ctx, workingRoot, nil, docsOnDisk)
if err != nil {
return nil, nil, err
}
@@ -165,7 +166,7 @@ func GetDocDiffs(ctx context.Context, ddb *doltdb.DoltDB, rsr env.RepoStateReade
return nil, nil, err
}
stagedDocDiffs, err := NewDocDiffs(ctx, headRoot, stagedRoot, docDetails)
stagedDocDiffs, err := NewDocDiffs(ctx, headRoot, stagedRoot, docsOnDisk)
if err != nil {
return nil, nil, err
}
-16
View File
@@ -1,16 +0,0 @@
// Copyright 2019 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package doltcore contains the packages for storing, and manipulating versioned data in dolt.
package doltcore
-17
View File
@@ -1,17 +0,0 @@
// Copyright 2019 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package doltdb provides a specific schema on top of noms and provides methods and objects for interacting with data
// stored in this schema.
package doltdb
-43
View File
@@ -1,43 +0,0 @@
// Copyright 2020 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package doltdb
import (
"context"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/store/types"
)
func DocTblKeyFromName(fmt *types.NomsBinFormat, name string) (types.Tuple, error) {
return types.NewTuple(fmt, types.Uint(schema.DocNameTag), types.String(name))
}
func getDocRow(ctx context.Context, docTbl *Table, sch schema.Schema, key types.Tuple) (r row.Row, ok bool, err error) {
rowMap, err := docTbl.GetRowData(ctx)
if err != nil {
return nil, false, err
}
var fields types.Value
fields, ok, err = rowMap.MaybeGet(ctx, key)
if err != nil || !ok {
return nil, ok, err
}
r, err = row.FromNoms(sch, key, fields.(types.Tuple))
return
}
+2 -2
View File
@@ -69,7 +69,7 @@ func createTestSchema(t *testing.T) schema.Schema {
return sch
}
func createTestTable(vrw types.ValueReadWriter, tSchema schema.Schema, rowData types.Map) (*Table, error) {
func CreateTestTable(vrw types.ValueReadWriter, tSchema schema.Schema, rowData types.Map) (*Table, error) {
schemaVal, err := encoding.MarshalSchemaAsNomsValue(context.Background(), vrw, tSchema)
if err != nil {
@@ -290,7 +290,7 @@ func TestLDNoms(t *testing.T) {
tSchema := createTestSchema(t)
rowData, _ := createTestRowData(t, ddb.db, tSchema)
tbl, err = createTestTable(ddb.db, tSchema, rowData)
tbl, err = CreateTestTable(ddb.db, tSchema, rowData)
if err != nil {
t.Fatal("Failed to create test table with data")
-240
View File
@@ -18,10 +18,8 @@ import (
"context"
"errors"
"fmt"
"strconv"
"strings"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
"github.com/dolthub/dolt/go/libraries/utils/set"
@@ -45,13 +43,6 @@ type RootValue struct {
fkc *ForeignKeyCollection // cache the first load
}
type DocDetails struct {
NewerText []byte
DocPk string
Value types.Value
File string
}
func NewRootValue(ctx context.Context, vrw types.ValueReadWriter, tables map[string]hash.Hash, ssMap types.Map, fkMap types.Map) (*RootValue, error) {
values := make([]types.Value, 2*len(tables))
@@ -1024,54 +1015,6 @@ func (root *RootValue) RemoveTables(ctx context.Context, tables ...string) (*Roo
return newRoot.PutForeignKeyCollection(ctx, fkc)
}
// DocDiff returns the added, modified and removed docs when comparing a root value with an other (newer) value. If the other value,
// is not provided, then we compare the docs on the root value to the docDetails provided.
func (root *RootValue) DocDiff(ctx context.Context, other *RootValue, docDetails []DocDetails) (added, modified, removed []string, err error) {
oldTbl, oldTblFound, err := root.GetTable(ctx, DocTableName)
if err != nil {
return nil, nil, nil, err
}
var oldSch schema.Schema
if oldTblFound {
sch, err := oldTbl.GetSchema(ctx)
if err != nil {
return nil, nil, nil, err
}
oldSch = sch
}
if other == nil {
detailsWithValues, err := addValuesToDocs(ctx, oldTbl, &oldSch, docDetails)
if err != nil {
return nil, nil, nil, err
}
a, m, r := GetDocDiffsFromDocDetails(ctx, detailsWithValues)
return a, m, r, nil
}
newTbl, newTblFound, err := other.GetTable(ctx, DocTableName)
if err != nil {
return nil, nil, nil, err
}
var newSch schema.Schema
if newTblFound {
sch, err := newTbl.GetSchema(ctx)
if err != nil {
return nil, nil, nil, err
}
newSch = sch
}
docDetailsBtwnRoots, err := getDocDetailsBtwnRoots(ctx, newTbl, newSch, newTblFound, oldTbl, oldSch, oldTblFound)
if err != nil {
return nil, nil, nil, err
}
a, m, r := GetDocDiffsFromDocDetails(ctx, docDetailsBtwnRoots)
return a, m, r, nil
}
// GetForeignKeyCollection returns the ForeignKeyCollection for this root. As collections are meant to be modified
// in-place, each returned collection may freely be altered without affecting future returned collections from this root.
func (root *RootValue) GetForeignKeyCollection(ctx context.Context) (*ForeignKeyCollection, error) {
@@ -1176,189 +1119,6 @@ func (root *RootValue) ValidateForeignKeys(ctx context.Context) (*RootValue, err
return root.PutForeignKeyCollection(ctx, fkCollection)
}
func getDocDetailsBtwnRoots(ctx context.Context, newTbl *Table, newSch schema.Schema, newTblFound bool, oldTbl *Table, oldSch schema.Schema, oldTblFound bool) ([]DocDetails, error) {
var docDetailsBtwnRoots []DocDetails
if newTblFound {
newRows, err := newTbl.GetRowData(ctx)
if err != nil {
return nil, err
}
err = newRows.IterAll(ctx, func(key, val types.Value) error {
newRow, err := row.FromNoms(newSch, key.(types.Tuple), val.(types.Tuple))
if err != nil {
return err
}
doc := DocDetails{}
updated, err := addDocPKToDocFromRow(newRow, &doc)
if err != nil {
return err
}
updated, err = addNewerTextToDocFromRow(ctx, newRow, &updated)
if err != nil {
return err
}
updated, err = AddValueToDocFromTbl(ctx, oldTbl, &oldSch, updated)
if err != nil {
return err
}
docDetailsBtwnRoots = append(docDetailsBtwnRoots, updated)
return nil
})
if err != nil {
return nil, err
}
}
if oldTblFound {
oldRows, err := oldTbl.GetRowData(ctx)
if err != nil {
return nil, err
}
err = oldRows.IterAll(ctx, func(key, val types.Value) error {
oldRow, err := row.FromNoms(oldSch, key.(types.Tuple), val.(types.Tuple))
if err != nil {
return err
}
doc := DocDetails{}
updated, err := addDocPKToDocFromRow(oldRow, &doc)
if err != nil {
return err
}
updated, err = AddValueToDocFromTbl(ctx, oldTbl, &oldSch, updated)
if err != nil {
return err
}
updated, err = AddNewerTextToDocFromTbl(ctx, newTbl, &newSch, updated)
if err != nil {
return err
}
if updated.Value != nil && updated.NewerText == nil {
docDetailsBtwnRoots = append(docDetailsBtwnRoots, updated)
}
return nil
})
if err != nil {
return nil, err
}
}
return docDetailsBtwnRoots, nil
}
func GetDocDiffsFromDocDetails(ctx context.Context, docDetails []DocDetails) (added, modified, removed []string) {
added = []string{}
modified = []string{}
removed = []string{}
for _, doc := range docDetails {
added, modified, removed = appendDocDiffs(added, modified, removed, doc.Value, doc.NewerText, doc.DocPk)
}
return added, modified, removed
}
func addValuesToDocs(ctx context.Context, tbl *Table, sch *schema.Schema, docDetails []DocDetails) ([]DocDetails, error) {
if tbl != nil && sch != nil {
for i, details := range docDetails {
newDetails, err := AddValueToDocFromTbl(ctx, tbl, sch, details)
if err != nil {
return nil, err
}
docDetails[i] = newDetails
}
}
return docDetails, nil
}
// AddValueToDocFromTbl updates the Value field of a docDetail using the provided table and schema.
func AddValueToDocFromTbl(ctx context.Context, tbl *Table, sch *schema.Schema, docDetail DocDetails) (DocDetails, error) {
if tbl != nil && sch != nil {
key, err := DocTblKeyFromName(tbl.Format(), docDetail.DocPk)
if err != nil {
return DocDetails{}, err
}
docRow, ok, err := getDocRow(ctx, tbl, *sch, key)
if err != nil {
return DocDetails{}, err
}
if ok {
docValue, _ := docRow.GetColVal(schema.DocTextTag)
docDetail.Value = docValue
} else {
docDetail.Value = nil
}
} else {
docDetail.Value = nil
}
return docDetail, nil
}
// AddNewerTextToDocFromTbl updates the NewerText field of a docDetail using the provided table and schema.
func AddNewerTextToDocFromTbl(ctx context.Context, tbl *Table, sch *schema.Schema, doc DocDetails) (DocDetails, error) {
if tbl != nil && sch != nil {
key, err := DocTblKeyFromName(tbl.Format(), doc.DocPk)
if err != nil {
return DocDetails{}, err
}
docRow, ok, err := getDocRow(ctx, tbl, *sch, key)
if err != nil {
return DocDetails{}, err
}
if ok {
docValue, _ := docRow.GetColVal(schema.DocTextTag)
doc.NewerText = []byte(docValue.(types.String))
} else {
doc.NewerText = nil
}
} else {
doc.NewerText = nil
}
return doc, nil
}
func addNewerTextToDocFromRow(ctx context.Context, r row.Row, doc *DocDetails) (DocDetails, error) {
docValue, ok := r.GetColVal(schema.DocTextTag)
if !ok {
doc.NewerText = nil
} else {
docValStr, err := strconv.Unquote(docValue.HumanReadableString())
if err != nil {
return DocDetails{}, err
}
doc.NewerText = []byte(docValStr)
}
return *doc, nil
}
func addDocPKToDocFromRow(r row.Row, doc *DocDetails) (DocDetails, error) {
colVal, _ := r.GetColVal(schema.DocNameTag)
if colVal == nil {
doc.DocPk = ""
} else {
docName, err := strconv.Unquote(colVal.HumanReadableString())
if err != nil {
return DocDetails{}, err
}
doc.DocPk = docName
}
return *doc, nil
}
func appendDocDiffs(added, modified, removed []string, olderVal types.Value, newerVal []byte, docPk string) (add, mod, rem []string) {
if olderVal == nil && newerVal != nil {
added = append(added, docPk)
} else if olderVal != nil {
if newerVal == nil {
removed = append(removed, docPk)
} else if olderVal.HumanReadableString() != strconv.Quote(string(newerVal)) {
modified = append(modified, docPk)
}
}
return added, modified, removed
}
// RootNeedsUniqueTagsMigration determines if this root needs to be migrated to uniquify its tags.
func RootNeedsUniqueTagsMigration(root *RootValue) (bool, error) {
// SuperSchemas were added in the same update that required unique tags. If a root does not have a
@@ -1,271 +0,0 @@
// Copyright 2019 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package doltdb
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/store/types"
)
func TestDocDiff(t *testing.T) {
ctx := context.Background()
ddb, _ := LoadDoltDB(ctx, types.Format_7_18, InMemDoltDB)
ddb.WriteEmptyRepo(ctx, "billy bob", "bigbillieb@fake.horse")
cs, _ := NewCommitSpec("master")
cm, _ := ddb.Resolve(ctx, cs, nil)
root, err := cm.GetRootValue()
assert.NoError(t, err)
docDetails := []DocDetails{
{DocPk: LicensePk},
{DocPk: ReadmePk},
}
// DocDiff between a root and itself should return no added, modified or removed docs.
added, modified, removed, err := root.DocDiff(ctx, root, docDetails)
assert.NoError(t, err)
if len(added)+len(modified)+len(removed) != 0 {
t.Error("Bad doc diff when comparing two repos")
}
// Create tbl1 with one license row
sch := createTestDocsSchema()
licRow := makeDocRow(t, sch, LicensePk, types.String("license row"))
m, _ := createTestRows(t, ddb.ValueReadWriter(), sch, []row.Row{licRow})
tbl1, err := createTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// Create root2 with tbl1 on it (one doc: license)
root2, err := root.PutTable(ctx, DocTableName, tbl1)
assert.NoError(t, err)
// DocDiff between root and root2 should return one added doc, LICENSE.md
added, modified, removed, err = root.DocDiff(ctx, root2, docDetails)
assert.NoError(t, err)
if len(added) != 1 || added[0] != "LICENSE.md" || len(modified)+len(removed) != 0 {
t.Error("Bad table diff after adding a single table")
}
// Create tbl2 with one readme row
readmeRow := makeDocRow(t, sch, ReadmePk, types.String("readme row"))
m, _ = createTestRows(t, ddb.ValueReadWriter(), sch, []row.Row{readmeRow})
tbl2, err := createTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// Create root3 with tbl2 on it (one doc: readme)
root3, err := root.PutTable(ctx, DocTableName, tbl2)
assert.NoError(t, err)
// DocDiff between root2 and root3 should return one removed doc (license) and one added doc (readme).
added, modified, removed, err = root2.DocDiff(ctx, root3, docDetails)
assert.NoError(t, err)
if len(removed) != 1 || removed[0] != "LICENSE.md" || len(added) != 1 || added[0] != "README.md" || len(modified) != 0 {
t.Error("Bad table diff after adding a single table")
}
// Create tbl3 with 2 doc rows (readme, license)
readmeRowUpdated := makeDocRow(t, sch, ReadmePk, types.String("a different readme"))
m, _ = createTestRows(t, ddb.ValueReadWriter(), sch, []row.Row{readmeRowUpdated, licRow})
tbl3, err := createTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// Create root4 with tbl3 on it (two docs: readme and license)
root4, err := root3.PutTable(ctx, DocTableName, tbl3)
assert.NoError(t, err)
// DocDiff between root3 and root4 should return one added doc (license) and one modified doc (readme).
added, modified, removed, err = root3.DocDiff(ctx, root4, nil)
assert.NoError(t, err)
if len(added) != 1 || added[0] != "LICENSE.md" || len(modified) != 1 || modified[0] != "README.md" || len(removed) != 0 {
t.Error("Bad table diff after adding a single table")
}
// DocDiff between root4 and root shows 2 remove docs (license, readme)
added, modified, removed, err = root4.DocDiff(ctx, root, nil)
assert.NoError(t, err)
if len(removed) != 2 || len(modified) != 0 || len(added) != 0 {
t.Error("Bad table diff after adding a single table")
}
}
func TestAddNewerTextAndValueFromTable(t *testing.T) {
ctx := context.Background()
ddb, _ := LoadDoltDB(ctx, types.Format_7_18, InMemDoltDB)
ddb.WriteEmptyRepo(ctx, "billy bob", "bigbillieb@fake.horse")
// If no tbl/schema is provided, doc NewerText and Value should be nil.
doc1 := DocDetails{DocPk: LicensePk}
doc1, err := AddNewerTextToDocFromTbl(ctx, nil, nil, doc1)
assert.NoError(t, err)
assert.Nil(t, doc1.NewerText)
doc1, err = AddValueToDocFromTbl(ctx, nil, nil, doc1)
assert.NoError(t, err)
assert.Nil(t, doc1.Value)
// Create table with no rows
sch := createTestDocsSchema()
rows := []row.Row{}
m, _ := createTestRows(t, ddb.ValueReadWriter(), sch, rows)
tbl, err := createTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// If a table doesn't have doc row, doc NewerText and Value should remain nil
doc2 := DocDetails{DocPk: LicensePk}
doc2, err = AddNewerTextToDocFromTbl(ctx, tbl, &sch, doc2)
assert.NoError(t, err)
assert.Nil(t, doc2.NewerText)
doc2, err = AddValueToDocFromTbl(ctx, tbl, &sch, doc2)
assert.NoError(t, err)
assert.Nil(t, doc2.Value)
// If a table doesn't have doc row, and NewerText and Value are originally non-nil, they should be updated to nil.
doc3 := DocDetails{DocPk: LicensePk, NewerText: []byte("Something in newer text field"), Value: types.String("something")}
doc3, err = AddNewerTextToDocFromTbl(ctx, tbl, &sch, doc3)
assert.NoError(t, err)
assert.Nil(t, doc3.NewerText)
doc3, err = AddValueToDocFromTbl(ctx, tbl, &sch, doc3)
assert.NoError(t, err)
assert.Nil(t, doc3.Value)
// Update tbl to have 2 doc rows, readme and license
rows = getDocRows(t, sch, types.String("text in doc_text"))
m, _ = createTestRows(t, ddb.ValueReadWriter(), sch, rows)
tbl, err = createTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// If a table has a doc row, NewerText and Value and should be updated to the `doc_text` value in that row.
doc4 := DocDetails{DocPk: LicensePk, NewerText: []byte("Something in newer text field")}
doc4, err = AddNewerTextToDocFromTbl(ctx, tbl, &sch, doc4)
assert.NoError(t, err)
assert.Equal(t, "text in doc_text", string(doc4.NewerText))
doc4, err = AddValueToDocFromTbl(ctx, tbl, &sch, doc4)
assert.NoError(t, err)
assert.Equal(t, types.String("text in doc_text"), doc4.Value)
// If a table has a doc row, and NewerText and Value are originally non-nil, they should be updated to the `doc_text` value.
doc5 := DocDetails{DocPk: LicensePk}
doc5, err = AddNewerTextToDocFromTbl(ctx, tbl, &sch, doc5)
assert.NoError(t, err)
assert.Equal(t, "text in doc_text", string(doc5.NewerText))
doc5, err = AddValueToDocFromTbl(ctx, tbl, &sch, doc5)
assert.NoError(t, err)
assert.Equal(t, types.String("text in doc_text"), doc5.Value)
}
func TestAddNewerTextAndDocPkFromRow(t *testing.T) {
ctx := context.Background()
ddb, _ := LoadDoltDB(ctx, types.Format_7_18, InMemDoltDB)
ddb.WriteEmptyRepo(ctx, "billy bob", "bigbillieb@fake.horse")
sch := createTestDocsSchema()
emptyRow, err := row.New(types.Format_7_18, sch, row.TaggedValues{})
// NewerText and DocPk should be nil from an empty row
doc1 := DocDetails{}
doc1, err = addNewerTextToDocFromRow(ctx, emptyRow, &doc1)
assert.NoError(t, err)
assert.Nil(t, doc1.NewerText)
doc1, err = addDocPKToDocFromRow(emptyRow, &doc1)
assert.NoError(t, err)
assert.Equal(t, "", doc1.DocPk)
licenseRow, err := row.New(types.Format_7_18, sch, row.TaggedValues{
schema.DocNameTag: types.String(LicensePk),
schema.DocTextTag: types.String("license!"),
})
assert.NoError(t, err)
// NewerText and DocPk should be added to doc from row
doc2 := DocDetails{}
doc2, err = addNewerTextToDocFromRow(ctx, licenseRow, &doc2)
assert.NoError(t, err)
assert.Equal(t, "license!", string(doc2.NewerText))
doc1, err = addDocPKToDocFromRow(licenseRow, &doc2)
assert.NoError(t, err)
assert.Equal(t, LicensePk, doc2.DocPk)
// When NewerText and DocPk are non-nil, they should be updated from the row provided.
doc3 := DocDetails{DocPk: "invalid", NewerText: []byte("something")}
doc3, err = addNewerTextToDocFromRow(ctx, licenseRow, &doc3)
assert.NoError(t, err)
assert.Equal(t, "license!", string(doc3.NewerText))
doc3, err = addDocPKToDocFromRow(licenseRow, &doc3)
assert.NoError(t, err)
assert.Equal(t, LicensePk, doc3.DocPk)
}
func createTestDocsSchema() schema.Schema {
typedColColl, _ := schema.NewColCollection(
schema.NewColumn(DocPkColumnName, schema.DocNameTag, types.StringKind, true, schema.NotNullConstraint{}),
schema.NewColumn(DocTextColumnName, schema.DocTextTag, types.StringKind, false),
)
sch, err := schema.SchemaFromCols(typedColColl)
if err != nil {
panic(err)
}
return sch
}
func getDocRows(t *testing.T, sch schema.Schema, rowVal types.Value) []row.Row {
rows := make([]row.Row, 2)
row1 := makeDocRow(t, sch, LicensePk, rowVal)
rows[0] = row1
row2 := makeDocRow(t, sch, ReadmePk, rowVal)
rows[1] = row2
return rows
}
func makeDocRow(t *testing.T, sch schema.Schema, pk string, rowVal types.Value) row.Row {
row, err := row.New(types.Format_7_18, sch, row.TaggedValues{
schema.DocNameTag: types.String(pk),
schema.DocTextTag: rowVal,
})
assert.NoError(t, err)
return row
}
func createTestRows(t *testing.T, vrw types.ValueReadWriter, sch schema.Schema, rows []row.Row) (types.Map, []row.Row) {
ctx := context.Background()
var err error
m, err := types.NewMap(ctx, vrw)
assert.NoError(t, err)
ed := m.Edit()
for _, r := range rows {
ed = ed.Set(r.NomsMapKey(sch), r.NomsMapValue(sch))
}
m, err = ed.Map(ctx)
assert.NoError(t, err)
return m, rows
}
@@ -147,10 +147,6 @@ var generatedSystemTablePrefixes = []string{
const (
// DocTableName is the name of the dolt table containing documents such as the license and readme
DocTableName = "dolt_docs"
// LicensePk is the key for accessing the license within the docs table
LicensePk = "LICENSE.md"
// ReadmePk is the key for accessing the readme within the docs table
ReadmePk = "README.md"
// DocPkColumnName is the name of the pk column in the docs table
DocPkColumnName = "doc_name"
//DocTextColumnName is the name of the column containing the document contents in the docs table
+250
View File
@@ -0,0 +1,250 @@
// Copyright 2020 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package doltdocs
import (
"context"
"errors"
"fmt"
"path/filepath"
"github.com/dolthub/dolt/go/libraries/doltcore/dbfactory"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/utils/filesys"
"github.com/dolthub/dolt/go/store/types"
)
var ErrDocsUpdate = errors.New("error updating local docs")
var ErrEmptyDocsTable = errors.New("error: All docs removed. Removing Docs Table")
var ErrMarshallingSchema = errors.New("error marshalling schema")
var doltDocsColumns, _ = schema.NewColCollection(
schema.NewColumn(doltdb.DocPkColumnName, schema.DocNameTag, types.StringKind, true, schema.NotNullConstraint{}),
schema.NewColumn(doltdb.DocTextColumnName, schema.DocTextTag, types.StringKind, false),
)
var DoltDocsSchema = schema.MustSchemaFromCols(doltDocsColumns)
type Doc struct {
Text []byte
DocPk string
File string
}
type Docs []Doc
const (
ReadmeFile = "../README.md"
LicenseFile = "../LICENSE.md"
// LicenseDoc is the key for accessing the license within the docs table
LicenseDoc = "LICENSE.md"
// ReadmeDoc is the key for accessing the readme within the docs table
ReadmeDoc = "README.md"
)
var SupportedDocs = Docs{
{DocPk: ReadmeDoc, File: ReadmeFile},
{DocPk: LicenseDoc, File: LicenseFile},
}
// GetLocalFileText returns a byte slice representing the contents of the provided file, if it exists
func GetLocalFileText(fs filesys.Filesys, file string) ([]byte, error) {
path := ""
if DocFileExists(fs, file) {
path = GetDocFilePath(file)
}
if path != "" {
return fs.ReadFile(path)
}
return nil, nil
}
// GetSupportedDocs takes in a filesystem and returns the contents of all docs on disk.
func GetSupportedDocs(fs filesys.Filesys) (docs Docs, err error) {
docs = Docs{}
for _, doc := range SupportedDocs {
newerText, err := GetLocalFileText(fs, doc.File)
if err != nil {
return nil, err
}
doc.Text = newerText
docs = append(docs, doc)
}
return docs, nil
}
// GetDoc takes in a filesystem and a docName and returns the doc's contents.
func GetDoc(fs filesys.Filesys, docName string) (doc Doc, err error) {
for _, doc := range SupportedDocs {
if doc.DocPk == docName {
newerText, err := GetLocalFileText(fs, doc.File)
if err != nil {
return Doc{}, err
}
doc.Text = newerText
return doc, nil
}
}
return Doc{}, err
}
func GetDocNamesFromDocs(docs Docs) []string {
if docs == nil {
return nil
}
ret := make([]string, len(docs))
for i, doc := range docs {
ret[i] = doc.DocPk
}
return ret
}
// GetDocsFromRoot takes in a root value and returns the docs stored in its dolt_docs table.
func GetDocsFromRoot(ctx context.Context, root *doltdb.RootValue, docNames ...string) (Docs, error) {
docTbl, docTblFound, err := root.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return nil, err
}
var sch schema.Schema
if docTblFound {
docSch, err := docTbl.GetSchema(ctx)
if err != nil {
return nil, err
}
sch = docSch
}
if docNames == nil {
docNames = GetDocNamesFromDocs(SupportedDocs)
}
docs := make(Docs, len(docNames))
for i, name := range docNames {
doc, isSupported := IsSupportedDoc(name)
if !isSupported {
return nil, fmt.Errorf("%s is not a supported doc", name)
}
docText, err := getDocTextFromTbl(ctx, docTbl, &sch, name)
if err != nil {
return nil, err
}
doc.Text = docText
docs[i] = doc
}
return docs, nil
}
// Save takes in a fs object and saves all the docs to the filesystem, overwriting any existing files.
func (docs Docs) Save(fs filesys.ReadWriteFS) error {
for _, doc := range docs {
if _, ok := IsSupportedDoc(doc.DocPk); !ok {
continue
}
filePath := GetDocFilePath(doc.File)
if doc.Text != nil {
err := fs.WriteFile(filePath, doc.Text)
if err != nil {
return err
}
} else {
err := DeleteDoc(fs, doc.DocPk)
if err != nil {
return err
}
}
}
return nil
}
// GetDocFilePath takes in a filename and appends it to the DoltDir filepath.
func GetDocFilePath(filename string) string {
return filepath.Join(dbfactory.DoltDir, filename)
}
// LoadDocs takes in a fs object and reads all the docs (ex. README.md) defined in SupportedDocs.
func LoadDocs(fs filesys.ReadWriteFS) (Docs, error) {
docsWithCurrentText := SupportedDocs
for i, val := range docsWithCurrentText {
path := GetDocFilePath(val.File)
exists, isDir := fs.Exists(path)
if exists && !isDir {
data, err := fs.ReadFile(path)
if err != nil {
return nil, err
}
val.Text = data
docsWithCurrentText[i] = val
}
}
return docsWithCurrentText, nil
}
func IsSupportedDoc(docName string) (Doc, bool) {
for _, doc := range SupportedDocs {
if doc.DocPk == docName {
return doc, true
}
}
return Doc{}, false
}
func DocFileExists(fs filesys.ReadWriteFS, file string) bool {
exists, isDir := fs.Exists(GetDocFilePath(file))
return exists && !isDir
}
// DeleteDoc takes in a filesytem object and deletes the file with docName, if it's a SupportedDoc.
func DeleteDoc(fs filesys.ReadWriteFS, docName string) error {
if doc, ok := IsSupportedDoc(docName); ok {
if doc.DocPk == docName {
path := GetDocFilePath(doc.File)
exists, isDir := fs.Exists(path)
if exists && !isDir {
return fs.DeleteFile(path)
}
}
}
return nil
}
// UpdateRootWithDocs takes in a root value, and some docs and writes those docs to the dolt_docs table
// (perhaps creating it in the process). The table might not necessarily need to be created if there are no docs in the
// repo yet.
func UpdateRootWithDocs(ctx context.Context, root *doltdb.RootValue, docs Docs) (*doltdb.RootValue, error) {
docTbl, err := CreateOrUpdateDocsTable(ctx, root, docs)
if errors.Is(ErrEmptyDocsTable, err) {
root, err = root.RemoveTables(ctx, doltdb.DocTableName)
} else if err != nil {
return nil, err
}
// There might not need be a need to create docs table if not docs have been created yet so check if docTbl != nil.
if docTbl != nil {
root, err = root.PutTable(ctx, doltdb.DocTableName, docTbl)
}
return root, nil
}
@@ -0,0 +1,296 @@
// Copyright 2020 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package doltdocs
import (
"context"
"errors"
"fmt"
"strconv"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
"github.com/dolthub/dolt/go/libraries/doltcore/table"
"github.com/dolthub/dolt/go/libraries/doltcore/table/typed/noms"
"github.com/dolthub/dolt/go/store/types"
)
// updateDocsTable takes in docTbl param and updates it with the value in docs. It returns the updated table.
func updateDocsTable(ctx context.Context, docTbl *doltdb.Table, docs Docs) (*doltdb.Table, error) {
m, err := docTbl.GetRowData(ctx)
if err != nil {
return nil, err
}
sch, err := docTbl.GetSchema(context.Background())
if err != nil {
return nil, err
}
me := m.Edit()
for _, doc := range docs {
key, err := docTblKeyFromName(docTbl.Format(), doc.DocPk)
if err != nil {
return nil, err
}
docRow, exists, err := table.GetRow(ctx, docTbl, sch, key)
if err != nil {
return nil, err
}
if exists && doc.Text == nil {
me = me.Remove(docRow.NomsMapKey(sch))
} else if doc.Text != nil {
docTaggedVals := row.TaggedValues{
schema.DocNameTag: types.String(doc.DocPk),
schema.DocTextTag: types.String(doc.Text),
}
docRow, err = row.New(types.Format_7_18, sch, docTaggedVals)
if err != nil {
return nil, err
}
me = me.Set(docRow.NomsMapKey(sch), docRow.NomsMapValue(sch))
}
}
updatedMap, err := me.Map(ctx)
if updatedMap.Len() == 0 {
return nil, ErrEmptyDocsTable
}
docTbl, err = docTbl.UpdateRows(ctx, updatedMap)
return docTbl, err
}
// createDocsTable creates a new in memory table that stores the given doc details.
func createDocsTable(ctx context.Context, vrw types.ValueReadWriter, docs Docs) (*doltdb.Table, error) {
imt := table.NewInMemTable(DoltDocsSchema)
// Determines if the table needs to be created at all and initializes a schema if it does.
createTable := false
for _, doc := range docs {
if doc.Text != nil {
createTable = true
docTaggedVals := row.TaggedValues{
schema.DocNameTag: types.String(doc.DocPk),
schema.DocTextTag: types.String(doc.Text),
}
docRow, err := row.New(types.Format_7_18, DoltDocsSchema, docTaggedVals)
if err != nil {
return nil, err
}
err = imt.AppendRow(docRow)
if err != nil {
return nil, err
}
}
}
if createTable {
rd := table.NewInMemTableReader(imt)
wr := noms.NewNomsMapCreator(context.Background(), vrw, DoltDocsSchema)
_, _, err := table.PipeRows(context.Background(), rd, wr, false)
if err != nil {
return nil, err
}
rd.Close(context.Background())
wr.Close(context.Background())
schVal, err := encoding.MarshalSchemaAsNomsValue(ctx, vrw, wr.GetSchema())
if err != nil {
return nil, ErrMarshallingSchema
}
empty, err := types.NewMap(ctx, vrw)
if err != nil {
return nil, err
}
newDocsTbl, err := doltdb.NewTable(ctx, vrw, schVal, wr.GetMap(), empty)
if err != nil {
return nil, err
}
return newDocsTbl, nil
}
return nil, nil
}
// CreateOrUpdateDocsTable takes a root value and a set of docs and either creates the docs table or updates it with docs.
func CreateOrUpdateDocsTable(ctx context.Context, root *doltdb.RootValue, docs Docs) (*doltdb.Table, error) {
docsTbl, found, err := root.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return nil, err
}
if found {
return updateDocsTable(ctx, docsTbl, docs)
} else {
return createDocsTable(ctx, root.VRW(), docs)
}
}
func docTblKeyFromName(fmt *types.NomsBinFormat, name string) (types.Tuple, error) {
return types.NewTuple(fmt, types.Uint(schema.DocNameTag), types.String(name))
}
// getDocTextFromTbl returns the Text field of a doc using the provided table and schema and primary key.
func getDocTextFromTbl(ctx context.Context, tbl *doltdb.Table, sch *schema.Schema, docPk string) ([]byte, error) {
if tbl != nil && sch != nil {
key, err := docTblKeyFromName(tbl.Format(), docPk)
if err != nil {
return nil, err
}
docRow, ok, err := getDocRow(ctx, tbl, *sch, key)
if err != nil {
return nil, err
}
if ok {
docValue, _ := docRow.GetColVal(schema.DocTextTag)
return []byte(docValue.(types.String)), nil
} else {
return nil, nil
}
} else {
return nil, nil
}
}
// getDocRow returns the associated row of a particular doc from the docTbl given.
func getDocRow(ctx context.Context, docTbl *doltdb.Table, sch schema.Schema, key types.Tuple) (r row.Row, ok bool, err error) {
rowMap, err := docTbl.GetRowData(ctx)
if err != nil {
return nil, false, err
}
var fields types.Value
fields, ok, err = rowMap.MaybeGet(ctx, key)
if err != nil || !ok {
return nil, ok, err
}
r, err = row.FromNoms(sch, key, fields.(types.Tuple))
return r, ok, err
}
// getDocTextFromRow updates return the text field of a provided row.
func getDocTextFromRow(r row.Row) ([]byte, error) {
docValue, ok := r.GetColVal(schema.DocTextTag)
if !ok {
return nil, nil
} else {
docValStr, err := strconv.Unquote(docValue.HumanReadableString())
if err != nil {
return nil, err
}
return []byte(docValStr), nil
}
}
// getDocPKFromRow updates returns the docPk field of a given row.
func getDocPKFromRow(r row.Row) (string, error) {
colVal, _ := r.GetColVal(schema.DocNameTag)
if colVal == nil {
return "", nil
} else {
docName, err := strconv.Unquote(colVal.HumanReadableString())
if err != nil {
return "", err
}
return docName, nil
}
}
// getFileFromDoc returns the file obj associated with the doc
func getFileFromDoc(docName string) (string, error) {
if doc, ok := IsSupportedDoc(docName); ok {
return doc.File, nil
}
return "", fmt.Errorf("Doc name not provided %s", docName)
}
// GetAllDocs takes a root value and returns all the docs available in the root.
func GetAllDocs(ctx context.Context, root *doltdb.RootValue) (Docs, bool, error) {
if root == nil {
return nil, false, nil
}
docsTbl, found, err := root.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return nil, false, err
}
if !found {
return nil, false, err
}
docs, err := getDocsFromTable(ctx, docsTbl)
return docs, true, err
}
// getDocsFromTable takes the doltdocs table and a schema and return all docs in the dolt_docs table.
func getDocsFromTable(ctx context.Context, table *doltdb.Table) (Docs, error) {
ret := make(Docs, 0)
sch, err := table.GetSchema(ctx)
if err != nil {
return nil, err
}
rows, err := table.GetRowData(ctx)
if err != nil {
return nil, err
}
err = rows.IterAll(ctx, func(key, val types.Value) error {
newRow, err := row.FromNoms(sch, key.(types.Tuple), val.(types.Tuple))
if err != nil {
return err
}
cols := sch.GetAllCols().GetColumns()
colVals := make([]types.Value, len(cols))
for i, col := range cols {
colval, ok := newRow.GetColVal(col.Tag)
if !ok {
return errors.New("error: could not get doc column value")
}
colVals[i] = colval
}
if len(colVals) < 2 {
return errors.New("error: not enough values read from the table")
}
doc := Doc{}
doc.DocPk = string(colVals[0].(types.String))
doc.Text = []byte(colVals[1].(types.String))
ret = append(ret, doc)
return nil
})
return ret, err
}
+197
View File
@@ -0,0 +1,197 @@
// Copyright 2020 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package doltdocs
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
"github.com/dolthub/dolt/go/store/types"
)
func TestAddNewerTextAndValueFromTable(t *testing.T) {
ctx := context.Background()
ddb, _ := doltdb.LoadDoltDB(ctx, types.Format_7_18, doltdb.InMemDoltDB)
ddb.WriteEmptyRepo(ctx, "billy bob", "bigbillieb@fake.horse")
// If no tbl/schema is provided, doc Text and Value should be nil.
doc1 := Doc{DocPk: LicenseDoc}
doc1Text, err := getDocTextFromTbl(ctx, nil, nil, doc1.DocPk)
assert.NoError(t, err)
doc1.Text = doc1Text
assert.Nil(t, doc1.Text)
// Create table with no rows
sch := createTestDocsSchema()
rows := []row.Row{}
m, _ := createTestRows(t, ddb.ValueReadWriter(), sch, rows)
tbl, err := CreateTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// If a table doesn't have doc row, doc Text and Value should remain nil
doc2 := Doc{DocPk: LicenseDoc}
doc2Text, err := getDocTextFromTbl(ctx, tbl, &sch, doc2.DocPk)
assert.NoError(t, err)
doc2.Text = doc2Text
assert.Nil(t, doc2.Text)
// If a table doesn't have doc row, and Text and Value are originally non-nil, they should be updated to nil.
doc3 := Doc{DocPk: LicenseDoc, Text: []byte("Something in newer text field")}
doc3Text, err := getDocTextFromTbl(ctx, tbl, &sch, doc3.DocPk)
assert.NoError(t, err)
doc3.Text = doc3Text
assert.Nil(t, doc3.Text)
// Update tbl to have 2 doc rows, readme and license
rows = getDocRows(t, sch, types.String("text in doc_text"))
m, _ = createTestRows(t, ddb.ValueReadWriter(), sch, rows)
tbl, err = CreateTestTable(ddb.ValueReadWriter(), sch, m)
assert.NoError(t, err)
// If a table has a doc row, Text and Value and should be updated to the `doc_text` value in that row.
doc4 := Doc{DocPk: LicenseDoc, Text: []byte("Something in newer text field")}
doc4Text, err := getDocTextFromTbl(ctx, tbl, &sch, doc4.DocPk)
assert.NoError(t, err)
doc4.Text = doc4Text
assert.Equal(t, "text in doc_text", string(doc4.Text))
// If a table has a doc row, and Text and Value are originally non-nil, they should be updated to the `doc_text` value.
doc5 := Doc{DocPk: LicenseDoc}
doc5Text, err := getDocTextFromTbl(ctx, tbl, &sch, doc5.DocPk)
assert.NoError(t, err)
doc5.Text = doc5Text
assert.Equal(t, "text in doc_text", string(doc5.Text))
}
func TestAddNewerTextAndDocPkFromRow(t *testing.T) {
ctx := context.Background()
ddb, _ := doltdb.LoadDoltDB(ctx, types.Format_7_18, doltdb.InMemDoltDB)
ddb.WriteEmptyRepo(ctx, "billy bob", "bigbillieb@fake.horse")
sch := createTestDocsSchema()
emptyRow, err := row.New(types.Format_7_18, sch, row.TaggedValues{})
// Text and DocName should be nil from an empty row
doc1 := Doc{}
text, err := getDocTextFromRow(emptyRow)
assert.NoError(t, err)
assert.Nil(t, text)
docPk, err := getDocPKFromRow(emptyRow)
assert.NoError(t, err)
doc1.DocPk = docPk
assert.Equal(t, "", doc1.DocPk)
licenseRow, err := row.New(types.Format_7_18, sch, row.TaggedValues{
schema.DocNameTag: types.String(LicenseDoc),
schema.DocTextTag: types.String("license!"),
})
assert.NoError(t, err)
// Text and DocName should be added to doc from row
doc2 := Doc{}
text, err = getDocTextFromRow(licenseRow)
assert.NoError(t, err)
doc2.Text = text
assert.Equal(t, "license!", string(doc2.Text))
docPk, err = getDocPKFromRow(licenseRow)
assert.NoError(t, err)
doc2.DocPk = docPk
assert.Equal(t, LicenseDoc, doc2.DocPk)
// When Text and DocName are non-nil, they should be updated from the row provided.
doc3 := Doc{DocPk: "invalid", Text: []byte("something")}
text, err = getDocTextFromRow(licenseRow)
assert.NoError(t, err)
doc3.Text = text
assert.Equal(t, "license!", string(doc3.Text))
docPk, err = getDocPKFromRow(licenseRow)
assert.NoError(t, err)
doc3.DocPk = docPk
assert.Equal(t, LicenseDoc, doc3.DocPk)
}
func CreateTestTable(vrw types.ValueReadWriter, tSchema schema.Schema, rowData types.Map) (*doltdb.Table, error) {
schemaVal, err := encoding.MarshalSchemaAsNomsValue(context.Background(), vrw, tSchema)
if err != nil {
return nil, err
}
empty, _ := types.NewMap(context.Background(), vrw)
tbl, err := doltdb.NewTable(context.Background(), vrw, schemaVal, rowData, empty)
if err != nil {
return nil, err
}
return tbl, nil
}
func createTestDocsSchema() schema.Schema {
typedColColl, _ := schema.NewColCollection(
schema.NewColumn(doltdb.DocPkColumnName, schema.DocNameTag, types.StringKind, true, schema.NotNullConstraint{}),
schema.NewColumn(doltdb.DocTextColumnName, schema.DocTextTag, types.StringKind, false),
)
sch, err := schema.SchemaFromCols(typedColColl)
if err != nil {
panic(err)
}
return sch
}
func getDocRows(t *testing.T, sch schema.Schema, rowVal types.Value) []row.Row {
rows := make([]row.Row, 2)
row1 := makeDocRow(t, sch, LicenseDoc, rowVal)
rows[0] = row1
row2 := makeDocRow(t, sch, ReadmeDoc, rowVal)
rows[1] = row2
return rows
}
func makeDocRow(t *testing.T, sch schema.Schema, pk string, rowVal types.Value) row.Row {
row, err := row.New(types.Format_7_18, sch, row.TaggedValues{
schema.DocNameTag: types.String(pk),
schema.DocTextTag: rowVal,
})
assert.NoError(t, err)
return row
}
func createTestRows(t *testing.T, vrw types.ValueReadWriter, sch schema.Schema, rows []row.Row) (types.Map, []row.Row) {
ctx := context.Background()
var err error
m, err := types.NewMap(ctx, vrw)
assert.NoError(t, err)
ed := m.Edit()
for _, r := range rows {
ed = ed.Set(r.NomsMapKey(sch), r.NomsMapValue(sch))
}
m, err = ed.Map(ctx)
assert.NoError(t, err)
return m, rows
}
+1 -1
View File
@@ -264,7 +264,7 @@ func CheckoutBranch(ctx context.Context, dEnv *env.DoltEnv, brName string) error
return err
}
unstagedDocs, err := GetUnstagedDocs(ctx, dEnv)
unstagedDocs, err := GetUnstagedDocs(ctx, dEnv.DbData())
if err != nil {
return err
}
-16
View File
@@ -1,16 +0,0 @@
// Copyright 2019 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package actions contains utility methods for inspecting and manipulating a dolt data repository's state.
package actions
+71 -32
View File
@@ -16,6 +16,9 @@ package actions
import (
"context"
"errors"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/diff"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
@@ -30,7 +33,7 @@ func SaveTrackedDocsFromWorking(ctx context.Context, dEnv *env.DoltEnv) error {
return err
}
return SaveTrackedDocs(ctx, dEnv, workingRoot, workingRoot, localDocs)
return SaveTrackedDocs(ctx, dEnv.DocsReadWriter(), workingRoot, workingRoot, localDocs)
}
// SaveDocsFromWorking saves docs from the working root to the filesystem, and could overwrite untracked docs.
@@ -46,11 +49,17 @@ func SaveDocsFromWorking(ctx context.Context, dEnv *env.DoltEnv) error {
// SaveDocsFromRoot saves docs from the root given to the filesystem, and could overwrite untracked docs.
func SaveDocsFromRoot(ctx context.Context, root *doltdb.RootValue, dEnv *env.DoltEnv) error {
localDocs := dEnv.Docs
drw := dEnv.DocsReadWriter()
err := dEnv.UpdateFSDocsToRootDocs(ctx, root, nil)
docs, err := doltdocs.GetDocsFromRoot(ctx, root, doltdocs.GetDocNamesFromDocs(doltdocs.SupportedDocs)...)
if err != nil {
return err
}
err = drw.WriteDocsToDisk(docs)
if err != nil {
// If we can't update docs on disk, attempt to revert the change
localDocs.Save(dEnv.FS)
drw.WriteDocsToDisk(localDocs)
return err
}
@@ -58,7 +67,7 @@ func SaveDocsFromRoot(ctx context.Context, root *doltdb.RootValue, dEnv *env.Dol
}
// SaveTrackedDocs writes the docs from the targetRoot to the filesystem. The working root is used to identify untracked docs, which are left unchanged.
func SaveTrackedDocs(ctx context.Context, dEnv *env.DoltEnv, workRoot, targetRoot *doltdb.RootValue, localDocs env.Docs) error {
func SaveTrackedDocs(ctx context.Context, drw env.DocsReadWriter, workRoot, targetRoot *doltdb.RootValue, localDocs doltdocs.Docs) error {
docDiffs, err := diff.NewDocDiffs(ctx, workRoot, nil, localDocs)
if err != nil {
return err
@@ -66,21 +75,22 @@ func SaveTrackedDocs(ctx context.Context, dEnv *env.DoltEnv, workRoot, targetRoo
docs := removeUntrackedDocs(localDocs, docDiffs)
err = dEnv.UpdateFSDocsToRootDocs(ctx, targetRoot, docs)
docs, err = doltdocs.GetDocsFromRoot(ctx, targetRoot, doltdocs.GetDocNamesFromDocs(docs)...)
if err != nil {
localDocs.Save(dEnv.FS)
return err
}
err = drw.WriteDocsToDisk(docs)
if err != nil {
// If we can't update docs on disk, attempt to revert the change
_ = drw.WriteDocsToDisk(localDocs)
return err
}
return nil
}
// SaveDocsFromDocDetails saves the provided docs to the filesystem.
// An untracked doc will be overwritten if doc.NewerText == nil.
func SaveDocsFromDocDetails(dEnv *env.DoltEnv, docs env.Docs) error {
return docs.Save(dEnv.FS)
}
func docIsUntracked(doc string, untracked []string) bool {
for _, val := range untracked {
if doc == val {
@@ -90,8 +100,8 @@ func docIsUntracked(doc string, untracked []string) bool {
return false
}
func removeUntrackedDocs(docs []doltdb.DocDetails, docDiffs *diff.DocDiffs) []doltdb.DocDetails {
result := []doltdb.DocDetails{}
func removeUntrackedDocs(docs doltdocs.Docs, docDiffs *diff.DocDiffs) doltdocs.Docs {
result := doltdocs.Docs{}
untracked := getUntrackedDocs(docs, docDiffs)
for _, doc := range docs {
@@ -102,7 +112,7 @@ func removeUntrackedDocs(docs []doltdb.DocDetails, docDiffs *diff.DocDiffs) []do
return result
}
func getUntrackedDocs(docs []doltdb.DocDetails, docDiffs *diff.DocDiffs) []string {
func getUntrackedDocs(docs doltdocs.Docs, docDiffs *diff.DocDiffs) []string {
untracked := []string{}
for _, docName := range docDiffs.Docs {
dt := docDiffs.DocToType[docName]
@@ -114,59 +124,63 @@ func getUntrackedDocs(docs []doltdb.DocDetails, docDiffs *diff.DocDiffs) []strin
return untracked
}
func getUpdatedWorkingAndStagedWithDocs(ctx context.Context, dEnv *env.DoltEnv, working, staged, head *doltdb.RootValue, docDetails []doltdb.DocDetails) (currRoot, stgRoot *doltdb.RootValue, err error) {
func getUpdatedWorkingAndStagedWithDocs(ctx context.Context, working, staged, head *doltdb.RootValue, docs doltdocs.Docs) (currRoot, stgRoot *doltdb.RootValue, retDocs doltdocs.Docs, err error) {
root := head
_, ok, err := staged.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
} else if ok {
root = staged
}
docs, err := dEnv.GetDocsWithNewerTextFromRoot(ctx, root, docDetails)
docs, err = doltdocs.GetDocsFromRoot(ctx, root, doltdocs.GetDocNamesFromDocs(docs)...)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
currRoot, err = dEnv.GetUpdatedRootWithDocs(ctx, working, docs)
currRoot, err = doltdocs.UpdateRootWithDocs(ctx, working, docs)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
stgRoot, err = dEnv.GetUpdatedRootWithDocs(ctx, staged, docs)
stgRoot, err = doltdocs.UpdateRootWithDocs(ctx, staged, docs)
if err != nil {
return nil, nil, err
return nil, nil, nil, err
}
return currRoot, stgRoot, nil
return currRoot, stgRoot, docs, nil
}
// GetUnstagedDocs retrieves the unstaged docs (docs from the filesystem).
func GetUnstagedDocs(ctx context.Context, dEnv *env.DoltEnv) (env.Docs, error) {
_, unstagedDocDiffs, err := diff.GetDocDiffs(ctx, dEnv.DoltDB, dEnv.RepoStateReader(), dEnv.DocsReadWriter())
func GetUnstagedDocs(ctx context.Context, dbData env.DbData) (doltdocs.Docs, error) {
_, unstagedDocDiffs, err := diff.GetDocDiffs(ctx, dbData.Ddb, dbData.Rsr, dbData.Drw)
if err != nil {
return nil, err
}
unstagedDocs := env.Docs{}
unstagedDocs := doltdocs.Docs{}
for _, docName := range unstagedDocDiffs.Docs {
docDetail, err := dEnv.GetDocDetail(docName)
docAr, err := dbData.Drw.GetDocsOnDisk(docName)
if err != nil {
return nil, err
}
unstagedDocs = append(unstagedDocs, docDetail)
if len(docAr) < 1 {
return nil, errors.New("error: Failed getting unstaged docs")
}
unstagedDocs = append(unstagedDocs, docAr[0])
}
return unstagedDocs, nil
}
// SaveDocsFromWorkingExcludingFSChanges saves docs from the working root to the filesystem, and does not overwrite changes to docs on the FS.
// Intended to be called after checking that no conflicts exist (during a checkout or merge, i.e.).
func SaveDocsFromWorkingExcludingFSChanges(ctx context.Context, dEnv *env.DoltEnv, docsToExclude env.Docs) error {
func SaveDocsFromWorkingExcludingFSChanges(ctx context.Context, dEnv *env.DoltEnv, docsToExclude doltdocs.Docs) error {
workingRoot, err := dEnv.WorkingRoot(ctx)
if err != nil {
return err
}
var docsToSave env.Docs
var docsToSave doltdocs.Docs
if len(docsToExclude) > 0 {
for _, doc := range dEnv.Docs {
for _, excludedDoc := range docsToExclude {
@@ -179,5 +193,30 @@ func SaveDocsFromWorkingExcludingFSChanges(ctx context.Context, dEnv *env.DoltEn
docsToSave = dEnv.Docs
}
return SaveTrackedDocs(ctx, dEnv, workingRoot, workingRoot, docsToSave)
return SaveTrackedDocs(ctx, dEnv.DocsReadWriter(), workingRoot, workingRoot, docsToSave)
}
// GetTablesOrDocs takes a slice of table or file names. Table names are returned as given. Supported doc names are
// read from disk and their name replace with the names of the dolt_docs system table in the input slice. Supported docs
// are returned in the second return param.
func GetTablesOrDocs(drw env.DocsReadWriter, tablesOrFiles []string) (tables []string, docs doltdocs.Docs, err error) {
for i, tbl := range tablesOrFiles {
if _, ok := doltdocs.IsSupportedDoc(tbl); ok {
docAr, err := drw.GetDocsOnDisk(tbl)
if err != nil {
return nil, nil, err
}
if len(docAr) < 1 {
return nil, nil, errors.New("error: Failed getting docs")
}
doc := docAr[0]
if doc.DocPk == "" {
return nil, nil, errors.New("Supported doc not found on disk.")
}
docs = append(docs, doc)
tablesOrFiles[i] = doltdb.DocTableName
}
}
return tablesOrFiles, docs, nil
}
+16 -8
View File
@@ -19,6 +19,7 @@ import (
"errors"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/utils/argparser"
)
@@ -169,15 +170,14 @@ func ResetSoftTables(ctx context.Context, dbData env.DbData, apr *argparser.ArgP
return stagedRoot, nil
}
func ResetSoft(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseResults, stagedRoot, headRoot *doltdb.RootValue) (*doltdb.RootValue, error) {
func ResetSoft(ctx context.Context, dbData env.DbData, apr *argparser.ArgParseResults, stagedRoot, headRoot *doltdb.RootValue) (*doltdb.RootValue, error) {
tables, err := getUnionedTables(ctx, apr.Args(), stagedRoot, headRoot)
if err != nil {
return nil, err
}
dbData := dEnv.DbData()
tables, docs, err := GetTblsAndDocDetails(dbData.Drw, tables)
tables, docs, err := GetTablesOrDocs(dbData.Drw, tables)
if err != nil {
return nil, err
}
@@ -192,7 +192,7 @@ func ResetSoft(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseRe
return nil, err
}
stagedRoot, err = resetDocs(ctx, dEnv, headRoot, docs)
stagedRoot, err = resetDocs(ctx, dbData, headRoot, stagedRoot, docs)
if err != nil {
return nil, err
}
@@ -219,18 +219,26 @@ func getUnionedTables(ctx context.Context, tables []string, stagedRoot, headRoot
return tables, nil
}
func resetDocs(ctx context.Context, dEnv *env.DoltEnv, headRoot *doltdb.RootValue, docDetails env.Docs) (newStgRoot *doltdb.RootValue, err error) {
docs, err := dEnv.GetDocsWithNewerTextFromRoot(ctx, headRoot, docDetails)
// resetDocs resets the working and staged docs with docs from head.
func resetDocs(ctx context.Context, dbData env.DbData, headRoot *doltdb.RootValue, staged *doltdb.RootValue, docs doltdocs.Docs) (newStgRoot *doltdb.RootValue, err error) {
docs, err = doltdocs.GetDocsFromRoot(ctx, headRoot, doltdocs.GetDocNamesFromDocs(docs)...)
working, err := env.WorkingRoot(ctx, dbData.Ddb, dbData.Rsr)
if err != nil {
return nil, err
}
err = dEnv.PutDocsToWorking(ctx, docs)
working, err = doltdocs.UpdateRootWithDocs(ctx, working, docs)
if err != nil {
return nil, err
}
return dEnv.PutDocsToStaged(ctx, docs)
_, err = env.UpdateWorkingRoot(ctx, dbData.Ddb, dbData.Rsw, working)
if err != nil {
return nil, err
}
return doltdocs.UpdateRootWithDocs(ctx, staged, docs)
}
func resetStaged(ctx context.Context, ddb *doltdb.DoltDB, rsw env.RepoStateWriter, tbls []string, staged, head *doltdb.RootValue) (*doltdb.RootValue, error) {
+24 -33
View File
@@ -18,6 +18,8 @@ import (
"context"
"errors"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
)
@@ -30,60 +32,37 @@ func StageTables(ctx context.Context, dbData env.DbData, tbls []string) error {
rsw := dbData.Rsw
drw := dbData.Drw
tables, docDetails, err := GetTblsAndDocDetails(drw, tbls)
tables, docs, err := GetTablesOrDocs(drw, tbls)
if err != nil {
return err
}
if len(docDetails) > 0 {
err = drw.PutDocsToWorking(ctx, docDetails)
staged, working, err := getStagedAndWorking(ctx, ddb, rsr)
if err != nil {
return err
}
if len(docs) > 0 {
working, err = doltdocs.UpdateRootWithDocs(ctx, working, docs)
if err != nil {
return err
}
}
staged, working, err := getStagedAndWorking(ctx, ddb, rsr)
if err != nil {
return err
}
err = stageTables(ctx, ddb, rsw, tables, staged, working)
if err != nil {
drw.ResetWorkingDocsToStagedDocs(ctx)
env.ResetWorkingDocsToStagedDocs(ctx, ddb, rsr, rsw)
return err
}
return nil
}
// GetTblsAndDocDetails takes a slice of strings where valid doc names are replaced with doc table name. Doc names are
// appended to a docDetails slice. We return a tuple of tables, docDetails and error.
func GetTblsAndDocDetails(drw env.DocsReadWriter, tbls []string) (tables []string, docDetails []doltdb.DocDetails, err error) {
for i, tbl := range tbls {
docDetail, err := drw.GetDocDetail(tbl)
if err != nil {
return nil, nil, err
}
if docDetail.DocPk != "" {
docDetails = append(docDetails, docDetail)
tbls[i] = doltdb.DocTableName
}
}
return tbls, docDetails, nil
}
func StageAllTables(ctx context.Context, dbData env.DbData) error {
ddb := dbData.Ddb
rsr := dbData.Rsr
rsw := dbData.Rsw
drw := dbData.Drw
err := drw.PutDocsToWorking(ctx, nil)
if err != nil {
return err
}
staged, err := env.StagedRoot(ctx, ddb, rsr)
if err != nil {
@@ -96,6 +75,18 @@ func StageAllTables(ctx context.Context, dbData env.DbData) error {
return err
}
docs, err := drw.GetDocsOnDisk()
if err != nil {
return err
}
working, err = doltdocs.UpdateRootWithDocs(ctx, working, docs)
if err != nil {
return err
}
tbls, err := doltdb.UnionTableNames(ctx, staged, working)
if err != nil {
@@ -104,7 +95,7 @@ func StageAllTables(ctx context.Context, dbData env.DbData) error {
err = stageTables(ctx, ddb, rsw, tbls, staged, working)
if err != nil {
drw.ResetWorkingDocsToStagedDocs(ctx)
env.ResetWorkingDocsToStagedDocs(ctx, ddb, rsr, rsw)
return err
}
+7 -5
View File
@@ -19,6 +19,7 @@ import (
"github.com/dolthub/dolt/go/libraries/doltcore/diff"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/utils/set"
)
@@ -36,13 +37,13 @@ func CheckoutAllTables(ctx context.Context, dEnv *env.DoltEnv) error {
return err
}
docs := *env.AllValidDocDetails
docs := doltdocs.SupportedDocs
return checkoutTablesAndDocs(ctx, dEnv, roots, tbls, docs)
}
func CheckoutTablesAndDocs(ctx context.Context, dEnv *env.DoltEnv, tbls []string, docs []doltdb.DocDetails) error {
func CheckoutTablesAndDocs(ctx context.Context, dEnv *env.DoltEnv, tbls []string, docs doltdocs.Docs) error {
roots, err := getRoots(ctx, dEnv.DoltDB, dEnv.RepoStateReader(), WorkingRoot, StagedRoot, HeadRoot)
if err != nil {
@@ -127,7 +128,7 @@ func MoveTablesBetweenRoots(ctx context.Context, tbls []string, src, dest *doltd
return dest, nil
}
func checkoutTablesAndDocs(ctx context.Context, dEnv *env.DoltEnv, roots map[RootType]*doltdb.RootValue, tbls []string, docs []doltdb.DocDetails) error {
func checkoutTablesAndDocs(ctx context.Context, dEnv *env.DoltEnv, roots map[RootType]*doltdb.RootValue, tbls []string, docs doltdocs.Docs) error {
unknownTbls := []string{}
currRoot := roots[WorkingRoot]
@@ -135,12 +136,13 @@ func checkoutTablesAndDocs(ctx context.Context, dEnv *env.DoltEnv, roots map[Roo
head := roots[HeadRoot]
if len(docs) > 0 {
currRootWithDocs, stagedWithDocs, err := getUpdatedWorkingAndStagedWithDocs(ctx, dEnv, currRoot, staged, head, docs)
currRootWithDocs, stagedWithDocs, updatedDocs, err := getUpdatedWorkingAndStagedWithDocs(ctx, currRoot, staged, head, docs)
if err != nil {
return err
}
currRoot = currRootWithDocs
staged = stagedWithDocs
docs = updatedDocs
}
for _, tblName := range tbls {
@@ -192,7 +194,7 @@ func checkoutTablesAndDocs(ctx context.Context, dEnv *env.DoltEnv, roots map[Roo
return err
}
return SaveDocsFromDocDetails(dEnv, docs)
return dEnv.DocsReadWriter().WriteDocsToDisk(docs)
}
func validateTablesExist(ctx context.Context, currRoot *doltdb.RootValue, unknown []string) error {
-16
View File
@@ -1,16 +0,0 @@
// Copyright 2019 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package env provides access to get / set configuration and data repository state.
package env
+37 -75
View File
@@ -15,88 +15,50 @@
package env
import (
"context"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/utils/filesys"
"github.com/dolthub/dolt/go/store/types"
)
type Docs []doltdb.DocDetails
var doltDocsColumns, _ = schema.NewColCollection(
schema.NewColumn(doltdb.DocPkColumnName, schema.DocNameTag, types.StringKind, true, schema.NotNullConstraint{}),
schema.NewColumn(doltdb.DocTextColumnName, schema.DocTextTag, types.StringKind, false),
)
var DoltDocsSchema = schema.MustSchemaFromCols(doltDocsColumns)
// AllValidDocDetails is a list of all valid docs with static fields DocPk and File. All other DocDetail fields
// are dynamic and must be added, modified or removed as needed.
var AllValidDocDetails = &Docs{
doltdb.DocDetails{DocPk: doltdb.ReadmePk, File: ReadmeFile},
doltdb.DocDetails{DocPk: doltdb.LicensePk, File: LicenseFile},
}
func LoadDocs(fs filesys.ReadWriteFS) (Docs, error) {
docsWithCurrentText := *AllValidDocDetails
for i, val := range docsWithCurrentText {
path := getDocFile(val.File)
exists, isDir := fs.Exists(path)
if exists && !isDir {
data, err := fs.ReadFile(path)
if err != nil {
return nil, err
}
val.NewerText = data
docsWithCurrentText[i] = val
}
// ResetWorkingDocsToStagedDocs resets the `dolt_docs` table on the working root to match the staged root.
// If the `dolt_docs` table does not exist on the staged root, it will be removed from the working root.
func ResetWorkingDocsToStagedDocs(ctx context.Context, ddb *doltdb.DoltDB, rsr RepoStateReader, rsw RepoStateWriter) error {
wrkRoot, err := WorkingRoot(ctx, ddb, rsr)
if err != nil {
return err
}
return docsWithCurrentText, nil
}
func (docs Docs) Save(fs filesys.ReadWriteFS) error {
for _, doc := range docs {
if !IsValidDoc(doc.DocPk) {
continue
stgRoot, err := StagedRoot(ctx, ddb, rsr)
if err != nil {
return err
}
stgDocTbl, stgDocsFound, err := stgRoot.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return err
}
_, wrkDocsFound, err := wrkRoot.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return err
}
if wrkDocsFound && !stgDocsFound {
newWrkRoot, err := wrkRoot.RemoveTables(ctx, doltdb.DocTableName)
if err != nil {
return err
}
filePath := getDocFile(doc.File)
if doc.NewerText != nil {
err := fs.WriteFile(filePath, doc.NewerText)
if err != nil {
return err
}
} else {
err := DeleteDoc(fs, doc.DocPk)
if err != nil {
return err
}
_, err = UpdateWorkingRoot(ctx, ddb, rsw, newWrkRoot)
return err
}
if stgDocsFound {
newWrkRoot, err := wrkRoot.PutTable(ctx, doltdb.DocTableName, stgDocTbl)
if err != nil {
return err
}
_, err = UpdateWorkingRoot(ctx, ddb, rsw, newWrkRoot)
return err
}
return nil
}
func DeleteDoc(fs filesys.ReadWriteFS, docName string) error {
for _, doc := range *AllValidDocDetails {
if doc.DocPk == docName {
path := getDocFile(doc.File)
exists, isDir := fs.Exists(path)
if exists && !isDir {
return fs.DeleteFile(path)
}
}
}
return nil
}
func IsValidDoc(docName string) bool {
for _, doc := range *AllValidDocDetails {
if doc.DocPk == docName {
return true
}
}
return false
}
func hasDocFile(fs filesys.ReadWriteFS, file string) bool {
exists, isDir := fs.Exists(getDocFile(file))
return exists && !isDir
}
+25 -347
View File
@@ -32,13 +32,11 @@ import (
"github.com/dolthub/dolt/go/libraries/doltcore/creds"
"github.com/dolthub/dolt/go/libraries/doltcore/dbfactory"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/grpcendpoint"
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/doltcore/schema/encoding"
"github.com/dolthub/dolt/go/libraries/doltcore/table"
"github.com/dolthub/dolt/go/libraries/doltcore/table/typed/noms"
"github.com/dolthub/dolt/go/libraries/utils/filesys"
"github.com/dolthub/dolt/go/store/hash"
"github.com/dolthub/dolt/go/store/types"
@@ -57,7 +55,6 @@ var ErrPreexistingDoltDir = errors.New(".dolt dir already exists")
var ErrStateUpdate = errors.New("error updating local data repo state")
var ErrMarshallingSchema = errors.New("error marshalling schema")
var ErrInvalidCredsFile = errors.New("invalid creds file")
var ErrDocsUpdate = errors.New("error updating local docs")
// DoltEnv holds the state of the current environment used by the cli.
type DoltEnv struct {
@@ -69,7 +66,7 @@ type DoltEnv struct {
RepoState *RepoState
RSLoadErr error
Docs Docs
Docs doltdocs.Docs
DocsLoadErr error
DoltDB *doltdb.DoltDB
@@ -84,7 +81,7 @@ type DoltEnv struct {
func Load(ctx context.Context, hdp HomeDirProvider, fs filesys.Filesys, urlStr, version string) *DoltEnv {
config, cfgErr := loadDoltCliConfig(hdp, fs)
repoState, rsErr := LoadRepoState(fs)
docs, docsErr := LoadDocs(fs)
docs, docsErr := doltdocs.LoadDocs(fs)
ddb, dbLoadErr := doltdb.LoadDoltDB(ctx, types.Format_Default, urlStr)
dEnv := &DoltEnv{
@@ -177,23 +174,6 @@ func (dEnv *DoltEnv) HasLocalConfig() bool {
return ok
}
// GetDoc returns the path to the provided file, if it exists
func (dEnv *DoltEnv) GetDoc(file string) string {
if !hasDocFile(dEnv.FS, file) {
return ""
}
return getDocFile(file)
}
// GetLocalFileText returns a byte slice representing the contents of the provided file, if it exists
func (dEnv *DoltEnv) GetLocalFileText(file string) ([]byte, error) {
path := dEnv.GetDoc(file)
if path != "" {
return dEnv.FS.ReadFile(path)
}
return nil, nil
}
func (dEnv *DoltEnv) bestEffortDeleteAll(dir string) {
fileToIsDir := make(map[string]bool)
dEnv.FS.Iter(dir, false, func(path string, size int64, isDir bool) (stop bool) {
@@ -395,10 +375,6 @@ func (r *repoStateReader) GetMergeCommit() string {
return r.dEnv.RepoState.Merge.Commit
}
func (r *repoStateReader) GetAllValidDocDetails() ([]doltdb.DocDetails, error) {
return r.dEnv.GetAllValidDocDetails()
}
func (dEnv *DoltEnv) RepoStateReader() RepoStateReader {
return &repoStateReader{dEnv}
}
@@ -433,45 +409,40 @@ func (r *repoStateWriter) ClearMerge() error {
return r.dEnv.RepoState.ClearMerge(r.dEnv.FS)
}
func (r *repoStateWriter) PutDocsToWorking(ctx context.Context, docDetails []doltdb.DocDetails) error {
return r.dEnv.PutDocsToWorking(ctx, docDetails)
}
func (r *repoStateWriter) ResetWorkingDocsToStagedDos(ctx context.Context) error {
return r.dEnv.ResetWorkingDocsToStagedDocs(ctx)
}
func (dEnv *DoltEnv) RepoStateWriter() RepoStateWriter {
return &repoStateWriter{dEnv}
}
type docsReadWriter struct {
dEnv *DoltEnv
FS filesys.Filesys
}
func (d *docsReadWriter) GetAllValidDocDetails() ([]doltdb.DocDetails, error) {
return d.dEnv.GetAllValidDocDetails()
// GetDocsOnDisk reads the filesystem and returns all docs.
func (d *docsReadWriter) GetDocsOnDisk(docNames ...string) (doltdocs.Docs, error) {
if docNames != nil {
ret := make(doltdocs.Docs, len(docNames))
for i, name := range docNames {
doc, err := doltdocs.GetDoc(d.FS, name)
if err != nil {
return nil, err
}
ret[i] = doc
}
return ret, nil
}
return doltdocs.GetSupportedDocs(d.FS)
}
func (d *docsReadWriter) PutDocsToWorking(ctx context.Context, docDetails []doltdb.DocDetails) error {
return d.dEnv.PutDocsToWorking(ctx, docDetails)
}
func (d *docsReadWriter) PutDocsToStaged(ctx context.Context, docDetails []doltdb.DocDetails) (*doltdb.RootValue, error) {
return d.dEnv.PutDocsToStaged(ctx, docDetails)
}
func (d *docsReadWriter) ResetWorkingDocsToStagedDocs(ctx context.Context) error {
return d.dEnv.ResetWorkingDocsToStagedDocs(ctx)
}
// GetDocDetail returns the details of a specific document passed as docName.
func (d *docsReadWriter) GetDocDetail(docName string) (doc doltdb.DocDetails, err error) {
return d.dEnv.GetDocDetail(docName)
// WriteDocsToDisk creates or updates the dolt_docs table with docs.
func (d *docsReadWriter) WriteDocsToDisk(docs doltdocs.Docs) error {
return docs.Save(d.FS)
}
func (dEnv *DoltEnv) DocsReadWriter() DocsReadWriter {
return &docsReadWriter{dEnv}
return &docsReadWriter{dEnv.FS}
}
func (dEnv *DoltEnv) HeadRoot(ctx context.Context) (*doltdb.RootValue, error) {
@@ -896,296 +867,3 @@ func (dEnv *DoltEnv) GetUserHomeDir() (string, error) {
func (dEnv *DoltEnv) TempTableFilesDir() string {
return mustAbs(dEnv, dEnv.GetDoltDir(), tempTablesDir)
}
func (dEnv *DoltEnv) GetAllValidDocDetails() (docs []doltdb.DocDetails, err error) {
docs = []doltdb.DocDetails{}
for _, doc := range *AllValidDocDetails {
newerText, err := dEnv.GetLocalFileText(doc.File)
if err != nil {
return nil, err
}
doc.NewerText = newerText
docs = append(docs, doc)
}
return docs, nil
}
func (dEnv *DoltEnv) GetDocDetail(docName string) (doc doltdb.DocDetails, err error) {
for _, doc := range *AllValidDocDetails {
if doc.DocPk == docName {
newerText, err := dEnv.GetLocalFileText(doc.File)
if err != nil {
return doltdb.DocDetails{}, err
}
doc.NewerText = newerText
return doc, nil
}
}
return doltdb.DocDetails{}, err
}
// WorkingRootWithDocs returns a copy of the working root that has been updated with the Dolt docs from the file system.
func (dEnv *DoltEnv) WorkingRootWithDocs(ctx context.Context) (*doltdb.RootValue, error) {
dds, err := dEnv.GetAllValidDocDetails()
if err != nil {
return nil, err
}
wr, err := dEnv.WorkingRoot(ctx)
if err != nil {
return nil, err
}
return dEnv.GetUpdatedRootWithDocs(ctx, wr, dds)
}
// GetUpdatedRootWithDocs adds, updates or removes the `dolt_docs` table on the provided root. The table will be added or updated
// When at least one doc.NewerText != nil. If the `dolt_docs` table exists and every doc.NewerText == nil, the table will be removed.
// If no docDetails are provided, we put all valid docs to the working root.
func (dEnv *DoltEnv) GetUpdatedRootWithDocs(ctx context.Context, root *doltdb.RootValue, docDetails []doltdb.DocDetails) (*doltdb.RootValue, error) {
docTbl, found, err := root.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return nil, err
}
docDetails, err = getDocDetails(dEnv, docDetails)
if err != nil {
return nil, err
}
if found {
return updateDocsOnRoot(ctx, dEnv, root, docTbl, docDetails)
}
return createDocsTableOnRoot(ctx, dEnv, root, docDetails)
}
// PutDocsToWorking adds, updates or removes the `dolt_docs` table on the working root using the provided docDetails.
func (dEnv *DoltEnv) PutDocsToWorking(ctx context.Context, docDetails []doltdb.DocDetails) error {
wrkRoot, err := dEnv.WorkingRoot(ctx)
if err != nil {
return err
}
rootWithDocs, err := dEnv.GetUpdatedRootWithDocs(ctx, wrkRoot, docDetails)
if err != nil {
return err
}
return dEnv.UpdateWorkingRoot(ctx, rootWithDocs)
}
// PutDocsToStaged adds, updates or removes the `dolt_docs` table on the staged root using the provided docDetails.
func (dEnv *DoltEnv) PutDocsToStaged(ctx context.Context, docDetails []doltdb.DocDetails) (*doltdb.RootValue, error) {
stgRoot, err := dEnv.StagedRoot(ctx)
if err != nil {
return nil, err
}
rootWithDocs, err := dEnv.GetUpdatedRootWithDocs(ctx, stgRoot, docDetails)
if err != nil {
return nil, err
}
_, err = dEnv.UpdateStagedRoot(ctx, rootWithDocs)
if err != nil {
return nil, err
}
return createDocsTableOnRoot(ctx, dEnv, rootWithDocs, docDetails)
}
func getDocDetails(dEnv *DoltEnv, docDetails []doltdb.DocDetails) ([]doltdb.DocDetails, error) {
if docDetails == nil {
docs, err := dEnv.GetAllValidDocDetails()
if err != nil {
return nil, err
}
return docs, nil
}
return docDetails, nil
}
// ResetWorkingDocsToStagedDocs resets the `dolt_docs` table on the working root to match the staged root.
// If the `dolt_docs` table does not exist on the staged root, it will be removed from the working root.
func (dEnv *DoltEnv) ResetWorkingDocsToStagedDocs(ctx context.Context) error {
wrkRoot, err := dEnv.WorkingRoot(ctx)
if err != nil {
return err
}
stgRoot, err := dEnv.StagedRoot(ctx)
if err != nil {
return err
}
stgDocTbl, stgDocsFound, err := stgRoot.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return err
}
_, wrkDocsFound, err := wrkRoot.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return err
}
if wrkDocsFound && !stgDocsFound {
newWrkRoot, err := wrkRoot.RemoveTables(ctx, doltdb.DocTableName)
if err != nil {
return err
}
return dEnv.UpdateWorkingRoot(ctx, newWrkRoot)
}
if stgDocsFound {
newWrkRoot, err := wrkRoot.PutTable(ctx, doltdb.DocTableName, stgDocTbl)
if err != nil {
return err
}
return dEnv.UpdateWorkingRoot(ctx, newWrkRoot)
}
return nil
}
func updateDocsOnRoot(ctx context.Context, dEnv *DoltEnv, root *doltdb.RootValue, docTbl *doltdb.Table, docDetails []doltdb.DocDetails) (*doltdb.RootValue, error) {
m, err := docTbl.GetRowData(ctx)
if err != nil {
return nil, err
}
sch, err := docTbl.GetSchema(context.Background())
if err != nil {
return nil, err
}
me := m.Edit()
for _, doc := range docDetails {
key, err := doltdb.DocTblKeyFromName(docTbl.Format(), doc.DocPk)
if err != nil {
return nil, err
}
docRow, exists, err := table.GetRow(ctx, docTbl, sch, key)
if err != nil {
return nil, err
}
if exists && doc.NewerText == nil {
me = me.Remove(docRow.NomsMapKey(sch))
} else if doc.NewerText != nil {
docTaggedVals := row.TaggedValues{
schema.DocNameTag: types.String(doc.DocPk),
schema.DocTextTag: types.String(doc.NewerText),
}
docRow, err = row.New(types.Format_7_18, sch, docTaggedVals)
if err != nil {
return nil, err
}
me = me.Set(docRow.NomsMapKey(sch), docRow.NomsMapValue(sch))
}
}
updatedMap, err := me.Map(ctx)
if updatedMap.Len() == 0 {
return root.RemoveTables(ctx, doltdb.DocTableName)
}
docTbl, err = docTbl.UpdateRows(ctx, updatedMap)
if err != nil {
return nil, err
}
return root.PutTable(ctx, doltdb.DocTableName, docTbl)
}
func createDocsTableOnRoot(ctx context.Context, dEnv *DoltEnv, root *doltdb.RootValue, docDetails []doltdb.DocDetails) (*doltdb.RootValue, error) {
imt := table.NewInMemTable(DoltDocsSchema)
createTable := false
for _, doc := range docDetails {
if doc.NewerText != nil {
createTable = true
docTaggedVals := row.TaggedValues{
schema.DocNameTag: types.String(doc.DocPk),
schema.DocTextTag: types.String(doc.NewerText),
}
docRow, err := row.New(types.Format_7_18, DoltDocsSchema, docTaggedVals)
if err != nil {
return nil, err
}
err = imt.AppendRow(docRow)
if err != nil {
return nil, err
}
}
}
if createTable {
rd := table.NewInMemTableReader(imt)
wr := noms.NewNomsMapCreator(context.Background(), dEnv.DoltDB.ValueReadWriter(), DoltDocsSchema)
_, _, err := table.PipeRows(context.Background(), rd, wr, false)
if err != nil {
return nil, err
}
rd.Close(context.Background())
wr.Close(context.Background())
vrw := root.VRW()
schVal, err := encoding.MarshalSchemaAsNomsValue(ctx, vrw, wr.GetSchema())
if err != nil {
return nil, ErrMarshallingSchema
}
empty, err := types.NewMap(ctx, root.VRW())
if err != nil {
return nil, err
}
newDocsTbl, err := doltdb.NewTable(ctx, root.VRW(), schVal, wr.GetMap(), empty)
if err != nil {
return nil, err
}
return root.PutTable(ctx, doltdb.DocTableName, newDocsTbl)
}
return root, nil
}
//UpdateFSDocsToRootDocs updates the provided docs from the root value, and then saves them to the filesystem.
// If docs == nil, all valid docs will be retrieved and written.
func (dEnv *DoltEnv) UpdateFSDocsToRootDocs(ctx context.Context, root *doltdb.RootValue, docs Docs) error {
docs, err := dEnv.GetDocsWithNewerTextFromRoot(ctx, root, docs)
if err != nil {
return nil
}
return docs.Save(dEnv.FS)
}
// GetDocsWithNewerTextFromRoot returns Docs with the NewerText value(s) from the provided root. If docs are provided,
// only those docs will be retrieved and returned. Otherwise, all valid doc details are returned with the updated NewerText.
func (dEnv *DoltEnv) GetDocsWithNewerTextFromRoot(ctx context.Context, root *doltdb.RootValue, docs Docs) (Docs, error) {
docTbl, docTblFound, err := root.GetTable(ctx, doltdb.DocTableName)
if err != nil {
return nil, err
}
var sch schema.Schema
if docTblFound {
docSch, err := docTbl.GetSchema(ctx)
if err != nil {
return nil, err
}
sch = docSch
}
if docs == nil {
docs = *AllValidDocDetails
}
for i, doc := range docs {
doc, err = doltdb.AddNewerTextToDocFromTbl(ctx, docTbl, &sch, doc)
if err != nil {
return nil, err
}
docs[i] = doc
}
return docs, nil
}
+3 -2
View File
@@ -25,6 +25,7 @@ import (
"github.com/dolthub/dolt/go/libraries/doltcore/dbfactory"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
"github.com/dolthub/dolt/go/libraries/utils/filesys"
"github.com/dolthub/dolt/go/store/hash"
@@ -175,8 +176,8 @@ func TestInitRepo(t *testing.T) {
t.Error("Failed to get staged root value.")
}
for _, doc := range *AllValidDocDetails {
docPath := getDocFile(doc.File)
for _, doc := range doltdocs.SupportedDocs {
docPath := doltdocs.GetDocFilePath(doc.File)
if len(docPath) > 0 && !strings.Contains(doc.File, docPath) {
t.Error("Doc file path should exist: ", doc.File)
}
-7
View File
@@ -31,9 +31,6 @@ const (
globalConfig = "config_global.json"
repoStateFile = "repo_state.json"
ReadmeFile = "../README.md"
LicenseFile = "../LICENSE.md"
)
// HomeDirProvider is a function that returns the users home directory. This is where global dolt state is stored for
@@ -90,7 +87,3 @@ func getHomeDir(hdp HomeDirProvider) (string, error) {
}
return homeDir, nil
}
func getDocFile(filename string) string {
return filepath.Join(dbfactory.DoltDir, filename)
}
+5 -5
View File
@@ -20,6 +20,7 @@ import (
"github.com/dolthub/dolt/go/cmd/dolt/errhand"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
"github.com/dolthub/dolt/go/libraries/utils/filesys"
"github.com/dolthub/dolt/go/store/hash"
@@ -43,11 +44,10 @@ type RepoStateWriter interface {
}
type DocsReadWriter interface {
GetAllValidDocDetails() ([]doltdb.DocDetails, error)
PutDocsToWorking(ctx context.Context, docDetails []doltdb.DocDetails) error
PutDocsToStaged(ctx context.Context, docDetails []doltdb.DocDetails) (*doltdb.RootValue, error)
ResetWorkingDocsToStagedDocs(ctx context.Context) error
GetDocDetail(docName string) (doc doltdb.DocDetails, err error)
// GetDocsOnDisk returns the docs in the filesytem optionally filtered by docNames.
GetDocsOnDisk(docNames ...string) (doltdocs.Docs, error)
// WriteDocsToDisk updates the documents stored in the filesystem with the contents in docs.
WriteDocsToDisk(docs doltdocs.Docs) error
}
type DbData struct {
+2 -2
View File
@@ -871,7 +871,7 @@ func GetTablesInConflict(ctx context.Context, ddb *doltdb.DoltDB, rsr env.RepoSt
}
func GetDocsInConflict(ctx context.Context, ddb *doltdb.DoltDB, rsr env.RepoStateReader, drw env.DocsReadWriter) (*diff.DocDiffs, error) {
docDetails, err := drw.GetAllValidDocDetails()
docs, err := drw.GetDocsOnDisk()
if err != nil {
return nil, err
}
@@ -881,5 +881,5 @@ func GetDocsInConflict(ctx context.Context, ddb *doltdb.DoltDB, rsr env.RepoStat
return nil, err
}
return diff.NewDocDiffs(ctx, workingRoot, nil, docDetails)
return diff.NewDocDiffs(ctx, workingRoot, nil, docs)
}
+18 -15
View File
@@ -18,10 +18,10 @@ import (
"context"
"fmt"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/store/hash"
)
@@ -100,12 +100,12 @@ func AllBranches(ctx context.Context, dEnv *env.DoltEnv, replay ReplayCommitFn,
return err
}
return rebaseRefs(ctx, dEnv, replay, nerf, branches...)
return rebaseRefs(ctx, dEnv.DbData(), replay, nerf, branches...)
}
// CurrentBranch rewrites the history of the current branch using the |replay| function.
func CurrentBranch(ctx context.Context, dEnv *env.DoltEnv, replay ReplayCommitFn, nerf NeedsRebaseFn) error {
return rebaseRefs(ctx, dEnv, replay, nerf, dEnv.RepoState.CWBHeadRef())
return rebaseRefs(ctx, dEnv.DbData(), replay, nerf, dEnv.RepoState.CWBHeadRef())
}
// AllBranchesByRoots rewrites the history of all branches in the repo using the |replay| function.
@@ -116,19 +116,23 @@ func AllBranchesByRoots(ctx context.Context, dEnv *env.DoltEnv, replay ReplayRoo
}
replayCommit := wrapReplayRootFn(replay)
return rebaseRefs(ctx, dEnv, replayCommit, nerf, branches...)
return rebaseRefs(ctx, dEnv.DbData(), replayCommit, nerf, branches...)
}
// CurrentBranchByRoot rewrites the history of the current branch using the |replay| function.
func CurrentBranchByRoot(ctx context.Context, dEnv *env.DoltEnv, replay ReplayRootFn, nerf NeedsRebaseFn) error {
replayCommit := wrapReplayRootFn(replay)
return rebaseRefs(ctx, dEnv, replayCommit, nerf, dEnv.RepoState.CWBHeadRef())
return rebaseRefs(ctx, dEnv.DbData(), replayCommit, nerf, dEnv.RepoState.CWBHeadRef())
}
func rebaseRefs(ctx context.Context, dEnv *env.DoltEnv, replay ReplayCommitFn, nerf NeedsRebaseFn, refs ...ref.DoltRef) error {
ddb := dEnv.DoltDB
cwbRef := dEnv.RepoState.CWBHeadRef()
dd, err := dEnv.GetAllValidDocDetails()
func rebaseRefs(ctx context.Context, dbData env.DbData, replay ReplayCommitFn, nerf NeedsRebaseFn, refs ...ref.DoltRef) error {
ddb := dbData.Ddb
rsr := dbData.Rsr
rsw := dbData.Rsw
drw := dbData.Drw
cwbRef := rsr.CWBHeadRef()
dd, err := drw.GetDocsOnDisk()
if err != nil {
return err
}
@@ -165,7 +169,7 @@ func rebaseRefs(ctx context.Context, dEnv *env.DoltEnv, replay ReplayCommitFn, n
}
}
cm, err := dEnv.DoltDB.ResolveRef(ctx, cwbRef)
cm, err := ddb.ResolveRef(ctx, cwbRef)
if err != nil {
return err
}
@@ -175,22 +179,21 @@ func rebaseRefs(ctx context.Context, dEnv *env.DoltEnv, replay ReplayCommitFn, n
return err
}
_, err = dEnv.UpdateStagedRoot(ctx, r)
_, err = doltdocs.UpdateRootWithDocs(ctx, r, dd)
if err != nil {
return err
}
err = dEnv.UpdateWorkingRoot(ctx, r)
_, err = env.UpdateStagedRoot(ctx, ddb, rsw, r)
if err != nil {
return err
}
err = dEnv.PutDocsToWorking(ctx, dd)
_, err = env.UpdateWorkingRoot(ctx, ddb, rsw, r)
if err != nil {
return err
}
_, err = dEnv.PutDocsToStaged(ctx, dd)
return err
}
+2 -1
View File
@@ -26,6 +26,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/dtestutils"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
@@ -982,7 +983,7 @@ func TestAlterSystemTables(t *testing.T) {
})
dtestutils.CreateTestTable(t, dEnv, "dolt_docs",
env.DoltDocsSchema,
doltdocs.DoltDocsSchema,
NewRow(types.String("LICENSE.md"), types.String("A license")))
dtestutils.CreateTestTable(t, dEnv, doltdb.DoltQueryCatalogTableName,
dtables.DoltQueryCatalogSchema,
+2 -2
View File
@@ -23,8 +23,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/dtestutils"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
. "github.com/dolthub/dolt/go/libraries/doltcore/sql/sqltestutil"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
@@ -194,7 +194,7 @@ var systemTableDeleteTests = []DeleteTest{
{
Name: "delete dolt_docs",
AdditionalSetup: CreateTableFn("dolt_docs",
env.DoltDocsSchema,
doltdocs.DoltDocsSchema,
NewRow(types.String("LICENSE.md"), types.String("A license"))),
DeleteQuery: "delete from dolt_docs",
ExpectedErr: "cannot delete from table",
+2 -1
View File
@@ -24,6 +24,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/dtestutils"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
@@ -400,7 +401,7 @@ var systemTableInsertTests = []InsertTest{
{
Name: "insert into dolt_docs",
AdditionalSetup: CreateTableFn("dolt_docs",
env.DoltDocsSchema,
doltdocs.DoltDocsSchema,
NewRow(types.String("LICENSE.md"), types.String("A license"))),
InsertQuery: "insert into dolt_docs (doc_name, doc_text) values ('README.md', 'Some text')",
ExpectedErr: "cannot insert into table",
@@ -24,8 +24,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/dtestutils"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
. "github.com/dolthub/dolt/go/libraries/doltcore/sql/sqltestutil"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
@@ -256,7 +256,7 @@ var systemTableReplaceTests = []ReplaceTest{
{
Name: "replace into dolt_docs",
AdditionalSetup: CreateTableFn("dolt_docs",
env.DoltDocsSchema,
doltdocs.DoltDocsSchema,
NewRow(types.String("LICENSE.md"), types.String("A license"))),
ReplaceQuery: "replace into dolt_docs (doc_name, doc_text) values ('README.md', 'Some text')",
ExpectedErr: "cannot insert into table",
+5 -5
View File
@@ -24,8 +24,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/dtestutils"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/envtestutils"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
@@ -1465,15 +1465,15 @@ var systemTableSelectTests = []SelectTest{
{
Name: "select from dolt_docs",
AdditionalSetup: CreateTableFn("dolt_docs",
env.DoltDocsSchema,
NewRowWithSchema(env.DoltDocsSchema,
doltdocs.DoltDocsSchema,
NewRowWithSchema(doltdocs.DoltDocsSchema,
types.String("LICENSE.md"),
types.String("A license")),
),
Query: "select * from dolt_docs",
ExpectedRows: ToSqlRows(CompressSchema(env.DoltDocsSchema),
ExpectedRows: ToSqlRows(CompressSchema(doltdocs.DoltDocsSchema),
NewRow(types.String("LICENSE.md"), types.String("A license"))),
ExpectedSchema: CompressSchema(env.DoltDocsSchema),
ExpectedSchema: CompressSchema(doltdocs.DoltDocsSchema),
},
{
Name: "select from dolt_query_catalog",
+2 -2
View File
@@ -24,8 +24,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdocs"
"github.com/dolthub/dolt/go/libraries/doltcore/dtestutils"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
. "github.com/dolthub/dolt/go/libraries/doltcore/sql/sqltestutil"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
@@ -378,7 +378,7 @@ var systemTableUpdateTests = []UpdateTest{
{
Name: "update dolt_docs",
AdditionalSetup: CreateTableFn("dolt_docs",
env.DoltDocsSchema,
doltdocs.DoltDocsSchema,
NewRow(types.String("LICENSE.md"), types.String("A license"))),
UpdateQuery: "update dolt_docs set doc_text = 'Some text')",
ExpectedErr: "cannot insert into table",