func (self *Collection) subDocumentType(docType reflect.Type, fieldName string, subDocSelectors []string) (reflect.Type, error) { if fieldName == "" { return docType, errs.Format("Collection '%s', selector '%s': Empty field name", self.Name, strings.Join(subDocSelectors, ".")) } switch docType.Kind() { case reflect.Struct: bsonName := strings.ToLower(fieldName) field := reflection.FindFlattenedStructField(docType, MatchBsonField(bsonName)) if field != nil { return field.Type, nil } return nil, errs.Format("Collection '%s', selector '%s': Struct has no field '%s'", self.Name, strings.Join(subDocSelectors, "."), fieldName) case reflect.Array, reflect.Slice: _, numberErr := strconv.Atoi(fieldName) if numberErr == nil || fieldName == "$" { return docType, nil } return docType.Elem(), nil case reflect.Ptr, reflect.Interface: return self.subDocumentType(docType.Elem(), fieldName, subDocSelectors) } return nil, errs.Format("Collection '%s', selector '%s': Can't select sub-document '%s' of type '%s'", self.Name, strings.Join(subDocSelectors, "."), fieldName, docType.String()) }
func (self *Ref) Collection() (collection *Collection, err error) { if self.CollectionName == "" { return nil, errs.Format("Missing collection name. Did you call mongo.Document.Init()?") } collection, ok := collections[self.CollectionName] if !ok { return nil, errs.Format("Collection '" + self.CollectionName + "' not registered") } return collection, nil }
func (self *Ref) Collection() *Collection { if self.CollectionName == "" { panic(errs.Format("Missing collection name. Did you call mongo.Document.Init()?")) } collection, ok := Collections[self.CollectionName] if !ok { panic(errs.Format("Collection '" + self.CollectionName + "' not registered")) } return collection }
func (self *SubDocumentBase) Save() error { if self.embeddingStruct == nil { return errs.Format("Can't save uninitialized mongo.SubDocument. embeddingStruct is nil.") } if !self.rootDocumentID.Valid() { return errs.Format("Can't save mongo.SubDocument with invalid RootDocumentObjectId.") } return self.collection.Update(self.rootDocumentID, bson.M{self.selector: self.embeddingStruct}) }
func (self *Ref) Validate(metaData *model.MetaData) error { if self.CollectionName == "" { return errs.Format("Missing CollectionName") } length := len(self.ID) if length != 0 && length != 12 { return errs.Format("Invalid ObjectId length %d", length) } if self.Required(metaData) && self.IsEmpty() { return model.NewRequiredError(metaData) } return nil }
func (self *Ref) References(doc Document) (ok bool, err error) { collection := doc.Collection() if collection == nil { return false, errs.Format("Document is not initialized") } if collection.Name != self.CollectionName { return false, errs.Format("mongo.Ref to collection '%s' can't reference document of collection '%s'", self.CollectionName, collection.Name) } id := doc.ObjectId() if !id.Valid() { return false, errs.Format("Can't reference document with empty ID") } return self.ID == id, nil }
func (self *Collection) documentWithID(id bson.ObjectId, subDocSelectors ...string) (document interface{}, err error) { if len(subDocSelectors) > 0 { panic("Sub document selectors are not implemented") } if id == "" { return nil, errs.Format("mongo.Collection %s: Can't get document with empty id", self.Name) } if err = self.ValidateSelector(subDocSelectors...); err != nil { return nil, err } self.checkDBConnection() document = self.NewDocument(subDocSelectors...) q := self.collection.Find(bson.M{"_id": id}) if len(subDocSelectors) == 0 { err = q.One(document) } else { err = q.Select(strings.Join(subDocSelectors, ".")).One(document) } if err != nil { return nil, err } // document has to be initialized again, // because mgo zeros the struct while unmarshalling. // Newly created slice elements need to be initialized too self.InitDocument(document) return document, nil }
func (self *Video) Render(context *Context, writer *utils.XMLWriter) (err error) { youtubeId := "" switch { case strings.HasPrefix(self.URL, "http://youtu.be/"): i := len("http://youtu.be/") youtubeId = self.URL[i : i+11] case strings.HasPrefix(self.URL, "http://www.youtube.com/watch?v="): i := len("http://www.youtube.com/watch?v=") youtubeId = self.URL[i : i+11] } if youtubeId != "" { writer.OpenTag("iframe").Attrib("id", self.id).AttribIfNotDefault("class", self.Class) width := self.Width if width == 0 { width = 640 } height := self.Height if height == 0 { height = 390 } writer.Attrib("src", "http://www.youtube.com/embed/", youtubeId) writer.Attrib("width", width) writer.Attrib("height", height) writer.Attrib("frameborder", "0") writer.Attrib("allowfullscreen", "allowfullscreen") writer.CloseTag() return nil } return errs.Format("Unsupported video URL: %s", self.URL) }
func From(document interface{}) (user *User) { v := reflect.ValueOf(document) // Dereference pointers until we have a struct value for v.Kind() == reflect.Ptr { if v.IsNil() { return nil } v = v.Elem() } if v.Kind() == reflect.Struct { if v.Type() == UserType { return v.Addr().Interface().(*User) } count := v.NumField() for i := 0; i < count; i++ { field := v.Field(i) if field.Type() == UserType { return field.Addr().Interface().(*User) } } } panic(errs.Format("user.From(): invalid document type %T", document)) }
func (self *MultipleChoice) Validate(metaData *MetaData) error { options := self.Options(metaData) if len(options) == 0 { return errs.Format("model.MultipleChoice needs options") } for _, option := range options { if option == "" { return errs.Format("model.MultipleChoice options must not be empty strings") } } for _, str := range *self { if !utils.StringIn(str, options) { return &InvalidChoice{str, options} } } return nil }
func (self *queryBase) Limit(limit int) Query { if limit < 0 { return &QueryError{self.ParentQuery(), errs.Format("Invalid negative limit: %d", limit)} } q := &limitQuery{limit: limit} q.init(q, self.thisQuery) return q }
func (self *queryBase) Skip(skip int) Query { if skip < 0 { return &QueryError{self.ParentQuery(), errs.Format("Invalid negative skip count: %d", skip)} } q := &skipQuery{skip: skip} q.init(q, self.thisQuery) return q }
func (self *queryBase) Or() Query { if !self.thisQuery.IsFilter() { return &QueryError{self.thisQuery, errs.Format("Or() can only be called after Filter()")} } q := &orQuery{} q.init(q, self.thisQuery) return q }
func (self *CookieSessionDataStore) Delete(context *Context) (err error) { sessionID, ok := context.SessionID() if !ok { return errs.Format("Can't delete session data without a session id") } context.SetSecureCookie(self.cookieName(sessionID), "", -time.Now().Unix(), "/") return nil }
func (self *CookieSessionDataStore) Delete(ctx *Context) (err error) { sessionID := ctx.Session.ID() if sessionID == "" { return errs.Format("Can't delete session data without a session id") } ctx.Response.SetSecureCookie(self.cookieName(sessionID), "", -time.Now().Unix(), "/") return nil }
func (self *Ref) Validate(metaData *model.MetaData) error { if self.CollectionName == "" { return errs.Format("Missing CollectionName") } length := len(self.ID) if length != 0 && length != 12 { return errs.Format("Invalid ObjectId length %d", length) } if self.Required(metaData) && self.IsEmpty() { return model.NewRequiredError(metaData) } if ok, err := self.CheckID(); !ok { if err != nil { return err } return errs.Format("Invalid mongo.Ref. No document with ID %s in collection %s", self.ID, self.CollectionName) } return nil }
func (self *Configuration) Init() error { if self.initialized { panic("view.Config already initialized") } if !self.IsProductionServer { addrs, err := net.InterfaceAddrs() if err != nil { return err } for _, addr := range addrs { if ipNet, ok := addr.(*net.IPNet); ok { ip := ipNet.IP.String() for _, prodIP := range Config.ProductionServerIPs { if ip == prodIP { self.IsProductionServer = true break } } } } } if !self.IsProductionServer { self.Debug.Mode = true } // Check if dirs exists and make them absolute for i := range Config.BaseDirs { dir, err := filepath.Abs(os.ExpandEnv(Config.BaseDirs[i])) if err != nil { return err } if !utils.DirExists(dir) { return errs.Format("BaseDir does not exist: %s", dir) } Config.BaseDirs[i] = dir fmt.Println("BaseDir:", dir) } for i := range Config.StaticDirs { Config.StaticDirs[i] = os.ExpandEnv(Config.StaticDirs[i]) fmt.Println("StaticDir:", Config.StaticDirs[i]) } for i := range Config.TemplateDirs { Config.TemplateDirs[i] = os.ExpandEnv(Config.TemplateDirs[i]) fmt.Println("TemplateDir:", Config.TemplateDirs[i]) } self.initialized = true return nil }
// IndirectURL encapsulates pointers to URL implementations. // To break circular dependencies, addresses of URL implementing variables // can be passed to this function that encapsulates it with an URL // implementation that dereferences the pointers at runtime. func IndirectURL(urlPtr interface{}) URL { switch s := urlPtr.(type) { case **Page: return &indirectPageURL{s} case *ViewWithURL: return IndirectViewWithURL(s) case *URL: return &indirectURL{s} } panic(errs.Format("%T not a pointer to a view.URL", urlPtr)) }
func (self *Ref) SetString(str string) error { switch len(str) { case 0, 12: self.ID = bson.ObjectId(str) case 24: self.ID = bson.ObjectIdHex(str) default: return errs.Format("Invalid string for bson.ObjectId: '%s'", str) } return nil }
func (self *IndexedSliceIterator) Next(resultRef interface{}) bool { if self.err != nil || self.index >= len(self.indices) { return false } if self.indices[self.index] >= self.slice.Len() { self.err = errs.Format("Index %d from indices greater or equal than length of slice %d", self.indices[self.index], self.slice.Len()) return false } reflection.SmartCopy(self.slice.Index(self.indices[self.index]), resultRef) self.index++ return false }
func (self *IndexedObjectIterator) Next() interface{} { if self.err != nil || self.index >= len(self.indices) { return nil } if self.indices[self.index] >= len(self.objects) { self.err = errs.Format("Index %d from indices slice greater or equal than length of objects slice %d", self.indices[self.index], len(self.objects)) return nil } object := self.objects[self.indices[self.index]] self.index++ return object }
// Returns an iterator of dereferenced refs, or an error iterator if there was an error func DereferenceIterator(refs ...Ref) model.Iterator { docs := make([]interface{}, len(refs)) for i := range refs { var err error docs[i], err = refs[i].Get() if err != nil { err = errs.Format("%s: %s", refs[i].ID.Hex(), err.Error()) return model.NewErrorIterator(err) } } return model.NewObjectIterator(docs...) }
// Returns an iterator of dereferenced refs, or an error iterator if there was an error func DereferenceIterator(refs ...Ref) model.Iterator { var docs []interface{} for i := range refs { doc, err := refs[i].Get() if err != nil { err = errs.Format("%s: %s", refs[i].ID.Hex(), err.Error()) return model.NewErrorOnlyIterator(err) } else if doc != nil { docs = append(docs, doc) } } return model.NewObjectIterator(docs...) }
// Returns an iterator for all refs without error and a slice of the errors func FailsafeDereferenceIterator(refs ...Ref) (i model.Iterator, errors []error) { var docs []interface{} for i := range refs { doc, err := refs[i].Get() if err == nil { docs = append(docs, doc) } else { err = errs.Format("%s: %s", refs[i].ID.Hex(), err.Error()) errors = append(errors, err) } } return model.NewObjectIterator(docs...), errors }
func (self *PrintfTemplate) Render(out io.Writer, context interface{}) (err error) { var str string switch reflect.TypeOf(context).Kind() { case reflect.Slice, reflect.Array: panic("todo implementation") default: str = fmt.Sprintf(self.text, context) } if strings.HasPrefix(str, "%!") { return errs.Format(str) } _, err = out.Write([]byte(str)) return err }
func RenderTemplate(filename string, out io.Writer, context interface{}) (err error) { filePath, found, _ := FindTemplateFile(filename) if !found { return errs.Format("Template file not found: %s", filename) } var templ templatesystem.Template templ, err = Config.TemplateSystem.ParseFile(filePath) if err != nil { return } // context = append(context, Config) return templ.Render(out, context) }
func (self *CookieSessionDataStore) Set(ctx *Context, data interface{}) (err error) { sessionID := ctx.Session.ID() if sessionID == "" { return errs.Format("Can't set session data without a session id") } var buffer bytes.Buffer encoder := gob.NewEncoder(&buffer) err = encoder.Encode(data) if err != nil { return err } dataBytes, err := EncryptCookie(buffer.Bytes()) if err != nil { return err } if len(dataBytes) > 4000 { // Max HTTP header size is 4094 minus some space for protocol return errs.Format("Session %s data size %d is larger than cookie limit of 4000 bytes", sessionID, len(dataBytes)) } ctx.Response.SetSecureCookie(self.cookieName(sessionID), string(dataBytes), 0, "/") return nil }
func (self *DocumentBase) Save() error { if self.embeddingStruct == nil { return errs.Format("Can't save uninitialized mongo.Document. embeddingStruct is nil.") } if !self.ID.Valid() { id, err := self.collection.Insert(self.embeddingStruct) if err == nil { self.ID = id } return err } return self.collection.Update(self.ID, self.embeddingStruct) }
func (self *Collection) SubDocumentWithID(id bson.ObjectId, selector string, resultRef interface{}) error { if id == "" { return errs.Format("mongo.Collection %s: Can't get document with empty id", self.Name) } self.checkDBConnection() q := self.collection.FindId(id).Select(bson.M{selector: 1}) err := q.One(resultRef) if err != nil { return err } // resultRef has to be initialized again, // because mgo zeros the struct while unmarshalling. // Newly created slice elements need to be initialized too self.InitSubDocument(resultRef) return nil }
func SliceDelete(slice []interface{}, index int, count int) (result []interface{}) { switch { case count < 0: panic(errs.Format("Negative count %d not allowed", count)) case count == 0: return slice } length := len(slice) errs.PanicIfErrIndexOutOfBounds("SliceDelete", index, length) if index+count > length { count = length - index } return append(slice[:index], slice[index+count:]...) }