<commit_before>// Copyright 2017 <NAME> <<EMAIL>>. All rights reserved.
// Use of this source code is governed by the AGPLv3 license that can be found in
// the LICENSE file.

package mongo

import (
	"github.com/praelatus/praelatus/ql/ast"
	"gopkg.in/mgo.v2/bson"
)

func eval(exp ast.InfixExpression) bson.M {
	b := bson.M{}

	switch exp.Operator {
	case "AND":
		opName := "$and"
		if _, ok := b[opName]; ok {
			b[opName] = append(b[opName].([]bson.M),
				eval(exp.Left.(ast.InfixExpression)), eval(exp.Right.(ast.InfixExpression)))
		} else {
			b[opName] = []bson.M{
				eval(exp.Left.(ast.InfixExpression)),
				eval(exp.Right.(ast.InfixExpression)),
			}
		}
	case "OR":
		opName := "$or"
		if _, ok := b[opName]; ok {
			b[opName] = append(b[opName].([]bson.M),
				eval(exp.Left.(ast.InfixExpression)), eval(exp.Right.(ast.InfixExpression)))
		} else {
			b[opName] = []bson.M{
				eval(exp.Left.(ast.InfixExpression)),
				eval(exp.Right.(ast.InfixExpression)),
			}
		}
	case "=":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, val.GetValue())
	case "~":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$regex": val.GetValue()})
	case "!=":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$ne": val.GetValue()})
	case ">":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$gt": val.GetValue()})
	case "<":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$lt": val.GetValue()})
	case ">=":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$gte": val.GetValue()})
	case "<=":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$lte": val.GetValue()})
	}

	return b
}

func evalAST(a ast.AST) bson.M {
	infix, ok := a.Root.Expression.(ast.InfixExpression)
	if !ok {
		return nil
	}

	return eval(infix)
}

func makeFieldSearchDoc(exp ast.InfixExpression, b bson.M, valDoc interface{}) {
	fn := exp.Left.(ast.FieldLiteral)
	if fn.IsCustomField() {
		customFieldDoc := bson.M{
			"name":  fn.Value,
			"value": valDoc,
		}

		if _, ok := b["fields"]; ok {
			b["fields"] = append(b["fields"].([]bson.M), customFieldDoc)
		} else {
			b["fields"] = []bson.M{customFieldDoc}
		}
	} else {
		b[fn.Value] = valDoc
	}
}
<commit_msg>Change name of ast Root node for clarity<commit_after>// Copyright 2017 <NAME> <<EMAIL>>. All rights reserved.
// Use of this source code is governed by the AGPLv3 license that can be found in
// the LICENSE file.

package mongo

import (
	"github.com/praelatus/praelatus/ql/ast"
	"gopkg.in/mgo.v2/bson"
)

func eval(exp ast.InfixExpression) bson.M {
	b := bson.M{}

	switch exp.Operator {
	case "AND":
		opName := "$and"
		if _, ok := b[opName]; ok {
			b[opName] = append(b[opName].([]bson.M),
				eval(exp.Left.(ast.InfixExpression)), eval(exp.Right.(ast.InfixExpression)))
		} else {
			b[opName] = []bson.M{
				eval(exp.Left.(ast.InfixExpression)),
				eval(exp.Right.(ast.InfixExpression)),
			}
		}
	case "OR":
		opName := "$or"
		if _, ok := b[opName]; ok {
			b[opName] = append(b[opName].([]bson.M),
				eval(exp.Left.(ast.InfixExpression)), eval(exp.Right.(ast.InfixExpression)))
		} else {
			b[opName] = []bson.M{
				eval(exp.Left.(ast.InfixExpression)),
				eval(exp.Right.(ast.InfixExpression)),
			}
		}
	case "=":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, val.GetValue())
	case "~":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$regex": val.GetValue()})
	case "!=":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$ne": val.GetValue()})
	case ">":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$gt": val.GetValue()})
	case "<":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$lt": val.GetValue()})
	case ">=":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$gte": val.GetValue()})
	case "<=":
		val := exp.Right.(ast.Literal)
		makeFieldSearchDoc(exp, b, bson.M{"$lte": val.GetValue()})
	}

	return b
}

func evalAST(a ast.AST) bson.M {
	infix, ok := a.Query.Expression.(ast.InfixExpression)
	if !ok {
		return nil
	}

	return eval(infix)
}

func makeFieldSearchDoc(exp ast.InfixExpression, b bson.M, valDoc interface{}) {
	fn := exp.Left.(ast.FieldLiteral)
	if fn.IsCustomField() {
		customFieldDoc := bson.M{
			"name":  fn.Value,
			"value": valDoc,
		}

		if _, ok := b["fields"]; ok {
			b["fields"] = append(b["fields"].([]bson.M), customFieldDoc)
		} else {
			b["fields"] = []bson.M{customFieldDoc}
		}
	} else {
		b[fn.Value] = valDoc
	}
}

{'fraction_non_alphanumeric': 0.2016586643387167, 'fraction_numerical': 0.0026189436927106066, 'mean_word_length': 3.7150205761316872, 'pattern_counts': {'":': 34, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2924211', 'n_tokens_mistral': 1976, 'n_tokens_neox': 1821, 'n_words': 341}