From 924a688a9d3fcaf9a661933a71e69f9c8add31d3 Mon Sep 17 00:00:00 2001 From: mr Date: Thu, 1 Aug 2024 09:13:10 +0200 Subject: [PATCH] COMPLEX SEARCH --- dbs/dbs.go | 83 +++++++++++++++++++ dbs/mongo/mongo.go | 50 ++++------- entrypoint.go | 9 +- .../resource_model_mongo_accessor.go | 13 ++- models/resources/data/data_mongo_accessor.go | 23 +++-- .../datacenter/datacenter_mongo_accessor.go | 23 +++-- .../processing/processing_mongo_accessor.go | 23 +++-- .../storage/storage_mongo_accessor.go | 23 +++-- .../workflow/workflow_mongo_accessor.go | 23 +++-- models/utils/abstracts.go | 15 +++- models/utils/interfaces.go | 4 +- models/workflow/workflow_mongo_accessor.go | 20 +++-- .../workflow_execution_mongo_accessor.go | 8 +- models/workspace/workspace_mongo_accessor.go | 13 ++- 14 files changed, 240 insertions(+), 90 deletions(-) diff --git a/dbs/dbs.go b/dbs/dbs.go index 11d8769..3403615 100644 --- a/dbs/dbs.go +++ b/dbs/dbs.go @@ -1,9 +1,92 @@ package dbs import ( + "fmt" + "strings" + "go.mongodb.org/mongo-driver/bson" ) +type Operator int + +const ( + LIKE Operator = iota + EXISTS + IN + GTE + LTE + LT + GT + EQUAL +) + +var str = [...]string{ + "like", + "exists", + "in", + "gte", + "lte", + "lt", + "gt", + "equal", +} + +func (m Operator) String() string { + return str[m] +} + +func (m Operator) ToMongoOperator() string { + switch m { + case LIKE: + return "$regex" + case EXISTS: + return "$exists" + case IN: + return "$in" + case GTE: + return "$gte" + case GT: + return "$gt" + case LTE: + return "$lte" + case LT: + return "$lt" + case EQUAL: + return "$match" + default: + return "$regex" + } +} + +func StringToOperator(s string) Operator { + for i, v := range str { + if v == s { + return Operator(i) + } + } + return LIKE +} + +func ToValueOperator(operator Operator, value interface{}) interface{} { + if strings.TrimSpace(fmt.Sprintf("%v", value)) == "*" { + value = "" + } + if operator == LIKE { + return "(?i).*" + strings.TrimSpace(fmt.Sprintf("%v", value)) + ".*" + } + return value +} + +type Filters struct { + And map[string]Filter `json:"and"` + Or map[string]Filter `json:"or"` +} + +type Filter struct { + Operator string `json:"operator,omitempty"` + Value interface{} `json:"value,omitempty"` +} + type Input = map[string]interface{} func InputToBson(i Input, isUpdate bool) bson.D { diff --git a/dbs/mongo/mongo.go b/dbs/mongo/mongo.go index 607fdf7..9e77173 100644 --- a/dbs/mongo/mongo.go +++ b/dbs/mongo/mongo.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "strings" "time" "cloud.o-forge.io/core/oc-lib/dbs" @@ -261,27 +260,35 @@ func (m *MongoDB) LoadOne(id string, collection_name string) (*mongo.SingleResul return res, 200, nil } -func (m *MongoDB) Search(search string, filter []string, collection_name string) (*mongo.Cursor, int, error) { +func (m *MongoDB) Search(filters dbs.Filters, collection_name string) (*mongo.Cursor, int, error) { if err := m.createClient(mngoConfig.GetUrl()); err != nil { return nil, 503, err } opts := options.Find() opts.SetLimit(100) - if strings.TrimSpace(search) == "*" { - search = "" - } - search = ".*" + strings.TrimSpace(search) + ".*" targetDBCollection := CollectionMap[collection_name] - list := []bson.M{} - for _, k := range filter { - list = append(list, bson.M{k: bson.M{"$regex": search, "$options": "i"}}) + andList := []bson.E{} + for k, filter := range filters.And { + andList = append(andList, bson.E{Key: k, Value: bson.M{ + dbs.StringToOperator(filter.Operator).ToMongoOperator(): dbs.ToValueOperator(dbs.StringToOperator(filter.Operator), filter.Value)}}) + } + orList := []bson.M{} + for k, filter := range filters.Or { + orList = append(orList, bson.M{ + k: bson.M{dbs.StringToOperator(filter.Operator).ToMongoOperator(): dbs.ToValueOperator(dbs.StringToOperator(filter.Operator), filter.Value)}}) } MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - + f := bson.D{} + if len(andList) > 0 { + f = append(f, andList...) + } + if len(orList) > 0 { + f = append(f, bson.E{Key: "$or", Value: orList}) + } if cursor, err := targetDBCollection.Find( MngoCtx, - bson.M{"$or": list}, + f, opts, ); err != nil { return nil, 404, err @@ -327,24 +334,3 @@ func (m *MongoDB) LoadAll(collection_name string) (*mongo.Cursor, int, error) { } return res, 200, nil } - -func (m *MongoDB) toOperator(operator string) string { - if operator == "like" { - return "$regex" - } else if operator == "exists" { - return "$exists" - } else if operator == "in" { - return "$in" - } else if operator == "gte" { - return "$gte" - } else if operator == "gt" { - return "$gt" - } else if operator == "lte" { - return "$lte" - } else if operator == "lt" { - return "$lt" - } else if operator == "eq" { - return "$match" - } - return operator -} diff --git a/entrypoint.go b/entrypoint.go index de24b42..2c58448 100644 --- a/entrypoint.go +++ b/entrypoint.go @@ -3,6 +3,7 @@ package oclib import ( "fmt" + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/logs" "cloud.o-forge.io/core/oc-lib/models" @@ -19,6 +20,8 @@ import ( "github.com/rs/zerolog" ) +type Filters = dbs.Filters + type LibDataEnum int const ( @@ -58,7 +61,7 @@ func Init(appName string) { mongo.MONGOService.Init(models.GetModelsNames(), GetConfig()) accessor := (&resource_model.ResourceModel{}).GetAccessor() for _, model := range []string{utils.DATA_RESOURCE.String(), utils.PROCESSING_RESOURCE.String(), utils.STORAGE_RESOURCE.String(), utils.DATACENTER_RESOURCE.String(), utils.WORKFLOW_RESOURCE.String()} { - data, code, _ := accessor.Search(model) + data, code, _ := accessor.Search(nil, model) if code == 404 || len(data) == 0 { m := map[string]resource_model.Model{} if model == utils.PROCESSING_RESOURCE.String() { @@ -87,8 +90,8 @@ func GetLogger() zerolog.Logger { return logs.GetLogger() } -func Search(word string, collection LibDataEnum) LibDataShallow { - d, code, err := models.Model(collection.EnumIndex()).GetAccessor().Search(word) +func Search(filters *dbs.Filters, word string, collection LibDataEnum) LibDataShallow { + d, code, err := models.Model(collection.EnumIndex()).GetAccessor().Search(filters, word) if err != nil { return LibDataShallow{Data: d, Code: code, Err: err.Error()} } diff --git a/models/resource_model/resource_model_mongo_accessor.go b/models/resource_model/resource_model_mongo_accessor.go index 73e5704..285e146 100644 --- a/models/resource_model/resource_model_mongo_accessor.go +++ b/models/resource_model/resource_model_mongo_accessor.go @@ -1,6 +1,7 @@ package resource_model import ( + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/utils" ) @@ -53,12 +54,16 @@ func (wfa ResourceModelMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, e return objs, 200, nil } -func (wfa *ResourceModelMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *ResourceModelMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{"resource_type"} + if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { + filters = &dbs.Filters{ + Or: map[string]dbs.Filter{ + "resource_type": {Operator: dbs.LIKE.String(), Value: search}, + }, + } } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(*filters, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err diff --git a/models/resources/data/data_mongo_accessor.go b/models/resources/data/data_mongo_accessor.go index 79faf36..352053b 100644 --- a/models/resources/data/data_mongo_accessor.go +++ b/models/resources/data/data_mongo_accessor.go @@ -1,6 +1,7 @@ package data import ( + "cloud.o-forge.io/core/oc-lib/dbs" mongo "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/resource_model" "cloud.o-forge.io/core/oc-lib/models/utils" @@ -41,7 +42,7 @@ func (dma *dataMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) { } res_mongo.Decode(&data) accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(dma.GetType()) + resources, _, err := accessor.Search(nil, dma.GetType()) if err == nil && len(resources) > 0 { data.ResourceModel = resources[0].(*resource_model.ResourceModel) } @@ -60,7 +61,7 @@ func (wfa dataMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) @@ -70,12 +71,20 @@ func (wfa dataMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) { return objs, 200, nil } -func (wfa *dataMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *dataMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{"abstractresource.abstractobject.name", "abstractresource.short_description", "abstractresource.description", "abstractresource.owner", "abstractresource.source_url"} + if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { + filters = &dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractresource.abstractobject.name": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.short_description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.owner": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.source_url": {Operator: dbs.LIKE.String(), Value: search}, + }, + } } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(*filters, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err @@ -85,7 +94,7 @@ func (wfa *dataMongoAccessor) Search(word string, options ...string) ([]utils.Sh return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) diff --git a/models/resources/datacenter/datacenter_mongo_accessor.go b/models/resources/datacenter/datacenter_mongo_accessor.go index cb4b2be..6758160 100644 --- a/models/resources/datacenter/datacenter_mongo_accessor.go +++ b/models/resources/datacenter/datacenter_mongo_accessor.go @@ -1,6 +1,7 @@ package datacenter import ( + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/resource_model" "cloud.o-forge.io/core/oc-lib/models/utils" @@ -43,7 +44,7 @@ func (dca *datacenterMongoAccessor) LoadOne(id string) (utils.DBObject, int, err res_mongo.Decode(&datacenter) accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(dca.GetType()) + resources, _, err := accessor.Search(nil, dca.GetType()) if err == nil && len(resources) > 0 { datacenter.ResourceModel = resources[0].(*resource_model.ResourceModel) } @@ -62,7 +63,7 @@ func (wfa datacenterMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, erro return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) @@ -72,12 +73,20 @@ func (wfa datacenterMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, erro return objs, 200, nil } -func (wfa *datacenterMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *datacenterMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{"abstractresource.abstractobject.name", "abstractresource.short_description", "abstractresource.description", "abstractresource.owner", "abstractresource.source_url"} + if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { + filters = &dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractresource.abstractobject.name": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.short_description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.owner": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.source_url": {Operator: dbs.LIKE.String(), Value: search}, + }, + } } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(*filters, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err @@ -87,7 +96,7 @@ func (wfa *datacenterMongoAccessor) Search(word string, options ...string) ([]ut return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) diff --git a/models/resources/processing/processing_mongo_accessor.go b/models/resources/processing/processing_mongo_accessor.go index 009ad14..af52d4f 100644 --- a/models/resources/processing/processing_mongo_accessor.go +++ b/models/resources/processing/processing_mongo_accessor.go @@ -1,6 +1,7 @@ package processing import ( + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/resource_model" "cloud.o-forge.io/core/oc-lib/models/utils" @@ -44,7 +45,7 @@ func (pma *processingMongoAccessor) LoadOne(id string) (utils.DBObject, int, err res_mongo.Decode(&processing) accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(pma.GetType()) + resources, _, err := accessor.Search(nil, pma.GetType()) if err == nil && len(resources) > 0 { processing.ResourceModel = resources[0].(*resource_model.ResourceModel) } @@ -63,7 +64,7 @@ func (wfa processingMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, erro return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) @@ -73,12 +74,20 @@ func (wfa processingMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, erro return objs, 200, nil } -func (wfa *processingMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *processingMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{"abstractresource.abstractobject.name", "abstractresource.short_description", "abstractresource.description", "abstractresource.owner", "abstractresource.source_url"} + if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { + filters = &dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractresource.abstractobject.name": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.short_description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.owner": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.source_url": {Operator: dbs.LIKE.String(), Value: search}, + }, + } } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(*filters, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err @@ -88,7 +97,7 @@ func (wfa *processingMongoAccessor) Search(word string, options ...string) ([]ut return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) diff --git a/models/resources/storage/storage_mongo_accessor.go b/models/resources/storage/storage_mongo_accessor.go index 7ee2d39..88816e5 100644 --- a/models/resources/storage/storage_mongo_accessor.go +++ b/models/resources/storage/storage_mongo_accessor.go @@ -1,6 +1,7 @@ package storage import ( + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/resource_model" "cloud.o-forge.io/core/oc-lib/models/utils" @@ -44,7 +45,7 @@ func (sma *storageMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) res_mongo.Decode(&storage) accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(sma.GetType()) + resources, _, err := accessor.Search(nil, sma.GetType()) if err == nil && len(resources) > 0 { storage.ResourceModel = resources[0].(*resource_model.ResourceModel) } @@ -63,7 +64,7 @@ func (wfa storageMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) @@ -73,12 +74,20 @@ func (wfa storageMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) return objs, 200, nil } -func (wfa *storageMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *storageMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{"abstractresource.abstractobject.name", "abstractresource.short_description", "abstractresource.description", "abstractresource.owner", "abstractresource.source_url"} + if (len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { + filters = &dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractresource.abstractobject.name": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.short_description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.owner": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.source_url": {Operator: dbs.LIKE.String(), Value: search}, + }, + } } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(*filters, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err @@ -88,7 +97,7 @@ func (wfa *storageMongoAccessor) Search(word string, options ...string) ([]utils return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) diff --git a/models/resources/workflow/workflow_mongo_accessor.go b/models/resources/workflow/workflow_mongo_accessor.go index 43c8068..623f1a6 100644 --- a/models/resources/workflow/workflow_mongo_accessor.go +++ b/models/resources/workflow/workflow_mongo_accessor.go @@ -1,6 +1,7 @@ package oclib import ( + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/resource_model" "cloud.o-forge.io/core/oc-lib/models/utils" @@ -48,7 +49,7 @@ func (wfa *workflowResourceMongoAccessor) LoadOne(id string) (utils.DBObject, in } res_mongo.Decode(&workflow) accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) if err == nil && len(resources) > 0 { workflow.ResourceModel = resources[0].(*resource_model.ResourceModel) } @@ -67,7 +68,7 @@ func (wfa workflowResourceMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) @@ -77,12 +78,20 @@ func (wfa workflowResourceMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int return objs, 200, nil } -func (wfa *workflowResourceMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *workflowResourceMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{"abstractresource.abstractobject.name", "abstractresource.short_description", "abstractresource.description", "abstractresource.owner", "abstractresource.source_url"} + if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { + filters = &dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractresource.abstractobject.name": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.short_description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.description": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.owner": {Operator: dbs.LIKE.String(), Value: search}, + "abstractresource.source_url": {Operator: dbs.LIKE.String(), Value: search}, + }, + } } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(*filters, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err @@ -92,7 +101,7 @@ func (wfa *workflowResourceMongoAccessor) Search(word string, options ...string) return nil, 404, err } accessor := (&resource_model.ResourceModel{}).GetAccessor() - resources, _, err := accessor.Search(wfa.GetType()) + resources, _, err := accessor.Search(nil, wfa.GetType()) for _, r := range results { if err == nil && len(resources) > 0 { r.ResourceModel = resources[0].(*resource_model.ResourceModel) diff --git a/models/utils/abstracts.go b/models/utils/abstracts.go index 4d17af5..952fd48 100644 --- a/models/utils/abstracts.go +++ b/models/utils/abstracts.go @@ -3,6 +3,7 @@ package utils import ( "errors" + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/logs" "github.com/go-playground/validator/v10" @@ -45,7 +46,19 @@ func (dma *AbstractAccessor) SetLogger(t DataType) { func (wfa *AbstractAccessor) GenericStoreOne(data DBObject, accessor Accessor) (DBObject, int, error) { data.GenerateID() - if cursor, _, _ := accessor.Search(data.GetName(), "abstractresource.abstractobject.name", "abstractobject.name"); len(cursor) > 0 { + f := dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractresource.abstractobject.name": { + Operator: dbs.LIKE.String(), + Value: data.GetName(), + }, + "abstractobject.name": { + Operator: dbs.LIKE.String(), + Value: data.GetName(), + }, + }, + } + if cursor, _, _ := accessor.Search(&f, ""); len(cursor) > 0 { return nil, 409, errors.New(accessor.GetType() + " with name " + data.GetName() + " already exists") } err := validate.Struct(data) diff --git a/models/utils/interfaces.go b/models/utils/interfaces.go index 4125b3f..037ccc4 100644 --- a/models/utils/interfaces.go +++ b/models/utils/interfaces.go @@ -1,5 +1,7 @@ package utils +import "cloud.o-forge.io/core/oc-lib/dbs" + type ShallowDBObject interface { GenerateID() GetID() string @@ -18,7 +20,7 @@ type DBObject interface { type Accessor interface { SetLogger(t DataType) GetType() string - Search(word string, options ...string) ([]ShallowDBObject, int, error) + Search(filters *dbs.Filters, search string) ([]ShallowDBObject, int, error) LoadAll() ([]ShallowDBObject, int, error) LoadOne(id string) (DBObject, int, error) DeleteOne(id string) (DBObject, int, error) diff --git a/models/workflow/workflow_mongo_accessor.go b/models/workflow/workflow_mongo_accessor.go index b48d81b..e60f515 100644 --- a/models/workflow/workflow_mongo_accessor.go +++ b/models/workflow/workflow_mongo_accessor.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/resources" "cloud.o-forge.io/core/oc-lib/models/utils" @@ -100,7 +101,12 @@ func (wfa *workflowMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, func (wfa *workflowMongoAccessor) execute(workflow *Workflow) { accessor := (&workspace.Workspace{}).GetAccessor() - resource, _, err := accessor.Search(workflow.Name+"_workspace", "abstractobject.name") + filters := &dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractobject.name": {Operator: dbs.LIKE.String(), Value: workflow.Name + "_workspace"}, + }, + } + resource, _, err := accessor.Search(filters, "") if err == nil && len(resource) == 1 { accessor.UpdateOne(&workspace.Workspace{ Active: true, @@ -156,12 +162,16 @@ func (wfa workflowMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error) return objs, 200, nil } -func (wfa *workflowMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *workflowMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{"abstractobject.name"} + if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { + filters = &dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractobject.name": {Operator: dbs.LIKE.String(), Value: search}, + }, + } } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(*filters, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err diff --git a/models/workflow_execution/workflow_execution_mongo_accessor.go b/models/workflow_execution/workflow_execution_mongo_accessor.go index 5f01358..ee40f6e 100644 --- a/models/workflow_execution/workflow_execution_mongo_accessor.go +++ b/models/workflow_execution/workflow_execution_mongo_accessor.go @@ -1,6 +1,7 @@ package workflow_execution import ( + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/utils" ) @@ -57,12 +58,9 @@ func (wfa workflowExecutionMongoAccessor) LoadAll() ([]utils.ShallowDBObject, in return objs, 200, nil } -func (wfa *workflowExecutionMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *workflowExecutionMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{} - } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(dbs.Filters{}, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err diff --git a/models/workspace/workspace_mongo_accessor.go b/models/workspace/workspace_mongo_accessor.go index 667f10a..f9e7f38 100644 --- a/models/workspace/workspace_mongo_accessor.go +++ b/models/workspace/workspace_mongo_accessor.go @@ -1,6 +1,7 @@ package workspace import ( + "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/dbs/mongo" "cloud.o-forge.io/core/oc-lib/models/resources/data" "cloud.o-forge.io/core/oc-lib/models/resources/datacenter" @@ -135,12 +136,16 @@ func (wfa workspaceMongoAccessor) LoadAll() ([]utils.ShallowDBObject, int, error return objs, 200, nil } -func (wfa *workspaceMongoAccessor) Search(word string, options ...string) ([]utils.ShallowDBObject, int, error) { +func (wfa *workspaceMongoAccessor) Search(filters *dbs.Filters, search string) ([]utils.ShallowDBObject, int, error) { objs := []utils.ShallowDBObject{} - if len(options) == 0 { - options = []string{"abstractobject.name"} + if (filters == nil || len(filters.And) == 0 || len(filters.Or) == 0) && search != "" { + filters = &dbs.Filters{ + Or: map[string]dbs.Filter{ + "abstractobject.name": {Operator: dbs.LIKE.String(), Value: search}, + }, + } } - res_mongo, code, err := mongo.MONGOService.Search(word, options, wfa.GetType()) + res_mongo, code, err := mongo.MONGOService.Search(*filters, wfa.GetType()) if err != nil { wfa.Logger.Error().Msg("Could not store to db. Error: " + err.Error()) return nil, code, err