示例#1
0
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())
}
示例#2
0
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
}
示例#3
0
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
}
示例#4
0
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})
}
示例#5
0
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
}
示例#6
0
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
}
示例#7
0
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
}
示例#8
0
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)
}
示例#9
0
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))
}
示例#10
0
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
}
示例#11
0
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
}
示例#12
0
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
}
示例#13
0
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
}
示例#14
0
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
}
示例#15
0
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
}
示例#16
0
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
}
示例#17
0
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
}
示例#18
0
// 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))
}
示例#19
0
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
}
示例#20
0
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
}
示例#22
0
// 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...)
}
示例#23
0
// 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...)
}
示例#24
0
// 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
}
示例#25
0
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
}
示例#26
0
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)
}
示例#27
0
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
}
示例#28
0
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)
}
示例#29
0
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
}
示例#30
0
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:]...)
}