Rename DataStore to Database (#1448)

This commit is contained in:
Erik Arvidsson
2016-05-06 17:37:19 -07:00
parent 58f5108f0b
commit 014e330315
60 changed files with 561 additions and 561 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ type Factory interface {
Shutter()
}
// RootTracker allows querying and management of the root of an entire tree of references. The "root" is the single mutable variable in a ChunkStore. It can store any ref, but it is typically used by higher layers (such as DataStore) to store a ref to a value that represents the current state and entire history of a datastore.
// RootTracker allows querying and management of the root of an entire tree of references. The "root" is the single mutable variable in a ChunkStore. It can store any ref, but it is typically used by higher layers (such as Database) to store a ref to a value that represents the current state and entire history of a database.
type RootTracker interface {
Root() ref.Ref
UpdateRoot(current, last ref.Ref) bool
+1 -1
View File
@@ -19,7 +19,7 @@ func main() {
flag.PrintDefaults()
}
flags.RegisterDataStoreFlags()
flags.RegisterDatabaseFlags()
flag.Parse()
if flag.NArg() != 1 {
+1 -1
View File
@@ -21,7 +21,7 @@ var (
)
func main() {
flags.RegisterDataStoreFlags()
flags.RegisterDatabaseFlags()
cpuCount := runtime.NumCPU()
runtime.GOMAXPROCS(cpuCount)
+1 -1
View File
@@ -37,7 +37,7 @@ func (s *testSuite) TestCSVExporter() {
// Setup data store
cs := chunks.NewLevelDBStore(s.LdbDir, "", 1, false)
ds := dataset.NewDataset(datas.NewDataStore(cs), setName)
ds := dataset.NewDataset(datas.NewDatabase(cs), setName)
// Build Struct fields based on header
f := make(types.TypeMap, len(header))
+1 -1
View File
@@ -26,7 +26,7 @@ var (
)
func main() {
flags.RegisterDataStoreFlags()
flags.RegisterDatabaseFlags()
cpuCount := runtime.NumCPU()
runtime.GOMAXPROCS(cpuCount)
+3 -3
View File
@@ -44,7 +44,7 @@ func (s *testSuite) TestCSVImporter() {
s.Equal("", out)
cs := chunks.NewLevelDBStore(s.LdbDir, "", 1, false)
ds := dataset.NewDataset(datas.NewDataStore(cs), setName)
ds := dataset.NewDataset(datas.NewDatabase(cs), setName)
defer ds.Store().Close()
defer os.RemoveAll(s.LdbDir)
@@ -106,7 +106,7 @@ func (s *testSuite) TestCSVImporterWithPipe() {
s.Equal("", out)
cs := chunks.NewLevelDBStore(s.LdbDir, "", 1, false)
ds := dataset.NewDataset(datas.NewDataStore(cs), setName)
ds := dataset.NewDataset(datas.NewDatabase(cs), setName)
defer ds.Store().Close()
defer os.RemoveAll(s.LdbDir)
@@ -138,7 +138,7 @@ func (s *testSuite) TestCSVImporterWithExternalHeader() {
s.Equal("", out)
cs := chunks.NewLevelDBStore(s.LdbDir, "", 1, false)
ds := dataset.NewDataset(datas.NewDataStore(cs), setName)
ds := dataset.NewDataset(datas.NewDatabase(cs), setName)
defer ds.Store().Close()
defer os.RemoveAll(s.LdbDir)
+3 -3
View File
@@ -13,7 +13,7 @@ import (
func TestRead(t *testing.T) {
assert := assert.New(t)
ds := datas.NewDataStore(chunks.NewMemoryStore())
ds := datas.NewDatabase(chunks.NewMemoryStore())
dataString := `a,1,true
b,2,false
@@ -47,7 +47,7 @@ b,2,false
func testTrailingHelper(t *testing.T, dataString string) {
assert := assert.New(t)
ds := datas.NewDataStore(chunks.NewMemoryStore())
ds := datas.NewDatabase(chunks.NewMemoryStore())
r := NewCSVReader(bytes.NewBufferString(dataString), ',')
@@ -92,7 +92,7 @@ g,h,i,j
func TestReadParseError(t *testing.T) {
assert := assert.New(t)
ds := datas.NewDataStore(chunks.NewMemoryStore())
ds := datas.NewDatabase(chunks.NewMemoryStore())
dataString := `a,"b`
r := NewCSVReader(bytes.NewBufferString(dataString), ',')
+22 -22
View File
@@ -17,44 +17,44 @@ var (
pathRegex = regexp.MustCompile("^(.+):(.+)$")
)
type DatastoreSpec struct {
type DatabaseSpec struct {
Protocol string
Path string
}
type DatasetSpec struct {
StoreSpec DatastoreSpec
StoreSpec DatabaseSpec
DatasetName string
}
type RefSpec struct {
StoreSpec DatastoreSpec
StoreSpec DatabaseSpec
Ref ref.Ref
}
type PathSpec interface {
Value() (datas.DataStore, types.Value, error)
Value() (datas.Database, types.Value, error)
}
func ParseDatastoreSpec(spec string) (DatastoreSpec, error) {
func ParseDatabaseSpec(spec string) (DatabaseSpec, error) {
res := storeRegex.FindStringSubmatch(spec)
if len(res) != 3 {
return DatastoreSpec{}, fmt.Errorf("Invalid datastore spec: %s", spec)
return DatabaseSpec{}, fmt.Errorf("Invalid database spec: %s", spec)
}
protocol := res[1]
switch protocol {
case "http", "https", "ldb":
if len(res[2]) == 0 {
return DatastoreSpec{}, fmt.Errorf("Invalid datastore spec: %s", spec)
return DatabaseSpec{}, fmt.Errorf("Invalid database spec: %s", spec)
}
return DatastoreSpec{Protocol: protocol, Path: strings.TrimRight(res[2][1:], "/")}, nil
return DatabaseSpec{Protocol: protocol, Path: strings.TrimRight(res[2][1:], "/")}, nil
case "mem":
if len(res[2]) > 0 {
return DatastoreSpec{}, fmt.Errorf("Invalid datastore spec: %s", spec)
return DatabaseSpec{}, fmt.Errorf("Invalid database spec: %s", spec)
}
return DatastoreSpec{Protocol: protocol, Path: ""}, nil
return DatabaseSpec{Protocol: protocol, Path: ""}, nil
}
return DatastoreSpec{}, fmt.Errorf("Invalid datastore spec: %s", spec)
return DatabaseSpec{}, fmt.Errorf("Invalid database spec: %s", spec)
}
func ParseDatasetSpec(spec string) (DatasetSpec, error) {
@@ -62,7 +62,7 @@ func ParseDatasetSpec(spec string) (DatasetSpec, error) {
if len(res) != 3 {
return DatasetSpec{}, fmt.Errorf("Invalid dataset spec: %s", spec)
}
storeSpec, err := ParseDatastoreSpec(res[1])
storeSpec, err := ParseDatabaseSpec(res[1])
if err != nil {
return DatasetSpec{}, err
}
@@ -95,21 +95,21 @@ func ParsePathSpec(spec string) (PathSpec, error) {
}
func (spec DatastoreSpec) Datastore() (ds datas.DataStore, err error) {
func (spec DatabaseSpec) Database() (ds datas.Database, err error) {
switch spec.Protocol {
case "http":
ds = datas.NewRemoteDataStore(spec.Protocol+":"+spec.Path, "")
ds = datas.NewRemoteDatabase(spec.Protocol+":"+spec.Path, "")
case "ldb":
ds = datas.NewDataStore(chunks.NewLevelDBStoreUseFlags(spec.Path, ""))
ds = datas.NewDatabase(chunks.NewLevelDBStoreUseFlags(spec.Path, ""))
case "mem":
ds = datas.NewDataStore(chunks.NewMemoryStore())
ds = datas.NewDatabase(chunks.NewMemoryStore())
default:
err = fmt.Errorf("Invalid path prototocol: %s", spec.Protocol)
}
return
}
func (spec DatastoreSpec) ChunkStore() (cs chunks.ChunkStore, err error) {
func (spec DatabaseSpec) ChunkStore() (cs chunks.ChunkStore, err error) {
switch spec.Protocol {
case "ldb":
cs = chunks.NewLevelDBStoreUseFlags(spec.Path, "")
@@ -123,7 +123,7 @@ func (spec DatastoreSpec) ChunkStore() (cs chunks.ChunkStore, err error) {
}
func (spec DatasetSpec) Dataset() (dataset.Dataset, error) {
store, err := spec.StoreSpec.Datastore()
store, err := spec.StoreSpec.Database()
if err != nil {
return dataset.Dataset{}, err
}
@@ -131,7 +131,7 @@ func (spec DatasetSpec) Dataset() (dataset.Dataset, error) {
return dataset.NewDataset(store, spec.DatasetName), nil
}
func (spec DatasetSpec) Value() (datas.DataStore, types.Value, error) {
func (spec DatasetSpec) Value() (datas.Database, types.Value, error) {
dataset, err := spec.Dataset()
if err != nil {
return nil, nil, err
@@ -145,14 +145,14 @@ func (spec DatasetSpec) Value() (datas.DataStore, types.Value, error) {
return dataset.Store(), commit, nil
}
func (spec RefSpec) Value() (datas.DataStore, types.Value, error) {
store, err := spec.StoreSpec.Datastore()
func (spec RefSpec) Value() (datas.Database, types.Value, error) {
store, err := spec.StoreSpec.Database()
if err != nil {
return nil, nil, err
}
return store, store.ReadValue(spec.Ref), nil
}
func RegisterDataStoreFlags() {
func RegisterDatabaseFlags() {
chunks.RegisterLevelDBFlags()
}
+54 -54
View File
@@ -18,14 +18,14 @@ import (
)
// TODO: implement this with mock httpService
func disabledTestHTTPDatastore(t *testing.T) {
func disabledTestHTTPDatabase(t *testing.T) {
assert := assert.New(t)
const port = 8017
const testString = "A String for testing"
const dsetId = "testds"
spec := fmt.Sprintf("http://localhost:%d/", port)
server := datas.NewRemoteDataStoreServer(chunks.NewTestStore(), port)
server := datas.NewRemoteDatabaseServer(chunks.NewTestStore(), port)
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
@@ -34,18 +34,18 @@ func disabledTestHTTPDatastore(t *testing.T) {
}()
time.Sleep(time.Second)
sp1, err := ParseDatastoreSpec(spec)
sp1, err := ParseDatabaseSpec(spec)
assert.NoError(err)
store1, err := sp1.Datastore()
store1, err := sp1.Database()
assert.NoError(err)
r1 := store1.WriteValue(types.NewString(testString))
store1, err = store1.Commit(dsetId, datas.NewCommit().Set(datas.ValueField, r1))
assert.NoError(err)
store1.Close()
sp2, err := ParseDatastoreSpec(spec)
sp2, err := ParseDatabaseSpec(spec)
assert.NoError(err)
store2, err := sp2.Datastore()
store2, err := sp2.Database()
assert.NoError(err)
assert.Equal(types.NewString(testString), store2.ReadValue(r1.TargetRef()))
@@ -53,7 +53,7 @@ func disabledTestHTTPDatastore(t *testing.T) {
wg.Wait()
}
func TestLDBDatastore(t *testing.T) {
func TestLDBDatabase(t *testing.T) {
assert := assert.New(t)
d1 := os.TempDir()
@@ -63,29 +63,29 @@ func TestLDBDatastore(t *testing.T) {
spec := fmt.Sprintf("ldb:%s", path.Join(dir, "store"))
cs := chunks.NewLevelDBStoreUseFlags(ldbDir, "")
ds := datas.NewDataStore(cs)
ds := datas.NewDatabase(cs)
s1 := types.NewString("A String")
s1Ref := ds.WriteValue(s1)
ds.Commit("testDs", datas.NewCommit().Set(datas.ValueField, s1Ref))
ds.Close()
sp, errRead := ParseDatastoreSpec(spec)
sp, errRead := ParseDatabaseSpec(spec)
assert.NoError(errRead)
store, err := sp.Datastore()
store, err := sp.Database()
assert.NoError(err)
assert.Equal(s1.String(), store.ReadValue(s1.Ref()).(types.String).String())
store.Close()
os.Remove(dir)
}
func TestMemDatastore(t *testing.T) {
func TestMemDatabase(t *testing.T) {
assert := assert.New(t)
spec := "mem"
sp, err := ParseDatastoreSpec(spec)
sp, err := ParseDatabaseSpec(spec)
assert.NoError(err)
store, err := sp.Datastore()
store, err := sp.Database()
assert.NoError(err)
r := store.WriteValue(types.Bool(true))
@@ -101,7 +101,7 @@ func disabledTestHTTPDataset(t *testing.T) {
spec := fmt.Sprintf("http://localhost:%d", port)
datasetSpec := fmt.Sprintf("%s:%s", spec, datasetId)
server := datas.NewRemoteDataStoreServer(chunks.NewTestStore(), port)
server := datas.NewRemoteDatabaseServer(chunks.NewTestStore(), port)
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
@@ -110,9 +110,9 @@ func disabledTestHTTPDataset(t *testing.T) {
}()
time.Sleep(time.Second)
sp1, err := ParseDatastoreSpec(spec)
sp1, err := ParseDatabaseSpec(spec)
assert.NoError(err)
store, err := sp1.Datastore()
store, err := sp1.Database()
assert.NoError(err)
dataset1 := dataset.NewDataset(store, datasetId)
@@ -152,7 +152,7 @@ func TestLDBDataset(t *testing.T) {
assert.NoError(err)
ldbPath := path.Join(dir, "name")
cs := chunks.NewLevelDBStoreUseFlags(ldbPath, "")
ds := datas.NewDataStore(cs)
ds := datas.NewDatabase(cs)
id := "dsName"
set := dataset.NewDataset(ds, id)
@@ -179,7 +179,7 @@ func TestLDBObject(t *testing.T) {
dsId := "dsId"
cs1 := chunks.NewLevelDBStoreUseFlags(ldbpath, "")
store1 := datas.NewDataStore(cs1)
store1 := datas.NewDatabase(cs1)
dataset1 := dataset.NewDataset(store1, dsId)
s1 := types.NewString("Commit Value")
r1 := store1.WriteValue(s1)
@@ -200,9 +200,9 @@ func TestLDBObject(t *testing.T) {
spec3 := fmt.Sprintf("ldb:%s:%s", ldbpath, s1.Ref().String())
sp3, err := ParsePathSpec(spec3)
datastore, v3, err := sp3.Value()
database, v3, err := sp3.Value()
assert.Equal(s1.String(), v3.(types.String).String())
datastore.Close()
database.Close()
}
func TestReadRef(t *testing.T) {
@@ -214,8 +214,8 @@ func TestReadRef(t *testing.T) {
ldbPath := path.Join(dir, "/name")
cs1 := chunks.NewLevelDBStoreUseFlags(ldbPath, "")
datastore1 := datas.NewDataStore(cs1)
dataset1 := dataset.NewDataset(datastore1, datasetId)
database1 := datas.NewDatabase(cs1)
dataset1 := dataset.NewDataset(database1, datasetId)
commit := types.NewString("Commit Value")
dataset1, err = dataset1.Commit(commit)
assert.NoError(err)
@@ -225,45 +225,45 @@ func TestReadRef(t *testing.T) {
spec2 := fmt.Sprintf("ldb:%s:%s", ldbPath, r1.String())
sp2, err := ParsePathSpec(spec2)
assert.NoError(err)
datastore, v2, err := sp2.Value()
database, v2, err := sp2.Value()
assert.NoError(err)
assert.EqualValues(r1.String(), v2.Ref().String())
datastore.Close()
database.Close()
}
func TestDatastoreSpecs(t *testing.T) {
func TestDatabaseSpecs(t *testing.T) {
assert := assert.New(t)
badSpecs := []string{"mem:", "mem:stuff", "http:", "https:", "random:", "random:random"}
for _, spec := range badSpecs {
_, err := ParseDatastoreSpec(spec)
_, err := ParseDatabaseSpec(spec)
assert.Error(err)
}
storeSpec, err := ParseDatastoreSpec("http://localhost:8000")
storeSpec, err := ParseDatabaseSpec("http://localhost:8000")
assert.NoError(err)
assert.Equal(DatastoreSpec{Protocol: "http", Path: "//localhost:8000"}, storeSpec)
assert.Equal(DatabaseSpec{Protocol: "http", Path: "//localhost:8000"}, storeSpec)
storeSpec, err = ParseDatastoreSpec("http://localhost:8000/")
storeSpec, err = ParseDatabaseSpec("http://localhost:8000/")
assert.NoError(err)
assert.Equal(DatastoreSpec{Protocol: "http", Path: "//localhost:8000"}, storeSpec)
assert.Equal(DatabaseSpec{Protocol: "http", Path: "//localhost:8000"}, storeSpec)
storeSpec, err = ParseDatastoreSpec("http://localhost:8000/fff")
storeSpec, err = ParseDatabaseSpec("http://localhost:8000/fff")
assert.NoError(err)
assert.Equal(DatastoreSpec{Protocol: "http", Path: "//localhost:8000/fff"}, storeSpec)
assert.Equal(DatabaseSpec{Protocol: "http", Path: "//localhost:8000/fff"}, storeSpec)
storeSpec, err = ParseDatastoreSpec("https://local.attic.io/john/doe")
storeSpec, err = ParseDatabaseSpec("https://local.attic.io/john/doe")
assert.NoError(err)
assert.Equal(DatastoreSpec{Protocol: "https", Path: "//local.attic.io/john/doe"}, storeSpec)
assert.Equal(DatabaseSpec{Protocol: "https", Path: "//local.attic.io/john/doe"}, storeSpec)
storeSpec, err = ParseDatastoreSpec("ldb:/filesys/john/doe")
storeSpec, err = ParseDatabaseSpec("ldb:/filesys/john/doe")
assert.NoError(err)
assert.Equal(DatastoreSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, storeSpec)
assert.Equal(DatabaseSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, storeSpec)
storeSpec, err = ParseDatastoreSpec("mem")
storeSpec, err = ParseDatabaseSpec("mem")
assert.NoError(err)
assert.Equal(DatastoreSpec{Protocol: "mem"}, storeSpec)
assert.Equal(DatabaseSpec{Protocol: "mem"}, storeSpec)
}
func TestDatasetSpecs(t *testing.T) {
@@ -277,27 +277,27 @@ func TestDatasetSpecs(t *testing.T) {
setSpec, err := ParseDatasetSpec("http://localhost:8000:dsname")
assert.NoError(err)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "http", Path: "//localhost:8000"}, DatasetName: "dsname"}, setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "http", Path: "//localhost:8000"}, DatasetName: "dsname"}, setSpec)
setSpec, err = ParseDatasetSpec("http://localhost:8000/john/doe/:dsname")
assert.NoError(err)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "http", Path: "//localhost:8000/john/doe"}, DatasetName: "dsname"}, setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "http", Path: "//localhost:8000/john/doe"}, DatasetName: "dsname"}, setSpec)
setSpec, err = ParseDatasetSpec("https://local.attic.io/john/doe:dsname")
assert.NoError(err)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "https", Path: "//local.attic.io/john/doe"}, DatasetName: "dsname"}, setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "https", Path: "//local.attic.io/john/doe"}, DatasetName: "dsname"}, setSpec)
setSpec, err = ParseDatasetSpec("http://local.attic.io/john/doe:dsname")
assert.NoError(err)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "http", Path: "//local.attic.io/john/doe"}, DatasetName: "dsname"}, setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "http", Path: "//local.attic.io/john/doe"}, DatasetName: "dsname"}, setSpec)
setSpec, err = ParseDatasetSpec("ldb:/filesys/john/doe:dsname")
assert.NoError(err)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, DatasetName: "dsname"}, setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, DatasetName: "dsname"}, setSpec)
setSpec, err = ParseDatasetSpec("mem:dsname")
assert.NoError(err)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "mem"}, DatasetName: "dsname"}, setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "mem"}, DatasetName: "dsname"}, setSpec)
}
func TestRefSpec(t *testing.T) {
@@ -307,15 +307,15 @@ func TestRefSpec(t *testing.T) {
refSpec, err := ParseRefSpec("http://local.attic.io/john/doe:sha1-0123456789012345678901234567890123456789")
assert.NoError(err)
assert.Equal(RefSpec{StoreSpec: DatastoreSpec{Protocol: "http", Path: "//local.attic.io/john/doe"}, Ref: testRef}, refSpec)
assert.Equal(RefSpec{StoreSpec: DatabaseSpec{Protocol: "http", Path: "//local.attic.io/john/doe"}, Ref: testRef}, refSpec)
refSpec, err = ParseRefSpec("ldb:/filesys/john/doe:sha1-0123456789012345678901234567890123456789")
assert.NoError(err)
assert.Equal(RefSpec{StoreSpec: DatastoreSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, Ref: testRef}, refSpec)
assert.Equal(RefSpec{StoreSpec: DatabaseSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, Ref: testRef}, refSpec)
refSpec, err = ParseRefSpec("mem:sha1-0123456789012345678901234567890123456789")
assert.NoError(err)
assert.Equal(RefSpec{StoreSpec: DatastoreSpec{Protocol: "mem"}, Ref: testRef}, refSpec)
assert.Equal(RefSpec{StoreSpec: DatabaseSpec{Protocol: "mem"}, Ref: testRef}, refSpec)
}
func TestPathSpec(t *testing.T) {
@@ -326,12 +326,12 @@ func TestPathSpec(t *testing.T) {
pathSpec, err := ParsePathSpec("http://local.attic.io/john/doe:sha1-0123456789012345678901234567890123456789")
assert.NoError(err)
refSpec := pathSpec.(*RefSpec)
assert.Equal(RefSpec{StoreSpec: DatastoreSpec{Protocol: "http", Path: "//local.attic.io/john/doe"}, Ref: testRef}, *refSpec)
assert.Equal(RefSpec{StoreSpec: DatabaseSpec{Protocol: "http", Path: "//local.attic.io/john/doe"}, Ref: testRef}, *refSpec)
pathSpec, err = ParsePathSpec("http://localhost:8000/john/doe/:dsname")
assert.NoError(err)
setSpec := pathSpec.(*DatasetSpec)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "http", Path: "//localhost:8000/john/doe"}, DatasetName: "dsname"}, *setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "http", Path: "//localhost:8000/john/doe"}, DatasetName: "dsname"}, *setSpec)
_, err = ParsePathSpec("http://local.attic.io")
assert.Error(err)
@@ -347,23 +347,23 @@ func disabledTestRefSpec(t *testing.T) {
setSpec, err := ParseDatasetSpec("/filesys/john/doe:dsName")
assert.NoError(err)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, DatasetName: "dsName"}, setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, DatasetName: "dsName"}, setSpec)
setSpec, err = ParseDatasetSpec("xyz")
assert.NoError(err)
assert.Equal(DatasetSpec{StoreSpec: DatastoreSpec{Protocol: "ldb", Path: "/u/testuser/.noms"}, DatasetName: "xyz"}, setSpec)
assert.Equal(DatasetSpec{StoreSpec: DatabaseSpec{Protocol: "ldb", Path: "/u/testuser/.noms"}, DatasetName: "xyz"}, setSpec)
storeSpec, err := ParseDatasetSpec("/path/to/somewhere")
assert.NoError(err)
assert.Equal(DatastoreSpec{Protocol: "ldb", Path: "/path/to/somewhere"}, storeSpec)
assert.Equal(DatabaseSpec{Protocol: "ldb", Path: "/path/to/somewhere"}, storeSpec)
testRef := ref.Parse("sha1-0123456789012345678901234567890123456789")
refSpec, err := ParseRefSpec("/filesys/john/doe:sha1-0123456789012345678901234567890123456789")
assert.NoError(err)
assert.Equal(RefSpec{StoreSpec: DatastoreSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, Ref: testRef}, refSpec)
assert.Equal(RefSpec{StoreSpec: DatabaseSpec{Protocol: "ldb", Path: "/filesys/john/doe"}, Ref: testRef}, refSpec)
refSpec, err = ParseRefSpec("sha1-0123456789012345678901234567890123456789")
assert.NoError(err)
assert.Equal(RefSpec{StoreSpec: DatastoreSpec{Protocol: "ldb", Path: "/u/testuser/.noms"}, Ref: testRef}, refSpec)
assert.Equal(RefSpec{StoreSpec: DatabaseSpec{Protocol: "ldb", Path: "/u/testuser/.noms"}, Ref: testRef}, refSpec)
}
+1 -1
View File
@@ -20,7 +20,7 @@ func main() {
flag.PrintDefaults()
}
flags.RegisterDataStoreFlags()
flags.RegisterDatabaseFlags()
flag.Parse()
if len(flag.Args()) != 2 {
+2 -2
View File
@@ -1,6 +1,6 @@
# Server
Server implements a noms datastore over HTTP.
Server implements a noms database over HTTP.
## Example
@@ -16,7 +16,7 @@ go build
./server ldb:/tmp/servertest
```
Then navigate a web browser to [http://localhost:8000/root](http://localhost:8000/root). You should see a string starting with `sha1-...`. This _ref_ is the unique identifier for the current state of the datastore. You can explore it further by fetching URLs like http://localhost:8000/ref/sha1-...
Then navigate a web browser to [http://localhost:8000/root](http://localhost:8000/root). You should see a string starting with `sha1-...`. This _ref_ is the unique identifier for the current state of the database. You can explore it further by fetching URLs like http://localhost:8000/ref/sha1-...
## About
+5 -5
View File
@@ -20,11 +20,11 @@ var (
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "usage: %s <datastore>\n", os.Args[0])
fmt.Fprintf(os.Stderr, "usage: %s <database>\n", os.Args[0])
flag.PrintDefaults()
}
flags.RegisterDataStoreFlags()
flags.RegisterDatabaseFlags()
flag.Parse()
if len(flag.Args()) != 1 {
@@ -32,16 +32,16 @@ func main() {
return
}
spec, err := flags.ParseDatastoreSpec(flag.Arg(0))
spec, err := flags.ParseDatabaseSpec(flag.Arg(0))
util.CheckError(err)
if spec.Protocol != "mem" && spec.Protocol != "ldb" {
err := errors.New("Illegal datastore spec for server, must be 'mem' or 'ldb'")
err := errors.New("Illegal database spec for server, must be 'mem' or 'ldb'")
util.CheckError(err)
}
cs, err := spec.ChunkStore()
util.CheckError(err)
server := datas.NewRemoteDataStoreServer(cs, *port)
server := datas.NewRemoteDatabaseServer(cs, *port)
// Shutdown server gracefully so that profile may be written
c := make(chan os.Signal, 1)
+2 -2
View File
@@ -1,6 +1,6 @@
# Shove
Shove syncs between datastores and datasets. It is the noms equivalent of Git's `push` and `pull` commands.
Shove syncs between databases and datasets. It is the noms equivalent of Git's `push` and `pull` commands.
## Example
@@ -16,7 +16,7 @@ go build
./shove ldb:/tmp/shovetest1:counter ldb:/tmp/shovetest2:counter2
../counter/counter ldb:/tmp/shovetest2:counter2
# Shove can also connect to http datastores
# Shove can also connect to http databases
cd ../server
go build
./server ldb:/tmp/shovetest2 &
+1 -1
View File
@@ -27,7 +27,7 @@ func main() {
flag.PrintDefaults()
}
flags.RegisterDataStoreFlags()
flags.RegisterDatabaseFlags()
flag.Parse()
if flag.NArg() != 2 {
+4 -4
View File
@@ -22,13 +22,13 @@ type testSuite struct {
}
func (s *testSuite) TestShove() {
source1 := dataset.NewDataset(datas.NewDataStore(chunks.NewLevelDBStore(s.LdbDir, "", 1, false)), "foo")
source1 := dataset.NewDataset(datas.NewDatabase(chunks.NewLevelDBStore(s.LdbDir, "", 1, false)), "foo")
source1, err := source1.Commit(types.Number(42))
s.NoError(err)
source2, err := source1.Commit(types.Number(43))
s.NoError(err)
source1HeadRef := source1.Head().Ref()
source2.Store().Close() // Close DataStore backing both Datasets
source2.Store().Close() // Close Database backing both Datasets
sourceSpec := fmt.Sprintf("ldb:%s:%s", s.LdbDir, source1HeadRef)
ldb2dir := path.Join(s.TempDir, "ldb2")
@@ -36,7 +36,7 @@ func (s *testSuite) TestShove() {
out := s.Run(main, []string{sourceSpec, sinkDatasetSpec})
s.Equal("", out)
dest := dataset.NewDataset(datas.NewDataStore(chunks.NewLevelDBStore(ldb2dir, "", 1, false)), "bar")
dest := dataset.NewDataset(datas.NewDatabase(chunks.NewLevelDBStore(ldb2dir, "", 1, false)), "bar")
s.True(types.Number(42).Equals(dest.Head().Get(datas.ValueField)))
dest.Store().Close()
@@ -44,7 +44,7 @@ func (s *testSuite) TestShove() {
out = s.Run(main, []string{sourceDataset, sinkDatasetSpec})
s.Equal("", out)
dest = dataset.NewDataset(datas.NewDataStore(chunks.NewLevelDBStore(ldb2dir, "", 1, false)), "bar")
dest = dataset.NewDataset(datas.NewDatabase(chunks.NewLevelDBStore(ldb2dir, "", 1, false)), "bar")
s.True(types.Number(43).Equals(dest.Head().Get(datas.ValueField)))
dest.Store().Close()
}
+1 -1
View File
@@ -32,7 +32,7 @@ func main() {
flag.PrintDefaults()
}
flags.RegisterDataStoreFlags()
flags.RegisterDatabaseFlags()
flag.Parse()
if flag.NArg() != 2 {
+1 -1
View File
@@ -46,7 +46,7 @@ func (a refIndexList) Less(i, j int) bool { return a[i].index < a[j].index }
func main() {
err := d.Try(func() {
flags.RegisterDataStoreFlags()
flags.RegisterDatabaseFlags()
flag.Usage = customUsage
flag.Parse()
+2 -2
View File
@@ -35,9 +35,9 @@ func main() {
spec, err := flags.ParsePathSpec(flag.Arg(0))
util.CheckError(err)
datastore, value, err := spec.Value()
database, value, err := spec.Value()
util.CheckError(err)
fmt.Println(types.EncodedValueWithTags(value))
datastore.Close()
database.Close()
}
+51
View File
@@ -0,0 +1,51 @@
package datas
import (
"io"
"github.com/attic-labs/noms/chunks"
"github.com/attic-labs/noms/types"
)
// Database provides versioned storage for noms values. Each Database instance represents one moment in history. Heads() returns the Commit from each active fork at that moment. The Commit() method returns a new Database, representing a new moment in history.
type Database interface {
// To implement types.ValueWriter, Database implementations provide WriteValue(). WriteValue() writes v to this Database, though v is not guaranteed to be be persistent until after a subsequent Commit(). The return value is the Ref of v.
types.ValueWriter
types.ValueReader
io.Closer
// MaybeHead returns the current Head Commit of this Database, which contains the current root of the Database's value tree, if available. If not, it returns a new Commit and 'false'.
MaybeHead(datasetID string) (types.Struct, bool)
// MaybeHeadRef returns the types.Ref of the Head Commit of this Database, and true, if available. If not, it returns an invalid types.Ref and false.
MaybeHeadRef(datasetID string) (types.Ref, bool)
// Head returns the current head Commit, which contains the current root of the Database's value tree.
Head(datasetID string) types.Struct
// HeadRef returns the ref of the current head Commit. See Head(datasetID).
HeadRef(datasetID string) types.Ref
// Datasets returns the root of the database which is a MapOfStringToRefOfCommit where string is a datasetID.
Datasets() types.Map
// Commit updates the Commit that datasetID in this database points at. All Values that have been written to this Database are guaranteed to be persistent after Commit(). If the update cannot be performed, e.g., because of a conflict, error will non-nil. The newest snapshot of the database is always returned.
Commit(datasetID string, commit types.Struct) (Database, error)
// Delete removes the Dataset named datasetID from the map at the root of the Database. The Dataset data is not necessarily cleaned up at this time, but may be garbage collected in the future. If the update cannot be performed, e.g., because of a conflict, error will non-nil. The newest snapshot of the database is always returned.
Delete(datasetID string) (Database, error)
batchSink() batchSink
batchStore() types.BatchStore
}
// This interface exists solely to allow RemoteDatabaseClient to pass back a gross side-channel thing for the purposes of pull.
type batchSink interface {
SchedulePut(c chunks.Chunk, hints types.Hints)
Flush()
io.Closer
}
func NewDatabase(cs chunks.ChunkStore) Database {
return newLocalDatabase(cs)
}
@@ -9,7 +9,7 @@ import (
"github.com/attic-labs/noms/types"
)
type dataStoreCommon struct {
type databaseCommon struct {
vs *types.ValueStore
rt chunks.RootTracker
rootRef ref.Ref
@@ -17,41 +17,41 @@ type dataStoreCommon struct {
}
var (
ErrOptimisticLockFailed = errors.New("Optimistic lock failed on datastore Root update")
ErrOptimisticLockFailed = errors.New("Optimistic lock failed on database Root update")
ErrMergeNeeded = errors.New("Dataset head is not ancestor of commit")
)
func newDataStoreCommon(vs *types.ValueStore, rt chunks.RootTracker) dataStoreCommon {
return dataStoreCommon{vs: vs, rt: rt, rootRef: rt.Root()}
func newDatabaseCommon(vs *types.ValueStore, rt chunks.RootTracker) databaseCommon {
return databaseCommon{vs: vs, rt: rt, rootRef: rt.Root()}
}
func (ds *dataStoreCommon) MaybeHead(datasetID string) (types.Struct, bool) {
func (ds *databaseCommon) MaybeHead(datasetID string) (types.Struct, bool) {
if r, ok := ds.MaybeHeadRef(datasetID); ok {
return r.TargetValue(ds).(types.Struct), true
}
return NewCommit(), false
}
func (ds *dataStoreCommon) MaybeHeadRef(datasetID string) (types.Ref, bool) {
func (ds *databaseCommon) MaybeHeadRef(datasetID string) (types.Ref, bool) {
if r, ok := ds.Datasets().MaybeGet(types.NewString(datasetID)); ok {
return r.(types.Ref), true
}
return types.Ref{}, false
}
func (ds *dataStoreCommon) Head(datasetID string) types.Struct {
func (ds *databaseCommon) Head(datasetID string) types.Struct {
c, ok := ds.MaybeHead(datasetID)
d.Chk.True(ok, "DataStore \"%s\" has no Head.", datasetID)
d.Chk.True(ok, "Database \"%s\" has no Head.", datasetID)
return c
}
func (ds *dataStoreCommon) HeadRef(datasetID string) types.Ref {
func (ds *databaseCommon) HeadRef(datasetID string) types.Ref {
r, ok := ds.MaybeHeadRef(datasetID)
d.Chk.True(ok, "DataStore \"%s\" has no Head.", datasetID)
d.Chk.True(ok, "Database \"%s\" has no Head.", datasetID)
return r
}
func (ds *dataStoreCommon) Datasets() types.Map {
func (ds *databaseCommon) Datasets() types.Map {
if ds.datasets == nil {
if ds.rootRef.IsEmpty() {
emptyMap := NewMapOfStringToRefOfCommit()
@@ -64,29 +64,29 @@ func (ds *dataStoreCommon) Datasets() types.Map {
return *ds.datasets
}
func (ds *dataStoreCommon) ReadValue(r ref.Ref) types.Value {
func (ds *databaseCommon) ReadValue(r ref.Ref) types.Value {
return ds.vs.ReadValue(r)
}
func (ds *dataStoreCommon) WriteValue(v types.Value) types.Ref {
func (ds *databaseCommon) WriteValue(v types.Value) types.Ref {
return ds.vs.WriteValue(v)
}
func (ds *dataStoreCommon) Close() error {
func (ds *databaseCommon) Close() error {
return ds.vs.Close()
}
func (ds *dataStoreCommon) datasetsFromRef(datasetsRef ref.Ref) *types.Map {
func (ds *databaseCommon) datasetsFromRef(datasetsRef ref.Ref) *types.Map {
c := ds.ReadValue(datasetsRef).(types.Map)
return &c
}
func (ds *dataStoreCommon) commit(datasetID string, commit types.Struct) error {
func (ds *databaseCommon) commit(datasetID string, commit types.Struct) error {
return ds.doCommit(datasetID, commit)
}
// doCommit manages concurrent access the single logical piece of mutable state: the current Root. doCommit is optimistic in that it is attempting to update head making the assumption that currentRootRef is the ref of the current head. The call to UpdateRoot below will return an 'ErrOptimisticLockFailed' error if that assumption fails (e.g. because of a race with another writer) and the entire algorithm must be tried again. This method will also fail and return an 'ErrMergeNeeded' error if the |commit| is not a descendent of the current dataset head
func (ds *dataStoreCommon) doCommit(datasetID string, commit types.Struct) error {
func (ds *databaseCommon) doCommit(datasetID string, commit types.Struct) error {
currentRootRef, currentDatasets := ds.getRootAndDatasets()
// TODO: This Commit will be orphaned if the tryUpdateRoot() below fails
@@ -113,13 +113,13 @@ func (ds *dataStoreCommon) doCommit(datasetID string, commit types.Struct) error
}
// doDelete manages concurrent access the single logical piece of mutable state: the current Root. doDelete is optimistic in that it is attempting to update head making the assumption that currentRootRef is the ref of the current head. The call to UpdateRoot below will return an 'ErrOptimisticLockFailed' error if that assumption fails (e.g. because of a race with another writer) and the entire algorithm must be tried again.
func (ds *dataStoreCommon) doDelete(datasetID string) error {
func (ds *databaseCommon) doDelete(datasetID string) error {
currentRootRef, currentDatasets := ds.getRootAndDatasets()
currentDatasets = currentDatasets.Remove(types.NewString(datasetID))
return ds.tryUpdateRoot(currentDatasets, currentRootRef)
}
func (ds *dataStoreCommon) getRootAndDatasets() (currentRootRef ref.Ref, currentDatasets types.Map) {
func (ds *databaseCommon) getRootAndDatasets() (currentRootRef ref.Ref, currentDatasets types.Map) {
currentRootRef = ds.rt.Root()
currentDatasets = ds.Datasets()
@@ -130,7 +130,7 @@ func (ds *dataStoreCommon) getRootAndDatasets() (currentRootRef ref.Ref, current
return
}
func (ds *dataStoreCommon) tryUpdateRoot(currentDatasets types.Map, currentRootRef ref.Ref) (err error) {
func (ds *databaseCommon) tryUpdateRoot(currentDatasets types.Map, currentRootRef ref.Ref) (err error) {
// TODO: This Commit will be orphaned if the UpdateRoot below fails
newRootRef := ds.WriteValue(currentDatasets).TargetRef()
// If the root has been updated by another process in the short window since we read it, this call will fail. See issue #404
@@ -16,7 +16,7 @@ type connectionState struct {
cs http.ConnState
}
type remoteDataStoreServer struct {
type remoteDatabaseServer struct {
cs chunks.ChunkStore
port int
l *net.Listener
@@ -24,14 +24,14 @@ type remoteDataStoreServer struct {
closing bool
}
func NewRemoteDataStoreServer(cs chunks.ChunkStore, port int) *remoteDataStoreServer {
return &remoteDataStoreServer{
func NewRemoteDatabaseServer(cs chunks.ChunkStore, port int) *remoteDatabaseServer {
return &remoteDatabaseServer{
cs, port, nil, make(chan *connectionState, 16), false,
}
}
// Run blocks while the remoteDataStoreServer is listening. Running on a separate go routine is supported.
func (s *remoteDataStoreServer) Run() {
// Run blocks while the remoteDatabaseServer is listening. Running on a separate go routine is supported.
func (s *remoteDatabaseServer) Run() {
fmt.Printf("Listening on port %d...\n", s.port)
l, err := net.Listen("tcp", fmt.Sprintf(":%d", s.port))
d.Chk.NoError(err)
@@ -71,13 +71,13 @@ func (s *remoteDataStoreServer) Run() {
srv.Serve(l)
}
func (s *remoteDataStoreServer) makeHandle(hndlr Handler) httprouter.Handle {
func (s *remoteDatabaseServer) makeHandle(hndlr Handler) httprouter.Handle {
return func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
hndlr(w, req, ps, s.cs)
}
}
func (s *remoteDataStoreServer) connState(c net.Conn, cs http.ConnState) {
func (s *remoteDatabaseServer) connState(c net.Conn, cs http.ConnState) {
if s.closing {
d.Chk.Equal(cs, http.StateClosed)
return
@@ -85,8 +85,8 @@ func (s *remoteDataStoreServer) connState(c net.Conn, cs http.ConnState) {
s.csChan <- &connectionState{c, cs}
}
// Will cause the remoteDataStoreServer to stop listening and an existing call to Run() to continue.
func (s *remoteDataStoreServer) Stop() {
// Will cause the remoteDatabaseServer to stop listening and an existing call to Run() to continue.
func (s *remoteDatabaseServer) Stop() {
s.closing = true
(*s.l).Close()
(s.cs).Close()
@@ -9,53 +9,53 @@ import (
"github.com/stretchr/testify/suite"
)
// writesOnCommit allows tests to adjust for how many writes dataStoreCommon performs on Commit()
// writesOnCommit allows tests to adjust for how many writes databaseCommon performs on Commit()
const writesOnCommit = 2
func TestLocalDataStore(t *testing.T) {
suite.Run(t, &LocalDataStoreSuite{})
func TestLocalDatabase(t *testing.T) {
suite.Run(t, &LocalDatabaseSuite{})
}
func TestRemoteDataStore(t *testing.T) {
suite.Run(t, &RemoteDataStoreSuite{})
func TestRemoteDatabase(t *testing.T) {
suite.Run(t, &RemoteDatabaseSuite{})
}
type DataStoreSuite struct {
type DatabaseSuite struct {
suite.Suite
cs *chunks.TestStore
ds DataStore
makeDs func(chunks.ChunkStore) DataStore
ds Database
makeDs func(chunks.ChunkStore) Database
}
type LocalDataStoreSuite struct {
DataStoreSuite
type LocalDatabaseSuite struct {
DatabaseSuite
}
func (suite *LocalDataStoreSuite) SetupTest() {
func (suite *LocalDatabaseSuite) SetupTest() {
suite.cs = chunks.NewTestStore()
suite.makeDs = NewDataStore
suite.makeDs = NewDatabase
suite.ds = suite.makeDs(suite.cs)
}
type RemoteDataStoreSuite struct {
DataStoreSuite
type RemoteDatabaseSuite struct {
DatabaseSuite
}
func (suite *RemoteDataStoreSuite) SetupTest() {
func (suite *RemoteDatabaseSuite) SetupTest() {
suite.cs = chunks.NewTestStore()
suite.makeDs = func(cs chunks.ChunkStore) DataStore {
suite.makeDs = func(cs chunks.ChunkStore) Database {
hbs := newHTTPBatchStoreForTest(suite.cs)
return &RemoteDataStoreClient{newDataStoreCommon(types.NewValueStore(hbs), hbs)}
return &RemoteDatabaseClient{newDatabaseCommon(types.NewValueStore(hbs), hbs)}
}
suite.ds = suite.makeDs(suite.cs)
}
func (suite *DataStoreSuite) TearDownTest() {
func (suite *DatabaseSuite) TearDownTest() {
suite.ds.Close()
suite.cs.Close()
}
func (suite *DataStoreSuite) TestReadWriteCache() {
func (suite *DatabaseSuite) TestReadWriteCache() {
var v types.Value = types.Bool(true)
suite.NotEqual(ref.Ref{}, suite.ds.WriteValue(v))
r := suite.ds.WriteValue(v).TargetRef()
@@ -68,7 +68,7 @@ func (suite *DataStoreSuite) TestReadWriteCache() {
suite.True(v.Equals(types.Bool(true)))
}
func (suite *DataStoreSuite) TestReadWriteCachePersists() {
func (suite *DatabaseSuite) TestReadWriteCachePersists() {
var err error
var v types.Value = types.Bool(true)
suite.NotEqual(ref.Ref{}, suite.ds.WriteValue(v))
@@ -83,15 +83,15 @@ func (suite *DataStoreSuite) TestReadWriteCachePersists() {
suite.NoError(err)
}
func (suite *DataStoreSuite) TestWriteRefToNonexistentValue() {
func (suite *DatabaseSuite) TestWriteRefToNonexistentValue() {
suite.Panics(func() { suite.ds.WriteValue(types.NewTypedRefFromValue(types.Bool(true))) })
}
func (suite *DataStoreSuite) TestTolerateUngettableRefs() {
func (suite *DatabaseSuite) TestTolerateUngettableRefs() {
suite.Nil(suite.ds.ReadValue(ref.Ref{}))
}
func (suite *DataStoreSuite) TestDataStoreCommit() {
func (suite *DatabaseSuite) TestDatabaseCommit() {
datasetID := "ds1"
datasets := suite.ds.Datasets()
suite.Zero(datasets.Len())
@@ -102,13 +102,13 @@ func (suite *DataStoreSuite) TestDataStoreCommit() {
ds2, err := suite.ds.Commit(datasetID, aCommit)
suite.NoError(err)
// The old datastore still has no head.
// The old database still has no head.
_, ok := suite.ds.MaybeHead(datasetID)
suite.False(ok)
_, ok = suite.ds.MaybeHeadRef(datasetID)
suite.False(ok)
// The new datastore has |a|.
// The new database has |a|.
aCommit1 := ds2.Head(datasetID)
suite.True(aCommit1.Get(ValueField).Equals(a))
aRef1 := ds2.HeadRef(datasetID)
@@ -151,14 +151,14 @@ func (suite *DataStoreSuite) TestDataStoreCommit() {
_, err = suite.ds.Commit("otherDs", aCommit)
suite.NoError(err)
// Get a fresh datastore, and verify that both datasets are present
// Get a fresh database, and verify that both datasets are present
newDs := suite.makeDs(suite.cs)
datasets2 := newDs.Datasets()
suite.Equal(uint64(2), datasets2.Len())
newDs.Close()
}
func (suite *DataStoreSuite) TestDataStoreDelete() {
func (suite *DatabaseSuite) TestDatabaseDelete() {
datasetID1, datasetID2 := "ds1", "ds2"
datasets := suite.ds.Datasets()
suite.Zero(datasets.Len())
@@ -182,7 +182,7 @@ func (suite *DataStoreSuite) TestDataStoreDelete() {
h, present := suite.ds.MaybeHead(datasetID1)
suite.False(present, "Dataset %s should not be present, but head is %v", datasetID1, h.Get(ValueField))
// Get a fresh datastore, and verify that only ds1 is present
// Get a fresh database, and verify that only ds1 is present
newDs := suite.makeDs(suite.cs)
datasets = newDs.Datasets()
suite.Equal(uint64(1), datasets.Len())
@@ -191,7 +191,7 @@ func (suite *DataStoreSuite) TestDataStoreDelete() {
newDs.Close()
}
func (suite *DataStoreSuite) TestDataStoreDeleteConcurrent() {
func (suite *DatabaseSuite) TestDatabaseDeleteConcurrent() {
datasetID := "ds1"
suite.Zero(suite.ds.Datasets().Len())
var err error
@@ -217,13 +217,13 @@ func (suite *DataStoreSuite) TestDataStoreDeleteConcurrent() {
h, present = ds2.MaybeHead(datasetID)
suite.True(present, "Dataset %s should be present", datasetID)
// Get a fresh datastore, and verify that no datastores are present
// Get a fresh database, and verify that no databases are present
newDs := suite.makeDs(suite.cs)
suite.Equal(uint64(0), newDs.Datasets().Len())
newDs.Close()
}
func (suite *DataStoreSuite) TestDataStoreConcurrency() {
func (suite *DatabaseSuite) TestDatabaseConcurrency() {
datasetID := "ds1"
var err error
@@ -251,7 +251,7 @@ func (suite *DataStoreSuite) TestDataStoreConcurrency() {
// Change 2:
// |a| <- |b| <- |e|
// Should be disallowed, DataStore returned by Commit() should have |c| as Head.
// Should be disallowed, Database returned by Commit() should have |c| as Head.
e := types.NewString("e")
eCommit := NewCommit().Set(ValueField, e).Set(ParentsField, NewSetOfRefOfCommit().Insert(types.NewTypedRefFromValue(bCommit)))
ds2, err = ds2.Commit(datasetID, eCommit)
@@ -259,7 +259,7 @@ func (suite *DataStoreSuite) TestDataStoreConcurrency() {
suite.True(ds2.Head(datasetID).Get(ValueField).Equals(c))
}
func (suite *DataStoreSuite) TestDataStoreHeightOfRefs() {
func (suite *DatabaseSuite) TestDatabaseHeightOfRefs() {
r1 := suite.ds.WriteValue(types.NewString("hello"))
suite.Equal(uint64(1), r1.Height())
@@ -268,7 +268,7 @@ func (suite *DataStoreSuite) TestDataStoreHeightOfRefs() {
suite.Equal(uint64(3), suite.ds.WriteValue(r2).Height())
}
func (suite *DataStoreSuite) TestDataStoreHeightOfCollections() {
func (suite *DatabaseSuite) TestDatabaseHeightOfCollections() {
setOfStringType := types.MakeSetType(types.StringType)
setOfRefOfStringType := types.MakeSetType(types.MakeRefType(types.StringType))
-51
View File
@@ -1,51 +0,0 @@
package datas
import (
"io"
"github.com/attic-labs/noms/chunks"
"github.com/attic-labs/noms/types"
)
// DataStore provides versioned storage for noms values. Each DataStore instance represents one moment in history. Heads() returns the Commit from each active fork at that moment. The Commit() method returns a new DataStore, representing a new moment in history.
type DataStore interface {
// To implement types.ValueWriter, DataStore implementations provide WriteValue(). WriteValue() writes v to this DataStore, though v is not guaranteed to be be persistent until after a subsequent Commit(). The return value is the Ref of v.
types.ValueWriter
types.ValueReader
io.Closer
// MaybeHead returns the current Head Commit of this Datastore, which contains the current root of the DataStore's value tree, if available. If not, it returns a new Commit and 'false'.
MaybeHead(datasetID string) (types.Struct, bool)
// MaybeHeadRef returns the types.Ref of the Head Commit of this Datastore, and true, if available. If not, it returns an invalid types.Ref and false.
MaybeHeadRef(datasetID string) (types.Ref, bool)
// Head returns the current head Commit, which contains the current root of the DataStore's value tree.
Head(datasetID string) types.Struct
// HeadRef returns the ref of the current head Commit. See Head(datasetID).
HeadRef(datasetID string) types.Ref
// Datasets returns the root of the datastore which is a MapOfStringToRefOfCommit where string is a datasetID.
Datasets() types.Map
// Commit updates the Commit that datasetID in this datastore points at. All Values that have been written to this DataStore are guaranteed to be persistent after Commit(). If the update cannot be performed, e.g., because of a conflict, error will non-nil. The newest snapshot of the datastore is always returned.
Commit(datasetID string, commit types.Struct) (DataStore, error)
// Delete removes the Dataset named datasetID from the map at the root of the DataStore. The Dataset data is not necessarily cleaned up at this time, but may be garbage collected in the future. If the update cannot be performed, e.g., because of a conflict, error will non-nil. The newest snapshot of the datastore is always returned.
Delete(datasetID string) (DataStore, error)
batchSink() batchSink
batchStore() types.BatchStore
}
// This interface exists solely to allow RemoteDataStoreClient to pass back a gross side-channel thing for the purposes of pull.
type batchSink interface {
SchedulePut(c chunks.Chunk, hints types.Hints)
Flush()
io.Closer
}
func NewDataStore(cs chunks.ChunkStore) DataStore {
return newLocalDataStore(cs)
}
+5 -5
View File
@@ -2,9 +2,9 @@ package datas
import "github.com/attic-labs/noms/chunks"
// Factory allows the creation of namespaced DataStore instances. The details of how namespaces are separated is left up to the particular implementation of Factory and DataStore.
// Factory allows the creation of namespaced Database instances. The details of how namespaces are separated is left up to the particular implementation of Factory and Database.
type Factory interface {
Create(string) (DataStore, bool)
Create(string) (Database, bool)
// Shutter shuts down the factory. Subsequent calls to Create() will fail.
Shutter()
@@ -14,11 +14,11 @@ type localFactory struct {
cf chunks.Factory
}
func (lf *localFactory) Create(ns string) (DataStore, bool) {
func (lf *localFactory) Create(ns string) (Database, bool) {
if cs := lf.cf.CreateStore(ns); cs != nil {
return newLocalDataStore(cs), true
return newLocalDatabase(cs), true
}
return &LocalDataStore{}, false
return &LocalDatabase{}, false
}
func (lf *localFactory) Shutter() {
+50
View File
@@ -0,0 +1,50 @@
package datas
import (
"github.com/attic-labs/noms/chunks"
"github.com/attic-labs/noms/ref"
"github.com/attic-labs/noms/types"
)
// Database provides versioned storage for noms values. Each Database instance represents one moment in history. Heads() returns the Commit from each active fork at that moment. The Commit() method returns a new Database, representing a new moment in history.
type LocalDatabase struct {
cch *cachingChunkHaver
databaseCommon
}
func newLocalDatabase(cs chunks.ChunkStore) *LocalDatabase {
return &LocalDatabase{
newCachingChunkHaver(cs),
newDatabaseCommon(types.NewValueStore(types.NewBatchStoreAdaptor(cs)), cs),
}
}
func (lds *LocalDatabase) Commit(datasetID string, commit types.Struct) (Database, error) {
err := lds.commit(datasetID, commit)
lds.vs.Flush()
return &LocalDatabase{
lds.cch,
newDatabaseCommon(lds.vs, lds.rt),
}, err
}
func (lds *LocalDatabase) Delete(datasetID string) (Database, error) {
err := lds.doDelete(datasetID)
lds.vs.Flush()
return &LocalDatabase{
lds.cch,
newDatabaseCommon(lds.vs, lds.rt),
}, err
}
func (lds *LocalDatabase) has(r ref.Ref) bool {
return lds.cch.Has(r)
}
func (lds *LocalDatabase) batchSink() batchSink {
return lds.vs.BatchStore()
}
func (lds *LocalDatabase) batchStore() types.BatchStore {
return lds.vs.BatchStore()
}
-50
View File
@@ -1,50 +0,0 @@
package datas
import (
"github.com/attic-labs/noms/chunks"
"github.com/attic-labs/noms/ref"
"github.com/attic-labs/noms/types"
)
// DataStore provides versioned storage for noms values. Each DataStore instance represents one moment in history. Heads() returns the Commit from each active fork at that moment. The Commit() method returns a new DataStore, representing a new moment in history.
type LocalDataStore struct {
cch *cachingChunkHaver
dataStoreCommon
}
func newLocalDataStore(cs chunks.ChunkStore) *LocalDataStore {
return &LocalDataStore{
newCachingChunkHaver(cs),
newDataStoreCommon(types.NewValueStore(types.NewBatchStoreAdaptor(cs)), cs),
}
}
func (lds *LocalDataStore) Commit(datasetID string, commit types.Struct) (DataStore, error) {
err := lds.commit(datasetID, commit)
lds.vs.Flush()
return &LocalDataStore{
lds.cch,
newDataStoreCommon(lds.vs, lds.rt),
}, err
}
func (lds *LocalDataStore) Delete(datasetID string) (DataStore, error) {
err := lds.doDelete(datasetID)
lds.vs.Flush()
return &LocalDataStore{
lds.cch,
newDataStoreCommon(lds.vs, lds.rt),
}, err
}
func (lds *LocalDataStore) has(r ref.Ref) bool {
return lds.cch.Has(r)
}
func (lds *LocalDataStore) batchSink() batchSink {
return lds.vs.BatchStore()
}
func (lds *LocalDataStore) batchStore() types.BatchStore {
return lds.vs.BatchStore()
}
+3 -3
View File
@@ -9,7 +9,7 @@ import (
)
// CopyMissingChunksP copies to |sink| all chunks in source that are reachable from (and including) |r|, skipping chunks that |sink| already has
func CopyMissingChunksP(source DataStore, sink *LocalDataStore, sourceRef types.Ref, concurrency int) {
func CopyMissingChunksP(source Database, sink *LocalDatabase, sourceRef types.Ref, concurrency int) {
copyCallback := func(r types.Ref) bool {
return sink.has(r.TargetRef())
}
@@ -17,7 +17,7 @@ func CopyMissingChunksP(source DataStore, sink *LocalDataStore, sourceRef types.
}
// CopyReachableChunksP copies to |sink| all chunks reachable from (and including) |r|, but that are not in the subtree rooted at |exclude|
func CopyReachableChunksP(source, sink DataStore, sourceRef, exclude types.Ref, concurrency int) {
func CopyReachableChunksP(source, sink Database, sourceRef, exclude types.Ref, concurrency int) {
excludeRefs := map[ref.Ref]bool{}
if !exclude.TargetRef().IsEmpty() {
@@ -38,7 +38,7 @@ func CopyReachableChunksP(source, sink DataStore, sourceRef, exclude types.Ref,
copyWorker(source, sink, sourceRef, copyCallback, concurrency)
}
func copyWorker(source DataStore, sink DataStore, sourceRef types.Ref, stopFn walk.SomeChunksCallback, concurrency int) {
func copyWorker(source Database, sink Database, sourceRef types.Ref, stopFn walk.SomeChunksCallback, concurrency int) {
bs := sink.batchSink()
walk.SomeChunksP(sourceRef, newTeeDataSource(source.batchStore(), bs), stopFn, concurrency)
+59
View File
@@ -0,0 +1,59 @@
package datas
import (
"github.com/attic-labs/noms/types"
"github.com/julienschmidt/httprouter"
)
// Database provides versioned storage for noms values. Each Database instance represents one moment in history. Heads() returns the Commit from each active fork at that moment. The Commit() method returns a new Database, representing a new moment in history.
type RemoteDatabaseClient struct {
databaseCommon
}
func NewRemoteDatabase(baseURL, auth string) *RemoteDatabaseClient {
httpBS := newHTTPBatchStore(baseURL, auth)
return &RemoteDatabaseClient{newDatabaseCommon(types.NewValueStore(httpBS), httpBS)}
}
func (rds *RemoteDatabaseClient) batchSink() batchSink {
httpBS := rds.vs.BatchStore().(*httpBatchStore)
return newNotABatchSink(httpBS.host, httpBS.auth)
}
func (rds *RemoteDatabaseClient) batchStore() types.BatchStore {
return rds.vs.BatchStore()
}
func (rds *RemoteDatabaseClient) Commit(datasetID string, commit types.Struct) (Database, error) {
err := rds.commit(datasetID, commit)
rds.vs.Flush()
return &RemoteDatabaseClient{newDatabaseCommon(rds.vs, rds.rt)}, err
}
func (rds *RemoteDatabaseClient) Delete(datasetID string) (Database, error) {
err := rds.doDelete(datasetID)
rds.vs.Flush()
return &RemoteDatabaseClient{newDatabaseCommon(rds.vs, rds.rt)}, err
}
func (f RemoteStoreFactory) CreateStore(ns string) Database {
return NewRemoteDatabase(f.host+httprouter.CleanPath(ns), f.auth)
}
func (f RemoteStoreFactory) Create(ns string) (Database, bool) {
if ds := f.CreateStore(ns); ds != nil {
return ds, true
}
return &LocalDatabase{}, false
}
func (f RemoteStoreFactory) Shutter() {}
func NewRemoteStoreFactory(host, auth string) Factory {
return RemoteStoreFactory{host: host, auth: auth}
}
type RemoteStoreFactory struct {
host string
auth string
}
@@ -22,7 +22,7 @@ import (
func TestHandleWriteValue(t *testing.T) {
assert := assert.New(t)
cs := chunks.NewTestStore()
ds := NewDataStore(cs)
ds := NewDatabase(cs)
l := types.NewList(
ds.WriteValue(types.Bool(true)),
@@ -47,7 +47,7 @@ func TestHandleWriteValue(t *testing.T) {
HandleWriteValue(w, &http.Request{Body: ioutil.NopCloser(body), Method: "POST"}, params{}, cs)
if assert.Equal(http.StatusCreated, w.Code, "Handler error:\n%s", string(w.Body.Bytes())) {
ds2 := NewDataStore(cs)
ds2 := NewDatabase(cs)
v := ds2.ReadValue(l2.Ref())
if assert.NotNil(v) {
assert.True(v.Equals(l2), "%+v != %+v", v, l2)
@@ -58,7 +58,7 @@ func TestHandleWriteValue(t *testing.T) {
func TestHandleWriteValueBackpressure(t *testing.T) {
assert := assert.New(t)
cs := &backpressureCS{ChunkStore: chunks.NewMemoryStore()}
ds := NewDataStore(cs)
ds := NewDatabase(cs)
l := types.NewList(
ds.WriteValue(types.Bool(true)),
-59
View File
@@ -1,59 +0,0 @@
package datas
import (
"github.com/attic-labs/noms/types"
"github.com/julienschmidt/httprouter"
)
// DataStore provides versioned storage for noms values. Each DataStore instance represents one moment in history. Heads() returns the Commit from each active fork at that moment. The Commit() method returns a new DataStore, representing a new moment in history.
type RemoteDataStoreClient struct {
dataStoreCommon
}
func NewRemoteDataStore(baseURL, auth string) *RemoteDataStoreClient {
httpBS := newHTTPBatchStore(baseURL, auth)
return &RemoteDataStoreClient{newDataStoreCommon(types.NewValueStore(httpBS), httpBS)}
}
func (rds *RemoteDataStoreClient) batchSink() batchSink {
httpBS := rds.vs.BatchStore().(*httpBatchStore)
return newNotABatchSink(httpBS.host, httpBS.auth)
}
func (rds *RemoteDataStoreClient) batchStore() types.BatchStore {
return rds.vs.BatchStore()
}
func (rds *RemoteDataStoreClient) Commit(datasetID string, commit types.Struct) (DataStore, error) {
err := rds.commit(datasetID, commit)
rds.vs.Flush()
return &RemoteDataStoreClient{newDataStoreCommon(rds.vs, rds.rt)}, err
}
func (rds *RemoteDataStoreClient) Delete(datasetID string) (DataStore, error) {
err := rds.doDelete(datasetID)
rds.vs.Flush()
return &RemoteDataStoreClient{newDataStoreCommon(rds.vs, rds.rt)}, err
}
func (f RemoteStoreFactory) CreateStore(ns string) DataStore {
return NewRemoteDataStore(f.host+httprouter.CleanPath(ns), f.auth)
}
func (f RemoteStoreFactory) Create(ns string) (DataStore, bool) {
if ds := f.CreateStore(ns); ds != nil {
return ds, true
}
return &LocalDataStore{}, false
}
func (f RemoteStoreFactory) Shutter() {}
func NewRemoteStoreFactory(host, auth string) Factory {
return RemoteStoreFactory{host: host, auth: auth}
}
type RemoteStoreFactory struct {
host string
auth string
}
+7 -7
View File
@@ -7,16 +7,16 @@ import (
)
type Dataset struct {
store datas.DataStore
store datas.Database
id string
}
func NewDataset(store datas.DataStore, datasetID string) Dataset {
func NewDataset(store datas.Database, datasetID string) Dataset {
d.Exp.NotEmpty(datasetID, "Cannot create an unnamed Dataset.")
return Dataset{store, datasetID}
}
func (ds *Dataset) Store() datas.DataStore {
func (ds *Dataset) Store() datas.Database {
return ds.store
}
@@ -65,12 +65,12 @@ func (ds *Dataset) CommitWithParents(v types.Value, p types.Set) (Dataset, error
return Dataset{store, ds.id}, err
}
func (ds *Dataset) Pull(sourceStore datas.DataStore, sourceRef types.Ref, concurrency int) (Dataset, error) {
_, topDown := ds.Store().(*datas.LocalDataStore)
func (ds *Dataset) Pull(sourceStore datas.Database, sourceRef types.Ref, concurrency int) (Dataset, error) {
_, topDown := ds.Store().(*datas.LocalDatabase)
return ds.pull(sourceStore, sourceRef, concurrency, topDown)
}
func (ds *Dataset) pull(source datas.DataStore, sourceRef types.Ref, concurrency int, topDown bool) (Dataset, error) {
func (ds *Dataset) pull(source datas.Database, sourceRef types.Ref, concurrency int, topDown bool) (Dataset, error) {
sink := *ds
sinkHeadRef := types.Ref{}
@@ -83,7 +83,7 @@ func (ds *Dataset) pull(source datas.DataStore, sourceRef types.Ref, concurrency
}
if topDown {
datas.CopyMissingChunksP(source, sink.Store().(*datas.LocalDataStore), sourceRef, concurrency)
datas.CopyMissingChunksP(source, sink.Store().(*datas.LocalDatabase), sourceRef, concurrency)
} else {
datas.CopyReachableChunksP(source, sink.Store(), sourceRef, sinkHeadRef, concurrency)
}
+3 -3
View File
@@ -15,12 +15,12 @@ func TestDatasetCommitTracker(t *testing.T) {
id2 := "othertestdataset"
cs := chunks.NewMemoryStore()
ds1 := NewDataset(datas.NewDataStore(cs), id1)
ds1 := NewDataset(datas.NewDatabase(cs), id1)
ds1Commit := types.NewString("Commit value for " + id1)
ds1, err := ds1.Commit(ds1Commit)
assert.NoError(err)
ds2 := NewDataset(datas.NewDataStore(cs), id2)
ds2 := NewDataset(datas.NewDatabase(cs), id2)
ds2Commit := types.NewString("Commit value for " + id2)
ds2, err = ds2.Commit(ds2Commit)
assert.NoError(err)
@@ -34,7 +34,7 @@ func TestDatasetCommitTracker(t *testing.T) {
}
func newDS(id string, cs *chunks.MemoryStore) Dataset {
store := datas.NewDataStore(cs)
store := datas.NewDatabase(cs)
return NewDataset(store, id)
}
+1 -1
View File
@@ -10,7 +10,7 @@ import (
)
func createTestDataset(name string) Dataset {
return NewDataset(datas.NewDataStore(chunks.NewTestStore()), name)
return NewDataset(datas.NewDatabase(chunks.NewTestStore()), name)
}
func TestValidateRef(t *testing.T) {
+14 -14
View File
@@ -23,40 +23,40 @@ Then launch Node so that we can have a play:
node
```
## [DataStore](TODO-link-to-DataStore-API)
## [Database](TODO-link-to-Database-API)
In Noms, data is represented as trees of immutable *values*. For example, the number `42` is a value. The string `'hello, world'` is a value. The set of all photos from the Hubble space telescope is a value, and each of those photos is also a value.
A DataStore is a place where you can store Noms values. To do anything with Noms, you will first need to create an instance of a DataStore:
A Database is a place where you can store Noms values. To do anything with Noms, you will first need to create an instance of a Database:
```js
const noms = require('@attic/noms');
// A datastore is backed by a "ChunkStore", which is where the physical chunks of data will be kept
// A database is backed by a "ChunkStore", which is where the physical chunks of data will be kept
// Noms/JS comes with several ChunkStore implementations, including MemoryStore, which is useful
// for testing.
const dataStore = new noms.DataStore(new noms.MemoryStore());
const database = new noms.Database(new noms.MemoryStore());
```
Noms is a [content-addressed](https://en.wikipedia.org/wiki/Content-addressable_storage) datastore. Every noms value has a hash. When you store a value in noms, you get a *Ref* (short for *reference*) to the data back. The Ref encapsulates the value's hash and some other details.
Noms is a [content-addressed](https://en.wikipedia.org/wiki/Content-addressable_storage) database. Every noms value has a hash. When you store a value in noms, you get a *Ref* (short for *reference*) to the data back. The Ref encapsulates the value's hash and some other details.
```js
const ref1 = dataStore.writeValue("Hello, world");
const ref1 = database.writeValue("Hello, world");
ref1.targetRef; // prints: Ref { _refStr: 'sha1-b237e82a5ed084438714743d30dd4900b1327609' }
// prints: Hello, world
dataStore.readValue(ref1.targetRef).then(console.log);
database.readValue(ref1.targetRef).then(console.log);
```
## [Dataset](TODO-link-to-DataSet-API)
A DataStore on its own can only be used to store and retrieve immutable objects by their hash. This has limited utility.
A Database on its own can only be used to store and retrieve immutable objects by their hash. This has limited utility.
If you need to keep track of something that changes over time, you need a [Dataset](TODO). A Dataset is a named pointer to a value that can change:
```
let dataSet = new noms.Dataset(dataStore, "salutation");
let dataSet = new noms.Dataset(database, "salutation");
// prints: null
dataSet.head().then(console.log);
@@ -70,15 +70,15 @@ dataSet
// prints: Hello, world
dataSet
.then(ds => ds.head())
.then(commit => commit.value.targetValue(dataStore))
.then(commit => commit.value.targetValue(database))
.then(console.log);
// prints: Buenos dias
const ref2 = dataStore.writeValue("Buenos dias");
const ref2 = database.writeValue("Buenos dias");
dataSet = dataSet.then(ds => ds.commit(ref2));
dataSet
.then(ds => ds.head())
.then(commit => commit.value.targetValue(dataStore))
.then(commit => commit.value.targetValue(database))
.then(console.log);
```
@@ -89,8 +89,8 @@ A DataSet is versioned. When you *commit* a new value, you aren't overwriting th
dataSet
.then(ds => ds.head())
.then(h => h.parents.first())
.then(rv => rv.targetValue(dataStore))
.then(commit => commit.value.targetValue(dataStore))
.then(rv => rv.targetValue(database))
.then(commit => commit.value.targetValue(database))
.then(console.log);
```
+8 -8
View File
@@ -23,40 +23,40 @@ Then launch Node so that we can have a play:
node
```
## [DataStore](TODO-link-to-DataStore-API)
## [Database](TODO-link-to-Database-API)
In Noms, data is represented as trees of immutable *values*. For example, the number `42` is a value. The string `'Hello, world'` is a value. The set of all photos from the Hubble space telescope is a value, and each of those photos is also a value.
A DataStore is a place where you can store Noms values. To do anything with Noms, you'll need a DataStore:
A Database is a place where you can store Noms values. To do anything with Noms, you'll need a Database:
```js
const noms = require('@attic/noms');
// A datastore is backed by a "ChunkStore", which is where the physical chunks of data will be kept
// A database is backed by a "ChunkStore", which is where the physical chunks of data will be kept
// Noms/JS comes with several ChunkStore implementations, including MemoryStore, which is useful
// for testing.
const dataStore = new noms.DataStore(new noms.MemoryStore());
const database = new noms.Database(new noms.MemoryStore());
```
Noms is [content-addressed](https://en.wikipedia.org/wiki/Content-addressable_storage), meaning that every Noms value is identified by a unique hash. When you store a value, you receive a *Ref* which contains the value's hash, and which can be used to retrieve the value later.
```js
const ref = dataStore.writeValue("Hello, world");
const ref = database.writeValue("Hello, world");
ref.targetHash; // prints: Ref { _refStr: 'sha1-b237e82a5ed084438714743d30dd4900b1327609' }
// prints: Hello, world
dataStore.readValue(ref).then(console.log);
database.readValue(ref).then(console.log);
```
## [Dataset](TODO-link-to-Dataset-API)
A DataStore on its own can only be used to store and retrieve immutable objects.
A Database on its own can only be used to store and retrieve immutable objects.
If you need to keep track of something that changes over time, you need a [Dataset](TODO). A Dataset is a named pointer to a value that can change:
```js
const dataset = new noms.Dataset(dataStore, "salutation");
const dataset = new noms.Dataset(database, "salutation");
// prints: null
dataset.head().then(console.log);
+10 -10
View File
@@ -1,10 +1,10 @@
# Spelling in Noms
Many commands and APIs in Noms accept datastore, dataset, or value specifications as arguments. This document describes how to construct these specifications.
Many commands and APIs in Noms accept database, dataset, or value specifications as arguments. This document describes how to construct these specifications.
## Spelling Datastores
## Spelling Databases
Datastore specifications take the form:
database specifications take the form:
```
<protocol>:<path>
@@ -12,29 +12,29 @@ Datastore specifications take the form:
The `path` part of the name is interpreted differently depending on the protocol:
- **http(s):** specs describe a remote datastore to be accessed over HTTP. In this case, the entire datastore spec is a normal http(s) URL. For example: `https://dev.noms.io/aa`.
- **ldb:** specs describe a local [LevelDB](https://github.com/google/leveldb)-backed datastore. In this case, the path component should be a relative or absolute path on disk to a directory in which to store the LevelDB data. For example: `ldb:~/noms-data`.
- **mem:** specs describe an ephemeral memory-backed datastore. In this case, the path component is not used and must be empty.
- **http(s):** specs describe a remote database to be accessed over HTTP. In this case, the entire database spec is a normal http(s) URL. For example: `https://dev.noms.io/aa`.
- **ldb:** specs describe a local [LevelDB](https://github.com/google/leveldb)-backed database. In this case, the path component should be a relative or absolute path on disk to a directory in which to store the LevelDB data. For example: `ldb:~/noms-data`.
- **mem:** specs describe an ephemeral memory-backed database. In this case, the path component is not used and must be empty.
## Spelling Datasets
Dataset specifications take the form:
```
<datastore>:<dataset>
<database>:<dataset>
```
See [spelling datastores](#spelling-datastores) for how to build the `datastore` part of the name. The `dataset` part is just any string matching the regex `^[a-zA-Z0-9\-_/]+$`.
See [spelling databases](#spelling-databases) for how to build the `database` part of the name. The `dataset` part is just any string matching the regex `^[a-zA-Z0-9\-_/]+$`.
## Spelling Values
Value specifications take the form:
```
<datastore>:<value-name>
<database>:<value-name>
```
See [spelling datastores](#spelling-datastores) for how to build the datastore part of the name.
See [spelling databases](#spelling-databases) for how to build the database part of the name.
The `value-name` part can be either a ref or a dataset name. If `value-name` matches the pattern `^sha1-[0-9a-fA-F]{40}$`, it will be interpreted as a ref. Otherwise it will be interpreted as a dataset name.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@attic/noms",
"version": "25.0.0",
"version": "26.0.0",
"description": "Noms JS SDK",
"repository": "https://github.com/attic-labs/noms",
"main": "dist/commonjs/noms.js",
@@ -4,7 +4,7 @@ import {suite, test} from 'mocha';
import {makeTestingBatchStore} from './batch-store-adaptor.js';
import {emptyRef} from './ref.js';
import {assert} from 'chai';
import {default as DataStore, getDatasTypes, newCommit} from './data-store.js';
import {default as Database, getDatasTypes, newCommit} from './database.js';
import {invariant, notNull} from './assert.js';
import {newList} from './list.js';
import {newMap} from './map.js';
@@ -12,10 +12,10 @@ import {stringType, makeListType, makeRefType, makeSetType} from './type.js';
import {encodeNomsValue} from './encode.js';
import {newSet} from './set.js';
suite('DataStore', () => {
suite('Database', () => {
test('access', async () => {
const bs = makeTestingBatchStore();
const ds = new DataStore(bs);
const ds = new Database(bs);
const input = 'abc';
const c = encodeNomsValue(input);
@@ -31,7 +31,7 @@ suite('DataStore', () => {
test('commit', async () => {
const bs = new makeTestingBatchStore();
let ds = new DataStore(bs);
let ds = new Database(bs);
const datasetID = 'ds1';
const datasets = await ds.datasets();
@@ -41,10 +41,10 @@ suite('DataStore', () => {
const aCommit = await newCommit('a');
const ds2 = await ds.commit(datasetID, aCommit);
// The old datastore still still has no head.
// The old database still still has no head.
assert.isNull(await ds.head(datasetID));
// The new datastore has |a|.
// The new database has |a|.
const aRef = notNull(await ds2.headRef(datasetID));
assert.isTrue(aCommit.ref.equals(aRef.targetRef));
assert.strictEqual(1, aRef.height);
@@ -97,15 +97,15 @@ suite('DataStore', () => {
ds = await ds.commit('otherDs', aCommit);
assert.strictEqual('a', notNull(await ds.head('otherDs')).value);
// Get a fresh datastore, and verify that both datasets are present
const newDs = new DataStore(bs);
// Get a fresh database, and verify that both datasets are present
const newDs = new Database(bs);
assert.strictEqual('d', notNull(await newDs.head(datasetID)).value);
assert.strictEqual('a', notNull(await newDs.head('otherDs')).value);
});
test('concurrency', async () => {
const bs = new makeTestingBatchStore();
let ds = new DataStore(bs);
let ds = new Database(bs);
const datasetID = 'ds1';
// |a|
@@ -118,7 +118,7 @@ suite('DataStore', () => {
assert.strictEqual('b', notNull(await ds.head(datasetID)).value);
// Important to create this here.
let ds2 = new DataStore(bs);
let ds2 = new Database(bs);
// Change 1:
// |a| <- |b| <- |c|
@@ -128,7 +128,7 @@ suite('DataStore', () => {
// Change 2:
// |a| <- |b| <- |e|
// Should be disallowed, DataStore returned by Commit() should have |c| as Head.
// Should be disallowed, Database returned by Commit() should have |c| as Head.
const eCommit = await newCommit('e', [bRef]);
let message = '';
try {
@@ -143,14 +143,14 @@ suite('DataStore', () => {
test('empty datasets', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const datasets = await ds.datasets();
assert.strictEqual(0, datasets.size);
});
test('head', async () => {
const bs = new makeTestingBatchStore();
let ds = new DataStore(bs);
let ds = new Database(bs);
const types = getDatasTypes();
const commit = await newCommit('foo', []);
@@ -159,7 +159,7 @@ suite('DataStore', () => {
const datasets = await newMap(['foo', commitRef], types.commitMapType);
const rootRef = ds.writeValue(datasets).targetRef;
assert.isTrue(await bs.updateRoot(rootRef, emptyRef));
ds = new DataStore(bs); // refresh the datasets
ds = new Database(bs); // refresh the datasets
assert.strictEqual(1, datasets.size);
const fooHead = await ds.head('foo');
@@ -170,7 +170,7 @@ suite('DataStore', () => {
});
test('height of refs', async () => {
const ds = new DataStore(new makeTestingBatchStore());
const ds = new Database(new makeTestingBatchStore());
const v1 = ds.writeValue('hello');
assert.strictEqual(1, v1.height);
@@ -181,7 +181,7 @@ suite('DataStore', () => {
});
test('height of collections', async() => {
const ds = new DataStore(new makeTestingBatchStore());
const ds = new Database(new makeTestingBatchStore());
const setOfStringType = makeSetType(stringType);
const setOfRefOfStringType = makeSetType(makeRefType(stringType));
+5 -5
View File
@@ -63,7 +63,7 @@ export function getDatasTypes(): DatasTypes {
return datasTypes;
}
export default class DataStore {
export default class Database {
_vs: ValueStore;
_rt: RootTracker;
_datasets: Promise<NomsMap<string, RefValue<Commit>>>;
@@ -74,8 +74,8 @@ export default class DataStore {
this._datasets = this._datasetsFromRootRef(bs.getRoot());
}
_clone(vs: ValueStore, rt: RootTracker): DataStore {
const ds = Object.create(DataStore.prototype);
_clone(vs: ValueStore, rt: RootTracker): Database {
const ds = Object.create(Database.prototype);
ds._vs = vs;
ds._rt = rt;
ds._datasets = this._datasetsFromRootRef(rt.getRoot());
@@ -125,7 +125,7 @@ export default class DataStore {
return true;
}
async commit(datasetId: string, commit: Commit): Promise<DataStore> {
async commit(datasetId: string, commit: Commit): Promise<Database> {
const currentRootRefP = this._rt.getRoot();
const datasetsP = this._datasetsFromRootRef(currentRootRefP);
let currentDatasets = await (datasetsP:Promise<NomsMap>);
@@ -158,7 +158,7 @@ export default class DataStore {
}
}
async function getAncestors(commits: NomsSet<RefValue<Commit>>, store: DataStore):
async function getAncestors(commits: NomsSet<RefValue<Commit>>, store: Database):
Promise<NomsSet<RefValue<Commit>>> {
let ancestors = await newSet([], getDatasTypes().commitSetType);
await commits.map(async (commitRef) => {
+4 -4
View File
@@ -4,13 +4,13 @@ import {suite, test} from 'mocha';
import {makeTestingBatchStore} from './batch-store-adaptor.js';
import {assert} from 'chai';
import Dataset from './dataset.js';
import DataStore from './data-store.js';
import Database from './database.js';
import {invariant, notNull} from './assert.js';
suite('Dataset', () => {
test('commit', async () => {
const bs = makeTestingBatchStore();
const store = new DataStore(bs);
const store = new Database(bs);
let ds = new Dataset(store, 'ds1');
// |a|
@@ -53,8 +53,8 @@ suite('Dataset', () => {
ds = await ds.commit('a');
assert.strictEqual('a', notNull(await ds.head('otherDs')).value);
// Get a fresh datastore, and verify that both datasets are present
const newStore = new DataStore(bs);
// Get a fresh database, and verify that both datasets are present
const newStore = new Database(bs);
assert.strictEqual('d', notNull(await newStore.head('ds1')).value);
assert.strictEqual('a', notNull(await newStore.head('otherDs')).value);
});
+5 -5
View File
@@ -1,21 +1,21 @@
// @flow
import {newCommit} from './data-store.js';
import {newCommit} from './database.js';
import type {valueOrPrimitive} from './value.js';
import type {Commit} from './commit.js';
import type DataStore from './data-store.js';
import type Database from './database.js';
import RefValue from './ref-value.js';
export default class Dataset {
_store: DataStore;
_store: Database;
_id: string;
constructor(store: DataStore, id: string) {
constructor(store: Database, id: string) {
this._store = store;
this._id = id;
}
get store(): DataStore {
get store(): Database {
return this._store;
}
+29 -29
View File
@@ -1,7 +1,7 @@
// @flow
import Chunk from './chunk.js';
import DataStore from './data-store.js';
import Database from './database.js';
import {makeTestingBatchStore} from './batch-store-adaptor.js';
import type RefValue from './ref-value.js';
import {default as Struct, StructMirror} from './struct.js';
@@ -52,7 +52,7 @@ suite('Decode', () => {
}
test('read', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = [1, 'hi', true];
const r = new JsonArrayReader(a, ds);
@@ -67,7 +67,7 @@ suite('Decode', () => {
});
test('read type', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
function doTest(expected: Type, a: Array<any>) {
const r = new JsonArrayReader(a, ds);
const tr = r.readValue();
@@ -86,7 +86,7 @@ suite('Decode', () => {
});
test('read primitives', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
function doTest(expected: any, a: Array<any>): void {
const r = new JsonArrayReader(a, ds);
@@ -106,7 +106,7 @@ suite('Decode', () => {
});
test('read list of number', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = [Kind.List, Kind.Number, false,
[Kind.Number, '0', Kind.Number, '1', Kind.Number, '2', Kind.Number, '3']];
const r = new JsonArrayReader(a, ds);
@@ -120,7 +120,7 @@ suite('Decode', () => {
// TODO: Can't round-trip collections of value types. =-(
test('read list of value', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = [Kind.List, Kind.Value, false,
[Kind.Number, '1', Kind.String, 'hi', Kind.Bool, true]];
const r = new JsonArrayReader(a, ds);
@@ -135,7 +135,7 @@ suite('Decode', () => {
});
test('read value list of number', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = [Kind.Value, Kind.List, Kind.Number, false,
[Kind.Number, '0', Kind.Number, '1', Kind.Number, '2']];
const r = new JsonArrayReader(a, ds);
@@ -148,7 +148,7 @@ suite('Decode', () => {
});
test('read compound list', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const ltr = makeListType(numberType);
const r1 = ds.writeValue(new NomsList(ltr, new ListLeafSequence(ds, ltr, [0])));
const r2 = ds.writeValue(new NomsList(ltr, new ListLeafSequence(ds, ltr, [1, 2])));
@@ -174,7 +174,7 @@ suite('Decode', () => {
});
test('read map of number to number', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[MapKind, NumberKind, NumberKind, false,
[NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`);
@@ -188,7 +188,7 @@ suite('Decode', () => {
});
test('read map of ref to number', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const rv1 = ds.writeValue(true);
const rv2 = ds.writeValue('hi');
const a = [
@@ -210,7 +210,7 @@ suite('Decode', () => {
});
test('read value map of number to number', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[ValueKind, MapKind, NumberKind, NumberKind, false,
[NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`);
const r = new JsonArrayReader(a, ds);
@@ -223,7 +223,7 @@ suite('Decode', () => {
});
test('read set of number', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[SetKind, NumberKind, false,
[NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`);
const r = new JsonArrayReader(a, ds);
@@ -236,7 +236,7 @@ suite('Decode', () => {
});
test('read compound set', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const ltr = makeSetType(numberType);
const r1 = ds.writeValue(new NomsSet(ltr, new SetLeafSequence(ds, ltr, [0, 1])));
const r2 = ds.writeValue(new NomsSet(ltr, new SetLeafSequence(ds, ltr, [2, 3, 4])));
@@ -259,7 +259,7 @@ suite('Decode', () => {
});
test('read value set of number', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[ValueKind, SetKind, NumberKind, false,
[NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`);
const r = new JsonArrayReader(a, ds);
@@ -283,7 +283,7 @@ suite('Decode', () => {
}
test('test read struct', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeStructType('A1', {
'x': numberType,
's': stringType,
@@ -303,7 +303,7 @@ suite('Decode', () => {
});
test('test read struct with list', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const ltr = makeListType(numberType);
const tr = makeStructType('A4', {
'b': boolType,
@@ -335,7 +335,7 @@ suite('Decode', () => {
});
test('test read struct with value', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeStructType('A5', {
'b': boolType,
'v': valueType,
@@ -364,7 +364,7 @@ suite('Decode', () => {
});
test('test read value struct', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeStructType('A1', {
'x': numberType,
's': stringType,
@@ -393,7 +393,7 @@ suite('Decode', () => {
});
test('test read map of string to struct', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeStructType('s', {
'b': boolType,
'i': numberType,
@@ -421,11 +421,11 @@ suite('Decode', () => {
});
test('decodeNomsValue', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const chunk = Chunk.fromString(
`t [${Kind.Value},${Kind.Set},${Kind.Number},false,[${Kind.Number},"0",${
Kind.Number},"1",${Kind.Number},"2",${Kind.Number},"3"]]`);
const v = decodeNomsValue(chunk, new DataStore(makeTestingBatchStore()));
const v = decodeNomsValue(chunk, new Database(makeTestingBatchStore()));
invariant(v instanceof NomsSet);
const t = makeSetType(numberType);
@@ -436,7 +436,7 @@ suite('Decode', () => {
test('decodeNomsValue: counter with one commit', async () => {
const bs = makeTestingBatchStore();
const ds = new DataStore(bs);
const ds = new Database(bs);
const makeChunk = a => Chunk.fromString(`t ${JSON.stringify(a)}`);
@@ -486,7 +486,7 @@ suite('Decode', () => {
test('out of line blob', async () => {
const chunk = Chunk.fromString('b hi');
const blob = decodeNomsValue(chunk, new DataStore(makeTestingBatchStore()));
const blob = decodeNomsValue(chunk, new Database(makeTestingBatchStore()));
invariant(blob instanceof NomsBlob);
const r = await blob.getReader().read();
assert.isFalse(r.done);
@@ -504,7 +504,7 @@ suite('Decode', () => {
}
const chunk2 = new Chunk(data);
const blob2 = decodeNomsValue(chunk2, new DataStore(makeTestingBatchStore()));
const blob2 = decodeNomsValue(chunk2, new Database(makeTestingBatchStore()));
invariant(blob2 instanceof NomsBlob);
const r2 = await blob2.getReader().read();
assert.isFalse(r2.done);
@@ -514,7 +514,7 @@ suite('Decode', () => {
});
test('inline blob', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[
ListKind, BlobKind, false, [BlobKind, false, "%s", BlobKind, false, "%s"]
]`, encodeBase64(stringToUint8Array('hello')), encodeBase64(stringToUint8Array('world')));
@@ -531,7 +531,7 @@ suite('Decode', () => {
});
test('compound blob', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const r1 = ds.writeValue(await newBlob(stringToUint8Array('hi')));
const r2 = ds.writeValue(await newBlob(stringToUint8Array('world')));
@@ -554,7 +554,7 @@ suite('Decode', () => {
});
test('recursive struct', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
// struct A {
// b: struct B {
@@ -607,7 +607,7 @@ suite('Decode', () => {
});
test('read union list', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[ListKind, UnionKind, 2, StringKind, NumberKind,
false, [StringKind, "hi", NumberKind, "42"]]`);
const r = new JsonArrayReader(a, ds);
@@ -618,7 +618,7 @@ suite('Decode', () => {
});
test('read empty union list', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[ListKind, UnionKind, 0, false, []]`);
const r = new JsonArrayReader(a, ds);
const v = r.readValue();
+22 -22
View File
@@ -29,13 +29,13 @@ import {ListLeafSequence, NomsList} from './list.js';
import {MapLeafSequence, NomsMap} from './map.js';
import {NomsSet, SetLeafSequence} from './set.js';
import {newBlob} from './blob.js';
import DataStore from './data-store.js';
import Database from './database.js';
import type {valueOrPrimitive} from './value.js';
suite('Encode', () => {
test('write primitives', () => {
function f(k: NomsKind, v: valueOrPrimitive, ex: valueOrPrimitive) {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
w.writeValue(v);
assert.deepEqual([k, ex], w.array);
@@ -54,7 +54,7 @@ suite('Encode', () => {
});
test('write simple blob', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const blob = await newBlob(new Uint8Array([0x00, 0x01]));
w.writeValue(blob);
@@ -62,7 +62,7 @@ suite('Encode', () => {
});
test('write list', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const tr = makeListType(numberType);
@@ -73,7 +73,7 @@ suite('Encode', () => {
});
test('write list of value', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const tr = makeListType(valueType);
@@ -88,7 +88,7 @@ suite('Encode', () => {
});
test('write list of list', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const it = makeListType(numberType);
@@ -105,7 +105,7 @@ suite('Encode', () => {
});
test('write leaf set', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const tr = makeSetType(numberType);
@@ -116,7 +116,7 @@ suite('Encode', () => {
});
test('write compound set', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const ltr = makeSetType(numberType);
const r1 = ds.writeValue(new NomsSet(ltr, new SetLeafSequence(ds, ltr, [0])));
@@ -140,7 +140,7 @@ suite('Encode', () => {
});
test('write set of set', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const st = makeSetType(numberType);
@@ -158,7 +158,7 @@ suite('Encode', () => {
});
test('write map', async() => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const tr = makeMapType(stringType, boolType);
@@ -170,7 +170,7 @@ suite('Encode', () => {
});
test('write map of map', async() => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const kt = makeMapType(stringType, numberType);
@@ -190,7 +190,7 @@ suite('Encode', () => {
});
test('write empty struct', async() => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const type = makeStructType('S', {});
@@ -201,7 +201,7 @@ suite('Encode', () => {
});
test('write struct', async() => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const type = makeStructType('S', {
@@ -217,7 +217,7 @@ suite('Encode', () => {
});
test('write struct with list', async() => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
let w = new JsonArrayWriter(ds);
const ltr = makeListType(stringType);
@@ -238,7 +238,7 @@ suite('Encode', () => {
});
test('write struct with struct', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const s2Type = makeStructType('S2', {
@@ -256,7 +256,7 @@ suite('Encode', () => {
});
test('write compound list', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const ltr = makeListType(numberType);
const r1 = ds.writeValue(new NomsList(ltr, new ListLeafSequence(ds, ltr, [0])));
@@ -280,7 +280,7 @@ suite('Encode', () => {
});
test('write compound set with bool', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const str = makeSetType(boolType);
const r1 = ds.writeValue(new NomsSet(str, new SetLeafSequence(ds, str, [true])));
@@ -301,7 +301,7 @@ suite('Encode', () => {
});
test('write type value', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const test = (expected: Array<any>, v: Type) => {
const w = new JsonArrayWriter(ds);
@@ -349,7 +349,7 @@ suite('Encode', () => {
return bytes;
}
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const blob = await newBlob(stringToUint8Array('hi'));
const chunk = encodeNomsValue(blob, ds);
@@ -372,7 +372,7 @@ suite('Encode', () => {
});
test('write ref', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const ref = Ref.parse('sha1-0123456789abcdef0123456789abcdef01234567');
const t = makeRefType(blobType);
@@ -383,7 +383,7 @@ suite('Encode', () => {
});
test('write union list', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const tr = makeListType(makeUnionType([stringType, numberType]));
const v = new NomsList(tr, new ListLeafSequence(ds, tr, ['hi', 42]));
@@ -393,7 +393,7 @@ suite('Encode', () => {
});
test('write empty union list', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const tr = makeListType(makeUnionType([]));
const v = new NomsList(tr, new ListLeafSequence(ds, tr, []));
+6 -6
View File
@@ -3,7 +3,7 @@
import {assert} from 'chai';
import {suite, test} from 'mocha';
import DataStore from './data-store.js';
import Database from './database.js';
import {makeTestingBatchStore} from './batch-store-adaptor.js';
import RefValue from './ref-value.js';
import {newStruct} from './struct.js';
@@ -207,7 +207,7 @@ suite('List', () => {
});
test('LONG: write, read, modify, read', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const nums = intSequence(testListSize);
const tr = makeListType(numberType);
@@ -227,14 +227,14 @@ suite('List', () => {
suite('ListLeafSequence', () => {
test('Empty list isEmpty', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeListType(stringType);
const newList = items => new NomsList(tr, new ListLeafSequence(ds, tr, items));
assert.isTrue(newList([]).isEmpty());
});
test('iterator', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeListType(numberType);
const test = async items => {
@@ -249,7 +249,7 @@ suite('ListLeafSequence', () => {
});
test('iteratorAt', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeListType(numberType);
const test = async items => {
@@ -269,7 +269,7 @@ suite('ListLeafSequence', () => {
suite('CompoundList', () => {
function build(): NomsList {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeListType(stringType);
const l1 = new NomsList(tr, new ListLeafSequence(ds, tr, ['a', 'b']));
const r1 = ds.writeValue(l1);
+20 -20
View File
@@ -3,7 +3,7 @@
import {assert} from 'chai';
import {suite, test} from 'mocha';
import DataStore from './data-store';
import Database from './database.js';
import MemoryStore from './memory-store.js';
import RefValue from './ref-value.js';
import BatchStore from './batch-store.js';
@@ -170,7 +170,7 @@ suite('BuildMap', () => {
});
test('LONG: write, read, modify, read', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const kvs = [];
for (let i = 0; i < testMapSize; i++) {
@@ -199,7 +199,7 @@ suite('BuildMap', () => {
suite('MapLeaf', () => {
test('isEmpty/size', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeMapType(stringType, boolType);
const newMap = entries => new NomsMap(tr, new MapLeafSequence(ds, tr, entries));
let m = newMap([]);
@@ -211,7 +211,7 @@ suite('MapLeaf', () => {
});
test('has', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeMapType(stringType, boolType);
const m = new NomsMap(tr,
new MapLeafSequence(ds, tr, [{key: 'a', value: false}, {key: 'k', value: true}]));
@@ -222,7 +222,7 @@ suite('MapLeaf', () => {
});
test('first/last/get', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeMapType(stringType, numberType);
const m = new NomsMap(tr,
new MapLeafSequence(ds, tr, [{key: 'a', value: 4}, {key: 'k', value: 8}]));
@@ -237,7 +237,7 @@ suite('MapLeaf', () => {
});
test('forEach', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeMapType(stringType, numberType);
const m = new NomsMap(tr,
new MapLeafSequence(ds, tr, [{key: 'a', value: 4}, {key: 'k', value: 8}]));
@@ -248,7 +248,7 @@ suite('MapLeaf', () => {
});
test('iterator', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeMapType(stringType, numberType);
const test = async entries => {
@@ -263,7 +263,7 @@ suite('MapLeaf', () => {
});
test('LONG: iteratorAt', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeMapType(stringType, numberType);
const build = entries => new NomsMap(tr, new MapLeafSequence(ds, tr, entries));
@@ -287,7 +287,7 @@ suite('MapLeaf', () => {
});
function testChunks(keyType: Type, valueType: Type) {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeMapType(keyType, valueType);
const r1 = ds.writeValue('x');
const r2 = ds.writeValue(true);
@@ -341,14 +341,14 @@ suite('CompoundMap', () => {
}
test('isEmpty/size', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
assert.isFalse(c.isEmpty());
assert.strictEqual(8, c.size);
});
test('get', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
assert.strictEqual(false, await c.get('a'));
@@ -368,7 +368,7 @@ suite('CompoundMap', () => {
});
test('first/last/has', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c, m1, m2] = build(ds);
assert.deepEqual(['a', false], await c.first());
@@ -395,7 +395,7 @@ suite('CompoundMap', () => {
});
test('forEach', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const kv = [];
@@ -405,7 +405,7 @@ suite('CompoundMap', () => {
});
test('iterator', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const expected = [{key: 'a', value: false}, {key: 'b', value: false}, {key: 'e', value: true},
{key: 'f', value: true}, {key: 'h', value: false}, {key: 'i', value: true},
@@ -415,7 +415,7 @@ suite('CompoundMap', () => {
});
test('LONG: iteratorAt', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const entries = [{key: 'a', value: false}, {key: 'b', value: false}, {key: 'e', value: true},
{key: 'f', value: true}, {key: 'h', value: false}, {key: 'i', value: true},
@@ -439,7 +439,7 @@ suite('CompoundMap', () => {
});
test('iterator return', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const iter = c.iterator();
const values = [];
@@ -455,7 +455,7 @@ suite('CompoundMap', () => {
});
test('iterator return parallel', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const iter = c.iterator();
const values = await Promise.all([iter.next(), iter.next(), iter.return(), iter.next()]);
@@ -466,7 +466,7 @@ suite('CompoundMap', () => {
});
test('chunks', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
assert.strictEqual(2, c.chunks.length);
});
@@ -504,7 +504,7 @@ suite('CompoundMap', () => {
}
const ms = new CountingMemoryStore();
const ds = new DataStore(new BatchStore(3, new BatchStoreAdaptorDelegate(ms)));
const ds = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms)));
[m1, m2] = await Promise.all([m1, m2].map(s => ds.readValue(ds.writeValue(s).targetRef)));
assert.deepEqual([[], [], []], await m1.diff(m1));
@@ -554,7 +554,7 @@ suite('CompoundMap', () => {
test('LONG: random map diff 0.1/0.9/0', () => testRandomDiff(randomMapSize, 0.1, 0.9, 0));
test('chunks', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const m = build(ds)[1];
const chunks = m.chunks;
const sequence = m.sequence;
+3 -3
View File
@@ -4,7 +4,7 @@ import {assert} from 'chai';
import {suite, test} from 'mocha';
import {makeTestingBatchStore} from './batch-store-adaptor.js';
import DataStore from './data-store.js';
import Database from './database.js';
import {ListLeafSequence} from './list.js';
import {
makeListType,
@@ -21,7 +21,7 @@ suite('MetaSequence', () => {
const listOfStringType = makeListType(stringType);
test('calculate ordered sequence MetaTuple height', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const seq1 = new SetLeafSequence(ds, setOfStringType, ['bar', 'baz']);
const seq2 = new SetLeafSequence(ds, setOfStringType, ['foo', 'qux', 'zoo']);
@@ -41,7 +41,7 @@ suite('MetaSequence', () => {
});
test('calculate indexed sequence MetaTuple height', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const seq1 = new ListLeafSequence(ds, listOfStringType, ['bar', 'baz']);
const seq2 = new ListLeafSequence(ds, listOfStringType, ['foo', 'qux', 'zoo']);
+2 -2
View File
@@ -1,7 +1,7 @@
// @flow
export {AsyncIterator} from './async-iterator.js';
export {default as DataStore, newCommit} from './data-store.js';
export {default as Database, newCommit} from './database.js';
export {default as Dataset} from './dataset.js';
export {newBlob, NomsBlob, BlobReader, BlobWriter} from './blob.js';
export {decodeNomsValue} from './decode.js';
@@ -45,7 +45,7 @@ export {
getTypeOfValue,
} from './type.js';
export {equals, less} from './compare.js';
export {DataStoreSpec, DatasetSpec, RefSpec, parseObjectSpec} from './specs.js';
export {DatabaseSpec, DatasetSpec, RefSpec, parseObjectSpec} from './specs.js';
export {default as walk} from './walk.js';
export type {AsyncIteratorResult} from './async-iterator.js';
+24 -24
View File
@@ -4,7 +4,7 @@ import {assert} from 'chai';
import {suite, test} from 'mocha';
import Chunk from './chunk.js';
import DataStore from './data-store.js';
import Database from './database.js';
import MemoryStore from './memory-store.js';
import RefValue from './ref-value.js';
import BatchStore from './batch-store.js';
@@ -134,7 +134,7 @@ suite('BuildSet', () => {
});
test('LONG: write, read, modify, read', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const nums = firstNNumbers(testSetSize);
const tr = makeSetType(numberType);
@@ -158,7 +158,7 @@ suite('BuildSet', () => {
suite('SetLeaf', () => {
test('isEmpty/size', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeSetType(stringType);
const newSet = items => new NomsSet(tr, new SetLeafSequence(ds, tr, items));
let s = newSet([]);
@@ -170,7 +170,7 @@ suite('SetLeaf', () => {
});
test('first/last/has', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeSetType(stringType);
const s = new NomsSet(tr, new SetLeafSequence(ds, tr, ['a', 'k']));
@@ -184,7 +184,7 @@ suite('SetLeaf', () => {
});
test('forEach', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeSetType(stringType);
const m = new NomsSet(tr, new SetLeafSequence(ds, tr, ['a', 'b']));
@@ -194,7 +194,7 @@ suite('SetLeaf', () => {
});
test('iterator', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeSetType(stringType);
const test = async items => {
@@ -209,7 +209,7 @@ suite('SetLeaf', () => {
});
test('LONG: iteratorAt', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeSetType(stringType);
const build = items => new NomsSet(tr, new SetLeafSequence(ds, tr, items));
@@ -227,7 +227,7 @@ suite('SetLeaf', () => {
});
function testChunks(elemType: Type) {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeSetType(elemType);
const r1 = ds.writeValue('x');
const r2 = ds.writeValue('a');
@@ -277,14 +277,14 @@ suite('CompoundSet', () => {
}
test('isEmpty/size', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
assert.isFalse(c.isEmpty());
assert.strictEqual(8, c.size);
});
test('first/last/has', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
assert.strictEqual('a', await c.first());
assert.strictEqual('n', await c.last());
@@ -305,7 +305,7 @@ suite('CompoundSet', () => {
});
test('forEach', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const values = [];
await c.forEach((k) => { values.push(k); });
@@ -313,7 +313,7 @@ suite('CompoundSet', () => {
});
test('iterator', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n'];
const c = build(ds, values);
assert.deepEqual(values, await flatten(c.iterator()));
@@ -321,7 +321,7 @@ suite('CompoundSet', () => {
});
test('LONG: iteratorAt', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n'];
const c = build(ds, values);
const offsets = {
@@ -343,7 +343,7 @@ suite('CompoundSet', () => {
});
test('iterator return', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n'];
const c = build(ds, values);
const iter = c.iterator();
@@ -358,7 +358,7 @@ suite('CompoundSet', () => {
});
test('iterator return parallel', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const iter = c.iterator();
const values = await Promise.all([iter.next(), iter.next(), iter.return(), iter.next()]);
@@ -368,20 +368,20 @@ suite('CompoundSet', () => {
});
test('chunks', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
assert.strictEqual(2, c.chunks.length);
});
test('map', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const values = await c.map((k) => k + '*');
assert.deepEqual(['a*', 'b*', 'e*', 'f*', 'h*', 'i*', 'm*', 'n*'], values);
});
test('map async', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const values = await c.map((k) => Promise.resolve(k + '*'));
assert.deepEqual(['a*', 'b*', 'e*', 'f*', 'h*', 'i*', 'm*', 'n*'], values);
@@ -399,7 +399,7 @@ suite('CompoundSet', () => {
}
test('advanceTo', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
@@ -441,7 +441,7 @@ suite('CompoundSet', () => {
});
async function testIntersect(expect: Array<string>, seqs: Array<Array<string>>) {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const first = build(ds, seqs[0]);
const sets:Array<NomsSet> = [];
@@ -470,7 +470,7 @@ suite('CompoundSet', () => {
});
test('iterator at 0', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeSetType(numberType);
const test = async (expected, items) => {
@@ -493,7 +493,7 @@ suite('CompoundSet', () => {
});
test('LONG: canned set diff', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const tr = makeSetType(numberType);
const s1 = await newSet(
firstNNumbers(testSetSize), tr).then(s => ds.readValue(ds.writeValue(s).targetRef));
@@ -547,7 +547,7 @@ suite('CompoundSet', () => {
}
const ms = new CountingMemoryStore();
const ds = new DataStore(new BatchStore(3, new BatchStoreAdaptorDelegate(ms)));
const ds = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms)));
[s1, s2] = await Promise.all([s1, s2].map(s => ds.readValue(ds.writeValue(s).targetRef)));
assert.deepEqual([[], []], await s1.diff(s1));
@@ -586,7 +586,7 @@ suite('CompoundSet', () => {
test('LONG: random set diff 0.1/0.9', () => testRandomDiff(randomSetSize, 0.1, 0.9));
test('chunks', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const s = build(ds, ['a', 'b', 'c', 'd']);
const chunks = s.chunks;
const sequence = s.sequence;
+9 -9
View File
@@ -3,34 +3,34 @@
import {invariant} from './assert.js';
import BatchStoreAdaptor from './batch-store-adaptor.js';
import Dataset from './dataset.js';
import DataStore from './data-store.js';
import Database from './database.js';
import HttpBatchStore from './http-batch-store.js';
import Ref from './ref.js';
import {DataStoreSpec, DatasetSpec, RefSpec, parseObjectSpec} from './specs.js';
import {DatabaseSpec, DatasetSpec, RefSpec, parseObjectSpec} from './specs.js';
import {assert} from 'chai';
import {suite, test} from 'mocha';
suite('Specs', () => {
test('DataStoreSpec', () => {
test('DatabaseSpec', () => {
const notAllowed = ['mem:', 'mem:stuff', 'http:', 'https:', 'random:', 'random:random'];
notAllowed.forEach(s => assert.isNull(DataStoreSpec.parse(s)));
notAllowed.forEach(s => assert.isNull(DatabaseSpec.parse(s)));
let spec = DataStoreSpec.parse('mem');
let spec = DatabaseSpec.parse('mem');
invariant(spec);
assert.equal(spec.scheme, 'mem');
assert.equal(spec.path, '');
assert.instanceOf(spec.store(), DataStore);
assert.instanceOf(spec.store(), Database);
assert.instanceOf(spec.store()._vs._bs, BatchStoreAdaptor);
spec = DataStoreSpec.parse('http://foo');
spec = DatabaseSpec.parse('http://foo');
invariant(spec);
assert.isNotNull(spec);
assert.equal(spec.scheme, 'http');
assert.equal(spec.path, '//foo');
assert.instanceOf(spec.store(), DataStore);
assert.instanceOf(spec.store(), Database);
assert.instanceOf(spec.store()._vs._bs, HttpBatchStore);
spec = DataStoreSpec.parse('https://foo');
spec = DatabaseSpec.parse('https://foo');
invariant(spec);
assert.isNotNull(spec);
assert.equal(spec.scheme, 'https');
+15 -15
View File
@@ -2,22 +2,22 @@
import BatchStoreAdaptor from './batch-store-adaptor.js';
import Dataset from './dataset.js';
import DataStore from './data-store.js';
import Database from './database.js';
import HttpBatchStore from './http-batch-store.js';
import MemoryStore from './memory-store.js';
import Ref from './ref.js';
// A parsed specification for the location of a Noms datastore.
// A parsed specification for the location of a Noms database.
// For example: 'mem:' or 'https://ds.noms.io/aa/music'
//
// See "spelling datastores" for details on supported syntaxes:
// See "spelling databases" for details on supported syntaxes:
// https://docs.google.com/document/d/1QgKcRS304llwU0ECahKtn8lGBFmT5zXzWr-5tah1S_4/edit
export class DataStoreSpec {
export class DatabaseSpec {
scheme: string;
path: string;
// Returns parsed spec, or null if the spec was invalid.
static parse(spec: string): ?DataStoreSpec {
static parse(spec: string): ?DatabaseSpec {
const match = spec.match(/^(.+?)(\:.+)?$/);
if (!match) {
return null;
@@ -46,13 +46,13 @@ export class DataStoreSpec {
this.path = path;
}
// Constructs a new DataStore based on the parsed spec.
store(): DataStore {
// Constructs a new Database based on the parsed spec.
store(): Database {
if (this.scheme === 'mem') {
return new DataStore(new BatchStoreAdaptor(new MemoryStore()));
return new Database(new BatchStoreAdaptor(new MemoryStore()));
}
if (this.scheme === 'http') {
return new DataStore(new HttpBatchStore(`${this.scheme}:${this.path}`));
return new Database(new HttpBatchStore(`${this.scheme}:${this.path}`));
}
throw new Error('Unreached');
}
@@ -64,7 +64,7 @@ export class DataStoreSpec {
// See "spelling datasets" for details on supported syntaxes:
// https://docs.google.com/document/d/1QgKcRS304llwU0ECahKtn8lGBFmT5zXzWr-5tah1S_4/edit
export class DatasetSpec {
store: DataStoreSpec;
store: DatabaseSpec;
name: string;
// Returns a parsed spec, or null if the spec was invalid.
@@ -73,14 +73,14 @@ export class DatasetSpec {
if (!match) {
return null;
}
const store = DataStoreSpec.parse(match[1]);
const store = DatabaseSpec.parse(match[1]);
if (!store) {
return null;
}
return new this(store, match[2]);
}
constructor(store: DataStoreSpec, name: string) {
constructor(store: DatabaseSpec, name: string) {
this.store = store;
this.name = name;
}
@@ -105,7 +105,7 @@ export class DatasetSpec {
// See "spelling objects" for details on supported syntaxes:
// https://docs.google.com/document/d/1QgKcRS304llwU0ECahKtn8lGBFmT5zXzWr-5tah1S_4/edit
export class RefSpec {
store: DataStoreSpec;
store: DatabaseSpec;
ref: Ref;
// Returns a parsed spec, or null if the spec was invalid.
@@ -120,7 +120,7 @@ export class RefSpec {
return null;
}
const store = DataStoreSpec.parse(match[1]);
const store = DatabaseSpec.parse(match[1]);
if (!store) {
return null;
}
@@ -128,7 +128,7 @@ export class RefSpec {
return new this(store, ref);
}
constructor(store: DataStoreSpec, ref: Ref) {
constructor(store: DatabaseSpec, ref: Ref) {
this.store = store;
this.ref = ref;
}
+2 -2
View File
@@ -13,7 +13,7 @@ import {
valueType,
} from './type.js';
import {suite, test} from 'mocha';
import DataStore from './data-store.js';
import Database from './database.js';
import {newList} from './list.js';
suite('Struct', () => {
@@ -31,7 +31,7 @@ suite('Struct', () => {
});
test('chunks', () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const bt = boolType;
const refOfBoolType = makeRefType(bt);
+3 -3
View File
@@ -1,6 +1,6 @@
// @flow
import DataStore from './data-store.js';
import Database from './database.js';
import type {Collection} from './collection.js';
import type {valueOrPrimitive} from './value.js';
import {assert} from 'chai';
@@ -47,10 +47,10 @@ export function assertChunkCountAndType(expectCount: number, expectType: Type,
export async function testRoundTripAndValidate<T: valueOrPrimitive>(v: T,
validateFn: (v2: T) => Promise<void>): Promise<void> {
const bs = makeTestingBatchStore();
const ds = new DataStore(bs);
const ds = new Database(bs);
const r1 = await ds.writeValue(v).targetRef;
const ds2 = new DataStore(bs);
const ds2 = new Database(bs);
const v2 = await ds2.readValue(r1);
if (v instanceof Value) {
+2 -2
View File
@@ -13,11 +13,11 @@ import {
getTypeOfValue,
} from './type.js';
import {suite, test} from 'mocha';
import DataStore from './data-store.js';
import Database from './database.js';
suite('Type', () => {
test('types', async () => {
const ds = new DataStore(makeTestingBatchStore());
const ds = new Database(makeTestingBatchStore());
const mapType = makeMapType(stringType, numberType);
const setType = makeSetType(stringType);
+1 -1
View File
@@ -64,7 +64,7 @@ export default class ValueStore {
// the floor because r already has a hint in the cache. If we later read some other
// chunk that references v, cacheChunks will overwrite this with a hint pointing to that chunk.
// If we don't do this, top-level Values that get read but not written -- such as the
// existing Head of a DataStore upon a Commit -- can be erroneously left out during a pull.
// existing Head of a Database upon a Commit -- can be erroneously left out during a pull.
this._knownRefs.addIfNotPresent(ref, new RefCacheEntry(true, getTypeOfValue(v), ref));
return v;
}
+3 -3
View File
@@ -2,7 +2,7 @@
import BatchStoreAdaptor from './batch-store-adaptor.js';
import {createStructClass} from './struct.js';
import DataStore from './data-store.js';
import Database from './database.js';
import {
makeListType,
makeMapType,
@@ -24,7 +24,7 @@ import {assert} from 'chai';
import type {valueOrPrimitive} from './value.js';
suite('walk', () => {
const ds = new DataStore(new BatchStoreAdaptor(new MemoryStore()));
const ds = new Database(new BatchStoreAdaptor(new MemoryStore()));
test('primitives', async () => {
await Promise.all([true, false, 42, 88.8, 'hello!', ''].map(async v => {
@@ -143,7 +143,7 @@ suite('walk', () => {
});
});
async function callbackHappensOnce(v: valueOrPrimitive, ds: DataStore,
async function callbackHappensOnce(v: valueOrPrimitive, ds: Database,
recurse: bool = false) : Promise<void> {
// Test that our callback only gets called once.
let count = 0;
+2 -2
View File
@@ -7,7 +7,7 @@ import {NomsMap} from './map.js';
import RefValue from './ref-value.js';
import Struct, {StructMirror} from './struct.js';
import type DataStore from './data-store.js';
import type Database from './database.js';
import type {valueOrPrimitive} from './value.js';
// Invokes |cb| once for |v| and each of its descendants. The returned promise is resolved when all
@@ -17,7 +17,7 @@ import type {valueOrPrimitive} from './value.js';
// skip a node's children.
//
// For convenience, if |cb| returns |undefined|, the default is |true|.
export default async function walk(v: valueOrPrimitive, ds: DataStore,
export default async function walk(v: valueOrPrimitive, ds: Database,
cb: (v: valueOrPrimitive) => Promise<?bool>): Promise<void> {
let cont = await cb(v);
if (cont === undefined) {
+2 -2
View File
@@ -10,12 +10,12 @@ import (
"github.com/attic-labs/noms/ref"
)
// ValueReader is an interface that knows how to read Noms Values, e.g. datas/DataStore. Required to avoid import cycle between this package and the package that implements Value reading.
// ValueReader is an interface that knows how to read Noms Values, e.g. datas/Database. Required to avoid import cycle between this package and the package that implements Value reading.
type ValueReader interface {
ReadValue(r ref.Ref) Value
}
// ValueReadWriter is an interface that knows how to read and write Noms Values, e.g. datas/DataStore. Required to avoid import cycle between this package and the package that implements Value read/writing.
// ValueReadWriter is an interface that knows how to read and write Noms Values, e.g. datas/Database. Required to avoid import cycle between this package and the package that implements Value read/writing.
type ValueReadWriter interface {
ValueReader
ValueWriter
+1 -1
View File
@@ -51,7 +51,7 @@ func (lvs *ValueStore) ReadValue(r ref.Ref) Value {
if v != nil {
lvs.cacheChunks(v, r)
// r is trivially a hint for v, so consider putting that in the cache. If we got to v by reading some higher-level chunk, this entry gets dropped on the floor because r already has a hint in the cache. If we later read some other chunk that references v, cacheChunks will overwrite this with a hint pointing to that chunk.
// If we don't do this, top-level Values that get read but not written -- such as the existing Head of a DataStore upon a Commit -- can be erroneously left out during a pull.
// If we don't do this, top-level Values that get read but not written -- such as the existing Head of a Database upon a Commit -- can be erroneously left out during a pull.
entry = hintedChunk{v.Type(), r}
}
if cur := lvs.check(r); cur == nil || cur.Hint().IsEmpty() {
+1 -1
View File
@@ -2,7 +2,7 @@ package types
import "github.com/attic-labs/noms/chunks"
// ValueWriter is an interface that knows how to write Noms Values, e.g. datas/DataStore. Required to avoid import cycle between this package and the package that implements Value writing.
// ValueWriter is an interface that knows how to write Noms Values, e.g. datas/Database. Required to avoid import cycle between this package and the package that implements Value writing.
type ValueWriter interface {
WriteValue(v Value) Ref
}