Example #1
0
        /// <summary>
        ///     Splits the given <paramref name="sql" /> into <paramref name="parts" />;
        /// </summary>
        /// <param name="sql">The SQL to split.</param>
        /// <param name="parts">The SQL parts.</param>
        /// <returns><c>True</c> if the SQL could be split; else, <c>False</c>.</returns>
        public static bool SplitSql(string sql, out SqlParts parts)
        {
            parts.Sql              = sql;
            parts.SqlCount         = null;
            parts.SqlFrom          = null;
            parts.SqlSelectRemoved = null;
            parts.SqlOrderBy       = null;
            parts.SqlOrderByFields = null;

            // Extract the columns from "SELECT <whatever> FROM"
            var m = RegexColumns.Match(sql);

            if (!m.Success)
            {
                return(false);
            }

            // Save column list and replace with COUNT(*)
            var g = m.Groups[1];

            parts.SqlSelectRemoved = sql.Substring(g.Index);

            var from = sql.Substring(g.Index + g.Length);

            parts.SqlFrom = from.Replace("FROM ", string.Empty);

            if (RegexDistinct.IsMatch(parts.SqlSelectRemoved))
            {
                parts.SqlCount = sql.Substring(0, g.Index) + "COUNT(" + m.Groups[1].ToString().Trim() + ") " + from;
            }
            else
            {
                parts.SqlCount = sql.Substring(0, g.Index) + "COUNT(*) " + from;
            }

            // Look for the last "ORDER BY <whatever>" clause not part of a ROW_NUMBER expression
            m = RegexOrderBy.Match(parts.SqlCount);

            if (m.Success)
            {
                g = m.Groups[0];
                parts.SqlOrderBy       = g.ToString();
                parts.SqlOrderByFields = m.Groups.OfType <Group>()
                                         .Select(x => x.Value.Replace("ORDER BY", string.Empty).Trim()).Where(x => x != string.Empty)
                                         .ToArray();
                parts.SqlCount = parts.SqlCount.Substring(0, g.Index) + parts.SqlCount.Substring(g.Index + g.Length);
            }

            return(true);
        }
        private SqlParts GetPartsData(OrderRules rules)
        {
            var offerJoinPart    = string.Empty;
            var offerSelectPart  = string.Empty;
            var buyingJoinPart   = string.Empty;
            var buyingSelectPart = string.Empty;

            if (rules.OfferMatrix.HasValue)
            {
                offerJoinPart = "left join usersettings.PricesData pd1 on pd1.PriceCode = mol.PriceId\r\n"
                                + "left join customers.Suppliers s1 on s1.Id = pd1.FirmCode";
                offerSelectPart = "Concat(s1.Name, ' - (', pd1.PriceName, ')')";
            }

            if (rules.BuyingMatrix.HasValue)
            {
                buyingJoinPart = "left join usersettings.PricesData pd3 on pd3.PriceCode = bol.PriceId\r\n"
                                 + "left join customers.Suppliers s3 on s3.Id = pd3.FirmCode";
                buyingSelectPart = "Concat(s3.Name, ' - (', pd3.PriceName, ')')";
            }
            var part = new SqlParts();

            if (!string.IsNullOrEmpty(offerJoinPart))
            {
                part.Join += offerJoinPart + Environment.NewLine;
            }
            if (!string.IsNullOrEmpty(buyingJoinPart))
            {
                part.Join += buyingJoinPart + Environment.NewLine;
            }
            if (rules.OfferMatrix.HasValue && rules.BuyingMatrix.HasValue)
            {
                part.Select = string.Format(@"if(({0}) is not null, {0}, {1})", offerSelectPart, buyingSelectPart);
            }
            else
            {
                if (rules.OfferMatrix.HasValue)
                {
                    part.Select = offerSelectPart;
                }
                if (rules.BuyingMatrix.HasValue)
                {
                    part.Select = buyingSelectPart;
                }
            }
            part.Select += " as MatrixPriceName";
            return(part);
        }
        internal SqlGeneratorQueryModelVisitor(ExcelQueryArgs args)
        {
            _args = args;
            SqlStatement = new SqlParts();
            SqlStatement.Table = (String.IsNullOrEmpty(_args.StartRange)) ?
                !String.IsNullOrEmpty(_args.NamedRangeName) && String.IsNullOrEmpty(_args.WorksheetName) ?
                string.Format("[{0}]",
                    _args.NamedRangeName) :
                string.Format("[{0}${1}]",
                    _args.WorksheetName, _args.NamedRangeName) :
                string.Format("[{0}${1}:{2}]",
                    _args.WorksheetName, _args.StartRange, _args.EndRange);

            if (!string.IsNullOrEmpty(_args.WorksheetName) && _args.WorksheetName.ToLower().EndsWith(".csv"))
                SqlStatement.Table = SqlStatement.Table.Replace("$]", "]");
        }
