예제 #1
0
        private static string ParseBooleanParam(ArticleSearchQueryParam p)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.Boolean);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 2х (используем 1й, 2й - остальные отбрасываем)
            if (p.QueryParams == null || p.QueryParams.Length < 2)
            {
                throw new ArgumentException();
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException();
            }

            // второй параметр должен быть bool
            if (!(p.QueryParams[1] is bool))
            {
                throw new InvalidCastException();
            }

            var dbType    = QPContext.DatabaseType;
            var fieldName = SqlQuerySyntaxHelper.EscapeEntityName(dbType, p.FieldColumn.ToLower());

            return((bool)p.QueryParams[0]
                ? $"({GetTableAlias(p)}.{fieldName} IS NULL)"
                : $"({GetTableAlias(p)}.{fieldName} = {((bool)p.QueryParams[1] ? 1 : 0)})");
        }
예제 #2
0
        private static string ParseBooleanParam(ArticleSearchQueryParam p)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.Boolean);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 2х (используем 1й, 2й - остальные отбрасываем)
            if (p.QueryParams == null || p.QueryParams.Length < 2)
            {
                throw new ArgumentException();
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException();
            }

            // второй параметр должен быть bool
            if (!(p.QueryParams[1] is bool))
            {
                throw new InvalidCastException();
            }

            return((bool)p.QueryParams[0]
                ? $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] IS NULL)"
                : $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] = {((bool)p.QueryParams[1] ? 1 : 0)})");
        }
예제 #3
0
        private static string GetTableAlias(ArticleSearchQueryParam p)
        {
            if (string.IsNullOrEmpty(p.ContentId))
            {
                return(ContentTableAlias);
            }

            return(string.IsNullOrEmpty(p.ReferenceFieldId)
                ? ContentTableAlias + "_" + p.ContentId
                : ContentTableAlias + "_" + p.ContentId + "_" + p.ReferenceFieldId);
        }
        private ArticleLinkSearchParameter ParseParam(ArticleSearchQueryParam param)
        {
            Ensure.NotNull(param);
            Ensure.That(param.SearchType == ArticleFieldSearchType.M2MRelation || param.SearchType == ArticleFieldSearchType.M2ORelation);

            if (param == null)
            {
                throw new ArgumentException("p");
            }

            if (param.SearchType != ArticleFieldSearchType.M2MRelation && param.SearchType != ArticleFieldSearchType.M2ORelation)
            {
                throw new ArgumentException("Undefined search paramenter type: " + param.SearchType);
            }

            Ensure.NotNullOrWhiteSpace(param.FieldID, "FieldId");

            var fieldId = int.Parse(param.FieldID);

            Ensure.That <InvalidCastException>(param.QueryParams[0] is object[]);
            Ensure.That <InvalidCastException>(param.QueryParams[1] is bool);
            Ensure.That <InvalidCastException>(param.QueryParams[2] is bool);
            Ensure.That <InvalidCastException>(param.QueryParams[3] is bool);

            var isNull   = (bool)param.QueryParams[1];
            var inverse  = (bool)param.QueryParams[2];
            var unionAll = (bool)param.QueryParams[3];
            var values   = Enumerable.Empty <int>();

            if (!isNull)
            {
                if (param.QueryParams[0] == null || ((object[])param.QueryParams[0]).Length == 0)
                {
                    return(null);
                }

                values = ((object[])param.QueryParams[0]).Select(Convert.ToInt32);
            }

            var field    = _articleSearchRepository.GetFieldByID(fieldId);
            var linkedId = field.LinkId ?? field.BackRelationId;

            if (!linkedId.HasValue)
            {
                throw new ApplicationException("Не удалость получить LinkedId для поля с id = " + fieldId);
            }

            if (!int.TryParse(param.ContentID, out var extensionContentId))
            {
                extensionContentId = 0;
            }

            if (!int.TryParse(param.ReferenceFieldID, out var referenceFieldId))
            {
                referenceFieldId = 0;
            }

            var result = new ArticleLinkSearchParameter
            {
                LinkId             = linkedId.Value,
                ExtensionContentId = extensionContentId,
                ReferenceFieldId   = referenceFieldId,
                Ids          = values.ToArray(),
                IsManyToMany = param.SearchType == ArticleFieldSearchType.M2MRelation,
                IsNull       = isNull,
                Inverse      = inverse,
                UnionAll     = unionAll
            };

            if (!result.IsManyToMany)
            {
                Ensure.NotNull(field.BackRelation, $"Не удалость получить BackRelation для поля с id = {fieldId}");
                result.FieldName = field.BackRelation.Name;
                result.ContentId = field.BackRelation.ContentId;
            }

            return(result);
        }
