github.com/tufanbarisyildirim/pop@v4.13.1+incompatible/validations.go (about)

     1  package pop
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/gobuffalo/validate"
     7  )
     8  
     9  type beforeValidatable interface {
    10  	BeforeValidations(*Connection) error
    11  }
    12  
    13  type validateable interface {
    14  	Validate(*Connection) (*validate.Errors, error)
    15  }
    16  
    17  type modelIterableValidator func(*Model) (*validate.Errors, error)
    18  
    19  func (m *Model) validate(c *Connection) (*validate.Errors, error) {
    20  	if x, ok := m.Value.(beforeValidatable); ok {
    21  		if err := x.BeforeValidations(c); err != nil {
    22  			return validate.NewErrors(), err
    23  		}
    24  	}
    25  	if x, ok := m.Value.(validateable); ok {
    26  		return x.Validate(c)
    27  	}
    28  	return validate.NewErrors(), nil
    29  }
    30  
    31  type validateCreateable interface {
    32  	ValidateCreate(*Connection) (*validate.Errors, error)
    33  }
    34  
    35  func (m *Model) validateCreate(c *Connection) (*validate.Errors, error) {
    36  	return m.iterateAndValidate(func(model *Model) (*validate.Errors, error) {
    37  		verrs, err := model.validate(c)
    38  		if err != nil {
    39  			return verrs, err
    40  		}
    41  		if x, ok := model.Value.(validateCreateable); ok {
    42  			vs, err := x.ValidateCreate(c)
    43  			if vs != nil {
    44  				verrs.Append(vs)
    45  			}
    46  			if err != nil {
    47  				return verrs, err
    48  			}
    49  		}
    50  
    51  		return verrs, err
    52  	})
    53  }
    54  
    55  func (m *Model) validateAndOnlyCreate(c *Connection) (*validate.Errors, error) {
    56  	return m.iterateAndValidate(func(model *Model) (*validate.Errors, error) {
    57  		id, err := model.fieldByName("ID")
    58  		if err != nil {
    59  			return nil, err
    60  		}
    61  		if !IsZeroOfUnderlyingType(id.Interface()) {
    62  			return validate.NewErrors(), nil
    63  		}
    64  
    65  		verrs, err := model.validate(c)
    66  		if err != nil {
    67  			return verrs, err
    68  		}
    69  		if x, ok := model.Value.(validateCreateable); ok {
    70  			vs, err := x.ValidateCreate(c)
    71  			if vs != nil {
    72  				verrs.Append(vs)
    73  			}
    74  			if err != nil {
    75  				return verrs, err
    76  			}
    77  		}
    78  
    79  		return verrs, err
    80  	})
    81  }
    82  
    83  type validateSaveable interface {
    84  	ValidateSave(*Connection) (*validate.Errors, error)
    85  }
    86  
    87  func (m *Model) validateSave(c *Connection) (*validate.Errors, error) {
    88  	return m.iterateAndValidate(func(model *Model) (*validate.Errors, error) {
    89  		verrs, err := model.validate(c)
    90  		if err != nil {
    91  			return verrs, err
    92  		}
    93  		if x, ok := model.Value.(validateSaveable); ok {
    94  			vs, err := x.ValidateSave(c)
    95  			if vs != nil {
    96  				verrs.Append(vs)
    97  			}
    98  			if err != nil {
    99  				return verrs, err
   100  			}
   101  		}
   102  
   103  		return verrs, err
   104  	})
   105  }
   106  
   107  type validateUpdateable interface {
   108  	ValidateUpdate(*Connection) (*validate.Errors, error)
   109  }
   110  
   111  func (m *Model) validateUpdate(c *Connection) (*validate.Errors, error) {
   112  	return m.iterateAndValidate(func(model *Model) (*validate.Errors, error) {
   113  		verrs, err := model.validate(c)
   114  		if err != nil {
   115  			return verrs, err
   116  		}
   117  		if x, ok := model.Value.(validateUpdateable); ok {
   118  			vs, err := x.ValidateUpdate(c)
   119  			if vs != nil {
   120  				verrs.Append(vs)
   121  			}
   122  			if err != nil {
   123  				return verrs, err
   124  			}
   125  		}
   126  
   127  		return verrs, err
   128  	})
   129  }
   130  
   131  func (m *Model) iterateAndValidate(fn modelIterableValidator) (*validate.Errors, error) {
   132  	v := reflect.Indirect(reflect.ValueOf(m.Value))
   133  	if v.Kind() == reflect.Slice || v.Kind() == reflect.Array {
   134  		for i := 0; i < v.Len(); i++ {
   135  			val := v.Index(i)
   136  			newModel := &Model{Value: val.Addr().Interface()}
   137  			verrs, err := fn(newModel)
   138  
   139  			if err != nil || verrs.HasAny() {
   140  				return verrs, err
   141  			}
   142  		}
   143  		return validate.NewErrors(), nil
   144  	}
   145  
   146  	return fn(m)
   147  }