public static StandardResult <SimpleTable> Execute(SimpleTable sourceTable, SimpleTable aggregateTable) { if (sourceTable == null) { return(StandardResult <SimpleTable> .ReturnError("AggregateTable() error: source table null")); } if (aggregateTable == null) { return(StandardResult <SimpleTable> .ReturnError("AggregateTable() error: aggregate table null")); } var newTable = new SimpleTable(); var nonaggregateFields = new Dictionary <string, Expression>(); var aggregateFields = new Dictionary <string, Expression>(); // create columns foreach (var map in aggregateTable) { var source = map["source"]; var destination = map["destination"]; newTable.AddColumnName(destination); var expression = ExpressionCache.Compile(source); if (expression == null) { return(StandardResult <SimpleTable> .ReturnError("AggregateTable() error: evaluator returns null", "Source: " + source)); } // does expression contain any aggregate methods? bool aggregateMethods = false; foreach (var token in expression.Parser.Tokenizer.Tokens) { if (token.TokenType == TokenType.Method && aggregateMethodsNames.Contains(token.Value)) { aggregateMethods = true; break; } } if (aggregateMethods) { aggregateFields.Add(destination, expression); } else { nonaggregateFields.Add(destination, expression); } } var associateBuckets = new Dictionary <SimpleTableRow, List <SimpleTableRow> >(); // create new rows with non-aggregate expressions & track assocations { var fieldSource = new FieldDataSource(); var context = new Context() { FieldSource = fieldSource }; var bucketsMap = new Dictionary <List <string>, SimpleTableRow>(); foreach (var sourceRow in sourceTable) { fieldSource.Row = sourceRow; var fields = new List <string>(); foreach (var field in nonaggregateFields) { var destination = field.Key; var expression = field.Value; var result = expression.Evaluate(context); if (result.IsError) { return(StandardResult <SimpleTable> .ReturnError("AggregateTable() error: occurred during evaluating: " + expression.Parser.Tokenizer.Expression, result.String)); } fields.Add(ExpandTable.ToString(result)); } var row = Find(fields, bucketsMap); if (row == null) { row = newTable.CreateRow(); bucketsMap.Add(fields, row); // populate non-aggregated rows int index = 0; foreach (var non in nonaggregateFields) { var destination = non.Key; var expression = non.Value; var result = fields[index++]; row[destination] = result; } } List <SimpleTableRow> bucketRows; if (!associateBuckets.TryGetValue(row, out bucketRows)) { bucketRows = new List <SimpleTableRow>(); associateBuckets.Add(row, bucketRows); } bucketRows.Add(sourceRow); } } // evaluation aggregate expressions { var fieldSource = new FieldDataSource(); var aggregateFieldSource = new AggregateFieldSource(); var context = new Context() { FieldSource = fieldSource, AggregateFieldSource = aggregateFieldSource }; foreach (var aggregateRow in newTable) { var bucketRows = associateBuckets[aggregateRow]; fieldSource.Row = bucketRows[0]; // any row -- note: undefine to reference non-aggregate fields outside of the aggregate expression aggregateFieldSource.TableRows = bucketRows; foreach (var field in aggregateFields) { var destination = field.Key; var expression = field.Value; var result = expression.Evaluate(context); if (result.IsError) { return(StandardResult <SimpleTable> .ReturnError("AggregateTable() error: occurred during evaluating: " + expression.Parser.Tokenizer.Expression, result.String)); } aggregateRow[destination] = ExpandTable.ToString(result); } } } return(StandardResult <SimpleTable> .ReturnResult(newTable)); }
public static StandardResult <SimpleTable> Execute(SimpleTable sourceTable, SimpleTable mapTable) { if (mapTable == null) { return(StandardResult <SimpleTable> .ReturnError("TransformTable() error: map table null")); } var newTable = new SimpleTable(); // create columns foreach (var map in mapTable) { var expression = ExpressionCache.Compile(map["source"]); if (expression == null) { return(StandardResult <SimpleTable> .ReturnError("TransformTable() error: evaluator returns null")); } newTable.AddColumnName(map["destination"]); } var fieldSource = new FieldDataSource(); foreach (var sourceRow in sourceTable) { fieldSource.Row = sourceRow; var destinationRow = newTable.CreateRow(); foreach (var map in mapTable) { var source = map["source"]; var destination = map["destination"]; var expression = ExpressionCache.Compile(source); if (expression == null) { return(StandardResult <SimpleTable> .ReturnError("ExpandTable() error: evaluator returns null")); } if (!expression.IsValid) { return(StandardResult <SimpleTable> .ReturnError("ExpandTable() error: occurred during evaluating: " + expression.Parser.Tokenizer.Expression)); } var result = expression.Evaluate(new Context() { FieldSource = fieldSource }); if (result.IsError) { return(StandardResult <SimpleTable> .ReturnError("ExpandTable() error: occurred during evaluating: " + expression.Parser.Tokenizer.Expression, result.String)); } destinationRow[destination] = ExpandTable.ToString(result); } } return(StandardResult <SimpleTable> .ReturnResult(newTable)); }