github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/env/memory.go (about)

     1  // Copyright 2021 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package env
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"os"
    21  	"time"
    22  
    23  	"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
    24  	"github.com/dolthub/dolt/go/libraries/doltcore/ref"
    25  	"github.com/dolthub/dolt/go/libraries/utils/concurrentmap"
    26  	"github.com/dolthub/dolt/go/libraries/utils/config"
    27  	"github.com/dolthub/dolt/go/store/chunks"
    28  	"github.com/dolthub/dolt/go/store/datas"
    29  	"github.com/dolthub/dolt/go/store/hash"
    30  )
    31  
    32  func NewMemoryDbData(ctx context.Context, cfg config.ReadableConfig) (DbData, error) {
    33  	branchName := GetDefaultInitBranch(cfg)
    34  
    35  	ddb, err := NewMemoryDoltDB(ctx, branchName)
    36  	if err != nil {
    37  		return DbData{}, err
    38  	}
    39  
    40  	rs, err := NewMemoryRepoState(ctx, ddb, branchName)
    41  	if err != nil {
    42  		return DbData{}, err
    43  	}
    44  
    45  	return DbData{
    46  		Ddb: ddb,
    47  		Rsw: rs,
    48  		Rsr: rs,
    49  	}, nil
    50  }
    51  
    52  func NewMemoryDoltDB(ctx context.Context, initBranch string) (*doltdb.DoltDB, error) {
    53  	ts := &chunks.TestStorage{}
    54  	cs := ts.NewViewWithDefaultFormat()
    55  	ddb := doltdb.DoltDBFromCS(cs)
    56  
    57  	m := "memory"
    58  	branchRef := ref.NewBranchRef(initBranch)
    59  	err := ddb.WriteEmptyRepoWithCommitTimeAndDefaultBranch(ctx, m, m, datas.CommitterDate(), branchRef)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	return ddb, nil
    65  }
    66  
    67  func NewMemoryRepoState(ctx context.Context, ddb *doltdb.DoltDB, initBranch string) (MemoryRepoState, error) {
    68  	head := ref.NewBranchRef(initBranch)
    69  	rs := MemoryRepoState{
    70  		DoltDB: ddb,
    71  		Head:   head,
    72  	}
    73  
    74  	commit, err := ddb.ResolveCommitRef(ctx, head)
    75  	if err != nil {
    76  		return MemoryRepoState{}, err
    77  	}
    78  
    79  	root, err := commit.GetRootValue(ctx)
    80  	if err != nil {
    81  		return MemoryRepoState{}, err
    82  	}
    83  
    84  	err = rs.UpdateWorkingRoot(ctx, root)
    85  	if err != nil {
    86  		return MemoryRepoState{}, err
    87  	}
    88  
    89  	err = rs.UpdateStagedRoot(ctx, root)
    90  	if err != nil {
    91  		return MemoryRepoState{}, err
    92  	}
    93  
    94  	return rs, nil
    95  }
    96  
    97  type MemoryRepoState struct {
    98  	DoltDB *doltdb.DoltDB
    99  	Head   ref.DoltRef
   100  }
   101  
   102  var _ RepoStateReader = MemoryRepoState{}
   103  var _ RepoStateWriter = MemoryRepoState{}
   104  
   105  func (m MemoryRepoState) CWBHeadRef() (ref.DoltRef, error) {
   106  	return m.Head, nil
   107  }
   108  
   109  func (m MemoryRepoState) CWBHeadSpec() (*doltdb.CommitSpec, error) {
   110  	headRef, err := m.CWBHeadRef()
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  	spec, err := doltdb.NewCommitSpec(headRef.GetPath())
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	return spec, nil
   119  }
   120  
   121  func (m MemoryRepoState) UpdateStagedRoot(ctx context.Context, newRoot doltdb.RootValue) error {
   122  	var h hash.Hash
   123  	var wsRef ref.WorkingSetRef
   124  
   125  	ws, err := m.WorkingSet(ctx)
   126  	if err == doltdb.ErrWorkingSetNotFound {
   127  		// first time updating root
   128  		headRef, err := m.CWBHeadRef()
   129  		if err != nil {
   130  			return err
   131  		}
   132  		wsRef, err = ref.WorkingSetRefForHead(headRef)
   133  		if err != nil {
   134  			return err
   135  		}
   136  		ws = doltdb.EmptyWorkingSet(wsRef).WithWorkingRoot(newRoot).WithStagedRoot(newRoot)
   137  	} else if err != nil {
   138  		return err
   139  	} else {
   140  		h, err = ws.HashOf()
   141  		if err != nil {
   142  			return err
   143  		}
   144  
   145  		wsRef = ws.Ref()
   146  	}
   147  
   148  	return m.DoltDB.UpdateWorkingSet(ctx, wsRef, ws.WithStagedRoot(newRoot), h, m.workingSetMeta(), nil)
   149  }
   150  
   151  func (m MemoryRepoState) UpdateWorkingRoot(ctx context.Context, newRoot doltdb.RootValue) error {
   152  	var h hash.Hash
   153  	var wsRef ref.WorkingSetRef
   154  
   155  	ws, err := m.WorkingSet(ctx)
   156  	if err == doltdb.ErrWorkingSetNotFound {
   157  		// first time updating root
   158  		headRef, err := m.CWBHeadRef()
   159  		if err != nil {
   160  			return err
   161  		}
   162  		wsRef, err = ref.WorkingSetRefForHead(headRef)
   163  		if err != nil {
   164  			return err
   165  		}
   166  		ws = doltdb.EmptyWorkingSet(wsRef).WithWorkingRoot(newRoot).WithStagedRoot(newRoot)
   167  	} else if err != nil {
   168  		return err
   169  	} else {
   170  		h, err = ws.HashOf()
   171  		if err != nil {
   172  			return err
   173  		}
   174  
   175  		wsRef = ws.Ref()
   176  	}
   177  
   178  	return m.DoltDB.UpdateWorkingSet(ctx, wsRef, ws.WithWorkingRoot(newRoot), h, m.workingSetMeta(), nil)
   179  }
   180  
   181  func (m MemoryRepoState) WorkingSet(ctx context.Context) (*doltdb.WorkingSet, error) {
   182  	headRef, err := m.CWBHeadRef()
   183  	if err != nil {
   184  		return nil, err
   185  	}
   186  	workingSetRef, err := ref.WorkingSetRefForHead(headRef)
   187  	if err != nil {
   188  		return nil, err
   189  	}
   190  
   191  	workingSet, err := m.DoltDB.ResolveWorkingSet(ctx, workingSetRef)
   192  	if err != nil {
   193  		return nil, err
   194  	}
   195  
   196  	return workingSet, nil
   197  }
   198  
   199  func (m MemoryRepoState) workingSetMeta() *datas.WorkingSetMeta {
   200  	return &datas.WorkingSetMeta{
   201  		Timestamp:   uint64(time.Now().Unix()),
   202  		Description: "updated from dolt environment",
   203  	}
   204  }
   205  
   206  func (m MemoryRepoState) SetCWBHeadRef(_ context.Context, r ref.MarshalableRef) (err error) {
   207  	m.Head = r.Ref
   208  	return
   209  }
   210  
   211  func (m MemoryRepoState) GetRemotes() (*concurrentmap.Map[string, Remote], error) {
   212  	return concurrentmap.New[string, Remote](), nil
   213  }
   214  
   215  func (m MemoryRepoState) AddRemote(r Remote) error {
   216  	return fmt.Errorf("cannot insert a remote in a memory database")
   217  }
   218  
   219  func (m MemoryRepoState) GetBranches() (*concurrentmap.Map[string, BranchConfig], error) {
   220  	return concurrentmap.New[string, BranchConfig](), nil
   221  }
   222  
   223  func (m MemoryRepoState) UpdateBranch(name string, new BranchConfig) error {
   224  	return nil
   225  }
   226  
   227  func (m MemoryRepoState) RemoveRemote(ctx context.Context, name string) error {
   228  	return fmt.Errorf("cannot delete a remote from a memory database")
   229  }
   230  
   231  func (m MemoryRepoState) TempTableFilesDir() (string, error) {
   232  	return os.TempDir(), nil
   233  }
   234  
   235  func (m MemoryRepoState) GetBackups() (*concurrentmap.Map[string, Remote], error) {
   236  	panic("cannot get backups on in memory database")
   237  }
   238  
   239  func (m MemoryRepoState) AddBackup(r Remote) error {
   240  	panic("cannot add backup to in memory database")
   241  }
   242  
   243  func (m MemoryRepoState) RemoveBackup(ctx context.Context, name string) error {
   244  	panic("cannot remove backup from in memory database")
   245  }