예제 #5
0
        private static string ParseIdentifierParam(ArticleSearchQueryParam p, ICollection <DbParameter> sqlParams)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.Identifier);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 4х (используем 1й, 2й, 3й и 4й - остальные отбрасываем)
            if (p.QueryParams == null || p.QueryParams.Length < 4)
            {
                throw new ArgumentException();
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException();
            }

            // второй параметр должен быть int или long или null
            if (p.QueryParams[1] != null && !(p.QueryParams[1] is int || p.QueryParams[1] is long))
            {
                throw new InvalidCastException();
            }

            // третий параметр должен быть int или long или null
            if (p.QueryParams[2] != null && !(p.QueryParams[2] is int || p.QueryParams[2] is long))
            {
                throw new InvalidCastException();
            }

            // четвертый параметр должен быть bool
            if (!(p.QueryParams[3] is bool))
            {
                throw new InvalidCastException();
            }

            // пятый параметр должен быть null или object[]
            if (p.QueryParams[4] != null && !(p.QueryParams[4] is object[]))
            {
                throw new InvalidCastException();
            }

            // шестой параметр должен быть bool
            if (!(p.QueryParams[5] is bool))
            {
                throw new InvalidCastException();
            }

            var inverse   = (bool)p.QueryParams[0];
            var isByValue = (bool)p.QueryParams[3];
            var isByText  = (bool)p.QueryParams[5];
            var dbType    = QPContext.DatabaseType;

            var escapedFieldColumnName = SqlQuerySyntaxHelper.EscapeEntityName(dbType, p.FieldColumn.ToLower());

            if (isByText)
            {
                // Если массив null или пустой - то возвращаем null
                if (p.QueryParams[4] == null || ((object[])p.QueryParams[4]).Length == 0)
                {
                    return(null);
                }

                var fieldId   = p.FieldId ?? string.Empty;
                var paramName = "@field" + fieldId.Replace("-", "_");
                var values    = ((object[])p.QueryParams[4]).Select(n => n.ToString()?.Trim())
                                .Where(n => !String.IsNullOrEmpty(n)).Select(int.Parse).ToArray();
                if (values.Length == 1)
                {
                    sqlParams.Add(SqlQuerySyntaxHelper.CreateDbParameter(dbType, paramName, values[0]));
                    return(string.Format(inverse ? "({1}.{0} <> {2} OR {1}.{0} IS NULL)" : "({1}.{0} = {2})", escapedFieldColumnName, GetTableAlias(p), paramName));
                }

                sqlParams.Add(SqlQuerySyntaxHelper.GetIdsDatatableParam(paramName, values, dbType));
                return(string.Format(inverse ? "({1}.{0} NOT IN (select id from {2}) OR {1}.{0} IS NULL)" : "({1}.{0} IN (select id from {2}))",
                                     escapedFieldColumnName, GetTableAlias(p), SqlQuerySyntaxHelper.IdList(dbType, paramName, "i")));
            }

            // ReSharper disable MergeSequentialChecks
            var numberFrom = p.QueryParams[1] is int || p.QueryParams[1] == null ? (int?)p.QueryParams[1] : (long?)p.QueryParams[1];
            var numberTo   = p.QueryParams[2] is int || p.QueryParams[2] == null ? (int?)p.QueryParams[2] : (long?)p.QueryParams[2];

            // ReSharper restore MergeSequentialChecks

            if (isByValue)
            {
                return(!numberFrom.HasValue ? null : string.Format(inverse ? "({1}.{0} <> {2} OR {1}.{0} IS NULL)" : "({1}.{0} = {2})", escapedFieldColumnName, GetTableAlias(p), numberFrom));
            }

            if (!numberFrom.HasValue && !numberTo.HasValue)
            {
                return(null);
            }

            if (numberFrom.HasValue && !numberTo.HasValue)
            {
                return(inverse
                    ? $"({GetTableAlias(p)}.{escapedFieldColumnName} < {numberFrom})"
                    : $"({GetTableAlias(p)}.{escapedFieldColumnName} >= {numberFrom})");
            }

            if (!numberFrom.HasValue)
            {
                return(inverse
                    ? $"({GetTableAlias(p)}.{escapedFieldColumnName} > {numberTo})"
                    : $"({GetTableAlias(p)}.{escapedFieldColumnName} <= {numberTo})");
            }

            if (numberFrom.Value < numberTo.Value)
            {
                return($"({GetTableAlias(p)}.{escapedFieldColumnName} {(inverse ? "NOT" : "")} BETWEEN {numberFrom} AND {numberTo})");
            }

            return(numberFrom.Value > numberTo.Value
                ? $"({GetTableAlias(p)}.{escapedFieldColumnName} {(inverse ? "NOT" : "")} BETWEEN {numberTo} AND {numberFrom})"
                : inverse
                    ? $"({GetTableAlias(p)}.{escapedFieldColumnName} <> {numberFrom})"
                    : $"({GetTableAlias(p)}.{escapedFieldColumnName} = {numberFrom})");
        }
