func (this *InitialProject) processTerms(item value.AnnotatedValue, context *Context) bool { n := len(this.plan.Terms()) var f map[string]interface{} if item.Type() == value.OBJECT { f = item.Copy().Fields() } if f == nil { f = make(map[string]interface{}, n) } pv := value.NewAnnotatedValue(f) pv.SetAttachments(item.Attachments()) p := value.NewValue(make(map[string]interface{}, n+32)) pv.SetAttachment("projection", p) for _, term := range this.plan.Terms() { if term.Result().Alias() != "" { v, err := term.Result().Expression().Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } p.SetField(term.Result().Alias(), v) // Explicit aliases override data if term.Result().As() != "" { pv.SetField(term.Result().As(), v) } } else { // Star starval := item.GetValue() if term.Result().Expression() != nil { var err error starval, err = term.Result().Expression().Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } } // Latest star overwrites previous star switch sa := starval.Actual().(type) { case map[string]interface{}: for k, v := range sa { p.SetField(k, v) } } } } return this.sendItem(pv) }
func (this *InitialProject) processItem(item value.AnnotatedValue, context *Context) bool { terms := this.plan.Terms() n := len(terms) if n > 1 { return this.processTerms(item, context) } if n == 0 { return this.sendItem(item) } // n == 1 result := terms[0].Result() expr := result.Expression() if expr == nil { // Unprefixed star if item.Type() == value.OBJECT { return this.sendItem(item) } else { return this.sendItem(_EMPTY_ANNOTATED_VALUE) } } else if this.plan.Projection().Raw() { // Raw projection of an expression v, err := expr.Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } if result.As() == "" { return this.sendItem(value.NewAnnotatedValue(v)) } sv := value.NewScopeValue(make(map[string]interface{}, 1), item) sv.SetField(result.As(), v) av := value.NewAnnotatedValue(sv) av.SetAttachment("projection", v) return this.sendItem(av) } else { // Any other projection return this.processTerms(item, context) } }