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