public void Test_EnsureCached_TwoThreads( ) { CachingQuerySqlBuilder cachingQuerySqlBuilder; Mock <IQuerySqlBuilder> mockQuerySqlBuilder; IQuerySqlBuilder querySqlBuilder; StructuredQuery structuredQuery; QuerySqlBuilderSettings settings; QueryBuild queryBuild; IUserRuleSetProvider userRuleSetProvider = MockUserRuleSetProvider( ); structuredQuery = new StructuredQuery( ); settings = new QuerySqlBuilderSettings( ); queryBuild = new QueryBuild( ); mockQuerySqlBuilder = new Mock <IQuerySqlBuilder>(MockBehavior.Strict); mockQuerySqlBuilder.Setup(x => x.BuildSql(structuredQuery, settings)) .Returns(() => { Thread.Sleep(100); return(queryBuild); }) .Verifiable( ); querySqlBuilder = mockQuerySqlBuilder.Object; cachingQuerySqlBuilder = new CachingQuerySqlBuilder(querySqlBuilder, userRuleSetProvider); Task task1 = Task.Factory.StartNew(() => cachingQuerySqlBuilder.BuildSql(structuredQuery, settings)); Thread.Sleep(1); // BlockIfPending can handle overlapping, but no coincident requests Task task2 = Task.Factory.StartNew(() => cachingQuerySqlBuilder.BuildSql(structuredQuery, settings)); Task.WaitAll(task1, task2); mockQuerySqlBuilder.Verify(x => x.BuildSql(structuredQuery, settings), Times.Exactly(1)); mockQuerySqlBuilder.VerifyAll( ); }
public void Test_Cached() { CachingQuerySqlBuilder cachingQuerySqlBuilder; Mock <IQuerySqlBuilder> mockQuerySqlBuilder; IQuerySqlBuilder querySqlBuilder; StructuredQuery structuredQuery; QuerySqlBuilderSettings settings; QueryBuild queryBuild; IUserRuleSetProvider userRuleSetProvider = MockUserRuleSetProvider( ); structuredQuery = new StructuredQuery( ); settings = new QuerySqlBuilderSettings( ); queryBuild = new QueryBuild( ); mockQuerySqlBuilder = new Mock <IQuerySqlBuilder>(MockBehavior.Strict); mockQuerySqlBuilder.Setup(x => x.BuildSql(structuredQuery, settings)) .Returns(() => queryBuild) .Verifiable(); querySqlBuilder = mockQuerySqlBuilder.Object; cachingQuerySqlBuilder = new CachingQuerySqlBuilder(querySqlBuilder, userRuleSetProvider); Assert.That(cachingQuerySqlBuilder.BuildSql(structuredQuery, settings), Is.SameAs(queryBuild), "Incorrect conversion"); Assert.That(cachingQuerySqlBuilder.Cache, Has.Count.EqualTo(1)); mockQuerySqlBuilder.Verify(x => x.BuildSql(structuredQuery, settings), Times.Exactly(1)); mockQuerySqlBuilder.VerifyAll(); }
public void Test_SqlIsUncacheable( ) { CachingQuerySqlBuilder cachingQuerySqlBuilder; Mock <IQuerySqlBuilder> mockQuerySqlBuilder; IQuerySqlBuilder querySqlBuilder; StructuredQuery structuredQuery; QuerySqlBuilderSettings settings; QueryBuild queryBuild; IUserRuleSetProvider userRuleSetProvider = MockUserRuleSetProvider( ); structuredQuery = new StructuredQuery( ); settings = new QuerySqlBuilderSettings( ); queryBuild = new QueryBuild( ); queryBuild.SqlIsUncacheable = true; mockQuerySqlBuilder = new Mock <IQuerySqlBuilder>(MockBehavior.Strict); mockQuerySqlBuilder.Setup(x => x.BuildSql(structuredQuery, settings)) .Returns(() => queryBuild) .Verifiable( ); querySqlBuilder = mockQuerySqlBuilder.Object; cachingQuerySqlBuilder = new CachingQuerySqlBuilder(querySqlBuilder, userRuleSetProvider); cachingQuerySqlBuilder.BuildSql(structuredQuery, settings); cachingQuerySqlBuilder.BuildSql(structuredQuery, settings); mockQuerySqlBuilder.Verify(x => x.BuildSql(structuredQuery, settings), Times.Exactly(2)); mockQuerySqlBuilder.VerifyAll( ); }
/// <summary> /// Actually build the SQL /// </summary> internal static bool DoesRequestAllowForCaching(StructuredQuery query, QuerySqlBuilderSettings settings) { if (query == null) { throw new ArgumentNullException("query"); } if (settings == null) { throw new ArgumentNullException("settings"); } // Note : settings.AdditionalOrderColumns is wholly derived from the query and settings, so we can ignore it // (however it should probably therefore be removed from the QuerySqlBuilderSettings altogether) // For now .. for safety // Note: if we ever want to address this, we need to ensure expression GUIDs get stitched up in QueryResult.ExpressionTypes if (settings.CaptureExpressionMetadata) { LogReasonForNonCaching("CaptureExpressionMetadata"); return(false); } // For now .. for sanity if (settings.DebugMode) { LogReasonForNonCaching("DebugMode"); return(false); } return(true); }
/// <summary> /// Generate the query SQL. Do not actually run it. /// </summary> /// <param name="query">The structured query object to convert.</param> /// <param name="settings">Build-time settings for the conversion.</param> /// <returns>An object structure containing SQL, and other discovered information.</returns> public QueryBuild BuildSql(StructuredQuery query, QuerySqlBuilderSettings settings) { if (query == null) { throw new ArgumentNullException("query"); } // Initialise settings if (settings == null) { settings = new QuerySqlBuilderSettings( ); } // Optimise tree StructuredQuery optimisedQuery = StructuredQueryHelper.PruneQueryTree(query); // Generate SQL QueryBuilder queryBuilder = new QueryBuilder(optimisedQuery, settings); QueryBuild result = queryBuilder.GetSqlInternal( ); // Logging using (MessageContext msg = new MessageContext("Reports")) { msg.Append(() => new string( '-', 50 )); msg.Append(() => "Final structured query:\n" + StructuredQueryHelper.ToXml(optimisedQuery)); msg.Append(() => new string( '-', 50 )); msg.Append(() => "SQL:\n" + result.Sql); msg.Append(() => new string( '-', 50 )); } // Note: identify cache dependencies after getting SQL, so that any calculations are resolved into the structured query. IdentifyCacheDependencies(optimisedQuery, settings); return(result); }
internal CachingQuerySqlBuilderKey(StructuredQuery query, QuerySqlBuilderSettings settings, UserRuleSet userRuleSet) { CacheKeyTokens = GetCacheKeyTokens(query, settings); // Uninspired, but adequate Bools = PackBools(settings); UserRuleSet = userRuleSet; // Users may share a query plan if they have the same set of security rules TimeZoneName = query.TimeZoneName; // TimeZoneName: Ideally this could be removed from the cache key, but it will be some effort for negligable short-term benefit _hashCode = GenerateHashCode(); }
public void DoesRequestAllowForCaching_CaptureExpressionMetadata( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); settings.CaptureExpressionMetadata = true; Assert.That(CachingQuerySqlBuilderKey.DoesRequestAllowForCaching(sq, settings), Is.False); }
public void DoesRequestAllowForCaching_Default( ) { StructuredQuery sq = new StructuredQuery(); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings(); settings.SecureQuery = false; Assert.That(CachingQuerySqlBuilderKey.DoesRequestAllowForCaching(sq, settings), Is.True); }
public void DoesRequestAllowForCaching_DebugMode( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); settings.DebugMode = true; Assert.That(CachingQuerySqlBuilderKey.DoesRequestAllowForCaching(sq, settings), Is.False); }
/// <summary> /// Actually build the SQL /// </summary> private QueryBuild BuildSqlImpl(StructuredQuery query, QuerySqlBuilderSettings settings) { // Unless otherwise specified, use the cache provider for creating inner security queries as well. if (settings.SecurityQuerySqlBuilder == null) { settings.SecurityQuerySqlBuilder = this; } return(QuerySqlBuilder.BuildSql(query, settings)); }
public void DoesRequestAllowForCaching_AdditionalOrderColumns( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); settings.AdditionalOrderColumns = new System.Collections.Generic.Dictionary <Guid, SelectColumn>( ); settings.AdditionalOrderColumns [Guid.Empty] = null; // See notes in CachingQuerySqlBuilderKey.DoesRequestAllowForCaching Assert.That(CachingQuerySqlBuilderKey.DoesRequestAllowForCaching(sq, settings), Is.True); }
/// <summary> /// Check cache dependencies. (Note: wrapped, so we can write tests guaranteeing we have the same implementation) /// </summary> internal static void IdentifyCacheDependencies(StructuredQuery query, QuerySqlBuilderSettings settings) { // Note: if we are suppressing the root type check, then it means that the caller will be joining the query into a larger query. // (I.e. this is a security subquery in a secured report). // If that is the case, then the parent query will already be registering invalidation watches for the type of that node. // So we don't need to further add them for the security query as well. // This is an important optimisation because there are security reports that apply to all resources, and get joined into nodes that // are only for specific resource types. So without ignoring the root, we would basically invalidate every report as part of every entity change. StructuredQueryHelper.IdentifyResultCacheDependencies(query, false, settings.SuppressRootTypeCheck || settings.SupportRootIdFilter); }
public void DoesRequestAllowForCaching_AllCacheableTrimmings( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); settings.SecureQuery = true; settings.SupportPaging = true; settings.UseSharedSql = true; settings.FullAggregateClustering = true; Assert.That(CachingQuerySqlBuilderKey.DoesRequestAllowForCaching(sq, settings), Is.True); }
public void Test_EnsureResultsFromDifferentInstancesReturnCorrectRequestColumnData( ) { CachingQuerySqlBuilder cachingQuerySqlBuilder; Mock <IQuerySqlBuilder> mockQuerySqlBuilder; IQuerySqlBuilder querySqlBuilder; QuerySqlBuilderSettings settings; QueryBuild queryBuild; IUserRuleSetProvider userRuleSetProvider = MockUserRuleSetProvider( ); StructuredQuery sq1 = new StructuredQuery { RootEntity = new ResourceEntity("test:person") }; sq1.SelectColumns.Add(new SelectColumn { Expression = new ResourceExpression(sq1.RootEntity, "core:name") }); StructuredQuery sq2 = new StructuredQuery { RootEntity = new ResourceEntity("test:person") }; sq2.SelectColumns.Add(new SelectColumn { Expression = new ResourceExpression(sq2.RootEntity, "core:name") }); Assert.That(sq1.SelectColumns [0].ColumnId, Is.Not.EqualTo(sq2.SelectColumns [0].ColumnId)); settings = new QuerySqlBuilderSettings( ); queryBuild = new QueryBuild(); queryBuild.Columns.Add(new ResultColumn { RequestColumn = sq1.SelectColumns [0] }); mockQuerySqlBuilder = new Mock <IQuerySqlBuilder>(MockBehavior.Strict); mockQuerySqlBuilder.Setup(x => x.BuildSql(sq1, settings)) .Returns(() => queryBuild) .Verifiable( ); querySqlBuilder = mockQuerySqlBuilder.Object; cachingQuerySqlBuilder = new CachingQuerySqlBuilder(querySqlBuilder, userRuleSetProvider); QueryBuild result1 = cachingQuerySqlBuilder.BuildSql(sq1, settings); Assert.That(result1.Columns [0].RequestColumn, Is.EqualTo(sq1.SelectColumns [0])); QueryBuild result2 = cachingQuerySqlBuilder.BuildSql(sq2, settings); Assert.That(result2.Columns [0].RequestColumn, Is.EqualTo(sq2.SelectColumns [0])); mockQuerySqlBuilder.Verify(x => x.BuildSql(sq1, settings), Times.Exactly(1)); mockQuerySqlBuilder.VerifyAll( ); }
public void CacheKeyMatches( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet = new UserRuleSet(new List <long>( )); settings.RunAsUser = 0; var key1 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); var key2 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); Assert.That(key1, Is.EqualTo(key2)); Assert.That(key1, Is.Not.SameAs(key2)); }
public void CacheKeyDifferent_StructuredQuery( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet = new UserRuleSet(new List <long>( )); settings.RunAsUser = 0; var key1 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); sq.RootEntity = new ResourceEntity( ); var key2 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); Assert.That(key1, Is.Not.EqualTo(key2)); }
public void CacheKeyDifferent_TimeZoneName( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet = new UserRuleSet(new List <long>( )); settings.RunAsUser = 0; var key1 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); sq.TimeZoneName = "asdf"; var key2 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); Assert.That(key1, Is.Not.EqualTo(key2)); }
public void CacheKeyDifferent_SupportQuickSearch( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet = new UserRuleSet(new List <long>( )); settings.RunAsUser = 0; settings.SupportQuickSearch = false; var key1 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); settings.SupportQuickSearch = true; var key2 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); Assert.That(key1, Is.Not.EqualTo(key2)); }
public void CacheKeyDifferent_FullAggregateClustering( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet = new UserRuleSet(new List <long>( )); settings.RunAsUser = 0; settings.FullAggregateClustering = false; var key1 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); settings.FullAggregateClustering = true; var key2 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); Assert.That(key1, Is.Not.EqualTo(key2)); }
/// <summary> /// Store various boolean settings into a bit field for convenient comparison and storage. /// Note: these only have meaning within this class. /// </summary> private static int PackBools(QuerySqlBuilderSettings settings) { if (settings == null) { throw new ArgumentNullException("settings"); } // Don't cache if any are true (for now) // DebugMode, CaptureExpressionMetadata int flags = 0; if (settings.SecureQuery) { flags += 1; } if (settings.SupportPaging) { flags += 2; } if (settings.SupportQuickSearch) { flags += 4; } if (settings.UseSharedSql) { flags += 8; } if (settings.FullAggregateClustering) { flags += 16; } if (settings.SupportClientAggregate) { flags += 32; } if (settings.SupportRootIdFilter) { flags += 64; } if (settings.SuppressRootTypeCheck) { flags += 128; } return(flags); }
//[Explicit] //[Test] //[TestCaseSource( "RunReport_GetTestData" )] public void RunQuery(TenantInfo tenant, long reportId, string reportName) { using (tenant.GetTenantAdminContext( )) { // Load report Report report = Factory.GraphEntityRepository.Get <Report>(reportId, ReportHelpers.ReportPreloaderQuery); Assert.That(report, Is.Not.Null, "Report entity not null"); // Convert to structured query StructuredQuery structuredQuery = Factory.ReportToQueryConverter.Convert(report); Assert.That(structuredQuery, Is.Not.Null, "StructuredQuery entity not null"); // Check for errors reported during conversionduring reporting (e.g. missing schema entities can't be found) if (structuredQuery.InvalidReportInformation != null) { foreach (var pair in structuredQuery.InvalidReportInformation) { Assert.That(pair.Value, Is.Empty, "Errors detected for " + pair.Key); } } // Build query QuerySqlBuilderSettings buildSettings = new QuerySqlBuilderSettings { Hint = "ReportTenantTests", SecureQuery = true, SupportPaging = true }; QueryBuild queryBuild = Factory.NonCachedQuerySqlBuilder.BuildSql(structuredQuery, buildSettings); Assert.That(queryBuild, Is.Not.Null, "QueryBuild entity not null"); Assert.That(queryBuild.Sql, Is.Not.Null, "QueryBuild.Sql entity not null"); // Run query QuerySettings runSettings = new QuerySettings { Hint = "ReportTenantTests", FirstRow = 0, PageSize = 1, SecureQuery = true, SupportPaging = true }; QueryResult result = Factory.Current.ResolveNamed <IQueryRunner>(Factory.NonCachedKey).ExecutePrebuiltQuery(structuredQuery, runSettings, queryBuild); //QueryResult result = Factory.NonCachedQueryRunner.ExecutePrebuiltQuery( structuredQuery, runSettings, queryBuild ); Assert.That(result, Is.Not.Null, "QueryResult entity not null"); } }
public void CacheKeyDifferent_ClientAggregates( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet = new UserRuleSet(new List <long>( )); settings.RunAsUser = 0; settings.SupportClientAggregate = true; settings.ClientAggregate = new ClientAggregate( ); var key1 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); settings.ClientAggregate.GroupedColumns.Add(new EDC.ReadiNow.Metadata.Reporting.ReportGroupField( )); var key2 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); Assert.That(key1, Is.Not.EqualTo(key2)); }
/// <summary> /// Get cache key hashes for both the query and the settings. /// </summary> /// <remarks> /// Note: we need to do both in the same context, so that a single StructuredQueryHashingContext can do all of the GUID normalizations together. /// </remarks> /// <returns>A hash string</returns> private static string GetCacheKeyTokens(StructuredQuery query, QuerySqlBuilderSettings settings) { if (query == null) { throw new ArgumentNullException("query"); } using (new StructuredQueryHashingContext( )) { string queryHash = query.CacheKeyToken(); byte[] clientAggregateBytes = null; if (settings.ClientAggregate != null) { clientAggregateBytes = settings.ClientAggregate.Serialize( ); } byte[] sharedParameterBytes = null; if (settings.SharedParameters != null) { using (var memoryStream = new MemoryStream( )) { // Serialize the query Serializer.Serialize(memoryStream, settings.SharedParameters); memoryStream.Flush( ); sharedParameterBytes = memoryStream.ToArray( ); } } byte[] hashValue = HashValues(clientAggregateBytes, sharedParameterBytes); string settingsHash = string.Empty; if (hashValue != null) { settingsHash = Convert.ToBase64String(hashValue); } string key = string.Concat(queryHash, " / ", settingsHash); return(key); } }
public void CacheKeyMatches_Match_With_Different_Instances(bool differentUsers, bool concurrent) { Func <int, CachingQuerySqlBuilderKey> makeKey = ( int userId ) => { StructuredQuery sq = new StructuredQuery( ); sq.SelectColumns.Add(new SelectColumn( )); sq.SelectColumns.Add(new SelectColumn( )); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet = new UserRuleSet(new List <long> { 1, 2, 3 }); settings.RunAsUser = userId; settings.SupportClientAggregate = true; settings.ClientAggregate = new ClientAggregate( ); settings.ClientAggregate.AggregatedColumns.Add(new EDC.ReadiNow.Metadata.Reporting.ReportAggregateField { ReportColumnId = sq.SelectColumns [0].ColumnId }); settings.ClientAggregate.GroupedColumns.Add(new EDC.ReadiNow.Metadata.Reporting.ReportGroupField { ReportColumnId = sq.SelectColumns [1].ColumnId }); var key = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet); return(key); }; CachingQuerySqlBuilderKey key1 = null; CachingQuerySqlBuilderKey key2 = null; if (concurrent) { Task.WaitAll( Task.Factory.StartNew(() => { key1 = makeKey(111); }), Task.Factory.StartNew(() => { key2 = makeKey(differentUsers ? 222 : 111); }) ); } else { key1 = makeKey(111); key2 = makeKey(differentUsers ? 222 : 111); } Assert.That(key1, Is.EqualTo(key2)); Assert.That(key1, Is.Not.SameAs(key2)); }
public void CacheKeyDifferent_RunAsUserRuleSet( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet1 = new UserRuleSet(new List <long> { 22, 33 }); UserRuleSet userRuleSet2 = new UserRuleSet(new List <long> { 44, 55 }); settings.RunAsUser = 1; var key1 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet1); settings.RunAsUser = 2; var key2 = new CachingQuerySqlBuilderKey(sq, settings, userRuleSet2); Assert.That(key1, Is.Not.EqualTo(key2)); }
public void CacheKeyMatches_MatchingRuleSets( ) { StructuredQuery sq = new StructuredQuery( ); QuerySqlBuilderSettings settings1 = new QuerySqlBuilderSettings( ); QuerySqlBuilderSettings settings2 = new QuerySqlBuilderSettings( ); UserRuleSet userRuleSet1 = new UserRuleSet(new List <long> { 1, 2, 3 }); UserRuleSet userRuleSet2 = new UserRuleSet(new List <long> { 1, 2, 3 }); settings1.RunAsUser = 111; settings2.RunAsUser = 222; var key1 = new CachingQuerySqlBuilderKey(sq, settings1, userRuleSet1); var key2 = new CachingQuerySqlBuilderKey(sq, settings2, userRuleSet2); Assert.That(key1, Is.EqualTo(key2)); Assert.That(key1, Is.Not.SameAs(key2)); }
public void Test_EnsureDifferentInstancesCanCacheMatch( ) { CachingQuerySqlBuilder cachingQuerySqlBuilder; Mock <IQuerySqlBuilder> mockQuerySqlBuilder; IQuerySqlBuilder querySqlBuilder; QuerySqlBuilderSettings settings; QueryBuild queryBuild; IUserRuleSetProvider userRuleSetProvider = MockUserRuleSetProvider( ); StructuredQuery sq1 = ReportHelpers.BuildFilterQuery("Name='test1'", new EntityRef("test:person"), true); sq1.SelectColumns.Add(new SelectColumn { Expression = new ResourceExpression(sq1.RootEntity, "core:name") }); StructuredQuery sq2 = ReportHelpers.BuildFilterQuery("Name='test1'", new EntityRef("test:person"), true); sq2.SelectColumns.Add(new SelectColumn { Expression = new ResourceExpression(sq2.RootEntity, "core:name") }); settings = new QuerySqlBuilderSettings( ); queryBuild = new QueryBuild( ); mockQuerySqlBuilder = new Mock <IQuerySqlBuilder>(MockBehavior.Strict); mockQuerySqlBuilder.Setup(x => x.BuildSql(sq1, settings)) .Returns(() => queryBuild) .Verifiable( ); querySqlBuilder = mockQuerySqlBuilder.Object; cachingQuerySqlBuilder = new CachingQuerySqlBuilder(querySqlBuilder, userRuleSetProvider); cachingQuerySqlBuilder.BuildSql(sq1, settings); cachingQuerySqlBuilder.BuildSql(sq2, settings); mockQuerySqlBuilder.Verify(x => x.BuildSql(sq1, settings), Times.Exactly(1)); mockQuerySqlBuilder.VerifyAll( ); }
/// <summary> /// Legacy API for accessing the query builder. /// </summary> public static QueryBuild GetSql(StructuredQuery query, QuerySqlBuilderSettings settings) { return(Factory.QuerySqlBuilder.BuildSql(query, settings)); }
/// <summary> /// Create a resolver to find entities with a field of a particular value. /// </summary> /// <param name="typeId">The type of resource to search.</param> /// <param name="fieldId">The field to search on.</param> /// <param name="secured">True if the generated resolver should be secured to the current user.</param> /// <returns>An IEntityResolver that can efficiently locate instances based on the field provided.</returns> /// <exception cref="System.ArgumentNullException"> /// typeId /// or /// fieldId /// </exception> public IEntityResolver GetResolverForField(long typeId, long fieldId, bool secured) { if (typeId == 0) { throw new ArgumentNullException("typeId"); } if (fieldId == 0) { throw new ArgumentNullException("fieldId"); } DataType fieldType; // Get field type using (new SecurityBypassContext( )) { IEntity field = _entityRepository.Get <Field>(fieldId); if (field == null) { throw new ArgumentException("Specified field ID does not refer to a field.", "fieldId"); } fieldType = FieldHelper.ConvertToDataType(field); } if (fieldType != DataType.String && fieldType != DataType.Int32) { throw new ArgumentException("Entity resolver does not support looking up instances by fields of type " + fieldType, "fieldId"); } // Build query var query = new StructuredQuery { RootEntity = new ResourceEntity(new EntityRef(typeId)) }; query.Conditions.Add( new QueryCondition { Expression = new ResourceDataColumn(query.RootEntity, new EntityRef(fieldId)), Operator = ConditionType.AnyOf, Parameter = "@valueList" }); query.SelectColumns.Add( new SelectColumn { Expression = new Metadata.Query.Structured.IdExpression { NodeId = query.RootEntity.NodeId } }); query.SelectColumns.Add( new SelectColumn { Expression = new Metadata.Query.Structured.ResourceDataColumn { NodeId = query.RootEntity.NodeId, FieldId = new EntityRef(fieldId) } }); // Get user long userId = RequestContext.GetContext( ).Identity.Id; // Get the SQL string. var settings = new QuerySqlBuilderSettings { SecureQuery = secured, Hint = "Entity.GetMatches", EmergencyDecorationCallback = queryRunSettings => { queryRunSettings.ValueList = new string[0]; // fieldValues EDC.ReadiNow.Diagnostics.EventLog.Application.WriteWarning("EmergencyDecorationCallback was executed and data was not provided. Some entities may get incorrectly hidden by security."); } }; QueryBuild queryResult = Factory.QuerySqlBuilder.BuildSql(query, settings); return(new EntityResolver(queryResult, fieldType)); }
private QueryBuild BuildSql(StructuredQuery query, QuerySqlBuilderSettings settings) { return(Factory.NonCachedQuerySqlBuilder.BuildSql(query, settings)); }