Update of /cvsroot/springnet/Spring.Net/src/Spring/Spring.Data.NHibernate20/Data/NHibernate
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv30699
Modified Files:
LocalSessionFactoryObject.cs
Log Message:
Added support for schema create, drop and update
Index: LocalSessionFactoryObject.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Data.NHibernate20/Data/NHibernate/LocalSessionFactoryObject.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** LocalSessionFactoryObject.cs 7 Apr 2008 20:12:53 -0000 1.1
--- LocalSessionFactoryObject.cs 1 May 2008 12:50:34 -0000 1.2
***************
*** 25,37 ****
--- 25,42 ----
using System.Collections.Generic;
using System.Data;
+ using System.Data.Common;
+
using Common.Logging;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Connection;
+ using NHibernate.Dialect;
using NHibernate.Engine;
using NHibernate.Event;
+ using NHibernate.Tool.hbm2ddl;
using Spring.Core.IO;
using Spring.Data.Common;
+ using Spring.Data.Support;
using Spring.Objects.Factory;
***************
*** 86,89 ****
--- 91,96 ----
private IDictionary eventListeners;
+ private bool schemaUpdate = false;
+
#endregion
***************
*** 242,245 ****
--- 249,265 ----
}
+ /// <summary>
+ /// Set whether to execute a schema update after SessionFactory initialization.
+ /// <p>
+ /// For details on how to make schema update scripts work, see the NHibernate
+ /// documentation, as this class leverages the same schema update script support
+ /// in <see cref="Configuration" /> as NHibernate's own SchemaUpdate tool.
+ /// </p>
+ /// </summary>
+ public bool SchemaUpdate
+ {
+ set { schemaUpdate = value; }
+ }
+
#endregion
***************
*** 305,309 ****
// Can be overridden by a custom value for the corresponding Hibernate property
config.SetProperty(Environment.CurrentSessionContextClass,
! "Spring.Data.NHibernate.SpringSessionContext, Spring.Data.NHibernate12");
}
--- 325,329 ----
// Can be overridden by a custom value for the corresponding Hibernate property
config.SetProperty(Environment.CurrentSessionContextClass,
! "Spring.Data.NHibernate.SpringSessionContext, Spring.Data.NHibernate20");
}
***************
*** 407,411 ****
this.sessionFactory = NewSessionFactory(config);
!
}
--- 427,431 ----
this.sessionFactory = NewSessionFactory(config);
! AfterSessionFactoryCreation();
}
***************
*** 457,460 ****
--- 477,642 ----
/// <summary>
+ /// Executes schema update if requested.
+ /// </summary>
+ protected virtual void AfterSessionFactoryCreation()
+ {
+ if (this.schemaUpdate)
+ {
+ UpdateDatabaseSchema();
+ }
+ }
+
+ /// <summary>
+ /// Execute schema drop script, determined by the Configuration object
+ /// used for creating the SessionFactory. A replacement for NHibernate's
+ /// SchemaExport class, to be invoked on application setup.
+ /// </summary>
+ /// <remarks>
+ /// Fetch the LocalSessionFactoryBean itself rather than the exposed
+ /// SessionFactory to be able to invoke this method, e.g. via
+ /// <code>LocalSessionFactoryObject lsfb = (LocalSessionFactoryObject) ctx.GetObject("mySessionFactory");</code>.
+ /// <p>
+ /// Uses the SessionFactory that this bean generates for accessing a ADO.NET
+ /// connection to perform the script.
+ /// </p>
+ /// </remarks>
+ public void DropDatabaseSchema()
+ {
+ log.Info("Dropping database schema for NHibernate SessionFactory");
+ HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
+ hibernateTemplate.Execute(
+ new HibernateDelegate(delegate(ISession session)
+ {
+ IDbConnection con = session.Connection;
+ Dialect dialect = Dialect.GetDialect(Configuration.Properties);
+ string[] sql = Configuration.GenerateDropSchemaScript(dialect);
+ ExecuteSchemaScript(con, sql);
+ return null;
+ }));
+
+ }
+
+ /// <summary>
+ /// Execute schema creation script, determined by the Configuration object
+ /// used for creating the SessionFactory. A replacement for NHibernate's
+ /// SchemaExport class, to be invoked on application setup.
+ /// </summary>
+ /// <remarks>
+ /// Fetch the LocalSessionFactoryObject itself rather than the exposed
+ /// SessionFactory to be able to invoke this method, e.g. via
+ /// <code>LocalSessionFactoryObject lsfo = (LocalSessionFactoryObject) ctx.GetObject("mySessionFactory");</code>.
+ /// <p>
+ /// Uses the SessionFactory that this bean generates for accessing a ADO.NET
+ /// connection to perform the script.
+ /// </p>
+ /// </remarks>
+ public void CreateDatabaseSchema()
+ {
+ log.Info("Creating database schema for Hibernate SessionFactory");
+ HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
+ hibernateTemplate.Execute(
+ new HibernateDelegate(delegate (ISession session)
+ {
+ IDbConnection con = session.Connection;
+ Dialect dialect = Dialect.GetDialect(Configuration.Properties);
+ string[] sql = Configuration.GenerateSchemaCreationScript(dialect);
+ ExecuteSchemaScript(con, sql);
+ return null;
+
+ }));
+ }
+
+ /// <summary>
+ /// Execute schema update script, determined by the Configuration object
+ /// used for creating the SessionFactory. A replacement for NHibernate's
+ /// SchemaUpdate class, for automatically executing schema update scripts
+ /// on application startup. Can also be invoked manually.
+ /// </summary>
+ /// <remarks>
+ /// Fetch the LocalSessionFactoryObject itself rather than the exposed
+ /// SessionFactory to be able to invoke this method, e.g. via
+ /// <code>LocalSessionFactoryObject lsfo = (LocalSessionFactoryObject) ctx.GetObject("mySessionFactory");</code>.
+ /// <p>
+ /// Uses the SessionFactory that this bean generates for accessing a ADO.NET
+ /// connection to perform the script.
+ /// </p>
+ /// </remarks>
+ public virtual void UpdateDatabaseSchema()
+ {
+ log.Info("Updating database schema for Hibernate SessionFactory");
+ HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
+ hibernateTemplate.TemplateFlushMode = TemplateFlushMode.Never;
+ hibernateTemplate.Execute(
+ new HibernateDelegate(delegate(ISession session)
+ {
+ IDbConnection con = session.Connection;
+ Dialect dialect = Dialect.GetDialect(Configuration.Properties);
+ DatabaseMetadata metadata = new DatabaseMetadata((DbConnection) con, dialect);
+ string[] sql = Configuration.GenerateSchemaUpdateScript(dialect, metadata);
+ ExecuteSchemaScript(con, sql);
+ return null;
+ }));
+ }
+
+
+ /// <summary>
+ /// Execute the given schema script on the given ADO.NET Connection.
+ /// </summary>
+ /// <remarks>
+ /// Note that the default implementation will log unsuccessful statements
+ /// and continue to execute. Override the <code>ExecuteSchemaStatement</code>
+ /// method to treat failures differently.
+ /// </remarks>
+ /// <param name="con">The connection to use.</param>
+ /// <param name="sql">The SQL statement to execute.</param>
+ protected virtual void ExecuteSchemaScript(IDbConnection con, string[] sql)
+ {
+ if (sql != null && sql.Length > 0)
+ {
+ IDbCommand cmd = con.CreateCommand();
+ try
+ {
+ for (int i = 0; i < sql.Length; i++)
+ {
+ ExecuteSchemaStatement(cmd, sql[i]);
+ }
+ }
+ finally
+ {
+ AdoUtils.DisposeCommand(cmd);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Execute the given schema SQL on the given ADO.NET command.
+ /// </summary>
+ /// <remarks>
+ /// Note that the default implementation will log unsuccessful statements
+ /// and continue to execute. Override this method to treat failures differently.
+ /// </remarks>
+ /// <param name="cmd"></param>
+ /// <param name="sql"></param>
+ protected virtual void ExecuteSchemaStatement(IDbCommand cmd, string sql)
+ {
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("Executing schema statement: " + sql);
+ }
+ try
+ {
+ cmd.CommandText = sql;
+ cmd.ExecuteNonQuery();
+ }
+ catch (ADOException ex)
+ {
+ if (log.IsWarnEnabled)
+ {
+ log.Warn("Unsuccessful schema statement: " + sql, ex);
+ }
+ }
+ }
+
+ /// <summary>
/// Subclasses can override this method to perform custom initialization
/// of the SessionFactory instance, creating it via the given Configuration
|