private async void loginButton_Click(object sender, EventArgs e) { var agent = this.sqlAgentsComboBox.SelectedValue as SqlAgentBase; if (agent == null) { MessageBox.Show("Agent type not specified.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (agent.IsFileBased && databaseTextBox.Text.IsNullOrWhiteSpace()) { MessageBox.Show("Database file not specified.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); } try { ISqlDictionary dictionary = null; if (this.useSqlRepositoryCheckBox.Checked) { dictionary = new SqlDictionary(this.sqlRepositoryFolderTextBox.Text, true); } _agent = (SqlAgentBase)Activator.CreateInstance(agent.GetType(), this.connectionStringTextBox.Text, this.databaseTextBox.Text, dictionary, null); await _agent.TestConnectionAsync(); } catch (Exception ex) { MessageBox.Show(ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } this.DialogResult = DialogResult.OK; this.Close(); }
private static SqlDictionary <string, string> CreateDictionary(out IDictionary <string, string> inner) { inner = new Dictionary <string, string>(); inner.Add("key1", "value1"); var server = new FakeSqlServer <string, string>(inner); var dic = new SqlDictionary <string, string>(server); dic.Load("SOMECONNECTIONSTRING", "SOMETABLE", "Key", "Value"); return(dic); }
//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="component">The build component that owns the dictionary. This is useful for logging /// messages during initialization.</param> /// <param name="configuration">The target dictionary configuration</param> /// <param name="connectionString">The connection string to use</param> /// <param name="groupId">The group ID to use</param> /// <param name="localCacheSize">The local cache size to use</param> /// <param name="reload">True to reload the cache or false to leave it alone. This is used to reload /// project data so that it is always current.</param> /// <returns>A target dictionary instance that uses a simple in-memory /// <see cref="Dictionary{TKey, TValue}"/> instance to store the targets.</returns> public SqlTargetDictionary(BuildComponentCore component, XPathNavigator configuration, string connectionString, string groupId, int localCacheSize, bool reload) : base(component, configuration) { this.connectionString = connectionString; base.DictionaryId = groupId; index = new SqlDictionary <Target>(connectionString, "Targets", "TargetKey", "TargetValue", "GroupId", groupId) { LocalCacheSize = localCacheSize }; int filesToLoad = 0; if (reload) { filesToLoad = Directory.EnumerateFiles(this.DirectoryPath, this.FilePattern, this.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Count(); } else { foreach (string file in Directory.EnumerateFiles(this.DirectoryPath, this.FilePattern, this.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { if ((this.NamespaceFileFilter.Count == 0 || this.NamespaceFileFilter.Contains( Path.GetFileName(file))) && !this.ContainsKey("N:" + Path.GetFileNameWithoutExtension(file))) { filesToLoad++; } } } // Loading new targets can take a while so issue a diagnostic message as an alert. The time estimate // is a ballpark figure and depends on the system. if (filesToLoad != 0) { component.WriteMessage(MessageLevel.Diagnostic, "{0} file(s) need to be added to the SQL " + "reflection target cache database. Indexing them will take about {1:N0} minute(s), " + "please be patient. Cache location: {2}", filesToLoad, Math.Ceiling(filesToLoad / 60.0), connectionString); this.LoadTargetDictionary(); } }
public static SqlDictionary LoadDefaultSqlDictionary() { var dict = new SqlDictionary(); var assembly = Assembly.GetExecutingAssembly(); var types = assembly.GetTypes().Where(t=>t.GetInterfaces().Contains(typeof(ISymbolRegister))); foreach(Type type in types) { var register = (ISymbolRegister)Activator.CreateInstance(type); var sqlMakers = new Dictionary<string,ISqlMaker>(); register.RegistSQL(sqlMakers); dict[register.dbType] = sqlMakers; } if (App.CustomSqlRegister !=null) App.CustomSqlRegister(dict); return dict; }
//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="component">The build component that owns the dictionary. This is useful for logging /// messages during initialization.</param> /// <param name="configuration">The target dictionary configuration</param> /// <param name="connectionString">The connection string to use</param> /// <param name="groupId">The group ID to use</param> /// <param name="localCacheSize">The local cache size to use</param> /// <param name="reload">True to reload the cache or false to leave it alone. This is used to reload /// project data so that it is always current.</param> /// <returns>A target dictionary instance that uses a simple in-memory /// <see cref="Dictionary{TKey, TValue}"/> instance to store the targets.</returns> public SqlTargetDictionary(BuildComponentCore component, XPathNavigator configuration, string connectionString, string groupId, int localCacheSize, bool reload) : base(component, configuration) { this.connectionString = connectionString; base.DictionaryId = groupId; index = new SqlDictionary<Target>(connectionString, "Targets", "TargetKey", "TargetValue", "GroupId", groupId) { LocalCacheSize = localCacheSize }; int filesToLoad = 0; if(reload) { filesToLoad = Directory.EnumerateFiles(this.DirectoryPath, this.FilePattern, this.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Count(); } else foreach(string file in Directory.EnumerateFiles(this.DirectoryPath, this.FilePattern, this.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) if((this.NamespaceFileFilter.Count == 0 || this.NamespaceFileFilter.Contains( Path.GetFileName(file))) && !this.ContainsKey("N:" + Path.GetFileNameWithoutExtension(file))) filesToLoad++; // Loading new targets can take a while so issue a diagnostic message as an alert. The time estimate // is a ballpark figure and depends on the system. if(filesToLoad != 0) { component.WriteMessage(MessageLevel.Diagnostic, "{0} file(s) need to be added to the SQL " + "reflection target cache database. Indexing them will take about {1:N0} minute(s), " + "please be patient. Cache location: {2}", filesToLoad, Math.Ceiling(filesToLoad / 60.0), connectionString); this.LoadTargetDictionary(); } }
static void Main(string[] args) { string connectionString = null; string tableName = null; string keyName = null; string valueName = null; var parser = new Fclp.FluentCommandLineParser(); parser.Setup <string>('c', "connectionString").Callback(x => connectionString = x); parser.Setup <string>('t', "tableName").Callback(x => tableName = x); parser.Setup <string>('k', "key").Callback(x => keyName = x); parser.Setup <string>('v', "value").Callback(x => valueName = x); parser.Parse(args); Console.WriteLine("Connecting..."); var dic1 = new SqlDictionary <int, int>(); dic1.Load(connectionString, "intint", keyName, valueName); Console.WriteLine("SqlDictionary.Clear"); dic1.Clear(); Console.WriteLine("dic1.Count == 0"); Debug.Assert(dic1.Count == 0); dic1.Add(1, 2); Console.WriteLine("dic1.Count == 1"); Debug.Assert(dic1.Count == 1); Console.WriteLine("dic1[1] == 2"); Debug.Assert(dic1[1] == 2); dic1.Remove(1); Console.WriteLine("dic1.Count == 0"); Debug.Assert(dic1.Count == 0); dic1[1] = 3; Console.WriteLine("dic1[1] == 3"); Debug.Assert(dic1[1] == 3); dic1[1] = 4; Console.WriteLine("dic1[1] == 4"); Debug.Assert(dic1[1] == 4); var dic2 = new SqlDictionary <int, string>(); dic2.Load(connectionString, "intstring", keyName, valueName); dic2.Clear(); dic2.Add(1, "2"); dic2.Remove(1); dic2[1] = "3"; dic2[1] = "4"; var dic3 = new SqlDictionary <string, string>(); dic3.Load(connectionString, "stringstring", keyName, valueName); dic3.Clear(); dic3.Add("1", "2"); dic3.Remove("1"); dic3["1"] = "3"; dic3["1"] = "4"; var dic4 = new SqlDictionary <string, SomeDto>(); dic4.Load(connectionString, "stringdto", keyName, valueName); dic4.Clear(); dic4.Add("1", new SomeDto() { Id = 1, Name = "SomeName" }); dic4.Remove("1"); dic4["1"] = new SomeDto() { Id = 2, Name = "SomeName" }; dic4["1"] = new SomeDto() { Id = 3, Name = "SomeName" }; var dic5 = new SqlNoMemoryDictionary <int, int>(); dic5.Prepare(connectionString, "lazyintint", keyName, valueName); dic5.Clear(); dic5.Add(1, 2); dic5.Remove(1); dic5[1] = 3; dic5[1] = 4; Console.WriteLine("OK!"); }
//===================================================================== /// <summary> /// This is used to create the index cache /// </summary> /// <param name="configuration">The configuration to use</param> private SqlDictionary<string> CreateCache(XPathNavigator configuration) { SqlDictionary<string> cache = null; HashSet<string> namespaceFileFilter = new HashSet<string>(); string groupId, connectionString, baseDirectory, wildcardPath, recurseValue, dupWarning, fullPath, directoryPart, filePart; bool recurse, reportDuplicateIds, cacheProject, isProjectData = false; int localCacheSize, filesToLoad; var parent = configuration.Clone(); parent.MoveToParent(); connectionString = parent.GetAttribute("connectionString", String.Empty); groupId = configuration.GetAttribute("groupId", String.Empty); // If caching project data, they will all go into a common index if(groupId.StartsWith("Project_", StringComparison.OrdinalIgnoreCase)) isProjectData = true; cache = sqlCaches.FirstOrDefault(c => c.GroupId == groupId); if(cache == null) { if(!Boolean.TryParse(parent.GetAttribute("cacheProject", String.Empty), out cacheProject)) cacheProject = false; if((isProjectData && !cacheProject) || String.IsNullOrWhiteSpace(connectionString)) return null; string cacheSize = configuration.GetAttribute("localCacheSize", String.Empty); if(String.IsNullOrWhiteSpace(cacheSize) || !Int32.TryParse(cacheSize, out localCacheSize)) localCacheSize = 2500; cache = new SqlDictionary<string>(connectionString, "IndexData", "IndexKey", "IndexValue", "GroupId", groupId) { LocalCacheSize = localCacheSize }; } baseDirectory = configuration.GetAttribute("base", String.Empty); if(!String.IsNullOrWhiteSpace(baseDirectory)) baseDirectory = Environment.ExpandEnvironmentVariables(baseDirectory); wildcardPath = configuration.GetAttribute("files", String.Empty); if(String.IsNullOrWhiteSpace(wildcardPath)) base.Component.WriteMessage(MessageLevel.Error, "Each data element must have a files attribute " + "specifying which files to index."); wildcardPath = Environment.ExpandEnvironmentVariables(wildcardPath); recurseValue = configuration.GetAttribute("recurse", String.Empty); if(String.IsNullOrWhiteSpace(recurseValue) || !Boolean.TryParse(recurseValue, out recurse)) recurse = false; // Support suppression of duplicate ID warnings. This can happen a lot when common classes appear in // multiple assemblies. dupWarning = configuration.GetAttribute("duplicateWarning", String.Empty); if(String.IsNullOrWhiteSpace(dupWarning) || !Boolean.TryParse(dupWarning, out reportDuplicateIds)) reportDuplicateIds = true; if(String.IsNullOrEmpty(baseDirectory)) fullPath = wildcardPath; else { // Verify that the directory exists if(!Directory.Exists(baseDirectory)) throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The targets " + "directory '{0}' does not exist. The configuration is most likely out of date. " + "Please delete this component from the project, add it back, and reconfigure it.", baseDirectory), "configuration"); fullPath = Path.Combine(baseDirectory, wildcardPath); } fullPath = Environment.ExpandEnvironmentVariables(fullPath); directoryPart = Path.GetDirectoryName(fullPath); if(String.IsNullOrEmpty(directoryPart)) directoryPart = Environment.CurrentDirectory; filePart = Path.GetFileName(fullPath); // Filtering reduces the number of files to load, especially for the core reflection data files namespaceFileFilter.Clear(); foreach(XPathNavigator filter in configuration.Select("namespace/@file")) namespaceFileFilter.Add(filter.Value); // Loading new targets can take a while so issue a diagnostic message as an alert filesToLoad = 0; if(namespaceFileFilter.Count != 0) { // Reflection data can be filtered by namespace so some or all of it may already be there foreach(string file in Directory.EnumerateFiles(directoryPart, filePart, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) if((namespaceFileFilter.Count == 0 || namespaceFileFilter.Contains(Path.GetFileName(file))) && !cache.ContainsKey("N:" + Path.GetFileNameWithoutExtension(file))) filesToLoad++; } else { // Comments files can't be filtered by namespace so we'll assume that if the collection is not // empty, it has already been loaded unless it's a project comments file list. In that case, // we will merge them if necessary. if(isProjectData || cache.Count == 0) filesToLoad = Directory.EnumerateFiles(directoryPart, filePart, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Count(); } if(filesToLoad != 0) { // The time estimate is a ballpark figure and depends on the system base.Component.WriteMessage(MessageLevel.Diagnostic, "{0} file(s) need to be added to the SQL " + "index cache database. Indexing them will take about {1:N0} minute(s), please be " + "patient. Group ID: {2} Cache location: {3}", filesToLoad, Math.Ceiling(filesToLoad / 60.0), groupId, connectionString); Parallel.ForEach(Directory.EnumerateFiles(directoryPart, filePart, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly), file => { // Skip the file if not in a defined filter if(namespaceFileFilter.Count != 0 && !namespaceFileFilter.Contains(Path.GetFileName(file))) return; base.Component.WriteMessage(MessageLevel.Info, "Indexing targets in {0}", file); using(SqlConnection cn = new SqlConnection(connectionString)) using(SqlCommand cmdSearch = new SqlCommand()) using(SqlCommand cmdAdd = new SqlCommand()) { cn.Open(); cmdSearch.Connection = cmdAdd.Connection = cn; cmdSearch.CommandText = String.Format(CultureInfo.InvariantCulture, "Select IndexKey From IndexData Where GroupId = '{0}' And IndexKey = @key", groupId); cmdSearch.Parameters.Add(new SqlParameter("@key", SqlDbType.VarChar, 768)); cmdAdd.CommandText = String.Format(CultureInfo.InvariantCulture, "IF NOT EXISTS(Select * From IndexData Where GroupId = '{0}' And IndexKey = @key) " + "Insert IndexData (GroupId, IndexKey, IndexValue) Values('{0}', @key, @value) " + "ELSE " + "Update IndexData Set IndexValue = @value Where GroupId = '{0}' And IndexKey = @key", groupId); cmdAdd.Parameters.Add(new SqlParameter("@key", SqlDbType.VarChar, 768)); cmdAdd.Parameters.Add(new SqlParameter("@value", SqlDbType.Text)); // Get the keys from the file and add them to the index foreach(var kv in base.GetValues(file)) { cmdSearch.Parameters[0].Value = cmdAdd.Parameters[0].Value = kv.Key; // Only report the warning if wanted if(cmdSearch.ExecuteScalar() != null && reportDuplicateIds) this.Component.WriteMessage(MessageLevel.Warn, "An entry for the key '{0}' " + "already exists and will be replaced by the one from '{1}'", kv.Key, file); cmdAdd.Parameters[1].Value = kv.Value.InnerXml; cmdAdd.ExecuteNonQuery(); } } }); } return cache; }
//===================================================================== /// <summary> /// This is used to create the index cache /// </summary> /// <param name="configuration">The configuration to use</param> private SqlDictionary <string> CreateCache(XPathNavigator configuration) { SqlDictionary <string> cache = null; HashSet <string> namespaceFileFilter = new HashSet <string>(); string groupId, connectionString, baseDirectory, wildcardPath, recurseValue, dupWarning, fullPath, directoryPart, filePart; bool recurse, reportDuplicateIds, cacheProject, isProjectData = false; int localCacheSize, filesToLoad; var parent = configuration.Clone(); parent.MoveToParent(); connectionString = parent.GetAttribute("connectionString", String.Empty); groupId = configuration.GetAttribute("groupId", String.Empty); // If caching project data, they will all go into a common index if (groupId.StartsWith("Project_", StringComparison.OrdinalIgnoreCase)) { isProjectData = true; } cache = sqlCaches.FirstOrDefault(c => c.GroupId == groupId); if (cache == null) { if (!Boolean.TryParse(parent.GetAttribute("cacheProject", String.Empty), out cacheProject)) { cacheProject = false; } if ((isProjectData && !cacheProject) || String.IsNullOrWhiteSpace(connectionString)) { return(null); } string cacheSize = configuration.GetAttribute("localCacheSize", String.Empty); if (String.IsNullOrWhiteSpace(cacheSize) || !Int32.TryParse(cacheSize, out localCacheSize)) { localCacheSize = 2500; } cache = new SqlDictionary <string>(connectionString, "IndexData", "IndexKey", "IndexValue", "GroupId", groupId) { LocalCacheSize = localCacheSize }; } baseDirectory = configuration.GetAttribute("base", String.Empty); if (!String.IsNullOrWhiteSpace(baseDirectory)) { baseDirectory = Environment.ExpandEnvironmentVariables(baseDirectory); } wildcardPath = configuration.GetAttribute("files", String.Empty); if (String.IsNullOrWhiteSpace(wildcardPath)) { base.Component.WriteMessage(MessageLevel.Error, "Each data element must have a files attribute " + "specifying which files to index."); } wildcardPath = Environment.ExpandEnvironmentVariables(wildcardPath); recurseValue = configuration.GetAttribute("recurse", String.Empty); if (String.IsNullOrWhiteSpace(recurseValue) || !Boolean.TryParse(recurseValue, out recurse)) { recurse = false; } // Support suppression of duplicate ID warnings. This can happen a lot when common classes appear in // multiple assemblies. dupWarning = configuration.GetAttribute("duplicateWarning", String.Empty); if (String.IsNullOrWhiteSpace(dupWarning) || !Boolean.TryParse(dupWarning, out reportDuplicateIds)) { reportDuplicateIds = true; } if (String.IsNullOrEmpty(baseDirectory)) { fullPath = wildcardPath; } else { // Verify that the directory exists if (!Directory.Exists(baseDirectory)) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The targets " + "directory '{0}' does not exist. The configuration is most likely out of date. " + "Please delete this component from the project, add it back, and reconfigure it.", baseDirectory), "configuration"); } fullPath = Path.Combine(baseDirectory, wildcardPath); } fullPath = Environment.ExpandEnvironmentVariables(fullPath); directoryPart = Path.GetDirectoryName(fullPath); if (String.IsNullOrEmpty(directoryPart)) { directoryPart = Environment.CurrentDirectory; } filePart = Path.GetFileName(fullPath); // Filtering reduces the number of files to load, especially for the core reflection data files namespaceFileFilter.Clear(); foreach (XPathNavigator filter in configuration.Select("namespace/@file")) { namespaceFileFilter.Add(filter.Value); } // Loading new targets can take a while so issue a diagnostic message as an alert filesToLoad = 0; if (namespaceFileFilter.Count != 0) { // Reflection data can be filtered by namespace so some or all of it may already be there foreach (string file in Directory.EnumerateFiles(directoryPart, filePart, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { if ((namespaceFileFilter.Count == 0 || namespaceFileFilter.Contains(Path.GetFileName(file))) && !cache.ContainsKey("N:" + Path.GetFileNameWithoutExtension(file))) { filesToLoad++; } } } else { // Comments files can't be filtered by namespace so we'll assume that if the collection is not // empty, it has already been loaded unless it's a project comments file list. In that case, // we will merge them if necessary. if (isProjectData || cache.Count == 0) { filesToLoad = Directory.EnumerateFiles(directoryPart, filePart, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Count(); } } if (filesToLoad != 0) { // The time estimate is a ballpark figure and depends on the system base.Component.WriteMessage(MessageLevel.Diagnostic, "{0} file(s) need to be added to the SQL " + "index cache database. Indexing them will take about {1:N0} minute(s), please be " + "patient. Group ID: {2} Cache location: {3}", filesToLoad, Math.Ceiling(filesToLoad / 60.0), groupId, connectionString); Parallel.ForEach(Directory.EnumerateFiles(directoryPart, filePart, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly), file => { // Skip the file if not in a defined filter if (namespaceFileFilter.Count != 0 && !namespaceFileFilter.Contains(Path.GetFileName(file))) { return; } base.Component.WriteMessage(MessageLevel.Info, "Indexing targets in {0}", file); using (SqlConnection cn = new SqlConnection(connectionString)) using (SqlCommand cmdSearch = new SqlCommand()) using (SqlCommand cmdAdd = new SqlCommand()) { cn.Open(); cmdSearch.Connection = cmdAdd.Connection = cn; cmdSearch.CommandText = String.Format(CultureInfo.InvariantCulture, "Select IndexKey From IndexData Where GroupId = '{0}' And IndexKey = @key", groupId); cmdSearch.Parameters.Add(new SqlParameter("@key", SqlDbType.VarChar, 768)); cmdAdd.CommandText = String.Format(CultureInfo.InvariantCulture, "IF NOT EXISTS(Select * From IndexData Where GroupId = '{0}' And IndexKey = @key) " + "Insert IndexData (GroupId, IndexKey, IndexValue) Values('{0}', @key, @value) " + "ELSE " + "Update IndexData Set IndexValue = @value Where GroupId = '{0}' And IndexKey = @key", groupId); cmdAdd.Parameters.Add(new SqlParameter("@key", SqlDbType.VarChar, 768)); cmdAdd.Parameters.Add(new SqlParameter("@value", SqlDbType.Text)); // Get the keys from the file and add them to the index foreach (var kv in base.GetValues(file)) { cmdSearch.Parameters[0].Value = cmdAdd.Parameters[0].Value = kv.Key; // Only report the warning if wanted if (cmdSearch.ExecuteScalar() != null && reportDuplicateIds) { this.Component.WriteMessage(MessageLevel.Warn, "An entry for the key '{0}' " + "already exists and will be replaced by the one from '{1}'", kv.Key, file); } cmdAdd.Parameters[1].Value = kv.Value.InnerXml; cmdAdd.ExecuteNonQuery(); } } }); } return(cache); }