PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/AggregationManager/CS/AggManager/EditAggs.cs

#
C# | 705 lines | 574 code | 85 blank | 46 comment | 42 complexity | a46938e4977077ab2c30c52855d9451e MD5 | raw file
  1. /*============================================================================
  2. File: EditAgggs.cs
  3. Summary: Contains the form to add, delete, and change aggregations
  4. Part of Aggregation Manager
  5. Date: January 2007
  6. ------------------------------------------------------------------------------
  7. This file is part of the Microsoft SQL Server Code Samples.
  8. Copyright (C) Microsoft Corporation. All rights reserved.
  9. This source code is intended only as a supplement to Microsoft
  10. Development Tools and/or on-line documentation. See these other
  11. materials for detailed information regarding Microsoft code samples.
  12. THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  13. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  15. PARTICULAR PURPOSE.
  16. ============================================================================*/
  17. using System;
  18. using System.Collections.Generic;
  19. using System.ComponentModel;
  20. using System.Data;
  21. using System.Drawing;
  22. using System.Text;
  23. using System.Windows.Forms;
  24. using Microsoft.AnalysisServices;
  25. using Microsoft.AnalysisServices.AdomdClient;
  26. namespace AggManager
  27. {
  28. public partial class EditAggs : Form
  29. {
  30. private MeasureGroup mg1;
  31. private AggregationDesign aggDes;
  32. string[,] dimAttributes;
  33. string[] dimNames;
  34. string[] dimIDs;
  35. bool boolOptimizeAgg = false;
  36. bool boolIsRigid = false;
  37. enum SynchControls
  38. {
  39. SynchTreeToGrid = 1,
  40. SynchGridToTreeView = 2,
  41. Unknown = 3
  42. }
  43. SynchControls sychContr = SynchControls.Unknown;
  44. public EditAggs()
  45. {
  46. InitializeComponent();
  47. }
  48. public void Init(string strAggDesign,
  49. MeasureGroup mg,
  50. string[,] inDimAttributes,
  51. string[] inDimNames ,
  52. string[] inDimIDs)
  53. {
  54. this.Text = this.Text + " Aggregation Desing :" + strAggDesign;
  55. mg1 = mg;
  56. aggDes = mg.AggregationDesigns[strAggDesign];
  57. dimAttributes = inDimAttributes;
  58. dimNames = inDimNames;
  59. dimIDs = inDimIDs;
  60. DataTable myTable = new DataTable("Aggregations");
  61. DataColumn colItem = new DataColumn("Name", Type.GetType("System.String"));
  62. myTable.Columns.Add(colItem);
  63. colItem = new DataColumn("Aggregations", Type.GetType("System.String"));
  64. myTable.Columns.Add(colItem);
  65. colItem = new DataColumn("Type", Type.GetType("System.String"));
  66. myTable.Columns.Add(colItem);
  67. DataView myDataView = new DataView(myTable);
  68. dataGrid1.DataSource = myDataView;
  69. DataRow NewRow;
  70. foreach (Aggregation agg in aggDes.Aggregations)
  71. {
  72. NewRow = myTable.NewRow();
  73. NewRow["Aggregations"] = ConvertAggToSting(agg);
  74. NewRow["Name"] = agg.Name;
  75. myTable.Rows.Add(NewRow);
  76. }
  77. AddGridStyle();
  78. PopulateTreeView();
  79. checkBoxRelationships.Checked = true;
  80. int i = 0;
  81. foreach (DataRow dRow in myDataView.Table.Rows)
  82. {
  83. dataGrid1.CurrentRowIndex = i;
  84. dataGrid1_Click(null, null);
  85. i++;
  86. }
  87. myDataView.AllowNew = false;
  88. }
  89. /// <summary>
  90. /// Setting data grid column captions and width
  91. /// </summary>
  92. private void AddGridStyle()
  93. {
  94. DataView myDataView = (DataView)dataGrid1.DataSource;
  95. int iWidth0 = 100;
  96. int iWidth1 = 400;
  97. Graphics Graphics = dataGrid1.CreateGraphics();
  98. if (myDataView.Table.Rows.Count > 0)
  99. {
  100. int iColWidth = (int)(Graphics.MeasureString
  101. (myDataView.Table.Rows[0].ItemArray[0].ToString(),
  102. dataGrid1.Font).Width);
  103. iWidth0 = (int)System.Math.Max(iWidth0, iColWidth);
  104. iColWidth = (int)(Graphics.MeasureString
  105. (myDataView.Table.Rows[0].ItemArray[1].ToString(),
  106. dataGrid1.Font).Width);
  107. iWidth1 = (int)System.Math.Max(iWidth1, iColWidth);
  108. }
  109. DataGridTableStyle myGridStyle = new DataGridTableStyle();
  110. myGridStyle.MappingName = "Aggregations";
  111. DataGridTextBoxColumn nameColumnStyle = new DataGridTextBoxColumn();
  112. nameColumnStyle.MappingName = "Name";
  113. nameColumnStyle.HeaderText = "Name";
  114. nameColumnStyle.Width = iWidth0;
  115. myGridStyle.GridColumnStyles.Add(nameColumnStyle);
  116. DataGridTextBoxColumn nameColumnStyle1 = new DataGridTextBoxColumn();
  117. nameColumnStyle1.MappingName = "Aggregations";
  118. nameColumnStyle1.HeaderText = "Aggregation Definition";
  119. nameColumnStyle1.Width = iWidth1;
  120. myGridStyle.GridColumnStyles.Add(nameColumnStyle1);
  121. DataGridTextBoxColumn nameColumnStyle2 = new DataGridTextBoxColumn();
  122. nameColumnStyle2.MappingName = "Type";
  123. nameColumnStyle2.HeaderText = "Type";
  124. nameColumnStyle2.Width = 50;
  125. myGridStyle.GridColumnStyles.Add(nameColumnStyle2);
  126. dataGrid1.TableStyles.Add(myGridStyle);
  127. }
  128. private void buttonCancel_Click(object sender, EventArgs e)
  129. {
  130. this.Close();
  131. }
  132. private void buttonOK_Click(object sender, EventArgs e)
  133. {
  134. DataView myDataView;
  135. int i = 0;
  136. string strRow;
  137. string strAggName;
  138. this.Cursor = Cursors.WaitCursor;
  139. aggDes.Aggregations.Clear();
  140. myDataView = (DataView)dataGrid1.DataSource;
  141. foreach (DataRow dRow in myDataView.Table.Rows)
  142. {
  143. if (dRow.RowState.ToString() != "Deleted")
  144. {
  145. strAggName = dRow.ItemArray[0].ToString();
  146. strRow = dRow.ItemArray[1].ToString();
  147. i++;
  148. if (AddAggregationToAggDesign(
  149. aggDes,
  150. strRow,
  151. strAggName) == false)
  152. i--; // No aggregation has been added
  153. }
  154. }
  155. MessageBox.Show( "Aggregation desing :" + aggDes.Name + " has been updated with " + i.ToString() + " aggregations ");
  156. this.Cursor = Cursors.Default;
  157. this.Close();
  158. }
  159. /// <summary>
  160. /// Helper function takes aggregation as input and returns string representation of aggregation
  161. /// </summary>
  162. private string ConvertAggToSting(Aggregation agg)
  163. {
  164. string outStr = "";
  165. AggregationAttribute aggAttr;
  166. AggregationDimension aggDim;
  167. foreach (MeasureGroupDimension mgDim in mg1.Dimensions)
  168. {
  169. aggDim = agg.Dimensions.Find(mgDim.CubeDimensionID);
  170. if (aggDim == null)
  171. {
  172. foreach (CubeAttribute cubeDimAttr in mgDim.CubeDimension.Attributes)
  173. outStr = outStr + "0";
  174. }
  175. else
  176. {
  177. foreach (CubeAttribute cubeDimAttr in mgDim.CubeDimension.Attributes)
  178. {
  179. aggAttr = aggDim.Attributes.Find(cubeDimAttr.AttributeID);
  180. if (aggAttr == null)
  181. outStr = outStr + "0";
  182. else
  183. outStr = outStr + "1";
  184. }
  185. }
  186. outStr = outStr + ",";
  187. }
  188. return outStr.Substring(0, outStr.Length - 1);
  189. }
  190. Boolean AddAggregationToAggDesign(AggregationDesign aggDesign, string instr, string aggName)
  191. {
  192. Aggregation agg;
  193. agg = aggDesign.Aggregations.Find(aggName);
  194. if (agg != null)
  195. aggName = "Aggregation " + aggDesign.Aggregations.Count.ToString();
  196. if (aggName == "")
  197. aggName = "Aggregation " + aggDesign.Aggregations.Count.ToString();
  198. agg = aggDesign.Aggregations.Add(aggName, aggName);
  199. string a1;
  200. int dimNum = 0;
  201. int attrNum = 0;
  202. bool newDim = true;
  203. for (int i = 0; i < instr.Length; i++)
  204. {
  205. a1 = instr[i].ToString();
  206. switch (a1)
  207. {
  208. case ",":
  209. dimNum++;
  210. attrNum = -1;
  211. newDim = true;
  212. break;
  213. case "0":
  214. break;
  215. case "1":
  216. if (newDim)
  217. {
  218. agg.Dimensions.Add(dimIDs[dimNum]);
  219. newDim = false;
  220. }
  221. agg.Dimensions[dimIDs[dimNum]].Attributes.Add(dimAttributes[dimNum, attrNum]);
  222. break;
  223. default:
  224. break;
  225. }
  226. attrNum++;
  227. }
  228. if (agg.Dimensions.Count == 0)
  229. {
  230. aggDesign.Aggregations.Remove(agg);
  231. return false;
  232. }
  233. return true;
  234. }
  235. /// <summary>
  236. /// Called to populate tree view representing dimension attributes
  237. /// </summary>
  238. public void PopulateTreeView()
  239. {
  240. treeViewAggregation.Nodes.Clear();
  241. if (!checkBoxRelationships.Checked )
  242. {
  243. foreach (MeasureGroupDimension mgDim in mg1.Dimensions)
  244. {
  245. TreeNode parentNode = treeViewAggregation.Nodes.Add(mgDim.CubeDimensionID, mgDim.CubeDimensionID);
  246. foreach (CubeAttribute cubeDimAttr in mgDim.CubeDimension.Attributes)
  247. parentNode.Nodes.Add(cubeDimAttr.AttributeID, cubeDimAttr.AttributeID);
  248. }
  249. }
  250. else
  251. {
  252. foreach (MeasureGroupDimension mgDim in mg1.Dimensions)
  253. {
  254. TreeNode parentNode = treeViewAggregation.Nodes.Add(mgDim.CubeDimensionID, mgDim.CubeDimensionID);
  255. foreach (CubeAttribute cubeDimAttr in mgDim.CubeDimension.Attributes)
  256. if (cubeDimAttr.Attribute.Usage == AttributeUsage.Key)
  257. {
  258. parentNode = parentNode.Nodes.Add(cubeDimAttr.AttributeID, cubeDimAttr.AttributeID);
  259. AddTreeViewNodeChildren(parentNode, cubeDimAttr);
  260. }
  261. }
  262. }
  263. treeViewAggregation.ExpandAll();
  264. }
  265. /// <summary>
  266. /// Recursive function. Adds nodes to the tree view control.
  267. /// Adds nodes accourding to attribute relationships
  268. /// </summary>
  269. private void AddTreeViewNodeChildren(TreeNode node, CubeAttribute cubeDimAttr )
  270. {
  271. foreach (AttributeRelationship attRel in cubeDimAttr.Attribute.AttributeRelationships)
  272. {
  273. CubeAttribute childAttr = cubeDimAttr.Parent.Attributes.Find(attRel.AttributeID);
  274. if (childAttr == null) break;
  275. TreeNode childNode = node.Nodes.Add(childAttr.AttributeID, childAttr.AttributeID);
  276. childNode.Tag = attRel;
  277. AddTreeViewNodeChildren( childNode, childAttr);
  278. }
  279. }
  280. private void EditAggs_Load(object sender, EventArgs e)
  281. {
  282. //Add menu item allowing for adding new aggregations to agg design
  283. MenuItem item1 = new MenuItem("Add Aggregation", new EventHandler(AddAggregationHandler));
  284. ContextMenu menu = new ContextMenu(new MenuItem[] { item1});
  285. this.dataGrid1.ContextMenu = menu;
  286. dataGrid1_Click(sender, e);
  287. }
  288. void AddAggregationHandler(object sender, EventArgs e)
  289. {
  290. DataView myDataView;
  291. myDataView = (DataView)dataGrid1.DataSource;
  292. String strAgg = "";
  293. int i = 0, j = 0;
  294. while (dimNames[i] != null)
  295. {
  296. j = 0;
  297. while (dimAttributes[i, j] != null)
  298. {
  299. strAgg = strAgg + "0";
  300. j++;
  301. }
  302. i++;
  303. strAgg = strAgg + ",";
  304. }
  305. strAgg = strAgg.Remove(strAgg.Length - 1);
  306. DataRow NewRow = myDataView.Table.NewRow();
  307. NewRow["Aggregations"] = strAgg;
  308. NewRow["Name"] = "Aggregation " + myDataView.Table.Rows.Count.ToString();
  309. myDataView.Table.Rows.Add(NewRow);
  310. }
  311. /// <summary>
  312. /// Helps synchronizing aggregation definition in current row data grid control to
  313. /// aggregation definition presented as checked boxes for appropriate attributes in
  314. /// tree view control
  315. /// </summary>
  316. private void dataGrid1_Click(object sender, EventArgs e)
  317. {
  318. if (sychContr == SynchControls.SynchGridToTreeView)
  319. return;
  320. try
  321. {
  322. int intGridOrdinal = dataGrid1.CurrentRowIndex;
  323. DataView myDataView;
  324. myDataView = (DataView)dataGrid1.DataSource;
  325. String strAgg = myDataView.Table.Rows[intGridOrdinal].ItemArray[1].ToString();
  326. if (checkBoxRelationships.Checked)
  327. {
  328. sychContr = SynchControls.SynchGridToTreeView;
  329. if (CheckOffTreeView(strAgg))
  330. myDataView.Table.Rows[intGridOrdinal][2] = "Rigid";
  331. else
  332. myDataView.Table.Rows[intGridOrdinal][2] = "Flexible";
  333. }
  334. else
  335. {
  336. int i = 0;
  337. foreach (TreeNode parentNode in treeViewAggregation.Nodes)
  338. {
  339. foreach (TreeNode childNode in parentNode.Nodes)
  340. {
  341. if (strAgg[i].ToString() == "1")
  342. {
  343. sychContr = SynchControls.SynchGridToTreeView;
  344. childNode.Checked = true;
  345. childNode.BackColor = dataGrid1.HeaderBackColor;
  346. }
  347. else
  348. {
  349. sychContr = SynchControls.SynchGridToTreeView;
  350. childNode.Checked = false;
  351. childNode.BackColor = treeViewAggregation.BackColor;
  352. }
  353. i++;
  354. }
  355. i++;
  356. }
  357. }
  358. }
  359. catch
  360. { }
  361. sychContr = SynchControls.Unknown;
  362. }
  363. private void dataGrid1_CurrentCellChanged(object sender, EventArgs e)
  364. {
  365. dataGrid1_Click(sender, e);
  366. }
  367. /// <summary>
  368. /// Main function called when user checks/uncheckes dimension attribute.
  369. /// If attribute checked it needs to be added to the string representation of an aggregations
  370. /// </summary>
  371. private void treeViewAggregation_AfterCheck(object sender, TreeViewEventArgs e)
  372. {
  373. // If happen to synch Tree to grid, we should quit
  374. if (sychContr == SynchControls.SynchTreeToGrid)
  375. return;
  376. if (e.Action == TreeViewAction.Unknown && !boolOptimizeAgg ) return;
  377. if (e.Node.Parent == null)
  378. return;
  379. int intGridOrdinal = dataGrid1.CurrentRowIndex;
  380. DataView myDataView;
  381. myDataView = (DataView)dataGrid1.DataSource;
  382. String strAgg = myDataView.Table.Rows[intGridOrdinal].ItemArray[1].ToString();
  383. int i = 0;
  384. int intAttrCount = 0;
  385. int slashIndex = 0;
  386. string parentName = "";
  387. slashIndex = e.Node.FullPath.IndexOf("\\");
  388. if ( slashIndex > 0 ) parentName = e.Node.FullPath.Substring( 0, slashIndex);
  389. else MessageBox.Show ( "Cannot find parent");
  390. while (treeViewAggregation.Nodes[i].Name != parentName)
  391. {
  392. intAttrCount++;
  393. intAttrCount += mg1.Dimensions[treeViewAggregation.Nodes[i].Name].CubeDimension.Attributes.Count;
  394. i++;
  395. }
  396. if (checkBoxRelationships.Checked)
  397. {
  398. //Find a place of an attribute in the attr string
  399. int j = 0;
  400. foreach (CubeAttribute cubeDimAttr in mg1.Dimensions[treeViewAggregation.Nodes[i].Name].CubeDimension.Attributes)
  401. {
  402. if (cubeDimAttr.AttributeID == e.Node.Name)
  403. intAttrCount += j;
  404. j++;
  405. }
  406. }
  407. else
  408. {
  409. intAttrCount += e.Node.Index;
  410. }
  411. if (e.Node.Checked)
  412. {
  413. strAgg = strAgg.Insert(intAttrCount, "1");
  414. strAgg = strAgg.Remove(intAttrCount + 1, 1);
  415. System.Drawing.Color ii = dataGrid1.HeaderBackColor;
  416. e.Node.BackColor = ii;
  417. }
  418. else
  419. {
  420. strAgg = strAgg.Insert(intAttrCount, "0");
  421. strAgg = strAgg.Remove(intAttrCount + 1, 1);
  422. e.Node.BackColor = treeViewAggregation.BackColor;
  423. }
  424. myDataView.Table.Rows[intGridOrdinal][1] = strAgg;
  425. if (sychContr == SynchControls.SynchTreeToGrid)
  426. dataGrid1_Click(null, null);
  427. sychContr = SynchControls.Unknown;
  428. }
  429. private void checkBoxRelationships_CheckedChanged(object sender, EventArgs e)
  430. {
  431. PopulateTreeView();
  432. dataGrid1_Click(sender, e);
  433. }
  434. /// <summary>
  435. /// Takes aggregation string as an input and interates over nodes in tree view control
  436. /// if attribute participates in aggregation, function will check the check box for
  437. /// the attribute
  438. /// </summary>
  439. private bool CheckOffTreeView(string strAgg)
  440. {
  441. string a1;
  442. int dimNum = 0;
  443. int attrNum = 0;
  444. bool newDim = true;
  445. boolIsRigid = true;
  446. TreeNode dimNode = treeViewAggregation.Nodes[0];
  447. TreeNode attrNode;
  448. for (int i = 0; i < strAgg.Length; i++)
  449. {
  450. a1 = strAgg[i].ToString();
  451. switch (a1)
  452. {
  453. case ",":
  454. dimNum++;
  455. attrNum = -1;
  456. newDim = true;
  457. dimNode = treeViewAggregation.Nodes[dimNum];
  458. break;
  459. case "0":
  460. attrNode = FindChildNode(dimNode, dimAttributes[dimNum, attrNum]);
  461. if (attrNode != null)
  462. {
  463. attrNode.Checked = false;
  464. attrNode.BackColor = treeViewAggregation.BackColor;
  465. }
  466. break;
  467. case "1":
  468. if (newDim) newDim = false;
  469. attrNode = FindChildNodeAndRelationships(dimNode, dimAttributes[dimNum, attrNum]);
  470. if (attrNode != null)
  471. {
  472. attrNode.Checked = true;
  473. attrNode.BackColor = dataGrid1.HeaderBackColor;
  474. }
  475. break;
  476. default:
  477. break;
  478. }
  479. attrNum++;
  480. }
  481. treeViewAggregation.ExpandAll();
  482. return boolIsRigid;
  483. }
  484. private TreeNode FindChildNodeAndRelationships(TreeNode node, string strNodeID)
  485. {
  486. TreeNode returnNode;
  487. foreach (TreeNode childNode in node.Nodes)
  488. {
  489. if (childNode.Name == strNodeID)
  490. {
  491. if (childNode.Tag != null)
  492. if (((AttributeRelationship)childNode.Tag).RelationshipType == RelationshipType.Flexible)
  493. boolIsRigid = false;
  494. return childNode;
  495. }
  496. returnNode = FindChildNodeAndRelationships(childNode, strNodeID);
  497. if (returnNode != null)
  498. {
  499. if (node.Tag != null)
  500. if (((AttributeRelationship)node.Tag).RelationshipType == RelationshipType.Flexible)
  501. boolIsRigid = false;
  502. return returnNode;
  503. }
  504. }
  505. return null;
  506. }
  507. private TreeNode FindChildNode(TreeNode node, string strNodeID)
  508. {
  509. TreeNode returnNode;
  510. foreach (TreeNode childNode in node.Nodes)
  511. {
  512. if (childNode.Name == strNodeID)
  513. return childNode;
  514. returnNode = FindChildNode(childNode, strNodeID);
  515. if (returnNode != null)
  516. return returnNode;
  517. }
  518. return null;
  519. }
  520. /// <summary>
  521. /// Goes over every aggregation in the aggregation design and eliminates
  522. /// redundant attributes from every aggregation
  523. /// Redundant is an attribute in aggregation that in the attribute relationship chain appears on top
  524. /// of another attribute.
  525. /// For example State attribute should not be selected if City attribute appears in the aggregation.
  526. /// </summary>
  527. private void buttonOptimizeAgg_Click(object sender, EventArgs e)
  528. {
  529. if (checkBoxRelationships.Checked == false)
  530. {
  531. MessageBox.Show("Please switch to relationships view");
  532. return;
  533. }
  534. this.Cursor = Cursors.WaitCursor;
  535. DataView myDataView;
  536. myDataView = (DataView)dataGrid1.DataSource;
  537. boolOptimizeAgg = true;
  538. int i = 0;
  539. foreach( DataRow dataGridRow in myDataView.Table.Rows)
  540. {
  541. dataGrid1.CurrentRowIndex = i;
  542. dataGrid1_Click(null,null);
  543. foreach (TreeNode node in treeViewAggregation.Nodes)
  544. OptimizeNode(node, false);
  545. i++;
  546. }
  547. boolOptimizeAgg = false;
  548. this.Cursor = Cursors.Default;
  549. }
  550. private void OptimizeNode(TreeNode node, bool removeChecks)
  551. {
  552. bool localRemoveChecks = removeChecks;
  553. foreach (TreeNode childNode in node.Nodes)
  554. {
  555. localRemoveChecks = removeChecks;
  556. if (childNode.Checked == true)
  557. if (removeChecks) childNode.Checked = false;
  558. else localRemoveChecks = true;
  559. OptimizeNode(childNode, localRemoveChecks);
  560. }
  561. }
  562. private void buttonEliminateDupe_Click(object sender, EventArgs e)
  563. {
  564. DataView myDataView;
  565. myDataView = (DataView)dataGrid1.DataSource;
  566. myDataView.Sort = "Aggregations";
  567. int i = 0;
  568. try
  569. {
  570. while (i < myDataView.Table.Rows.Count - 1)
  571. {
  572. while (myDataView.Table.Rows[i].ItemArray[1].ToString() == myDataView.Table.Rows[i + 1].ItemArray[1].ToString())
  573. myDataView.Table.Rows.Remove(myDataView.Table.Rows[i + 1]);
  574. i++;
  575. }
  576. }
  577. catch
  578. { }
  579. myDataView.Sort = "";
  580. }
  581. }
  582. }