예제 #6
0
        private static string ParseO2MRelationParam(ArticleSearchQueryParam p, ICollection <DbParameter> sqlParams)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.O2MRelation || p.SearchType == ArticleFieldSearchType.Classifier);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 2х (используем 1й и 2й - остальные отбрасываем)
            if (p.QueryParams == null || p.QueryParams.Length < 3)
            {
                throw new ArgumentException();
            }

            // первый параметр должен быть null или object[]
            if (p.QueryParams[0] != null && !(p.QueryParams[0] is object[]))
            {
                throw new InvalidCastException();
            }

            // второй параметр должен быть bool
            if (!(p.QueryParams[1] is bool))
            {
                throw new InvalidCastException();
            }

            if (!(p.QueryParams[2] is bool))
            {
                throw new InvalidCastException();
            }

            var isNull        = (bool)p.QueryParams[1];
            var inverse       = (bool)p.QueryParams[2];
            var inverseString = inverse ? "NOT" : string.Empty;

            var dbType    = QPContext.DatabaseType;
            var fieldName = SqlQuerySyntaxHelper.EscapeEntityName(dbType, p.FieldColumn.ToLower());

            if (isNull)
            {
                return(string.Format("({1}.{0} IS {2} NULL)", fieldName, GetTableAlias(p), inverseString));
            }

            // Если массив null или пустой - то возвращаем null
            if (p.QueryParams[0] == null || ((object[])p.QueryParams[0]).Length == 0)
            {
                return(null);
            }

            var values    = ((object[])p.QueryParams[0]).Select(n => int.Parse(n.ToString())).ToArray();
            var fieldId   = p.FieldId ?? string.Empty;
            var paramName = "@field" + fieldId.Replace("-", "_");

            if (values.Length == 1)
            {
                sqlParams.Add(SqlQuerySyntaxHelper.CreateDbParameter(dbType, paramName, values[0]));
                return(inverse
                    ? $"({GetTableAlias(p)}.{fieldName} <> {paramName} OR {GetTableAlias(p)}.{fieldName} IS NULL)"
                    : $"({GetTableAlias(p)}.{fieldName} = {paramName})");
            }

            sqlParams.Add(SqlQuerySyntaxHelper.GetIdsDatatableParam(paramName, values, dbType));
            return(inverse
                ? $"({GetTableAlias(p)}.{fieldName} NOT IN (select id from {SqlQuerySyntaxHelper.IdList(dbType, paramName, "i")}) OR {GetTableAlias(p)}.{fieldName} IS NULL)"
                : $"({GetTableAlias(p)}.{fieldName} IN (select id from {SqlQuerySyntaxHelper.IdList(dbType, paramName, "i")}))");
        }
