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();
 }
Exemple #7
0
        public void DoesRequestAllowForCaching_CaptureExpressionMetadata( )
        {
            StructuredQuery         sq       = new StructuredQuery( );
            QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( );

            settings.CaptureExpressionMetadata = true;

            Assert.That(CachingQuerySqlBuilderKey.DoesRequestAllowForCaching(sq, settings), Is.False);
        }
Exemple #8
0
        public void DoesRequestAllowForCaching_Default( )
        {
            StructuredQuery         sq       = new StructuredQuery();
            QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings();

            settings.SecureQuery = false;

            Assert.That(CachingQuerySqlBuilderKey.DoesRequestAllowForCaching(sq, settings), Is.True);
        }
Exemple #9
0
        public void DoesRequestAllowForCaching_DebugMode( )
        {
            StructuredQuery         sq       = new StructuredQuery( );
            QuerySqlBuilderSettings settings = new QuerySqlBuilderSettings( );

            settings.DebugMode = true;

            Assert.That(CachingQuerySqlBuilderKey.DoesRequestAllowForCaching(sq, settings), Is.False);
        }
Exemple #10
0
        /// <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));
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        /// <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);
        }
Exemple #13
0
        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( );
        }
Exemple #15
0
        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));
        }
Exemple #16
0
        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));
        }
Exemple #17
0
        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));
        }
Exemple #18
0
        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));
        }
Exemple #19
0
        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);
        }
Exemple #21
0
        //[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");
            }
        }
Exemple #22
0
        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);
            }
        }
Exemple #24
0
        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));
        }
Exemple #25
0
        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));
        }
Exemple #26
0
        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( );
        }
Exemple #28
0
 /// <summary>
 /// Legacy API for accessing the query builder.
 /// </summary>
 public static QueryBuild GetSql(StructuredQuery query, QuerySqlBuilderSettings settings)
 {
     return(Factory.QuerySqlBuilder.BuildSql(query, settings));
 }
Exemple #29
0
        /// <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));
        }
Exemple #30
0
 private QueryBuild BuildSql(StructuredQuery query, QuerySqlBuilderSettings settings)
 {
     return(Factory.NonCachedQuerySqlBuilder.BuildSql(query, settings));
 }