Example #4
0
        private bool CheckIfInvalidColumnNameUsed(SqlParts sql)
        {
            var usedColumns  = sql.ColumnNamesUsed;
            var tableColumns = ExcelUtilities.GetColumnNames(_args.WorksheetName, _args.NamedRangeName, _args.FileName);

            foreach (var column in usedColumns)
            {
                if (!tableColumns.Contains(column))
                {
                    throw new DataException(string.Format(
                                                "'{0}' is not a valid column name. " +
                                                "Valid column names are: '{1}'",
                                                column,
                                                string.Join("', '", tableColumns.ToArray())));
                }
            }
            return(false);
        }
Example #5
0
        public object ParseSQLSelect(string SQL, SqlParts part)
        {
            //Expected sequence (1) Call ParseSQLSelect with source SQL and a given SqlPart.
            //Subsequent calls can then be made to return other parts without always passing
            //return arguments as well as avoiding re-parsing on subsequent calls.
            if (SQL != Source)
            {
                ParseSQLSelect(SQL);
                //Tack-on HavingClause/GroupByClause data in WhereClause... if (the calling application needs these separate, it can call the other method...
                if (!string.IsNullOrEmpty(HavingClause))
                {
                    WhereClause += $" Having {HavingClause}";
                }
                if (!string.IsNullOrEmpty(GroupByClause))
                {
                    WhereClause += $" Group By {GroupByClause}";
                }
            }
            switch (part)
            {
            case SqlParts.Distinct: return(Distinct);

            case SqlParts.Fields: return(Fields);

            case SqlParts.FromClause: return(FromClause);

            case SqlParts.WhereClause: return(WhereClause);

            case SqlParts.HavingClause: return(HavingClause);

            case SqlParts.GroupByClause: return(GroupByClause);

            case SqlParts.OrderByClause: return(OrderByClause);

            case SqlParts.RowLimit: return(RowLimit);

            default:
                throw new NotSupportedException($"Unexpected SqlParts value ({part})encountered.");
            }
        }
Example #6
0
        private void LogSqlStatement(SqlParts sqlParts)
        {
            if (_log.IsDebugEnabled)
            {
                var logMessage = new StringBuilder();
                logMessage.AppendFormat("{0};", sqlParts);
                for (var i = 0; i < sqlParts.Parameters.Count(); i++)
                {
                    var paramValue   = sqlParts.Parameters.ElementAt(i).Value.ToString();
                    var paramMessage = string.Format(" p{0} = '{1}';",
                                                     i, sqlParts.Parameters.ElementAt(i).Value);

                    if (paramValue.IsNumber())
                    {
                        paramMessage = paramMessage.Replace("'", "");
                    }
                    logMessage.Append(paramMessage);
                }

                var sqlLog = LogManager.GetLogger("LinqToExcel.SQL");
                sqlLog.Debug(logMessage.ToString());
            }
        }
Example #7
0
        /// <summary>
        /// Executes the sql query and returns the data results
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="queryModel">Linq query model</param>
        protected IEnumerable <object> GetDataResults(SqlParts sql, QueryModel queryModel)
        {
            IEnumerable <object> results;
            OleDbDataReader      data = null;

            var conn    = ExcelUtilities.GetConnection(_args);
            var command = conn.CreateCommand();

            try
            {
                if (conn.State == ConnectionState.Closed)
                {
                    conn.Open();
                }

                command.CommandText = sql.ToString();
                command.Parameters.AddRange(sql.Parameters.ToArray());
                try { data = command.ExecuteReader(); }
                catch (OleDbException e)
                {
                    if (e.Message.Contains(_args.WorksheetName))
                    {
                        throw new DataException(
                                  string.Format(
                                      "'{0}' is not a valid worksheet name in file {3}. Valid worksheet names are: '{1}'. Error received: {2}",
                                      _args.WorksheetName,
                                      string.Join("', '", ExcelUtilities.GetWorksheetNames(_args.FileName).ToArray()),
                                      e.Message, _args.FileName), e);
                    }
                    if (!CheckIfInvalidColumnNameUsed(sql))
                    {
                        throw;
                    }
                }

                var columns = ExcelUtilities.GetColumnNames(data);
                LogColumnMappingWarnings(columns);
                if (columns.Count() == 1 && columns.First() == "Expr1000")
                {
                    results = GetScalarResults(data);
                }
                else if (queryModel.MainFromClause.ItemType == typeof(ExcelRow))
                {
                    results = GetRowResults(data, columns);
                }
                else if (queryModel.MainFromClause.ItemType == typeof(ExcelRowNoHeader))
                {
                    results = GetRowNoHeaderResults(data);
                }
                else
                {
                    results = GetTypeResults(data, columns, queryModel);
                }
            }
            finally
            {
                command.Dispose();

                if (!_args.UsePersistentConnection)
                {
                    conn.Dispose();
                    _args.PersistentConnection = null;
                }
            }

            return(results);
        }