Implement Derby shutdown policy
authorKonstantin Triger <kostat@mono-cvs.ximian.com>
Sun, 11 Mar 2007 11:54:31 +0000 (11:54 -0000)
committerKonstantin Triger <kostat@mono-cvs.ximian.com>
Sun, 11 Mar 2007 11:54:31 +0000 (11:54 -0000)
svn path=/trunk/mcs/; revision=74060

mcs/class/Mainsoft.Web/Mainsoft.Web.Profile/DerbyProfileProvider.cs
mcs/class/Mainsoft.Web/Mainsoft.Web.Security/DerbyDBSchema.cs
mcs/class/Mainsoft.Web/Mainsoft.Web.Security/DerbyMembershipProvider.cs
mcs/class/Mainsoft.Web/Mainsoft.Web.Security/DerbyRoleProvider.cs

index ed0727118f3fcfb6458a6a2bf7fd6587ba65bb9c..d5ad027e201175f96197b8cd6e2b606784bfffe5 100644 (file)
@@ -35,21 +35,22 @@ using System.Collections;
 using System.Configuration;\r
 using System.Globalization;\r
 using System.Web.Profile;\r
-using System.Web.Configuration;\r
-using System.Configuration.Provider;
+using System.Web.Configuration;
 using System.Collections.Specialized;\r
 using System.Text;\r
 using System.IO;\r
 \r
 using Mainsoft.Web.Security;\r
