#region Using directives

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.OracleClient;
using System.Data.OleDb;
using System.Data.Odbc;
using System.Configuration;

#endregion

namespace VSGeneric
{
	enum provider {sqlserver, oracle, oledb, odbc};

	class Program
	{
		static void Main(string[] args)
		{
			Program p = new Program();
			//p.GetConnectionBaseClass();
			p.RewriteConnectionStringAndUpdateConfigFile(DbProviderFactories.GetFactory("System.Data.SqlClient"), "MyOtherServer", "Pubs");
		}

		public provider GetProviderFromConfigFile()
		{
			//return SQL Server for now...
			return provider.sqlserver;
		}

		public IDbConnection GetConnectionInterface()
		{
			// determine provider from configuration
			provider prov = GetProviderFromConfigFile();
			IDbConnection conn = null;
			switch (prov)
			{
				case provider.sqlserver:
					conn = new SqlConnection(); break;
				case provider.oracle:
					conn = new OracleConnection(); break;
				// add new providers as the application supports them
			}
			return conn;
		}


		public DbConnection GetConnectionBaseClass()
		{
			// determine provider from configuration
			provider prov = GetProviderFromConfigFile();
			DbConnection conn = null;
			switch (prov)
			{
				case provider.sqlserver:
					conn = new SqlConnection(); break;
				case provider.oracle:
					conn = new OracleConnection(); break;
					// add new providers as the application supports them
			}
				return conn;
		}

		public DbConnection GetConnectionBaseClass2()
		{
      DbProviderFactory f = GetProviderFactoryFromUserInput();
      // call provider factory-specific CreateConnection
      return f.CreateConnection();
		}

		public DbProviderFactory GetProviderFactoryFromUserInput()
		{
			DataTable t = DbProviderFactories.GetFactoryClasses();
			DataRow r;
			// user selects a DataRow r from DataTable t
			r = t.Rows[0];
			return DbProviderFactories.GetFactory(r);
		}

		public DbConnection GetInitializedConnectionBaseClass()
		{
      DbConnection conn = null;
      ConnectionStringSettings s =
        ConfigurationManager.ConnectionStrings["Publications"];
      DbProviderFactory f = DbProviderFactories.GetFactory(
        s.ProviderName);
      conn = f.CreateConnection();
      conn.ConnectionString = s.ConnectionString;
      return conn;
		}

		public void ChangeDataSourceOrProvider()
		{
      // see this method in the example above
      DbProviderFactory f = GetProviderFactoryFromUserInput();
      // if our factory supports creating a DbConnection, return it.
      if (f.CanCreateDataSourceEnumerator)
      {
        DbDataSourceEnumerator e = f.CreateDataSourceEnumerator();
        DataTable t = e.GetDataSources();
        // code elided, user chooses a Data Row selected_row
        int selected_row = 0;
        DataRow r = t.Rows[selected_row];
        string dataSource = (string)r["ServerName"];
        if (r["InstanceName"] != null)
          dataSource += ("\\" + r["InstanceName"]);
        // this method is defined below
        RewriteConnectionStringAndUpdateConfigFile(f, dataSource, "Pubs");
      }
      else
        Console.WriteLine("Source must be changed manually");
		}

    public void RewriteConnectionStringAndUpdateConfigFile(DbProviderFactory f, string dataSource, string name)
		{
      Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

			DbConnectionStringBuilder b = f.CreateConnectionStringBuilder();
			b.ConnectionString = config.ConnectionStrings.ConnectionStrings[name].ConnectionString;
			if (b.ContainsKey("Data Source"))
			{
				b.Remove("Data Source");
				b.Add("Data Source", dataSource);

				// Update ConfigurationSettings connection string
				config.ConnectionStrings.ConnectionStrings[name].ConnectionString = b.ConnectionString;
        config.Save(ConfigurationSaveMode.Modified);

			}
		}

	}
}
