mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-27 23:47:33 -05:00
Restructure in to subpackages
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
package indexer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type alreadyExistsErr struct {
|
||||
typeName, key, val string
|
||||
}
|
||||
|
||||
func (e *alreadyExistsErr) Error() string {
|
||||
return fmt.Sprintf("%s with %s=%s does already exist", e.typeName, e.key, e.val)
|
||||
}
|
||||
|
||||
func IsAlreadyExistsErr(e error) bool {
|
||||
_, ok := e.(*alreadyExistsErr)
|
||||
return ok
|
||||
}
|
||||
|
||||
type notFoundErr struct {
|
||||
typeName, key, val string
|
||||
}
|
||||
|
||||
func (e *notFoundErr) Error() string {
|
||||
return fmt.Sprintf("%s with %s=%s not found", e.typeName, e.key, e.val)
|
||||
}
|
||||
|
||||
func IsNotFoundErr(e error) bool {
|
||||
_, ok := e.(*notFoundErr)
|
||||
return ok
|
||||
}
|
||||
31
accounts/pkg/indexer/errors/errors.go
Normal file
31
accounts/pkg/indexer/errors/errors.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type AlreadyExistsErr struct {
|
||||
TypeName, Key, Value string
|
||||
}
|
||||
|
||||
func (e *AlreadyExistsErr) Error() string {
|
||||
return fmt.Sprintf("%s with %s=%s does already exist", e.TypeName, e.Key, e.Value)
|
||||
}
|
||||
|
||||
func IsAlreadyExistsErr(e error) bool {
|
||||
_, ok := e.(*AlreadyExistsErr)
|
||||
return ok
|
||||
}
|
||||
|
||||
type NotFoundErr struct {
|
||||
TypeName, Key, Value string
|
||||
}
|
||||
|
||||
func (e *NotFoundErr) Error() string {
|
||||
return fmt.Sprintf("%s with %s=%s not found", e.TypeName, e.Key, e.Value)
|
||||
}
|
||||
|
||||
func IsNotFoundErr(e error) bool {
|
||||
_, ok := e.(*NotFoundErr)
|
||||
return ok
|
||||
}
|
||||
15
accounts/pkg/indexer/index/index.go
Normal file
15
accounts/pkg/indexer/index/index.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package index
|
||||
|
||||
// Index can be implemented to create new indexer-strategies. See Unique for example.
|
||||
// Each indexer implementation is bound to one data-column (IndexBy) and a data-type (TypeName)
|
||||
type Index interface {
|
||||
Init() error
|
||||
Lookup(v string) ([]string, error)
|
||||
Add(id, v string) (string, error)
|
||||
Remove(id string, v string) error
|
||||
Update(id, oldV, newV string) error
|
||||
Search(pattern string) ([]string, error)
|
||||
IndexBy() string
|
||||
TypeName() string
|
||||
FilesDir() string
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package indexer
|
||||
package index
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
idxerrs "github.com/owncloud/ocis/accounts/pkg/indexer/errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
@@ -55,7 +56,7 @@ func (idx NonUniqueIndex) Lookup(v string) ([]string, error) {
|
||||
searchPath := path.Join(idx.indexRootDir, v)
|
||||
fi, err := ioutil.ReadDir(searchPath)
|
||||
if os.IsNotExist(err) {
|
||||
return []string{}, ¬FoundErr{idx.typeName, idx.indexBy, v}
|
||||
return []string{}, &idxerrs.NotFoundErr{idx.typeName, idx.indexBy, v}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -68,7 +69,7 @@ func (idx NonUniqueIndex) Lookup(v string) ([]string, error) {
|
||||
}
|
||||
|
||||
if len(ids) == 0 {
|
||||
return []string{}, ¬FoundErr{idx.typeName, idx.indexBy, v}
|
||||
return []string{}, &idxerrs.NotFoundErr{idx.typeName, idx.indexBy, v}
|
||||
}
|
||||
|
||||
return ids, nil
|
||||
@@ -84,7 +85,7 @@ func (idx NonUniqueIndex) Add(id, v string) (string, error) {
|
||||
|
||||
err := os.Symlink(oldName, newName)
|
||||
if errors.Is(err, os.ErrExist) {
|
||||
return "", &alreadyExistsErr{idx.typeName, idx.indexBy, v}
|
||||
return "", &idxerrs.AlreadyExistsErr{idx.typeName, idx.indexBy, v}
|
||||
}
|
||||
|
||||
return newName, err
|
||||
@@ -113,7 +114,7 @@ func (idx NonUniqueIndex) Update(id, oldV, newV string) (err error) {
|
||||
newPath := path.Join(newDir, id)
|
||||
|
||||
if _, err = os.Stat(oldPath); os.IsNotExist(err) {
|
||||
return ¬FoundErr{idx.typeName, idx.indexBy, oldV}
|
||||
return &idxerrs.NotFoundErr{idx.typeName, idx.indexBy, oldV}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -151,7 +152,7 @@ func (idx NonUniqueIndex) Search(pattern string) ([]string, error) {
|
||||
}
|
||||
|
||||
if len(paths) == 0 {
|
||||
return nil, ¬FoundErr{idx.typeName, idx.indexBy, pattern}
|
||||
return nil, &idxerrs.NotFoundErr{idx.typeName, idx.indexBy, pattern}
|
||||
}
|
||||
|
||||
return paths, nil
|
||||
@@ -1,6 +1,8 @@
|
||||
package indexer
|
||||
package index
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/accounts/pkg/indexer/errors"
|
||||
"github.com/owncloud/ocis/accounts/pkg/indexer/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"path"
|
||||
@@ -51,7 +53,7 @@ func TestNonUniqueIndexDelete(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNonUniqueIndexInit(t *testing.T) {
|
||||
dataDir := createTmpDir(t)
|
||||
dataDir := test.CreateTmpDir(t)
|
||||
indexRootDir := path.Join(dataDir, "index.disk")
|
||||
filesDir := path.Join(dataDir, "users")
|
||||
|
||||
@@ -82,22 +84,22 @@ func TestNonUniqueIndexSearch(t *testing.T) {
|
||||
|
||||
res, err = sut.Search("does-not-exist@example.com")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, ¬FoundErr{}, err)
|
||||
assert.IsType(t, &errors.NotFoundErr{}, err)
|
||||
|
||||
_ = os.RemoveAll(dataPath)
|
||||
}
|
||||
|
||||
func getNonUniqueIdxSut(t *testing.T) (sut IndexType, dataPath string) {
|
||||
dataPath = writeIndexTestData(t, testData, "Id")
|
||||
func getNonUniqueIdxSut(t *testing.T) (sut Index, dataPath string) {
|
||||
dataPath = test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
sut = NewNonUniqueIndex("Pet", "Color", path.Join(dataPath, "pets"), path.Join(dataPath, "index.disk"))
|
||||
err := sut.Init()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, u := range testData["pets"] {
|
||||
pkVal := valueOf(u, "Id")
|
||||
idxByVal := valueOf(u, "Color")
|
||||
for _, u := range test.TestData["pets"] {
|
||||
pkVal := test.ValueOf(u, "Id")
|
||||
idxByVal := test.ValueOf(u, "Color")
|
||||
_, err := sut.Add(pkVal, idxByVal)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -1,8 +1,9 @@
|
||||
package indexer
|
||||
package index
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
errors2 "github.com/owncloud/ocis/accounts/pkg/indexer/errors"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -66,7 +67,7 @@ func (idx Unique) Add(id, v string) (string, error) {
|
||||
newName := path.Join(idx.indexRootDir, v)
|
||||
err := os.Symlink(oldName, newName)
|
||||
if errors.Is(err, os.ErrExist) {
|
||||
return "", &alreadyExistsErr{idx.typeName, idx.indexBy, v}
|
||||
return "", &errors2.AlreadyExistsErr{idx.typeName, idx.indexBy, v}
|
||||
}
|
||||
|
||||
return newName, err
|
||||
@@ -87,7 +88,7 @@ func (idx Unique) Lookup(v string) (resultPath []string, err error) {
|
||||
searchPath := path.Join(idx.indexRootDir, v)
|
||||
if err = isValidSymlink(searchPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
err = ¬FoundErr{idx.typeName, idx.indexBy, v}
|
||||
err = &errors2.NotFoundErr{idx.typeName, idx.indexBy, v}
|
||||
}
|
||||
|
||||
return
|
||||
@@ -106,7 +107,7 @@ func (idx Unique) Update(id, oldV, newV string) (err error) {
|
||||
oldPath := path.Join(idx.indexRootDir, oldV)
|
||||
if err = isValidSymlink(oldPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return ¬FoundErr{idx.typeName, idx.indexBy, oldV}
|
||||
return &errors2.NotFoundErr{idx.TypeName(), idx.IndexBy(), oldV}
|
||||
}
|
||||
|
||||
return
|
||||
@@ -114,7 +115,7 @@ func (idx Unique) Update(id, oldV, newV string) (err error) {
|
||||
|
||||
newPath := path.Join(idx.indexRootDir, newV)
|
||||
if err = isValidSymlink(newPath); err == nil {
|
||||
return &alreadyExistsErr{idx.typeName, idx.indexBy, newV}
|
||||
return &errors2.AlreadyExistsErr{idx.typeName, idx.indexBy, newV}
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
@@ -131,7 +132,7 @@ func (idx Unique) Search(pattern string) ([]string, error) {
|
||||
}
|
||||
|
||||
if len(paths) == 0 {
|
||||
return nil, ¬FoundErr{idx.typeName, idx.indexBy, pattern}
|
||||
return nil, &errors2.NotFoundErr{idx.typeName, idx.indexBy, pattern}
|
||||
}
|
||||
|
||||
res := make([]string, 0, 0)
|
||||
@@ -1,6 +1,8 @@
|
||||
package indexer
|
||||
package index
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/accounts/pkg/indexer/errors"
|
||||
"github.com/owncloud/ocis/accounts/pkg/indexer/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"path"
|
||||
@@ -20,7 +22,7 @@ func TestUniqueLookupSingleEntry(t *testing.T) {
|
||||
t.Log("non-existing lookup")
|
||||
resultPath, err = uniq.Lookup("doesnotExists@example.com")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, ¬FoundErr{}, err)
|
||||
assert.IsType(t, &errors.NotFoundErr{}, err)
|
||||
assert.Empty(t, resultPath)
|
||||
|
||||
_ = os.RemoveAll(dataDir)
|
||||
@@ -32,7 +34,7 @@ func TestUniqueUniqueConstraint(t *testing.T) {
|
||||
|
||||
_, err := uniq.Add("abcdefg-123", "mikey@example.com")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, &alreadyExistsErr{}, err)
|
||||
assert.IsType(t, &errors.AlreadyExistsErr{}, err)
|
||||
|
||||
_ = os.RemoveAll(dataDir)
|
||||
}
|
||||
@@ -45,7 +47,7 @@ func TestUniqueRemove(t *testing.T) {
|
||||
|
||||
_, err = uniq.Lookup("mikey@example.com")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, ¬FoundErr{}, err)
|
||||
assert.IsType(t, &errors.NotFoundErr{}, err)
|
||||
|
||||
_ = os.RemoveAll(dataDir)
|
||||
}
|
||||
@@ -60,18 +62,18 @@ func TestUniqueUpdate(t *testing.T) {
|
||||
t.Log("failed update because already exists")
|
||||
err = uniq.Update("", "", "mikey2@example.com")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, &alreadyExistsErr{}, err)
|
||||
assert.IsType(t, &errors.AlreadyExistsErr{}, err)
|
||||
|
||||
t.Log("failed update because not found")
|
||||
err = uniq.Update("", "", "something2@example.com")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, ¬FoundErr{}, err)
|
||||
assert.IsType(t, &errors.NotFoundErr{}, err)
|
||||
|
||||
_ = os.RemoveAll(dataDir)
|
||||
}
|
||||
|
||||
func TestUniqueInit(t *testing.T) {
|
||||
dataDir := createTmpDir(t)
|
||||
dataDir := test.CreateTmpDir(t)
|
||||
indexRootDir := path.Join(dataDir, "index.disk")
|
||||
filesDir := path.Join(dataDir, "users")
|
||||
|
||||
@@ -102,27 +104,27 @@ func TestUniqueIndexSearch(t *testing.T) {
|
||||
|
||||
res, err = sut.Search("does-not-exist@example.com")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, ¬FoundErr{}, err)
|
||||
assert.IsType(t, &errors.NotFoundErr{}, err)
|
||||
|
||||
_ = os.RemoveAll(dataPath)
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
assert.True(t, IsAlreadyExistsErr(&alreadyExistsErr{}))
|
||||
assert.True(t, IsNotFoundErr(¬FoundErr{}))
|
||||
assert.True(t, errors.IsAlreadyExistsErr(&errors.AlreadyExistsErr{}))
|
||||
assert.True(t, errors.IsNotFoundErr(&errors.NotFoundErr{}))
|
||||
}
|
||||
|
||||
func getUniqueIdxSut(t *testing.T) (sut IndexType, dataPath string) {
|
||||
dataPath = writeIndexTestData(t, testData, "Id")
|
||||
func getUniqueIdxSut(t *testing.T) (sut Index, dataPath string) {
|
||||
dataPath = test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
sut = NewUniqueIndex("User", "Email", path.Join(dataPath, "users"), path.Join(dataPath, "indexer.disk"))
|
||||
err := sut.Init()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, u := range testData["users"] {
|
||||
pkVal := valueOf(u, "Id")
|
||||
idxByVal := valueOf(u, "Email")
|
||||
for _, u := range test.TestData["users"] {
|
||||
pkVal := test.ValueOf(u, "Id")
|
||||
idxByVal := test.ValueOf(u, "Email")
|
||||
_, err := sut.Add(pkVal, idxByVal)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -2,6 +2,8 @@
|
||||
package indexer
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/accounts/pkg/indexer/errors"
|
||||
"github.com/owncloud/ocis/accounts/pkg/indexer/index"
|
||||
"github.com/rs/zerolog"
|
||||
"path"
|
||||
)
|
||||
@@ -9,7 +11,7 @@ import (
|
||||
// Indexer is a facade to configure and query over multiple indices.
|
||||
type Indexer struct {
|
||||
config *Config
|
||||
indices indexMap
|
||||
indices typeMap
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
@@ -18,24 +20,10 @@ type Config struct {
|
||||
Log zerolog.Logger
|
||||
}
|
||||
|
||||
// IndexType can be implemented to create new indexer-strategies. See Unique for example.
|
||||
// Each indexer implementation is bound to one data-column (IndexBy) and a data-type (TypeName)
|
||||
type IndexType interface {
|
||||
Init() error
|
||||
Lookup(v string) ([]string, error)
|
||||
Add(id, v string) (string, error)
|
||||
Remove(id string, v string) error
|
||||
Update(id, oldV, newV string) error
|
||||
Search(pattern string) ([]string, error)
|
||||
IndexBy() string
|
||||
TypeName() string
|
||||
FilesDir() string
|
||||
}
|
||||
|
||||
func NewIndex(cfg *Config) *Indexer {
|
||||
return &Indexer{
|
||||
config: cfg,
|
||||
indices: indexMap{},
|
||||
indices: typeMap{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +32,7 @@ func (i Indexer) AddUniqueIndex(t interface{}, indexBy, pkName, entityDirName st
|
||||
fullDataPath := path.Join(i.config.DataDir, entityDirName)
|
||||
indexPath := path.Join(i.config.DataDir, i.config.IndexRootDirName)
|
||||
|
||||
idx := NewUniqueIndex(typeName, indexBy, fullDataPath, indexPath)
|
||||
idx := index.NewUniqueIndex(typeName, indexBy, fullDataPath, indexPath)
|
||||
|
||||
i.indices.addIndex(typeName, pkName, idx)
|
||||
return idx.Init()
|
||||
@@ -55,7 +43,7 @@ func (i Indexer) AddNonUniqueIndex(t interface{}, indexBy, pkName, entityDirName
|
||||
fullDataPath := path.Join(i.config.DataDir, entityDirName)
|
||||
indexPath := path.Join(i.config.DataDir, i.config.IndexRootDirName)
|
||||
|
||||
idx := NewNonUniqueIndex(typeName, indexBy, fullDataPath, indexPath)
|
||||
idx := index.NewNonUniqueIndex(typeName, indexBy, fullDataPath, indexPath)
|
||||
|
||||
i.indices.addIndex(typeName, pkName, idx)
|
||||
return idx.Init()
|
||||
@@ -65,9 +53,9 @@ func (i Indexer) AddNonUniqueIndex(t interface{}, indexBy, pkName, entityDirName
|
||||
func (i Indexer) Add(t interface{}) error {
|
||||
typeName := getTypeFQN(t)
|
||||
if fields, ok := i.indices[typeName]; ok {
|
||||
for _, indices := range fields.indicesByField {
|
||||
for _, indices := range fields.IndicesByField {
|
||||
for _, idx := range indices {
|
||||
pkVal := valueOf(t, fields.pKFieldName)
|
||||
pkVal := valueOf(t, fields.PKFieldName)
|
||||
idxByVal := valueOf(t, idx.IndexBy())
|
||||
if _, err := idx.Add(pkVal, idxByVal); err != nil {
|
||||
return err
|
||||
@@ -83,10 +71,10 @@ func (i Indexer) FindBy(t interface{}, field string, val string) ([]string, erro
|
||||
typeName := getTypeFQN(t)
|
||||
resultPaths := make([]string, 0)
|
||||
if fields, ok := i.indices[typeName]; ok {
|
||||
for _, idx := range fields.indicesByField[field] {
|
||||
for _, idx := range fields.IndicesByField[field] {
|
||||
res, err := idx.Lookup(val)
|
||||
if err != nil {
|
||||
if IsNotFoundErr(err) {
|
||||
if errors.IsNotFoundErr(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -111,9 +99,9 @@ func (i Indexer) FindBy(t interface{}, field string, val string) ([]string, erro
|
||||
func (i Indexer) Delete(t interface{}) error {
|
||||
typeName := getTypeFQN(t)
|
||||
if fields, ok := i.indices[typeName]; ok {
|
||||
for _, indices := range fields.indicesByField {
|
||||
for _, indices := range fields.IndicesByField {
|
||||
for _, idx := range indices {
|
||||
pkVal := valueOf(t, fields.pKFieldName)
|
||||
pkVal := valueOf(t, fields.PKFieldName)
|
||||
idxByVal := valueOf(t, idx.IndexBy())
|
||||
if err := idx.Remove(pkVal, idxByVal); err != nil {
|
||||
return err
|
||||
@@ -129,10 +117,10 @@ func (i Indexer) FindByPartial(t interface{}, field string, pattern string) ([]s
|
||||
typeName := getTypeFQN(t)
|
||||
resultPaths := make([]string, 0)
|
||||
if fields, ok := i.indices[typeName]; ok {
|
||||
for _, idx := range fields.indicesByField[field] {
|
||||
for _, idx := range fields.IndicesByField[field] {
|
||||
res, err := idx.Search(pattern)
|
||||
if err != nil {
|
||||
if IsNotFoundErr(err) {
|
||||
if errors.IsNotFoundErr(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -158,8 +146,8 @@ func (i Indexer) FindByPartial(t interface{}, field string, pattern string) ([]s
|
||||
func (i Indexer) Update(t interface{}, field, oldVal, newVal string) error {
|
||||
typeName := getTypeFQN(t)
|
||||
if fields, ok := i.indices[typeName]; ok {
|
||||
for _, idx := range fields.indicesByField[field] {
|
||||
pkVal := valueOf(t, fields.pKFieldName)
|
||||
for _, idx := range fields.IndicesByField[field] {
|
||||
pkVal := valueOf(t, fields.PKFieldName)
|
||||
if err := idx.Update(pkVal, oldVal, newVal); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,58 +1,60 @@
|
||||
package indexer
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/accounts/pkg/indexer/errors"
|
||||
"github.com/owncloud/ocis/accounts/pkg/indexer/test"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIndexer_AddWithUniqueIndex(t *testing.T) {
|
||||
dataDir := writeIndexTestData(t, testData, "Id")
|
||||
dataDir := test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
indexer := NewIndex(&Config{
|
||||
DataDir: dataDir,
|
||||
IndexRootDirName: "index.disk",
|
||||
Log: zerolog.Logger{},
|
||||
})
|
||||
|
||||
indexer.AddUniqueIndex(&User{}, "UserName", "Id", "users")
|
||||
indexer.AddUniqueIndex(&test.User{}, "UserName", "Id", "users")
|
||||
|
||||
u := &User{Id: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
|
||||
u := &test.User{Id: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
|
||||
err := indexer.Add(u)
|
||||
assert.NoError(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestIndexer_FindByWithUniqueIndex(t *testing.T) {
|
||||
dataDir := writeIndexTestData(t, testData, "Id")
|
||||
dataDir := test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
indexer := NewIndex(&Config{
|
||||
DataDir: dataDir,
|
||||
IndexRootDirName: "index.disk",
|
||||
Log: zerolog.Logger{},
|
||||
})
|
||||
|
||||
indexer.AddUniqueIndex(&User{}, "UserName", "Id", "users")
|
||||
indexer.AddUniqueIndex(&test.User{}, "UserName", "Id", "users")
|
||||
|
||||
u := &User{Id: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
|
||||
u := &test.User{Id: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
|
||||
err := indexer.Add(u)
|
||||
assert.NoError(t, err)
|
||||
|
||||
res, err := indexer.FindBy(User{}, "UserName", "mikey")
|
||||
res, err := indexer.FindBy(test.User{}, "UserName", "mikey")
|
||||
assert.NoError(t, err)
|
||||
t.Log(res)
|
||||
}
|
||||
|
||||
func TestIndexer_AddWithNonUniqueIndex(t *testing.T) {
|
||||
dataDir := writeIndexTestData(t, testData, "Id")
|
||||
dataDir := test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
indexer := NewIndex(&Config{
|
||||
DataDir: dataDir,
|
||||
IndexRootDirName: "index.disk",
|
||||
Log: zerolog.Logger{},
|
||||
})
|
||||
|
||||
indexer.AddNonUniqueIndex(&TestPet{}, "Kind", "Id", "pets")
|
||||
indexer.AddNonUniqueIndex(&test.TestPet{}, "Kind", "Id", "pets")
|
||||
|
||||
pet1 := TestPet{Id: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
|
||||
pet2 := TestPet{Id: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
|
||||
pet1 := test.TestPet{Id: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
|
||||
pet2 := test.TestPet{Id: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
|
||||
|
||||
err := indexer.Add(pet1)
|
||||
assert.NoError(t, err)
|
||||
@@ -60,24 +62,24 @@ func TestIndexer_AddWithNonUniqueIndex(t *testing.T) {
|
||||
err = indexer.Add(pet2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
res, err := indexer.FindBy(TestPet{}, "Kind", "Hog")
|
||||
res, err := indexer.FindBy(test.TestPet{}, "Kind", "Hog")
|
||||
assert.NoError(t, err)
|
||||
|
||||
t.Log(res)
|
||||
}
|
||||
|
||||
func TestIndexer_DeleteWithNonUniqueIndex(t *testing.T) {
|
||||
dataDir := writeIndexTestData(t, testData, "Id")
|
||||
dataDir := test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
indexer := NewIndex(&Config{
|
||||
DataDir: dataDir,
|
||||
IndexRootDirName: "index.disk",
|
||||
Log: zerolog.Logger{},
|
||||
})
|
||||
|
||||
indexer.AddNonUniqueIndex(&TestPet{}, "Kind", "Id", "pets")
|
||||
indexer.AddNonUniqueIndex(&test.TestPet{}, "Kind", "Id", "pets")
|
||||
|
||||
pet1 := TestPet{Id: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
|
||||
pet2 := TestPet{Id: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
|
||||
pet1 := test.TestPet{Id: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
|
||||
pet2 := test.TestPet{Id: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
|
||||
|
||||
err := indexer.Add(pet1)
|
||||
assert.NoError(t, err)
|
||||
@@ -90,17 +92,17 @@ func TestIndexer_DeleteWithNonUniqueIndex(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIndexer_SearchWithNonUniqueIndex(t *testing.T) {
|
||||
dataDir := writeIndexTestData(t, testData, "Id")
|
||||
dataDir := test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
indexer := NewIndex(&Config{
|
||||
DataDir: dataDir,
|
||||
IndexRootDirName: "index.disk",
|
||||
Log: zerolog.Logger{},
|
||||
})
|
||||
|
||||
indexer.AddNonUniqueIndex(&TestPet{}, "Name", "Id", "pets")
|
||||
indexer.AddNonUniqueIndex(&test.TestPet{}, "Name", "Id", "pets")
|
||||
|
||||
pet1 := TestPet{Id: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
|
||||
pet2 := TestPet{Id: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
|
||||
pet1 := test.TestPet{Id: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
|
||||
pet2 := test.TestPet{Id: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
|
||||
|
||||
err := indexer.Add(pet1)
|
||||
assert.NoError(t, err)
|
||||
@@ -115,17 +117,17 @@ func TestIndexer_SearchWithNonUniqueIndex(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIndexer_UpdateWithUniqueIndex(t *testing.T) {
|
||||
dataDir := writeIndexTestData(t, testData, "Id")
|
||||
dataDir := test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
indexer := NewIndex(&Config{
|
||||
DataDir: dataDir,
|
||||
IndexRootDirName: "index.disk",
|
||||
Log: zerolog.Logger{},
|
||||
})
|
||||
|
||||
indexer.AddUniqueIndex(&User{}, "UserName", "Id", "users")
|
||||
indexer.AddUniqueIndex(&test.User{}, "UserName", "Id", "users")
|
||||
|
||||
user1 := &User{Id: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
|
||||
user2 := &User{Id: "hijklmn-456", UserName: "frank", Email: "frank@example.com"}
|
||||
user1 := &test.User{Id: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
|
||||
user2 := &test.User{Id: "hijklmn-456", UserName: "frank", Email: "frank@example.com"}
|
||||
|
||||
err := indexer.Add(user1)
|
||||
assert.NoError(t, err)
|
||||
@@ -140,21 +142,21 @@ func TestIndexer_UpdateWithUniqueIndex(t *testing.T) {
|
||||
// Update to non existing value
|
||||
err = indexer.Update(user2, "UserName", "mikey", "jane")
|
||||
assert.Error(t, err)
|
||||
assert.IsType(t, &alreadyExistsErr{}, err)
|
||||
assert.IsType(t, &errors.AlreadyExistsErr{}, err)
|
||||
}
|
||||
|
||||
func TestIndexer_UpdateWithNonUniqueIndex(t *testing.T) {
|
||||
dataDir := writeIndexTestData(t, testData, "Id")
|
||||
dataDir := test.WriteIndexTestData(t, test.TestData, "Id")
|
||||
indexer := NewIndex(&Config{
|
||||
DataDir: dataDir,
|
||||
IndexRootDirName: "index.disk",
|
||||
Log: zerolog.Logger{},
|
||||
})
|
||||
|
||||
indexer.AddNonUniqueIndex(&TestPet{}, "Name", "Id", "pets")
|
||||
indexer.AddNonUniqueIndex(&test.TestPet{}, "Name", "Id", "pets")
|
||||
|
||||
pet1 := TestPet{Id: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
|
||||
pet2 := TestPet{Id: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
|
||||
pet1 := test.TestPet{Id: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
|
||||
pet2 := test.TestPet{Id: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
|
||||
|
||||
err := indexer.Add(pet1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
package indexer
|
||||
|
||||
// indexMap stores the indexer layout at runtime.
|
||||
import "github.com/owncloud/ocis/accounts/pkg/indexer/index"
|
||||
|
||||
type indexMap map[tName]typeMapping
|
||||
// typeMap stores the indexer layout at runtime.
|
||||
|
||||
type typeMap map[tName]typeMapping
|
||||
type tName = string
|
||||
type fieldName = string
|
||||
|
||||
type typeMapping struct {
|
||||
pKFieldName string
|
||||
indicesByField map[fieldName][]IndexType
|
||||
PKFieldName string
|
||||
IndicesByField map[fieldName][]index.Index
|
||||
}
|
||||
|
||||
func (m indexMap) addIndex(typeName string, pkName string, idx IndexType) {
|
||||
func (m typeMap) addIndex(typeName string, pkName string, idx index.Index) {
|
||||
if val, ok := m[typeName]; ok {
|
||||
val.indicesByField[idx.IndexBy()] = append(val.indicesByField[idx.IndexBy()], idx)
|
||||
val.IndicesByField[idx.IndexBy()] = append(val.IndicesByField[idx.IndexBy()], idx)
|
||||
return
|
||||
}
|
||||
m[typeName] = typeMapping{
|
||||
pKFieldName: pkName,
|
||||
indicesByField: map[string][]IndexType{
|
||||
PKFieldName: pkName,
|
||||
IndicesByField: map[string][]index.Index{
|
||||
idx.IndexBy(): {idx},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package indexer
|
||||
package test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -16,7 +16,7 @@ type TestPet struct {
|
||||
Id, Kind, Color, Name string
|
||||
}
|
||||
|
||||
var testData = map[string][]interface{}{
|
||||
var TestData = map[string][]interface{}{
|
||||
"users": {
|
||||
User{Id: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"},
|
||||
User{Id: "hijklmn-456", UserName: "frank", Email: "frank@example.com"},
|
||||
@@ -31,8 +31,8 @@ var testData = map[string][]interface{}{
|
||||
},
|
||||
}
|
||||
|
||||
func writeIndexTestData(t *testing.T, m map[string][]interface{}, pk string) string {
|
||||
rootDir := createTmpDir(t)
|
||||
func WriteIndexTestData(t *testing.T, m map[string][]interface{}, pk string) string {
|
||||
rootDir := CreateTmpDir(t)
|
||||
for dirName := range m {
|
||||
fileTypePath := path.Join(rootDir, dirName)
|
||||
|
||||
@@ -45,7 +45,7 @@ func writeIndexTestData(t *testing.T, m map[string][]interface{}, pk string) str
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pkVal := valueOf(u, pk)
|
||||
pkVal := ValueOf(u, pk)
|
||||
if err := ioutil.WriteFile(path.Join(fileTypePath, pkVal), data, 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -54,12 +54,3 @@ func writeIndexTestData(t *testing.T, m map[string][]interface{}, pk string) str
|
||||
|
||||
return rootDir
|
||||
}
|
||||
|
||||
func createTmpDir(t *testing.T) string {
|
||||
name, err := ioutil.TempDir("/var/tmp", "testfiles-*")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
23
accounts/pkg/indexer/test/helpers.go
Normal file
23
accounts/pkg/indexer/test/helpers.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func CreateTmpDir(t *testing.T) string {
|
||||
name, err := ioutil.TempDir("/var/tmp", "testfiles-*")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func ValueOf(v interface{}, field string) string {
|
||||
r := reflect.ValueOf(v)
|
||||
f := reflect.Indirect(r).FieldByName(field)
|
||||
|
||||
return f.String()
|
||||
}
|
||||
Reference in New Issue
Block a user