diff --git a/go/gen/fb/serial/fileidentifiers.go b/go/gen/fb/serial/fileidentifiers.go index e76cf8659b..d9f82b6b55 100644 --- a/go/gen/fb/serial/fileidentifiers.go +++ b/go/gen/fb/serial/fileidentifiers.go @@ -18,3 +18,10 @@ package serial const StoreRootFileID = "STRT" const TagFileID = "DTAG" + +func GetFileID(bs []byte) string { + if len(bs) < 8 { + return "" + } + return string(bs[4:8]) +} diff --git a/go/gen/fb/serial/tag.go b/go/gen/fb/serial/tag.go index c33a3acafb..33226850d6 100644 --- a/go/gen/fb/serial/tag.go +++ b/go/gen/fb/serial/tag.go @@ -47,11 +47,11 @@ func (rcv *Tag) Table() flatbuffers.Table { return rcv._tab } -func (rcv *Tag) CommitAddr(j int) int8 { +func (rcv *Tag) CommitAddr(j int) byte { o := flatbuffers.UOffsetT(rcv._tab.Offset(4)) if o != 0 { a := rcv._tab.Vector(o) - return rcv._tab.GetInt8(a + flatbuffers.UOffsetT(j*1)) + return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1)) } return 0 } @@ -64,11 +64,19 @@ func (rcv *Tag) CommitAddrLength() int { return 0 } -func (rcv *Tag) MutateCommitAddr(j int, n int8) bool { +func (rcv *Tag) CommitAddrBytes() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(4)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + +func (rcv *Tag) MutateCommitAddr(j int, n byte) bool { o := flatbuffers.UOffsetT(rcv._tab.Offset(4)) if o != 0 { a := rcv._tab.Vector(o) - return rcv._tab.MutateInt8(a+flatbuffers.UOffsetT(j*1), n) + return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n) } return false } diff --git a/go/libraries/doltcore/doltdb/doltdb_test.go b/go/libraries/doltcore/doltdb/doltdb_test.go index 40ed44fa8f..88a9769da1 100644 --- a/go/libraries/doltcore/doltdb/doltdb_test.go +++ b/go/libraries/doltcore/doltdb/doltdb_test.go @@ -101,7 +101,7 @@ func createTestRowDataFromTaggedValues(t *testing.T, vrw types.ValueReadWriter, ed := m.Edit() for i, val := range vals { - r, err := row.New(types.Format_Default, sch, val) + r, err := row.New(vrw.Format(), sch, val) require.NoError(t, err) rows[i] = r ed = ed.Set(r.NomsMapKey(sch), r.NomsMapValue(sch)) diff --git a/go/serial/fileidentifiers.go b/go/serial/fileidentifiers.go index e76cf8659b..d9f82b6b55 100644 --- a/go/serial/fileidentifiers.go +++ b/go/serial/fileidentifiers.go @@ -18,3 +18,10 @@ package serial const StoreRootFileID = "STRT" const TagFileID = "DTAG" + +func GetFileID(bs []byte) string { + if len(bs) < 8 { + return "" + } + return string(bs[4:8]) +} diff --git a/go/serial/tag.fbs b/go/serial/tag.fbs index e9964fe6cb..c6097ffd56 100644 --- a/go/serial/tag.fbs +++ b/go/serial/tag.fbs @@ -14,7 +14,7 @@ table Tag { // 20-byte hash of the commit. - commit_addr:[byte] (required); + commit_addr:[ubyte] (required); name:string (required); email:string (required); desc:string (required); diff --git a/go/store/cmd/noms/noms.go b/go/store/cmd/noms/noms.go index e454f6938f..44f1861428 100644 --- a/go/store/cmd/noms/noms.go +++ b/go/store/cmd/noms/noms.go @@ -242,5 +242,6 @@ See Spelling Objects at https://github.com/attic-labs/noms/blob/master/doc/spell cat.Flag("raw", "If true, includes the raw binary version of each chunk in the nbs file").Bool() cat.Flag("decompressed", "If true, includes the decompressed binary version of each chunk in the nbs file").Bool() cat.Flag("no-show", "If true, skips printing of the value").Bool() + cat.Flag("no-refs", "If true, skips printing of the refs").Bool() cat.Flag("hashes-only", "If true, only prints the b32 hashes").Bool() } diff --git a/go/store/cmd/noms/noms_cat.go b/go/store/cmd/noms/noms_cat.go index 4a968392fe..e97580d6ea 100644 --- a/go/store/cmd/noms/noms_cat.go +++ b/go/store/cmd/noms/noms_cat.go @@ -55,6 +55,7 @@ var ( catRaw = false catDecomp = false catNoShow = false + catNoRefs = false catHashesOnly = false ) @@ -71,6 +72,7 @@ func setupCatFlags() *flag.FlagSet { catFlagSet := flag.NewFlagSet("cat", flag.ExitOnError) catFlagSet.BoolVar(&catRaw, "raw", false, "If true, includes the raw binary version of each chunk in the nbs file") catFlagSet.BoolVar(&catNoShow, "no-show", false, "If true, skips printing of the value") + catFlagSet.BoolVar(&catNoRefs, "no-refs", false, "If true, skips printing of the refs") catFlagSet.BoolVar(&catHashesOnly, "hashes-only", false, "If true, only prints the b32 hashes") catFlagSet.BoolVar(&catDecomp, "decompressed", false, "If true, includes the decompressed binary version of each chunk in the nbs file") return catFlagSet @@ -188,17 +190,19 @@ func runCat(ctx context.Context, args []string) int { fmt.Println() } - refIdx := 0 - err = types.WalkRefs(chunk, vrw.Format(), func(ref types.Ref) error { - if refIdx == 0 { - fmt.Printf(" chunk[%d] references chunks:\n", cidx) - } + if !catNoRefs { + refIdx := 0 + err = types.WalkRefs(chunk, vrw.Format(), func(ref types.Ref) error { + if refIdx == 0 { + fmt.Printf(" chunk[%d] references chunks:\n", cidx) + } - fmt.Printf(" Ref Hash: %s\n", ref.TargetHash().String()) - refIdx++ + fmt.Printf(" Ref Hash: %s\n", ref.TargetHash().String()) + refIdx++ - return nil - }) + return nil + }) + } d.PanicIfError(err) fmt.Println() diff --git a/go/store/datas/commit_test.go b/go/store/datas/commit_test.go index bac5040b3f..6de32fef81 100644 --- a/go/store/datas/commit_test.go +++ b/go/store/datas/commit_test.go @@ -141,7 +141,7 @@ func TestNewCommit(t *testing.T) { parents := mustList(types.NewList(context.Background(), db)) parentsClosure := mustParentsClosure(t, false)(getParentsClosure(context.Background(), db, parents)) - commit, err := newCommit(context.Background(), types.Float(1), parents, parentsClosure, false, types.EmptyStruct(types.Format_7_18)) + commit, err := newCommit(context.Background(), types.Float(1), parents, parentsClosure, false, types.EmptyStruct(db.Format())) assert.NoError(err) at, err := types.TypeOf(commit) assert.NoError(err) @@ -160,9 +160,9 @@ func TestNewCommit(t *testing.T) { assert.NoError(err) // Committing another Float - parents = mustList(types.NewList(context.Background(), db, mustRef(types.NewRef(commit, types.Format_7_18)))) + parents = mustList(types.NewList(context.Background(), db, mustRef(types.NewRef(commit, db.Format())))) parentsClosure = mustParentsClosure(t, true)(getParentsClosure(context.Background(), db, parents)) - commit2, err := newCommit(context.Background(), types.Float(2), parents, parentsClosure, true, types.EmptyStruct(types.Format_7_18)) + commit2, err := newCommit(context.Background(), types.Float(2), parents, parentsClosure, true, types.EmptyStruct(db.Format())) assert.NoError(err) at2, err := types.TypeOf(commit2) assert.NoError(err) @@ -179,9 +179,9 @@ func TestNewCommit(t *testing.T) { assert.NoError(err) // Now commit a String - parents = mustList(types.NewList(context.Background(), db, mustRef(types.NewRef(commit2, types.Format_7_18)))) + parents = mustList(types.NewList(context.Background(), db, mustRef(types.NewRef(commit2, db.Format())))) parentsClosure = mustParentsClosure(t, true)(getParentsClosure(context.Background(), db, parents)) - commit3, err := newCommit(context.Background(), types.String("Hi"), parents, parentsClosure, true, types.EmptyStruct(types.Format_7_18)) + commit3, err := newCommit(context.Background(), types.String("Hi"), parents, parentsClosure, true, types.EmptyStruct(db.Format())) assert.NoError(err) at3, err := types.TypeOf(commit3) assert.NoError(err) @@ -198,14 +198,14 @@ func TestNewCommit(t *testing.T) { assert.NoError(err) // Now commit a String with MetaInfo - meta, err := types.NewStruct(types.Format_7_18, "Meta", types.StructData{"date": types.String("some date"), "number": types.Float(9)}) + meta, err := types.NewStruct(db.Format(), "Meta", types.StructData{"date": types.String("some date"), "number": types.Float(9)}) assert.NoError(err) metaType := nomdl.MustParseType(`Struct Meta { date: String, number: Float, }`) assertTypeEquals(metaType, mustType(types.TypeOf(meta))) - parents = mustList(types.NewList(context.Background(), db, mustRef(types.NewRef(commit2, types.Format_7_18)))) + parents = mustList(types.NewList(context.Background(), db, mustRef(types.NewRef(commit2, db.Format())))) parentsClosure = mustParentsClosure(t, true)(getParentsClosure(context.Background(), db, parents)) commit4, err := newCommit(context.Background(), types.String("Hi"), parents, parentsClosure, true, meta) assert.NoError(err) @@ -228,8 +228,8 @@ func TestNewCommit(t *testing.T) { // Merge-commit with different parent types parents = mustList(types.NewList(context.Background(), db, - mustRef(types.NewRef(commit2, types.Format_7_18)), - mustRef(types.NewRef(commit3, types.Format_7_18)))) + mustRef(types.NewRef(commit2, db.Format())), + mustRef(types.NewRef(commit3, db.Format())))) parentsClosure = mustParentsClosure(t, true)(getParentsClosure(context.Background(), db, parents)) commit5, err := newCommit( context.Background(), @@ -237,7 +237,7 @@ func TestNewCommit(t *testing.T) { parents, parentsClosure, true, - types.EmptyStruct(types.Format_7_18)) + types.EmptyStruct(db.Format())) assert.NoError(err) at5, err := types.TypeOf(commit5) assert.NoError(err) @@ -258,15 +258,15 @@ func TestCommitWithoutMetaField(t *testing.T) { db := NewDatabase(storage.NewView()).(*database) defer db.Close() - metaCommit, err := types.NewStruct(types.Format_7_18, "Commit", types.StructData{ + metaCommit, err := types.NewStruct(db.Format(), "Commit", types.StructData{ "value": types.Float(9), "parents": mustSet(types.NewSet(context.Background(), db)), - "meta": types.EmptyStruct(types.Format_7_18), + "meta": types.EmptyStruct(db.Format()), }) assert.NoError(err) assert.True(IsCommit(metaCommit)) - noMetaCommit, err := types.NewStruct(types.Format_7_18, "Commit", types.StructData{ + noMetaCommit, err := types.NewStruct(db.Format(), "Commit", types.StructData{ "value": types.Float(9), "parents": mustSet(types.NewSet(context.Background(), db)), }) @@ -283,7 +283,7 @@ func toRefList(vrw types.ValueReadWriter, commits ...types.Struct) (types.List, le := l.Edit() for _, p := range commits { - le = le.Append(mustRef(types.NewRef(p, types.Format_7_18))) + le = le.Append(mustRef(types.NewRef(p, vrw.Format()))) } return le.List(context.Background()) } @@ -317,7 +317,7 @@ func assertCommonAncestor(t *testing.T, expected, a, b types.Struct, ldb, rdb *d for name, method := range methods { tn := fmt.Sprintf("find common ancestor using %s", name) t.Run(tn, func(t *testing.T) { - found, ok, err := method(context.Background(), mustRef(types.NewRef(a, types.Format_7_18)), mustRef(types.NewRef(b, types.Format_7_18)), ldb, rdb) + found, ok, err := method(context.Background(), mustRef(types.NewRef(a, ldb.Format())), mustRef(types.NewRef(b, rdb.Format())), ldb, rdb) assert.NoError(err) if assert.True(ok) { @@ -578,7 +578,7 @@ func TestFindCommonAncestor(t *testing.T) { assertCommonAncestor(t, a1, a6, c3, db, db) // Traversing multiple parents on both sides // No common ancestor - found, ok, err := FindCommonAncestor(context.Background(), mustRef(types.NewRef(d2, types.Format_7_18)), mustRef(types.NewRef(a6, types.Format_7_18)), db, db) + found, ok, err := FindCommonAncestor(context.Background(), mustRef(types.NewRef(d2, db.Format())), mustRef(types.NewRef(a6, db.Format())), db, db) require.NoError(t, err) if !assert.False(ok) { @@ -655,7 +655,7 @@ func TestFindCommonAncestor(t *testing.T) { assertCommonAncestor(t, a6, a9, ra9, db, rdb) // Common third parent - _, _, err = FindCommonAncestor(context.Background(), mustRef(types.NewRef(a9, types.Format_7_18)), mustRef(types.NewRef(ra9, types.Format_7_18)), rdb, db) + _, _, err = FindCommonAncestor(context.Background(), mustRef(types.NewRef(a9, db.Format())), mustRef(types.NewRef(ra9, db.Format())), rdb, db) assert.Error(err) } @@ -666,19 +666,19 @@ func TestNewCommitRegressionTest(t *testing.T) { parents := mustList(types.NewList(context.Background(), db)) parentsClosure := mustParentsClosure(t, false)(getParentsClosure(context.Background(), db, parents)) - c1, err := newCommit(context.Background(), types.String("one"), parents, parentsClosure, false, types.EmptyStruct(types.Format_7_18)) + c1, err := newCommit(context.Background(), types.String("one"), parents, parentsClosure, false, types.EmptyStruct(db.Format())) assert.NoError(t, err) - cx, err := newCommit(context.Background(), types.Bool(true), parents, parentsClosure, false, types.EmptyStruct(types.Format_7_18)) + cx, err := newCommit(context.Background(), types.Bool(true), parents, parentsClosure, false, types.EmptyStruct(db.Format())) assert.NoError(t, err) _, err = db.WriteValue(context.Background(), c1) assert.NoError(t, err) _, err = db.WriteValue(context.Background(), cx) assert.NoError(t, err) value := types.String("two") - parents, err = types.NewList(context.Background(), db, mustRef(types.NewRef(c1, types.Format_7_18))) + parents, err = types.NewList(context.Background(), db, mustRef(types.NewRef(c1, db.Format()))) assert.NoError(t, err) parentsClosure = mustParentsClosure(t, true)(getParentsClosure(context.Background(), db, parents)) - meta, err := types.NewStruct(types.Format_7_18, "", types.StructData{ + meta, err := types.NewStruct(db.Format(), "", types.StructData{ "basis": cx, }) assert.NoError(t, err) diff --git a/go/store/datas/database_test.go b/go/store/datas/database_test.go index 673c0cf6d5..db46ebe51e 100644 --- a/go/store/datas/database_test.go +++ b/go/store/datas/database_test.go @@ -265,17 +265,17 @@ func (suite *DatabaseSuite) TestDatabaseCommit() { suite.Equal(uint64(2), datasets2.Len()) } -func (m nomsDatasetsMap) toNomsMap() (types.Map, bool) { - return m.m, true -} - func mustNomsMap(t *testing.T, dsm DatasetsMap) types.Map { - m, ok := dsm.(nomsDatasetsMap).toNomsMap() + m, ok := dsm.(nomsDatasetsMap) require.True(t, ok) - return m + return m.m } func (suite *DatabaseSuite) TestDatasetsMapType() { + if suite.db.Format() == types.Format_DOLT_1 { + suite.T().Skip() + } + dsID1, dsID2 := "ds1", "ds2" datasets, err := suite.db.Datasets(context.Background()) diff --git a/go/store/datas/dataset.go b/go/store/datas/dataset.go index 8c0b06e408..912716a549 100644 --- a/go/store/datas/dataset.go +++ b/go/store/datas/dataset.go @@ -29,6 +29,7 @@ import ( "github.com/dolthub/dolt/go/store/chunks" "github.com/dolthub/dolt/go/store/hash" "github.com/dolthub/dolt/go/store/types" + "github.com/dolthub/dolt/go/gen/fb/serial" ) // DatasetRe is a regexp that matches a legal Dataset name anywhere within the @@ -58,6 +59,35 @@ func (h nomsHead) Addr() hash.Hash { return h.addr } +type serialTagHead struct { + msg *serial.Tag + addr hash.Hash +} + +func newSerialTagHead(bs []byte, addr hash.Hash) serialTagHead { + return serialTagHead{serial.GetRootAsTag(bs, 0), addr} +} + +func (h serialTagHead) TypeName() string { + return TagName +} + +func (h serialTagHead) Addr() hash.Hash { + return h.addr +} + +func (h serialTagHead) HeadTag() (*TagMeta, hash.Hash, error) { + addr := hash.New(h.msg.CommitAddrBytes()) + meta := &TagMeta{ + Name: string(h.msg.Name()), + Email: string(h.msg.Email()), + Timestamp: h.msg.TimestampMillis(), + Description: string(h.msg.Desc()), + UserTimestamp: h.msg.UserTimestampMillis(), + } + return meta, addr, nil +} + // Dataset is a named value within a Database. Different head values may be stored in a dataset. Most commonly, this is // a commit, but other values are also supported in some cases. type Dataset struct { @@ -70,6 +100,11 @@ func newHead(db *database, c chunks.Chunk) (dsHead, error) { if c.IsEmpty() { return nil, nil } + + if serial.GetFileID(c.Data()) == serial.TagFileID { + return newSerialTagHead(c.Data(), c.Hash()), nil + } + head, err := types.DecodeValue(c, db) if err != nil { return nil, err @@ -150,7 +185,7 @@ func (ds Dataset) MaybeHeadAddr() (hash.Hash, bool) { } func (ds Dataset) IsTag() bool { - return ds.head == nil && ds.head.TypeName() == TagName + return ds.head != nil && ds.head.TypeName() == TagName } func (ds Dataset) HeadTag() (*TagMeta, hash.Hash, error) { diff --git a/go/store/datas/tag_test.go b/go/store/datas/tag_test.go index c6d0e33cf8..f7f7810120 100644 --- a/go/store/datas/tag_test.go +++ b/go/store/datas/tag_test.go @@ -39,6 +39,10 @@ func TestNewTag(t *testing.T) { db := NewDatabase(storage.NewView()).(*database) defer db.Close() + if db.Format() == types.Format_DOLT_1 { + t.Skip() + } + parents := mustList(types.NewList(ctx, db)) parentsClosure := mustParentsClosure(t, false)(getParentsClosure(ctx, db, parents)) commit, err := newCommit(ctx, types.Float(1), parents, parentsClosure, false, types.EmptyStruct(types.Format_7_18))