public void ExecuteExplainPlan(SqlObfuscator obfuscator) { // Don't re-run an explain plan if one already exists if (_explainPlan != null) { return; } try { // Using invoke for thread safety, DoExplainPlanCondition is nullable if (DoExplainPlanCondition?.Invoke() == true) { var explainPlan = GenerateExplainPlan?.Invoke(_explainPlanResources); if (explainPlan != null) { foreach (var data in explainPlan.ExplainPlanDatas) { foreach (var index in explainPlan.ObfuscatedHeaders) { data[index] = obfuscator.GetObfuscatedSql(data[index].ToString(), DatastoreVendorName); } } _explainPlan = new ExplainPlan(explainPlan.ExplainPlanHeaders, explainPlan.ExplainPlanDatas, explainPlan.ObfuscatedHeaders); } } } catch (Exception exception) { Log.DebugFormat("Unable to execute explain plan: {0}", exception); } }
public static ExplainPlan GenerateExplainPlan(object resources) { if (!(resources is IDbCommand)) { return(null); } var dbCommand = (IDbCommand)resources; if (dbCommand.Connection.State != ConnectionState.Open) { dbCommand.Connection.Open(); } ExplainPlan explainPlan = null; //KILL THE CONNECTION NO MATTER WHAT HAPPENS DURING EXECUTION TO AVOID CONNECTION LEAKING using (dbCommand) using (dbCommand.Connection) { dbCommand.Transaction = null; SqlParser.FixParameterizedSql(dbCommand); dbCommand.CommandText = "EXPLAIN " + dbCommand.CommandText; using (IDataReader reader = dbCommand.ExecuteReader()) { var headers = GetReaderHeaders(reader); // Decide which headers should be obfuscated based on the Vendor (this is only SQL) var obfuscatedHeaders = GetObfuscatedIndexes(headers); explainPlan = new ExplainPlan(headers, new List <List <object> >(), obfuscatedHeaders); var explainPlanDatas = new List <List <object> >(); while (reader.Read()) { object[] values = new object[reader.FieldCount]; reader.GetValues(values); explainPlanDatas.Add(values.ToList()); } explainPlan.ExplainPlanDatas = explainPlanDatas; } } return(explainPlan); }
public ExplainPlanWireModel(ExplainPlan explainPlan) { _explainPlan = explainPlan; }