/// <summary> /// Reconfigure the server-side objects previously configured /// </summary> public async Task ReconfigureAsync(string xconfig) { var command = "call {0}.Reconfigure(\"{1}\");".FormatWith(ClrAssemblyID, xconfig.EscapeMdxString()); Action action = () => { AnalysisServicesHelper.ExecuteNonQuery(_connectionString, command); }; using (var task = Task.Factory.StartNew(action)) await task.ConfigureAwait(continueOnCapturedContext : false); }
/// <summary> /// Uninstall the server-side objects previously configured /// </summary> public async Task UninstallAsync() { var command = "call {0}.Uninstall();".FormatWith(ClrAssemblyID); Action action = () => { AnalysisServicesHelper.ExecuteNonQuery(_connectionString, command); AnalysisServicesHelper.UnregisterClrAssembly(_connectionString, ClrAssemblyID); }; using (var task = Task.Factory.StartNew(action)) await task.ConfigureAwait(continueOnCapturedContext : false); }
/// <summary> /// Execute server-side AnalyzeBatch procedure /// </summary> public async Task <AnalyzerStatistics> AnalyzeBatchAsync(string connectionStringBatch, string statement, ClearCacheMode clearCacheMode = ClearCacheMode.Default, string xconfig = null, string batchName = null, bool throwOnError = true) { #region Argument exception if (connectionStringBatch == null) { throw new ArgumentNullException("connectionStringBatch"); } if (statement == null) { throw new ArgumentNullException("statement"); } #endregion var currentProcess = Process.GetCurrentProcess(); var processName = currentProcess.ProcessName; var clientVersion = "{0} ({1})".FormatWith(currentProcess.MainModule.FileVersionInfo.FileVersion, ClientVersion); #if DEBUG Func <Guid, ClearCacheMode, string> commandAnalyze = (batchID, cacheMode) => "call {0}.AnalyzeBatchWithDebug(\"{1}\", {2}, \"{3}\", \"{4}\", \"{5}\", \"{6}\", \"{7}\", \"{8}\");".FormatWith(ClrAssemblyID, statement.EscapeMdxString(), (int)cacheMode, batchID, connectionStringBatch.EscapeMdxString(), clientVersion, processName, batchName, throwOnError); #else Func <Guid, ClearCacheMode, string> commandAnalyze = (batchID, cacheMode) => "call {0}.AnalyzeBatch(\"{1}\", {2}, \"{3}\", \"{4}\", \"{5}\", \"{6}\", \"{7}\", \"{8}\");".FormatWith(ClrAssemblyID, statement.EscapeMdxString(), (int)cacheMode, batchID, connectionStringBatch.EscapeMdxString(), clientVersion, processName, batchName, throwOnError); #endif Func <AnalyzerStatistics> analyzeProcedure = () => { ExecutionProgressControl?.StartMonitor_Batch(); try { var batchID = Guid.NewGuid(); var coldCacheExecutionResult = AnalysisServicesHelper.ExecuteForDataSet(_connectionString, commandAnalyze(batchID, clearCacheMode), _cancellationTokenSource.Token).ToAnalyzerExecutionResult(dispose: true); var warmCacheExecutionResult = AnalysisServicesHelper.ExecuteForDataSet(_connectionString, commandAnalyze(batchID, ClearCacheMode.Nothing), _cancellationTokenSource.Token).ToAnalyzerExecutionResult(dispose: true); return(AnalyzerStatistics.CreateFromAnalyzerExecutionResults(coldCacheExecutionResult, warmCacheExecutionResult)); } finally { ExecutionProgressControl?.StopMonitor_Batch(); } }; using (_cancellationTokenSource = new CancellationTokenSource()) { using (var task = Task.Factory.StartNew(analyzeProcedure)) return(await task.ConfigureAwait(continueOnCapturedContext : false)); } }
/// <summary> /// Retrieve server-side assembly configuration /// </summary> public async Task <DataTable> GetConfigurationForEngineAsync() { var command = "call {0}.GetConfiguration({1});".FormatWith(ClrAssemblyID, (int)ConfigurationType.Engine); Func <DataTable> function = () => { return(AnalysisServicesHelper.ExecuteForDataTable(_connectionString, command)); }; using (_cancellationTokenSource = new CancellationTokenSource()) { using (var task = Task.Factory.StartNew(function)) return(await task.ConfigureAwait(continueOnCapturedContext : false)); } }
/// <summary> /// Retrieve server-side assembly version /// </summary> public async Task <Version> GetVersionAsync() { var command = "call {0}.GetVersion();".FormatWith(ClrAssemblyID); Func <Version> function = () => { if (AnalysisServicesHelper.ClrAssemblyInstalled(_connectionString, ClrAssemblyID)) { return(AnalysisServicesHelper.ExecuteForDataTable(_connectionString, command).ToVersion()); } return(null); }; using (var task = Task.Factory.StartNew(function)) return(await task.ConfigureAwait(continueOnCapturedContext : false)); }
/// <summary> /// Install and configure the server-side objects using custom assembly file path /// </summary> public async Task InstallAsync(string assemblyFilePath = null) { if (assemblyFilePath == null) { string clrAssemblyFileName; switch (AnalysisServicesHelper.InstanceVersion(_connectionString).Major) { case 11: clrAssemblyFileName = ClrAssemblyFileNameFormat.FormatWith(2012); break; case 12: clrAssemblyFileName = ClrAssemblyFileNameFormat.FormatWith(2014); break; case 13: clrAssemblyFileName = ClrAssemblyFileNameFormat.FormatWith(2016); break; case 14: clrAssemblyFileName = ClrAssemblyFileNameFormat.FormatWith(2017); break; default: throw new ApplicationException("Unsupported SSAS version"); } assemblyFilePath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), clrAssemblyFileName); } var command = "call {0}.Install();".FormatWith(ClrAssemblyID); Action action = () => { AnalysisServicesHelper.RegisterClrAssembly(_connectionString, ClrAssemblyID, ClrAssemblyName, ClrAssemblyDescription, assemblyFilePath); AnalysisServicesHelper.ExecuteNonQuery(_connectionString, command); }; using (var task = Task.Factory.StartNew(action)) await task.ConfigureAwait(continueOnCapturedContext : false); }
/// <summary> /// Execute server-side Analyze procedure /// </summary> public async Task <AnalyzerStatistics> AnalyzeAsync(string statement, ClearCacheMode clearCacheMode = ClearCacheMode.Default, int queryResultRowLimit = 0) { #region Argument exception if (statement == null) { throw new ArgumentNullException("statement"); } #endregion var currentProcess = Process.GetCurrentProcess(); var processName = currentProcess.ProcessName; var clientVersion = "{0} ({1})".FormatWith(currentProcess.MainModule.FileVersionInfo.FileVersion, ClientVersion); #if DEBUG Func <ClearCacheMode, string> commandAnalyze = (cacheMode) => "call {0}.AnalyzeWithDebug(\"{1}\", {2}, {3}, \"{4}\", \"{5}\");".FormatWith(ClrAssemblyID, statement.EscapeMdxString(), (int)cacheMode, queryResultRowLimit, clientVersion, processName); #else Func <ClearCacheMode, string> commandAnalyze = (cacheMode) => "call {0}.Analyze(\"{1}\", {2}, {3}, \"{4}\", \"{5}\");".FormatWith(ClrAssemblyID, statement.EscapeMdxString(), (int)cacheMode, queryResultRowLimit, clientVersion, processName); #endif Action <DataSet, string> saveDebug = (data, dbgType) => { if (!DebugToXml) { return; } var debugPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"SSASQueryAnalyzer\debug"); Directory.CreateDirectory(debugPath); data.WriteXml(Path.Combine(debugPath, "AnalyzerExecutionResult-{0:yyyyMMdd-hhmmss-fff}.{1}").FormatWith(DateTime.Now, dbgType), XmlWriteMode.WriteSchema); }; Func <AnalyzerStatistics> analyzeProcedure = () => { ExecutionProgressControl?.StartMonitor(); try { AnalyzerExecutionResult coldCacheExecutionResult; AnalyzerExecutionResult warmCacheExecutionResult; using (var data = AnalysisServicesHelper.ExecuteForDataSet(_connectionString, commandAnalyze(clearCacheMode), _cancellationTokenSource.Token)) { saveDebug(data, "xqac"); coldCacheExecutionResult = data.ToAnalyzerExecutionResult(dispose: true); } ExecutionProgressControl?.ColdCacheExecutionCompleted(); using (var data = AnalysisServicesHelper.ExecuteForDataSet(_connectionString, commandAnalyze(ClearCacheMode.Nothing), _cancellationTokenSource.Token)) { saveDebug(data, "xqaw"); warmCacheExecutionResult = data.ToAnalyzerExecutionResult(dispose: true); } ExecutionProgressControl?.WarmCacheExecutionCompleted(); return(AnalyzerStatistics.CreateFromAnalyzerExecutionResults(coldCacheExecutionResult, warmCacheExecutionResult)); } finally { ExecutionProgressControl?.StopMonitor(); } }; using (_cancellationTokenSource = new CancellationTokenSource()) { using (var task = Task.Factory.StartNew(analyzeProcedure)) return(await task.ConfigureAwait(continueOnCapturedContext : false)); } }
/// <summary> /// /// </summary> public ProcedureEvents GetLastEvent() { var command = "call {0}.GetLastEvent();".FormatWith(ClrAssemblyID); return((ProcedureEvents)AnalysisServicesHelper.ExecuteScalar(_connectionString, command)); }