PageRenderTime 53ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/wojilu/Data/DbConfig.cs

https://bitbucket.org/kingshine/wojilu
C# | 309 lines | 146 code | 75 blank | 88 comment | 19 complexity | 321ebd8a4504c0349e096dafbed6f832 MD5 | raw file
Possible License(s): MIT
  1. /*
  2. * Copyright 2010 www.wojilu.com
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Text;
  19. using wojilu.ORM;
  20. using wojilu.Reflection;
  21. using wojilu.Serialization;
  22. using wojilu.Web;
  23. using System.IO;
  24. using System.Web;
  25. using wojilu.IO;
  26. namespace wojilu.Data {
  27. /// <summary>
  28. /// 数据库连接字符串内容的封装
  29. /// </summary>
  30. public class ConnectionString {
  31. public String Name { get; set; }
  32. public String StringContent { get; set; }
  33. public DatabaseType DbType { get; set; }
  34. }
  35. /// <summary>
  36. /// ORM 的数据库配置
  37. /// </summary>
  38. public class DbConfig {
  39. private static readonly ILog logger = LogManager.GetLogger( typeof( DbConfig ) );
  40. public DbConfig() {
  41. this.ConnectionStringTable = new Dictionary<String, object>();
  42. this.AssemblyList = new List<object>();
  43. this.DbType = new Dictionary<String, object>();
  44. this.Interceptor = new List<object>();
  45. this.IsCheckDatabase = true;
  46. this.ContextCache = true;
  47. this.Mapping = new List<object>();
  48. }
  49. /// <summary>
  50. /// 默认数据库名称(值为default)
  51. /// </summary>
  52. public static readonly String DefaultDbName = "default";
  53. /// <summary>
  54. /// 配置的缓存内容(单例模式缓存)
  55. /// </summary>
  56. public static DbConfig Instance = loadConfig( getConfigPath() );
  57. /// <summary>
  58. /// 直接解析json的结果:多个数据库连接字符串(connectionString)的键值对
  59. /// </summary>
  60. public Dictionary<String, object> ConnectionStringTable { get; set; }
  61. private Dictionary<String, ConnectionString> _connectionStringMap = new Dictionary<String, ConnectionString>();
  62. /// <summary>
  63. /// 多个数据库连接字符串对象的map,值是ConnectionString对象(包括Name/StringContent/DbType)
  64. /// </summary>
  65. /// <returns></returns>
  66. public Dictionary<String, ConnectionString> GetConnectionStringMap() {
  67. return _connectionStringMap;
  68. }
  69. internal void SetConnectionStringMap( Dictionary<String, ConnectionString> cmap ) {
  70. _connectionStringMap = cmap;
  71. }
  72. /// <summary>
  73. /// 直接解析json的结果:数据库类型
  74. /// </summary>
  75. public Dictionary<String, object> DbType { get; set; }
  76. /// <summary>
  77. /// 直接解析json的结果:程序集列表
  78. /// </summary>
  79. public List<object> AssemblyList { get; set; }
  80. /// <summary>
  81. /// 是否坚持数据库,如果检查,则会将尚未创建的数据表自动创建
  82. /// </summary>
  83. public Boolean IsCheckDatabase { get; set; }
  84. /// <summary>
  85. /// 数据表的前缀(默认没有前缀)
  86. /// </summary>
  87. public String TablePrefix { get; set; }
  88. /// <summary>
  89. /// 是否开启一级缓存,默认开启,并且建议开启
  90. /// </summary>
  91. public Boolean ContextCache { get; set; }
  92. /// <summary>
  93. /// 是否开启二级缓存
  94. /// </summary>
  95. public Boolean ApplicationCache { get; set; }
  96. /// <summary>
  97. /// 二级缓存的时间(分钟)
  98. /// </summary>
  99. public int ApplicationCacheMinutes { get; set; }
  100. /// <summary>
  101. /// 二级缓存管理程序,请填写类型(type)的全名(full name),比如 wojilu.somens.myCache;
  102. /// 如果不填写,则使用默认的System.Web.Caching
  103. /// </summary>
  104. public String ApplicationCacheManager { get; set; }
  105. /// <summary>
  106. /// ORM 的元数据文件名称,一般不需填写(建议不要填写)。如果为了提高网站启动时候的速度,可以填写。
  107. /// 系统会根据文件名自动生成元数据文件,可以避免以后网站启动过程中的反射,能略微提高启动速度;
  108. /// 文件名不包括路径(必须放在bin目录中),比如 wojilu.meta.dll
  109. /// </summary>
  110. public String MetaDLL { get; set; }
  111. /// <summary>
  112. /// 直接解析json的结果:数据表映射
  113. /// </summary>
  114. public List<object> Mapping { get; set; }
  115. /// <summary>
  116. /// 拦截器列表
  117. /// </summary>
  118. public List<object> Interceptor { get; set; }
  119. /// <summary>
  120. /// 反射优化模式,目前只实现了 CodeDom 方式
  121. /// </summary>
  122. [NotSerialize]
  123. internal OptimizeMode OptimizeMode {
  124. get { return OptimizeMode.CodeDom; }
  125. set { }
  126. }
  127. /// <summary>
  128. /// 获取元数据库文件的绝对路径
  129. /// </summary>
  130. /// <returns></returns>
  131. public String GetMetaDllAbsPath() {
  132. if (strUtil.IsNullOrEmpty( this.MetaDLL )) return "";
  133. String dllPath = this.MetaDLL;
  134. if (dllPath.ToLower().EndsWith( ".dll" ) == false)
  135. dllPath = dllPath + ".dll";
  136. dllPath = Path.Combine( PathTool.GetBinDirectory(), dllPath );
  137. return dllPath;
  138. }
  139. private Dictionary<String, MappingInfo> _mappings = new Dictionary<String, MappingInfo>();
  140. private void addMapping( MappingInfo mi ) {
  141. _mappings.Add( mi.TypeName, mi );
  142. }
  143. /// <summary>
  144. /// 获取映射信息
  145. /// </summary>
  146. /// <returns></returns>
  147. internal Dictionary<String, MappingInfo> GetMappingInfo() {
  148. return _mappings;
  149. }
  150. //----------------------------------------------------------------------
  151. private static DbConfig loadConfig( String cfgPath ) {
  152. String str = file.Read( cfgPath );
  153. DbConfig dbc = JSON.ToObject<DbConfig>( str );
  154. loadMappingInfo( dbc );
  155. checkConnectionString( dbc );
  156. return dbc;
  157. }
  158. private static void loadMappingInfo( DbConfig dbc ) {
  159. if (dbc.Mapping.Count == 0) return;
  160. foreach (Dictionary<String, object> dic in dbc.Mapping) {
  161. MappingInfo mi = new MappingInfo();
  162. if (dic.ContainsKey( "name" )) mi.TypeName = dic["name"].ToString();
  163. if (dic.ContainsKey( "database" )) mi.Database = dic["database"].ToString();
  164. if (dic.ContainsKey( "table" )) mi.Table = dic["table"].ToString();
  165. dbc.addMapping( mi );
  166. }
  167. }
  168. private static String getConfigPath() {
  169. return PathHelper.Map( strUtil.Join( cfgHelper.ConfigRoot, "orm.config" ) );
  170. }
  171. private static void checkConnectionString( DbConfig result ) {
  172. logger.Info( "checkConnectionString..." );
  173. if (result.ConnectionStringTable == null) return;
  174. Dictionary<String, ConnectionString> connStringMap = new Dictionary<String, ConnectionString>();
  175. Dictionary<String, String> newString = new Dictionary<string, string>();
  176. foreach (KeyValuePair<String, object> kv in result.ConnectionStringTable) {
  177. String connectionString = kv.Value.ToString();
  178. DatabaseType dbtype = getDbType( kv.Key, connectionString, result );
  179. ConnectionString objConnString = new ConnectionString {
  180. Name = kv.Key,
  181. StringContent = connectionString,
  182. DbType = dbtype
  183. };
  184. connStringMap.Add( kv.Key, objConnString );
  185. logger.Info( "connectionString:" + connectionString );
  186. IDatabaseDialect dialect = DataFactory.GetDialect( dbtype );
  187. if ((dbtype == DatabaseType.Access)) {
  188. String connectionItem = dialect.GetConnectionItem( connectionString, ConnectionItemType.Database );
  189. logger.Info( "database path original:" + connectionItem );
  190. if (IsRelativePath( connectionItem )) {
  191. connectionItem = PathHelper.Map( strUtil.Join( SystemInfo.ApplicationPath, connectionItem ) );
  192. logger.Info( "database path now:" + connectionItem );
  193. String newConnString = String.Format( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", connectionItem );
  194. newString.Add( kv.Key, newConnString );
  195. }
  196. }
  197. }
  198. foreach (KeyValuePair<String, String> kv in newString) {
  199. result.ConnectionStringTable[kv.Key] = kv.Value;
  200. connStringMap[kv.Key].StringContent = kv.Value;
  201. }
  202. result.SetConnectionStringMap( connStringMap );
  203. }
  204. private static bool IsRelativePath( string connectionItem ) {
  205. return connectionItem.IndexOf( ":" ) < 0;
  206. }
  207. private static DatabaseType getDbType( String dbname, String connectionString, DbConfig result ) {
  208. foreach (KeyValuePair<String, Object> kv in result.DbType) {
  209. if (kv.Key == dbname) return DbTypeChecker.GetFromString( kv.Value.ToString() );
  210. }
  211. DatabaseType dbtype = DbTypeChecker.GetDatabaseType( connectionString );
  212. return dbtype;
  213. }
  214. //----------------------------------------------------------------------
  215. /// <summary>
  216. /// 根据命名,获取数据库连接字符串
  217. /// </summary>
  218. /// <param name="db"></param>
  219. /// <returns></returns>
  220. public static String GetConnectionString( String db ) {
  221. if (DbConfig.Instance.ConnectionStringTable.ContainsKey( db ) == false)
  222. throw new Exception( lang.get( "dbNotExist" ) + ": " + db );
  223. return (String)DbConfig.Instance.ConnectionStringTable[db];
  224. }
  225. internal static void SaveConnectionString( String connectionString ) {
  226. String cfgPath = getConfigPath();
  227. if (DbConfig.Instance.ConnectionStringTable == null)
  228. DbConfig.Instance.ConnectionStringTable = new Dictionary<String, object>();
  229. DbConfig.Instance.ConnectionStringTable[DefaultDbName] = connectionString;
  230. String str = JsonString.ConvertObject( DbConfig.Instance, true );
  231. file.Write( cfgPath, str );
  232. }
  233. }
  234. }