func newConfig(conf *config.URL) (*Cache, error) { cache := &Cache{ Logger: log.Std, } if codecName := conf.Fragment.Get("codec"); codecName != "" { cache.codec = codec.Get(codecName) if cache.codec == nil { if imp := codec.RequiredImport(codecName); imp != "" { return nil, fmt.Errorf("please import %q to use the codec %q", imp, codecName) } return nil, fmt.Errorf("unknown codec %q, maybe you forgot an import?", codecName) } } else { cache.codec = codec.Get("gob") } cache.prefix = conf.Fragment.Get("prefix") cache.prefixLen = len(cache.prefix) if pipeName := conf.Fragment.Get("pipe"); pipeName != "" { cache.pipe = pipe.Get(pipeName) if cache.pipe == nil { if imp := pipe.RequiredImport(pipeName); imp != "" { return nil, fmt.Errorf("please import %q to use the pipe %q", imp, pipeName) } return nil, fmt.Errorf("unknown pipe %q, maybe you forgot an import?", pipeName) } } var opener driver.Opener if conf.Scheme != "" { opener = driver.Get(conf.Scheme) if opener == nil { if imp := imports[conf.Scheme]; imp != "" { return nil, fmt.Errorf("please import %q to use the cache driver %q", imp, conf.Scheme) } return nil, fmt.Errorf("unknown cache driver %q, maybe you forgot an import?", conf.Scheme) } } else { opener = driver.Get("dummy") } var err error if cache.driver, err = opener(conf); err != nil { return nil, err } return cache, nil }
func (o *Orm) fields(table string, s *structs.Struct) (*driver.Fields, map[string]*reference, error) { methods, err := driver.MakeMethods(s.Type) if err != nil { return nil, nil, err } fields := &driver.Fields{ Struct: s, PrimaryKey: -1, Methods: methods, } var references map[string]*reference for ii, v := range s.QNames { // XXX: Check if this quoting is enough fields.QuotedNames = append(fields.QuotedNames, fmt.Sprintf("\"%s\".\"%s\"", table, s.MNames[ii])) t := s.Types[ii] ftag := s.Tags[ii] // Check encoded types if cn := ftag.CodecName(); cn != "" { if codec.Get(cn) == nil { if imp := codec.RequiredImport(cn); imp != "" { return nil, nil, fmt.Errorf("please import %q to use the codec %q", imp, cn) } return nil, nil, fmt.Errorf("can't find codec %q. Perhaps you missed an import?", cn) } } else { switch t.Kind() { case reflect.Array, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map: return nil, nil, fmt.Errorf("field %q in struct %s has invalid type %s", v, s.Type, t) } } if pn := ftag.PipeName(); pn != "" { // Check if the field has a codec and the pipe exists if ftag.CodecName() == "" { return nil, nil, fmt.Errorf("field %q has pipe %s but no codec - only encoded types can use pipes", v, pn) } if pipe.FromTag(ftag) == nil { return nil, nil, fmt.Errorf("can't find ORM pipe %q. Perhaps you missed an import?", pn) } } // Struct has flattened types, but we need to original type // to determine if it should be nullempty or omitempty by default field := s.Type.FieldByIndex(s.Indexes[ii]) fields.OmitEmpty = append(fields.OmitEmpty, ftag.Has("omitempty") || (defaultsToOmitEmpty(field.Type, ftag) && !ftag.Has("notomitempty"))) fields.NullEmpty = append(fields.NullEmpty, ftag.Has("nullempty") || (defaultsToNullEmpty(field.Type, ftag) && !ftag.Has("notnullempty"))) if ftag.Has("primary_key") { if fields.PrimaryKey >= 0 { return nil, nil, fmt.Errorf("duplicate primary_key in struct %v (%s and %s)", s.Type, s.QNames[fields.PrimaryKey], v) } fields.PrimaryKey = ii } if ftag.Has("auto_increment") { if k := types.Kind(t.Kind()); k != types.Int && k != types.Uint { return nil, nil, fmt.Errorf("auto_increment field %q in struct %s must be of integer type (signed or unsigned", v, s.Type) } fields.AutoincrementPk = fields.PrimaryKey == ii } if ref := ftag.Value("references"); ref != "" { m := referencesRe.FindStringSubmatch(ref) if len(m) != 4 { return nil, nil, fmt.Errorf("field %q has invalid references %q. Must be in the form references=Model or references=Model(Field)", v, ref) } if references == nil { references = make(map[string]*reference) } references[v] = &reference{model: m[1], field: m[3]} } } if err := o.setFieldsDefaults(fields); err != nil { return nil, nil, err } return fields, references, nil }