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); }
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); }
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); }
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 }
//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)); }