예제 #7
0
        private static string ParseNumericRangeParam(ArticleSearchQueryParam p)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.NumericRange);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 4х (используем 1й, 2й, 3й и 4й, 5-й опционально)
            if (p.QueryParams == null)
            {
                throw new ArgumentException("QueryParams is null");
            }
            if (p.QueryParams.Length < 4)
            {
                throw new ArgumentException("QueryParams length < 4");
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException("param 0");
            }

            // второй параметр должен быть int или long или null
            if (p.QueryParams[1] != null && !(p.QueryParams[1] is int || p.QueryParams[1] is long))
            {
                throw new InvalidCastException("param 1");
            }

            // третий параметр должен быть int или long или null
            if (p.QueryParams[2] != null && !(p.QueryParams[2] is int || p.QueryParams[2] is long))
            {
                throw new InvalidCastException("param 2");
            }

            // четвертый параметр должен быть bool
            if (!(p.QueryParams[3] is bool))
            {
                throw new InvalidCastException("param 3");
            }

            var isNull    = (bool)p.QueryParams[0];
            var isByValue = (bool)p.QueryParams[3];
            var inverse   = p.QueryParams.Length > 4 && p.QueryParams[4] is bool && (bool)p.QueryParams[4];

            var dbType    = QPContext.DatabaseType;
            var fieldName = SqlQuerySyntaxHelper.EscapeEntityName(dbType, p.FieldColumn.ToLower());

            if (isNull)
            {
                return($"({GetTableAlias(p)}.{fieldName} IS {(inverse ? "NOT " : "")}NULL)");
            }

            // ReSharper disable MergeSequentialChecks
            var numberFrom = p.QueryParams[1] is int || p.QueryParams[1] == null ? (int?)p.QueryParams[1] : (long?)p.QueryParams[1];
            var numberTo   = p.QueryParams[2] is int || p.QueryParams[2] == null ? (int?)p.QueryParams[2] : (long?)p.QueryParams[2];

            if (isByValue)
            {
                return(!numberFrom.HasValue ? null : $"({GetTableAlias(p)}.{fieldName} {(inverse ? "<>" : "=")} {numberFrom})");
            }

            if (!numberFrom.HasValue && !numberTo.HasValue)
            {
                return(null);
            }

            if (numberFrom.HasValue && !numberTo.HasValue)
            {
                return($"({GetTableAlias(p)}.{fieldName} {(inverse ? "<" : ">=")} {numberFrom})");
            }
            if (!numberFrom.HasValue)
            {
                return($"({GetTableAlias(p)}.{fieldName} {(inverse ? ">" : "<=")} {numberTo})");
            }

            if (numberFrom.Value < numberTo.Value)
            {
                return($"({GetTableAlias(p)}.{fieldName} {(inverse ? "NOT " : "")}BETWEEN {numberFrom} AND {numberTo})");
            }

            return(numberFrom.Value > numberTo.Value
                ? $"({GetTableAlias(p)}.{fieldName} {(inverse ? "NOT " : "")}BETWEEN {numberTo} AND {numberFrom})"
                : $"({GetTableAlias(p)}.{fieldName} {(inverse ? "<>" : "=")} {numberFrom})");
        }
예제 #8
0
        private static string ParseTimeRangeParam(ArticleSearchQueryParam p)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.TimeRange);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 3х (используем 1й, 2й, 3й и 4й- остальные отбрасываем)
            if (p.QueryParams == null || p.QueryParams.Length < 4)
            {
                throw new ArgumentException();
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException();
            }

            // второй параметр должен быть строкой или null
            if (p.QueryParams[1] != null && !(p.QueryParams[1] is string))
            {
                throw new InvalidCastException();
            }

            // третий параметр должен быть строкой или null
            if (p.QueryParams[2] != null && !(p.QueryParams[2] is string))
            {
                throw new InvalidCastException();
            }

            // четвертый параметр должен быть bool
            if (!(p.QueryParams[3] is bool))
            {
                throw new InvalidCastException();
            }

            var isNull         = (bool)p.QueryParams[0];
            var timeFromString = (string)p.QueryParams[1];
            var timeToString   = (string)p.QueryParams[2];
            var isByValue      = (bool)p.QueryParams[3];

            TimeSpan?timeFrom = null;
            TimeSpan?timeTo   = null;

            var dbType    = QPContext.DatabaseType;
            var fieldName = SqlQuerySyntaxHelper.EscapeEntityName(dbType, p.FieldColumn.ToLower());

            // isnull == true

            if (isNull)
            {
                return($"({GetTableAlias(p)}.{fieldName} IS NULL)");
            }

            var ns = SqlQuerySyntaxHelper.DbSchemaName(dbType);

            if (isByValue)
            {
                if (string.IsNullOrWhiteSpace(timeFromString))
                {
                    return(null);
                }

                if (!Converter.TryConvertToSqlTimeString(timeFromString, out _, out timeFrom))
                {
                    throw new FormatException("time From");
                }

                // ReSharper disable once PossibleInvalidOperationException
                return($"({ns}.qp_abs_time_seconds({GetTableAlias(p)}.{fieldName}) = {timeFrom.Value.TotalSeconds})");
            }

            // если обе даты пустые - то возвращаем null
            if (string.IsNullOrWhiteSpace(timeFromString) && string.IsNullOrWhiteSpace(timeToString))
            {
                return(null);
            }

            if (!string.IsNullOrWhiteSpace(timeFromString))
            {
                if (!Converter.TryConvertToSqlTimeString(timeFromString, out _, out timeFrom))
                {
                    throw new FormatException("time From");
                }
            }

            if (!string.IsNullOrWhiteSpace(timeToString))
            {
                if (!Converter.TryConvertToSqlTimeString(timeToString, out var _, out timeTo))
                {
                    throw new FormatException("time To");
                }
            }

            // дата "до" пустая а "от" не пустая
            if (!string.IsNullOrWhiteSpace(timeFromString) && string.IsNullOrWhiteSpace(timeToString))
            {
                // ReSharper disable once PossibleInvalidOperationException
                return($"({ns}.qp_abs_time_seconds({GetTableAlias(p)}.{fieldName}) >= {timeFrom.Value.TotalSeconds})");
            }

            // дата "от" пустая а "до" не пустая
            if (string.IsNullOrWhiteSpace(timeFromString) && !string.IsNullOrWhiteSpace(timeToString))
            {
                // ReSharper disable once PossibleInvalidOperationException
                return($"({ns}.qp_abs_time_seconds({GetTableAlias(p)}.{fieldName}) <= {timeTo.Value.TotalSeconds})");
            }

            // обе границы диапазона не пустые
            // From < To
            // ReSharper disable PossibleInvalidOperationException
            if (timeFrom.Value < timeTo.Value)
            {
                return($"({ns}.qp_abs_time_seconds({GetTableAlias(p)}.{fieldName}) BETWEEN {timeFrom.Value.TotalSeconds} AND {timeTo.Value.TotalSeconds})");
            }

            // ReSharper restore PossibleInvalidOperationException

            return(timeFrom.Value > timeTo.Value
                ? $"({ns}.qp_abs_time_seconds({GetTableAlias(p)}.{fieldName}) BETWEEN {timeTo.Value.TotalSeconds} AND {timeFrom.Value.TotalSeconds})"
                : $"({ns}.qp_abs_time_seconds({GetTableAlias(p)}.{fieldName}) = {timeFrom.Value.TotalSeconds})");
        }
