diff --git a/server/internal/infrastructure/mongo/asset.go b/server/internal/infrastructure/mongo/asset.go index 43512468b0..a7a5aba857 100644 --- a/server/internal/infrastructure/mongo/asset.go +++ b/server/internal/infrastructure/mongo/asset.go @@ -131,8 +131,8 @@ func (r *Asset) paginate(ctx context.Context, filter any, sort *asset.SortType, } } - c := mongodoc.NewAssetConsumer() - pageInfo, err := r.client.Paginate(ctx, r.readFilter(filter), usort, pagination, c) + c := mongodoc.NewAssetConsumer(r.f.Readable) + pageInfo, err := r.client.Paginate(ctx, filter, usort, pagination, c) if err != nil { return nil, nil, rerror.ErrInternalByWithContext(ctx, err) } @@ -141,16 +141,16 @@ func (r *Asset) paginate(ctx context.Context, filter any, sort *asset.SortType, } func (r *Asset) find(ctx context.Context, filter any) ([]*asset.Asset, error) { - c := mongodoc.NewAssetConsumer() - if err2 := r.client.Find(ctx, r.readFilter(filter), c); err2 != nil { + c := mongodoc.NewAssetConsumer(r.f.Readable) + if err2 := r.client.Find(ctx, filter, c); err2 != nil { return nil, rerror.ErrInternalByWithContext(ctx, err2) } return c.Result, nil } func (r *Asset) findOne(ctx context.Context, filter any) (*asset.Asset, error) { - c := mongodoc.NewAssetConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewAssetConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return c.Result[0], nil @@ -171,9 +171,9 @@ func filterAssets(ids []id.AssetID, rows []*asset.Asset) []*asset.Asset { return res } -func (r *Asset) readFilter(filter any) any { - return applyWorkspaceFilter(filter, r.f.Readable) -} +// func (r *Asset) readFilter(filter any) any { +// return applyWorkspaceFilter(filter, r.f.Readable) +// } func (r *Asset) writeFilter(filter any) any { return applyWorkspaceFilter(filter, r.f.Writable) diff --git a/server/internal/infrastructure/mongo/dataset.go b/server/internal/infrastructure/mongo/dataset.go index 282a84c60e..cabdc72105 100644 --- a/server/internal/infrastructure/mongo/dataset.go +++ b/server/internal/infrastructure/mongo/dataset.go @@ -98,12 +98,15 @@ func (r *Dataset) FindBySchemaAllBy(ctx context.Context, s id.DatasetSchemaID, c if err != nil { return err } + if r.f.Readable != nil && !r.f.Readable.Has(m.Scene()) { + return nil + } return cb(m) }) - if err := r.client.Find(ctx, r.readFilter(bson.M{ + if err := r.client.Find(ctx, bson.M{ "schema": s.String(), - }), c); err != nil { + }, c); err != nil { return rerror.ErrInternalByWithContext(ctx, err) } @@ -337,24 +340,24 @@ func (r *Dataset) RemoveByScene(ctx context.Context, sceneID id.SceneID) error { } func (r *Dataset) find(ctx context.Context, dst dataset.List, filter interface{}) (dataset.List, error) { - c := mongodoc.NewDatasetConsumer() - if err2 := r.client.Find(ctx, r.readFilter(filter), c); err2 != nil { + c := mongodoc.NewDatasetConsumer(r.f.Readable) + if err2 := r.client.Find(ctx, filter, c); err2 != nil { return nil, rerror.ErrInternalByWithContext(ctx, err2) } return c.Result, nil } func (r *Dataset) findOne(ctx context.Context, filter interface{}) (*dataset.Dataset, error) { - c := mongodoc.NewDatasetConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewDatasetConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return c.Result[0], nil } func (r *Dataset) paginate(ctx context.Context, filter bson.M, pagination *usecasex.Pagination) (dataset.List, *usecasex.PageInfo, error) { - c := mongodoc.NewDatasetConsumer() - pageInfo, err := r.client.Paginate(ctx, r.readFilter(filter), nil, pagination, c) + c := mongodoc.NewDatasetConsumer(r.f.Readable) + pageInfo, err := r.client.Paginate(ctx, filter, nil, pagination, c) if err != nil { return nil, nil, rerror.ErrInternalByWithContext(ctx, err) } diff --git a/server/internal/infrastructure/mongo/dataset_schema.go b/server/internal/infrastructure/mongo/dataset_schema.go index a5a98b1bb2..460315a0dc 100644 --- a/server/internal/infrastructure/mongo/dataset_schema.go +++ b/server/internal/infrastructure/mongo/dataset_schema.go @@ -4,6 +4,7 @@ import ( "context" "go.mongodb.org/mongo-driver/bson" + "golang.org/x/exp/slices" "github.com/reearth/reearth/server/internal/infrastructure/mongo/mongodoc" "github.com/reearth/reearth/server/internal/usecase/repo" @@ -93,9 +94,13 @@ func (r *DatasetSchema) FindBySceneAndSource(ctx context.Context, sceneID id.Sce } func (r *DatasetSchema) CountByScene(ctx context.Context, id id.SceneID) (int, error) { - res, err := r.client.Count(ctx, r.readFilter(bson.M{ + if r.f.Readable != nil && !slices.Contains(r.f.Readable, id) { + return 0, nil + } + + res, err := r.client.Count(ctx, bson.M{ "scene": id.String(), - })) + }) if err != nil { return 0, err } @@ -144,24 +149,24 @@ func (r *DatasetSchema) RemoveByScene(ctx context.Context, sceneID id.SceneID) e } func (r *DatasetSchema) find(ctx context.Context, filter any) ([]*dataset.Schema, error) { - c := mongodoc.NewDatasetSchemaConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewDatasetSchemaConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return c.Result, nil } func (r *DatasetSchema) findOne(ctx context.Context, filter any) (*dataset.Schema, error) { - c := mongodoc.NewDatasetSchemaConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewDatasetSchemaConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return c.Result[0], nil } func (r *DatasetSchema) paginate(ctx context.Context, filter bson.M, pagination *usecasex.Pagination) ([]*dataset.Schema, *usecasex.PageInfo, error) { - c := mongodoc.NewDatasetSchemaConsumer() - pageInfo, err := r.client.Paginate(ctx, r.readFilter(filter), nil, pagination, c) + c := mongodoc.NewDatasetSchemaConsumer(r.f.Readable) + pageInfo, err := r.client.Paginate(ctx, filter, nil, pagination, c) if err != nil { return nil, nil, rerror.ErrInternalByWithContext(ctx, err) } @@ -183,9 +188,9 @@ func filterDatasetSchemas(ids []id.DatasetSchemaID, rows []*dataset.Schema) []*d return res } -func (r *DatasetSchema) readFilter(filter any) any { - return applySceneFilter(filter, r.f.Readable) -} +// func (r *DatasetSchema) readFilter(filter any) any { +// return applySceneFilter(filter, r.f.Readable) +// } func (r *DatasetSchema) writeFilter(filter any) any { return applySceneFilter(filter, r.f.Writable) diff --git a/server/internal/infrastructure/mongo/layer.go b/server/internal/infrastructure/mongo/layer.go index 25cd2a913d..d0501bbf23 100644 --- a/server/internal/infrastructure/mongo/layer.go +++ b/server/internal/infrastructure/mongo/layer.go @@ -269,16 +269,16 @@ func (r *Layer) RemoveByScene(ctx context.Context, sceneID id.SceneID) error { } func (r *Layer) find(ctx context.Context, dst layer.List, filter interface{}) (layer.List, error) { - c := mongodoc.NewLayerConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewLayerConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return lo.ToSlicePtr(c.Result), nil } func (r *Layer) findOne(ctx context.Context, filter interface{}) (layer.Layer, error) { - c := mongodoc.NewLayerConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewLayerConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } if len(c.Result) == 0 { @@ -288,8 +288,8 @@ func (r *Layer) findOne(ctx context.Context, filter interface{}) (layer.Layer, e } func (r *Layer) findItemOne(ctx context.Context, filter interface{}) (*layer.Item, error) { - c := mongodoc.NewLayerConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewLayerConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } if len(c.Result) == 0 { @@ -299,8 +299,8 @@ func (r *Layer) findItemOne(ctx context.Context, filter interface{}) (*layer.Ite } func (r *Layer) findGroupOne(ctx context.Context, filter interface{}) (*layer.Group, error) { - c := mongodoc.NewLayerConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewLayerConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } if len(c.Result) == 0 { @@ -310,16 +310,16 @@ func (r *Layer) findGroupOne(ctx context.Context, filter interface{}) (*layer.Gr } func (r *Layer) findItems(ctx context.Context, dst layer.ItemList, filter interface{}) (layer.ItemList, error) { - c := mongodoc.NewLayerConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewLayerConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return layer.List(lo.ToSlicePtr(c.Result)).ToLayerItemList(), nil } func (r *Layer) findGroups(ctx context.Context, dst layer.GroupList, filter interface{}) (layer.GroupList, error) { - c := mongodoc.NewLayerConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewLayerConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return layer.List(lo.ToSlicePtr(c.Result)).ToLayerGroupList(), nil @@ -373,9 +373,9 @@ func filterLayerGroups(ids []id.LayerID, rows []*layer.Group) []*layer.Group { return res } -func (r *Layer) readFilter(filter interface{}) interface{} { - return applySceneFilter(filter, r.f.Readable) -} +// func (r *Layer) readFilter(filter interface{}) interface{} { +// return applySceneFilter(filter, r.f.Readable) +// } func (r *Layer) writeFilter(filter interface{}) interface{} { return applySceneFilter(filter, r.f.Writable) diff --git a/server/internal/infrastructure/mongo/mongodoc/asset.go b/server/internal/infrastructure/mongo/mongodoc/asset.go index 7066ca10a5..f6e0cac39a 100644 --- a/server/internal/infrastructure/mongo/mongodoc/asset.go +++ b/server/internal/infrastructure/mongo/mongodoc/asset.go @@ -5,7 +5,7 @@ import ( "github.com/reearth/reearth/server/pkg/asset" "github.com/reearth/reearth/server/pkg/id" - "github.com/reearth/reearthx/mongox" + "golang.org/x/exp/slices" ) type AssetDocument struct { @@ -18,10 +18,12 @@ type AssetDocument struct { ContentType string } -type AssetConsumer = mongox.SliceFuncConsumer[*AssetDocument, *asset.Asset] +type AssetConsumer = Consumer[*AssetDocument, *asset.Asset] -func NewAssetConsumer() *AssetConsumer { - return NewComsumer[*AssetDocument, *asset.Asset]() +func NewAssetConsumer(workspaces []id.WorkspaceID) *AssetConsumer { + return NewConsumer[*AssetDocument, *asset.Asset](func(a *asset.Asset) bool { + return workspaces == nil || slices.Contains(workspaces, a.Workspace()) + }) } func NewAsset(asset *asset.Asset) (*AssetDocument, string) { diff --git a/server/internal/infrastructure/mongo/mongodoc/consumer.go b/server/internal/infrastructure/mongo/mongodoc/consumer.go index 54703fede3..19455fc6bd 100644 --- a/server/internal/infrastructure/mongo/mongodoc/consumer.go +++ b/server/internal/infrastructure/mongo/mongodoc/consumer.go @@ -1,13 +1,36 @@ package mongodoc -import "github.com/reearth/reearthx/mongox" - -func NewComsumer[T Model[U], U any]() *mongox.SliceFuncConsumer[T, U] { - return mongox.NewSliceFuncConsumer(func(d T) (U, error) { - return d.Model() - }) -} +import ( + "github.com/reearth/reearthx/mongox" + "go.mongodb.org/mongo-driver/bson" +) type Model[T any] interface { Model() (T, error) } + +type Consumer[T, K any] struct { + Result []K + c mongox.SimpleConsumer[T] +} + +func NewConsumer[T Model[U], U any](filter func(U) bool) *Consumer[T, U] { + var c *Consumer[T, U] + c = &Consumer[T, U]{ + c: mongox.SimpleConsumer[T](func(d T) error { + e, err := d.Model() + if err != nil { + return err + } + if filter == nil || filter(e) { + c.Result = append(c.Result, e) + } + return nil + }), + } + return c +} + +func (s *Consumer[T, K]) Consume(raw bson.Raw) error { + return s.c.Consume(raw) +} diff --git a/server/internal/infrastructure/mongo/mongodoc/dataset.go b/server/internal/infrastructure/mongo/mongodoc/dataset.go index 7dd7e8d342..6a37459034 100644 --- a/server/internal/infrastructure/mongo/mongodoc/dataset.go +++ b/server/internal/infrastructure/mongo/mongodoc/dataset.go @@ -2,6 +2,7 @@ package mongodoc import ( "go.mongodb.org/mongo-driver/bson" + "golang.org/x/exp/slices" "github.com/reearth/reearth/server/pkg/dataset" "github.com/reearth/reearth/server/pkg/id" @@ -30,10 +31,12 @@ type DatasetExtendedDocument struct { Depth int } -type DatasetConsumer = mongox.SliceFuncConsumer[*DatasetDocument, *dataset.Dataset] +type DatasetConsumer = Consumer[*DatasetDocument, *dataset.Dataset] -func NewDatasetConsumer() *DatasetConsumer { - return NewComsumer[*DatasetDocument, *dataset.Dataset]() +func NewDatasetConsumer(scenes []id.SceneID) *DatasetConsumer { + return NewConsumer[*DatasetDocument, *dataset.Dataset](func(a *dataset.Dataset) bool { + return scenes == nil || slices.Contains(scenes, a.Scene()) + }) } type DatasetMapConsumer struct { diff --git a/server/internal/infrastructure/mongo/mongodoc/dataset_schema.go b/server/internal/infrastructure/mongo/mongodoc/dataset_schema.go index cd0d15b298..766763122b 100644 --- a/server/internal/infrastructure/mongo/mongodoc/dataset_schema.go +++ b/server/internal/infrastructure/mongo/mongodoc/dataset_schema.go @@ -4,7 +4,7 @@ import ( "github.com/reearth/reearth/server/pkg/dataset" "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/scene" - "github.com/reearth/reearthx/mongox" + "golang.org/x/exp/slices" ) type DatasetSchemaDocument struct { @@ -23,10 +23,12 @@ type DatasetSchemaFieldDocument struct { Source string } -type DatasetSchemaConsumer = mongox.SliceFuncConsumer[*DatasetSchemaDocument, *dataset.Schema] +type DatasetSchemaConsumer = Consumer[*DatasetSchemaDocument, *dataset.Schema] -func NewDatasetSchemaConsumer() *DatasetSchemaConsumer { - return NewComsumer[*DatasetSchemaDocument, *dataset.Schema]() +func NewDatasetSchemaConsumer(scenes []id.SceneID) *DatasetSchemaConsumer { + return NewConsumer[*DatasetSchemaDocument, *dataset.Schema](func(a *dataset.Schema) bool { + return scenes == nil || slices.Contains(scenes, a.Scene()) + }) } func (d *DatasetSchemaDocument) Model() (*dataset.Schema, error) { diff --git a/server/internal/infrastructure/mongo/mongodoc/layer.go b/server/internal/infrastructure/mongo/mongodoc/layer.go index ee0827d120..5c0e8768ce 100644 --- a/server/internal/infrastructure/mongo/mongodoc/layer.go +++ b/server/internal/infrastructure/mongo/mongodoc/layer.go @@ -6,7 +6,7 @@ import ( "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/layer" "github.com/reearth/reearth/server/pkg/scene" - "github.com/reearth/reearthx/mongox" + "golang.org/x/exp/slices" ) type LayerDocument struct { @@ -53,10 +53,12 @@ type LayerTagDocument struct { type LayerTagListDocument []LayerTagDocument -type LayerConsumer = mongox.SliceFuncConsumer[*LayerDocument, layer.Layer] +type LayerConsumer = Consumer[*LayerDocument, layer.Layer] -func NewLayerConsumer() *LayerConsumer { - return NewComsumer[*LayerDocument, layer.Layer]() +func NewLayerConsumer(scenes []id.SceneID) *LayerConsumer { + return NewConsumer[*LayerDocument, layer.Layer](func(a layer.Layer) bool { + return scenes == nil || slices.Contains(scenes, a.Scene()) + }) } func NewLayer(l layer.Layer) (*LayerDocument, string) { diff --git a/server/internal/infrastructure/mongo/mongodoc/plugin.go b/server/internal/infrastructure/mongo/mongodoc/plugin.go index 5a28202fda..f017e14e46 100644 --- a/server/internal/infrastructure/mongo/mongodoc/plugin.go +++ b/server/internal/infrastructure/mongo/mongodoc/plugin.go @@ -3,7 +3,7 @@ package mongodoc import ( "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/plugin" - "github.com/reearth/reearthx/mongox" + "golang.org/x/exp/slices" ) type PluginDocument struct { @@ -47,10 +47,13 @@ type WidgetLocationDocument struct { Area string } -type PluginConsumer = mongox.SliceFuncConsumer[*PluginDocument, *plugin.Plugin] +type PluginConsumer = Consumer[*PluginDocument, *plugin.Plugin] -func NewPluginConsumer() *PluginConsumer { - return NewComsumer[*PluginDocument, *plugin.Plugin]() +func NewPluginConsumer(scenes []id.SceneID) *PluginConsumer { + return NewConsumer[*PluginDocument, *plugin.Plugin](func(a *plugin.Plugin) bool { + sid := a.ID().Scene() + return sid == nil || scenes == nil || slices.Contains(scenes, *sid) + }) } func NewPlugin(plugin *plugin.Plugin) (*PluginDocument, string) { diff --git a/server/internal/infrastructure/mongo/mongodoc/project.go b/server/internal/infrastructure/mongo/mongodoc/project.go index f04d2f5697..b11da0f2f9 100644 --- a/server/internal/infrastructure/mongo/mongodoc/project.go +++ b/server/internal/infrastructure/mongo/mongodoc/project.go @@ -7,7 +7,7 @@ import ( "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/project" "github.com/reearth/reearth/server/pkg/visualizer" - "github.com/reearth/reearthx/mongox" + "golang.org/x/exp/slices" ) type ProjectDocument struct { @@ -32,10 +32,12 @@ type ProjectDocument struct { CoreSupport bool } -type ProjectConsumer = mongox.SliceFuncConsumer[*ProjectDocument, *project.Project] +type ProjectConsumer = Consumer[*ProjectDocument, *project.Project] -func NewProjectConsumer() *ProjectConsumer { - return NewComsumer[*ProjectDocument, *project.Project]() +func NewProjectConsumer(workspaces []id.WorkspaceID) *ProjectConsumer { + return NewConsumer[*ProjectDocument, *project.Project](func(a *project.Project) bool { + return workspaces == nil || slices.Contains(workspaces, a.Workspace()) + }) } func NewProject(project *project.Project) (*ProjectDocument, string) { diff --git a/server/internal/infrastructure/mongo/mongodoc/property.go b/server/internal/infrastructure/mongo/mongodoc/property.go index 5274d84a88..045f7168b1 100644 --- a/server/internal/infrastructure/mongo/mongodoc/property.go +++ b/server/internal/infrastructure/mongo/mongodoc/property.go @@ -2,6 +2,7 @@ package mongodoc import ( "go.mongodb.org/mongo-driver/bson" + "golang.org/x/exp/slices" "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/property" @@ -44,10 +45,12 @@ type PropertyItemDocument struct { Fields []*PropertyFieldDocument } -type PropertyConsumer = mongox.SliceFuncConsumer[*PropertyDocument, *property.Property] +type PropertyConsumer = Consumer[*PropertyDocument, *property.Property] -func NewPropertyConsumer() *PropertyConsumer { - return NewComsumer[*PropertyDocument, *property.Property]() +func NewPropertyConsumer(scenes []id.SceneID) *PropertyConsumer { + return NewConsumer[*PropertyDocument, *property.Property](func(a *property.Property) bool { + return scenes == nil || slices.Contains(scenes, a.Scene()) + }) } type PropertyBatchConsumer struct { diff --git a/server/internal/infrastructure/mongo/mongodoc/property_schema.go b/server/internal/infrastructure/mongo/mongodoc/property_schema.go index 9ca3b3c397..8948bc0dfe 100644 --- a/server/internal/infrastructure/mongo/mongodoc/property_schema.go +++ b/server/internal/infrastructure/mongo/mongodoc/property_schema.go @@ -4,7 +4,7 @@ import ( "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/property" "github.com/reearth/reearth/server/pkg/scene" - "github.com/reearth/reearthx/mongox" + "golang.org/x/exp/slices" ) type PropertySchemaDocument struct { @@ -58,10 +58,13 @@ type PropertyConditonDocument struct { Value interface{} } -type PropertySchemaConsumer = mongox.SliceFuncConsumer[*PropertySchemaDocument, *property.Schema] +type PropertySchemaConsumer = Consumer[*PropertySchemaDocument, *property.Schema] -func NewPropertySchemaConsumer() *PropertySchemaConsumer { - return NewComsumer[*PropertySchemaDocument, *property.Schema]() +func NewPropertySchemaConsumer(scenes []id.SceneID) *PropertySchemaConsumer { + return NewConsumer[*PropertySchemaDocument, *property.Schema](func(a *property.Schema) bool { + sid := a.ID().Plugin().Scene() + return sid == nil || scenes == nil || slices.Contains(scenes, *sid) + }) } func NewPropertySchemaField(f *property.SchemaField) *PropertySchemaFieldDocument { diff --git a/server/internal/infrastructure/mongo/mongodoc/scene.go b/server/internal/infrastructure/mongo/mongodoc/scene.go index 864630a5b7..999595064a 100644 --- a/server/internal/infrastructure/mongo/mongodoc/scene.go +++ b/server/internal/infrastructure/mongo/mongodoc/scene.go @@ -5,10 +5,10 @@ import ( "time" "go.mongodb.org/mongo-driver/bson" + "golang.org/x/exp/slices" "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/scene" - "github.com/reearth/reearthx/mongox" ) type SceneDocument struct { @@ -44,10 +44,12 @@ type SceneClusterDocument struct { Property string } -type SceneConsumer = mongox.SliceFuncConsumer[*SceneDocument, *scene.Scene] +type SceneConsumer = Consumer[*SceneDocument, *scene.Scene] -func NewSceneConsumer() *SceneConsumer { - return NewComsumer[*SceneDocument, *scene.Scene]() +func NewSceneConsumer(workspaces []id.WorkspaceID) *SceneConsumer { + return NewConsumer[*SceneDocument, *scene.Scene](func(s *scene.Scene) bool { + return workspaces == nil || slices.Contains(workspaces, s.Workspace()) + }) } type SceneIDDocument struct { diff --git a/server/internal/infrastructure/mongo/mongodoc/tag.go b/server/internal/infrastructure/mongo/mongodoc/tag.go index d02905052a..b0472ba827 100644 --- a/server/internal/infrastructure/mongo/mongodoc/tag.go +++ b/server/internal/infrastructure/mongo/mongodoc/tag.go @@ -6,7 +6,7 @@ import ( "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/scene" "github.com/reearth/reearth/server/pkg/tag" - "github.com/reearth/reearthx/mongox" + "golang.org/x/exp/slices" ) type TagDocument struct { @@ -28,10 +28,12 @@ type TagGroupDocument struct { Tags []string } -type TagConsumer = mongox.SliceFuncConsumer[*TagDocument, tag.Tag] +type TagConsumer = Consumer[*TagDocument, tag.Tag] -func NewTagConsumer() *TagConsumer { - return NewComsumer[*TagDocument, tag.Tag]() +func NewTagConsumer(scenes []id.SceneID) *TagConsumer { + return NewConsumer[*TagDocument, tag.Tag](func(a tag.Tag) bool { + return scenes == nil || slices.Contains(scenes, a.Scene()) + }) } func NewTag(t tag.Tag) (*TagDocument, string) { diff --git a/server/internal/infrastructure/mongo/mongodoc/tag_test.go b/server/internal/infrastructure/mongo/mongodoc/tag_test.go index 986a6d3674..0a30ebe664 100644 --- a/server/internal/infrastructure/mongo/mongodoc/tag_test.go +++ b/server/internal/infrastructure/mongo/mongodoc/tag_test.go @@ -1,11 +1,13 @@ package mongodoc import ( + "io" "testing" "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/scene" "github.com/reearth/reearth/server/pkg/tag" + "github.com/samber/lo" "github.com/stretchr/testify/assert" "go.mongodb.org/mongo-driver/bson" ) @@ -171,84 +173,78 @@ func TestNewTags(t *testing.T) { } } -func TestFuncConsumer_Consume(t *testing.T) { +func TestTagConsumer_Consume(t *testing.T) { sid := id.NewSceneID() - tg, _ := tag.NewGroup(). + tg := tag.NewGroup(). NewID(). Label("group"). Scene(sid). - Build() - ti, _ := tag.NewItem(). + MustBuild() + ti := tag.NewItem(). NewID(). Label("group"). Scene(sid). - Build() - doc, _ := NewTag(tg) - doc1, _ := NewTag(ti) - r, _ := bson.Marshal(doc) - r1, _ := bson.Marshal(doc1) - type fields struct { - Rows []*tag.Tag - GroupRows []*tag.Group - ItemRows []*tag.Item - } - type args struct { - raw bson.Raw - } + MustBuild() + doc1, _ := NewTag(tg) + doc2, _ := NewTag(ti) + r1 := lo.Must(bson.Marshal(doc1)) + r2 := lo.Must(bson.Marshal(doc2)) tests := []struct { name string - fields fields - args args + filter []id.SceneID + arg bson.Raw wantErr bool + wantEOF bool + result []tag.Tag }{ { - name: "nil row", - fields: fields{ - Rows: nil, - GroupRows: nil, - ItemRows: nil, - }, - args: args{ - raw: nil, - }, + name: "nil", + filter: nil, + arg: nil, wantErr: false, + wantEOF: true, + result: nil, }, { - name: "consume tag group", - fields: fields{ - Rows: nil, - GroupRows: nil, - ItemRows: nil, - }, - args: args{ - raw: r, - }, + name: "consume tag group", + filter: nil, + arg: r1, wantErr: false, + wantEOF: false, + result: []tag.Tag{tg}, }, { - name: "consume tag item", - fields: fields{ - Rows: nil, - GroupRows: nil, - ItemRows: nil, - }, - args: args{ - raw: r1, - }, + name: "consume tag item", + filter: nil, + arg: r2, wantErr: false, + wantEOF: false, + result: []tag.Tag{ti}, }, { - name: "fail: unmarshal error", - fields: fields{ - Rows: nil, - GroupRows: nil, - ItemRows: nil, - }, - args: args{ - raw: []byte{}, - }, + name: "filtered", + filter: []id.SceneID{sid}, + arg: r2, + wantErr: false, + wantEOF: false, + result: []tag.Tag{ti}, + }, + { + name: "rejected", + filter: []id.SceneID{id.NewSceneID()}, + arg: r2, + wantErr: false, + wantEOF: false, + result: nil, + }, + { + name: "fail: unmarshal error", + filter: nil, + arg: []byte{}, wantErr: true, + wantEOF: false, + result: nil, }, } @@ -256,10 +252,16 @@ func TestFuncConsumer_Consume(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() - c := NewTagConsumer() - if err := c.Consume(tc.args.raw); tc.wantErr { + c := NewTagConsumer(tc.filter) + err := c.Consume(tc.arg) + if tc.wantEOF { + assert.Equal(t, io.EOF, err) + } else if tc.wantErr { assert.Error(t, err) + } else { + assert.NoError(t, err) } + assert.Equal(t, tc.result, c.Result) }) } } diff --git a/server/internal/infrastructure/mongo/mongodoc/user.go b/server/internal/infrastructure/mongo/mongodoc/user.go index 7f5b480c7d..f8389644c2 100644 --- a/server/internal/infrastructure/mongo/mongodoc/user.go +++ b/server/internal/infrastructure/mongo/mongodoc/user.go @@ -6,7 +6,6 @@ import ( "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/user" user1 "github.com/reearth/reearth/server/pkg/user" - "github.com/reearth/reearthx/mongox" "github.com/reearth/reearthx/util" ) @@ -35,10 +34,10 @@ type UserVerificationDoc struct { Verified bool } -type UserConsumer = mongox.SliceFuncConsumer[*UserDocument, *user.User] +type UserConsumer = Consumer[*UserDocument, *user.User] func NewUserConsumer() *UserConsumer { - return NewComsumer[*UserDocument, *user.User]() + return NewConsumer[*UserDocument, *user.User](nil) } func NewUser(user *user1.User) (*UserDocument, string) { diff --git a/server/internal/infrastructure/mongo/mongodoc/workspace.go b/server/internal/infrastructure/mongo/mongodoc/workspace.go index 3fb1364482..c1b08404f8 100644 --- a/server/internal/infrastructure/mongo/mongodoc/workspace.go +++ b/server/internal/infrastructure/mongo/mongodoc/workspace.go @@ -3,7 +3,6 @@ package mongodoc import ( "github.com/reearth/reearth/server/pkg/id" "github.com/reearth/reearth/server/pkg/workspace" - "github.com/reearth/reearthx/mongox" ) type WorkspaceMemberDocument struct { @@ -18,10 +17,10 @@ type WorkspaceDocument struct { Policy *workspace.PolicyID `bson:"policy,omitempty"` } -type WorkspaceConsumer = mongox.SliceFuncConsumer[*WorkspaceDocument, *workspace.Workspace] +type WorkspaceConsumer = Consumer[*WorkspaceDocument, *workspace.Workspace] func NewWorkspaceConsumer() *WorkspaceConsumer { - return NewComsumer[*WorkspaceDocument, *workspace.Workspace]() + return NewConsumer[*WorkspaceDocument, *workspace.Workspace](nil) } func NewWorkspace(ws *workspace.Workspace) (*WorkspaceDocument, string) { diff --git a/server/internal/infrastructure/mongo/plugin.go b/server/internal/infrastructure/mongo/plugin.go index b1ca64bae1..16a19d1668 100644 --- a/server/internal/infrastructure/mongo/plugin.go +++ b/server/internal/infrastructure/mongo/plugin.go @@ -103,24 +103,24 @@ func (r *Plugin) Remove(ctx context.Context, id id.PluginID) error { } func (r *Plugin) find(ctx context.Context, filter any) ([]*plugin.Plugin, error) { - c := mongodoc.NewPluginConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewPluginConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return c.Result, nil } func (r *Plugin) findOne(ctx context.Context, filter any) (*plugin.Plugin, error) { - c := mongodoc.NewPluginConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewPluginConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return c.Result[0], nil } -func (r *Plugin) readFilter(filter any) any { - return applyOptionalSceneFilter(filter, r.f.Readable) -} +// func (r *Plugin) readFilter(filter any) any { +// return applyOptionalSceneFilter(filter, r.f.Readable) +// } func (r *Plugin) writeFilter(filter any) any { return applyOptionalSceneFilter(filter, r.f.Writable) diff --git a/server/internal/infrastructure/mongo/project.go b/server/internal/infrastructure/mongo/project.go index 28256f82e9..6c83ca0cf3 100644 --- a/server/internal/infrastructure/mongo/project.go +++ b/server/internal/infrastructure/mongo/project.go @@ -44,7 +44,7 @@ func (r *Project) Filtered(f repo.WorkspaceFilter) repo.Project { func (r *Project) FindByID(ctx context.Context, id id.ProjectID) (*project.Project, error) { return r.findOne(ctx, bson.M{ "id": id.String(), - }) + }, true) } func (r *Project) FindByIDs(ctx context.Context, ids id.ProjectIDList) ([]*project.Project, error) { @@ -88,7 +88,7 @@ func (r *Project) FindByPublicName(ctx context.Context, name string) (*project.P }, } - return r.findOneWithoutReadFilter(ctx, f) + return r.findOne(ctx, f, false) } func (r *Project) CountByWorkspace(ctx context.Context, ws id.WorkspaceID) (int, error) { @@ -129,19 +129,19 @@ func (r *Project) Remove(ctx context.Context, id id.ProjectID) error { } func (r *Project) find(ctx context.Context, filter interface{}) ([]*project.Project, error) { - c := mongodoc.NewProjectConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewProjectConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return c.Result, nil } -func (r *Project) findOne(ctx context.Context, filter any) (*project.Project, error) { - return r.findOneWithoutReadFilter(ctx, r.readFilter(filter)) -} - -func (r *Project) findOneWithoutReadFilter(ctx context.Context, filter any) (*project.Project, error) { - c := mongodoc.NewProjectConsumer() +func (r *Project) findOne(ctx context.Context, filter any, filterByWorkspaces bool) (*project.Project, error) { + var f []id.WorkspaceID + if filterByWorkspaces { + f = r.f.Readable + } + c := mongodoc.NewProjectConsumer(f) if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } @@ -149,8 +149,8 @@ func (r *Project) findOneWithoutReadFilter(ctx context.Context, filter any) (*pr } func (r *Project) paginate(ctx context.Context, filter bson.M, pagination *usecasex.Pagination) ([]*project.Project, *usecasex.PageInfo, error) { - c := mongodoc.NewProjectConsumer() - pageInfo, err := r.client.Paginate(ctx, r.readFilter(filter), nil, pagination, c) + c := mongodoc.NewProjectConsumer(r.f.Readable) + pageInfo, err := r.client.Paginate(ctx, filter, nil, pagination, c) if err != nil { return nil, nil, rerror.ErrInternalByWithContext(ctx, err) } @@ -172,9 +172,9 @@ func filterProjects(ids []id.ProjectID, rows []*project.Project) []*project.Proj return res } -func (r *Project) readFilter(filter interface{}) interface{} { - return applyWorkspaceFilter(filter, r.f.Readable) -} +// func (r *Project) readFilter(filter interface{}) interface{} { +// return applyWorkspaceFilter(filter, r.f.Readable) +// } func (r *Project) writeFilter(filter interface{}) interface{} { return applyWorkspaceFilter(filter, r.f.Writable) diff --git a/server/internal/infrastructure/mongo/project_test.go b/server/internal/infrastructure/mongo/project_test.go index c236589d1a..3ca5a2eef0 100644 --- a/server/internal/infrastructure/mongo/project_test.go +++ b/server/internal/infrastructure/mongo/project_test.go @@ -17,6 +17,34 @@ import ( "go.mongodb.org/mongo-driver/bson" ) +func TestProject_FindByIDs(t *testing.T) { + c := mongotest.Connect(t)(t) + ctx := context.Background() + pid := id.NewProjectID() + pid2 := id.NewProjectID() + wid := id.NewWorkspaceID() + wid2 := id.NewWorkspaceID() + _, _ = c.Collection("project").InsertMany(ctx, []any{ + bson.M{"id": pid.String(), "team": wid.String()}, + bson.M{"id": pid2.String(), "team": wid2.String()}, + }) + + r := NewProject(mongox.NewClientWithDatabase(c)) + got, err := r.FindByIDs(ctx, id.ProjectIDList{pid}) + assert.NoError(t, err) + assert.Equal(t, 1, len(got)) + assert.Equal(t, pid, got[0].ID()) + + r2 := r.Filtered(repo.WorkspaceFilter{ + Readable: id.WorkspaceIDList{wid2}, + }) + got, err = r2.FindByIDs(ctx, id.ProjectIDList{pid, pid2}) + assert.NoError(t, err) + assert.Equal(t, 2, len(got)) + assert.Nil(t, got[0]) + assert.Equal(t, pid2, got[1].ID()) +} + func TestProject_CountByWorkspace(t *testing.T) { c := mongotest.Connect(t)(t) ctx := context.Background() diff --git a/server/internal/infrastructure/mongo/property.go b/server/internal/infrastructure/mongo/property.go index 39416bb87d..2cb0d7b6be 100644 --- a/server/internal/infrastructure/mongo/property.go +++ b/server/internal/infrastructure/mongo/property.go @@ -10,6 +10,7 @@ import ( "github.com/reearth/reearthx/log" "github.com/reearth/reearthx/mongox" "github.com/reearth/reearthx/rerror" + "github.com/samber/lo" "go.mongodb.org/mongo-driver/bson" ) @@ -74,24 +75,15 @@ func (r *Property) FindByIDs(ctx context.Context, ids id.PropertyIDList) (proper "$in": ids.Strings(), }, } - c := mongodoc.NewPropertyConsumer() + + c := mongodoc.NewPropertyConsumer(r.f.Readable) if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } - readableScenes := make(map[id.SceneID]struct{}) - for _, sceneID := range r.f.Readable { - readableScenes[sceneID] = struct{}{} - } - if len(readableScenes) != len(r.f.Readable) { - log.Warnc(ctx, "readable id list is not unique") - } - res := c.Result[:0] - for _, col := range c.Result { - if _, ok := readableScenes[col.Scene()]; ok { - res = append(res, col) - } - } - return filterProperties(ids, res), nil + + log.Debugfc(ctx, "mongo: property.FindByIDs: len(c.Result)=%d len(ids)=%d len(readable)=%d len(uniq readable)=%d", len(c.Result), len(ids), len(r.f.Readable), len(lo.Uniq(r.f.Readable))) + + return filterProperties(ids, c.Result), nil } func (r *Property) FindLinkedAll(ctx context.Context, id id.SceneID) (property.List, error) { @@ -208,16 +200,16 @@ func (r *Property) RemoveByScene(ctx context.Context, sceneID id.SceneID) error } func (r *Property) find(ctx context.Context, filter any) (property.List, error) { - c := mongodoc.NewPropertyConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewPropertyConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return c.Result, nil } func (r *Property) findOne(ctx context.Context, filter any) (*property.Property, error) { - c := mongodoc.NewPropertyConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewPropertyConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return c.Result[0], nil @@ -238,9 +230,9 @@ func filterProperties(ids []id.PropertyID, rows property.List) property.List { return res } -func (r *Property) readFilter(filter any) any { - return applySceneFilter(filter, r.f.Readable) -} +// func (r *Property) readFilter(filter any) any { +// return applySceneFilter(filter, r.f.Readable) +// } func (r *Property) writeFilter(filter any) any { return applySceneFilter(filter, r.f.Writable) diff --git a/server/internal/infrastructure/mongo/property_schema.go b/server/internal/infrastructure/mongo/property_schema.go index d4ccbeeebe..17d8effeae 100644 --- a/server/internal/infrastructure/mongo/property_schema.go +++ b/server/internal/infrastructure/mongo/property_schema.go @@ -125,24 +125,24 @@ func (r *PropertySchema) RemoveAll(ctx context.Context, ids []id.PropertySchemaI } func (r *PropertySchema) find(ctx context.Context, dst property.SchemaList, filter any) (property.SchemaList, error) { - c := mongodoc.NewPropertySchemaConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewPropertySchemaConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return c.Result, nil } func (r *PropertySchema) findOne(ctx context.Context, filter any) (*property.Schema, error) { - c := mongodoc.NewPropertySchemaConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewPropertySchemaConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return c.Result[0], nil } -func (r *PropertySchema) readFilter(filter any) any { - return applyOptionalSceneFilter(filter, r.f.Readable) -} +// func (r *PropertySchema) readFilter(filter any) any { +// return applyOptionalSceneFilter(filter, r.f.Readable) +// } func (r *PropertySchema) writeFilter(filter any) any { return applyOptionalSceneFilter(filter, r.f.Writable) diff --git a/server/internal/infrastructure/mongo/scene.go b/server/internal/infrastructure/mongo/scene.go index 837091018b..52357b807d 100644 --- a/server/internal/infrastructure/mongo/scene.go +++ b/server/internal/infrastructure/mongo/scene.go @@ -91,24 +91,24 @@ func (r *Scene) Remove(ctx context.Context, id id.SceneID) error { } func (r *Scene) find(ctx context.Context, filter interface{}) ([]*scene.Scene, error) { - c := mongodoc.NewSceneConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewSceneConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return c.Result, nil } func (r *Scene) findOne(ctx context.Context, filter any) (*scene.Scene, error) { - c := mongodoc.NewSceneConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewSceneConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return c.Result[0], nil } -func (r *Scene) readFilter(filter any) any { - return applyWorkspaceFilter(filter, r.f.Readable) -} +// func (r *Scene) readFilter(filter any) any { +// return applyWorkspaceFilter(filter, r.f.Readable) +// } func (r *Scene) writeFilter(filter any) any { return applyWorkspaceFilter(filter, r.f.Writable) diff --git a/server/internal/infrastructure/mongo/tag.go b/server/internal/infrastructure/mongo/tag.go index 271420525c..f8460bd621 100644 --- a/server/internal/infrastructure/mongo/tag.go +++ b/server/internal/infrastructure/mongo/tag.go @@ -166,16 +166,16 @@ func (r *Tag) RemoveByScene(ctx context.Context, sceneID id.SceneID) error { } func (r *Tag) find(ctx context.Context, filter any) ([]*tag.Tag, error) { - c := mongodoc.NewTagConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewTagConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return lo.ToSlicePtr(c.Result), nil } func (r *Tag) findOne(ctx context.Context, filter any) (tag.Tag, error) { - c := mongodoc.NewTagConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewTagConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } if len(c.Result) == 0 { @@ -185,32 +185,32 @@ func (r *Tag) findOne(ctx context.Context, filter any) (tag.Tag, error) { } func (r *Tag) findItemOne(ctx context.Context, filter any) (*tag.Item, error) { - c := mongodoc.NewTagConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewTagConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return tag.ToTagItem(c.Result[0]), nil } func (r *Tag) findGroupOne(ctx context.Context, filter any) (*tag.Group, error) { - c := mongodoc.NewTagConsumer() - if err := r.client.FindOne(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewTagConsumer(r.f.Readable) + if err := r.client.FindOne(ctx, filter, c); err != nil { return nil, err } return tag.ToTagGroup(c.Result[0]), nil } func (r *Tag) findItems(ctx context.Context, filter any) ([]*tag.Item, error) { - c := mongodoc.NewTagConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewTagConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return tag.List(c.Result).Items(), nil } func (r *Tag) findGroups(ctx context.Context, filter any) ([]*tag.Group, error) { - c := mongodoc.NewTagConsumer() - if err := r.client.Find(ctx, r.readFilter(filter), c); err != nil { + c := mongodoc.NewTagConsumer(r.f.Readable) + if err := r.client.Find(ctx, filter, c); err != nil { return nil, err } return tag.List(c.Result).Groups(), nil @@ -264,9 +264,9 @@ func filterTagGroups(ids id.TagIDList, rows []*tag.Group) []*tag.Group { return res } -func (r *Tag) readFilter(filter any) any { - return applySceneFilter(filter, r.f.Readable) -} +// func (r *Tag) readFilter(filter any) any { +// return applySceneFilter(filter, r.f.Readable) +// } func (r *Tag) writeFilter(filter any) any { return applySceneFilter(filter, r.f.Writable) diff --git a/server/internal/usecase/repo/container.go b/server/internal/usecase/repo/container.go index 428d057c7d..cfb13e14ea 100644 --- a/server/internal/usecase/repo/container.go +++ b/server/internal/usecase/repo/container.go @@ -84,18 +84,20 @@ func (f WorkspaceFilter) Merge(g WorkspaceFilter) WorkspaceFilter { var r, w user.WorkspaceIDList if f.Readable != nil || g.Readable != nil { if f.Readable == nil { - r = append(g.Readable[:0:0], g.Readable...) + r = g.Readable.Clone() } else { - r = append(f.Readable, g.Readable...) + r = f.Readable.AddUniq(g.Readable...) } } + if f.Writable != nil || g.Writable != nil { if f.Writable == nil { - w = append(g.Writable[:0:0], g.Writable...) + w = g.Writable.Clone() } else { - w = append(f.Writable, g.Writable...) + w = f.Writable.AddUniq(g.Writable...) } } + return WorkspaceFilter{ Readable: r, Writable: w, @@ -124,20 +126,23 @@ func SceneFilterFromOperator(o *usecase.Operator) SceneFilter { func (f SceneFilter) Merge(g SceneFilter) SceneFilter { var r, w scene.IDList + if f.Readable != nil || g.Readable != nil { if f.Readable == nil { - r = append(g.Readable[:0:0], g.Readable...) + r = g.Readable.Clone() } else { - r = append(f.Readable, g.Readable...) + r = f.Readable.AddUniq(g.Readable...) } } + if f.Writable != nil || g.Writable != nil { if f.Writable == nil { - w = append(g.Writable[:0:0], g.Writable...) + w = g.Writable.Clone() } else { - w = append(f.Writable, g.Writable...) + w = f.Writable.AddUniq(g.Writable...) } } + return SceneFilter{ Readable: r, Writable: w, diff --git a/server/internal/usecase/repo/container_test.go b/server/internal/usecase/repo/container_test.go index 6bb15c8516..2c74f87947 100644 --- a/server/internal/usecase/repo/container_test.go +++ b/server/internal/usecase/repo/container_test.go @@ -15,7 +15,7 @@ func TestWorkspaceFilter_Merge(t *testing.T) { Readable: user.WorkspaceIDList{a, b}, Writable: user.WorkspaceIDList{b, a}, }, WorkspaceFilter{ - Readable: user.WorkspaceIDList{a}, + Readable: user.WorkspaceIDList{a, b}, Writable: user.WorkspaceIDList{b}, }.Merge(WorkspaceFilter{ Readable: user.WorkspaceIDList{b}, @@ -34,7 +34,7 @@ func TestSceneFilter_Merge(t *testing.T) { Readable: scene.IDList{a, b}, Writable: scene.IDList{b, a}, }, SceneFilter{ - Readable: scene.IDList{a}, + Readable: scene.IDList{a, b}, Writable: scene.IDList{b}, }.Merge(SceneFilter{ Readable: scene.IDList{b}, diff --git a/server/pkg/tag/group_builder.go b/server/pkg/tag/group_builder.go index e84d28f3e5..75cd658974 100644 --- a/server/pkg/tag/group_builder.go +++ b/server/pkg/tag/group_builder.go @@ -58,6 +58,10 @@ func (b *GroupBuilder) Scene(sid SceneID) *GroupBuilder { } func (b *GroupBuilder) Tags(tl IDList) *GroupBuilder { + if len(tl) == 0 { + b.g.tags = nil + return b + } b.g.tags = tl.Clone() return b }