This is an automated email from the ASF dual-hosted git repository.

vinci pushed a commit to branch refactor
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git


The following commit(s) were added to refs/heads/refactor by this push:
     new 4df9d6d  feat: append stock check for generic store
4df9d6d is described below

commit 4df9d6d161230363301060565421d1f00d723c7b
Author: ShiningRush <277040...@qq.com>
AuthorDate: Sat Sep 19 11:17:00 2020 +0800

    feat: append stock check for generic store
---
 api/internal/core/store/store.go         | 32 ++++++++++++++------
 api/internal/core/store/store_test.go    | 51 ++++++++++++++++++++++++++++++++
 api/internal/core/store/validate_test.go |  4 +--
 3 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/api/internal/core/store/store.go b/api/internal/core/store/store.go
index 7296082..46793e6 100644
--- a/api/internal/core/store/store.go
+++ b/api/internal/core/store/store.go
@@ -20,10 +20,11 @@ type GenericStore struct {
 }
 
 type GenericStoreOption struct {
-       BasePath  string
-       ObjType   reflect.Type
-       KeyFunc   func(obj interface{}) string
-       Validator Validator
+       BasePath   string
+       ObjType    reflect.Type
+       KeyFunc    func(obj interface{}) string
+       StockCheck func(obj interface{}, stockObj interface{}) error
+       Validator  Validator
 }
 
 func NewGenericStore(opt GenericStoreOption) (*GenericStore, error) {
@@ -145,13 +146,28 @@ func (s *GenericStore) List(input ListInput) 
(*ListOutput, error) {
        return output, nil
 }
 
-func (s *GenericStore) Create(ctx context.Context, obj interface{}) error {
+func (s *GenericStore) ingestValidate(obj interface{}) error {
        if s.opt.Validator != nil {
                if err := s.opt.Validator.Validate(obj); err != nil {
                        return err
                }
        }
 
+       if s.opt.StockCheck != nil {
+               for k := range s.cache {
+                       if err := s.opt.StockCheck(obj, s.cache[k]); err != nil 
{
+                               return err
+                       }
+               }
+       }
+       return nil
+}
+
+func (s *GenericStore) Create(ctx context.Context, obj interface{}) error {
+       if err := s.ingestValidate(obj); err != nil {
+               return err
+       }
+
        key := s.opt.KeyFunc(obj)
        if key == "" {
                return fmt.Errorf("key is required")
@@ -173,10 +189,8 @@ func (s *GenericStore) Create(ctx context.Context, obj 
interface{}) error {
 }
 
 func (s *GenericStore) Update(ctx context.Context, obj interface{}) error {
-       if s.opt.Validator != nil {
-               if err := s.opt.Validator.Validate(obj); err != nil {
-                       return err
-               }
+       if err := s.ingestValidate(obj); err != nil {
+               return err
        }
 
        key := s.opt.KeyFunc(obj)
diff --git a/api/internal/core/store/store_test.go 
b/api/internal/core/store/store_test.go
index 4895258..536cc79 100644
--- a/api/internal/core/store/store_test.go
+++ b/api/internal/core/store/store_test.go
@@ -397,6 +397,57 @@ func TestGenericStore_List(t *testing.T) {
        }
 }
 
+func TestGenericStore_ingestValidate(t *testing.T) {
+       tests := []struct {
+               giveStore       *GenericStore
+               giveObj         interface{}
+               giveStockCheck  func(obj interface{}, stockObj interface{}) 
error
+               giveValidateErr error
+               wantErr         error
+       }{
+               {
+                       giveStore: &GenericStore{
+                               cache: map[string]interface{}{
+                                       "test1-f1": &TestStruct{Field1: 
"test1-f1", Field2: "test1-f2"},
+                                       "test2-f1": &TestStruct{Field1: 
"test2-f1", Field2: "test2-f2"},
+                               },
+                       },
+                       giveObj: &TestStruct{
+                               Field1: "test3-f1",
+                               Field2: "test2-f2",
+                       },
+                       giveStockCheck: func(obj interface{}, stockObj 
interface{}) error {
+                               if obj.(*TestStruct).Field2 == 
stockObj.(*TestStruct).Field2 {
+                                       return fmt.Errorf("field2: %s is 
conflicted", obj.(*TestStruct).Field2)
+                               }
+                               return nil
+                       },
+                       wantErr: fmt.Errorf("field2: test2-f2 is conflicted"),
+               },
+               {
+                       giveStore:       &GenericStore{},
+                       giveObj:         &TestStruct{},
+                       giveValidateErr: fmt.Errorf("validate failed"),
+                       wantErr:         fmt.Errorf("validate failed"),
+               },
+       }
+
+       for _, tc := range tests {
+               validateCalled := false
+               mValidator := &MockValidator{}
+               mValidator.On("Validate", mock.Anything).Run(func(args 
mock.Arguments) {
+                       validateCalled = true
+                       assert.Equal(t, tc.giveObj, args.Get(0))
+               }).Return(tc.giveValidateErr)
+
+               tc.giveStore.opt.Validator = mValidator
+               tc.giveStore.opt.StockCheck = tc.giveStockCheck
+               err := tc.giveStore.ingestValidate(tc.giveObj)
+               assert.True(t, validateCalled)
+               assert.Equal(t, tc.wantErr, err)
+       }
+}
+
 func TestGenericStore_Create(t *testing.T) {
        tests := []struct {
                caseDesc        string
diff --git a/api/internal/core/store/validate_test.go 
b/api/internal/core/store/validate_test.go
index f7d1ac9..bf5ab05 100644
--- a/api/internal/core/store/validate_test.go
+++ b/api/internal/core/store/validate_test.go
@@ -6,7 +6,7 @@ import (
        "testing"
 )
 
-type TestOjb struct {
+type TestObj struct {
        Name  string `json:"name"`
        Email string `json:"email"`
        Age   int    `json:"age"`
@@ -21,7 +21,7 @@ func TestJsonSchemaValidator_Validate(t *testing.T) {
        }{
                {
                        givePath: "./test_case.json",
-                       giveObj: TestOjb{
+                       giveObj: TestObj{
                                Name:  "lessName",
                                Email: "too long name greater than 10",
                                Age:   12,

Reply via email to