예제 #9
0
        private static string ParseDateTimeRangeParam(ArticleSearchQueryParam p)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.DateTimeRange);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 4х (используем 1й, 2й, 3й и 4й остальные отбрасываем)
            if (p.QueryParams == null || p.QueryParams.Length < 4)
            {
                throw new ArgumentException();
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException();
            }

            // второй параметр должен быть строкой или null
            if (p.QueryParams[1] != null && !(p.QueryParams[1] is string))
            {
                throw new InvalidCastException();
            }

            // третий параметр должен быть строкой или null
            if (p.QueryParams[2] != null && !(p.QueryParams[2] is string))
            {
                throw new InvalidCastException();
            }

            // четвертый параметр должен быть bool
            if (!(p.QueryParams[3] is bool))
            {
                throw new InvalidCastException();
            }

            var isNull             = (bool)p.QueryParams[0];
            var datetimeFromString = (string)p.QueryParams[1];
            var datetimeToString   = (string)p.QueryParams[2];
            var isByValue          = (bool)p.QueryParams[3];

            string   sqlDateTimeFromString;
            DateTime?datetimeFrom;
            string   sqlDateTimeToString;
            DateTime?datetimeTo;

            var dbType = QPContext.DatabaseType;

            var fieldName = SqlQuerySyntaxHelper.EscapeEntityName(dbType, p.FieldColumn.ToLower());

            if (isNull)
            {
                return($"({GetTableAlias(p)}.{fieldName} IS NULL)");
            }

            if (isByValue)
            {
                if (string.IsNullOrWhiteSpace(datetimeFromString))
                {
                    return(null);
                }

                if (!Converter.TryConvertToSqlDateString(datetimeFromString, null, out sqlDateTimeFromString, out datetimeFrom))
                {
                    throw new FormatException("datetime From");
                }

                return($"({GetTableAlias(p)}.{fieldName} = '{sqlDateTimeFromString}')");
            }

            // если обе даты пустые - то возвращаем null
            if (string.IsNullOrWhiteSpace(datetimeFromString) && string.IsNullOrWhiteSpace(datetimeToString))
            {
                return(null);
            }

            // дата "до" пустая а "от" не пустая
            if (!string.IsNullOrWhiteSpace(datetimeFromString) && string.IsNullOrWhiteSpace(datetimeToString))
            {
                if (!Converter.TryConvertToSqlDateString(datetimeFromString, null, out sqlDateTimeFromString, out datetimeFrom))
                {
                    throw new FormatException("datetime From");
                }

                return($"({GetTableAlias(p)}.{fieldName} >= '{sqlDateTimeFromString}')");
            }

            // дата "от" пустая а "до" не пустая
            if (string.IsNullOrWhiteSpace(datetimeFromString) && !string.IsNullOrWhiteSpace(datetimeToString))
            {
                if (!Converter.TryConvertToSqlDateString(datetimeToString, new TimeSpan(23, 59, 59), out sqlDateTimeToString, out datetimeTo))
                {
                    throw new FormatException("datetime To");
                }

                return($"({GetTableAlias(p)}.{fieldName} <= '{sqlDateTimeToString}')");
            }

            // обе границы диапазона не пустые
            if (!Converter.TryConvertToSqlDateString(datetimeFromString, null, out sqlDateTimeFromString, out datetimeFrom))
            {
                throw new FormatException("datetime From");
            }

            if (!Converter.TryConvertToSqlDateString(datetimeToString, null, out sqlDateTimeToString, out datetimeTo))
            {
                throw new FormatException("datetime To");
            }

            // From < To
            // ReSharper disable PossibleInvalidOperationException
            return(datetimeFrom.Value < datetimeTo.Value
                ? $"({GetTableAlias(p)}.{fieldName} BETWEEN '{sqlDateTimeFromString}' AND '{sqlDateTimeToString}')"
                : $"({GetTableAlias(p)}.{fieldName} BETWEEN '{sqlDateTimeToString}' AND '{sqlDateTimeFromString}')");
            // ReSharper restore PossibleInvalidOperationException
        }