+using System.Configuration.Provider;\r
 \r
 namespace Mainsoft.Web.Profile
 {
        public class DerbyProfileProvider : ProfileProvider
        {\r
                ConnectionStringSettings _connectionString;\r
-               string _connectionStringName = string.Empty;\r
                string _applicationName = string.Empty;
+               bool _schemaChecked = false;\r
+               DerbyUnloadManager.DerbyShutDownPolicy _shutDownPolicy = DerbyUnloadManager.DerbyShutDownPolicy.Default;
 
                public DerbyProfileProvider ()
                {
@@ -63,10 +64,12 @@ namespace Mainsoft.Web.Profile
 \r
                DbConnection CreateConnection ()\r
                {\r
-                       if (_connectionString == null)\r
-                               throw new ProviderException (String.Format ("The connection name '{0}' was not found in the applications configuration or the connection string is empty.", _connectionStringName));\r
-                       \r
-                       DerbyDBSchema.CheckSchema (_connectionString.ConnectionString);\r
+                       if (!_schemaChecked) {\r
+                               DerbyDBSchema.CheckSchema (_connectionString.ConnectionString);\r
+                               _schemaChecked = true;\r
+\r
+                               DerbyUnloadManager.RegisterUnloadHandler (_connectionString.ConnectionString, _shutDownPolicy);\r
+                       }\r
 \r
                        OleDbConnection connection = new OleDbConnection (_connectionString.ConnectionString);\r
                        connection.Open ();\r
@@ -83,9 +86,9 @@ namespace Mainsoft.Web.Profile
                public override int DeleteProfiles (ProfileInfoCollection profiles)\r
                {\r
                        if (profiles == null)\r
-                               throw new ArgumentNullException ("prfoles");\r
+                               throw new ArgumentNullException ("profiles");\r
                        if (profiles.Count == 0)\r
-                               throw new ArgumentException ("prfoles");\r
+                               throw new ArgumentException ("profiles");\r
 \r
                        string [] usernames = new string [profiles.Count];\r
 \r
@@ -312,17 +315,14 @@ namespace Mainsoft.Web.Profile
                        _applicationName = GetStringConfigValue (config, "applicationName", "/");\r
 \r
                        ProfileSection profileSection = (ProfileSection) WebConfigurationManager.GetSection ("system.web/profile");\r
-                       _connectionStringName = config ["connectionStringName"];\r
-                       \r
-                       if (_applicationName.Length > 256)\r
-                               throw new ProviderException ("The ApplicationName attribute must be 256 characters long or less.");\r
-                       if (_connectionStringName == null || _connectionStringName.Length == 0)\r
-                               throw new ProviderException ("The ConnectionStringName attribute must be present and non-zero length.");
-\r
-                       _connectionString = WebConfigurationManager.ConnectionStrings [_connectionStringName];\r
+                       string connectionStringName = config ["connectionStringName"];\r
+                       _connectionString = WebConfigurationManager.ConnectionStrings [connectionStringName];\r
+                       if (_connectionString == null)\r
+                               throw new ProviderException (String.Format ("The connection name '{0}' was not found in the applications configuration or the connection string is empty.", connectionStringName));\r
 \r
-                       if (_connectionString != null)\r
-                               DerbyDBSchema.RegisterUnloadHandler (_connectionString.ConnectionString);\r
+                       string shutdown = config ["shutdown"];\r
+                       if (!String.IsNullOrEmpty (shutdown))\r
+                               _shutDownPolicy = (DerbyUnloadManager.DerbyShutDownPolicy) Enum.Parse (typeof (DerbyUnloadManager.DerbyShutDownPolicy), shutdown, true);\r
                }\r
 \r
                private ProfileInfoCollection BuildProfileInfoCollection (DbDataReader reader, int pageIndex, int pageSize, out int totalRecords)\r
index ac140d3ead3f89ce29ec5f1b866ff2621153a028..a12596e73ca8082d975a2c3aee918d7b79c64878 100644 (file)
@@ -33,13 +33,14 @@ using System.Data;
 using System.Data.OleDb;
 using System.Collections.Generic;
 using System.Text;
+using System.Configuration.Provider;
 
 namespace Mainsoft.Web.Security
 {
        internal class DerbyDBSchema
-       {\r
-               const string _currentSchemaVersion = "1.0";\r
-               static object _lock = "DerbyDBSchema";
+       {
+               const string _currentSchemaVersion = "1.0";
+               static readonly object _lock = new object ();
 
                #region schema string array
                static string [] schemaElements = new string [] {
@@ -169,131 +170,143 @@ namespace Mainsoft.Web.Security
                        @"CREATE INDEX aspnet_Version_Idx ON aspnet_Version(SchemaVersion)",
                        @"INSERT INTO aspnet_Version VALUES ('1.0')"
                };
-               #endregion\r
-\r
-               public static void CheckSchema (string connectionString)\r
-               {\r
-                       string schemaVersion = GetSchemaVersion (connectionString);\r
-                       if (schemaVersion != null)\r
-                               if (string.CompareOrdinal (schemaVersion, _currentSchemaVersion) == 0)\r
-                                       return;\r
-                               else\r
-                                       throw new Exception ("Incorrect aspnetdb schema version.");\r
-\r
-                       lock (_lock) {\r
-                               if (GetSchemaVersion (connectionString) != _currentSchemaVersion) {\r
-                                       InitializeSchema (connectionString);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               static string GetSchemaVersion (string connectionString)\r
-               {\r
-                       OleDbConnection connection = new OleDbConnection ();\r
-                       connection.ConnectionString = connectionString;\r
-\r
-                       try {\r
-                               connection.Open ();\r
-                       }\r
-                       catch (Exception) {\r
-                               return null;\r
-                       }\r
-\r
-                       using (connection) {\r
-                               OleDbCommand cmd = new OleDbCommand ("SELECT SchemaVersion FROM aspnet_Version", connection);\r
-                               try {\r
-                                       using (OleDbDataReader reader = cmd.ExecuteReader ()) {\r
-                                               if (reader.Read ())\r
-                                                       return reader.GetString (0);\r
-                                       }\r
-                               }\r
-                               catch (Exception) { }\r
-                               return null;\r
-                       }\r
-               }\r
-\r
-               static void InitializeSchema (string connectionString)\r
-               {\r
-                       if (connectionString.ToLower ().IndexOf ("create=true") < 0) {\r
-                               if (!connectionString.Trim ().EndsWith (";"))\r
-                                       connectionString += ";";\r
-\r
-                               connectionString += "create=true";\r
-                       }\r
-\r
-                       OleDbConnection connection = new OleDbConnection ();\r
-                       connection.ConnectionString = connectionString;\r
-\r
-                       connection.Open ();\r
-\r
-                       using (connection) {\r
-                               for (int i = 0; i < schemaElements.Length; i++) {\r
-                                       OleDbCommand cmd = new OleDbCommand (schemaElements [i], connection);\r
-                                       cmd.ExecuteNonQuery ();\r
-                               }\r
-                       }\r
+               #endregion
+
+               public static void CheckSchema (string connectionString) {
+                       string schemaVersion = GetSchemaVersion (connectionString);
+                       if (schemaVersion != null) {
+                               if (string.CompareOrdinal (schemaVersion, _currentSchemaVersion) == 0)
+                                       return;
+                       }
+                       else {
+                               lock (_lock) {
+                                       schemaVersion = GetSchemaVersion (connectionString);
+                                       if (schemaVersion == null) {
+                                               InitializeSchema (connectionString);
+                                               return;
+                                       }
+                               }
+                       }
+
+                       throw new ProviderException (String.Format ("Incorrect aspnetdb schema version: found '{0}', expected '{1}'.", schemaVersion, _currentSchemaVersion));
+               }
+
+               static string GetSchemaVersion (string connectionString)
+               {
+                       OleDbConnection connection = new OleDbConnection (connectionString);
+
+                       connection.Open ();
+
+                       using (connection) {
+                               OleDbCommand cmd = new OleDbCommand ("SELECT SchemaVersion FROM aspnet_Version", connection);
+
+                               try {
+                                       using (OleDbDataReader reader = cmd.ExecuteReader ()) {
+                                               if (reader.Read ())
+                                                       return reader.GetString (0);
+                                       }
+                               }
+                               catch { }
+
+                               return null;
+                       }
                }
 
-               public static void RegisterUnloadHandler (string connectionString)
+               static void InitializeSchema (string connectionString)
                {
-                       DerbyUnloadManager derbyMan = new DerbyUnloadManager (connectionString);
-                       derbyMan.RegisterUnloadHandler ();
+                       OleDbConnection connection = new OleDbConnection ();
+                       connection.ConnectionString = connectionString;
+
+                       connection.Open ();
+
+                       using (connection) {
+                               for (int i = 0; i < schemaElements.Length; i++) {
+                                       OleDbCommand cmd = new OleDbCommand (schemaElements [i], connection);
+                                       cmd.ExecuteNonQuery ();
+                               }
+                       }
                }
        }
 
        internal class DerbyUnloadManager
        {
-               private string _releaseString = null;
-
-               public DerbyUnloadManager (string connectionString)
+               public enum DerbyShutDownPolicy
                {
-                       _releaseString = connectionString;
-
-                       string [] parts = _releaseString.Split (';');
-                       bool found = false;
-
-                       for (int i=0; i<parts.Length; i++)
-                       {
-                               if (parts[i].ToLower().Trim().StartsWith("create"))
-                               {
-                                       parts[i] = parts[i].ToLower().Trim().Replace("create", "shutdown");
-                                       found = true;
-                                       break;
-                               }
-                       }
-                       if (found)
-                               _releaseString = string.Join (";", parts);
-                       else
-                       {
-                               if (!_releaseString.Trim ().EndsWith (";"))
-                                       _releaseString += ";";
-
-                               _releaseString += "shutdown=true";
-                       }
+                       Default,
+                       Never,
+                       Database,
+                       System
+               }
+
+               readonly string _connectionString;
+               readonly DerbyShutDownPolicy _policy;
+
+               DerbyUnloadManager (string connectionString, DerbyShutDownPolicy policy) {
+                       _connectionString = connectionString;
+                       _policy = policy;
+               }
+
+               public static void RegisterUnloadHandler (string connectionString, DerbyShutDownPolicy policy) {
+                       if (policy == DerbyShutDownPolicy.Never)
+                               return;
+
+                       if (connectionString.IndexOf("org.apache.derby.jdbc.EmbeddedDriver", StringComparison.Ordinal) < 0)
+                               return;
+
+                       DerbyUnloadManager derbyMan = new DerbyUnloadManager (connectionString, policy);
+                       AppDomain.CurrentDomain.DomainUnload += new EventHandler (derbyMan.UnloadHandler);
                }
 
                public void UnloadHandler (object sender, EventArgs e)
                {
-                       OleDbConnection connection = new OleDbConnection (_releaseString);
+                       string shutUrl;
 
-                       try {
-                               connection.Open ();
+                       switch (_policy) {
+                       case DerbyShutDownPolicy.Never:
+                               return;
+                       case DerbyShutDownPolicy.Database:
+                               shutUrl = GetConnectionProperty (_connectionString, "JdbcURL");
+                               break;
+                       case DerbyShutDownPolicy.System:
+                               shutUrl = "JdbcURL=jdbc:derby:";
+                               break;
+                       default:
+                       case DerbyShutDownPolicy.Default:
+                               java.lang.ClassLoader contextLoader = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData (J2EEConsts.CLASS_LOADER);
+                               java.lang.Class klass = contextLoader.loadClass ("org.apache.derby.jdbc.EmbeddedDriver");
+                               if (klass == null)
+                                       return;
+
+                               shutUrl = (klass.getClassLoader () == contextLoader) ?
+                                       "JdbcURL=jdbc:derby:" : GetConnectionProperty (_connectionString, "JdbcURL");
+
+                               break;
                        }
-                       catch (Exception ex) {
-#if TRACE\r
-                               Console.Write (ex.ToString ());
+
+                       const string shuttingConnection = "JdbcDriverClassName=org.apache.derby.jdbc.EmbeddedDriver;{0};shutdown=true";
+
+                       if (!String.IsNullOrEmpty (shutUrl)) {
+                               try {
+                                       new OleDbConnection (String.Format (shuttingConnection, shutUrl)).Open ();
+                               }
+                               catch (Exception ex) {
+#if TRACE
+                                       Console.Write (ex.ToString ());
 #endif
+                               }
                        }
                }
 
-               public void RegisterUnloadHandler ()
-               {
-                       AppDomain.CurrentDomain.DomainUnload += new EventHandler (UnloadHandler);
-               }
+               static string GetConnectionProperty (string connectionString, string name) {
+                       if (String.IsNullOrEmpty (connectionString))
+                               return null;
 
-               public void UnregisterUnloadHandler ()
-               {
-                       AppDomain.CurrentDomain.DomainUnload -= new EventHandler (UnloadHandler);
+                       string [] parts = connectionString.Split (';');
+                       foreach (string part in parts)
+                               if (part.StartsWith (name, StringComparison.OrdinalIgnoreCase))
+                                       return part;
+
+                       return null;
                }
        }
 }
index ab885ad29d3bc8414e62aa500c690d5694b0b9df..7590f46366106c19b06081b136922f19e0ee5611 100644 (file)
@@ -61,12 +61,19 @@ namespace Mainsoft.Web.Security {
                string passwordStrengthRegularExpression;
                TimeSpan userIsOnlineTimeWindow;
                ConnectionStringSettings connectionString;
+               bool schemaChecked = false;
+               DerbyUnloadManager.DerbyShutDownPolicy shutDownPolicy = DerbyUnloadManager.DerbyShutDownPolicy.Default;
 
                string applicationName;
 
                DbConnection CreateConnection ()
                {\r
-                       DerbyDBSchema.CheckSchema (connectionString.ConnectionString);\r
+                       if (!schemaChecked) {\r
+                               DerbyDBSchema.CheckSchema (connectionString.ConnectionString);\r
+                               schemaChecked = true;\r
+\r
+                               DerbyUnloadManager.RegisterUnloadHandler (connectionString.ConnectionString, shutDownPolicy);\r
+                       }\r
 \r
                        OleDbConnection connection = new OleDbConnection (connectionString.ConnectionString);
                        connection.Open ();
@@ -604,7 +611,12 @@ namespace Mainsoft.Web.Security {
                        if (connectionString == null)\r
                                throw new ProviderException (String.Format ("The connection name '{0}' was not found in the applications configuration or the connection string is empty.", connectionStringName));\r
 \r
-                       DerbyDBSchema.RegisterUnloadHandler (connectionString.ConnectionString);\r
+                       if (connectionString == null)\r
+                               throw new ProviderException (String.Format ("The connection name '{0}' was not found in the applications configuration or the connection string is empty.", connectionStringName));\r
+\r
+                       string shutdown = config ["shutdown"];\r
+                       if (!String.IsNullOrEmpty (shutdown))\r
+                               shutDownPolicy = (DerbyUnloadManager.DerbyShutDownPolicy) Enum.Parse (typeof (DerbyUnloadManager.DerbyShutDownPolicy), shutdown, true);\r
                }
 
                public override string ResetPassword (string username, string answer)
index 02e341aa37d4332a4541762c94a1e401cbdec3e6..6f6bbfa3993c4ff336be55ca83d11e423198b345 100644 (file)
@@ -47,10 +47,17 @@ namespace Mainsoft.Web.Security
        {\r
                ConnectionStringSettings connectionString;\r
                string applicationName;\r
+               bool schemaChecked = false;\r
+               DerbyUnloadManager.DerbyShutDownPolicy shutDownPolicy = DerbyUnloadManager.DerbyShutDownPolicy.Default;\r
 \r
                DbConnection CreateConnection ()\r
                {\r
-                       DerbyDBSchema.CheckSchema (connectionString.ConnectionString);\r
+                       if (!schemaChecked) {\r
+                               DerbyDBSchema.CheckSchema (connectionString.ConnectionString);\r
+                               schemaChecked = true;\r
+\r
+                               DerbyUnloadManager.RegisterUnloadHandler (connectionString.ConnectionString, shutDownPolicy);\r
+                       }\r
 \r
                        OleDbConnection connection = new OleDbConnection (connectionString.ConnectionString);\r
                        connection.Open ();\r
@@ -267,7 +274,9 @@ namespace Mainsoft.Web.Security
                        if (connectionString == null)\r
                                throw new ProviderException (String.Format("The connection name '{0}' was not found in the applications configuration or the connection string is empty.", connectionStringName));\r
 \r
-                       DerbyDBSchema.RegisterUnloadHandler (connectionString.ConnectionString);\r
+                       string shutdown = config ["shutdown"];\r
+                       if (!String.IsNullOrEmpty (shutdown))\r
+                               shutDownPolicy = (DerbyUnloadManager.DerbyShutDownPolicy) Enum.Parse (typeof (DerbyUnloadManager.DerbyShutDownPolicy), shutdown, true);\r
                }\r
 \r
                public override bool IsUserInRole (string username, string rolename)\r