Пример #1
0
        public static object UseSqlAsFuncsFrom(CallExpr ce, Generator.Ctx ctx)
        {
            var arg0 = Generator.Generate(ce.args[0], ctx);

            if (OPs.KindOf(arg0) != ValueKind.Const)
            {
                ctx.Error("Constant value expected");
            }

            var arg1 = (ce.args.Count < 2) ? null : Generator.Generate(ce.args[1], ctx);

            var        sqlFileName = Convert.ToString(arg0);
            DbFuncType forKinds;

            if (arg1 == null)
            {
                forKinds = DbFuncType.TimeSlice | DbFuncType.TimeInterval;
            }
            else
            {
                var lst = arg1 as IList ?? new object[] { arg1 };
                forKinds = DbFuncType.None;
                foreach (var v in lst)
                {
                    forKinds |= (DbFuncType)Enum.Parse(typeof(DbFuncType), Convert.ToString(v));
                }
            }

            var dbConnName = (ce.args.Count < 3) ? DefaultDbConnName : OPs.TryAsName(ce.args[2], ctx);

            if (string.IsNullOrEmpty(dbConnName))
            {
                ctx.Error($"Connection name must be nonempty: {ce.args[2]}");
            }

            var fullFileName = Path.IsPathRooted(sqlFileName)
                ? sqlFileName
                : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Convert.ToString(sqlFileName));

            var           cacheKey = $"FuncDefs:{fullFileName}:{forKinds.ToString()}";
            Func <object> ldfsFunc = () =>
            {
                var sqlCtx = new W.Expressions.Sql.Preprocessing.PreprocessingContext()
                {
                    sqlFileName                 = fullFileName,
                    cacheSubdomain              = "DB",
                    dbConnValueName             = dbConnName,
                    forKinds                    = forKinds,
                    ctx                         = ctx,
                    cachingExpiration           = TimeSpan.FromMinutes(5),
                    defaultLocationForValueInfo = (ce.args.Count < 4) ? null : OPs.TryAsString(ce.args[3], ctx)
                };
                return(sqlCtx.LoadingFuncs());
            };
            var lfds = (IEnumerable <FuncDef>)FuncDefs_Core._Cached(cacheKey, ldfsFunc, DateTimeOffset.MaxValue, TimeSpan.FromMinutes(5));

            return(lfds);
        }
Пример #2
0
        public static object LookupHelperFuncs(CallExpr ce, Generator.Ctx ctx)
        {
            var dbConn     = ce.args[0];
            var dbConnName = OPs.TryAsName(dbConn, ctx);

            if (dbConnName == null)
            {
                throw new Generator.Exception($"Can't get DB connection name: {dbConn}");
            }

            var pairs = ctx.GetConstant(ce.args[1]) as IList;

            if (pairs == null)
            {
                throw new Generator.Exception($"Can't interpet as array of constants: {ce.args[1]}");
            }
            if (pairs.Count % 2 != 0)
            {
                throw new Generator.Exception($"Items count must be even (cause it must be array of pairs): {ce.args[1]}");
            }

            var location = Convert.ToString(ctx.GetConstant(ce.args[2]));

            var defs = new List <FuncDef>(pairs.Count / 2);

            for (int i = 0; i < pairs.Count; i += 2)
            {
                var dbTableName = pairs[i].ToString();
                var substance   = pairs[i + 1].ToString();

                // Dictionary loader func
                defs.Add(FuncDefs_Core.macroFuncImpl(ctx,
                                                     // name
                                                     new ConstExpr($"{dbConnName}:{dbTableName}_LoadDict"),
                                                     // inputs
                                                     new ArrayExpr(),
                                                     // outputs
                                                     new ArrayExpr(new ConstExpr($"{substance}_DICT_{location}")),
                                                     // body
                                                     new CallExpr(LoadCodeLookupDictRows, dbConn, new ConstExpr(dbTableName)),
                                                     //
                                                     null, false
                                                     ));
            }



            return(defs);
        }
Пример #3
0
        static Contexts GetCtxForCode(Contexts parent, string codeText)
        {
            var obj = FuncDefs_Core._Cached($"$Contexts_{codeText.GetHashCode()}", (Func <object>)(() =>
            {
                var res = new Contexts();

                //***** формируем по тексту синтаксическое дерево
                var e = Parser.ParseToExpr(codeText);

                if (parent == null)
                {
                    var funcDefs = new W.Expressions.FuncDefs()
                                   .AddFrom(typeof(W.Expressions.FuncDefs_Core))
                                   .AddFrom(typeof(W.Expressions.FuncDefs_Excel))
                                   .AddFrom(typeof(W.Expressions.FuncDefs_Report))
                    ;
                    var valsDefs = new Dictionary <string, object>();
                    //***** создаём контекст кодогенератора, содержащий предопределённые значения и перечень функций
                    res.gCtx = new Generator.Ctx(valsDefs, funcDefs.GetFuncs);
                    //***** формируем код
                    var g = Generator.Generate(e, res.gCtx);
                    //***** проверяем, заданы ли выражения для всех именованных значений
                    try { res.gCtx.CheckUndefinedValues(); }
                    catch (W.Expressions.Generator.Exception ex) { throw new UndefinedValuesException(ex.Message); }
                    res.eCtx = new AsyncExprRootCtx(res.gCtx.name2ndx, res.gCtx.values, OPs.GlobalMaxParallelismSemaphore);
                }
                else
                {
                    //***** создаём контекст кодогенератора, содержащий предопределённые значения и перечень функций
                    res.gCtx = new Generator.Ctx(parent.gCtx);
                    //***** формируем код
                    var g = Generator.Generate(e, res.gCtx);
                    //***** проверяем, заданы ли выражения для всех именованных значений
                    try { res.gCtx.CheckUndefinedValues(); }
                    catch (W.Expressions.Generator.Exception ex) { throw new UndefinedValuesException(ex.Message); }
                    res.eCtx = new AsyncExprCtx(res.gCtx, res.gCtx.values, parent.eCtx);
                }
                return(res);
            }), DateTime.UtcNow.AddMinutes(5), ObjectCache.NoSlidingExpiration);

            return((Contexts)obj);
        }
