public object SelectOne(IQueryExpression queryExpression) { IList list = new List <object>(1); IQueryExpression q2 = new QueryExpression(); q2.EntityType = queryExpression.EntityType; q2.GroupBys = queryExpression.GroupBys; q2.Havings = queryExpression.Havings; q2.IsDistinct = queryExpression.IsDistinct; q2.OrderBys = queryExpression.OrderBys; q2.PageIndex = 1; q2.PageSize = 1; q2.ReturnMatchedCount = false; q2.Selects = queryExpression.Selects; q2.Wheres = queryExpression.Wheres; SelectCollection(list, q2); if (list.Count > 0) { return(list[0]); } else { return(null); } }
public IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow, IDictionary <string, IFilter> enabledFilters) { var key = new HQLQueryPlanKey(queryExpression, shallow, enabledFilters); var plan = (QueryExpressionPlan)planCache[key]; if (plan == null) { if (log.IsDebugEnabled) { log.Debug("unable to locate HQL query plan in cache; generating (" + queryExpression.Key + ")"); } plan = new QueryExpressionPlan(queryExpression, shallow, enabledFilters, factory); planCache.Put(key, plan); } else { if (log.IsDebugEnabled) { log.Debug("located HQL query plan in cache (" + queryExpression.Key + ")"); } plan = CopyIfRequired(plan, queryExpression); } return(plan); }
protected internal virtual IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow) { using (new SessionIdLoggingContext(SessionId)) { return(factory.QueryPlanCache.GetHQLQueryPlan(queryExpression, shallow, EnabledFilters)); } }
public override void List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) { using (BeginProcess()) { // We need to flush the batcher. Otherwise it may have pending operations which will not already have reached the database, // and the query may yield stale data. Flush(); queryParameters.ValidateParameters(); var plan = GetHQLQueryPlan(queryExpression, false); bool success = false; try { plan.PerformList(queryParameters, this, results); success = true; } catch (HibernateException) { // Do not call Convert on HibernateExceptions throw; } catch (Exception e) { throw Convert(e, "Could not execute query"); } finally { AfterOperation(success); } temporaryPersistenceContext.Clear(); } }
static IQueryTranslator[] CreateQueryTranslators( IQueryExpression queryExpression, IASTNode ast, string queryIdentifier, string collectionRole, bool shallow, IDictionary <string, IFilter> filters, ISessionFactoryImplementor factory) { var polymorphicParsers = AstPolymorphicProcessor.Process(ast, factory); var translators = polymorphicParsers .ToArray(hql => queryExpression is NhLinqExpression linqExpression ? new QueryTranslatorImpl(queryIdentifier, hql, filters, factory, linqExpression.NamedParameters) : new QueryTranslatorImpl(queryIdentifier, hql, filters, factory)); foreach (var translator in translators) { if (collectionRole == null) { translator.Compile(factory.Settings.QuerySubstitutions, shallow); } else { translator.Compile(collectionRole, factory.Settings.QuerySubstitutions, shallow); } } return(translators); }
public bool Equals(IQueryExpression other, Func <IQueryExpression, IQueryExpression, bool> comparer) { if (this == other) { return(true); } var func = other as ISqlFunction; if (func == null || Name != func.Name || Parameters.Length != func.Parameters.Length && SystemType != func.SystemType) { return(false); } for (var i = 0; i < Parameters.Length; i++) { if (!Parameters[i].Equals(func.Parameters[i], comparer)) { return(false); } } return(comparer(this, other)); }
private static bool ResolveDiscrete(IQueryExpression node, IErrorList errorList, IDiscrete resolvedFinalDiscrete, ref ResolvedExpression resolvedExpression) { // This is enforced by the caller. bool IsNumberTypeAvailable = Expression.IsLanguageTypeAvailable(LanguageClasses.Number.Guid, node, out ITypeName NumberTypeName, out ICompiledType NumberType); Debug.Assert(IsNumberTypeAvailable); resolvedExpression.ResolvedResult = new ResultType(NumberTypeName, NumberType, resolvedFinalDiscrete.ValidDiscreteName.Item.Name); resolvedExpression.ResolvedException = new ResultException(); if (resolvedFinalDiscrete.NumericValue.IsAssigned) { IExpression NumericValue = (IExpression)resolvedFinalDiscrete.NumericValue.Item; resolvedExpression.ConstantSourceList.Add(NumericValue); } else { resolvedExpression.ExpressionConstant = new DiscreteLanguageConstant(resolvedFinalDiscrete); } resolvedExpression.SelectedResultList = new SealableList <IParameter>(); resolvedExpression.FeatureCall = new FeatureCall(); return(true); }
public virtual List <SearchFacet> GetSearchFacets(IQueryExpression expression, string[] groupByFields, Directory directory = null) { if (directory == null) { directory = LuceneContext.Directory; } groupByFields = groupByFields.Select(x => ContentIndexHelpers.GetIndexFieldName(x)).ToArray(); var result = new List <SearchFacet>(); using (IndexReader indexReader = IndexReader.Open(directory, true)) { var queryParser = new MultiFieldQueryParser(LuceneConfiguration.LuceneVersion, expression.GetFieldName() , LuceneConfiguration.Analyzer); queryParser.AllowLeadingWildcard = true; var query = queryParser.Parse(expression.GetExpression()); SimpleFacetedSearch facetSearch = new SimpleFacetedSearch(indexReader, groupByFields); SimpleFacetedSearch.Hits hits = facetSearch.Search(query, int.MaxValue); long totalHits = hits.TotalHitCount; foreach (SimpleFacetedSearch.HitsPerFacet hitPerGroup in hits.HitsPerFacet) { long hitCountPerGroup = hitPerGroup.HitCount; result.Add(new SearchFacet() { Count = hitPerGroup.HitCount, Term = hitPerGroup.Name.ToString() }); } } return(result); }
public ExpandedQueryExpression(IQueryExpression queryExpression, IASTNode tree, string key) { _tree = tree; Key = key; Type = queryExpression.Type; ParameterDescriptors = queryExpression.ParameterDescriptors; }
//[Test] //public virtual void TestMain() //{ // Main(null); // Assert.IsTrue(true); //} /// <exception cref="System.Exception" /> public static void Main(string[] ars) { var sql = Performance.SqlBenchmarkSelect; for (var i = 0; i < 3; ++i) { var lexer = new MySqlLexer(sql); var exprParser = new MySqlExprParser(lexer); var parser = new MySqlDmlSelectParser(lexer, exprParser); IQueryExpression stmt = parser.Select(); } // System.out.println(stmt); Thread.Sleep(1000); long loop = 300 * 10000; var t1 = Runtime.CurrentTimeMillis(); t1 = Runtime.CurrentTimeMillis(); for (long i_1 = 0; i_1 < loop; ++i_1) { var lexer = new MySqlLexer(sql); var exprParser = new MySqlExprParser(lexer); var parser = new MySqlDmlSelectParser(lexer, exprParser); IQueryExpression stmt = parser.Select(); } var t2 = Runtime.CurrentTimeMillis(); Console.Out.WriteLine((t2 - t1) * 1000.0d / loop + " us"); }
public static IQueryExpression FilterByACL(this IQueryExpression expression) { var aclQuery = new AccessControlListQuery(); var _virtualRoleRepository = ServiceLocator.Current.GetInstance <IVirtualRoleRepository>(); var principal = PrincipalInfo.Current; var context = HttpContext.Current; if (principal?.Principal == null) { return(expression); } aclQuery.AddUser(principal.Principal.Identity.Name); ClaimsPrincipal claimsPrincipal = principal.Principal as ClaimsPrincipal; IEnumerable <Claim> claims = claimsPrincipal != null?claimsPrincipal.Claims.Where <Claim>(c => c.Type.Equals("http://schemas.microsoft.com/ws/2008/06/identity/claims/role")) : (IEnumerable <Claim>)null; if (claims == null) { return(expression); } foreach (Claim claim in claims) { aclQuery.AddRole(claim.Value); } foreach (string allRole in _virtualRoleRepository.GetAllRoles()) { VirtualRoleProviderBase virtualRole; if (_virtualRoleRepository.TryGetRole(allRole, out virtualRole) && virtualRole.IsInVirtualRole(principal.Principal, context)) { aclQuery.AddRole(allRole); } } return(expression.And(aclQuery)); }
public virtual IList <T> List <T>(IQueryExpression query, QueryParameters parameters) { var results = new List <T>(); List(query, parameters, results); return(results); }
public override void List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) { using (new SessionIdLoggingContext(SessionId)) { CheckAndUpdateSessionStatus(); queryParameters.ValidateParameters(); var plan = GetHQLQueryPlan(queryExpression, false); bool success = false; try { plan.PerformList(queryParameters, this, results); success = true; } catch (HibernateException) { // Do not call Convert on HibernateExceptions throw; } catch (Exception e) { throw Convert(e, "Could not execute query"); } finally { AfterOperation(success); } temporaryPersistenceContext.Clear(); } }
public bool Equals(IQueryExpression other, Func <IQueryExpression, IQueryExpression, bool> comparer) { if (this == other) { return(true); } var expr = other as ISqlExpression; if (expr == null || SystemType != expr.SystemType || Expr != expr.Expr || Parameters.Length != expr.Parameters.Length) { return(false); } for (var i = 0; i < Parameters.Length; i++) { if (!Parameters[i].Equals(expr.Parameters[i], comparer)) { return(false); } } return(comparer(this, other)); }
public override async Task ListAsync(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (BeginProcess()) { queryParameters.ValidateParameters(); var plan = GetHQLQueryPlan(queryExpression, false); bool success = false; try { await(plan.PerformListAsync(queryParameters, this, results, cancellationToken)).ConfigureAwait(false); success = true; } catch (OperationCanceledException) { throw; } catch (HibernateException) { // Do not call Convert on HibernateExceptions throw; } catch (Exception e) { throw Convert(e, "Could not execute query"); } finally { await(AfterOperationAsync(success, cancellationToken)).ConfigureAwait(false); } temporaryPersistenceContext.Clear(); } }
/// <summary> /// Not ($not) /// </summary> /// <param name="expression">Operator Expression</param> public static IQueryExpression Not(IQueryExpression expression) { if (expression is QueryExpression queryExpression) { return(new QueryExpression { Field = expression.Field, Value = new Query { Operator = MongoOperator.Not, Value = queryExpression.Value } }); } else { return(new QueryExpression { Field = expression.Field, Value = new Query { Operator = MongoOperator.Not, Value = expression } }); } }
public IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow, IDictionary<string, IFilter> enabledFilters) { string expressionStr = queryExpression.Key; var key = new HQLQueryPlanKey(expressionStr, shallow, enabledFilters); var plan = (IQueryExpressionPlan)planCache[key]; if (plan == null) { if (log.IsDebugEnabled) { log.Debug("unable to locate HQL query plan in cache; generating (" + expressionStr + ")"); } plan = new HQLExpressionQueryPlan(expressionStr, queryExpression, shallow, enabledFilters, factory); planCache.Put(key, plan); } else { if (log.IsDebugEnabled) { log.Debug("located HQL query plan in cache (" + expressionStr + ")"); } } return plan; }
public static IQueryExpression FilterByAncestor(this IQueryExpression expression, ContentReference ancestor) { var virtualPathQuery = new VirtualPathQuery(); virtualPathQuery.AddContentNodes(ancestor); return(expression.And(virtualPathQuery)); }
public override async Task ListAsync(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (BeginProcess()) { // We need to flush the batcher. Otherwise it may have pending operations which will not already have reached the database, // and the query may yield stale data. await(FlushAsync(cancellationToken)).ConfigureAwait(false); queryParameters.ValidateParameters(); var plan = GetHQLQueryPlan(queryExpression, false); bool success = false; try { await(plan.PerformListAsync(queryParameters, this, results, cancellationToken)).ConfigureAwait(false); success = true; } catch (OperationCanceledException) { throw; } catch (HibernateException) { // Do not call Convert on HibernateExceptions throw; } catch (Exception e) { throw Convert(e, "Could not execute query"); } finally { await(AfterOperationAsync(success, cancellationToken)).ConfigureAwait(false); } temporaryPersistenceContext.Clear(); } }
public virtual void VisitQueryExpression <TQueryFromExpression, TQueryClauseExpression, TQueryEndExpression>( IQueryExpression <TQueryFromExpression, TQueryClauseExpression, TQueryEndExpression> queryExpression) where TQueryFromExpression : IQueryFromExpression where TQueryClauseExpression : IQueryClauseExpression where TQueryEndExpression : IQueryEndExpression { Visit(queryExpression); }
public InsertReplaceStatement(Identifier table, IList <Identifier> columnList, IQueryExpression select) { this.Table = table; this.ColumnList = columnList; this.RowList = null; this.Select = select; }
public DmlReplaceStatement(ReplaceMode mode, Identifier table, IList <Identifier> columnNameList, IQueryExpression select) : base(table, columnNameList, select) { Mode = mode; }
public ExistsPrimary(IQueryExpression subquery) { if (subquery == null) { throw new ArgumentException("subquery is null for EXISTS expression"); } Subquery = subquery; }
public DmlReplaceStatement(ReplaceMode mode, Identifier table, IList<Identifier> columnNameList, IQueryExpression select) : base(table, columnNameList, select) { Mode = mode; }
public static IQueryExpression Not(this IQueryExpression query, IQueryExpression anotherQuery) { var groupQuery = new GroupQuery(LuceneOperator.NOT); groupQuery.QueryExpressions.Add(query); groupQuery.QueryExpressions.Add(anotherQuery); return(groupQuery); }
/// <summary> /// Opens a typed stream of type T and issues a query. /// </summary> /// <remarks>You supply node instead of typed stream so disposal is automatic and to enable /// indexing if available.</remarks> public static List <Selectable> Find <Selectable, T>(Node <object> table, IQueryExpression <Selectable, T> expression) { List <Selectable> result = new List <Selectable>(); FindInternal <Selectable, T>(result, table, expression); return(result); }
internal SelectClause(bool isDistinct, IQueryExpression takeValue, IQueryExpression skipValue, IEnumerable <IColumn> columns) : base(null) { IsDistinct = isDistinct; TakeValue = takeValue; SkipValue = skipValue; Columns.AddRange(columns); }
public InList(IQueryExpression exp1, bool isNot, IEnumerable <IQueryExpression> values) : base(exp1, isNot, SqlQuery.Precedence.Comparison) { if (values != null) { Values.AddRange(values); } }
public InList(IQueryExpression exp1, bool isNot, params IQueryExpression[] values) : base(exp1, isNot, SqlQuery.Precedence.Comparison) { if (values != null && values.Length > 0) { Values.AddRange(values); } }
/// <summary> /// Open a typed stream of type T and issues a query. /// </summary> /// <remarks>You supply node instead of typed stream so disposal is automatic and to enable /// indexing if available.</remarks> public static QueryResults <Selectable> FindAsync <Selectable, T>(Node <object> table, IQueryExpression <Selectable, T> expression) { return(new QueryResults <Selectable>(delegate(List <Selectable> result) { Query.FindInternal <Selectable, T>(result, table, expression); })); }
public virtual IList <T> List <T>(IQueryExpression query, QueryParameters parameters) { using (new SessionIdLoggingContext(SessionId)) { var results = new List <T>(); List(query, parameters, results); return(results); } }
protected DmlInsertReplaceStatement(Identifier table, IList<Identifier> columnNameList, IList<RowExpression> rowList) { this.table = table; this.columnNameList = EnsureListType(columnNameList); this.rowList = EnsureListType(rowList); select = null; }
public override IQueryTranslator[] GetQueries(IQueryExpression query, bool scalar) { using (new SessionIdLoggingContext(SessionId)) { // take the union of the query spaces (ie the queried tables) var plan = Factory.QueryPlanCache.GetHQLQueryPlan(query, scalar, EnabledFilters); return(plan.Translators); } }
/// <summary> /// </summary> /// <param name="mode"></param> /// <param name="ignore"></param> /// <param name="table"></param> /// <param name="columnNameList"></param> /// <param name="select"></param> /// <param name="duplicateUpdate"></param> public DmlInsertStatement(InsertMode mode, bool ignore, Identifier table, IList<Identifier> columnNameList, IQueryExpression select, IList<Pair<Identifier, IExpression>> duplicateUpdate) : base(table, columnNameList, select) { Mode = mode; IsIgnore = ignore; DuplicateUpdate = EnsureListType(duplicateUpdate); }
protected DmlInsertReplaceStatement(Identifier table, IList<Identifier> columnNameList, IQueryExpression select) { if (select == null) { throw new ArgumentException("argument 'select' is empty"); } this.select = select; this.table = table; this.columnNameList = EnsureListType(columnNameList); rowList = null; }
public SubqueryFactor(IQueryExpression subquery, string alias) : base(alias) { if (alias == null) { throw new ArgumentException("alias is required for _subquery factor"); } if (subquery == null) { throw new ArgumentException("_subquery is null"); } Subquery = subquery; }
/// <summary> /// Creates a new AST-based query translator. /// </summary> /// <param name="queryIdentifier">The query-identifier (used in stats collection)</param> /// <param name="queryExpression">The hql query to translate</param> /// <param name="enabledFilters">Currently enabled filters</param> /// <param name="factory">The session factory constructing this translator instance.</param> public QueryTranslatorImpl( string queryIdentifier, IQueryExpression queryExpression, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory) { _queryIdentifier = queryIdentifier; _hql = queryExpression.ToString(); _compiled = false; _shallowQuery = false; _enabledFilters = enabledFilters; _factory = factory; _parser = new HqlParseEngine(queryExpression.Translate(factory), factory); }
public static SqlCommand GetCountSQLCommand(IQueryExpression expression, DateTime from, DateTime to, int timeSlices, string field) { StringBuilder sql = new StringBuilder(); Dictionary<string, object> parameters = new Dictionary<string, object>(); List<string> fieldTableAliases = new List<string>(); StringBuilder sqlSelect = new StringBuilder(); sqlSelect.AppendLine("declare @timeSliceDuration int"); sqlSelect.AppendLine("set @timeSliceDuration = DATEDIFF(s, @fromTimestamp, @toTimestamp) / @timeSlices"); sqlSelect.Append("select DATEDIFF(s, @fromTimestamp, [Messages].[Timestamp]) / @timeSliceDuration AS TimeSlice"); if (field != null) { sqlSelect.Append(", fd.[Value]"); } sqlSelect.Append(", COUNT(*) [Count] FROM [Messages] (NOLOCK) "); if (field != null) { sqlSelect.Append("INNER JOIN [Fields] fd (NOLOCK) ON Messages.ID = fd.MessageID AND fd.Field = @fd0"); parameters.Add("@fd0", field); } StringBuilder sqlOrderBy = new StringBuilder(); sqlOrderBy.Append("GROUP BY DATEDIFF(s, @fromTimestamp, [Messages].[Timestamp]) / @timeSliceDuration"); if (field != null) { sqlOrderBy.Append(", fd.[Value]"); } sqlOrderBy.Append("ORDER BY [TimeSlice] ASC"); AppendFromToParameters(from, to, sql, parameters); sql.Append(TranslateQueryExpressionToWhereClause(expression, parameters, fieldTableAliases)); SqlCommand command = GetCommand( sqlSelect.ToString(), sql.ToString(), sqlOrderBy.ToString(), fieldTableAliases); parameters.Add("@timeSlices", timeSlices); LoadParameterValues(command, parameters); return command; }
public static IQueryExpression Plus(IQueryExpression leftExpression, IQueryExpression rightExpression) { return new BinaryOperatorExpression() {LeftExpression = leftExpression, RightExpression = rightExpression, Operation = BinaryOperator.PLUS}; }
protected static IQueryTranslator[] CreateTranslators(IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory) { return factory.Settings.QueryTranslatorFactory.CreateQueryTranslators(queryExpression, collectionRole, shallow, enabledFilters, factory); }
public static IQueryExpression Divide(IQueryExpression leftExpression, IQueryExpression rightExpression) { return new BinaryOperatorExpression() {LeftExpression = leftExpression, RightExpression = rightExpression, Operation = BinaryOperator.DIVIDE}; }
public static IQueryExpression Min(IQueryExpression expression) { return new AggregateExpression() {Expression = expression, Aggregate = AggregateFunction.MIN}; }
public static IQueryExpression Concat(IQueryExpression leftExpression, IQueryExpression rightExpression) { return new BinaryOperatorExpression() {LeftExpression = leftExpression, RightExpression = rightExpression, Operation = BinaryOperator.CONCAT}; }
public static IQueryExpression Count(IQueryExpression expression) { return new AggregateExpression() {Expression = expression, Aggregate = AggregateFunction.COUNT}; }
public static IQueryExpression BinaryNot(IQueryExpression expression) { return new UnaryOperatorExpression() {Expression = expression, Operation = UnaryOperator.BINARY_NOT}; }
public static IQueryExpression BinaryOr(IQueryExpression leftExpression, IQueryExpression rightExpression) { return new BinaryOperatorExpression() {LeftExpression = leftExpression, RightExpression = rightExpression, Operation = BinaryOperator.BINARY_OR}; }
public static IQueryExpression Sum(IQueryExpression expression) { return new AggregateExpression() {Expression = expression, Aggregate = AggregateFunction.SUM}; }
public static IQueryExpression Times(IQueryExpression leftExpression, IQueryExpression rightExpression) { return new BinaryOperatorExpression() {LeftExpression = leftExpression, RightExpression = rightExpression, Operation = BinaryOperator.MULTIPLY}; }
public static IQueryExpression ShiftRight(IQueryExpression leftExpression, IQueryExpression rightExpression) { return new BinaryOperatorExpression() {LeftExpression = leftExpression, RightExpression = rightExpression, Operation = BinaryOperator.SHIFT_RIGHT}; }
public QueryExpressionPlan(IQueryExpression queryExpression, bool shallow, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory) : this(queryExpression.Key, CreateTranslators(queryExpression, null, shallow, enabledFilters, factory)) { QueryExpression = queryExpression; }
public IQueryTranslator[] CreateQueryTranslators(IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory) { return CreateQueryTranslators(queryExpression.Translate(factory, collectionRole != null), queryExpression.Key, collectionRole, shallow, filters, factory); }
public static IQueryExpression Average(IQueryExpression expression) { return new AggregateExpression() {Expression = expression, Aggregate = AggregateFunction.AVERAGE}; }
public static IQueryExpression Mod(IQueryExpression leftExpression, IQueryExpression rightExpression) { return new BinaryOperatorExpression() {LeftExpression = leftExpression, RightExpression = rightExpression, Operation = BinaryOperator.MODULO}; }
public void AddFromTableRef(IQueryExpression tableRef) { _from.Add(tableRef); }
public static IQueryExpression Plus(IQueryExpression expression) { return new UnaryOperatorExpression() {Expression = expression, Operation = UnaryOperator.PLUS}; }
private QueryExpressionPlan(HQLQueryPlan source, IQueryExpression expression) : base(source) { QueryExpression = expression; }
protected internal HQLExpressionQueryPlan(string expressionStr, IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory) : base(expressionStr, CreateTranslators(expressionStr, queryExpression, collectionRole, shallow, enabledFilters, factory)) { QueryExpression = queryExpression; }
public QueryExpressionPlan Copy(IQueryExpression expression) { return new QueryExpressionPlan(this, expression); }
private static IQueryTranslator[] CreateTranslators(string expressionStr, IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory) { IQueryTranslatorFactory2 qtFactory = new ASTQueryTranslatorFactory(); return qtFactory.CreateQueryTranslators(expressionStr, queryExpression, collectionRole, shallow, enabledFilters, factory); }