Initial QSfera import
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
package bleve
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/blevesearch/bleve/v2"
|
||||
storageProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
|
||||
"github.com/qsfera/server/pkg/log"
|
||||
"github.com/qsfera/server/services/search/pkg/search"
|
||||
)
|
||||
|
||||
var _ search.BatchOperator = (*Batch)(nil) // ensure Batch implements BatchOperator
|
||||
|
||||
type Batch struct {
|
||||
batch *bleve.Batch
|
||||
index bleve.Index
|
||||
size int
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func NewBatch(index bleve.Index, size int) (*Batch, error) {
|
||||
if size <= 0 {
|
||||
return nil, errors.New("batch size must be greater than 0")
|
||||
}
|
||||
|
||||
return &Batch{
|
||||
batch: index.NewBatch(),
|
||||
index: index,
|
||||
size: size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *Batch) Upsert(id string, r search.Resource) error {
|
||||
return b.withSizeLimit(func() error {
|
||||
return b.batch.Index(id, r)
|
||||
})
|
||||
}
|
||||
|
||||
func (b *Batch) Move(id, parentID, location string) error {
|
||||
return b.withSizeLimit(func() error {
|
||||
rootResource, err := searchResourceByID(id, b.index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentPath := rootResource.Path
|
||||
nextPath := utils.MakeRelativePath(location)
|
||||
|
||||
rootResource.Path = nextPath
|
||||
rootResource.Name = path.Base(nextPath)
|
||||
rootResource.ParentID = parentID
|
||||
|
||||
resources := []*search.Resource{rootResource}
|
||||
|
||||
if rootResource.Type == uint64(storageProvider.ResourceType_RESOURCE_TYPE_CONTAINER) {
|
||||
descendantResources, err := searchResourcesByPath(rootResource.RootID, currentPath, b.index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, descendantResource := range descendantResources {
|
||||
descendantResource.Path = strings.Replace(descendantResource.Path, currentPath, nextPath, 1)
|
||||
resources = append(resources, descendantResource)
|
||||
}
|
||||
}
|
||||
|
||||
for _, resource := range resources {
|
||||
if err := b.batch.Index(resource.ID, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
if b.batch.Size() >= b.size {
|
||||
if err := b.Push(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (b *Batch) Delete(id string) error {
|
||||
return b.withSizeLimit(func() error {
|
||||
affectedResources, err := searchAndUpdateResourcesDeletionState(id, true, b.index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, resource := range affectedResources {
|
||||
if err := b.batch.Index(resource.ID, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
if b.batch.Size() >= b.size {
|
||||
if err := b.Push(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (b *Batch) Restore(id string) error {
|
||||
return b.withSizeLimit(func() error {
|
||||
affectedResources, err := searchAndUpdateResourcesDeletionState(id, false, b.index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, resource := range affectedResources {
|
||||
if err := b.batch.Index(resource.ID, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
if b.batch.Size() >= b.size {
|
||||
if err := b.Push(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (b *Batch) Purge(id string, onlyDeleted bool) error {
|
||||
return b.withSizeLimit(func() error {
|
||||
rootResource, err := searchResourceByID(id, b.index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var affectResources []*search.Resource
|
||||
add := func(resource *search.Resource) {
|
||||
if onlyDeleted && !resource.Deleted {
|
||||
return
|
||||
}
|
||||
|
||||
affectResources = append(affectResources, resource)
|
||||
}
|
||||
|
||||
add(rootResource)
|
||||
|
||||
if rootResource.Type == uint64(storageProvider.ResourceType_RESOURCE_TYPE_CONTAINER) {
|
||||
descendantResources, err := searchResourcesByPath(rootResource.RootID, rootResource.Path, b.index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, descendantResource := range descendantResources {
|
||||
add(descendantResource)
|
||||
}
|
||||
}
|
||||
|
||||
for _, resource := range affectResources {
|
||||
b.batch.Delete(resource.ID)
|
||||
if b.batch.Size() >= b.size {
|
||||
if err := b.Push(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (b *Batch) Push() error {
|
||||
if b.batch.Size() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := b.index.Batch(b.batch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.batch.Reset()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Batch) withSizeLimit(f func() error) error {
|
||||
if err := f(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if b.batch.Size() >= b.size {
|
||||
return b.Push()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user