예제 #10
0
        /// <summary>
        /// Парсинг параметра поиска по тексту
        /// </summary>
        private static string ParseTextParam(ArticleSearchQueryParam p, ICollection <DbParameter> sqlParams)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.Text || p.SearchType == ArticleFieldSearchType.StringEnum);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn is empty");
            }

            // параметры не пустые и их не меньше 2х (используем 1, 2, опциоально - 3)
            if (p.QueryParams == null)
            {
                throw new ArgumentException("QueryParams is null");
            }
            if (p.QueryParams.Length < 2)
            {
                throw new ArgumentException("QueryParams length < 2");
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException("param 0");
            }

            // второй параметр должен быть строкой или null
            if (p.QueryParams[1] != null && !(p.QueryParams[1] is string))
            {
                throw new InvalidCastException("param 1");
            }

            var dbType    = QPContext.DatabaseType;
            var fieldId   = p.FieldId ?? string.Empty;
            var paramName = "@field" + fieldId.Replace("-", "_");
            var escapedFieldColumnName = SqlQuerySyntaxHelper.EscapeEntityName(dbType, p.FieldColumn.ToLower());

            var isNull  = (bool)p.QueryParams[0];
            var inverse = p.QueryParams.Length > 2 && p.QueryParams[2] is bool && (bool)p.QueryParams[2];

            var exactMatch     = p.QueryParams.Length > 3 && p.QueryParams[3] is bool && (bool)p.QueryParams[3];
            var startFromBegin = p.QueryParams.Length > 4 && p.QueryParams[4] is bool && (bool)p.QueryParams[4];
            var listTexts      = (p.QueryParams.Length > 5 && p.QueryParams[5] is object[]) ? (object[])p.QueryParams[5] : Array.Empty <object>();

            if (listTexts.Length > 0)
            {
                sqlParams.Add(SqlQuerySyntaxHelper.GetStringsDatatableParam(
                                  paramName, listTexts.Select(n => n.ToString()?.Trim()), dbType)
                              );
                return(string.Format(inverse ? "({1}.{0} NOT IN (select value from {2}) OR {1}.{0} IS NULL)" : "({1}.{0} IN (select value from {2}))",
                                     escapedFieldColumnName, GetTableAlias(p), SqlQuerySyntaxHelper.StrList(dbType, paramName, "v")));
            }

            // isnull == true
            if (isNull)
            {
                return($"({GetTableAlias(p)}.{escapedFieldColumnName} IS {(inverse ? "NOT " : "")}NULL)");
            }

            // isnull == false  строка пустая
            if (string.IsNullOrEmpty((string)p.QueryParams[1]))
            {
                return(null);
            }

            // Иначе формируем результат
            var value = exactMatch ?
                        Cleaner.ToSafeSqlString(((string)p.QueryParams[1]).Trim()) :
                        Cleaner.ToSafeSqlLikeCondition(dbType, ((string)p.QueryParams[1]).Trim());

            if (exactMatch)
            {
                return($"({GetTableAlias(p)}.{escapedFieldColumnName} {(inverse ? "<> " : "=")} '{value}')");
            }

            var like = dbType == DatabaseType.Postgres ? "ILIKE" : "LIKE";

            return(startFromBegin
                ? $"({GetTableAlias(p)}.{escapedFieldColumnName} {like} '{(inverse ? "%" + value : value + "%")}')"
                : $"({GetTableAlias(p)}.{escapedFieldColumnName} {(inverse ? "NOT " : "")}{like} '%{value}%')");
        }
