package storage import ( "context" "errors" "fmt" "local/dndex/config" "local/dndex/storage/driver" "local/dndex/storage/entity" "local/dndex/storage/operator" "strings" "go.mongodb.org/mongo-driver/bson" ) type Graph struct { driver driver.Driver } func NewGraph() Graph { var d driver.Driver switch strings.ToLower(config.New().DriverType) { case "mongo": d = driver.NewMongo() case "boltdb": d = driver.NewBoltDB() } return Graph{ driver: d, } } func (g Graph) Search(ctx context.Context, namespace string, nameContains string) ([]entity.One, error) { filter := operator.Regex{Key: entity.Name, Value: fmt.Sprintf(".*%s.*", nameContains)} return g.find(ctx, namespace, filter) } func (g Graph) ListCaseInsensitive(ctx context.Context, namespace string, from ...string) ([]entity.One, error) { if len(from) == 0 { return g.List(ctx, namespace) } pattern := strings.Join(from, "|") pattern = "^(?i)(" + pattern + ")" filter := operator.Regex{Key: entity.Name, Value: pattern} return g.find(ctx, namespace, filter) } func (g Graph) List(ctx context.Context, namespace string, from ...string) ([]entity.One, error) { filter := operator.NewFilterIn(entity.Name, from) return g.find(ctx, namespace, filter) } func (g Graph) find(ctx context.Context, namespace string, filter interface{}) ([]entity.One, error) { ch, err := g.driver.Find(ctx, namespace, filter) if err != nil { return nil, err } return g.gatherOnes(ctx, ch) } func (g Graph) gatherOnes(ctx context.Context, ch <-chan bson.Raw) ([]entity.One, error) { var ones []entity.One for one := range ch { var o entity.One if err := bson.Unmarshal(one, &o); err != nil { return nil, err } ones = append(ones, o) } return ones, nil } func (g Graph) Insert(ctx context.Context, namespace string, one entity.One) error { if ones, err := g.ListCaseInsensitive(ctx, namespace, one.Name); err != nil { return err } else if len(ones) > 0 { return errors.New("collision on primary key when case insensitive") } return g.driver.Insert(ctx, namespace, one) } func (g Graph) Update(ctx context.Context, namespace string, one entity.One, modify interface{}) error { return g.driver.Update(ctx, namespace, one, modify) } func (g Graph) Delete(ctx context.Context, namespace string, filter interface{}) error { return g.driver.Delete(ctx, namespace, filter) }