Пример #4
0
        static IEnumerable <FuncDef> DefineProjectionFuncsImpl(CallExpr ce, Generator.Ctx ctx, bool acceptVector)
        {
            var inpParams      = ((IList)OPs.GetConstant(ctx, ce.args[0])).Cast <object>().Select(Convert.ToString).ToArray();
            var inpParamsParts = inpParams.Select(s => s.Split('_')).ToArray();
            var inpParamsMasks = inpParamsParts.Where(parts => parts.Any(string.IsNullOrEmpty)).ToArray();
            var outParams      = ((IList)OPs.GetConstant(ctx, ce.args[1])).Cast <object>().Select(Convert.ToString).ToArray();
            var outParamsMasks = outParams.Select(s => Convert.ToString(s).Split('_')).ToArray();

            var newFuncName = "@projfunc:" + ce.args[ce.args.Count - 1].ToString().Replace('(', '_').Replace(')', '_').Replace('"', '_').Replace('\'', '_');

            #region Collect suitable parameters from all functions outputs
            var suitableParams = new Dictionary <string, string[]>(StringComparer.OrdinalIgnoreCase);

            foreach (var f in ctx.GetFunc(null, 0))
            {
                foreach (var prm in f.resultsInfo)
                {
                    var prmParts = prm.Parts();
                    for (int i = 0; i < inpParamsMasks.Length; i++)
                    {
                        var maskParts = inpParamsMasks[i];
                        var details   = GetDetailsIfMatched(prmParts, maskParts);
                        if (details == null)
                        {
                            continue;
                        }
                        if (!suitableParams.TryGetValue(details, out var suitables))
                        {
                            suitables = new string[inpParamsMasks.Length];
                            suitableParams.Add(details, suitables);
                        }
                        suitables[i] = details;
                    }
                }
            }
            #endregion

            #region Return FuncDef for each suitable params set
            foreach (var suitable in suitableParams.Where(prms => prms.Value.All(s => s != null)))
            {
                var details = suitable.Key;
                var inps    = new string[inpParamsParts.Length];
                for (int i = 0; i < inpParamsParts.Length; i++)
                {
                    var ip = inpParamsParts[i];
                    if (ip.Any(string.IsNullOrEmpty))
                    {   // one or more parts masked
                        inps[i] = ParamFromMaskAndDetails(details, ip);
                    }
                    else
                    {
                        inps[i] = inpParams[i];
                    }
                }

                var outs = new string[outParams.Length];
                for (int i = 0; i < outParamsMasks.Length; i++)
                {
                    outs[i] = ParamFromMaskAndDetails(details, outParamsMasks[i]);
                }

                yield return(FuncDefs_Core.macroFuncImpl(
                                 context: ctx,
                                 nameForNewFunc: new ConstExpr(newFuncName + details),
                                 inpsDescriptors: new ArrayExpr(inps.Select(ReferenceExpr.Create).Cast <Expr>().ToList()),
                                 outsDescriptors: new ArrayExpr(outs.Select(ReferenceExpr.Create).Cast <Expr>().ToList()),
                                 funcBody: ce.args[ce.args.Count - 1],
                                 inputParameterToSubstitute: (ce.args.Count > 3) ? ce.args[2] : null,
                                 funcAcceptVector: acceptVector
                                 ));
            }
            #endregion
        }
Пример #5
0
        //public static async Task CommitPreferredConn(AsyncExprCtx ctx)
        //{
        //    var conn = (IDbConn)await ctx.GetValue(DefaultDbConnName);
        //    await conn.Commit(ctx.Cancellation);
        //}

        //public static async Task<object> ExecNonQuery(AsyncExprCtx ctx, string cmdText, string oraConnName)
        //{
        //	var conn = (IOraConn)await ctx.GetValue(ctx, oraConnName);
        //	return await conn.ExecCmd(new OracleCommandData() { Kind = CommandKind.NonQuery, SqlText = cmdText }, ctx.Cancellation);
        //}

        public static async Task <object> CachedExecQuery(AsyncExprCtx ctx, string query, string oraConnName, bool arrayResults)
        {
            return(await FuncDefs_Core._Cached(ctx, query, (LazyAsync)(aec =>
                                                                       ExecQuery(aec, query, oraConnName, arrayResults)),
                                               DateTime.Now + TimeSpan.FromMinutes(5), TimeSpan.Zero));
        }