github.com/goravel/framework@v1.13.9/database/factory.go (about) 1 package database 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 8 "github.com/mitchellh/mapstructure" 9 10 "github.com/goravel/framework/contracts/database/factory" 11 ormcontract "github.com/goravel/framework/contracts/database/orm" 12 ) 13 14 type FactoryImpl struct { 15 count *int // number of models to generate 16 query ormcontract.Query // query instance 17 } 18 19 func NewFactoryImpl(query ormcontract.Query) *FactoryImpl { 20 return &FactoryImpl{ 21 query: query, 22 } 23 } 24 25 // Count Specify the number of models you wish to create / make. 26 func (f *FactoryImpl) Count(count int) ormcontract.Factory { 27 return f.newInstance(map[string]any{"count": count}) 28 } 29 30 // Create a model and persist it in the database. 31 func (f *FactoryImpl) Create(value any, attributes ...map[string]any) error { 32 if err := f.Make(value, attributes...); err != nil { 33 return err 34 } 35 36 return f.query.Create(value) 37 } 38 39 // CreateQuietly create a model and persist it in the database without firing any events. 40 func (f *FactoryImpl) CreateQuietly(value any, attributes ...map[string]any) error { 41 if err := f.Make(value, attributes...); err != nil { 42 return err 43 } 44 45 return f.query.WithoutEvents().Create(value) 46 } 47 48 // Make a model instance that's not persisted in the database. 49 func (f *FactoryImpl) Make(value any, attributes ...map[string]any) error { 50 reflectValue := reflect.Indirect(reflect.ValueOf(value)) 51 switch reflectValue.Kind() { 52 case reflect.Array, reflect.Slice: 53 count := 1 54 if f.count != nil { 55 count = *f.count 56 } 57 for i := 0; i < count; i++ { 58 elemValue := reflect.New(reflectValue.Type().Elem()).Interface() 59 attributes, err := f.getRawAttributes(elemValue, attributes...) 60 if err != nil { 61 return err 62 } 63 if attributes == nil { 64 return errors.New("failed to get raw attributes") 65 } 66 decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ 67 Squash: true, 68 Result: elemValue, 69 }) 70 if err != nil { 71 return err 72 } 73 if err := decoder.Decode(attributes); err != nil { 74 return err 75 } 76 reflectValue = reflect.Append(reflectValue, reflect.ValueOf(elemValue).Elem()) 77 } 78 79 reflect.ValueOf(value).Elem().Set(reflectValue) 80 81 return nil 82 default: 83 attributes, err := f.getRawAttributes(value, attributes...) 84 if err != nil { 85 return err 86 } 87 if attributes == nil { 88 return errors.New("failed to get raw attributes") 89 } 90 decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ 91 Squash: true, 92 Result: value, 93 }) 94 if err != nil { 95 return err 96 } 97 98 return decoder.Decode(attributes) 99 } 100 } 101 102 func (f *FactoryImpl) getRawAttributes(value any, attributes ...map[string]any) (map[string]any, error) { 103 factoryModel, exist := value.(factory.Model) 104 if !exist { 105 return nil, fmt.Errorf("%s does not find factory method", reflect.TypeOf(value).String()) 106 } 107 108 definition := factoryModel.Factory().Definition() 109 if len(attributes) > 0 { 110 for key, value := range attributes[0] { 111 definition[key] = value 112 } 113 } 114 115 return definition, nil 116 } 117 118 // newInstance create a new factory instance. 119 func (f *FactoryImpl) newInstance(attributes ...map[string]any) ormcontract.Factory { 120 instance := &FactoryImpl{ 121 count: f.count, 122 query: f.query, 123 } 124 125 if len(attributes) > 0 { 126 attr := attributes[0] 127 if count, ok := attr["count"].(int); ok { 128 instance.count = &count 129 } 130 } 131 132 return instance 133 }