Tommie 的个人资料: : Tommie照片日志列表更多 工具 帮助

日志


Trying the other solution [step 2: implementing and installing the adapter]

This should be pretty straight-forward. I'll have to do these steps:

  • Implement the adapter
    • Implement Initialize()
    • Implement MakeSchemaChanges()
    • Implement MakeDataChanges()
  • Install the adapter on the TFS VPC
  • Navigate to the warehouse web service and invoke the Run command (which will make the warehouse read and execute the adapter)

That should be it. So, let's have a look at how the adapter looks like, method by method:

  • public void Initialize(IDatastore ds)

public void Initialize(IDataStore ds) { // Check the data store m_dataStore = ds; if (m_dataStore == null) { throw new Exception("Null data store"); } // Connect to the TFS Server String url = "ORCASBETA2_VSTS"; //or perhaps it should be http://orcasbeta2_tfsv:8080 ? TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(url); if (tfs == null) { throw new Exception("TF Server instance not obtained for TFS url:" + url); } }

  • public SchemaChangesResult MakeSchemaChanges()

public SchemaChangesResult MakeSchemaChanges() { SchemaChangesResult result = SchemaChangesResult.NoChanges; WarehouseConfig config = m_dataStore.GetWarehouseConfig(); Fact codeMetricsFact = new Fact(); //Set the name of the fact codeMetricsFact.Name = "Code Metrics"; //Set friendly name. This will be used in the OLAP cube in SQL Enterprise editions- codeMetricsFact.FriendlyName = "Code Metrics"; //Create the fields the Code Metrics fact will have Field maintainabilityIndex = new Field(); maintainabilityIndex.Name = "Maintainability Index"; maintainabilityIndex.Type = "INT"; maintainabilityIndex.AggregationFunction = "sum"; Field cyclomaticComplexity = new Field(); cyclomaticComplexity.Name = "Cyclomatic Complexity"; cyclomaticComplexity.Type = "INT"; cyclomaticComplexity.AggregationFunction = "sum"; Field depthOfInheritance = new Field(); depthOfInheritance.Name = "Depth of Inheritance"; depthOfInheritance.Type = "INT"; depthOfInheritance.AggregationFunction = "sum"; Field classCoupling = new Field(); classCoupling.Name = "Class Coupling"; classCoupling.Type = "INT"; classCoupling.AggregationFunction = "sum"; Field linesOfCode = new Field(); linesOfCode.Name = "Lines of Code"; linesOfCode.Type = "INT"; linesOfCode.AggregationFunction = "sum"; //Add the fields to the newly created fact table. codeMetricsFact.Fields.Add(maintainabilityIndex); codeMetricsFact.Fields.Add(cyclomaticComplexity); codeMetricsFact.Fields.Add(depthOfInheritance); codeMetricsFact.Fields.Add(classCoupling); codeMetricsFact.Fields.Add(linesOfCode); //Create and add dimensionUse for Build to fact. This means that this fact can be sliced by Build. DimensionUse dimUse = new DimensionUse(); dimUse.FriendlyUseName = "Build"; dimUse.UseName = "Build"; dimUse.DimensionName = "Build"; dimUse.IntermediateFactName = null; //I don't know what the hell this does, really... codeMetricsFact.DimensionUses.Add(dimUse); //Add the new fact to the config config.Facts.Add(codeMetricsFact); //Check if adapter is requested to stop before starting transaction. if (m_stopRequested) { return SchemaChangesResult.StopRequested; } // Use transactions for safe operation m_dataStore.BeginTransaction(); try { // This will add the new fact and new dimension to the warehouse. // If user wants to add new fields or measures to existing dimensions or facts in // warehouse, then use the IDataStore.Add* methods. IDataStore.Add(config) will not // work in that case. // Also note that the Add method only appends the new facts and dimensions from the // modified config. The current existing facts and dimensions will not get added twice. m_dataStore.Add(config); m_dataStore.CommitTransaction(); } catch { m_dataStore.RollbackTransaction(); throw new Exception("Transaction failed. Could not make schema changes!"); } result = SchemaChangesResult.ChangesComplete; return result; }

  • public DataChangesResult MakeDataChanges()

public DataChangesResult MakeDataChanges() { DataChangesResult result = DataChangesResult.NoChanges; FactEntry metricsDataEntry = m_dataStore.CreateFactEntry("Code Metrics"); string connString = "Data Source=ORCASBETA2_TFSV;" + "Database=CMDB;" + "Integrated Security=true;"; SqlConnection conn = new SqlConnection(connString); try { conn.Open(); } catch (Exception e) { m_dataStore.LogEvent(AdapterEventLevel.Error, "Could not open CMDB."); return DataChangesResult.NoChanges; } try { SqlCommand command = new SqlCommand("HarvestCodeMetrics", conn); command.CommandType = CommandType.StoredProcedure; using (SqlDataReader myReader = command.ExecuteReader(System.Data.CommandBehavior.CloseConnection)) { // Harvest data from CMDB. The indexes of metricsDataEntry must correspond // to an existing field in the Code Metrics fact table, as created in // MakeSchemaChanges() above. while (myReader.Read()) { metricsDataEntry["Maintainability Index"] = myReader.GetInt32(myReader.GetOrdinal("MaintainabilityIndex")); metricsDataEntry["Cyclomatic Complexity"] = myReader.GetInt32(myReader.GetOrdinal("CyclomaticComplexity")); metricsDataEntry["Depth of Inheritance"] = myReader.GetInt32(myReader.GetOrdinal("DepthOfInheritance")); metricsDataEntry["Class Coupling"] = myReader.GetInt32(myReader.GetOrdinal("ClassCoupling")); metricsDataEntry["Lines of Code"] = myReader.GetInt32(myReader.GetOrdinal("LinesOfCode")); metricsDataEntry["Build"] = myReader.GetString(myReader.GetOrdinal("Build")); } myReader.Close(); } } catch (Exception e) { m_dataStore.LogEvent(AdapterEventLevel.Error, "Could not read from CMDB"); return DataChangesResult.NoChanges; } //Check if adapter is requested to stop if (m_stopRequested) { return DataChangesResult.StopRequested; } // Not requested to stop? Great, start the transaction then. m_dataStore.BeginTransaction(); try { m_dataStore.SaveFactEntry(metricsDataEntry, false); // If true, the save may result in updating an _existing_ row. m_dataStore.CommitTransaction(); } catch { m_dataStore.RollbackTransaction(); throw new Exception("Error! Couldn't save the fact entry"); } //we're done, mark that we've done some changes. result = DataChangesResult.ChangesComplete; m_dataStore.LogEvent(AdapterEventLevel.Informational, "Updated warehouse"); return result; }

That's it. Let's try to build the adapter and install it, following these instructions. I'll publish a new post when I've tried this out.

评论 (3)

请稍候...
很抱歉,您输入的评论太长。请缩短您的评论。
您没有输入任何内容,请重试。
很抱歉,我们当前无法添加您的评论。请稍后重试。
若要添加评论,需要您的家长授予您相应权限。请求权限
您的家长禁用了评论功能。
很抱歉,我们当前无法删除您的评论。请稍后重试。
您已超过了一天之内允许提供的评论数上限。请在 24 小时后重试。
因为我们的系统表明您可能在向其他用户提供垃圾评论,您的帐户已禁用了评论功能。如果您认为我们错误地禁用了您的帐户,请联系 Windows Live 支持部门
完成下面的安全检查,您提供评论的过程才能完成。
您在安全检查中键入的字符必须与图片或音频中的字符一致。

若要添加评论,请使用您的 Windows Live ID 登录(如果您使用过 Hotmail、Messenger 或 Xbox LIVE,您就拥有 Windows Live ID)。登录


还没有 Windows Live ID 吗?请注册

没有名字发表:

Hi,Do you need advertising displays, digital signages, advertising player and LCD displays? Please go Here:www.amberdigital.com.hk(Amberdigital).we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

amberdigital Contact Us

website:www.amberdigital.com.hk
alibaba:amberdigital.en.alibaba.com[bcgcbffcgjahi]

9 月 30 日
匿名 的图片
(没有名字) 发表:
她的人生杭州装饰注定不能由自己杭州中央空调维修决定,当踏入杭州家装这深宅大院,她就知道杭州空调维修今生今世都将被束缚。三从四德的为妻之道杭州办公室装修她是懂的呀,只是为什么杭州装修面对他和他的所爱,她的心却回复杭州空调维修公司不了原来的杭州装饰公司简单?他怎么可能杭州空调移机爱上她呢?他心系杭州家政国家大事
8 月 4 日
12 月 8 日

引用通告

此日志的引用通告 URL 是:
http://tomfury.spaces.live.com/blog/cns!F58BF7D0B46F52B9!300.trak
引用此项的网络日志