public DatabaseResolver(IAssignmentGraphWalker assignmentGraphWalker, IAnalysisLogger analysisLogger, List <IDatabaseAccessDetector> databaseAccessDetectors, IDatabaseFinder databaseFinder) { _assignmentGraphWalker = assignmentGraphWalker; _analysisLogger = analysisLogger; _databaseAccessDetectors = databaseAccessDetectors; _databaseFinder = databaseFinder; }
public AnalysisEngine(IAssignmentGraphIndexer assignmentGraphIndexer, IAssignmentGraphWalker assignmentGraphWalker, IMethodIndexer methodIndexer, IDelegateIndexer delegateIndexer, ICallTreeWalker callTreeWalker, ITypeService typeService, ILogOutput logOutput) { _assignmentGraphIndexer = assignmentGraphIndexer; _assignmentGraphWalker = assignmentGraphWalker; _methodIndexer = methodIndexer; _delegateIndexer = delegateIndexer; _callTreeWalker = callTreeWalker; _typeService = typeService; _logOutput = logOutput; }
public string FindDatabaseName(TargetMethodMatch targetMethodMatch, MethodCall methodCall, MethodObject currentMethod, IAssignmentGraphWalker assignmentGraphWalker) { if (!_lastLoadedForApp.Equals(AnalysisScope.CurrentApplicationName)) { IndexAppConfig(); _lastLoadedForApp = AnalysisScope.CurrentApplicationName; } var assemblyName = currentMethod.GetMethodDefinition().Module.Assembly.Name.Name; // strategy 1 - if application accesses only one db, then choose that var appDbs = GetConnectionStrings(AnalysisScope.CurrentApplicationName); if (appDbs.Indexes.Count() == 1) { var indexedDb = appDbs.IndexValues.First(); return(indexedDb.First()); // TODO: if multiple app.configs contains the same db, then here you might want to choose which one you want } // strategy 2 - if the assembly has an app config with only 1 connection string var assDbs = GetConnectionStrings(assemblyName); if (assDbs.Indexes.Count() == 1) { var indexedDb = assDbs.IndexValues.First(); return(indexedDb.First()); // TODO: if multiple app.configs contains the same db, then here you might want to choose which one you want } // strategy 3 - if the database access is ADO.NET then use backtracking search to find the conn string name if (targetMethodMatch.AccessMode.IndexOf("ado.net", StringComparison.OrdinalIgnoreCase) > -1) { var matches = PerformAdoNetBacktrackingSearch(methodCall, assignmentGraphWalker); if (matches.Count == 1) { return(matches.First()); } } // strategy 4 - if EF then find the ctor of the context and do a backtracking search from there // TODO // there are multiple possible matches or none at all return("Unknown"); }
public DelegateIndexer(IAssignmentGraphWalker assignmentGraphWalker) { _assignmentGraphWalker = assignmentGraphWalker; CleanIndexes(); }
private List <string> PerformAdoNetBacktrackingSearch(MethodCall method, IAssignmentGraphWalker assignmentGraphWalker) { // these tell the backtracking search that it can follow the instantiation (ctor) of the below classes in its search var permittedGoToInstancePatterns = new List <GoToInstancePattern>(); permittedGoToInstancePatterns.Add(new GoToInstancePattern() { TypeMustHavePattern = "System.Data.Common.DbCommand", MemberMustNotHavePattern = ".ctor", TryInstance = TryInstance.First }); // ADO.NET permittedGoToInstancePatterns.Add(new GoToInstancePattern() { TypeMustHavePattern = "System.Data.SqlClient.SqlCommand", MemberMustNotHavePattern = ".ctor", TryInstance = TryInstance.First }); // ADO.NET permittedGoToInstancePatterns.Add(new GoToInstancePattern() { TypeMustHavePattern = "System.Data.Common.DbConnection", MemberMustNotHavePattern = ".ctor", TryInstance = TryInstance.First }); permittedGoToInstancePatterns.Add(new GoToInstancePattern() { TypeMustHavePattern = "System.Data.SqlClient.SqlConnection", MemberMustNotHavePattern = ".ctor", TryInstance = TryInstance.First }); permittedGoToInstancePatterns.Add(new GoToInstancePattern() { TypeMustHavePattern = "System.Data.SqlClient.SqlBulkCopy", MemberMustNotHavePattern = ".ctor", TryInstance = TryInstance.First }); // SqlBulkCopy // can be useful when using a library where you create derived classes var searchBaseConstructorPatterns = new List <string>(); var results = assignmentGraphWalker.PerformBacktrackingSearch(method.Instruction, method.OwnerMethod, _appConfigSourceDetector, permittedGoToInstancePatterns, searchBaseConstructorPatterns); var sources = new List <string>(); foreach (var result in results) { foreach (var node in result.FoundNodes) { if (node.Triple.To.ObjectKey.Equals("System.Configuration.ConfigurationManager.ConnectionStringSettingsCollection::[System.String]>>1")) { var dbsOfAssembly = GetConnectionStrings(node.Triple.ParentAssembly); var database = dbsOfAssembly.Get(node.Triple.From.ObjectKey).FirstOrDefault(); // TODO: if there is more than one that matches you might want to choose it here if (!string.IsNullOrEmpty(database)) { sources.Add(database); } else { var dbsOfApplication = GetConnectionStrings(AnalysisScope.CurrentApplicationName); database = dbsOfApplication.Get(node.Triple.From.ObjectKey).FirstOrDefault(); // TODO: if there is more than one that matches you might want to choose it here if (!string.IsNullOrEmpty(database)) { sources.Add(database); } } } else { // currently this finder only supports the ConnectionStringSettingsCollection } } } return(sources); }