/ASSP/CubeInfo.cs

# · C# · 302 lines · 181 code · 32 blank · 89 comment · 18 complexity · 7d5b4b2e236bb9dd2225f0f94686c770 MD5 · raw file

  1. /*============================================================================
  2. File: CubeInfo.cs
  3. Summary: Implements a function which returns the date when the current cube
  4. was last processed.
  5. Date: July 12, 2006
  6. ----------------------------------------------------------------------------
  7. This file is part of the Analysis Services Stored Procedure Project.
  8. http://www.codeplex.com/Wiki/View.aspx?ProjectName=ASStoredProcedures
  9. THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  10. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  11. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  12. PARTICULAR PURPOSE.
  13. ============================================================================*/
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Text;
  17. using Microsoft.AnalysisServices.AdomdServer;
  18. using Microsoft.AnalysisServices; //reference to AMO
  19. namespace ASStoredProcs
  20. {
  21. public class CubeInfo
  22. {
  23. //the assembly must be registered with unrestricted permissions for this function to succeed
  24. [SafeToPrepare(true)]
  25. public static DateTime GetCubeLastProcessedDate()
  26. {
  27. string sServerName = Context.CurrentServerID;
  28. string sDatabaseName = Context.CurrentDatabaseName;
  29. string sCubeName = AMOHelpers.GetCurrentCubeName();
  30. DateTime dtTemp = DateTime.MinValue;
  31. Exception exDelegate = null;
  32. System.Threading.Thread td = new System.Threading.Thread(delegate()
  33. {
  34. try
  35. {
  36. Microsoft.AnalysisServices.Server oServer = new Microsoft.AnalysisServices.Server();
  37. oServer.Connect("Data Source=" + sServerName);
  38. Database db = oServer.Databases.GetByName(sDatabaseName);
  39. Cube cube = db.Cubes.FindByName(sCubeName);
  40. dtTemp = cube.LastProcessed;
  41. }
  42. catch (Exception ex)
  43. {
  44. exDelegate = ex;
  45. }
  46. }
  47. );
  48. td.Start(); //run the delegate code
  49. while (!td.Join(1000)) //wait for up to a second for the delegate to finish
  50. {
  51. Context.CheckCancelled(); //if the delegate isn't done, check whether the parent query has been cancelled. If the parent query has been cancelled (or the ForceCommitTimeout expires) then this will immediately exit
  52. }
  53. if (exDelegate != null) throw exDelegate;
  54. return dtTemp;
  55. //return Context.CurrentCube.LastProcessed; //this doesn't work because of a bug: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=124606
  56. }
  57. [SafeToPrepare(true)]
  58. public static DateTime GetMeasureGroupLastProcessedDate(string MeasureGroupName)
  59. {
  60. string sServerName = Context.CurrentServerID;
  61. string sDatabaseName = Context.CurrentDatabaseName;
  62. string sCubeName = AMOHelpers.GetCurrentCubeName();
  63. DateTime dtTemp = DateTime.MinValue;
  64. Exception exDelegate = null;
  65. System.Threading.Thread td = new System.Threading.Thread(delegate()
  66. {
  67. try
  68. {
  69. Microsoft.AnalysisServices.Server oServer = new Microsoft.AnalysisServices.Server();
  70. oServer.Connect("Data Source=" + sServerName);
  71. Database db = oServer.Databases.GetByName(sDatabaseName);
  72. Cube cube = db.Cubes.GetByName(sCubeName);
  73. dtTemp = cube.MeasureGroups.GetByName(MeasureGroupName).LastProcessed;
  74. }
  75. catch (Exception ex)
  76. {
  77. exDelegate = ex;
  78. }
  79. }
  80. );
  81. td.Start(); //run the delegate code
  82. while (!td.Join(1000)) //wait for up to a second for the delegate to finish
  83. {
  84. Context.CheckCancelled(); //if the delegate isn't done, check whether the parent query has been cancelled. If the parent query has been cancelled (or the ForceCommitTimeout expires) then this will immediately exit
  85. }
  86. if (exDelegate != null) throw exDelegate;
  87. return dtTemp;
  88. }
  89. /// <summary>
  90. /// Max() of last processed dates of all partitions and measure groups in the current cube
  91. /// </summary>
  92. [SafeToPrepare(true)]
  93. public static DateTime GetLastProcessedDateOverPartitions()
  94. {
  95. return GetLastProcessedDateOverPartitions(true);
  96. }
  97. /// <summary>
  98. /// Max() of last processed dates of all partitions in the current cube.
  99. /// Additionaly last processed dates of measure groups can be considered.
  100. /// </summary>
  101. /// <param name="IncludeMeasureGroupLastProcessed">
  102. /// If a dimension was processed by ProcessUpdate and no aggregations were dropped in partitions,
  103. /// then last processed timestamps of individual partitions will not be updated,
  104. /// but the timestamps of measure groups will.
  105. /// Set this parameter to true if you also want to monitor dimension processing.
  106. /// </param>
  107. [SafeToPrepare(true)]
  108. public static DateTime GetLastProcessedDateOverPartitions(bool IncludeMeasureGroupLastProcessed)
  109. {
  110. return GetLastProcessedDateOverPartitions(string.Empty, IncludeMeasureGroupLastProcessed);
  111. }
  112. /// <summary>
  113. /// Max() of last processed dates of all partitions in the current cube for a given measure group.
  114. /// </summary>
  115. /// <param name="MeasureGroupName">Name of the measure group.
  116. /// If null or empty - all measure groups will be considered</param>
  117. /// <param name="IncludeMeasureGroupLastProcessed">
  118. /// If a dimension was processed by ProcessUpdate and no aggregations were dropped in partitions,
  119. /// then last processed timestamps of individual partitions will not be updated,
  120. /// but the timestamps of measure groups will.
  121. /// Set this parameter to true if you also want to monitor dimension processing.
  122. /// </param>
  123. [SafeToPrepare(true)]
  124. public static DateTime GetLastProcessedDateOverPartitions(string MeasureGroupName, bool IncludeMeasureGroupLastProcessed)
  125. {
  126. return GetLastProcessedDateOverPartitions(MeasureGroupName, string.Empty, IncludeMeasureGroupLastProcessed);
  127. }
  128. /// <summary>
  129. /// Last processed date for a given partition in a given measure group in the current cube
  130. /// or Max() if MeasureGroupName/PartitionName is null or empty.
  131. /// </summary>
  132. /// <param name="MeasureGroupName">Name of the measure group.
  133. /// If null or empty - all measure groups will be considered.
  134. /// May not be null or empty if PartitionName is not null or empty</param>
  135. /// <param name="PartitionName">Name of the partition.
  136. /// If null or empty - all partitions (of a measure group) will be considered.</param>
  137. /// <param name="IncludeMeasureGroupLastProcessed">
  138. /// If a dimension was processed by ProcessUpdate and no aggregations were dropped in partitions,
  139. /// then last processed timestamps of individual partitions will not be updated,
  140. /// but the timestamps of measure groups will.
  141. /// Set this parameter to true if you also want to monitor dimension processing.
  142. /// </param>
  143. [SafeToPrepare(true)]
  144. public static DateTime GetLastProcessedDateOverPartitions(string MeasureGroupName, string PartitionName, bool IncludeMeasureGroupLastProcessed)
  145. {
  146. return GetLastProcessedDateOverPartitions(string.Empty, MeasureGroupName, PartitionName, IncludeMeasureGroupLastProcessed);
  147. }
  148. /// <summary>
  149. /// Last processed date for a given partition in a given measure group in the given cube
  150. /// or Max() if MeasureGroupName/PartitionName is null or empty.
  151. /// </summary>
  152. /// <param name="CubeName">Cube to look at. If null or empty, current cube will be used</param>
  153. /// <param name="MeasureGroupName">Name of the measure group.
  154. /// If null or empty - all measure groups will be considered.
  155. /// May not be null or empty if PartitionName is not null or empty</param>
  156. /// <param name="PartitionName">Name of the partition.
  157. /// If null or empty - all partitions (of a measure group) will be considered.</param>
  158. /// <param name="IncludeMeasureGroupLastProcessed">
  159. /// If a dimension was processed by ProcessUpdate and no aggregations were dropped in partitions,
  160. /// then last processed timestamps of individual partitions will not be updated,
  161. /// but the timestamps of measure groups will.
  162. /// Set this parameter to true if you also want to monitor dimension processing.
  163. /// </param>
  164. [SafeToPrepare(true)]
  165. public static DateTime GetLastProcessedDateOverPartitions(string CubeName, string MeasureGroupName, string PartitionName, bool IncludeMeasureGroupLastProcessed)
  166. {
  167. string sServerName = Context.CurrentServerID;
  168. string sDatabaseName = Context.CurrentDatabaseName;
  169. string sCubeName;
  170. if (string.IsNullOrEmpty(CubeName))
  171. {
  172. sCubeName = AMOHelpers.GetCurrentCubeName();
  173. }
  174. else
  175. {
  176. sCubeName = CubeName;
  177. }
  178. if (!string.IsNullOrEmpty(PartitionName) && string.IsNullOrEmpty(MeasureGroupName))
  179. {
  180. throw new Exception("Measure group may not be empty if partition is explicitly specified");
  181. }
  182. DateTime dtTemp = DateTime.MinValue;
  183. Exception exDelegate = null;
  184. System.Threading.Thread td = new System.Threading.Thread(delegate()
  185. {
  186. try
  187. {
  188. Microsoft.AnalysisServices.Server oServer = new Microsoft.AnalysisServices.Server();
  189. oServer.Connect("Data Source=" + sServerName);
  190. Database db = oServer.Databases.GetByName(sDatabaseName);
  191. Cube cube = db.Cubes.FindByName(sCubeName);
  192. //If measure group is specified - get it. Otherwise iterate over all measure groups
  193. if (!string.IsNullOrEmpty(MeasureGroupName))
  194. {
  195. dtTemp = FindMaxLastProcessedDateInMeasureGroup(cube.MeasureGroups.GetByName(MeasureGroupName), PartitionName, IncludeMeasureGroupLastProcessed);
  196. }
  197. else
  198. {
  199. foreach (MeasureGroup curMeasureGroup in cube.MeasureGroups)
  200. {
  201. DateTime curLastProcessedDate = FindMaxLastProcessedDateInMeasureGroup(curMeasureGroup, PartitionName, IncludeMeasureGroupLastProcessed);
  202. if (dtTemp < curLastProcessedDate)
  203. {
  204. dtTemp = curLastProcessedDate;
  205. }
  206. }
  207. }
  208. }
  209. catch (Exception ex)
  210. {
  211. exDelegate = ex;
  212. }
  213. }
  214. );
  215. td.Start(); //run the delegate code
  216. while (!td.Join(1000)) //wait for up to a second for the delegate to finish
  217. {
  218. Context.CheckCancelled(); //if the delegate isn't done, check whether the parent query has been cancelled. If the parent query has been cancelled (or the ForceCommitTimeout expires) then this will immediately exit
  219. }
  220. if (exDelegate != null) throw exDelegate;
  221. return dtTemp;
  222. }
  223. /// <summary>
  224. /// Helper method for iteration in a measure group
  225. /// </summary>
  226. /// <param name="MeasureGroup">Measure group object (may not be null)</param>
  227. /// <param name="PartitionName">Name of the partition.
  228. /// If null or empty - all partitions (of a measure group) will be considered.</param>
  229. /// <param name="IncludeMeasureGroupLastProcessed">
  230. /// If a dimension was processed by ProcessUpdate and no aggregations were dropped in partitions,
  231. /// then last processed timestamps of individual partitions will not be updated,
  232. /// but the timestamps of measure groups will.
  233. /// Set this parameter to true if you also want to monitor dimension processing.
  234. /// </param>
  235. [SafeToPrepare(true)]
  236. private static DateTime FindMaxLastProcessedDateInMeasureGroup(MeasureGroup MeasureGroup, string PartitionName, bool IncludeMeasureGroupLastProcessed)
  237. {
  238. DateTime result = DateTime.MinValue;
  239. if (IncludeMeasureGroupLastProcessed)
  240. {
  241. result = MeasureGroup.LastProcessed;
  242. }
  243. //Look at one specific partition
  244. if (!string.IsNullOrEmpty(PartitionName))
  245. {
  246. Partition partition = MeasureGroup.Partitions.GetByName(PartitionName);
  247. if (result < partition.LastProcessed)
  248. {
  249. result = partition.LastProcessed;
  250. }
  251. }
  252. else
  253. {
  254. //Iterate over all partitions and search for max()
  255. foreach (Partition curPartition in MeasureGroup.Partitions)
  256. {
  257. if (result < curPartition.LastProcessed)
  258. {
  259. result = curPartition.LastProcessed;
  260. }
  261. }
  262. }
  263. return result;
  264. }
  265. }
  266. }