예제 #1
0
        // 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);
        }
예제 #2
0
        void Write(DataTable table)
        {
            var tbl = DataTableLocal.Convert(table);

            //Write(Persist.RelationSignature);
            Write(tbl.Cardinality);
            foreach (var row in tbl.GetRows())
            {
                Write(row);
            }
        }
예제 #3
0
        // 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);
        }
예제 #4
0
        // 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);
                }
            }
        }