func (d *Driver) makeTable(m driver.Model) (*Table, error) { fields := m.Fields() names := fields.MNames qnames := fields.QNames ftypes := fields.Types tags := fields.Tags dbFields := make([]*Field, len(names)) for ii, v := range names { typ := ftypes[ii] tag := tags[ii] ft, err := d.backend.FieldType(typ, tag) if err != nil { return nil, err } def := tag.Value("default") if fields.HasDefault(ii) { // Handled by the ORM def = "" } if def != "" { if driver.IsFunc(def) { fname, _ := driver.SplitFuncArgs(def) fn, err := d.backend.Func(fname, ftypes[ii]) if err != nil { if err == ErrFuncNotSupported { err = fmt.Errorf("backend %s does not support function %s", d.backend.Name(), tag.Value("default")) } return nil, err } def = fn } else { def = driver.UnescapeDefault(def) if typ.Kind() == reflect.String { def = d.db.QuoteString(def) } } } field := &Field{ Name: v, Type: ft, Default: def, } if tag.Has("notnull") { field.AddConstraint(ConstraintNotNull) } if d.isPrimaryKey(fields, ii, tag) { field.AddConstraint(ConstraintPrimaryKey) } else if tag.Has("unique") { field.AddConstraint(ConstraintUnique) } if tag.Has("auto_increment") { field.AddOption(OptionAutoIncrement) } if ref := fields.References[qnames[ii]]; ref != nil { fk, _, err := ref.Model.Fields().Map(ref.Field) if err != nil { return nil, err } field.Constraints = append(field.Constraints, &Constraint{ Type: ConstraintForeignKey, References: MakeReference(ref.Model.Table(), fk), }) } dbFields[ii] = field } return &Table{Fields: dbFields}, nil }
func (o *Orm) setFieldsDefaults(f *driver.Fields) error { defaults := make(map[int]reflect.Value) for ii, v := range f.Tags { def := v.Value("default") if def == "" { continue } if driver.IsFunc(def) { // Currently we only support two hardcoded functions, now() and today() fname, _ := driver.SplitFuncArgs(def) fn, ok := ormFuncs[fname] if !ok { return fmt.Errorf("unknown orm function %s()", fname) } retType := fn.Type().Out(0) if retType != f.Types[ii] { return fmt.Errorf("type mismatch: orm function %s() returns %s, but field %s in %s is of type %s", fname, retType, f.QNames[ii], f.Type, f.Types[ii]) } if o.driver.Capabilities()&driver.CAP_DEFAULTS == 0 || !o.driver.HasFunc(fname, retType) { defaults[ii] = fn } } else { // Raw value, only to be stored in defaults if the driver // does not support CAP_DEFAULTS or it's a TEXT value and // the driver lacks CAP_DEFAULTS_TEXT caps := o.driver.Capabilities() if caps&driver.CAP_DEFAULTS != 0 && (caps&driver.CAP_DEFAULTS_TEXT != 0 || !isText(f, ii)) { continue } // Try to parse it ftyp := f.Types[ii] indirs := 0 for ftyp.Kind() == reflect.Ptr { indirs++ ftyp = ftyp.Elem() } val := reflect.New(ftyp) if err := input.Parse(def, val.Interface()); err != nil { return fmt.Errorf("invalid default value %q for field %s of type %s in %s: %s", def, f.QNames[ii], f.Types[ii], f.Type, err) } if indirs == 0 { defaults[ii] = val.Elem() } else { // Pointer, need to allocate a new value each time typ := f.Types[ii].Elem() defVal := val.Elem() f := func() reflect.Value { v := reflect.New(typ).Elem() for v.Kind() == reflect.Ptr { v.Set(reflect.New(v.Type().Elem())) v = v.Elem() } v.Set(defVal) return v } defaults[ii] = reflect.ValueOf(f) } } } if len(defaults) > 0 { f.Defaults = defaults } return nil }