func (this *Filter) Run() { defer close(this.outputChannel) // FIXME should ensure booleanFactors are sorted // from cheapest to most expensive to compute // start the source go this.source.Run() DOCUMENT: for row := range this.source.GetOutputChannel() { var context ast.Context switch row := row.(type) { case datasource.Document: context = ast.NewContext(row) default: panic(fmt.Sprintf("Non-map rows not currently supported (saw %T)", row)) } for _, booleanFactor := range this.booleanFactors { result, err := booleanFactor.EvaluateBoolean(context) if err != nil { log.Printf("Error evaluating boolean factor: %v", err) continue DOCUMENT } if !result { continue DOCUMENT } } this.outputChannel <- row } }
func (this *Project) Run() { defer close(this.outputChannel) // start the source go this.source.Run() DOCUMENT: for row := range this.source.GetOutputChannel() { if this.projection != nil { var context ast.Context switch row := row.(type) { case datasource.Document: //log.Printf("creating context with %v", row) context = ast.NewContext(row) default: panic(fmt.Sprintf("Non-map rows not currently supported (saw %T)", row)) } result, err := this.projection.Evaluate(context) if err != nil { log.Printf("Error evaluating projection: %v", err) continue DOCUMENT } this.outputChannel <- result } else { this.outputChannel <- row } } }
func (this *Order) Less(i, j int) bool { left := this.output[i] right := this.output[j] var leftContext, rightContext ast.Context switch left := left.(type) { case datasource.Document: leftContext = ast.NewContext(left) switch right := right.(type) { case datasource.Document: rightContext = ast.NewContext(right) default: panic(fmt.Sprintf("Non-map rows not currently supported (saw %T)", right)) } default: panic(fmt.Sprintf("Non-map rows not currently supported (saw %T)", left)) } for _, oe := range this.orderBy { leftVal, err := oe.Expression().Evaluate(leftContext) if err != nil { log.Printf("Error evaluating expression: %v", err) return false } rightVal, err := oe.Expression().Evaluate(rightContext) if err != nil { log.Printf("Error evaluating expression: %v", err) return false } result := ast.CollateJSON(leftVal, rightVal) if result != 0 { if oe.Order() && result < 0 { return true } else if !oe.Order() && result > 0 { return true } else { return false } } // at this level they are the same, keep going } // if we go to this point the order expressions could not differentiate between the elements return false }