From: Michael D. <mik...@us...> - 2004-10-29 05:58:21
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Cfg In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17342/NHibernate/Cfg Modified Files: Binder.cs Configuration.cs Environment.cs Mappings.cs Added Files: Settings.cs SettingsFactory.cs Log Message: NH-90 : code for a pluggable cache. Added a Settings class and removed some old hibernate properties that don't apply to .net. Index: Mappings.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Cfg/Mappings.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Mappings.cs 22 Aug 2004 06:24:26 -0000 1.8 --- Mappings.cs 29 Oct 2004 05:58:06 -0000 1.9 *************** *** 1,4 **** --- 1,6 ---- using System; using System.Collections; + + using NHibernate.Cache; using NHibernate.Mapping; *************** *** 8,11 **** --- 10,14 ---- /// A collection of mappings from classes and collections to relational database tables. /// </summary> + /// <remarks>Represents a single <c><hibernate-mapping></c> element.</remarks> public class Mappings { *************** *** 22,27 **** private bool autoImport; private string defaultAccess; ! internal Mappings(IDictionary classes, IDictionary collections, IDictionary tables, IDictionary queries, IDictionary imports, IList secondPasses) { this.classes = classes; --- 25,31 ---- private bool autoImport; private string defaultAccess; + private IDictionary caches; ! internal Mappings(IDictionary classes, IDictionary collections, IDictionary tables, IDictionary queries, IDictionary imports, IDictionary caches, IList secondPasses) { this.classes = classes; *************** *** 30,36 **** --- 34,57 ---- this.tables = tables; this.imports = imports; + this.caches = caches; this.secondPasses = secondPasses; } + /// <summary> + /// Associates the class name with the cache strategy. + /// </summary> + /// <param name="name">The classname of the class to cache.</param> + /// <param name="cache">The <see cref="ICacheConcurrencyStrategy"/> to use for caching.</param> + /// <exception cref="MappingException">Thrown when <c>name</c> already has a <c>cache</c> associated with it.</exception> + public void AddCache(string name, ICacheConcurrencyStrategy cache) + { + object old = caches[ name ]; + if( old!=null ) + { + throw new MappingException( "duplicate cache region" ); + } + caches[ name ] = cache; + } + public void AddClass(PersistentClass persistentClass) { Index: Binder.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Cfg/Binder.cs,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** Binder.cs 14 Oct 2004 04:33:13 -0000 1.32 --- Binder.cs 29 Oct 2004 05:58:06 -0000 1.33 *************** *** 4,7 **** --- 4,8 ---- using System.Xml; + using NHibernate.Cache; using NHibernate.Engine; using NHibernate.Loader; *************** *** 11,17 **** using NHibernate.Util; ! namespace NHibernate.Cfg { ! ! internal class Binder { private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Binder)); --- 12,19 ---- using NHibernate.Util; ! namespace NHibernate.Cfg ! { ! internal class Binder ! { private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Binder)); *************** *** 275,282 **** case "jcs-cache": ! model.Cache = Configuration.CreateCache( ! subnode.Attributes["usage"].Value, ! model.PersistentClazz.Name, ! model ); break; --- 277,284 ---- case "jcs-cache": ! string className = model.PersistentClazz.FullName; ! ICacheConcurrencyStrategy cache = CacheFactory.CreateCache( subnode, className, model.IsMutable ); ! mappings.AddCache( className, cache ); ! model.Cache = cache; break; *************** *** 1132,1139 **** else if ( "jcs-cache".Equals(name) ) { ! model.Cache = Configuration.CreateCache( ! subnode.Attributes["usage"].Value, ! model.Role, ! model.Owner ); } } --- 1134,1144 ---- else if ( "jcs-cache".Equals(name) ) { ! ICacheConcurrencyStrategy cache = CacheFactory.CreateCache( subnode, model.Role, model.Owner.IsMutable ); ! mappings.AddCache( model.Role, cache ); ! model.Cache = cache; ! // model.Cache = Configuration.CreateCache( ! // subnode.Attributes["usage"].Value, ! // model.Role, ! // model.Owner ); } } Index: Configuration.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Cfg/Configuration.cs,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** Configuration.cs 28 Sep 2004 01:08:40 -0000 1.21 --- Configuration.cs 29 Oct 2004 05:58:06 -0000 1.22 *************** *** 43,46 **** --- 43,47 ---- private IInterceptor interceptor = EmptyInterceptor; private IDictionary properties = Environment.Properties; + private IDictionary caches = new Hashtable(); private XmlSchema mappingSchema; *************** *** 208,212 **** public Mappings CreateMappings() { ! return new Mappings(classes, collections, tables, namedQueries, imports, secondPasses); } --- 209,213 ---- public Mappings CreateMappings() { ! return new Mappings(classes, collections, tables, namedQueries, imports, caches, secondPasses); } *************** *** 608,612 **** copy.Add(de.Key, de.Value); } ! return new SessionFactoryImpl(this, copy, interceptor); } --- 609,626 ---- copy.Add(de.Key, de.Value); } ! ! Settings settings = BuildSettings(); ! ConfigureCaches( settings ); ! ! return new SessionFactoryImpl( this, copy, interceptor, settings ); ! } ! ! /// <summary> ! /// Builds an object-oriented view of the settings. ! /// </summary> ! /// <returns>A <see cref="Settings"/> object initialized from the settings properties.</returns> ! protected Settings BuildSettings() ! { ! return SettingsFactory.BuildSettings( properties ); } *************** *** 800,823 **** } ! public static ICacheConcurrencyStrategy CreateCache(string usage, string name, PersistentClass owner) { ! log.Info("creating cache region: " + name + ", usage: " + usage); ! ICache cache = new HashtableCache(name); ! switch (usage) { ! case "read-only": ! if (owner.IsMutable) log.Warn("read-only cache configured for mutable: " + name); ! return new ReadOnlyCache(cache); ! ! case "read-write": ! return new ReadWriteCache(cache); ! ! case "nonstrict-read-write": ! return new NonstrictReadWriteCache(cache); ! ! default: ! throw new MappingException("jcs-cache usage attribute should be read-only, read-write, or nonstrict-read-write only"); } --- 814,845 ---- } ! //TODO: make properties a Settings class ! protected void ConfigureCaches(Settings settings) { ! log.Info( "instantiating and configuring caches" ); ! // TODO: add ability to configure cache_region_prefix ! foreach( DictionaryEntry de in caches ) { ! string name = (string)de.Key; ! ICacheConcurrencyStrategy strategy = (ICacheConcurrencyStrategy)de.Value; ! ! if( log.IsDebugEnabled ) ! { ! log.Debug( "instantiating cache " + name ); ! } ! ! ICache cache; ! try ! { ! cache = settings.CacheProvider.BuildCache( name, properties ); ! } ! catch( CacheException ce ) ! { ! throw new HibernateException( "Could not instantiate Cache", ce ); ! } ! ! strategy.Cache = cache; } Index: Environment.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Cfg/Environment.cs,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** Environment.cs 24 Sep 2004 03:31:25 -0000 1.19 --- Environment.cs 29 Oct 2004 05:58:06 -0000 1.20 *************** *** 46,64 **** public const string QuerySubstitutions = "hibernate.query.substitutions"; public const string QueryImports = "hibernate.query.imports"; - // MikeD added these while synching up SessionFactoryImpl. Not sure if they have any ado.net - // equivalents - we can probably remove these and remove the SessionFactoryImpl code that - // uses them. - [Obsolete("Removing ConnectionPool from NH")] - public const string PoolSize = "hibernate.connection.pool_size"; - public const string StatementBatchSize = "hibernate.jdbc.batch_size"; - public const string StatementFetchSize = "hibernate.jdbc.fetch_size"; - public const string UseScrollableResultSet = "hibernate.jdbc.use_scrollable_resultset"; - - // going to remove this - the DataProvider should implement their own IDbCommand - // caching, not NHibernate - [Obsolete("Removing StatementCache from NH")] - public const string StatementCacheSize = "hibernate.statement_cache.size"; - static Environment() { --- 46,51 ---- public const string QuerySubstitutions = "hibernate.query.substitutions"; public const string QueryImports = "hibernate.query.imports"; + public const string CacheProvider = "hibernate.cache.provider_class"; static Environment() { --- NEW FILE: Settings.cs --- using System; using System.Collections; using System.Data; using NHibernate.Cache; using NHibernate.Connection; using NHibernate.Dialect; using NHibernate.Transaction; namespace NHibernate.Cfg { /// <summary> /// Settings that affect the behavior of NHibernate at runtime. /// </summary> public sealed class Settings { private bool _isShowSqlEnabled; private bool _isOuterJoinFetchEnabled; private IDictionary _querySubstitutions; private Dialect.Dialect _dialect; private IsolationLevel _isolationLevel; private IConnectionProvider _connectionProvider; private ITransactionFactory _transactionFactory; private string _sessionFactoryName; private ICacheProvider _cacheProvider; private string _defaultSchemaName; public bool IsShowSqlEnabled { get { return _isShowSqlEnabled; } set { _isShowSqlEnabled = value; } } public bool IsOuterJoinFetchEnabled { get { return _isOuterJoinFetchEnabled; } set { _isOuterJoinFetchEnabled = value; } } public IDictionary QuerySubstitutions { get { return _querySubstitutions; } set { _querySubstitutions = value; } } public Dialect.Dialect Dialect { get { return _dialect; } set { _dialect = value; } } // some other ones in here I don't think will be added public string DefaultSchemaName { get { return _defaultSchemaName; } set { _defaultSchemaName = value; } } public IsolationLevel IsolationLevel { get { return _isolationLevel; } set { _isolationLevel = value; } } public IConnectionProvider ConnectionProvider { get { return _connectionProvider; } set { _connectionProvider = value; } } public ITransactionFactory TransactionFactory { get { return _transactionFactory; } set { _transactionFactory = value; } } public string SessionFactoryName { get { return _sessionFactoryName; } set { _sessionFactoryName = value; } } public ICacheProvider CacheProvider { get { return _cacheProvider; } set { _cacheProvider = value; } } } } --- NEW FILE: SettingsFactory.cs --- using System; using System.Collections; using System.Data; using System.Text; using NHibernate.Cache; using NHibernate.Connection; using NHibernate.Dialect; using NHibernate.Transaction; using NHibernate.Util; namespace NHibernate.Cfg { /// <summary> /// Reads configuration properties and configures a <see cref="Settings"/> instance. /// </summary> public sealed class SettingsFactory { private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(SettingsFactory) ); private SettingsFactory() { //should not be publically creatable } public static Settings BuildSettings(IDictionary properties) { Settings settings = new Settings(); Dialect.Dialect dialect = null; try { dialect = Dialect.Dialect.GetDialect( properties ); IDictionary temp = new Hashtable(); foreach( DictionaryEntry de in dialect.DefaultProperties ) { temp[ de.Key ] = de.Value; } foreach( DictionaryEntry de in properties ) { temp[ de.Key ] = de.Value; } properties = temp; } catch( HibernateException he ) { log.Warn( "No dialect set - using GenericDialect: " + he.Message ); dialect = new GenericDialect(); } bool useOuterJoin = PropertiesHelper.GetBoolean(Cfg.Environment.OuterJoin, properties, true); log.Info( "use outer join fetching: " + useOuterJoin ); IConnectionProvider connectionProvider = ConnectionProviderFactory.NewConnectionProvider(properties); ITransactionFactory transactionFactory = new TransactionFactory(); //Transaction BuildTransactionFactory(properties); string isolationString = PropertiesHelper.GetString( Cfg.Environment.Isolation, properties, String.Empty ); IsolationLevel isolation = IsolationLevel.Unspecified; if( isolationString.Length > 0) { try { isolation = (IsolationLevel)Enum.Parse( typeof(IsolationLevel), isolationString ); log.Info( "Using Isolation Level: " + isolation.ToString() ); } catch( ArgumentException ae ) { log.Error( "error configuring IsolationLevel " + isolationString, ae ); throw new HibernateException( "The isolation level of " + isolationString + " is not a valid IsolationLevel. Please " + "use one of the Member Names from the IsolationLevel.", ae ); } } string defaultSchema = properties[Cfg.Environment.DefaultSchema] as string; if ( defaultSchema!=null) log.Info ("Default schema set to: " + defaultSchema); bool showSql = PropertiesHelper.GetBoolean( Cfg.Environment.ShowSql, properties, false ); if (showSql) log.Info("echoing all SQL to stdout"); // queries: IDictionary querySubstitutions = PropertiesHelper.ToDictionary( Cfg.Environment.QuerySubstitutions, " ,=;:\n\t\r\f", properties ); if ( log.IsInfoEnabled ) { StringBuilder sb = new StringBuilder("Query language substitutions: "); foreach(DictionaryEntry entry in querySubstitutions) { sb.AppendFormat("{0}={1};", entry.Key, entry.Value); } log.Info(sb.ToString()); } string cacheClassName = PropertiesHelper.GetString( Environment.CacheProvider, properties, "NHibernate.Cache.HashtableCacheProvider" ); ICacheProvider cacheProvider = null; log.Info( "cache provider: " + cacheClassName ); try { cacheProvider = (ICacheProvider) Activator.CreateInstance( ReflectHelper.ClassForName( cacheClassName ) ); } catch( Exception e ) { throw new HibernateException( "could not instantiate CacheProvider: " + cacheClassName, e ); } string sessionFactoryName = (string) properties[ Cfg.Environment.SessionFactoryName ]; settings.DefaultSchemaName = defaultSchema; settings.IsShowSqlEnabled = showSql; settings.Dialect = dialect; settings.IsolationLevel = isolation; settings.ConnectionProvider = connectionProvider; settings.QuerySubstitutions = querySubstitutions; settings.TransactionFactory = transactionFactory; settings.CacheProvider = cacheProvider; settings.SessionFactoryName = sessionFactoryName; settings.IsOuterJoinFetchEnabled = useOuterJoin; return settings; } } } |