// Invoke a defined function with required argument in scope // If folded, applies an offset to get the right accumulator public TypedValue Invoke(CodeValue funcarg, PointerValue accblkarg, NumberValue accbasarg, TypedValue[] valargs) { Logger.WriteLine(3, "Invoke {0} accbase={1} ({2})", funcarg, accbasarg, String.Join(",", valargs.Select(a => a.ToString()).ToArray())); // wrap raw value with evaluator var expr = funcarg.Value as ExpressionEval; Logger.Assert(expr != null, "invoke eval"); var args = DataRow.CreateNonTuple(expr.Lookup, valargs); TypedValue ret; if (expr.HasFold) { var accblk = accblkarg.Value as AccumulatorBlock; var accbase = (int)accbasarg.Value; ret = expr.EvalHasFold(args, accblk, accbase); } else { ret = expr.EvalOpen(args); } // If the return value is an unresolved sql table then resolve it now // before exiting the lookup scope (which it may need) if (ret is RelationValue && !(ret.AsTable() is DataTableLocal)) { ret = RelationValue.Create(DataTableLocal.Convert(ret.AsTable(), args, expr.Evaluator)); } Logger.WriteLine(3, "[Inv {0}]", ret); return(ret); }
void Write(DataTable table) { var tbl = DataTableLocal.Convert(table); //Write(Persist.RelationSignature); Write(tbl.Cardinality); foreach (var row in tbl.GetRows()) { Write(row); } }
// Invoke a do block with its own scope level public TypedValue DoBlock(CodeValue exprarg, PointerValue accblkarg) { Logger.WriteLine(3, "DoBlock {0}", exprarg); _catvars = _catvars.PushScope(); var accblk = accblkarg.Value as AccumulatorBlock; var expr = exprarg.Value as ExpressionEval; var ret = expr.Evaluator.Exec(exprarg.Value.Code, null, null, accblk); // If the return value is an unresolved sql table then resolve it now // before exiting the local variable scope (which it may need) if (ret is RelationValue && !(ret.AsTable() is DataTableLocal)) { ret = RelationValue.Create(DataTableLocal.Convert(ret.AsTable())); } _catvars = _catvars.PopScope(); Logger.WriteLine(3, "[Do {0}]", ret); return(ret); }
// set entry to value, update as needed internal void SetValue(CatalogEntry entry, TypedValue value) { // Choose where to store and whether to convert TypedValue finalvalue; if (entry.IsDatabase && _catalog.SqlFlag) { // Database + sql => hand it to sql, to create table if needed // set a default value to carry the type DataTableSql.Create(entry.Name, value.AsTable()); finalvalue = value.DataType.DefaultValue(); } else { // everything else stored in catalog if (value.DataType is DataTypeRelation) { finalvalue = RelationValue.Create(DataTableLocal.Convert(value.AsTable())); } else { finalvalue = value; } // set flags for persisting if (entry.IsPersistent) { entry.IsUnsaved = true; entry.IsLoaded = true; } } // store value if changed if (finalvalue != entry.Value) { var oldvalue = (entry.Value == null) ? null : entry; entry.Set(finalvalue); if (entry.IsPersistent && _catalog.SaveFlag) { _catalog.StoreEntry(entry, oldvalue); } } }