예제 #11
0
        private static string ParseIdentifierParam(ArticleSearchQueryParam p, ICollection <SqlParameter> sqlParams)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.Identifier);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 4х (используем 1й, 2й, 3й и 4й - остальные отбрасываем)
            if (p.QueryParams == null || p.QueryParams.Length < 4)
            {
                throw new ArgumentException();
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException();
            }

            // второй параметр должен быть int или long или null
            if (p.QueryParams[1] != null && !(p.QueryParams[1] is int || p.QueryParams[1] is long))
            {
                throw new InvalidCastException();
            }

            // третий параметр должен быть int или long или null
            if (p.QueryParams[2] != null && !(p.QueryParams[2] is int || p.QueryParams[2] is long))
            {
                throw new InvalidCastException();
            }

            // четвертый параметр должен быть bool
            if (!(p.QueryParams[3] is bool))
            {
                throw new InvalidCastException();
            }

            // пятый параметр должен быть null или object[]
            if (p.QueryParams[4] != null && !(p.QueryParams[4] is object[]))
            {
                throw new InvalidCastException();
            }

            // шестой параметр должен быть bool
            if (!(p.QueryParams[5] is bool))
            {
                throw new InvalidCastException();
            }

            var inverse   = (bool)p.QueryParams[0];
            var isByValue = (bool)p.QueryParams[3];
            var isByText  = (bool)p.QueryParams[5];

            if (isByText)
            {
                // Если массив null или пустой - то возвращаем null
                if (p.QueryParams[4] == null || ((object[])p.QueryParams[4]).Length == 0)
                {
                    return(null);
                }

                var fieldId   = p.FieldID ?? string.Empty;
                var paramName = "@field" + fieldId.Replace("-", "_");
                var values    = ((object[])p.QueryParams[4]).Select(n => int.Parse(n.ToString())).ToArray();
                if (values.Length == 1)
                {
                    sqlParams.Add(new SqlParameter(paramName, values[0]));
                    return(string.Format(inverse ? "({1}.[{0}] <> {2} OR {1}.[{0}] IS NULL)" : "({1}.[{0}] = {2})", p.FieldColumn.ToLower(), GetTableAlias(p), paramName));
                }

                sqlParams.Add(new SqlParameter(paramName, SqlDbType.Structured)
                {
                    TypeName = "Ids", Value = Common.IdsToDataTable(values)
                });
                return(string.Format(inverse ? "({1}.[{0}] NOT IN (select id from {2}) OR {1}.[{0}] IS NULL)" : "({1}.[{0}] IN (select id from {2}))", p.FieldColumn.ToLower(), GetTableAlias(p), paramName));
            }

            // ReSharper disable MergeSequentialChecks
            var numberFrom = p.QueryParams[1] is int || p.QueryParams[1] == null ? (int?)p.QueryParams[1] : (long?)p.QueryParams[1];
            var numberTo   = p.QueryParams[2] is int || p.QueryParams[2] == null ? (int?)p.QueryParams[2] : (long?)p.QueryParams[2];

            // ReSharper restore MergeSequentialChecks

            if (isByValue)
            {
                return(!numberFrom.HasValue ? null : string.Format(inverse ? "({1}.[{0}] <> {2} OR {1}.[{0}] IS NULL)" : "({1}.[{0}] = {2})", p.FieldColumn.ToLower(), GetTableAlias(p), numberFrom));
            }

            if (!numberFrom.HasValue && !numberTo.HasValue)
            {
                return(null);
            }

            if (numberFrom.HasValue && !numberTo.HasValue)
            {
                return(inverse
                    ? $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] < {numberFrom})"
                    : $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] >= {numberFrom})");
            }

            if (!numberFrom.HasValue)
            {
                return(inverse
                    ? $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] > {numberTo})"
                    : $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] <= {numberTo})");
            }

            if (numberFrom.Value < numberTo.Value)
            {
                return($"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] {(inverse ? "NOT" : "")} BETWEEN {numberFrom} AND {numberTo})");
            }

            return(numberFrom.Value > numberTo.Value
                ? $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] {(inverse ? "NOT" : "")} BETWEEN {numberTo} AND {numberFrom})"
                : inverse
                    ? $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] <> {numberFrom})"
                    : $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] = {numberFrom})");
        }
