mirror of
https://github.com/dolthub/dolt.git
synced 2026-05-02 11:30:13 -05:00
Revert "Revert "Merge pull request #3077 from dolthub/aaron/datas-commit-as-fb-message""
This reverts commit ee68e00000.
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/fatih/color"
|
||||
|
||||
"github.com/dolthub/dolt/go/cmd/dolt/cli"
|
||||
"github.com/dolthub/dolt/go/gen/fb/serial"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/dbfactory"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/env"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
|
||||
@@ -140,11 +141,17 @@ func (cmd RootsCmd) processTableFile(ctx context.Context, path string, modified
|
||||
|
||||
if mightBeDatasetMap {
|
||||
err := types.WriteEncodedValue(ctx, cli.OutStream, value)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
cli.Println()
|
||||
}
|
||||
} else if sm, ok := value.(types.SerialMessage); ok {
|
||||
if serial.GetFileID([]byte(sm)) == serial.StoreRootFileID {
|
||||
err := types.WriteEncodedValue(ctx, cli.OutStream, value)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
cli.Println()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
// Code generated by the FlatBuffers compiler. DO NOT EDIT.
|
||||
|
||||
package serial
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type Commit struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsCommit(buf []byte, offset flatbuffers.UOffsetT) *Commit {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &Commit{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsCommit(buf []byte, offset flatbuffers.UOffsetT) *Commit {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &Commit{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func (rcv *Commit) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Commit) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *Commit) Root(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) RootLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) RootBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Commit) MutateRoot(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Commit) Height() uint64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetUint64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) MutateHeight(n uint64) bool {
|
||||
return rcv._tab.MutateUint64Slot(6, n)
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentAddrs(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentAddrsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentAddrsBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Commit) MutateParentAddrs(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentHeights(j int) uint64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetUint64(a + flatbuffers.UOffsetT(j*8))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentHeightsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) MutateParentHeights(j int, n uint64) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateUint64(a+flatbuffers.UOffsetT(j*8), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentClosure(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentClosureLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentClosureBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Commit) MutateParentClosure(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Commit) Name() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Commit) Email() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Commit) Description() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Commit) TimestampMillis() uint64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetUint64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) MutateTimestampMillis(n uint64) bool {
|
||||
return rcv._tab.MutateUint64Slot(20, n)
|
||||
}
|
||||
|
||||
func (rcv *Commit) UserTimestampMillis() int64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) MutateUserTimestampMillis(n int64) bool {
|
||||
return rcv._tab.MutateInt64Slot(22, n)
|
||||
}
|
||||
|
||||
func CommitStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(10)
|
||||
}
|
||||
func CommitAddRoot(builder *flatbuffers.Builder, root flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(root), 0)
|
||||
}
|
||||
func CommitStartRootVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(1, numElems, 1)
|
||||
}
|
||||
func CommitAddHeight(builder *flatbuffers.Builder, height uint64) {
|
||||
builder.PrependUint64Slot(1, height, 0)
|
||||
}
|
||||
func CommitAddParentAddrs(builder *flatbuffers.Builder, parentAddrs flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(parentAddrs), 0)
|
||||
}
|
||||
func CommitStartParentAddrsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(1, numElems, 1)
|
||||
}
|
||||
func CommitAddParentHeights(builder *flatbuffers.Builder, parentHeights flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(parentHeights), 0)
|
||||
}
|
||||
func CommitStartParentHeightsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(8, numElems, 8)
|
||||
}
|
||||
func CommitAddParentClosure(builder *flatbuffers.Builder, parentClosure flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(4, flatbuffers.UOffsetT(parentClosure), 0)
|
||||
}
|
||||
func CommitStartParentClosureVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(1, numElems, 1)
|
||||
}
|
||||
func CommitAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(5, flatbuffers.UOffsetT(name), 0)
|
||||
}
|
||||
func CommitAddEmail(builder *flatbuffers.Builder, email flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(6, flatbuffers.UOffsetT(email), 0)
|
||||
}
|
||||
func CommitAddDescription(builder *flatbuffers.Builder, description flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(7, flatbuffers.UOffsetT(description), 0)
|
||||
}
|
||||
func CommitAddTimestampMillis(builder *flatbuffers.Builder, timestampMillis uint64) {
|
||||
builder.PrependUint64Slot(8, timestampMillis, 0)
|
||||
}
|
||||
func CommitAddUserTimestampMillis(builder *flatbuffers.Builder, userTimestampMillis int64) {
|
||||
builder.PrependInt64Slot(9, userTimestampMillis, 0)
|
||||
}
|
||||
func CommitEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
@@ -253,210 +253,3 @@ func MergeStateAddCandidateMergeCommit(builder *flatbuffers.Builder, candidateMe
|
||||
func MergeStateEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
|
||||
type Commit struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsCommit(buf []byte, offset flatbuffers.UOffsetT) *Commit {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &Commit{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsCommit(buf []byte, offset flatbuffers.UOffsetT) *Commit {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &Commit{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func (rcv *Commit) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Commit) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *Commit) Root(obj *Ref) *Ref {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(Ref)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentList(obj *Ref, j int) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
x = rcv._tab.Indirect(x)
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentListLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Commit) ParentClosure(obj *Ref) *Ref {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(Ref)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *Commit) Meta(obj *CommitMeta) *CommitMeta {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(CommitMeta)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CommitStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(4)
|
||||
}
|
||||
func CommitAddRoot(builder *flatbuffers.Builder, root flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(root), 0)
|
||||
}
|
||||
func CommitAddParentList(builder *flatbuffers.Builder, parentList flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(parentList), 0)
|
||||
}
|
||||
func CommitStartParentListVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(4, numElems, 4)
|
||||
}
|
||||
func CommitAddParentClosure(builder *flatbuffers.Builder, parentClosure flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(parentClosure), 0)
|
||||
}
|
||||
func CommitAddMeta(builder *flatbuffers.Builder, meta flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(meta), 0)
|
||||
}
|
||||
func CommitEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
|
||||
type CommitMeta struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsCommitMeta(buf []byte, offset flatbuffers.UOffsetT) *CommitMeta {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &CommitMeta{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsCommitMeta(buf []byte, offset flatbuffers.UOffsetT) *CommitMeta {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &CommitMeta{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func (rcv *CommitMeta) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *CommitMeta) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *CommitMeta) Name() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *CommitMeta) Email() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *CommitMeta) Desc() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *CommitMeta) Timestamp(obj *Timestamp) *Timestamp {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
x := o + rcv._tab.Pos
|
||||
if obj == nil {
|
||||
obj = new(Timestamp)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *CommitMeta) UserTimestamp(obj *Timestamp) *Timestamp {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
x := o + rcv._tab.Pos
|
||||
if obj == nil {
|
||||
obj = new(Timestamp)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CommitMetaStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(5)
|
||||
}
|
||||
func CommitMetaAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(name), 0)
|
||||
}
|
||||
func CommitMetaAddEmail(builder *flatbuffers.Builder, email flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(email), 0)
|
||||
}
|
||||
func CommitMetaAddDesc(builder *flatbuffers.Builder, desc flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(desc), 0)
|
||||
}
|
||||
func CommitMetaAddTimestamp(builder *flatbuffers.Builder, timestamp flatbuffers.UOffsetT) {
|
||||
builder.PrependStructSlot(3, flatbuffers.UOffsetT(timestamp), 0)
|
||||
}
|
||||
func CommitMetaAddUserTimestamp(builder *flatbuffers.Builder, userTimestamp flatbuffers.UOffsetT) {
|
||||
builder.PrependStructSlot(4, flatbuffers.UOffsetT(userTimestamp), 0)
|
||||
}
|
||||
func CommitMetaEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package serial
|
||||
const StoreRootFileID = "STRT"
|
||||
const TagFileID = "DTAG"
|
||||
const WorkingSetFileID = "WRST"
|
||||
const CommitFileID = "DCMT"
|
||||
|
||||
func GetFileID(bs []byte) string {
|
||||
if len(bs) < 8 {
|
||||
|
||||
@@ -37,7 +37,7 @@ type Commit struct {
|
||||
}
|
||||
|
||||
func NewCommit(ctx context.Context, vrw types.ValueReadWriter, commitV types.Value) (*Commit, error) {
|
||||
parents, err := datas.GetCommitParents(ctx, commitV)
|
||||
parents, err := datas.GetCommitParents(ctx, vrw, commitV)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -49,7 +49,7 @@ func NewCommit(ctx context.Context, vrw types.ValueReadWriter, commitV types.Val
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rootVal, err := datas.GetCommitValue(ctx, commitV)
|
||||
rootVal, err := datas.GetCommitValue(ctx, vrw, commitV)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -264,7 +264,9 @@ func (ddb *DoltDB) NewPendingCommit(
|
||||
}
|
||||
|
||||
for _, pc := range parentCommits {
|
||||
parents = append(parents, pc.stref.TargetHash())
|
||||
if pc.stref.TargetHash() != nomsHeadAddr {
|
||||
parents = append(parents, pc.stref.TargetHash())
|
||||
}
|
||||
}
|
||||
|
||||
commitOpts := datas.CommitOptions{Parents: parents, Meta: cm}
|
||||
|
||||
@@ -525,7 +525,9 @@ func (ddb *DoltDB) CommitWithParentCommits(ctx context.Context, valHash hash.Has
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parents = append(parents, addr)
|
||||
if addr != headAddr {
|
||||
parents = append(parents, addr)
|
||||
}
|
||||
}
|
||||
|
||||
commitOpts := datas.CommitOptions{Parents: parents, Meta: cm}
|
||||
|
||||
@@ -17,6 +17,7 @@ package commitwalk
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -36,6 +37,18 @@ const (
|
||||
workingDir = "/doesnotexist/work"
|
||||
)
|
||||
|
||||
var lastUserTSMillis int64
|
||||
|
||||
func MonotonicNow() time.Time {
|
||||
now := time.Now()
|
||||
millis := now.UnixMilli()
|
||||
if millis <= lastUserTSMillis {
|
||||
now = time.UnixMilli(lastUserTSMillis).Add(time.Millisecond)
|
||||
}
|
||||
lastUserTSMillis = now.UnixMilli()
|
||||
return now
|
||||
}
|
||||
|
||||
func testHomeDirFunc() (string, error) {
|
||||
return testHomeDir, nil
|
||||
}
|
||||
@@ -109,6 +122,7 @@ func TestGetDotDotRevisions(t *testing.T) {
|
||||
|
||||
res, err := GetDotDotRevisions(context.Background(), dEnv.DoltDB, featureHash, dEnv.DoltDB, mainHash, 100)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, res, 7)
|
||||
assertEqualHashes(t, featureCommits[7], res[0])
|
||||
assertEqualHashes(t, featureCommits[6], res[1])
|
||||
@@ -201,7 +215,7 @@ func assertEqualHashes(t *testing.T, lc, rc *doltdb.Commit) {
|
||||
}
|
||||
|
||||
func mustCreateCommit(t *testing.T, ddb *doltdb.DoltDB, bn string, rvh hash.Hash, parents ...*doltdb.Commit) *doltdb.Commit {
|
||||
cm, err := datas.NewCommitMeta("Bill Billerson", "bill@billerson.com", "A New Commit.")
|
||||
cm, err := datas.NewCommitMetaWithUserTS("Bill Billerson", "bill@billerson.com", "A New Commit.", MonotonicNow())
|
||||
require.NoError(t, err)
|
||||
pcs := make([]*doltdb.CommitSpec, 0, len(parents))
|
||||
for _, parent := range parents {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
namespace serial;
|
||||
|
||||
table Commit {
|
||||
// hash addr of the root value associated with the commit.
|
||||
root:[ubyte] (required);
|
||||
height:uint64;
|
||||
|
||||
parent_addrs:[ubyte] (required);
|
||||
parent_heights:[uint64] (required);
|
||||
|
||||
parent_closure:[ubyte];
|
||||
|
||||
name:string (required);
|
||||
email:string (required);
|
||||
description:string (required);
|
||||
timestamp_millis:uint64;
|
||||
user_timestamp_millis:int64;
|
||||
}
|
||||
|
||||
// KEEP THIS IN SYNC WITH fileidentifiers.go
|
||||
file_identifier "DCMT";
|
||||
|
||||
root_type Commit;
|
||||
@@ -40,18 +40,3 @@ table MergeState {
|
||||
pre_merge_root:Ref (required);
|
||||
candidate_merge_commit:Ref (required);
|
||||
}
|
||||
|
||||
table Commit {
|
||||
root:Ref (required);
|
||||
parent_list:[Ref] (required);
|
||||
parent_closure:Ref (required);
|
||||
meta:CommitMeta (required);
|
||||
}
|
||||
|
||||
table CommitMeta {
|
||||
name:string (required);
|
||||
email:string (required);
|
||||
desc:string (required);
|
||||
timestamp:Timestamp (required);
|
||||
user_timestamp:Timestamp (required);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package serial
|
||||
const StoreRootFileID = "STRT"
|
||||
const TagFileID = "DTAG"
|
||||
const WorkingSetFileID = "WRST"
|
||||
const CommitFileID = "DCMT"
|
||||
|
||||
func GetFileID(bs []byte) string {
|
||||
if len(bs) < 8 {
|
||||
|
||||
@@ -7,6 +7,7 @@ rm $GEN_DIR/*.go
|
||||
|
||||
# generate golang (de)serialization package
|
||||
flatc -o $GEN_DIR --gen-onefile --filename-suffix "" --gen-mutable --go-namespace "serial" --go \
|
||||
commit.fbs \
|
||||
database.fbs \
|
||||
prolly.fbs \
|
||||
schema.fbs \
|
||||
|
||||
@@ -71,7 +71,7 @@ func (iter *CommitIterator) Next(ctx context.Context) (LogNode, bool) {
|
||||
// and splice that into the iterators list of branches.
|
||||
branches := branchList{}
|
||||
|
||||
refs, err := datas.GetCommitParents(ctx, br.commit)
|
||||
refs, err := datas.GetCommitParents(ctx, iter.vr, br.commit)
|
||||
d.PanicIfError(err)
|
||||
for _, r := range refs {
|
||||
v, err := iter.vr.ReadValue(ctx, r.TargetHash())
|
||||
|
||||
@@ -89,9 +89,10 @@ func (s *nomsCommitTestSuite) TestNomsCommitReadPathFromStdin() {
|
||||
sp, _ = spec.ForDataset(sp.String())
|
||||
defer sp.Close()
|
||||
|
||||
vrw := sp.GetVRW(context.Background())
|
||||
commit, ok := sp.GetDataset(context.Background()).MaybeHead()
|
||||
s.True(ok, "should have a commit now")
|
||||
value, err := datas.GetCommitValue(context.Background(), commit)
|
||||
value, err := datas.GetCommitValue(context.Background(), vrw, commit)
|
||||
s.NoError(err)
|
||||
s.NotNil(value)
|
||||
h, err := value.Hash(types.Format_7_18)
|
||||
@@ -118,9 +119,10 @@ func (s *nomsCommitTestSuite) TestNomsCommitToDatasetWithoutHead() {
|
||||
sp, _ = spec.ForDataset(sp.String())
|
||||
defer sp.Close()
|
||||
|
||||
vrw := sp.GetVRW(context.Background())
|
||||
commit, ok := sp.GetDataset(context.Background()).MaybeHead()
|
||||
s.True(ok, "should have a commit now")
|
||||
value, err := datas.GetCommitValue(context.Background(), commit)
|
||||
value, err := datas.GetCommitValue(context.Background(), vrw, commit)
|
||||
s.NoError(err)
|
||||
s.NotNil(value)
|
||||
h, err := value.Hash(types.Format_7_18)
|
||||
|
||||
@@ -74,7 +74,7 @@ func runDiff(ctx context.Context, args []string) int {
|
||||
d.PanicIfFalse(vrw1.Format() == vrw2.Format())
|
||||
|
||||
if stat {
|
||||
diff.Summary(ctx, value1, value2)
|
||||
diff.Summary(ctx, vrw1, vrw2, value1, value2)
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ func printCommit(ctx context.Context, node LogNode, path types.Path, w io.Writer
|
||||
|
||||
parentLabel := "Parent"
|
||||
parentValue := "None"
|
||||
parents, err := datas.GetCommitParents(context.Background(), node.commit)
|
||||
parents, err := datas.GetCommitParents(context.Background(), vr, node.commit)
|
||||
d.PanicIfError(err)
|
||||
if len(parents) > 1 {
|
||||
pstrings := make([]string, len(parents))
|
||||
@@ -339,7 +339,7 @@ func writeDiffLines(ctx context.Context, node LogNode, path types.Path, vr types
|
||||
mlw := &writers.MaxLineWriter{Dest: w, MaxLines: uint32(maxLines), NumLines: uint32(lineno)}
|
||||
pw := &writers.PrefixWriter{Dest: mlw, PrefixFunc: genPrefix, NeedsPrefix: true, NumLines: uint32(lineno)}
|
||||
|
||||
parents, err := datas.GetCommitParents(ctx, node.commit)
|
||||
parents, err := datas.GetCommitParents(ctx, vr, node.commit)
|
||||
d.PanicIfError(err)
|
||||
|
||||
if len(parents) == 0 {
|
||||
|
||||
@@ -173,7 +173,7 @@ func getMergeCandidates(ctx context.Context, db datas.Database, vrw types.ValueR
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
vfld, err := datas.GetCommitValue(ctx, ancestorCommit)
|
||||
vfld, err := datas.GetCommitValue(ctx, vrw, ancestorCommit)
|
||||
d.PanicIfError(err)
|
||||
d.PanicIfFalse(vfld != nil)
|
||||
return leftHead, rightHead, vfld, nil
|
||||
|
||||
@@ -131,7 +131,7 @@ func (s *nomsMergeTestSuite) validateDataset(name string, expected types.Struct,
|
||||
if s.NoError(err) {
|
||||
defer sp.Close()
|
||||
commit := mustHead(sp.GetDataset(context.Background()))
|
||||
vparents, err := datas.GetCommitParents(context.Background(), commit)
|
||||
vparents, err := datas.GetCommitParents(context.Background(), sp.GetVRW(context.Background()), commit)
|
||||
s.NoError(err)
|
||||
s.Equal(len(vparents), len(parents), "parents were not the same length")
|
||||
for i := range parents {
|
||||
|
||||
@@ -32,7 +32,6 @@ import (
|
||||
"github.com/dolthub/dolt/go/store/cmd/noms/util"
|
||||
"github.com/dolthub/dolt/go/store/config"
|
||||
"github.com/dolthub/dolt/go/store/d"
|
||||
"github.com/dolthub/dolt/go/store/datas"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
@@ -167,15 +166,5 @@ func validate(ctx context.Context, nbf *types.NomsBinFormat, r types.Value) bool
|
||||
return false
|
||||
}
|
||||
|
||||
yep, err := r.(types.Map).Any(ctx, func(k, v types.Value) bool {
|
||||
if !datas.IsRefOfCommitType(nbf, mustType(types.TypeOf(v))) {
|
||||
fmt.Fprintf(os.Stderr, "Invalid root map. Value for key '%s' is not a ref of commit.", string(k.(types.String)))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
d.PanicIfError(err)
|
||||
|
||||
return yep
|
||||
return true
|
||||
}
|
||||
|
||||
+110
-10
@@ -27,6 +27,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
|
||||
"github.com/dolthub/dolt/go/gen/fb/serial"
|
||||
"github.com/dolthub/dolt/go/store/d"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/dolthub/dolt/go/store/nomdl"
|
||||
@@ -112,10 +115,71 @@ func NewCommitForValue(ctx context.Context, vrw types.ValueReadWriter, v types.V
|
||||
return newCommitForValue(ctx, vrw, v, opts)
|
||||
}
|
||||
|
||||
func commit_flatbuffer(vaddr hash.Hash, opts CommitOptions, heights []uint64) []byte {
|
||||
builder := flatbuffers.NewBuilder(1024)
|
||||
vaddroff := builder.CreateByteVector(vaddr[:])
|
||||
|
||||
hashsz := 20
|
||||
hashessz := len(opts.Parents) * hashsz
|
||||
builder.Prep(flatbuffers.SizeUOffsetT, hashessz)
|
||||
stop := int(builder.Head())
|
||||
start := stop - hashessz
|
||||
for i := 0; i < len(opts.Parents); i++ {
|
||||
copy(builder.Bytes[start:stop], opts.Parents[i][:])
|
||||
start += hashsz
|
||||
}
|
||||
start = stop - hashessz
|
||||
parentaddrsoff := builder.CreateByteVector(builder.Bytes[start:stop])
|
||||
|
||||
// Starts at SerialMessageRefHeight.
|
||||
maxheight := uint64(types.SerialMessageRefHeight)
|
||||
serial.CommitStartParentHeightsVector(builder, len(opts.Parents))
|
||||
for i := len(opts.Parents) - 1; i >= 0; i-- {
|
||||
builder.PrependUint64(heights[i])
|
||||
if heights[i] > maxheight {
|
||||
maxheight = heights[i]
|
||||
}
|
||||
}
|
||||
parentheightsoff := builder.EndVector(len(opts.Parents))
|
||||
|
||||
nameoff := builder.CreateString(opts.Meta.Name)
|
||||
emailoff := builder.CreateString(opts.Meta.Email)
|
||||
descoff := builder.CreateString(opts.Meta.Description)
|
||||
serial.CommitStart(builder)
|
||||
serial.CommitAddRoot(builder, vaddroff)
|
||||
serial.CommitAddHeight(builder, maxheight+1)
|
||||
serial.CommitAddParentAddrs(builder, parentaddrsoff)
|
||||
serial.CommitAddParentHeights(builder, parentheightsoff)
|
||||
serial.CommitAddName(builder, nameoff)
|
||||
serial.CommitAddEmail(builder, emailoff)
|
||||
serial.CommitAddDescription(builder, descoff)
|
||||
serial.CommitAddTimestampMillis(builder, opts.Meta.Timestamp)
|
||||
serial.CommitAddUserTimestampMillis(builder, opts.Meta.UserTimestamp)
|
||||
builder.FinishWithFileIdentifier(serial.CommitEnd(builder), []byte(serial.CommitFileID))
|
||||
return builder.FinishedBytes()
|
||||
}
|
||||
|
||||
func newCommitForValue(ctx context.Context, vrw types.ValueReadWriter, v types.Value, opts CommitOptions) (types.Value, error) {
|
||||
if opts.Meta == nil {
|
||||
opts.Meta = &CommitMeta{}
|
||||
}
|
||||
|
||||
if vrw.Format() == types.Format_DOLT_DEV {
|
||||
r, err := vrw.WriteValue(ctx, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
heights := make([]uint64, len(opts.Parents))
|
||||
parents, err := vrw.ReadManyValues(ctx, opts.Parents)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range heights {
|
||||
heights[i] = serial.GetRootAsCommit([]byte(parents[i].(types.SerialMessage)), 0).Height()
|
||||
}
|
||||
return types.SerialMessage(commit_flatbuffer(r.TargetHash(), opts, heights)), nil
|
||||
}
|
||||
|
||||
metaSt, err := opts.Meta.toNomsStruct(vrw.Format())
|
||||
if err != nil {
|
||||
return types.Struct{}, err
|
||||
@@ -262,7 +326,14 @@ func FindClosureCommonAncestor(ctx context.Context, cl RefClosure, cm types.Ref,
|
||||
}
|
||||
|
||||
// GetCommitParents returns |Ref|s to the parents of the commit.
|
||||
func GetCommitParents(ctx context.Context, cv types.Value) ([]types.Ref, error) {
|
||||
func GetCommitParents(ctx context.Context, vr types.ValueReader, cv types.Value) ([]types.Ref, error) {
|
||||
if sm, ok := cv.(types.SerialMessage); ok {
|
||||
data := []byte(sm)
|
||||
if serial.GetFileID(data) != serial.CommitFileID {
|
||||
return nil, errors.New("GetCommitParents: provided value is not a commit.")
|
||||
}
|
||||
return types.SerialCommitParentRefs(vr.Format(), sm)
|
||||
}
|
||||
c, ok := cv.(types.Struct)
|
||||
if !ok {
|
||||
return nil, errors.New("GetCommitParents: provided value is not a commit.")
|
||||
@@ -301,6 +372,20 @@ func GetCommitParents(ctx context.Context, cv types.Value) ([]types.Ref, error)
|
||||
// GetCommitMeta extracts the CommitMeta field from a commit. Returns |nil,
|
||||
// nil| if there is no metadata for the commit.
|
||||
func GetCommitMeta(ctx context.Context, cv types.Value) (*CommitMeta, error) {
|
||||
if sm, ok := cv.(types.SerialMessage); ok {
|
||||
data := []byte(sm)
|
||||
if serial.GetFileID(data) != serial.CommitFileID {
|
||||
return nil, errors.New("GetCommitMeta: provided value is not a commit.")
|
||||
}
|
||||
cmsg := serial.GetRootAsCommit(data, 0)
|
||||
ret := &CommitMeta{}
|
||||
ret.Name = string(cmsg.Name())
|
||||
ret.Email = string(cmsg.Email())
|
||||
ret.Description = string(cmsg.Description())
|
||||
ret.Timestamp = cmsg.TimestampMillis()
|
||||
ret.UserTimestamp = cmsg.UserTimestampMillis()
|
||||
return ret, nil
|
||||
}
|
||||
c, ok := cv.(types.Struct)
|
||||
if !ok {
|
||||
return nil, errors.New("GetCommitMeta: provided value is not a commit.")
|
||||
@@ -322,7 +407,17 @@ func GetCommitMeta(ctx context.Context, cv types.Value) (*CommitMeta, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func GetCommitValue(ctx context.Context, cv types.Value) (types.Value, error) {
|
||||
func GetCommitValue(ctx context.Context, vr types.ValueReader, cv types.Value) (types.Value, error) {
|
||||
if sm, ok := cv.(types.SerialMessage); ok {
|
||||
data := []byte(sm)
|
||||
if serial.GetFileID(data) != serial.CommitFileID {
|
||||
return nil, errors.New("GetCommitValue: provided value is not a commit.")
|
||||
}
|
||||
cmsg := serial.GetRootAsCommit(data, 0)
|
||||
var roothash hash.Hash
|
||||
copy(roothash[:], cmsg.RootBytes())
|
||||
return vr.ReadValue(ctx, roothash)
|
||||
}
|
||||
c, ok := cv.(types.Struct)
|
||||
if !ok {
|
||||
return nil, errors.New("GetCommitValue: provided value is not a commit.")
|
||||
@@ -350,7 +445,7 @@ func parentsToQueue(ctx context.Context, refs types.RefSlice, q *RefByHeightHeap
|
||||
return fmt.Errorf("target not found: %v", r.TargetHash())
|
||||
}
|
||||
|
||||
parents, err := GetCommitParents(ctx, v)
|
||||
parents, err := GetCommitParents(ctx, vr, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -523,6 +618,12 @@ func newParentsClosureIterator(ctx context.Context, r types.Ref, vr types.ValueR
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, ok := sv.(types.SerialMessage); ok {
|
||||
// TODO: __DOLT_DEV__ should support parent closures.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
s, ok := sv.(types.Struct)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("target ref is not struct: %v", sv)
|
||||
@@ -577,17 +678,16 @@ func IsCommitType(nbf *types.NomsBinFormat, t *types.Type) bool {
|
||||
}
|
||||
|
||||
func IsCommit(v types.Value) (bool, error) {
|
||||
if s, ok := v.(types.Struct); !ok {
|
||||
return false, nil
|
||||
} else {
|
||||
if s, ok := v.(types.Struct); ok {
|
||||
return types.IsValueSubtypeOf(s.Format(), v, valueCommitType)
|
||||
} else if sm, ok := v.(types.SerialMessage); ok {
|
||||
data := []byte(sm)
|
||||
return serial.GetFileID(data) == serial.CommitFileID, nil
|
||||
} else {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func IsRefOfCommitType(nbf *types.NomsBinFormat, t *types.Type) bool {
|
||||
return t.TargetKind() == types.RefKind && IsCommitType(nbf, getRefElementType(t))
|
||||
}
|
||||
|
||||
type RefByHeightHeap []types.Ref
|
||||
|
||||
func (r RefByHeightHeap) Less(i, j int) bool {
|
||||
|
||||
@@ -51,10 +51,6 @@ type CommitMeta struct {
|
||||
UserTimestamp int64
|
||||
}
|
||||
|
||||
var uMilliToNano = uint64(time.Millisecond / time.Nanosecond)
|
||||
var milliToNano = int64(time.Millisecond / time.Nanosecond)
|
||||
var secToMilli = int64(time.Second / time.Millisecond)
|
||||
|
||||
// NewCommitMeta creates a CommitMeta instance from a name, email, and description and uses the current time for the
|
||||
// timestamp
|
||||
func NewCommitMeta(name, email, desc string) (*CommitMeta, error) {
|
||||
@@ -79,10 +75,8 @@ func NewCommitMetaWithUserTS(name, email, desc string, userTS time.Time) (*Commi
|
||||
return nil, ErrEmptyCommitMessage
|
||||
}
|
||||
|
||||
ns := uint64(CommitNowFunc().UnixNano())
|
||||
ms := ns / uMilliToNano
|
||||
|
||||
userMS := userTS.UnixNano() / milliToNano
|
||||
ms := uint64(CommitNowFunc().UnixMilli())
|
||||
userMS := userTS.UnixMilli()
|
||||
|
||||
return &CommitMeta{n, e, ms, d, userMS}, nil
|
||||
}
|
||||
@@ -154,9 +148,7 @@ func (cm *CommitMeta) toNomsStruct(nbf *types.NomsBinFormat) (types.Struct, erro
|
||||
|
||||
// Time returns the time at which the commit occurred
|
||||
func (cm *CommitMeta) Time() time.Time {
|
||||
seconds := cm.UserTimestamp / secToMilli
|
||||
nanos := (cm.UserTimestamp % secToMilli) * milliToNano
|
||||
return time.Unix(seconds, nanos)
|
||||
return time.UnixMilli(cm.UserTimestamp)
|
||||
}
|
||||
|
||||
// FormatTS takes the internal timestamp and turns it into a human readable string in the time.RubyDate format
|
||||
|
||||
@@ -53,15 +53,12 @@ func mustHeight(ds Dataset) uint64 {
|
||||
|
||||
func mustHeadValue(ds Dataset) types.Value {
|
||||
val, ok, err := ds.MaybeHeadValue()
|
||||
|
||||
if err != nil {
|
||||
panic("error getting head")
|
||||
panic("error getting head " + err.Error())
|
||||
}
|
||||
|
||||
if !ok {
|
||||
panic("no head")
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
@@ -307,8 +304,6 @@ func commonAncWithLazyClosure(ctx context.Context, c1, c2 types.Ref, vr1, vr2 ty
|
||||
|
||||
// Assert that c is the common ancestor of a and b, using multiple common ancestor methods.
|
||||
func assertCommonAncestor(t *testing.T, expected, a, b types.Value, ldb, rdb *database) {
|
||||
assert := assert.New(t)
|
||||
|
||||
type caFinder func(ctx context.Context, c1, c2 types.Ref, vr1, vr2 types.ValueReader) (a types.Ref, ok bool, err error)
|
||||
|
||||
methods := map[string]caFinder{
|
||||
@@ -318,21 +313,23 @@ func assertCommonAncestor(t *testing.T, expected, a, b types.Value, ldb, rdb *da
|
||||
"FindCommonAncestorUsingParentsList": findCommonAncestorUsingParentsList,
|
||||
}
|
||||
|
||||
for name, method := range methods {
|
||||
tn := fmt.Sprintf("find common ancestor using %s", name)
|
||||
t.Run(tn, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
found, ok, err := method(ctx, mustRef(types.NewRef(a, ldb.Format())), mustRef(types.NewRef(b, rdb.Format())), ldb, rdb)
|
||||
assert.NoError(err)
|
||||
aref := mustRef(types.NewRef(a, ldb.Format()))
|
||||
bref := mustRef(types.NewRef(b, rdb.Format()))
|
||||
|
||||
for name, method := range methods {
|
||||
t.Run(fmt.Sprintf("%s/%s_%s", name, aref.TargetHash().String(), bref.TargetHash().String()), func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
ctx := context.Background()
|
||||
found, ok, err := method(ctx, aref, bref, ldb, rdb)
|
||||
assert.NoError(err)
|
||||
if assert.True(ok) {
|
||||
tv, err := found.TargetValue(context.Background(), ldb)
|
||||
assert.NoError(err)
|
||||
ancestor := tv.(types.Struct)
|
||||
expV, _ := GetCommitValue(ctx, expected)
|
||||
aV, _ := GetCommitValue(ctx, a)
|
||||
bV, _ := GetCommitValue(ctx, b)
|
||||
ancV, _ := GetCommitValue(ctx, ancestor)
|
||||
ancestor := tv
|
||||
expV, _ := GetCommitValue(ctx, ldb, expected)
|
||||
aV, _ := GetCommitValue(ctx, ldb, a)
|
||||
bV, _ := GetCommitValue(ctx, rdb, b)
|
||||
ancV, _ := GetCommitValue(ctx, ldb, ancestor)
|
||||
assert.True(
|
||||
expected.Equals(ancestor),
|
||||
"%s should be common ancestor of %s, %s. Got %s",
|
||||
@@ -351,7 +348,7 @@ func addCommit(t *testing.T, db *database, datasetID string, val string, parents
|
||||
ds, err := db.GetDataset(context.Background(), datasetID)
|
||||
assert.NoError(t, err)
|
||||
ds, err = db.Commit(context.Background(), ds, types.String(val), CommitOptions{Parents: mustCommitToTargetHashes(db, parents...)})
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
return mustHead(ds), mustHeadAddr(ds)
|
||||
}
|
||||
|
||||
@@ -418,6 +415,9 @@ func TestCommitParentsClosure(t *testing.T) {
|
||||
}
|
||||
|
||||
assertCommitParentsClosure := func(v types.Value, es []expected) {
|
||||
if _, ok := v.(types.SerialMessage); ok {
|
||||
t.Skip("__DOLT_DEV__ does not implement ParentsClosure yet.")
|
||||
}
|
||||
s, ok := v.(types.Struct)
|
||||
if !assert.True(ok) {
|
||||
return
|
||||
@@ -592,10 +592,10 @@ func TestFindCommonAncestor(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
if !assert.False(ok) {
|
||||
d2V, _ := GetCommitValue(ctx, d2)
|
||||
a6V, _ := GetCommitValue(ctx, a6)
|
||||
d2V, _ := GetCommitValue(ctx, db, d2)
|
||||
a6V, _ := GetCommitValue(ctx, db, a6)
|
||||
fTV, _ := found.TargetValue(ctx, db)
|
||||
fV, _ := GetCommitValue(ctx, fTV)
|
||||
fV, _ := GetCommitValue(ctx, db, fTV)
|
||||
|
||||
assert.Fail(
|
||||
"Unexpected common ancestor!",
|
||||
|
||||
@@ -365,31 +365,48 @@ func (db *database) doSetHead(ctx context.Context, ds Dataset, addr hash.Hash) e
|
||||
return err
|
||||
}
|
||||
|
||||
newSt := newHead.(nomsHead).st
|
||||
newVal := newHead.value()
|
||||
|
||||
headType := newHead.TypeName()
|
||||
switch headType {
|
||||
case commitName:
|
||||
var iscommit bool
|
||||
iscommit, err = IsCommit(newSt)
|
||||
iscommit, err := IsCommit(newVal)
|
||||
if err != nil {
|
||||
break
|
||||
return err
|
||||
}
|
||||
if !iscommit {
|
||||
err = fmt.Errorf("SetHead failed: reffered to value is not a commit:")
|
||||
return fmt.Errorf("SetHead failed: reffered to value is not a commit:")
|
||||
}
|
||||
case TagName:
|
||||
err = db.validateTag(ctx, newHead.(nomsHead).st)
|
||||
istag, err := IsTag(newVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !istag {
|
||||
return fmt.Errorf("SetHead failed: reffered to value is not a tag:")
|
||||
}
|
||||
_, commitaddr, err := newHead.HeadTag()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
commitval, err := db.ReadValue(ctx, commitaddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iscommit, err := IsCommit(commitval)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !iscommit {
|
||||
return fmt.Errorf("SetHead failed: reffered to value is not a tag:")
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Unrecognized dataset value: %s", headType)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key := types.String(ds.ID())
|
||||
|
||||
vref, err := types.NewRef(newSt, db.Format())
|
||||
vref, err := types.NewRef(newVal, db.Format())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -449,8 +466,7 @@ func (db *database) doFastForward(ctx context.Context, ds Dataset, newHeadAddr h
|
||||
return fmt.Errorf("FastForward: target value of new head address %v is not a commit.", newHeadAddr)
|
||||
}
|
||||
|
||||
var v types.Value
|
||||
v = newHead.(nomsHead).st
|
||||
v := newHead.value()
|
||||
iscommit, err := IsCommit(v)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -887,52 +903,6 @@ func (db *database) validateRefAsCommit(ctx context.Context, r types.Ref) (types
|
||||
return v.(types.Struct), nil
|
||||
}
|
||||
|
||||
func (db *database) validateTag(ctx context.Context, t types.Struct) error {
|
||||
is, err := IsTag(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !is {
|
||||
return fmt.Errorf("Tag struct %s is malformed, IsTag() == false", t.String())
|
||||
}
|
||||
|
||||
r, ok, err := t.MaybeGet(TagCommitRefField)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("tag is missing field %s", TagCommitRefField)
|
||||
}
|
||||
|
||||
_, err = db.validateRefAsCommit(ctx, r.(types.Ref))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *database) validateWorkingSet(t types.Struct) error {
|
||||
is, err := IsWorkingSet(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !is {
|
||||
return fmt.Errorf("WorkingSet struct %s is malformed, IsWorkingSet() == false", t.String())
|
||||
}
|
||||
|
||||
_, ok, err := t.MaybeGet(WorkingRootRefField)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("WorkingSet is missing field %s", WorkingRootRefField)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildNewCommit(ctx context.Context, ds Dataset, v types.Value, opts CommitOptions) (types.Value, error) {
|
||||
if opts.Parents == nil || len(opts.Parents) == 0 {
|
||||
headAddr, ok := ds.MaybeHeadAddr()
|
||||
|
||||
@@ -195,6 +195,11 @@ func (suite *DatabaseSuite) TestCommitProperlyTracksRoot() {
|
||||
}
|
||||
|
||||
func (suite *DatabaseSuite) TestDatabaseCommit() {
|
||||
baseHeight := 0
|
||||
if types.Format_Default == types.Format_DOLT_DEV {
|
||||
baseHeight = types.SerialMessageRefHeight
|
||||
}
|
||||
|
||||
datasetID := "ds1"
|
||||
datasets, err := suite.db.Datasets(context.Background())
|
||||
suite.NoError(err)
|
||||
@@ -218,7 +223,7 @@ func (suite *DatabaseSuite) TestDatabaseCommit() {
|
||||
suite.NoError(err)
|
||||
suite.True(ok)
|
||||
suite.True(h.Equals(a))
|
||||
suite.Equal(uint64(1), mustHeight(ds2))
|
||||
suite.Equal(uint64(1+baseHeight), mustHeight(ds2))
|
||||
|
||||
ds = ds2
|
||||
aCommitAddr := mustHeadAddr(ds) // to be used to test disallowing of non-fastforward commits below
|
||||
@@ -228,7 +233,7 @@ func (suite *DatabaseSuite) TestDatabaseCommit() {
|
||||
ds, err = CommitValue(context.Background(), suite.db, ds, b)
|
||||
suite.NoError(err)
|
||||
suite.True(mustHeadValue(ds).Equals(b))
|
||||
suite.Equal(uint64(2), mustHeight(ds))
|
||||
suite.Equal(uint64(2+baseHeight), mustHeight(ds))
|
||||
|
||||
// |a| <- |b|
|
||||
// \----|c|
|
||||
@@ -243,7 +248,7 @@ func (suite *DatabaseSuite) TestDatabaseCommit() {
|
||||
ds, err = CommitValue(context.Background(), suite.db, ds, d)
|
||||
suite.NoError(err)
|
||||
suite.True(mustHeadValue(ds).Equals(d))
|
||||
suite.Equal(uint64(3), mustHeight(ds))
|
||||
suite.Equal(uint64(3+baseHeight), mustHeight(ds))
|
||||
|
||||
// Attempt to recommit |b| with |a| as parent.
|
||||
// Should be disallowed.
|
||||
@@ -455,15 +460,15 @@ func (suite *DatabaseSuite) TestCommitWithConcurrentChunkStoreUse() {
|
||||
func (suite *DatabaseSuite) TestDeleteWithConcurrentChunkStoreUse() {
|
||||
datasetID := "ds1"
|
||||
ds1, err := suite.db.GetDataset(context.Background(), datasetID)
|
||||
suite.NoError(err)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Setup:
|
||||
// ds1: |a| <- |b|
|
||||
ds1, _ = CommitValue(context.Background(), suite.db, ds1, types.String("a"))
|
||||
b := types.String("b")
|
||||
ds1, err = CommitValue(context.Background(), suite.db, ds1, b)
|
||||
suite.NoError(err)
|
||||
suite.True(mustHeadValue(ds1).Equals(b))
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().True(mustHeadValue(ds1).Equals(b))
|
||||
|
||||
// Craft DB that will allow me to move the backing ChunkStore while suite.db isn't looking
|
||||
interloper := suite.makeDb(suite.storage.NewViewWithDefaultFormat())
|
||||
@@ -473,28 +478,28 @@ func (suite *DatabaseSuite) TestDeleteWithConcurrentChunkStoreUse() {
|
||||
// ds1: |a| <- |b| <- |e|
|
||||
e := types.String("e")
|
||||
iDS, err := interloper.GetDataset(context.Background(), datasetID)
|
||||
suite.NoError(err)
|
||||
suite.Require().NoError(err)
|
||||
iDS, concErr := CommitValue(context.Background(), interloper, iDS, e)
|
||||
suite.NoError(concErr)
|
||||
suite.True(mustHeadValue(iDS).Equals(e))
|
||||
suite.Require().NoError(concErr)
|
||||
suite.Require().True(mustHeadValue(iDS).Equals(e))
|
||||
|
||||
// Attempt to delete ds1 via suite.db, which should fail due to the above
|
||||
_, err = suite.db.Delete(context.Background(), ds1)
|
||||
suite.Error(err)
|
||||
suite.Require().Error(err)
|
||||
|
||||
// Concurrent change, but to some other dataset. This shouldn't stop changes to ds1.
|
||||
// ds1: |a| <- |b| <- |e|
|
||||
// ds2: |stuff|
|
||||
stf := types.String("stuff")
|
||||
otherDS, err := suite.db.GetDataset(context.Background(), "other")
|
||||
suite.NoError(err)
|
||||
iDS, concErr = CommitValue(context.Background(), interloper, otherDS, stf)
|
||||
suite.NoError(concErr)
|
||||
suite.True(mustHeadValue(iDS).Equals(stf))
|
||||
suite.Require().NoError(err)
|
||||
iDS, concErr = CommitValue(context.Background(), suite.db, otherDS, stf)
|
||||
suite.Require().NoError(concErr)
|
||||
suite.Require().True(mustHeadValue(iDS).Equals(stf))
|
||||
|
||||
// Attempted concurrent delete, which should proceed without a problem
|
||||
ds1, err = suite.db.Delete(context.Background(), ds1)
|
||||
suite.NoError(err)
|
||||
suite.Require().NoError(err)
|
||||
present := ds1.HasHead()
|
||||
suite.False(present, "Dataset %s should not be present", datasetID)
|
||||
}
|
||||
@@ -559,7 +564,7 @@ func (suite *DatabaseSuite) TestFastForward() {
|
||||
|
||||
// This should succeed, because while |a| is not a direct parent of |c|, it is an ancestor.
|
||||
ds, err = suite.db.FastForward(context.Background(), ds, cCommitAddr)
|
||||
suite.NoError(err)
|
||||
suite.Require().NoError(err)
|
||||
suite.True(mustHeadValue(ds).Equals(c))
|
||||
}
|
||||
|
||||
@@ -636,11 +641,12 @@ func (suite *DatabaseSuite) TestDatabaseHeightOfCollections() {
|
||||
}
|
||||
|
||||
func (suite *DatabaseSuite) TestMetaOption() {
|
||||
ds, err := suite.db.GetDataset(context.Background(), "ds1")
|
||||
ctx := context.Background()
|
||||
ds, err := suite.db.GetDataset(ctx, "ds1")
|
||||
suite.NoError(err)
|
||||
|
||||
ds, err = suite.db.Commit(context.Background(), ds, types.String("a"), CommitOptions{Meta: &CommitMeta{Name: "arv"}})
|
||||
ds, err = suite.db.Commit(ctx, ds, types.String("a"), CommitOptions{Meta: &CommitMeta{Name: "arv"}})
|
||||
suite.NoError(err)
|
||||
c := mustHead(ds).(types.Struct)
|
||||
suite.Equal(types.String("arv"), mustGetValue(mustGetValue(c.MaybeGet("meta")).(types.Struct).MaybeGet("name")))
|
||||
meta, err := GetCommitMeta(ctx, mustHead(ds))
|
||||
suite.Equal("arv", meta.Name)
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ type dsHead interface {
|
||||
Addr() hash.Hash
|
||||
HeadTag() (*TagMeta, hash.Hash, error)
|
||||
HeadWorkingSet() (*WorkingSetHead, error)
|
||||
|
||||
value() types.Value
|
||||
}
|
||||
|
||||
type nomsHead struct {
|
||||
@@ -67,6 +69,10 @@ func (h nomsHead) Addr() hash.Hash {
|
||||
return h.addr
|
||||
}
|
||||
|
||||
func (h nomsHead) value() types.Value {
|
||||
return h.st
|
||||
}
|
||||
|
||||
type serialTagHead struct {
|
||||
msg *serial.Tag
|
||||
addr hash.Hash
|
||||
@@ -84,6 +90,10 @@ func (h serialTagHead) Addr() hash.Hash {
|
||||
return h.addr
|
||||
}
|
||||
|
||||
func (h serialTagHead) value() types.Value {
|
||||
return types.SerialMessage(h.msg.Table().Bytes)
|
||||
}
|
||||
|
||||
func (h serialTagHead) HeadTag() (*TagMeta, hash.Hash, error) {
|
||||
addr := hash.New(h.msg.CommitAddrBytes())
|
||||
meta := &TagMeta{
|
||||
@@ -117,6 +127,10 @@ func (h serialWorkingSetHead) Addr() hash.Hash {
|
||||
return h.addr
|
||||
}
|
||||
|
||||
func (h serialWorkingSetHead) value() types.Value {
|
||||
return types.SerialMessage(h.msg.Table().Bytes)
|
||||
}
|
||||
|
||||
func (h serialWorkingSetHead) HeadTag() (*TagMeta, hash.Hash, error) {
|
||||
return nil, hash.Hash{}, errors.New("HeadTag called on working set")
|
||||
}
|
||||
@@ -141,6 +155,35 @@ func (h serialWorkingSetHead) HeadWorkingSet() (*WorkingSetHead, error) {
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
type serialCommitHead struct {
|
||||
msg types.SerialMessage
|
||||
addr hash.Hash
|
||||
}
|
||||
|
||||
func newSerialCommitHead(sm types.SerialMessage, addr hash.Hash) serialCommitHead {
|
||||
return serialCommitHead{sm, addr}
|
||||
}
|
||||
|
||||
func (h serialCommitHead) TypeName() string {
|
||||
return commitName
|
||||
}
|
||||
|
||||
func (h serialCommitHead) Addr() hash.Hash {
|
||||
return h.addr
|
||||
}
|
||||
|
||||
func (h serialCommitHead) value() types.Value {
|
||||
return h.msg
|
||||
}
|
||||
|
||||
func (h serialCommitHead) HeadTag() (*TagMeta, hash.Hash, error) {
|
||||
return nil, hash.Hash{}, errors.New("HeadTag called on commit")
|
||||
}
|
||||
|
||||
func (h serialCommitHead) HeadWorkingSet() (*WorkingSetHead, error) {
|
||||
return nil, errors.New("HeadWorkingSet called on commit")
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@@ -162,6 +205,9 @@ func newHead(head types.Value, addr hash.Hash) (dsHead, error) {
|
||||
if serial.GetFileID(data) == serial.WorkingSetFileID {
|
||||
return newSerialWorkingSetHead(data, addr), nil
|
||||
}
|
||||
if serial.GetFileID(data) == serial.CommitFileID {
|
||||
return newSerialCommitHead(sm, addr), nil
|
||||
}
|
||||
}
|
||||
|
||||
matched, err := IsCommit(head)
|
||||
@@ -213,7 +259,12 @@ func (ds Dataset) MaybeHead() (types.Value, bool) {
|
||||
if ds.head == nil {
|
||||
return types.Struct{}, false
|
||||
}
|
||||
return ds.head.(nomsHead).st, true
|
||||
if nh, ok := ds.head.(nomsHead); ok {
|
||||
return nh.st, true
|
||||
} else if sch, ok := ds.head.(serialCommitHead); ok {
|
||||
return sch.msg, true
|
||||
}
|
||||
panic("unexpected ds.head type for MaybeHead call")
|
||||
}
|
||||
|
||||
// MaybeHeadRef returns the Ref of the current Head Commit of this Dataset,
|
||||
@@ -352,11 +403,11 @@ func (ds Dataset) HasHead() bool {
|
||||
// available. If not it returns nil and 'false'.
|
||||
func (ds Dataset) MaybeHeadValue() (types.Value, bool, error) {
|
||||
if c, ok := ds.MaybeHead(); ok {
|
||||
v, err := GetCommitValue(context.TODO(), c)
|
||||
v, err := GetCommitValue(context.TODO(), ds.db, c)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return v, true, nil
|
||||
return v, v != nil, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ func mustGetValue(v types.Value, found bool, err error) types.Value {
|
||||
return v
|
||||
}
|
||||
|
||||
func mustGetCommitValue(v types.Value) types.Value {
|
||||
r, err := GetCommitValue(context.Background(), v)
|
||||
func mustGetCommitValue(db *database, v types.Value) types.Value {
|
||||
r, err := GetCommitValue(context.Background(), db, v)
|
||||
d.PanicIfError(err)
|
||||
d.PanicIfFalse(r != nil)
|
||||
return r
|
||||
@@ -67,7 +67,7 @@ func TestExplicitBranchUsingDatasets(t *testing.T) {
|
||||
a := types.String("a")
|
||||
ds1, err = CommitValue(context.Background(), store, ds1, a)
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(ds1)).Equals(a))
|
||||
assert.True(mustGetCommitValue(ds1.db, mustHead(ds1)).Equals(a))
|
||||
|
||||
// ds1: |a|
|
||||
// \ds2
|
||||
@@ -75,31 +75,31 @@ func TestExplicitBranchUsingDatasets(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
ds2, err = store.Commit(context.Background(), ds2, mustHeadValue(ds1), CommitOptions{Parents: []hash.Hash{mustHeadAddr(ds1)}})
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(ds2)).Equals(a))
|
||||
assert.True(mustGetCommitValue(store, mustHead(ds2)).Equals(a))
|
||||
|
||||
// ds1: |a| <- |b|
|
||||
b := types.String("b")
|
||||
ds1, err = CommitValue(context.Background(), store, ds1, b)
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(ds1)).Equals(b))
|
||||
assert.True(mustGetCommitValue(store, mustHead(ds1)).Equals(b))
|
||||
|
||||
// ds1: |a| <- |b|
|
||||
// \ds2 <- |c|
|
||||
c := types.String("c")
|
||||
ds2, err = CommitValue(context.Background(), store, ds2, c)
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(ds2)).Equals(c))
|
||||
assert.True(mustGetCommitValue(store, mustHead(ds2)).Equals(c))
|
||||
|
||||
// ds1: |a| <- |b| <--|d|
|
||||
// \ds2 <- |c| <--/
|
||||
d := types.String("d")
|
||||
ds2, err = store.Commit(context.Background(), ds2, d, CommitOptions{Parents: []hash.Hash{mustHeadAddr(ds1), mustHeadAddr(ds2)}})
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(ds2)).Equals(d))
|
||||
assert.True(mustGetCommitValue(store, mustHead(ds2)).Equals(d))
|
||||
|
||||
ds1, err = store.Commit(context.Background(), ds1, d, CommitOptions{Parents: []hash.Hash{mustHeadAddr(ds1), mustHeadAddr(ds2)}})
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(ds1)).Equals(d))
|
||||
assert.True(mustGetCommitValue(store, mustHead(ds1)).Equals(d))
|
||||
}
|
||||
|
||||
func TestTwoClientsWithEmptyDataset(t *testing.T) {
|
||||
@@ -118,7 +118,7 @@ func TestTwoClientsWithEmptyDataset(t *testing.T) {
|
||||
a := types.String("a")
|
||||
dsx, err = CommitValue(context.Background(), store, dsx, a)
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(dsx)).Equals(a))
|
||||
assert.True(mustGetCommitValue(dsx.db, mustHead(dsx)).Equals(a))
|
||||
|
||||
// dsy: || -> |b|
|
||||
_, ok := dsy.MaybeHead()
|
||||
@@ -151,7 +151,7 @@ func TestTwoClientsWithNonEmptyDataset(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
ds1, err = CommitValue(context.Background(), store, ds1, a)
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(ds1)).Equals(a))
|
||||
assert.True(mustGetCommitValue(ds1.db, mustHead(ds1)).Equals(a))
|
||||
}
|
||||
|
||||
dsx, err := store.GetDataset(context.Background(), id1)
|
||||
@@ -160,14 +160,14 @@ func TestTwoClientsWithNonEmptyDataset(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
|
||||
// dsx: |a| -> |b|
|
||||
assert.True(mustGetCommitValue(mustHead(dsx)).Equals(a))
|
||||
assert.True(mustGetCommitValue(dsx.db, mustHead(dsx)).Equals(a))
|
||||
b := types.String("b")
|
||||
dsx, err = CommitValue(context.Background(), store, dsx, b)
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(dsx)).Equals(b))
|
||||
assert.True(mustGetCommitValue(dsx.db, mustHead(dsx)).Equals(b))
|
||||
|
||||
// dsy: |a| -> |c|
|
||||
assert.True(mustGetCommitValue(mustHead(dsy)).Equals(a))
|
||||
assert.True(mustGetCommitValue(dsy.db, mustHead(dsy)).Equals(a))
|
||||
c := types.String("c")
|
||||
_, err = CommitValue(context.Background(), store, dsy, c)
|
||||
assert.Error(err)
|
||||
@@ -177,7 +177,7 @@ func TestTwoClientsWithNonEmptyDataset(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
dsy, err = CommitValue(context.Background(), store, dsy, c)
|
||||
assert.NoError(err)
|
||||
assert.True(mustGetCommitValue(mustHead(dsy)).Equals(c))
|
||||
assert.True(mustGetCommitValue(dsy.db, mustHead(dsy)).Equals(c))
|
||||
}
|
||||
|
||||
func TestIdValidation(t *testing.T) {
|
||||
@@ -211,7 +211,7 @@ func TestHeadValueFunctions(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
assert.True(ds1.HasHead())
|
||||
|
||||
hv, err := GetCommitValue(context.Background(), mustHead(ds1))
|
||||
hv, err := GetCommitValue(context.Background(), ds1.db, mustHead(ds1))
|
||||
assert.NoError(err)
|
||||
assert.Equal(a, hv)
|
||||
assert.Equal(a, mustHeadValue(ds1))
|
||||
|
||||
@@ -181,7 +181,7 @@ func (suite *PullSuite) TestPullEverything() {
|
||||
|
||||
v := mustValue(suite.sinkVRW.ReadValue(context.Background(), sourceAddr)).(types.Struct)
|
||||
suite.NotNil(v)
|
||||
suite.True(l.Equals(mustGetCommitValue(v)))
|
||||
suite.True(l.Equals(mustGetCommitValue(suite.sinkVRW, v)))
|
||||
}
|
||||
|
||||
// Source: -6-> C3(L5) -1-> N
|
||||
@@ -228,7 +228,7 @@ func (suite *PullSuite) TestPullMultiGeneration() {
|
||||
v, err := suite.sinkVRW.ReadValue(context.Background(), sourceAddr)
|
||||
suite.NoError(err)
|
||||
suite.NotNil(v)
|
||||
suite.True(srcL.Equals(mustGetCommitValue(v)))
|
||||
suite.True(srcL.Equals(mustGetCommitValue(suite.sinkVRW, v)))
|
||||
}
|
||||
|
||||
// Source: -6-> C2(L5) -1-> N
|
||||
@@ -281,7 +281,7 @@ func (suite *PullSuite) TestPullDivergentHistory() {
|
||||
v, err := suite.sinkVRW.ReadValue(context.Background(), sourceAddr)
|
||||
suite.NoError(err)
|
||||
suite.NotNil(v)
|
||||
suite.True(srcL.Equals(mustGetCommitValue(v)))
|
||||
suite.True(srcL.Equals(mustGetCommitValue(suite.sinkVRW, v)))
|
||||
}
|
||||
|
||||
// Source: -6-> C2(L4) -1-> N
|
||||
@@ -333,7 +333,7 @@ func (suite *PullSuite) TestPullUpdates() {
|
||||
v, err := suite.sinkVRW.ReadValue(context.Background(), sourceAddr)
|
||||
suite.NoError(err)
|
||||
suite.NotNil(v)
|
||||
suite.True(srcL.Equals(mustGetCommitValue(v)))
|
||||
suite.True(srcL.Equals(mustGetCommitValue(suite.sinkVRW, v)))
|
||||
}
|
||||
|
||||
func (suite *PullSuite) commitToSource(v types.Value, p []hash.Hash) hash.Hash {
|
||||
@@ -590,8 +590,8 @@ func mustValue(val types.Value, err error) types.Value {
|
||||
return val
|
||||
}
|
||||
|
||||
func mustGetCommitValue(c types.Value) types.Value {
|
||||
v, err := datas.GetCommitValue(context.Background(), c)
|
||||
func mustGetCommitValue(vr types.ValueReader, c types.Value) types.Value {
|
||||
v, err := datas.GetCommitValue(context.Background(), vr, c)
|
||||
d.PanicIfError(err)
|
||||
d.PanicIfFalse(v != nil)
|
||||
return v
|
||||
|
||||
+13
-8
@@ -16,6 +16,7 @@ package datas
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
|
||||
@@ -56,6 +57,13 @@ func newTag(ctx context.Context, db *database, commitAddr hash.Hash, meta *TagMe
|
||||
if err != nil {
|
||||
return hash.Hash{}, types.Ref{}, err
|
||||
}
|
||||
iscommit, err := IsCommit(commitSt)
|
||||
if err != nil {
|
||||
return hash.Hash{}, types.Ref{}, err
|
||||
}
|
||||
if !iscommit {
|
||||
return hash.Hash{}, types.Ref{}, errors.New("newTag: commitAddr does not point to a commit.")
|
||||
}
|
||||
commitRef, err := types.NewRef(commitSt, db.Format())
|
||||
if err != nil {
|
||||
return hash.Hash{}, types.Ref{}, err
|
||||
@@ -76,11 +84,6 @@ func newTag(ctx context.Context, db *database, commitAddr hash.Hash, meta *TagMe
|
||||
return hash.Hash{}, types.Ref{}, err
|
||||
}
|
||||
|
||||
err = db.validateTag(ctx, tagSt)
|
||||
if err != nil {
|
||||
return hash.Hash{}, types.Ref{}, err
|
||||
}
|
||||
|
||||
tagRef, err := db.WriteValue(ctx, tagSt)
|
||||
if err != nil {
|
||||
return hash.Hash{}, types.Ref{}, err
|
||||
@@ -131,11 +134,13 @@ func tag_flatbuffer(commitAddr hash.Hash, meta *TagMeta) []byte {
|
||||
}
|
||||
|
||||
func IsTag(v types.Value) (bool, error) {
|
||||
if s, ok := v.(types.Struct); !ok {
|
||||
return false, nil
|
||||
} else {
|
||||
if s, ok := v.(types.Struct); ok {
|
||||
return types.IsValueSubtypeOf(s.Format(), v, valueTagType)
|
||||
} else if sm, ok := v.(types.SerialMessage); ok {
|
||||
data := []byte(sm)
|
||||
return serial.GetFileID(data) == serial.TagFileID, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func makeTagStructType(metaType, refType *types.Type) (*types.Type, error) {
|
||||
|
||||
@@ -58,10 +58,8 @@ func NewTagMetaWithUserTS(name, email, desc string, userTS time.Time) *TagMeta {
|
||||
e := strings.TrimSpace(email)
|
||||
d := strings.TrimSpace(desc)
|
||||
|
||||
ns := uint64(TagNowFunc().UnixNano())
|
||||
ms := ns / uMilliToNano
|
||||
|
||||
userMS := userTS.UnixNano() / milliToNano
|
||||
ms := uint64(TagNowFunc().UnixMilli())
|
||||
userMS := userTS.UnixMilli()
|
||||
|
||||
return &TagMeta{n, e, ms, d, userMS}
|
||||
}
|
||||
@@ -123,9 +121,7 @@ func (tm *TagMeta) toNomsStruct(nbf *types.NomsBinFormat) (types.Struct, error)
|
||||
|
||||
// Time returns the time at which the tag occurred
|
||||
func (tm *TagMeta) Time() time.Time {
|
||||
seconds := int64(tm.Timestamp) / secToMilli
|
||||
nanos := (int64(tm.Timestamp) % secToMilli) * milliToNano
|
||||
return time.Unix(seconds, nanos)
|
||||
return time.UnixMilli(int64(tm.Timestamp))
|
||||
}
|
||||
|
||||
// FormatTS takes the internal timestamp and turns it into a human readable string in the time.RubyDate format
|
||||
|
||||
@@ -195,13 +195,15 @@ func NewMergeState(_ context.Context, preMergeWorking types.Ref, commit types.Va
|
||||
}
|
||||
|
||||
func IsWorkingSet(v types.Value) (bool, error) {
|
||||
if s, ok := v.(types.Struct); !ok {
|
||||
return false, nil
|
||||
} else {
|
||||
if s, ok := v.(types.Struct); ok {
|
||||
// We're being more lenient here than in other checks, to make it more likely we can release changes to the
|
||||
// working set data description in a backwards compatible way.
|
||||
// types.IsValueSubtypeOf is very strict about the type description.
|
||||
return s.Name() == WorkingSetName, nil
|
||||
} else if sm, ok := v.(types.SerialMessage); ok {
|
||||
return serial.GetFileID([]byte(sm)) == serial.WorkingSetFileID, nil
|
||||
} else {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
)
|
||||
|
||||
// Summary prints a summary of the diff between two values to stdout.
|
||||
func Summary(ctx context.Context, value1, value2 types.Value) {
|
||||
func Summary(ctx context.Context, vr1 types.ValueReader, vr2 types.ValueReader, value1, value2 types.Value) {
|
||||
if is1, err := datas.IsCommit(value1); err != nil {
|
||||
panic(err)
|
||||
} else if is1 {
|
||||
@@ -46,10 +46,10 @@ func Summary(ctx context.Context, value1, value2 types.Value) {
|
||||
fmt.Println("Comparing commit values")
|
||||
|
||||
var err error
|
||||
value1, err = datas.GetCommitValue(ctx, value1)
|
||||
value1, err = datas.GetCommitValue(ctx, vr1, value1)
|
||||
d.PanicIfError(err)
|
||||
|
||||
value2, err = datas.GetCommitValue(ctx, value2)
|
||||
value2, err = datas.GetCommitValue(ctx, vr2, value2)
|
||||
d.PanicIfError(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,6 +446,8 @@ func TestPinDatasetSpec(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
defer unpinned.Close()
|
||||
|
||||
vrw := unpinned.GetVRW(context.Background())
|
||||
|
||||
db := unpinned.GetDatabase(context.Background())
|
||||
ds, err := db.GetDataset(context.Background(), "foo")
|
||||
assert.NoError(err)
|
||||
@@ -462,7 +464,7 @@ func TestPinDatasetSpec(t *testing.T) {
|
||||
assert.True(ok)
|
||||
|
||||
commitValue := func(val types.Value) types.Value {
|
||||
v, err := datas.GetCommitValue(context.Background(), val)
|
||||
v, err := datas.GetCommitValue(context.Background(), vrw, val)
|
||||
d.PanicIfError(err)
|
||||
d.PanicIfFalse(v != nil)
|
||||
return v
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dolthub/dolt/go/gen/fb/serial"
|
||||
"github.com/dolthub/dolt/go/store/d"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
)
|
||||
@@ -233,6 +234,13 @@ func (fp FieldPath) Resolve(ctx context.Context, v Value, vr ValueReader) (Value
|
||||
} else if ok {
|
||||
return sv, nil
|
||||
}
|
||||
case SerialMessage:
|
||||
data := []byte(v)
|
||||
if serial.GetFileID(data) == serial.CommitFileID && fp.Name == "value" {
|
||||
msg := serial.GetRootAsCommit(data, 0)
|
||||
addr := hash.New(msg.RootBytes())
|
||||
return vr.ReadValue(ctx, addr)
|
||||
}
|
||||
case *Type:
|
||||
if desc, ok := v.Desc.(StructDesc); ok {
|
||||
if df, _ := desc.Field(fp.Name); df != nil {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/dolthub/dolt/go/gen/fb/serial"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
@@ -51,6 +52,20 @@ func (sm SerialMessage) Hash(nbf *NomsBinFormat) (hash.Hash, error) {
|
||||
}
|
||||
|
||||
func (sm SerialMessage) HumanReadableString() string {
|
||||
if serial.GetFileID([]byte(sm)) == serial.StoreRootFileID {
|
||||
msg := serial.GetRootAsStoreRoot([]byte(sm), 0)
|
||||
ret := &strings.Builder{}
|
||||
refs := msg.Refs(nil)
|
||||
fmt.Fprintf(ret, "{\n")
|
||||
hashes := refs.RefArrayBytes()
|
||||
for i := 0; i < refs.NamesLength(); i++ {
|
||||
name := refs.Names(i)
|
||||
addr := hash.New(hashes[:20])
|
||||
fmt.Fprintf(ret, " %s: %s\n", name, addr.String())
|
||||
}
|
||||
fmt.Fprintf(ret, "}")
|
||||
return ret.String()
|
||||
}
|
||||
return "SerialMessage"
|
||||
}
|
||||
|
||||
@@ -65,8 +80,9 @@ func (sm SerialMessage) WalkValues(ctx context.Context, cb ValueCallback) error
|
||||
return errors.New("unsupported WalkValues on SerialMessage. Use types.WalkValues.")
|
||||
}
|
||||
|
||||
// Refs in SerialMessage do not have height.
|
||||
const serialMessageRefHeight = 5
|
||||
// Refs in SerialMessage do not have height. This should be taller than
|
||||
// any true Ref height we expect to see in a RootValue.
|
||||
const SerialMessageRefHeight = 1024
|
||||
|
||||
func (sm SerialMessage) WalkRefs(nbf *NomsBinFormat, cb RefCallback) error {
|
||||
switch serial.GetFileID([]byte(sm)) {
|
||||
@@ -77,7 +93,7 @@ func (sm SerialMessage) WalkRefs(nbf *NomsBinFormat, cb RefCallback) error {
|
||||
for i := 0; i < rm.NamesLength(); i++ {
|
||||
off := i * 20
|
||||
addr := hash.New(refs[off : off+20])
|
||||
r, err := constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], 5)
|
||||
r, err := constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], SerialMessageRefHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -88,7 +104,7 @@ func (sm SerialMessage) WalkRefs(nbf *NomsBinFormat, cb RefCallback) error {
|
||||
case serial.TagFileID:
|
||||
msg := serial.GetRootAsTag([]byte(sm), 0)
|
||||
addr := hash.New(msg.CommitAddrBytes())
|
||||
r, err := constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], 5)
|
||||
r, err := constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], SerialMessageRefHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -96,7 +112,7 @@ func (sm SerialMessage) WalkRefs(nbf *NomsBinFormat, cb RefCallback) error {
|
||||
case serial.WorkingSetFileID:
|
||||
msg := serial.GetRootAsWorkingSet([]byte(sm), 0)
|
||||
addr := hash.New(msg.WorkingRootAddrBytes())
|
||||
r, err := constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], 5)
|
||||
r, err := constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], SerialMessageRefHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -105,7 +121,7 @@ func (sm SerialMessage) WalkRefs(nbf *NomsBinFormat, cb RefCallback) error {
|
||||
}
|
||||
if msg.StagedRootAddrLength() != 0 {
|
||||
addr = hash.New(msg.StagedRootAddrBytes())
|
||||
r, err = constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], 5)
|
||||
r, err = constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], SerialMessageRefHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -115,7 +131,7 @@ func (sm SerialMessage) WalkRefs(nbf *NomsBinFormat, cb RefCallback) error {
|
||||
}
|
||||
if msg.MergeStateAddrLength() != 0 {
|
||||
addr = hash.New(msg.MergeStateAddrBytes())
|
||||
r, err = constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], 5)
|
||||
r, err = constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], SerialMessageRefHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -123,10 +139,46 @@ func (sm SerialMessage) WalkRefs(nbf *NomsBinFormat, cb RefCallback) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case serial.CommitFileID:
|
||||
parents, err := SerialCommitParentRefs(nbf, sm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, r := range parents {
|
||||
if err = cb(r); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
msg := serial.GetRootAsCommit([]byte(sm), 0)
|
||||
addr := hash.New(msg.RootBytes())
|
||||
r, err := constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], SerialMessageRefHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = cb(r); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: cb for parent closure.
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SerialCommitParentRefs(nbf *NomsBinFormat, sm SerialMessage) ([]Ref, error) {
|
||||
msg := serial.GetRootAsCommit([]byte(sm), 0)
|
||||
ret := make([]Ref, msg.ParentHeightsLength())
|
||||
addrs := msg.ParentAddrsBytes()
|
||||
for i := 0; i < msg.ParentHeightsLength(); i++ {
|
||||
addr := hash.New(addrs[:20])
|
||||
addrs = addrs[20:]
|
||||
r, err := constructRef(nbf, addr, PrimitiveTypeMap[ValueKind], msg.ParentHeights(i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret[i] = r
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (sm SerialMessage) readFrom(nbf *NomsBinFormat, b *binaryNomsReader) (Value, error) {
|
||||
bytes := b.ReadInlineBlob()
|
||||
return SerialMessage(bytes), nil
|
||||
@@ -155,3 +207,7 @@ func (sm SerialMessage) writeTo(w nomsWriter, nbf *NomsBinFormat) error {
|
||||
w.writeRaw(sm)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sm SerialMessage) valueReadWriter() ValueReadWriter {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ func ReadFromReader(ctx context.Context, rd io.Reader) ([]types.Value, error) {
|
||||
return nil, ErrCorruptNVF
|
||||
}
|
||||
|
||||
rootVal, err := datas.GetCommitValue(ctx, commitSt)
|
||||
rootVal, err := datas.GetCommitValue(ctx, vrw, commitSt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user