1 #region MIT license
2 //
3 // MIT license
4 //
5 // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 // THE SOFTWARE.
24 //
25 #endregion
26 
27 using System;
28 using System.Collections.Generic;
29 using System.Configuration;
30 using System.Data;
31 using System.IO;
32 using System.Reflection;
33 using DbLinq.Util;
34 using DbLinq.Vendor;
35 using DbMetal.Configuration;
36 
37 namespace DbMetal.Generator.Implementation
38 {
39 #if !MONO_STRICT
40     public
41 #endif
42     class SchemaLoaderFactory : ISchemaLoaderFactory
43     {
44         private TextWriter log;
45         /// <summary>
46         /// Log output
47         /// </summary>
48         public TextWriter Log
49         {
50             get { return log ?? Console.Out; }
51             set { log = value; }
52         }
53 
54         /// <summary>
55         /// the 'main entry point' into this class
56         /// </summary>
Load(Parameters parameters)57         public ISchemaLoader Load(Parameters parameters)
58         {
59             string dbLinqSchemaLoaderType;
60             string databaseConnectionType;
61             string sqlDialectType;
62             GetLoaderAndConnection(parameters, out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType);
63             return Load(parameters, dbLinqSchemaLoaderType, databaseConnectionType, sqlDialectType);
64         }
65 
66         /// <summary>
67         /// given a schemaLoaderType and dbConnType
68         /// (e.g. DbLinq.Oracle.OracleSchemaLoader and System.Data.OracleClient.OracleConnection),
69         /// return an instance of the OracleSchemaLoader.
70         /// </summary>
Load(Parameters parameters, Type dbLinqSchemaLoaderType, Type databaseConnectionType, Type sqlDialectType)71         public ISchemaLoader Load(Parameters parameters, Type dbLinqSchemaLoaderType, Type databaseConnectionType, Type sqlDialectType)
72         {
73             if (dbLinqSchemaLoaderType == null)
74                 throw new ArgumentNullException("dbLinqSchemaLoaderType");
75             if (databaseConnectionType == null)
76                 throw new ArgumentNullException("databaseConnectionType");
77 
78             string errorMsg = "";
79             try
80             {
81                 errorMsg = "Failed on Activator.CreateInstance(" + dbLinqSchemaLoaderType.Name + ")";
82                 var loader = (ISchemaLoader)Activator.CreateInstance(dbLinqSchemaLoaderType);
83                 // set log output
84                 loader.Log = Log;
85 
86                 errorMsg = "Failed on Activator.CreateInstance(" + databaseConnectionType.Name + ")";
87                 var connection = (IDbConnection)Activator.CreateInstance(databaseConnectionType);
88 
89                 IVendor vendor = null;
90                 if (sqlDialectType != null)
91                 {
92                     errorMsg = "Failed on Activator.CreateInstance(" + sqlDialectType.Name + ")";
93                     vendor = (IVendor)Activator.CreateInstance(sqlDialectType);
94                     loader.Vendor = vendor;
95                 }
96 
97                 if (parameters != null)
98                 {
99                     string connectionString = parameters.Conn;
100                     if (string.IsNullOrEmpty(connectionString))
101                         connectionString = loader.Vendor.BuildConnectionString(parameters.Server, parameters.Database,
102                                                                                parameters.User, parameters.Password);
103                     errorMsg = "Failed on setting ConnectionString=" + connectionString;
104                     connection.ConnectionString = connectionString;
105                 }
106 
107                 errorMsg = "";
108                 loader.Connection = connection;
109                 return loader;
110             }
111             catch (Exception ex)
112             {
113                 //see Pascal's comment on this failure:
114                 //http://groups.google.com/group/dblinq/browse_thread/thread/b7a29138435b0678
115                 Output.WriteErrorLine(Log, "LoaderFactory.Load(schemaType=" + dbLinqSchemaLoaderType.Name + ", dbConnType=" + databaseConnectionType.Name + ")");
116                 if (errorMsg != "")
117                     Output.WriteErrorLine(Log, errorMsg);
118                 Output.WriteErrorLine(Log, "LoaderFactory.Load() failed: " + ex.Message);
119                 throw;
120             }
121         }
122 
Load(Parameters parameters, string dbLinqSchemaLoaderTypeName, string databaseConnectionTypeName, string sqlDialectTypeName)123         public ISchemaLoader Load(Parameters parameters, string dbLinqSchemaLoaderTypeName, string databaseConnectionTypeName, string sqlDialectTypeName)
124         {
125             Type dbLinqSchemaLoaderType = Type.GetType(dbLinqSchemaLoaderTypeName);
126             Type databaseConnectionType = Type.GetType(databaseConnectionTypeName);
127             Type sqlDialectType         = string.IsNullOrEmpty(sqlDialectTypeName) ? null : Type.GetType(sqlDialectTypeName);
128 
129             if (dbLinqSchemaLoaderType == null)
130                 throw new ArgumentException("Could not load dbLinqSchemaLoaderType type '" + dbLinqSchemaLoaderTypeName + "'.  Try using the --with-schema-loader=TYPE option.");
131             if (databaseConnectionType == null)
132                 throw new ArgumentException("Could not load databaseConnectionType type '" + databaseConnectionTypeName + "'.  Try using the --with-dbconnection=TYPE option.");
133 
134             ISchemaLoader loader = Load(parameters, dbLinqSchemaLoaderType, databaseConnectionType, sqlDialectType);
135             return loader;
136         }
137 
GetLoaderAndConnection(string provider, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType)138         private void GetLoaderAndConnection(string provider, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType)
139         {
140             var configuration = (ProvidersSection)ConfigurationManager.GetSection("providers");
141 
142             ProvidersSection.ProviderElement element;
143             string errorMsg = null;
144             if (configuration == null || !configuration.Providers.TryGetProvider(provider, out element, out errorMsg))
145             {
146                 throw new ApplicationException(string.Format("Failed to load provider {0}: {1}", provider, errorMsg));
147             }
148 
149             //var element = configuration.Providers.GetProvider(provider);
150             //databaseConnectionType = types[1].Trim();
151             dbLinqSchemaLoaderType = element.DbLinqSchemaLoader;
152             databaseConnectionType = element.DatabaseConnection;
153             sqlDialectType         = element.SqlDialectType;
154         }
155 
GetLoaderAndConnection(Parameters parameters, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType)156         protected void GetLoaderAndConnection(Parameters parameters, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType)
157         {
158             dbLinqSchemaLoaderType = databaseConnectionType = sqlDialectType = null;
159 
160             if (!string.IsNullOrEmpty(parameters.Provider))
161             {
162                 GetLoaderAndConnection(parameters.Provider, out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType);
163             }
164             else if (!string.IsNullOrEmpty(parameters.DbLinqSchemaLoaderProvider) &&
165                 !string.IsNullOrEmpty(parameters.DatabaseConnectionProvider) &&
166                 !string.IsNullOrEmpty(parameters.SqlDialectType))
167             {
168                 // User manually specified everything we need; don't bother with the
169                 // default .exe.config provider lookup
170             }
171             else
172             {
173                 // No provider specified, not explicitly provided either
174                 // Default to using SQL Server for sqlmetal.exe compatibility
175                 GetLoaderAndConnection("SqlServer", out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType);
176             }
177 
178             // Allow command-line options to override the .exe.config file.
179             if (!string.IsNullOrEmpty(parameters.DbLinqSchemaLoaderProvider))
180                 dbLinqSchemaLoaderType = parameters.DbLinqSchemaLoaderProvider;
181             if (!string.IsNullOrEmpty(parameters.DatabaseConnectionProvider))
182                 databaseConnectionType = parameters.DatabaseConnectionProvider;
183             if (!string.IsNullOrEmpty(parameters.SqlDialectType))
184                 sqlDialectType = parameters.SqlDialectType;
185         }
186 
187     }
188 }
189