예제 #12
0
        private static string ParseO2MRelationParam(ArticleSearchQueryParam p, ICollection <SqlParameter> sqlParams)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.O2MRelation || p.SearchType == ArticleFieldSearchType.Classifier);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn");
            }

            // параметры не пустые и их не меньше 2х (используем 1й и 2й - остальные отбрасываем)
            if (p.QueryParams == null || p.QueryParams.Length < 3)
            {
                throw new ArgumentException();
            }

            // первый параметр должен быть null или object[]
            if (p.QueryParams[0] != null && !(p.QueryParams[0] is object[]))
            {
                throw new InvalidCastException();
            }

            // второй параметр должен быть bool
            if (!(p.QueryParams[1] is bool))
            {
                throw new InvalidCastException();
            }

            if (!(p.QueryParams[2] is bool))
            {
                throw new InvalidCastException();
            }

            var isNull        = (bool)p.QueryParams[1];
            var inverse       = (bool)p.QueryParams[2];
            var inverseString = inverse ? "NOT" : string.Empty;

            if (isNull)
            {
                return(string.Format("({1}.[{0}] IS {2} NULL)", p.FieldColumn.ToLower(), GetTableAlias(p), inverseString));
            }

            // Если массив null или пустой - то возвращаем null
            if (p.QueryParams[0] == null || ((object[])p.QueryParams[0]).Length == 0)
            {
                return(null);
            }

            var values    = ((object[])p.QueryParams[0]).Select(n => int.Parse(n.ToString())).ToArray();
            var fieldId   = p.FieldID ?? string.Empty;
            var paramName = "@field" + fieldId.Replace("-", "_");

            if (values.Length == 1)
            {
                sqlParams.Add(new SqlParameter(paramName, values[0]));
                return(inverse
                    ? $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] <> {paramName} OR {GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] IS NULL)"
                    : $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] = {paramName})");
            }

            sqlParams.Add(new SqlParameter(paramName, SqlDbType.Structured)
            {
                TypeName = "Ids", Value = Common.IdsToDataTable(values)
            });
            return(inverse
                ? $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] NOT IN (select id from {paramName}) OR {GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] IS NULL)"
                : $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] IN (select id from {paramName}))");
        }
예제 #13
0
        /// <summary>
        /// Парсинг параметра поиска по тексту
        /// </summary>
        private static string ParseTextParam(ArticleSearchQueryParam p)
        {
            Ensure.NotNull(p);
            Ensure.That(p.SearchType == ArticleFieldSearchType.Text || p.SearchType == ArticleFieldSearchType.StringEnum);

            if (string.IsNullOrWhiteSpace(p.FieldColumn))
            {
                throw new ArgumentException("FieldColumn is empty");
            }

            // параметры не пустые и их не меньше 2х (используем 1, 2, опциоально - 3)
            if (p.QueryParams == null)
            {
                throw new ArgumentException("QueryParams is null");
            }
            if (p.QueryParams.Length < 2)
            {
                throw new ArgumentException("QueryParams length < 2");
            }

            // первый параметр должен быть bool
            if (!(p.QueryParams[0] is bool))
            {
                throw new InvalidCastException("param 0");
            }

            // второй параметр должен быть строкой или null
            if (p.QueryParams[1] != null && !(p.QueryParams[1] is string))
            {
                throw new InvalidCastException("param 1");
            }

            var isNull  = (bool)p.QueryParams[0];
            var inverse = p.QueryParams.Length > 2 && p.QueryParams[2] is bool && (bool)p.QueryParams[2];

            var exactMatch     = p.QueryParams.Length > 3 && p.QueryParams[3] is bool && (bool)p.QueryParams[3];
            var startFromBegin = p.QueryParams.Length > 4 && p.QueryParams[4] is bool && (bool)p.QueryParams[4];

            // isnull == true
            if (isNull)
            {
                return($"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] IS {(inverse ? "NOT " : "")}NULL)");
            }

            // isnull == false  строка пустая
            if (string.IsNullOrEmpty((string)p.QueryParams[1]))
            {
                return(null);
            }

            // Иначе формируем результат
            var value = Cleaner.ToSafeSqlLikeCondition(((string)p.QueryParams[1]).Trim());

            if (exactMatch)
            {
                return($"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] {(inverse ? "<> " : "=")} '{value}')");
            }

            return(startFromBegin
                ? $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] LIKE '{(inverse ? "%" + value : value + "%")}')"
                : $"({GetTableAlias(p)}.[{p.FieldColumn.ToLower()}] {(inverse ? "NOT " : "")}LIKE '%{value}%')");
        }