Ejemplo n.º 1
0
        public static object IDictsToLookup2(IList args)
        {
            var dicts  = (IList)args[0];
            var fields = (IList)args[1];
            var res    = new object[dicts.Count][];

            if (res.Length == 0)
            {
                return(res);
            }
            int n = fields.Count;

            int[] fieldsNdxs = new int[n];
            var   lstKeys    = new List <int>();
            var   k2n        = ((IIndexedDict)dicts[0]).Key2Ndx;

            for (int i = n - 1; i >= 0; i--)
            {
                var s = Convert.ToString(fields[i]);
                fieldsNdxs[i] = k2n[s];
                if (ValueInfo.IsID(s))
                {
                    lstKeys.Add(i);
                }
            }
            for (int i = 0; i < res.Length; i++)
            {
                var src = ((IIndexedDict)dicts[i]).ValuesList;
                var dst = new object[n];
                for (int j = 0; j < n; j++)
                {
                    dst[j] = src[fieldsNdxs[j]];
                }
                res[i] = dst;
            }
            var keysNdxs = lstKeys.ToArray();

            Array.Sort(res, (a, b) => a.CompareSameTimedKeys(b, keysNdxs));
            return(res);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create definitions of loading functions from specified SQL query
        /// </summary>
        /// <param name="funcNamesPrefix">Optional prefix for functions names. If null or empty, first table from 'FROM' clause is used</param>
        /// <param name="actualityInDays">Used to restrict the minimum queried timestamp // :MIN_TIME = :BEG_TIME-actualityInDays</param>
        /// <param name="queryText">SQL query text. Only some subset of SQL is supported
        /// (all sources in FROM cluase must have aliases, all fields in SELECT must be specified with source aliases, subqueries is not tested, etc)</param>
        /// <returns>Enumeration of pairs (func_name, loading function definition)</returns>
        internal static IEnumerable <FuncDef> FuncDefsForSql(Preprocessing.SqlFuncPreprocessingCtx c)
        {
            var sql = SqlParse.Do(c.queryText, SqlExpr.Options.EmptyFromPossible);

            sql = c.PostProc(sql);

            if (sql == null)
            {
                yield break;
            }

            var actuality = TimeSpan.FromDays((c.actualityInDays < 0) ? Attr.defaultActualityDays : c.actualityInDays);

            if (string.IsNullOrEmpty(c.funcNamesPrefix))
            {
                c.funcNamesPrefix = sql.sources[0].expr.ToString();
            }
            // generate list of results
            bool timedQuery    = false;
            bool withSeparator = false;

            ValueInfo[] resultsInfo;
            {
                int n   = sql.results.Length;
                var lst = new List <ValueInfo>(n);
                for (int i = 0; i < n; i++)
                {
                    var d = sql.results[i].alias;//.ToUpperInvariant();
                    if (d == nameof(START_TIME))
                    {
                        timedQuery = timedQuery || i == 1;
                    }
                    else if (d == nameof(END_TIME) || d == nameof(END_TIME__DT))
                    {
                        //if (d.Length == nameof(END_TIME).Length)
                        //	timedQuery = timedQuery || i == 2;
                    }
                    else if (d == nameof(INS_OUTS_SEPARATOR))
                    {
                        withSeparator = true;
                    }
                    else
                    {
                        //if (d.Length > 30)
                        //    throw new Generator.Exception($"SQL identifier too long (max 30, but {d.Length} chars in \"{d}\")");
                        var vi = ValueInfo.Create(d, defaultLocation: c.DefaultLocationForValueInfo);
                        int DL = vi.DescriptorLength();
                        if (DL > 30)
                        {
                            throw new Generator.Exception($"SQL identifier too long (max 30, but {DL} chars in \"{vi}\")");
                        }
                        lst.Add(vi);
                    }
                }
                resultsInfo = lst.ToArray();
            }

            var dbConnName = c.tblAttrs.GetString(Attr.Tbl.DbConnName) ?? c.ldr.dbConnValueName;

            #region Some query with INS_OUTS_SEPARATOR column
            if (withSeparator || !timedQuery || (c.ldr.forKinds & DbFuncType.Raw) != 0)
            {   // separator column present
                string[] inputs, outputs;
                var      qt        = SqlQueryNonTimed(sql, c.arrayResults, dbConnName, out inputs, out outputs);
                Fn       func      = FuncNonTimedQuery(qt);
                var      colsNames = qt.colsNames.Where(s => s != nameof(START_TIME) && s != nameof(END_TIME) && s != nameof(END_TIME__DT)).ToList();
                for (int i = inputs.Length - 1; i >= 0; i--)
                {
                    if (!ValueInfo.IsID(inputs[i]))
                    {
                        colsNames.RemoveAt(i);
                    }
                }
                var fd = new FuncDef(func, c.funcNamesPrefix /* + "_Values"*/, inputs.Length, inputs.Length,
                                     ValueInfo.CreateMany(inputs),
                                     ValueInfo.CreateMany(colsNames.ToArray()),
                                     FuncFlags.Defaults, 0, 0, c.ldr.cachingExpiration, c.ldr.cacheSubdomain,
                                     c.tblAttrs.ToDictionary(p => p.Key.ToString(), p => p.Value)
                                     );
                fd.xtraAttrs.Add(nameof(QueryTemplate), qt);
                yield return(fd);

                yield break;
            }
            #endregion
            #region Range
            if ((c.ldr.forKinds & DbFuncType.TimeInterval) != 0)
            {
                var qt   = SqlQueryTimed(sql, DbFuncType.TimeInterval, c.arrayResults, dbConnName);
                Fn  func = FuncTimedRangeQuery(actuality, qt);
                var fd   = new FuncDef(func, c.funcNamesPrefix + "_Range", 3, 3,
                                       ValueInfo.CreateMany(qt.colsNames[0], nameof(ValueInfo.A_TIME__XT), nameof(ValueInfo.B_TIME__XT)),
                                       resultsInfo, FuncFlags.Defaults, 0, 0, c.ldr.cachingExpiration, c.ldr.cacheSubdomain,
                                       c.tblAttrs.ToDictionary(p => p.Key.ToString(), p => p.Value)
                                       );
                fd.xtraAttrs.Add(nameof(QueryTemplate), qt);
                yield return(fd);
            }
            #endregion
            #region Slice at AT_TIME
            if ((c.ldr.forKinds & DbFuncType.TimeSlice) != 0)
            {
                var qt   = SqlQueryTimed(sql, DbFuncType.TimeSlice, c.arrayResults, dbConnName);
                Fn  func = FuncTimedSliceQuery(actuality, qt);
                var fd   = new FuncDef(func, c.funcNamesPrefix + "_Slice", 2, 2,
                                       ValueInfo.CreateMany(qt.colsNames[0], nameof(ValueInfo.At_TIME__XT)),
                                       resultsInfo, FuncFlags.Defaults, 0, 0, c.ldr.cachingExpiration, c.ldr.cacheSubdomain,
                                       c.tblAttrs.ToDictionary(p => p.Key.ToString(), p => p.Value)
                                       );
                fd.xtraAttrs.Add(nameof(QueryTemplate), qt);
                yield return(fd);
            }
            #endregion
            #region Raw interval // START_TIME in range MIN_TIME .. MAX_TIME
            if ((c.ldr.forKinds & DbFuncType.TimeRawInterval) != 0)
            {
                var qt   = SqlQueryTimed(sql, DbFuncType.TimeRawInterval, c.arrayResults, dbConnName);
                Fn  func = FuncRawIntervalQuery(qt);
                var fd   = new FuncDef(func, c.funcNamesPrefix + "_Raw", 3, 3,
                                       ValueInfo.CreateMany(qt.colsNames[0], "MIN_TIME__XT", "MAX_TIME__XT"),
                                       resultsInfo, FuncFlags.Defaults, 0, 0, c.ldr.cachingExpiration, c.ldr.cacheSubdomain,
                                       c.tblAttrs.ToDictionary(p => p.Key.ToString(), p => p.Value)
                                       );
                fd.xtraAttrs.Add(nameof(QueryTemplate), qt);
                yield return(fd);
            }
            #endregion
            #region Insert rows function
            if ((c.ldr.forKinds & DbFuncType.Insert) != 0)
            {
                var qt = SqlCommandInsert(sql, dbConnName, c.DefaultLocationForValueInfo, out var outputs);
                //todo: Sql insert
                //Fn func = FuncInsert(qt);
            }
            #endregion
        }
Ejemplo n.º 3
0
        FuncInfo(FuncDef fd, SolverAliases aliasOf, string cachingDomainParam = null)
        {
            name    = fd.name;
            this.fd = fd;
            if (cachingDomainParam != null && fd.cachingExpiration != TimeSpan.Zero)
            {
                nCachingInps = 1;
                inputs       = new string[fd.argsInfo.Length + nCachingInps];
                int k = 0;
                inputs[k++] = cachingDomainParam;
                foreach (var arg in fd.argsInfo)
                {
                    inputs[k++] = arg.ToString();
                }
            }
            else
            {
                inputs = new string[fd.argsInfo.Length];
                for (int i = 0; i < inputs.Length; i++)
                {
                    var s = fd.argsInfo[i].ToString();
                    inputs[i] = aliasOf.GetRealName(s);
                }
            }
            int no = fd.resultsInfo.Length;

            outputs = new string[no];
            var pureOuts = new List <string>(no);
            var inOuts   = new List <string>(no);

            for (int i = 0; i < outputs.Length; i++)
            {
                var s    = fd.resultsInfo[i].ToString();
                var real = aliasOf.GetRealName(s);
                if (real != s && !inputs.Contains(real))
                {
                    if (fd.kind != FuncKind.Macro)
                    {
                        throw new SolverException(string.Format("Name conflict between alias '{0}' and output of function '{1}'", s, name));
                    }
                }
                outputs[i] = real;
            }
            foreach (var s in outputs)
            {
                if (Array.IndexOf <string>(inputs, s) < 0)
                {
                    pureOuts.Add(s);
                }
                else
                {
                    System.Diagnostics.Debug.Assert(ValueInfo.IsID(s), $"Only _ID parameters can be 'in/out' // {name}:{s}");
                    inOuts.Add(s);
                }
            }
            var pureIns = new List <string>(no);

            for (int i = 0; i < inputs.Length; i++)
            {
                var s = inputs[i];
                if (Array.IndexOf <string>(outputs, s) < 0)
                {
                    pureIns.Add(s);
                }
            }

            this.pureIns  = pureIns.ToArray();
            this.pureOuts = pureOuts.ToArray();
            this.inOuts   = inOuts.ToArray();
        }