示例#1
0
        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;
 }