Fixing an issue with output parameters that are of type IntPtr
[castle.git] / ActiveRecord / Castle.ActiveRecord / Framework / Config / InPlaceConfigurationSource.cs
blob50ca515d2d11ab1bc0ebbcd3ac968a880a989902
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.ActiveRecord.Framework.Config
17 using System;
18 using System.Collections.Generic;
19 using System.Configuration;
20 using System.Text.RegularExpressions;
21 using Castle.ActiveRecord.Framework.Scopes;
22 using Castle.Core.Configuration;
24 /// <summary>
25 /// Enum for database types support for configuration construction.
26 /// Not to be confused by databases supported by ActiveRecord
27 /// </summary>
28 public enum DatabaseType
30 /// <summary>
31 /// Microsoft SQL Server 2005
32 /// </summary>
33 MSSQLServer2005,
34 /// <summary>
35 /// Microsoft SQL Server 2000
36 /// </summary>
37 MSSQLServer2000
40 /// <summary>
41 /// Usefull for test cases.
42 /// </summary>
43 public class InPlaceConfigurationSource : IConfigurationSource
45 private readonly IDictionary<Type, IConfiguration> _type2Config = new Dictionary<Type, IConfiguration>();
46 private Type threadScopeInfoImplementation;
47 private Type sessionFactoryHolderImplementation;
48 private Type namingStrategyImplementation;
49 private bool debug;
50 private bool isLazyByDefault;
51 private bool pluralizeTableNames;
52 private bool verifyModelsAgainstDBSchema;
54 /// <summary>
55 /// Initializes a new instance of the <see cref="InPlaceConfigurationSource"/> class.
56 /// </summary>
57 public InPlaceConfigurationSource()
61 #region IConfigurationSource Members
63 /// <summary>
64 /// Return a type that implements
65 /// the interface <see cref="IThreadScopeInfo"/>
66 /// </summary>
67 /// <value></value>
68 public Type ThreadScopeInfoImplementation
70 get { return threadScopeInfoImplementation; }
71 set { threadScopeInfoImplementation = value; }
74 /// <summary>
75 /// Return a type that implements
76 /// the interface <see cref="ISessionFactoryHolder"/>
77 /// </summary>
78 /// <value></value>
79 public Type SessionFactoryHolderImplementation
81 get { return sessionFactoryHolderImplementation; }
82 set { sessionFactoryHolderImplementation = value; }
85 /// <summary>
86 /// Return a type that implements
87 /// the interface NHibernate.Cfg.INamingStrategy
88 /// </summary>
89 /// <value></value>
90 public Type NamingStrategyImplementation
92 get { return namingStrategyImplementation; }
93 set { namingStrategyImplementation = value; }
96 /// <summary>
97 /// Return an <see cref="IConfiguration"/> for the specified type.
98 /// </summary>
99 /// <param name="type"></param>
100 /// <returns></returns>
101 public IConfiguration GetConfiguration(Type type)
103 IConfiguration configuration;
104 _type2Config.TryGetValue(type, out configuration);
105 return configuration;
108 /// <summary>
109 /// Gets a value indicating whether this <see cref="IConfigurationSource"/> produce debug information
110 /// </summary>
111 /// <value><c>true</c> if debug; otherwise, <c>false</c>.</value>
112 public bool Debug
114 get { return debug; }
117 /// <summary>
118 /// Gets a value indicating whether the entities should be lazy by default.
119 /// </summary>
120 /// <value>
121 /// <c>true</c> if entities should be lazy by default; otherwise, <c>false</c>.
122 /// </value>
123 public bool IsLazyByDefault
125 get { return isLazyByDefault; }
128 /// <summary>
129 /// Gets a value indicating whether table names are assumed plural by default.
130 /// </summary>
131 /// <value>
132 /// <c>true</c> if table names should be pluralized by default; otherwise, <c>false</c>.
133 /// </value>
134 public bool PluralizeTableNames
136 get { return pluralizeTableNames; }
137 set { pluralizeTableNames = value; }
140 /// <summary>
141 /// Gets or Sets a value indicating whether the models should be verified against the db schema on Initialisation.
142 /// </summary>
143 /// <value>
144 /// <c>true</c> if models should be verified; otherwise, <c>false</c>.
145 /// </value>
146 public bool VerifyModelsAgainstDBSchema
148 get { return verifyModelsAgainstDBSchema; }
149 set { verifyModelsAgainstDBSchema = value; }
152 #endregion
154 /// <summary>
155 /// Builds a InPlaceConfigurationSource set up to access a MS SQL server database using integrated security.
156 /// </summary>
157 /// <param name="server">The server.</param>
158 /// <param name="initialCatalog">The initial catalog.</param>
159 /// <returns></returns>
160 public static InPlaceConfigurationSource BuildForMSSqlServer(string server, string initialCatalog)
162 if (string.IsNullOrEmpty(server)) throw new ArgumentNullException("server");
163 if (string.IsNullOrEmpty(initialCatalog)) throw new ArgumentNullException("initialCatalog");
165 return Build(DatabaseType.MSSQLServer2005, "Server=" + server + ";initial catalog=" + initialCatalog + ";Integrated Security=SSPI");
168 /// <summary>
169 /// Builds a InPlaceConfigurationSource set up to access a MS SQL server database using the specified username and password.
170 /// </summary>
171 /// <param name="server">The server.</param>
172 /// <param name="initialCatalog">The initial catalog.</param>
173 /// <param name="username">The username.</param>
174 /// <param name="password">The password.</param>
175 /// <returns></returns>
176 public static InPlaceConfigurationSource BuildForMSSqlServer(string server, string initialCatalog, string username, string password)
178 if (string.IsNullOrEmpty(server)) throw new ArgumentNullException("server");
179 if (string.IsNullOrEmpty(initialCatalog)) throw new ArgumentNullException("initialCatalog");
180 if (string.IsNullOrEmpty(username)) throw new ArgumentNullException("username");
181 if (string.IsNullOrEmpty(password)) throw new ArgumentNullException("password");
183 return Build(DatabaseType.MSSQLServer2005, "Server=" + server + ";initial catalog=" + initialCatalog + ";User id=" + username + ";password=" + password);
186 /// <summary>
187 /// Builds an InPlaceConfiguratioSource for the specified database.
188 /// </summary>
189 /// <param name="database">The database.</param>
190 /// <param name="connectionString">The connection string.</param>
191 /// <returns></returns>
192 public static InPlaceConfigurationSource Build(DatabaseType database, string connectionString)
194 if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException("connectionString");
196 InPlaceConfigurationSource config = new InPlaceConfigurationSource();
198 Dictionary<string,string> parameters = new Dictionary<string,string>();
199 parameters["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";
200 parameters["cache.use_second_level_cache"] = "false";
202 if (database == DatabaseType.MSSQLServer2000)
204 parameters["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver";
205 parameters["dialect"] = "NHibernate.Dialect.MsSql2000Dialect";
206 parameters["connection.connection_string"] = connectionString;
208 else if (database == DatabaseType.MSSQLServer2005)
210 parameters["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver";
211 parameters["dialect"] = "NHibernate.Dialect.MsSql2005Dialect";
212 parameters["connection.connection_string"] = connectionString;
215 config.Add(typeof(ActiveRecordBase), parameters);
217 return config;
220 /// <summary>
221 /// Sets a value indicating whether this instance is running in web app.
222 /// </summary>
223 /// <value>
224 /// <c>true</c> if this instance is running in web app; otherwise, <c>false</c>.
225 /// </value>
226 public bool IsRunningInWebApp
228 set { SetUpThreadInfoType(value, null); }
231 /// <summary>
232 /// Adds the specified type with the properties
233 /// </summary>
234 /// <param name="type">The type.</param>
235 /// <param name="properties">The properties.</param>
236 public void Add(Type type, IDictionary<string,string> properties)
238 Add(type, ConvertToConfiguration(properties));
241 /// <summary>
242 /// Adds the specified type with configuration
243 /// </summary>
244 /// <param name="type">The type.</param>
245 /// <param name="config">The config.</param>
246 public void Add(Type type, IConfiguration config)
248 ProcessConfiguration(config);
250 _type2Config[type] = config;
253 /// <summary>
254 /// Sets the type of the thread info.
255 /// </summary>
256 /// <param name="isWeb">if we run in a web context or not</param>
257 /// <param name="customType">Type of the custom implementation</param>
258 protected void SetUpThreadInfoType(bool isWeb, String customType)
260 Type threadInfoType = null;
262 if (isWeb)
264 threadInfoType = typeof(WebThreadScopeInfo);
267 if (customType != null && customType != String.Empty)
269 String typeName = customType;
271 threadInfoType = Type.GetType(typeName, false, false);
273 if (threadInfoType == null)
275 String message = String.Format("The type name {0} could not be found", typeName);
277 throw new ActiveRecordException(message);
281 ThreadScopeInfoImplementation = threadInfoType;
284 /// <summary>
285 /// Sets the type of the session factory holder.
286 /// </summary>
287 /// <param name="customType">Custom implementation</param>
288 protected void SetUpSessionFactoryHolderType(String customType)
290 Type sessionFactoryHolderType = typeof(SessionFactoryHolder);
292 if (customType != null && customType != String.Empty)
294 String typeName = customType;
296 sessionFactoryHolderType = Type.GetType(typeName, false, false);
298 if (sessionFactoryHolderType == null)
300 String message = String.Format("The type name {0} could not be found", typeName);
302 throw new ActiveRecordException(message);
306 SessionFactoryHolderImplementation = sessionFactoryHolderType;
309 /// <summary>
310 /// Sets the type of the naming strategy.
311 /// </summary>
312 /// <param name="customType">Custom implementation type name</param>
313 protected void SetUpNamingStrategyType(String customType)
315 if (customType != null && customType != String.Empty)
317 String typeName = customType;
319 Type namingStrategyType = Type.GetType(typeName, false, false);
321 if (namingStrategyType == null)
323 String message = String.Format("The type name {0} could not be found", typeName);
325 throw new ActiveRecordException(message);
328 NamingStrategyImplementation = namingStrategyType;
332 /// <summary>
333 /// Sets the debug flag.
334 /// </summary>
335 /// <param name="isDebug">if set to <c>true</c> Active Record will produce debug information.</param>
336 protected void SetDebugFlag(bool isDebug)
338 debug = isDebug;
341 /// <summary>
342 /// Set whatever entities are lazy by default or not.
343 /// </summary>
344 protected void SetIsLazyByDefault(bool lazyByDefault)
346 isLazyByDefault = lazyByDefault;
349 /// <summary>
350 /// Sets the debug flag.
351 /// </summary>
352 /// <param name="verifyModelsAgainstDBSchema">if set to <c>true</c> Active Record will verify the models against the db schema on startup.</param>
353 protected void SetVerifyModelsAgainstDBSchema(bool verifyModelsAgainstDBSchema)
355 this.verifyModelsAgainstDBSchema = verifyModelsAgainstDBSchema;
358 /// <summary>
359 /// Sets the pluralizeTableNames flag.
360 /// </summary>
361 /// <param name="pluralize">if set to <c>true</c> Active Record will pluralize inferred table names.</param>
362 protected void SetPluralizeTableNames(bool pluralize)
364 pluralizeTableNames = pluralize;
367 private static IConfiguration ConvertToConfiguration(IDictionary<string,string> properties)
369 MutableConfiguration conf = new MutableConfiguration("Config");
371 foreach(KeyValuePair<string,string> entry in properties)
373 conf.Children.Add(new MutableConfiguration(entry.Key, entry.Value));
376 return conf;
379 /// <summary>
380 /// Processes the configuration applying any substitutions.
381 /// </summary>
382 /// <param name="config">The configuration</param>
383 private static void ProcessConfiguration(IConfiguration config)
385 const string ConnectionStringKey = "connection.connection_string";
387 for(int i = 0; i < config.Children.Count; ++i)
389 IConfiguration property = config.Children[i];
391 if (property.Name.IndexOf(ConnectionStringKey) >= 0)
393 String value = property.Value;
394 Regex connectionStringRegex = new Regex(@"ConnectionString\s*=\s*\$\{(?<ConnectionStringName>[^}]+)\}");
396 if (connectionStringRegex.IsMatch(value))
398 string connectionStringName = connectionStringRegex.Match(value).
399 Groups["ConnectionStringName"].Value;
400 value = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
401 config.Children[i] = new MutableConfiguration(property.Name, value);