From 97eaae9d8454ade646dbd210bcf0cb521ec6b288 Mon Sep 17 00:00:00 2001 From: OpenSim Master Date: Mon, 18 Jan 2010 15:50:33 -0800 Subject: [PATCH 1/8] * Fixed the Cable Beach inventory server to save the CreatorID as well as properly handling null item names and descriptions * Fixed the MySQL reader to safely handle null values in string columns that can be null --- OpenSim/Data/MySQL/MySQLInventoryData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index f566fdec2e..4b71e3951f 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -345,8 +345,8 @@ namespace OpenSim.Data.MySQL item.AssetID = new UUID((string) reader["assetID"]); item.AssetType = (int) reader["assetType"]; item.Folder = new UUID((string) reader["parentFolderID"]); - item.Name = (string) reader["inventoryName"]; - item.Description = (string) reader["inventoryDescription"]; + item.Name = (string)(reader["inventoryName"] ?? String.Empty); + item.Description = (string)(reader["inventoryDescription"] ?? String.Empty); item.NextPermissions = (uint) reader["inventoryNextPermissions"]; item.CurrentPermissions = (uint) reader["inventoryCurrentPermissions"]; item.InvType = (int) reader["invType"]; From 6392cfcd61a156bda403ee233c322650940df6f7 Mon Sep 17 00:00:00 2001 From: OpenSim Master Date: Mon, 18 Jan 2010 13:47:41 -0800 Subject: [PATCH 2/8] Fixing an incorrect logging message in insertUserRow --- OpenSim/Data/MySQL/MySQLManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/MySQLManager.cs b/OpenSim/Data/MySQL/MySQLManager.cs index a6cce57819..243394e9db 100644 --- a/OpenSim/Data/MySQL/MySQLManager.cs +++ b/OpenSim/Data/MySQL/MySQLManager.cs @@ -778,7 +778,7 @@ namespace OpenSim.Data.MySQL string aboutText, string firstText, UUID profileImage, UUID firstImage, UUID webLoginKey, int userFlags, int godLevel, string customType, UUID partner) { - m_log.Debug("[MySQLManager]: Fetching profile for " + uuid.ToString()); + m_log.Debug("[MySQLManager]: Creating profile for \"" + username + " " + lastname + "\" (" + uuid + ")"); string sql = "INSERT INTO users (`UUID`, `username`, `lastname`, `email`, `passwordHash`, `passwordSalt`, `homeRegion`, `homeRegionID`, "; sql += From 3e697ad57e8f26e50e13b88fff059855ed17e660 Mon Sep 17 00:00:00 2001 From: OpenSim Master Date: Mon, 18 Jan 2010 15:50:33 -0800 Subject: [PATCH 3/8] * Fixed the Cable Beach inventory server to save the CreatorID as well as properly handling null item names and descriptions * Fixed the MySQL reader to safely handle null values in string columns that can be null --- OpenSim/Data/MySQL/MySQLInventoryData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index f566fdec2e..4b71e3951f 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -345,8 +345,8 @@ namespace OpenSim.Data.MySQL item.AssetID = new UUID((string) reader["assetID"]); item.AssetType = (int) reader["assetType"]; item.Folder = new UUID((string) reader["parentFolderID"]); - item.Name = (string) reader["inventoryName"]; - item.Description = (string) reader["inventoryDescription"]; + item.Name = (string)(reader["inventoryName"] ?? String.Empty); + item.Description = (string)(reader["inventoryDescription"] ?? String.Empty); item.NextPermissions = (uint) reader["inventoryNextPermissions"]; item.CurrentPermissions = (uint) reader["inventoryCurrentPermissions"]; item.InvType = (int) reader["invType"]; From 5f1f5c29e93d5ef92ccf93386c0738a205df4150 Mon Sep 17 00:00:00 2001 From: OpenSim Master Date: Mon, 18 Jan 2010 13:47:41 -0800 Subject: [PATCH 4/8] Fixing an incorrect logging message in insertUserRow --- OpenSim/Data/MySQL/MySQLManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/MySQLManager.cs b/OpenSim/Data/MySQL/MySQLManager.cs index a6cce57819..243394e9db 100644 --- a/OpenSim/Data/MySQL/MySQLManager.cs +++ b/OpenSim/Data/MySQL/MySQLManager.cs @@ -778,7 +778,7 @@ namespace OpenSim.Data.MySQL string aboutText, string firstText, UUID profileImage, UUID firstImage, UUID webLoginKey, int userFlags, int godLevel, string customType, UUID partner) { - m_log.Debug("[MySQLManager]: Fetching profile for " + uuid.ToString()); + m_log.Debug("[MySQLManager]: Creating profile for \"" + username + " " + lastname + "\" (" + uuid + ")"); string sql = "INSERT INTO users (`UUID`, `username`, `lastname`, `email`, `passwordHash`, `passwordSalt`, `homeRegion`, `homeRegionID`, "; sql += From e1b5c612472b9d1acf47383c0bf75b555daff2e6 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Thu, 4 Feb 2010 13:19:30 -0800 Subject: [PATCH 5/8] Updated MySQL connection management to use the MySQL connection pooling. This should accommodate various timeout problems that exist with the current connection pool code in a more general and standard way. --- OpenSim/Data/MySQL/MySQLAssetData.cs | 349 +++---- OpenSim/Data/MySQL/MySQLAuthenticationData.cs | 73 +- OpenSim/Data/MySQL/MySQLEstateData.cs | 466 ++++----- OpenSim/Data/MySQL/MySQLFramework.cs | 62 +- .../Data/MySQL/MySQLGenericTableHandler.cs | 225 +++-- OpenSim/Data/MySQL/MySQLGridData.cs | 354 +++---- OpenSim/Data/MySQL/MySQLInventoryData.cs | 867 +++++++---------- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 918 +++++++++--------- OpenSim/Data/MySQL/MySQLLogData.cs | 16 +- OpenSim/Data/MySQL/MySQLManager.cs | 432 ++++----- OpenSim/Data/MySQL/MySQLRegionData.cs | 255 ++--- OpenSim/Data/MySQL/MySQLUserAccountData.cs | 156 +-- OpenSim/Data/MySQL/MySQLUserData.cs | 674 +++++-------- OpenSim/Data/MySQL/MySQLXInventoryData.cs | 65 +- OpenSim/Data/MySQL/Tests/MySQLGridTest.cs | 9 +- 15 files changed, 2261 insertions(+), 2660 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index 6a4ccd7057..666c22f135 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -43,10 +43,13 @@ namespace OpenSim.Data.MySQL { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private MySQLManager _dbConnection; + private string m_connectionString; + private object m_dbLock = new object(); #region IPlugin Members + public override string Version { get { return "1.0.0.0"; } } + /// /// Initialises Asset interface /// @@ -58,62 +61,28 @@ namespace OpenSim.Data.MySQL /// /// /// connect string - override public void Initialise(string connect) + public override void Initialise(string connect) { - // TODO: This will let you pass in the connect string in - // the config, though someone will need to write that. - if (connect == String.Empty) - { - // This is old seperate config file - m_log.Warn("no connect string, using old mysql_connection.ini instead"); - Initialise(); - } - else - { - _dbConnection = new MySQLManager(connect); - } + m_connectionString = connect; // This actually does the roll forward assembly stuff Assembly assem = GetType().Assembly; - Migration m = new Migration(_dbConnection.Connection, assem, "AssetStore"); - m.Update(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + Migration m = new Migration(dbcon, assem, "AssetStore"); + m.Update(); + } } - /// - /// Initialises Asset interface - /// - /// - /// Loads and initialises the MySQL storage plugin - /// uses the obsolete mysql_connection.ini - /// - /// - /// - /// DEPRECATED and shouldn't be used public override void Initialise() { - IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); - string hostname = GridDataMySqlFile.ParseFileReadValue("hostname"); - string database = GridDataMySqlFile.ParseFileReadValue("database"); - string username = GridDataMySqlFile.ParseFileReadValue("username"); - string password = GridDataMySqlFile.ParseFileReadValue("password"); - string pooling = GridDataMySqlFile.ParseFileReadValue("pooling"); - string port = GridDataMySqlFile.ParseFileReadValue("port"); - - _dbConnection = new MySQLManager(hostname, database, username, password, pooling, port); - + throw new NotImplementedException(); } public override void Dispose() { } - /// - /// Database provider version - /// - override public string Version - { - get { return _dbConnection.getVersion(); } - } - /// /// The name of this DB provider /// @@ -135,46 +104,43 @@ namespace OpenSim.Data.MySQL override public AssetBase GetAsset(UUID assetID) { AssetBase asset = null; - lock (_dbConnection) + lock (m_dbLock) { - _dbConnection.CheckConnection(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - MySqlCommand cmd = - new MySqlCommand( + using (MySqlCommand cmd = new MySqlCommand( "SELECT name, description, assetType, local, temporary, data FROM assets WHERE id=?id", - _dbConnection.Connection); - cmd.Parameters.AddWithValue("?id", assetID.ToString()); - - try - { - using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + dbcon)) { - if (dbReader.Read()) + cmd.Parameters.AddWithValue("?id", assetID.ToString()); + + try { - asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"]); - asset.Data = (byte[]) dbReader["data"]; - asset.Description = (string) dbReader["description"]; + using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + { + if (dbReader.Read()) + { + asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"]); + asset.Data = (byte[])dbReader["data"]; + asset.Description = (string)dbReader["description"]; - string local = dbReader["local"].ToString(); - if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) - asset.Local = true; - else - asset.Local = false; + string local = dbReader["local"].ToString(); + if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) + asset.Local = true; + else + asset.Local = false; - asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); + asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); + } + } + } + catch (Exception e) + { + m_log.Error("[ASSETS DB]: MySql failure fetching asset " + assetID + ": " + e.Message); } - dbReader.Close(); - cmd.Dispose(); } - if (asset != null) - UpdateAccessTime(asset); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString() - + Environment.NewLine + "Reconnecting", assetID); - _dbConnection.Reconnect(); } } return asset; @@ -187,55 +153,57 @@ namespace OpenSim.Data.MySQL /// On failure : Throw an exception and attempt to reconnect to database override public void StoreAsset(AssetBase asset) { - lock (_dbConnection) + lock (m_dbLock) { - _dbConnection.CheckConnection(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - MySqlCommand cmd = - new MySqlCommand( - "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, data)" + - "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?data)", - _dbConnection.Connection); + MySqlCommand cmd = + new MySqlCommand( + "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, data)" + + "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?data)", + dbcon); - string assetName = asset.Name; - if (asset.Name.Length > 64) - { - assetName = asset.Name.Substring(0, 64); - m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add"); - } - - string assetDescription = asset.Description; - if (asset.Description.Length > 64) - { - assetDescription = asset.Description.Substring(0, 64); - m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add"); - } - - // need to ensure we dispose - try - { - using (cmd) + string assetName = asset.Name; + if (asset.Name.Length > 64) { - // create unix epoch time - int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); - cmd.Parameters.AddWithValue("?id", asset.ID); - cmd.Parameters.AddWithValue("?name", assetName); - cmd.Parameters.AddWithValue("?description", assetDescription); - cmd.Parameters.AddWithValue("?assetType", asset.Type); - cmd.Parameters.AddWithValue("?local", asset.Local); - cmd.Parameters.AddWithValue("?temporary", asset.Temporary); - cmd.Parameters.AddWithValue("?create_time", now); - cmd.Parameters.AddWithValue("?access_time", now); - cmd.Parameters.AddWithValue("?data", asset.Data); - cmd.ExecuteNonQuery(); - cmd.Dispose(); + assetName = asset.Name.Substring(0, 64); + m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add"); + } + + string assetDescription = asset.Description; + if (asset.Description.Length > 64) + { + assetDescription = asset.Description.Substring(0, 64); + m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add"); + } + + // need to ensure we dispose + try + { + using (cmd) + { + // create unix epoch time + int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); + cmd.Parameters.AddWithValue("?id", asset.ID); + cmd.Parameters.AddWithValue("?name", assetName); + cmd.Parameters.AddWithValue("?description", assetDescription); + cmd.Parameters.AddWithValue("?assetType", asset.Type); + cmd.Parameters.AddWithValue("?local", asset.Local); + cmd.Parameters.AddWithValue("?temporary", asset.Temporary); + cmd.Parameters.AddWithValue("?create_time", now); + cmd.Parameters.AddWithValue("?access_time", now); + cmd.Parameters.AddWithValue("?data", asset.Data); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + } + catch (Exception e) + { + m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", + asset.FullID, asset.Name, e.Message); } - } - catch (Exception e) - { - m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Attempting reconnect. Error: {2}", - asset.FullID, asset.Name, e.Message); - _dbConnection.Reconnect(); } } } @@ -245,34 +213,35 @@ namespace OpenSim.Data.MySQL // Writing to the database every time Get() is called on an asset is killing us. Seriously. -jph return; - lock (_dbConnection) + lock (m_dbLock) { - _dbConnection.CheckConnection(); - - MySqlCommand cmd = - new MySqlCommand("update assets set access_time=?access_time where id=?id", - _dbConnection.Connection); - - // need to ensure we dispose - try + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - using (cmd) + dbcon.Open(); + MySqlCommand cmd = + new MySqlCommand("update assets set access_time=?access_time where id=?id", + dbcon); + + // need to ensure we dispose + try { - // create unix epoch time - int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); - cmd.Parameters.AddWithValue("?id", asset.ID); - cmd.Parameters.AddWithValue("?access_time", now); - cmd.ExecuteNonQuery(); - cmd.Dispose(); + using (cmd) + { + // create unix epoch time + int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); + cmd.Parameters.AddWithValue("?id", asset.ID); + cmd.Parameters.AddWithValue("?access_time", now); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ASSETS DB]: " + + "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString() + + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name); } - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ASSETS DB]: " + - "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString() - + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name); - _dbConnection.Reconnect(); } } @@ -287,37 +256,30 @@ namespace OpenSim.Data.MySQL { bool assetExists = false; - lock (_dbConnection) + lock (m_dbLock) { - _dbConnection.CheckConnection(); - - MySqlCommand cmd = - new MySqlCommand( - "SELECT id FROM assets WHERE id=?id", - _dbConnection.Connection); - - cmd.Parameters.AddWithValue("?id", uuid.ToString()); - - try + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + dbcon.Open(); + using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM assets WHERE id=?id", dbcon)) { - if (dbReader.Read()) - { - assetExists = true; - } + cmd.Parameters.AddWithValue("?id", uuid.ToString()); - dbReader.Close(); - cmd.Dispose(); + try + { + using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + { + if (dbReader.Read()) + assetExists = true; + } + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid); + } } } - catch (Exception e) - { - m_log.ErrorFormat( - "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString() - + Environment.NewLine + "Attempting reconnection", uuid); - _dbConnection.Reconnect(); - } } return assetExists; @@ -335,38 +297,39 @@ namespace OpenSim.Data.MySQL { List retList = new List(count); - lock (_dbConnection) + lock (m_dbLock) { - _dbConnection.CheckConnection(); - - MySqlCommand cmd = new MySqlCommand("SELECT name,description,assetType,temporary,id FROM assets LIMIT ?start, ?count", _dbConnection.Connection); - cmd.Parameters.AddWithValue("?start", start); - cmd.Parameters.AddWithValue("?count", count); - - try + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - using (MySqlDataReader dbReader = cmd.ExecuteReader()) + dbcon.Open(); + MySqlCommand cmd = new MySqlCommand("SELECT name,description,assetType,temporary,id FROM assets LIMIT ?start, ?count", dbcon); + cmd.Parameters.AddWithValue("?start", start); + cmd.Parameters.AddWithValue("?count", count); + + try { - while (dbReader.Read()) + using (MySqlDataReader dbReader = cmd.ExecuteReader()) { - AssetMetadata metadata = new AssetMetadata(); - metadata.Name = (string) dbReader["name"]; - metadata.Description = (string) dbReader["description"]; - metadata.Type = (sbyte) dbReader["assetType"]; - metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. - metadata.FullID = new UUID((string) dbReader["id"]); + while (dbReader.Read()) + { + AssetMetadata metadata = new AssetMetadata(); + metadata.Name = (string)dbReader["name"]; + metadata.Description = (string)dbReader["description"]; + metadata.Type = (sbyte)dbReader["assetType"]; + metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. + metadata.FullID = new UUID((string)dbReader["id"]); - // Current SHA1s are not stored/computed. - metadata.SHA1 = new byte[] {}; + // Current SHA1s are not stored/computed. + metadata.SHA1 = new byte[] { }; - retList.Add(metadata); + retList.Add(metadata); + } } } - } - catch (Exception e) - { - m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString() + Environment.NewLine + "Attempting reconnection"); - _dbConnection.Reconnect(); + catch (Exception e) + { + m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); + } } } @@ -374,7 +337,5 @@ namespace OpenSim.Data.MySQL } #endregion - - } } diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index e508b5285b..5056aee6c1 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -38,16 +38,22 @@ namespace OpenSim.Data.MySQL public class MySqlAuthenticationData : MySqlFramework, IAuthenticationData { private string m_Realm; - private List m_ColumnNames = null; - private int m_LastExpire = 0; + private List m_ColumnNames; + private int m_LastExpire; + // private string m_connectionString; public MySqlAuthenticationData(string connectionString, string realm) : base(connectionString) { m_Realm = realm; + m_connectionString = connectionString; - Migration m = new Migration(m_Connection, GetType().Assembly, "AuthStore"); - m.Update(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + Migration m = new Migration(dbcon, GetType().Assembly, "AuthStore"); + m.Update(); + } } public AuthenticationData Get(UUID principalID) @@ -55,45 +61,42 @@ namespace OpenSim.Data.MySQL AuthenticationData ret = new AuthenticationData(); ret.Data = new Dictionary(); - MySqlCommand cmd = new MySqlCommand( - "select * from `"+m_Realm+"` where UUID = ?principalID" - ); - - cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - - IDataReader result = ExecuteReader(cmd); - - if (result.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - ret.PrincipalID = principalID; + dbcon.Open(); + MySqlCommand cmd = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon); + cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - if (m_ColumnNames == null) + IDataReader result = cmd.ExecuteReader(); + + if (result.Read()) { - m_ColumnNames = new List(); + ret.PrincipalID = principalID; - DataTable schemaTable = result.GetSchemaTable(); - foreach (DataRow row in schemaTable.Rows) - m_ColumnNames.Add(row["ColumnName"].ToString()); + if (m_ColumnNames == null) + { + m_ColumnNames = new List(); + + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + m_ColumnNames.Add(row["ColumnName"].ToString()); + } + + foreach (string s in m_ColumnNames) + { + if (s == "UUID") + continue; + + ret.Data[s] = result[s].ToString(); + } + + return ret; } - - foreach (string s in m_ColumnNames) + else { - if (s == "UUID") - continue; - - ret.Data[s] = result[s].ToString(); + return null; } - - result.Close(); - CloseReaderCommand(cmd); - - return ret; } - - result.Close(); - CloseReaderCommand(cmd); - - return null; } public bool Store(AuthenticationData data) diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs index e8694fcd50..2eae2d82b2 100644 --- a/OpenSim/Data/MySQL/MySQLEstateData.cs +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs @@ -44,7 +44,6 @@ namespace OpenSim.Data.MySQL private const string m_waitTimeoutSelect = "select @@wait_timeout"; - private MySqlConnection m_connection; private string m_connectionString; private long m_waitTimeout; private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond; @@ -67,24 +66,26 @@ namespace OpenSim.Data.MySQL m_log.Debug("Exception: password not found in connection string\n" + e.ToString()); } - m_connection = new MySqlConnection(m_connectionString); - m_connection.Open(); - GetWaitTimeout(); - Assembly assem = GetType().Assembly; - Migration m = new Migration(m_connection, assem, "EstateStore"); - m.Update(); - - Type t = typeof(EstateSettings); - m_Fields = t.GetFields(BindingFlags.NonPublic | - BindingFlags.Instance | - BindingFlags.DeclaredOnly); - - foreach (FieldInfo f in m_Fields) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - if (f.Name.Substring(0, 2) == "m_") - m_FieldMap[f.Name.Substring(2)] = f; + dbcon.Open(); + + Assembly assem = GetType().Assembly; + Migration m = new Migration(dbcon, assem, "EstateStore"); + m.Update(); + + Type t = typeof(EstateSettings); + m_Fields = t.GetFields(BindingFlags.NonPublic | + BindingFlags.Instance | + BindingFlags.DeclaredOnly); + + foreach (FieldInfo f in m_Fields) + { + if (f.Name.Substring(0, 2) == "m_") + m_FieldMap[f.Name.Substring(2)] = f; + } } } @@ -95,47 +96,29 @@ namespace OpenSim.Data.MySQL protected void GetWaitTimeout() { - MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, - m_connection); - - using (MySqlDataReader dbReader = - cmd.ExecuteReader(CommandBehavior.SingleRow)) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - if (dbReader.Read()) + dbcon.Open(); + + using (MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon)) { - m_waitTimeout - = Convert.ToInt32(dbReader["@@wait_timeout"]) * - TimeSpan.TicksPerSecond + m_waitTimeoutLeeway; + using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + { + if (dbReader.Read()) + { + m_waitTimeout + = Convert.ToInt32(dbReader["@@wait_timeout"]) * + TimeSpan.TicksPerSecond + m_waitTimeoutLeeway; + } + } } - dbReader.Close(); - cmd.Dispose(); + m_lastConnectionUse = DateTime.Now.Ticks; + + m_log.DebugFormat( + "[REGION DB]: Connection wait timeout {0} seconds", + m_waitTimeout / TimeSpan.TicksPerSecond); } - - m_lastConnectionUse = DateTime.Now.Ticks; - - m_log.DebugFormat( - "[REGION DB]: Connection wait timeout {0} seconds", - m_waitTimeout / TimeSpan.TicksPerSecond); - } - - protected void CheckConnection() - { - long timeNow = DateTime.Now.Ticks; - if (timeNow - m_lastConnectionUse > m_waitTimeout || - m_connection.State != ConnectionState.Open) - { - m_log.DebugFormat("[REGION DB]: Database connection has gone away - reconnecting"); - - lock (m_connection) - { - m_connection.Close(); - m_connection = new MySqlConnection(m_connectionString); - m_connection.Open(); - } - } - - m_lastConnectionUse = timeNow; } public EstateSettings LoadEstateSettings(UUID regionID) @@ -143,114 +126,111 @@ namespace OpenSim.Data.MySQL EstateSettings es = new EstateSettings(); es.OnSave += StoreEstateSettings; - string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID"; + string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID"; - CheckConnection(); + bool migration = true; - MySqlCommand cmd = m_connection.CreateCommand(); - - cmd.CommandText = sql; - cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); - - IDataReader r = cmd.ExecuteReader(); - - if (r.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - foreach (string name in FieldList) + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) { - if (m_FieldMap[name].GetValue(es) is bool) + cmd.CommandText = sql; + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); + + using (IDataReader r = cmd.ExecuteReader()) { - int v = Convert.ToInt32(r[name]); - if (v != 0) - m_FieldMap[name].SetValue(es, true); - else - m_FieldMap[name].SetValue(es, false); - } - else if (m_FieldMap[name].GetValue(es) is UUID) - { - UUID uuid = UUID.Zero; + if (r.Read()) + { + migration = false; - UUID.TryParse(r[name].ToString(), out uuid); - m_FieldMap[name].SetValue(es, uuid); - } - else - { - m_FieldMap[name].SetValue(es, r[name]); - } - } - r.Close(); - } - else - { - // Migration case - // - r.Close(); + foreach (string name in FieldList) + { + if (m_FieldMap[name].GetValue(es) is bool) + { + int v = Convert.ToInt32(r[name]); + if (v != 0) + m_FieldMap[name].SetValue(es, true); + else + m_FieldMap[name].SetValue(es, false); + } + else if (m_FieldMap[name].GetValue(es) is UUID) + { + UUID uuid = UUID.Zero; - List names = new List(FieldList); - - names.Remove("EstateID"); - - sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")"; - - cmd.CommandText = sql; - cmd.Parameters.Clear(); - - foreach (string name in FieldList) - { - if (m_FieldMap[name].GetValue(es) is bool) - { - if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.AddWithValue("?" + name, "1"); - else - cmd.Parameters.AddWithValue("?" + name, "0"); - } - else - { - cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); + UUID.TryParse(r[name].ToString(), out uuid); + m_FieldMap[name].SetValue(es, uuid); + } + else + { + m_FieldMap[name].SetValue(es, r[name]); + } + } + } } } - cmd.ExecuteNonQuery(); - - cmd.CommandText = "select LAST_INSERT_ID() as id"; - cmd.Parameters.Clear(); - - r = cmd.ExecuteReader(); - - r.Read(); - - es.EstateID = Convert.ToUInt32(r["id"]); - - r.Close(); - - cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; - cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); - cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); - - // This will throw on dupe key - try + if (migration) { - cmd.ExecuteNonQuery(); - } - catch (Exception) - { - } + // Migration case + List names = new List(FieldList); - // Munge and transfer the ban list - // - cmd.Parameters.Clear(); - cmd.CommandText = "insert into estateban select " + es.EstateID.ToString() + ", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = ?UUID"; - cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); + names.Remove("EstateID"); - try - { - cmd.ExecuteNonQuery(); - } - catch (Exception) - { - } + sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")"; - es.Save(); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = sql; + cmd.Parameters.Clear(); + + foreach (string name in FieldList) + { + if (m_FieldMap[name].GetValue(es) is bool) + { + if ((bool)m_FieldMap[name].GetValue(es)) + cmd.Parameters.AddWithValue("?" + name, "1"); + else + cmd.Parameters.AddWithValue("?" + name, "0"); + } + else + { + cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); + } + } + + cmd.ExecuteNonQuery(); + + cmd.CommandText = "select LAST_INSERT_ID() as id"; + cmd.Parameters.Clear(); + + using (IDataReader r = cmd.ExecuteReader()) + { + r.Read(); + es.EstateID = Convert.ToUInt32(r["id"]); + } + + cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); + + // This will throw on dupe key + try { cmd.ExecuteNonQuery(); } + catch (Exception) { } + + // Munge and transfer the ban list + cmd.Parameters.Clear(); + cmd.CommandText = "insert into estateban select " + es.EstateID.ToString() + ", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = ?UUID"; + cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); + + try { cmd.ExecuteNonQuery(); } + catch (Exception) { } + + es.Save(); + } + } } LoadBanList(es); @@ -265,29 +245,33 @@ namespace OpenSim.Data.MySQL { string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")"; - CheckConnection(); - - MySqlCommand cmd = m_connection.CreateCommand(); - - cmd.CommandText = sql; - - foreach (string name in FieldList) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - if (m_FieldMap[name].GetValue(es) is bool) + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) { - if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.AddWithValue("?" + name, "1"); - else - cmd.Parameters.AddWithValue("?" + name, "0"); - } - else - { - cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); + cmd.CommandText = sql; + + foreach (string name in FieldList) + { + if (m_FieldMap[name].GetValue(es) is bool) + { + if ((bool)m_FieldMap[name].GetValue(es)) + cmd.Parameters.AddWithValue("?" + name, "1"); + else + cmd.Parameters.AddWithValue("?" + name, "0"); + } + else + { + cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); + } + } + + cmd.ExecuteNonQuery(); } } - cmd.ExecuteNonQuery(); - SaveBanList(es); SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers); SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess); @@ -298,77 +282,89 @@ namespace OpenSim.Data.MySQL { es.ClearBans(); - CheckConnection(); - - MySqlCommand cmd = m_connection.CreateCommand(); - - cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID"; - cmd.Parameters.AddWithValue("?EstateID", es.EstateID); - - IDataReader r = cmd.ExecuteReader(); - - while (r.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - EstateBan eb = new EstateBan(); + dbcon.Open(); - UUID uuid = new UUID(); - UUID.TryParse(r["bannedUUID"].ToString(), out uuid); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", es.EstateID); - eb.BannedUserID = uuid; - eb.BannedHostAddress = "0.0.0.0"; - eb.BannedHostIPMask = "0.0.0.0"; - es.AddBan(eb); + using (IDataReader r = cmd.ExecuteReader()) + { + while (r.Read()) + { + EstateBan eb = new EstateBan(); + + UUID uuid = new UUID(); + UUID.TryParse(r["bannedUUID"].ToString(), out uuid); + + eb.BannedUserID = uuid; + eb.BannedHostAddress = "0.0.0.0"; + eb.BannedHostIPMask = "0.0.0.0"; + es.AddBan(eb); + } + } + } } - r.Close(); } private void SaveBanList(EstateSettings es) { - CheckConnection(); - - MySqlCommand cmd = m_connection.CreateCommand(); - - cmd.CommandText = "delete from estateban where EstateID = ?EstateID"; - cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); - - cmd.ExecuteNonQuery(); - - cmd.Parameters.Clear(); - - cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )"; - - foreach (EstateBan b in es.EstateBans) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); - cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString()); + dbcon.Open(); - cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from estateban where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); + + cmd.ExecuteNonQuery(); + + cmd.Parameters.Clear(); + + cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )"; + + foreach (EstateBan b in es.EstateBans) + { + cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString()); + + cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + } + } } } void SaveUUIDList(uint EstateID, string table, UUID[] data) { - CheckConnection(); - - MySqlCommand cmd = m_connection.CreateCommand(); - - cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID"; - cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); - - cmd.ExecuteNonQuery(); - - cmd.Parameters.Clear(); - - cmd.CommandText = "insert into " + table + " (EstateID, uuid) values ( ?EstateID, ?uuid )"; - - foreach (UUID uuid in data) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); - cmd.Parameters.AddWithValue("?uuid", uuid.ToString()); + dbcon.Open(); - cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); + + cmd.ExecuteNonQuery(); + + cmd.Parameters.Clear(); + + cmd.CommandText = "insert into " + table + " (EstateID, uuid) values ( ?EstateID, ?uuid )"; + + foreach (UUID uuid in data) + { + cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); + cmd.Parameters.AddWithValue("?uuid", uuid.ToString()); + + cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + } + } } } @@ -376,25 +372,29 @@ namespace OpenSim.Data.MySQL { List uuids = new List(); - CheckConnection(); - - MySqlCommand cmd = m_connection.CreateCommand(); - - cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID"; - cmd.Parameters.AddWithValue("?EstateID", EstateID); - - IDataReader r = cmd.ExecuteReader(); - - while (r.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - // EstateBan eb = new EstateBan(); + dbcon.Open(); - UUID uuid = new UUID(); - UUID.TryParse(r["uuid"].ToString(), out uuid); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", EstateID); - uuids.Add(uuid); + using (IDataReader r = cmd.ExecuteReader()) + { + while (r.Read()) + { + // EstateBan eb = new EstateBan(); + + UUID uuid = new UUID(); + UUID.TryParse(r["uuid"].ToString(), out uuid); + + uuids.Add(uuid); + } + } + } } - r.Close(); return uuids.ToArray(); } diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index fca0ca5e8a..3fdcf1e54c 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -40,12 +40,16 @@ namespace OpenSim.Data.MySQL /// public class MySqlFramework { - protected MySqlConnection m_Connection; + private static readonly log4net.ILog m_log = + log4net.LogManager.GetLogger( + System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + protected string m_connectionString; + protected object m_dbLock = new object(); protected MySqlFramework(string connectionString) { - m_Connection = new MySqlConnection(connectionString); - m_Connection.Open(); + m_connectionString = connectionString; } ////////////////////////////////////////////////////////////// @@ -55,64 +59,24 @@ namespace OpenSim.Data.MySQL // protected int ExecuteNonQuery(MySqlCommand cmd) { - lock (m_Connection) + lock (m_dbLock) { - cmd.Connection = m_Connection; - - bool errorSeen = false; - - while (true) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { + dbcon.Open(); + cmd.Connection = dbcon; + try { return cmd.ExecuteNonQuery(); } - catch (MySqlException e) - { - if (errorSeen) - throw; - - // This is "Server has gone away" and "Server lost" - // - if (e.Number == 2006 || e.Number == 2013) - { - errorSeen = true; - - m_Connection.Close(); - MySqlConnection newConnection = - (MySqlConnection)((ICloneable)m_Connection).Clone(); - m_Connection.Dispose(); - m_Connection = newConnection; - m_Connection.Open(); - - cmd.Connection = m_Connection; - } - else - throw; - } catch (Exception e) { + m_log.Error(e.Message, e); return 0; } } } } - - protected IDataReader ExecuteReader(MySqlCommand cmd) - { - MySqlConnection newConnection = - (MySqlConnection)((ICloneable)m_Connection).Clone(); - newConnection.Open(); - - cmd.Connection = newConnection; - return cmd.ExecuteReader(); - } - - protected void CloseReaderCommand(MySqlCommand cmd) - { - cmd.Connection.Close(); - cmd.Connection.Dispose(); - cmd.Dispose(); - } } } diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index fdb98eba92..698bf521d6 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -54,12 +54,16 @@ namespace OpenSim.Data.MySQL string realm, string storeName) : base(connectionString) { m_Realm = realm; + m_connectionString = connectionString; + if (storeName != String.Empty) { - Assembly assem = GetType().Assembly; - - Migration m = new Migration(m_Connection, assem, storeName); - m.Update(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + Migration m = new Migration(dbcon, GetType().Assembly, storeName); + m.Update(); + } } Type t = typeof(T); @@ -107,147 +111,160 @@ namespace OpenSim.Data.MySQL List terms = new List(); - MySqlCommand cmd = new MySqlCommand(); - - for (int i = 0 ; i < fields.Length ; i++) + using (MySqlCommand cmd = new MySqlCommand()) { - cmd.Parameters.AddWithValue(fields[i], keys[i]); - terms.Add("`" + fields[i] + "` = ?" + fields[i]); + for (int i = 0 ; i < fields.Length ; i++) + { + cmd.Parameters.AddWithValue(fields[i], keys[i]); + terms.Add("`" + fields[i] + "` = ?" + fields[i]); + } + + string where = String.Join(" and ", terms.ToArray()); + + string query = String.Format("select * from {0} where {1}", + m_Realm, where); + + cmd.CommandText = query; + + return DoQuery(cmd); } - - string where = String.Join(" and ", terms.ToArray()); - - string query = String.Format("select * from {0} where {1}", - m_Realm, where); - - cmd.CommandText = query; - - return DoQuery(cmd); } protected T[] DoQuery(MySqlCommand cmd) { - IDataReader reader = ExecuteReader(cmd); - if (reader == null) - return new T[0]; - - CheckColumnNames(reader); - List result = new List(); - while (reader.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - T row = new T(); + dbcon.Open(); + cmd.Connection = dbcon; - foreach (string name in m_Fields.Keys) + using (IDataReader reader = cmd.ExecuteReader()) { - if (m_Fields[name].GetValue(row) is bool) - { - int v = Convert.ToInt32(reader[name]); - m_Fields[name].SetValue(row, v != 0 ? true : false); - } - else if (m_Fields[name].GetValue(row) is UUID) - { - UUID uuid = UUID.Zero; + if (reader == null) + return new T[0]; - UUID.TryParse(reader[name].ToString(), out uuid); - m_Fields[name].SetValue(row, uuid); - } - else if (m_Fields[name].GetValue(row) is int) + CheckColumnNames(reader); + + while (reader.Read()) { - int v = Convert.ToInt32(reader[name]); - m_Fields[name].SetValue(row, v); - } - else - { - m_Fields[name].SetValue(row, reader[name]); - } - } + T row = new T(); + + foreach (string name in m_Fields.Keys) + { + if (m_Fields[name].GetValue(row) is bool) + { + int v = Convert.ToInt32(reader[name]); + m_Fields[name].SetValue(row, v != 0 ? true : false); + } + else if (m_Fields[name].GetValue(row) is UUID) + { + UUID uuid = UUID.Zero; + + UUID.TryParse(reader[name].ToString(), out uuid); + m_Fields[name].SetValue(row, uuid); + } + else if (m_Fields[name].GetValue(row) is int) + { + int v = Convert.ToInt32(reader[name]); + m_Fields[name].SetValue(row, v); + } + else + { + m_Fields[name].SetValue(row, reader[name]); + } + } - if (m_DataField != null) - { - Dictionary data = - new Dictionary(); + if (m_DataField != null) + { + Dictionary data = + new Dictionary(); - foreach (string col in m_ColumnNames) - { - data[col] = reader[col].ToString(); - if (data[col] == null) - data[col] = String.Empty; + foreach (string col in m_ColumnNames) + { + data[col] = reader[col].ToString(); + if (data[col] == null) + data[col] = String.Empty; + } + + m_DataField.SetValue(row, data); + } + + result.Add(row); } - - m_DataField.SetValue(row, data); } - - result.Add(row); } - CloseReaderCommand(cmd); - return result.ToArray(); } public T[] Get(string where) { - MySqlCommand cmd = new MySqlCommand(); - - string query = String.Format("select * from {0} where {1}", - m_Realm, where); - - cmd.CommandText = query; - - return DoQuery(cmd); + using (MySqlCommand cmd = new MySqlCommand()) + { + + string query = String.Format("select * from {0} where {1}", + m_Realm, where); + + cmd.CommandText = query; + + return DoQuery(cmd); + } } public bool Store(T row) { - MySqlCommand cmd = new MySqlCommand(); - - string query = ""; - List names = new List(); - List values = new List(); - - foreach (FieldInfo fi in m_Fields.Values) + using (MySqlCommand cmd = new MySqlCommand()) { - names.Add(fi.Name); - values.Add("?" + fi.Name); - cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString()); - } - if (m_DataField != null) - { - Dictionary data = + string query = ""; + List names = new List(); + List values = new List(); + + foreach (FieldInfo fi in m_Fields.Values) + { + names.Add(fi.Name); + values.Add("?" + fi.Name); + cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString()); + } + + if (m_DataField != null) + { + Dictionary data = (Dictionary)m_DataField.GetValue(row); - foreach (KeyValuePair kvp in data) - { - names.Add(kvp.Key); - values.Add("?" + kvp.Key); - cmd.Parameters.AddWithValue("?" + kvp.Key, kvp.Value); + foreach (KeyValuePair kvp in data) + { + names.Add(kvp.Key); + values.Add("?" + kvp.Key); + cmd.Parameters.AddWithValue("?" + kvp.Key, kvp.Value); + } } + + query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")"; + + cmd.CommandText = query; + + if (ExecuteNonQuery(cmd) > 0) + return true; + + return false; } - - query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")"; - - cmd.CommandText = query; - - if (ExecuteNonQuery(cmd) > 0) - return true; - - return false; } public bool Delete(string field, string val) { - MySqlCommand cmd = new MySqlCommand(); + using (MySqlCommand cmd = new MySqlCommand()) + { - cmd.CommandText = String.Format("delete from {0} where `{1}` = ?{1}", m_Realm, field); - cmd.Parameters.AddWithValue(field, val); + cmd.CommandText = String.Format("delete from {0} where `{1}` = ?{1}", m_Realm, field); + cmd.Parameters.AddWithValue(field, val); - if (ExecuteNonQuery(cmd) > 0) - return true; + if (ExecuteNonQuery(cmd) > 0) + return true; - return false; + return false; + } } } } diff --git a/OpenSim/Data/MySQL/MySQLGridData.cs b/OpenSim/Data/MySQL/MySQLGridData.cs index 1ec26090b1..f4e7b859d6 100644 --- a/OpenSim/Data/MySQL/MySQLGridData.cs +++ b/OpenSim/Data/MySQL/MySQLGridData.cs @@ -31,6 +31,7 @@ using System.Data; using System.Reflection; using System.Threading; using log4net; +using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; @@ -43,49 +44,9 @@ namespace OpenSim.Data.MySQL { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - /// - /// MySQL Database Manager - /// - private MySQLManager database; - - - /// - /// Better DB manager. Swap-in replacement too. - /// - public Dictionary m_dbconnections = new Dictionary(); - - public int m_maxConnections = 10; - public int m_lastConnect; - - public MySQLSuperManager GetLockedConnection() - { - int lockedCons = 0; - while (true) - { - m_lastConnect++; - - // Overflow protection - if (m_lastConnect == int.MaxValue) - m_lastConnect = 0; - - MySQLSuperManager x = m_dbconnections[m_lastConnect % m_maxConnections]; - if (!x.Locked) - { - x.GetLock(); - return x; - } - - lockedCons++; - if (lockedCons > m_maxConnections) - { - lockedCons = 0; - Thread.Sleep(1000); // Wait some time before searching them again. - m_log.Debug( - "WARNING: All threads are in use. Probable cause: Something didnt release a mutex properly, or high volume of requests inbound."); - } - } - } - + private MySQLManager m_database; + private object m_dbLock = new object(); + private string m_connectionString; override public void Initialise() { @@ -106,49 +67,17 @@ namespace OpenSim.Data.MySQL /// connect string. override public void Initialise(string connect) { - if (connect != String.Empty) - { - database = new MySQLManager(connect); - - m_log.Info("Creating " + m_maxConnections + " DB connections..."); - for (int i = 0; i < m_maxConnections; i++) - { - m_log.Info("Connecting to DB... [" + i + "]"); - MySQLSuperManager msm = new MySQLSuperManager(); - msm.Manager = new MySQLManager(connect); - m_dbconnections.Add(i, msm); - } - - } - else - { - m_log.Warn("Using deprecated mysql_connection.ini. Please update database_connect in GridServer_Config.xml and we'll use that instead"); - IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); - string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); - string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); - string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); - string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); - - database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, - settingPooling, settingPort); - - m_log.Info("Creating " + m_maxConnections + " DB connections..."); - for (int i = 0; i < m_maxConnections; i++) - { - m_log.Info("Connecting to DB... [" + i + "]"); - MySQLSuperManager msm = new MySQLSuperManager(); - msm.Manager = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, - settingPooling, settingPort); - m_dbconnections.Add(i, msm); - } - } + m_connectionString = connect; + m_database = new MySQLManager(connect); // This actually does the roll forward assembly stuff Assembly assem = GetType().Assembly; - Migration m = new Migration(database.Connection, assem, "GridStore"); - m.Update(); + + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + Migration m = new Migration(dbcon, assem, "GridStore"); + m.Update(); + } } /// @@ -156,7 +85,6 @@ namespace OpenSim.Data.MySQL /// override public void Dispose() { - database.Close(); } /// @@ -187,8 +115,6 @@ namespace OpenSim.Data.MySQL /// Array of sim profiles override public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax) { - MySQLSuperManager dbm = GetLockedConnection(); - try { Dictionary param = new Dictionary(); @@ -197,35 +123,33 @@ namespace OpenSim.Data.MySQL param["?xmax"] = xmax.ToString(); param["?ymax"] = ymax.ToString(); - IDbCommand result = - dbm.Manager.Query( - "SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax", - param); - IDataReader reader = result.ExecuteReader(); - - RegionProfileData row; - - List rows = new List(); - - while ((row = dbm.Manager.readSimRow(reader)) != null) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - rows.Add(row); - } - reader.Close(); - result.Dispose(); + dbcon.Open(); - return rows.ToArray(); + using (IDbCommand result = m_database.Query(dbcon, + "SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax", + param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + RegionProfileData row; + + List rows = new List(); + + while ((row = m_database.readSimRow(reader)) != null) + rows.Add(row); + + return rows.ToArray(); + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } /// @@ -236,42 +160,38 @@ namespace OpenSim.Data.MySQL /// A list of sim profiles override public List GetRegionsByName(string namePrefix, uint maxNum) { - MySQLSuperManager dbm = GetLockedConnection(); - try { Dictionary param = new Dictionary(); param["?name"] = namePrefix + "%"; - IDbCommand result = - dbm.Manager.Query( - "SELECT * FROM regions WHERE regionName LIKE ?name", - param); - IDataReader reader = result.ExecuteReader(); - - RegionProfileData row; - - List rows = new List(); - - while (rows.Count < maxNum && (row = dbm.Manager.readSimRow(reader)) != null) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - rows.Add(row); - } - reader.Close(); - result.Dispose(); + dbcon.Open(); - return rows; + using (IDbCommand result = m_database.Query(dbcon, + "SELECT * FROM regions WHERE regionName LIKE ?name", + param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + RegionProfileData row; + + List rows = new List(); + + while (rows.Count < maxNum && (row = m_database.readSimRow(reader)) != null) + rows.Add(row); + + return rows; + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } /// @@ -281,32 +201,30 @@ namespace OpenSim.Data.MySQL /// Sim profile override public RegionProfileData GetProfileByHandle(ulong handle) { - MySQLSuperManager dbm = GetLockedConnection(); - try { Dictionary param = new Dictionary(); - param["?handle"] = handle.ToString(); + param["?handle"] = handle.ToString(); - IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param); - IDataReader reader = result.ExecuteReader(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - RegionProfileData row = dbm.Manager.readSimRow(reader); - reader.Close(); - result.Dispose(); - - return row; + using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM regions WHERE regionHandle = ?handle", param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + RegionProfileData row = m_database.readSimRow(reader); + return row; + } + } } + } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } /// @@ -316,30 +234,29 @@ namespace OpenSim.Data.MySQL /// The sim profile override public RegionProfileData GetProfileByUUID(UUID uuid) { - MySQLSuperManager dbm = GetLockedConnection(); - try { Dictionary param = new Dictionary(); - param["?uuid"] = uuid.ToString(); + param["?uuid"] = uuid.ToString(); - IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE uuid = ?uuid", param); - IDataReader reader = result.ExecuteReader(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - RegionProfileData row = dbm.Manager.readSimRow(reader); - reader.Close(); - result.Dispose(); - - return row; + using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM regions WHERE uuid = ?uuid", param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + RegionProfileData row = m_database.readSimRow(reader); + return row; + } + } } + } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; - } finally - { - dbm.Release(); } } @@ -351,37 +268,36 @@ namespace OpenSim.Data.MySQL { if (regionName.Length > 2) { - MySQLSuperManager dbm = GetLockedConnection(); - try { Dictionary param = new Dictionary(); // Add % because this is a like query. param["?regionName"] = regionName + "%"; - // Order by statement will return shorter matches first. Only returns one record or no record. - IDbCommand result = - dbm.Manager.Query( + + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + // Order by statement will return shorter matches first. Only returns one record or no record. + using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM regions WHERE regionName like ?regionName order by LENGTH(regionName) asc LIMIT 1", - param); - IDataReader reader = result.ExecuteReader(); - - RegionProfileData row = dbm.Manager.readSimRow(reader); - reader.Close(); - result.Dispose(); - - return row; + param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + RegionProfileData row = m_database.readSimRow(reader); + return row; + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } + m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters"); return null; } @@ -393,17 +309,16 @@ namespace OpenSim.Data.MySQL /// Successful? override public DataResponse StoreProfile(RegionProfileData profile) { - MySQLSuperManager dbm = GetLockedConnection(); - try { - if (dbm.Manager.insertRegion(profile)) - { - return DataResponse.RESPONSE_OK; - } - return DataResponse.RESPONSE_ERROR; - } - finally + try { - dbm.Release(); + if (m_database.insertRegion(profile)) + return DataResponse.RESPONSE_OK; + else + return DataResponse.RESPONSE_ERROR; + } + catch + { + return DataResponse.RESPONSE_ERROR; } } @@ -415,18 +330,16 @@ namespace OpenSim.Data.MySQL //public DataResponse DeleteProfile(RegionProfileData profile) override public DataResponse DeleteProfile(string uuid) { - MySQLSuperManager dbm = GetLockedConnection(); - - - try { - if (dbm.Manager.deleteRegion(uuid)) - { - return DataResponse.RESPONSE_OK; - } - return DataResponse.RESPONSE_ERROR; - } finally + try { - dbm.Release(); + if (m_database.deleteRegion(uuid)) + return DataResponse.RESPONSE_OK; + else + return DataResponse.RESPONSE_ERROR; + } + catch + { + return DataResponse.RESPONSE_ERROR; } } @@ -477,33 +390,32 @@ namespace OpenSim.Data.MySQL /// override public ReservationData GetReservationAtPoint(uint x, uint y) { - MySQLSuperManager dbm = GetLockedConnection(); - try { Dictionary param = new Dictionary(); - param["?x"] = x.ToString(); - param["?y"] = y.ToString(); - IDbCommand result = - dbm.Manager.Query( - "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y", - param); - IDataReader reader = result.ExecuteReader(); + param["?x"] = x.ToString(); + param["?y"] = y.ToString(); - ReservationData row = dbm.Manager.readReservationRow(reader); - reader.Close(); - result.Dispose(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - return row; + using (IDbCommand result = m_database.Query(dbcon, + "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y", + param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + ReservationData row = m_database.readReservationRow(reader); + return row; + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; - } finally - { - dbm.Release(); } } } diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index 4b71e3951f..192deb298a 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -26,7 +26,6 @@ */ using System; -using System.IO; using System.Collections.Generic; using System.Reflection; using log4net; @@ -44,14 +43,10 @@ namespace OpenSim.Data.MySQL private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - /// - /// The database manager - /// - private MySQLManager database; + private string m_connectionString; + private object m_dbLock = new object(); - private bool rollbackStore = false; - private bool opengridmode = false; - private string rollbackDir = ""; + public string Version { get { return "1.0.0.0"; } } public void Initialise() { @@ -72,37 +67,17 @@ namespace OpenSim.Data.MySQL /// connect string public void Initialise(string connect) { - if (connect != String.Empty) - { - database = new MySQLManager(connect); - } - else - { - m_log.Warn("Reverting to deprecated mysql_connection.ini file for connection info"); - IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); - string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); - string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); - string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); - string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); - - rollbackDir = GridDataMySqlFile.ParseFileReadValue("rollbackdir"); - rollbackStore = GridDataMySqlFile.ParseFileReadValue("rollback") == "true"; - opengridmode = GridDataMySqlFile.ParseFileReadValue("opengridmode") == "true"; - - if (rollbackStore) - m_log.Warn("[MysqlInventory] Enabling rollback mode in: " + rollbackDir); - - database = - new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, - settingPort); - } + m_connectionString = connect; // This actually does the roll forward assembly stuff Assembly assem = GetType().Assembly; - Migration m = new Migration(database.Connection, assem, "InventoryStore"); - m.Update(); + + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + Migration m = new Migration(dbcon, assem, "InventoryStore"); + m.Update(); + } } /// @@ -123,15 +98,6 @@ namespace OpenSim.Data.MySQL // Do nothing. } - /// - /// Returns the version of this DB provider - /// - /// A string containing the DB provider version - public string Version - { - get { return database.getVersion(); } - } - /// /// Returns a list of items in a specified folder /// @@ -141,36 +107,37 @@ namespace OpenSim.Data.MySQL { try { - lock (database) + lock (m_dbLock) { List items = new List(); - database.CheckConnection(); - - MySqlCommand result = - new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", folderID.ToString()); - MySqlDataReader reader = result.ExecuteReader(); - - while (reader.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - // A null item (because something went wrong) breaks everything in the folder - InventoryItemBase item = readInventoryItem(reader); - if (item != null) - items.Add(item); + dbcon.Open(); + + using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", dbcon)) + { + result.Parameters.AddWithValue("?uuid", folderID.ToString()); + + using (MySqlDataReader reader = result.ExecuteReader()) + { + while (reader.Read()) + { + // A null item (because something went wrong) breaks everything in the folder + InventoryItemBase item = readInventoryItem(reader); + if (item != null) + items.Add(item); + } + + return items; + } + } } - - reader.Close(); - result.Dispose(); - - return items; } } catch (Exception e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } } @@ -184,33 +151,33 @@ namespace OpenSim.Data.MySQL { try { - lock (database) + lock (m_dbLock) { - database.CheckConnection(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - MySqlCommand result = - new MySqlCommand( - "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", user.ToString()); - result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); - MySqlDataReader reader = result.ExecuteReader(); + using (MySqlCommand result = new MySqlCommand( + "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon)) + { + result.Parameters.AddWithValue("?uuid", user.ToString()); + result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); + using (MySqlDataReader reader = result.ExecuteReader()) + { + List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); - - reader.Close(); - result.Dispose(); - - return items; + return items; + } + } + } } } catch (Exception e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } } @@ -225,46 +192,44 @@ namespace OpenSim.Data.MySQL { try { - lock (database) + lock (m_dbLock) { - database.CheckConnection(); - - MySqlCommand result = - new MySqlCommand( - "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", user.ToString()); - result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); - - MySqlDataReader reader = result.ExecuteReader(); - - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - InventoryFolderBase rootFolder = null; - - // There should only ever be one root folder for a user. However, if there's more - // than one we'll simply use the first one rather than failing. It would be even - // nicer to print some message to this effect, but this feels like it's too low a - // to put such a message out, and it's too minor right now to spare the time to - // suitably refactor. - if (items.Count > 0) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - rootFolder = items[0]; + dbcon.Open(); + + using (MySqlCommand result = new MySqlCommand( + "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon)) + { + result.Parameters.AddWithValue("?uuid", user.ToString()); + result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); + + using (MySqlDataReader reader = result.ExecuteReader()) + { + List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + InventoryFolderBase rootFolder = null; + + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. + if (items.Count > 0) + rootFolder = items[0]; + + return rootFolder; + } + } } - - reader.Close(); - result.Dispose(); - - return rootFolder; } } catch (Exception e) { - database.Reconnect(); - m_log.Error(e.ToString()); - throw; + m_log.Error(e.Message, e); + return null; } } @@ -279,31 +244,31 @@ namespace OpenSim.Data.MySQL { try { - lock (database) + lock (m_dbLock) { - database.CheckConnection(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - MySqlCommand result = - new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", parentID.ToString()); - MySqlDataReader reader = result.ExecuteReader(); + using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", dbcon)) + { + result.Parameters.AddWithValue("?uuid", parentID.ToString()); + using (MySqlDataReader reader = result.ExecuteReader()) + { + List items = new List(); - List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - reader.Close(); - result.Dispose(); - - return items; + return items; + } + } + } } } catch (Exception e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } } @@ -378,29 +343,31 @@ namespace OpenSim.Data.MySQL { try { - lock (database) + lock (m_dbLock) { - database.CheckConnection(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - MySqlCommand result = - new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection); - result.Parameters.AddWithValue("?uuid", itemID.ToString()); - MySqlDataReader reader = result.ExecuteReader(); + using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", dbcon)) + { + result.Parameters.AddWithValue("?uuid", itemID.ToString()); - InventoryItemBase item = null; - if (reader.Read()) - item = readInventoryItem(reader); + using (MySqlDataReader reader = result.ExecuteReader()) + { + InventoryItemBase item = null; + if (reader.Read()) + item = readInventoryItem(reader); - reader.Close(); - result.Dispose(); - - return item; + return item; + } + } + } } } catch (Exception e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); } return null; } @@ -425,7 +392,7 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); } return null; @@ -441,151 +408,35 @@ namespace OpenSim.Data.MySQL { try { - lock (database) + lock (m_dbLock) { - database.CheckConnection(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - MySqlCommand result = - new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection); - result.Parameters.AddWithValue("?uuid", folderID.ToString()); - MySqlDataReader reader = result.ExecuteReader(); + using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon)) + { + result.Parameters.AddWithValue("?uuid", folderID.ToString()); - InventoryFolderBase folder = null; - if (reader.Read()) - folder = readInventoryFolder(reader); - reader.Close(); - result.Dispose(); + using (MySqlDataReader reader = result.ExecuteReader()) + { + InventoryFolderBase folder = null; + if (reader.Read()) + folder = readInventoryFolder(reader); - return folder; + return folder; + } + } + } } } catch (Exception e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } } - #region Inventory Rollback-via-.sql Support - /// - /// Not a good SQL escape function, but it'll do the job (if mutilate the data.) - /// Someone may want to write something better here. - /// - /// - /// - private static string cheapSQLescape(string str) - { - str = str.Replace("\\", ""); - str = str.Replace("'", ""); - str = str.Replace("\"", ""); - return "'" + str + "'"; - } - - private static string InventoryItemToSql(InventoryItemBase item) - { - string sql = - "REPLACE /*! INVITEM AT ***$SUBS$*** */ INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName" - + ", inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType" - + ", creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, inventoryGroupPermissions, salePrice, saleType" - + ", creationDate, groupID, groupOwned, flags) VALUES "; - sql += - "(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription" - + ", ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID" - + ", ?inventoryBasePermissions, ?inventoryEveryOnePermissions, ?inventoryGroupPermissions, ?salePrice, ?saleType, ?creationDate" - + ", ?groupID, ?groupOwned, ?flags);\r\n"; - - string itemName = item.Name; - string itemDesc = item.Description; - - sql = sql.Replace("$SUBS$", Util.UnixTimeSinceEpoch().ToString()); - - sql = sql.Replace("?inventoryID", cheapSQLescape(item.ID.ToString())); - sql = sql.Replace("?assetID", cheapSQLescape(item.AssetID.ToString())); - sql = sql.Replace("?assetType", cheapSQLescape(item.AssetType.ToString())); - sql = sql.Replace("?parentFolderID", cheapSQLescape(item.Folder.ToString())); - sql = sql.Replace("?avatarID", cheapSQLescape(item.Owner.ToString())); - sql = sql.Replace("?inventoryName", cheapSQLescape(itemName)); - sql = sql.Replace("?inventoryDescription", cheapSQLescape(itemDesc)); - sql = sql.Replace("?inventoryNextPermissions", cheapSQLescape(item.NextPermissions.ToString())); - sql = sql.Replace("?inventoryCurrentPermissions", cheapSQLescape(item.CurrentPermissions.ToString())); - sql = sql.Replace("?invType", cheapSQLescape(item.InvType.ToString())); - sql = sql.Replace("?creatorID", cheapSQLescape(item.CreatorId)); - sql = sql.Replace("?inventoryBasePermissions", cheapSQLescape(item.BasePermissions.ToString())); - sql = sql.Replace("?inventoryEveryOnePermissions", cheapSQLescape(item.EveryOnePermissions.ToString())); - sql = sql.Replace("?inventoryGroupPermissions", cheapSQLescape(item.GroupPermissions.ToString())); - sql = sql.Replace("?salePrice", cheapSQLescape(item.SalePrice.ToString())); - sql = sql.Replace("?saleType", cheapSQLescape(unchecked((sbyte)item.SaleType).ToString())); - sql = sql.Replace("?creationDate", cheapSQLescape(item.CreationDate.ToString())); - sql = sql.Replace("?groupID", cheapSQLescape(item.GroupID.ToString())); - sql = sql.Replace("?groupOwned", cheapSQLescape(item.GroupOwned.ToString())); - sql = sql.Replace("?flags", cheapSQLescape(item.Flags.ToString())); - - return sql; - } - - private static string InventoryFolderToSql(InventoryFolderBase folder) - { - string sql = - "REPLACE /*! INVFOLDER AT ***$SUBS$*** */ INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES "; - sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version);\r\n"; - - string folderName = folder.Name; - - sql = sql.Replace("$SUBS$", Util.UnixTimeSinceEpoch().ToString()); - - sql = sql.Replace("?folderID", cheapSQLescape(folder.ID.ToString())); - sql = sql.Replace("?agentID", cheapSQLescape(folder.Owner.ToString())); - sql = sql.Replace("?parentFolderID", cheapSQLescape(folder.ParentID.ToString())); - sql = sql.Replace("?folderName", cheapSQLescape(folderName)); - sql = sql.Replace("?type", cheapSQLescape(folder.Type.ToString())); - sql = sql.Replace("?version", cheapSQLescape(folder.Version.ToString())); - - return sql; - } - - private static string getRollbackFolderDate() - { - return DateTime.UtcNow.Year.ToString() + "-" + DateTime.UtcNow.Month.ToString() + "-" + - DateTime.UtcNow.Day.ToString(); - } - - private void StoreRollbackItem(UUID ItemID) - { - if (rollbackStore == true) - { - string todaysPath = RollbackGetTodaysPath(); - - InventoryItemBase imb = getInventoryItem(ItemID); - string sql = InventoryItemToSql(imb); - File.AppendAllText(Path.Combine(todaysPath, imb.Owner.ToString()), sql); - } - } - - private void StoreRollbackFolder(UUID FolderID) - { - if (rollbackStore == true) - { - string todaysPath = RollbackGetTodaysPath(); - - InventoryFolderBase ifb = getInventoryFolder(FolderID); - string sql = InventoryFolderToSql(ifb); - File.AppendAllText(Path.Combine(todaysPath, ifb.Owner.ToString()), sql); - } - } - - private string RollbackGetTodaysPath() - { - if (!Directory.Exists(rollbackDir)) - Directory.CreateDirectory(rollbackDir); - - string todaysPath = Path.Combine(rollbackDir, getRollbackFolderDate()); - if (!Directory.Exists(todaysPath)) - Directory.CreateDirectory(todaysPath); - return todaysPath; - } - #endregion - /// /// Adds a specified item to the database /// @@ -619,46 +470,48 @@ namespace OpenSim.Data.MySQL try { - database.CheckConnection(); - - MySqlCommand result = new MySqlCommand(sql, database.Connection); - result.Parameters.AddWithValue("?inventoryID", item.ID.ToString()); - result.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); - result.Parameters.AddWithValue("?assetType", item.AssetType.ToString()); - result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString()); - result.Parameters.AddWithValue("?avatarID", item.Owner.ToString()); - result.Parameters.AddWithValue("?inventoryName", itemName); - result.Parameters.AddWithValue("?inventoryDescription", itemDesc); - result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString()); - result.Parameters.AddWithValue("?inventoryCurrentPermissions", - item.CurrentPermissions.ToString()); - result.Parameters.AddWithValue("?invType", item.InvType); - result.Parameters.AddWithValue("?creatorID", item.CreatorId); - result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); - result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); - result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); - result.Parameters.AddWithValue("?salePrice", item.SalePrice); - result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType)); - result.Parameters.AddWithValue("?creationDate", item.CreationDate); - result.Parameters.AddWithValue("?groupID", item.GroupID); - result.Parameters.AddWithValue("?groupOwned", item.GroupOwned); - result.Parameters.AddWithValue("?flags", item.Flags); - - lock (database) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - result.ExecuteNonQuery(); - } + dbcon.Open(); - result.Dispose(); + MySqlCommand result = new MySqlCommand(sql, dbcon); + result.Parameters.AddWithValue("?inventoryID", item.ID.ToString()); + result.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); + result.Parameters.AddWithValue("?assetType", item.AssetType.ToString()); + result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString()); + result.Parameters.AddWithValue("?avatarID", item.Owner.ToString()); + result.Parameters.AddWithValue("?inventoryName", itemName); + result.Parameters.AddWithValue("?inventoryDescription", itemDesc); + result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString()); + result.Parameters.AddWithValue("?inventoryCurrentPermissions", + item.CurrentPermissions.ToString()); + result.Parameters.AddWithValue("?invType", item.InvType); + result.Parameters.AddWithValue("?creatorID", item.CreatorId); + result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); + result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); + result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); + result.Parameters.AddWithValue("?salePrice", item.SalePrice); + result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType)); + result.Parameters.AddWithValue("?creationDate", item.CreationDate); + result.Parameters.AddWithValue("?groupID", item.GroupID); + result.Parameters.AddWithValue("?groupOwned", item.GroupOwned); + result.Parameters.AddWithValue("?flags", item.Flags); - result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", database.Connection); - result.Parameters.AddWithValue("?folderID", item.Folder.ToString -()); - lock (database) - { - result.ExecuteNonQuery(); + lock (m_dbLock) + { + result.ExecuteNonQuery(); + } + + result.Dispose(); + + result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon); + result.Parameters.AddWithValue("?folderID", item.Folder.ToString()); + lock (m_dbLock) + { + result.ExecuteNonQuery(); + } + result.Dispose(); } - result.Dispose(); } catch (MySqlException e) { @@ -672,8 +525,6 @@ namespace OpenSim.Data.MySQL /// Inventory item to update public void updateInventoryItem(InventoryItemBase item) { - StoreRollbackItem(item.ID); - addInventoryItem(item); } @@ -683,25 +534,24 @@ namespace OpenSim.Data.MySQL /// The inventory item UUID to delete public void deleteInventoryItem(UUID itemID) { - StoreRollbackItem(itemID); - try { - database.CheckConnection(); - - MySqlCommand cmd = - new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", database.Connection); - cmd.Parameters.AddWithValue("?uuid", itemID.ToString()); - - lock (database) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.ExecuteNonQuery(); + dbcon.Open(); + + MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon); + cmd.Parameters.AddWithValue("?uuid", itemID.ToString()); + + lock (m_dbLock) + { + cmd.ExecuteNonQuery(); + } } } catch (MySqlException e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); } } @@ -732,26 +582,29 @@ namespace OpenSim.Data.MySQL m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length + " to " + folderName.Length + " characters on add folder"); } - database.CheckConnection(); - - MySqlCommand cmd = new MySqlCommand(sql, database.Connection); - cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); - cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString()); - cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); - cmd.Parameters.AddWithValue("?folderName", folderName); - cmd.Parameters.AddWithValue("?type", folder.Type); - cmd.Parameters.AddWithValue("?version", folder.Version); - - try + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - lock (database) + dbcon.Open(); + + MySqlCommand cmd = new MySqlCommand(sql, dbcon); + cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); + cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString()); + cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); + cmd.Parameters.AddWithValue("?folderName", folderName); + cmd.Parameters.AddWithValue("?type", folder.Type); + cmd.Parameters.AddWithValue("?version", folder.Version); + + try { - cmd.ExecuteNonQuery(); + lock (m_dbLock) + { + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); } - } - catch (Exception e) - { - m_log.Error(e.ToString()); } } @@ -761,7 +614,6 @@ namespace OpenSim.Data.MySQL /// Folder to update public void updateInventoryFolder(InventoryFolderBase folder) { - StoreRollbackFolder(folder.ID); addInventoryFolder(folder); } @@ -772,27 +624,28 @@ namespace OpenSim.Data.MySQL /// UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID public void moveInventoryFolder(InventoryFolderBase folder) { - StoreRollbackFolder(folder.ID); - string sql = "UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID"; - database.CheckConnection(); - - MySqlCommand cmd = new MySqlCommand(sql, database.Connection); - cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); - cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); - - try + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - lock (database) + dbcon.Open(); + + MySqlCommand cmd = new MySqlCommand(sql, dbcon); + cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString()); + cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString()); + + try { - cmd.ExecuteNonQuery(); + lock (m_dbLock) + { + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); } - } - catch (Exception e) - { - m_log.Error(e.ToString()); } } @@ -836,95 +689,102 @@ namespace OpenSim.Data.MySQL try { List folders = new List(); - Dictionary> hashtable - = new Dictionary>(); ; + Dictionary> hashtable = new Dictionary>(); ; List parentFolder = new List(); - lock (database) + bool buildResultsFromHashTable = false; + + lock (m_dbLock) { - MySqlCommand result; - MySqlDataReader reader; - bool buildResultsFromHashTable = false; - - database.CheckConnection(); - - /* Fetch the parent folder from the database to determine the agent ID, and if - * we're querying the root of the inventory folder tree */ - result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", parentID.ToString()); - reader = result.ExecuteReader(); - while (reader.Read()) // Should be at most 1 result - parentFolder.Add(readInventoryFolder(reader)); - reader.Close(); - result.Dispose(); - - if (parentFolder.Count >= 1) // No result means parent folder does not exist + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - if (parentFolder[0].ParentID == UUID.Zero) // We are querying the root folder + dbcon.Open(); + + /* Fetch the parent folder from the database to determine the agent ID, and if + * we're querying the root of the inventory folder tree */ + using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon)) { - /* Get all of the agent's folders from the database, put them in a list and return it */ - result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); - reader = result.ExecuteReader(); - while (reader.Read()) + result.Parameters.AddWithValue("?uuid", parentID.ToString()); + + using (MySqlDataReader reader = result.ExecuteReader()) { - InventoryFolderBase curFolder = readInventoryFolder(reader); - if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list - folders.Add(curFolder); + // Should be at most 1 result + while (reader.Read()) + parentFolder.Add(readInventoryFolder(reader)); } - reader.Close(); - result.Dispose(); - } // if we are querying the root folder - else // else we are querying a subtree of the inventory folder tree + } + + if (parentFolder.Count >= 1) // No result means parent folder does not exist { - /* Get all of the agent's folders from the database, put them all in a hash table - * indexed by their parent ID */ - result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); - reader = result.ExecuteReader(); - while (reader.Read()) + if (parentFolder[0].ParentID == UUID.Zero) // We are querying the root folder { - InventoryFolderBase curFolder = readInventoryFolder(reader); - if (hashtable.ContainsKey(curFolder.ParentID)) // Current folder already has a sibling - hashtable[curFolder.ParentID].Add(curFolder); // append to sibling list - else // else current folder has no known (yet) siblings + /* Get all of the agent's folders from the database, put them in a list and return it */ + using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon)) { - List siblingList = new List(); - siblingList.Add(curFolder); - // Current folder has no known (yet) siblings - hashtable.Add(curFolder.ParentID, siblingList); + result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); + + using (MySqlDataReader reader = result.ExecuteReader()) + { + while (reader.Read()) + { + InventoryFolderBase curFolder = readInventoryFolder(reader); + if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list + folders.Add(curFolder); + } + } } - } // while more items to read from the database - reader.Close(); - result.Dispose(); + } // if we are querying the root folder + else // else we are querying a subtree of the inventory folder tree + { + /* Get all of the agent's folders from the database, put them all in a hash table + * indexed by their parent ID */ + using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon)) + { + result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); - // Set flag so we know we need to build the results from the hash table after - // we unlock the database - buildResultsFromHashTable = true; + using (MySqlDataReader reader = result.ExecuteReader()) + { + while (reader.Read()) + { + InventoryFolderBase curFolder = readInventoryFolder(reader); + if (hashtable.ContainsKey(curFolder.ParentID)) // Current folder already has a sibling + hashtable[curFolder.ParentID].Add(curFolder); // append to sibling list + else // else current folder has no known (yet) siblings + { + List siblingList = new List(); + siblingList.Add(curFolder); + // Current folder has no known (yet) siblings + hashtable.Add(curFolder.ParentID, siblingList); + } + } // while more items to read from the database + } + } - } // else we are querying a subtree of the inventory folder tree - } // if folder parentID exists + // Set flag so we know we need to build the results from the hash table after + // we unlock the database + buildResultsFromHashTable = true; - if (buildResultsFromHashTable) - { - /* We have all of the user's folders stored in a hash table indexed by their parent ID - * and we need to return the requested subtree. We will build the requested subtree - * by performing a breadth-first-search on the hash table */ - if (hashtable.ContainsKey(parentID)) - folders.AddRange(hashtable[parentID]); - for (int i = 0; i < folders.Count; i++) // **Note: folders.Count is *not* static - if (hashtable.ContainsKey(folders[i].ID)) - folders.AddRange(hashtable[folders[i].ID]); + } // else we are querying a subtree of the inventory folder tree + } // if folder parentID exists + + if (buildResultsFromHashTable) + { + /* We have all of the user's folders stored in a hash table indexed by their parent ID + * and we need to return the requested subtree. We will build the requested subtree + * by performing a breadth-first-search on the hash table */ + if (hashtable.ContainsKey(parentID)) + folders.AddRange(hashtable[parentID]); + for (int i = 0; i < folders.Count; i++) // **Note: folders.Count is *not* static + if (hashtable.ContainsKey(folders[i].ID)) + folders.AddRange(hashtable[folders[i].ID]); + } } } // lock (database) + return folders; } catch (Exception e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } } @@ -935,25 +795,24 @@ namespace OpenSim.Data.MySQL /// the folder UUID protected void deleteOneFolder(UUID folderID) { - StoreRollbackFolder(folderID); - try { - database.CheckConnection(); - - MySqlCommand cmd = - new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection); - cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); - - lock (database) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.ExecuteNonQuery(); + dbcon.Open(); + + using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", dbcon)) + { + cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); + + lock (m_dbLock) + cmd.ExecuteNonQuery(); + } } } catch (MySqlException e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); } } @@ -963,30 +822,23 @@ namespace OpenSim.Data.MySQL /// the folder UUID protected void deleteItemsInFolder(UUID folderID) { - if (rollbackStore) - { - foreach (InventoryItemBase itemBase in getInventoryInFolder(folderID)) - { - StoreRollbackItem(itemBase.ID); - } - } - try { - database.CheckConnection(); - - MySqlCommand cmd = - new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection); - cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); - - lock (database) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.ExecuteNonQuery(); + dbcon.Open(); + + using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", dbcon)) + { + cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); + + lock (m_dbLock) + cmd.ExecuteNonQuery(); + } } } catch (MySqlException e) { - database.Reconnect(); m_log.Error(e.ToString()); } } @@ -999,80 +851,53 @@ namespace OpenSim.Data.MySQL { List subFolders = getFolderHierarchy(folderID); - // Dont delete in OGM - makes for easier restores if someone sends a malcious command. (just restore the folder entry) - if (opengridmode == false) + //Delete all sub-folders + foreach (InventoryFolderBase f in subFolders) { - //Delete all sub-folders - foreach (InventoryFolderBase f in subFolders) - { - StoreRollbackFolder(f.ID); - deleteOneFolder(f.ID); - - if (rollbackStore) - { - foreach (InventoryItemBase itemBase in getInventoryInFolder(f.ID)) - { - StoreRollbackItem(itemBase.ID); - } - } - deleteItemsInFolder(f.ID); - } + deleteOneFolder(f.ID); + deleteItemsInFolder(f.ID); } - StoreRollbackFolder(folderID); //Delete the actual row deleteOneFolder(folderID); - - // Just delete the folder context in OGM - if (opengridmode == false) - { - if (rollbackStore) - { - foreach (InventoryItemBase itemBase in getInventoryInFolder(folderID)) - { - StoreRollbackItem(itemBase.ID); - } - } - deleteItemsInFolder(folderID); - } + deleteItemsInFolder(folderID); } public List fetchActiveGestures(UUID avatarID) { - MySqlDataReader result = null; - MySqlCommand sqlCmd = null; - lock (database) + lock (m_dbLock) { try { - database.CheckConnection(); - sqlCmd = new MySqlCommand( - "SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags = 1", - database.Connection); - sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString()); - sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); - result = sqlCmd.ExecuteReader(); - - List list = new List(); - while (result.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - InventoryItemBase item = readInventoryItem(result); - if (item != null) - list.Add(item); + dbcon.Open(); + + using (MySqlCommand sqlCmd = new MySqlCommand( + "SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags = 1", dbcon)) + { + sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString()); + sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); + + using (MySqlDataReader result = sqlCmd.ExecuteReader()) + { + List list = new List(); + while (result.Read()) + { + InventoryItemBase item = readInventoryItem(result); + if (item != null) + list.Add(item); + } + return list; + } + } } - return list; } catch (Exception e) { - database.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - if (result != null) result.Close(); - if (sqlCmd != null) sqlCmd.Dispose(); - } } } } diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index 9a4a4bb8dc..a06eec3db9 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -48,75 +48,54 @@ namespace OpenSim.Data.MySQL { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private string m_ConnectionString; - - private MySqlConnection m_Connection = null; + private string m_connectionString; + private object m_dbLock = new object(); public void Initialise(string connectionString) { - m_ConnectionString = connectionString; + m_connectionString = connectionString; - m_Connection = new MySqlConnection(m_ConnectionString); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - m_Connection.Open(); + // Apply new Migrations + // + Assembly assem = GetType().Assembly; + Migration m = new Migration(dbcon, assem, "RegionStore"); + m.Update(); - // Apply new Migrations - // - Assembly assem = GetType().Assembly; - Migration m = new Migration(m_Connection, assem, "RegionStore"); - m.Update(); - - // NOTE: This is a very slow query that times out on regions with a lot of prims. - // I'm told that it is no longer relevant so it's commented out now, but if it - // is relevant it should be added as a console command instead of part of the - // startup phase - // Clean dropped attachments - // - //try - //{ - // using (MySqlCommand cmd = m_Connection.CreateCommand()) - // { - // cmd.CommandText = "delete from prims, primshapes using prims " + - // "left join primshapes on prims.uuid = primshapes.uuid " + - // "where PCode = 9 and State <> 0"; - // ExecuteNonQuery(cmd); - // } - //} - //catch (MySqlException ex) - //{ - // m_log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message); - //} + // Clean dropped attachments + // + try + { + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from prims, primshapes using prims " + + "left join primshapes on prims.uuid = primshapes.uuid " + + "where PCode = 9 and State <> 0"; + ExecuteNonQuery(cmd); + } + } + catch (MySqlException ex) + { + m_log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message); + } + } } private IDataReader ExecuteReader(MySqlCommand c) { IDataReader r = null; - bool errorSeen = false; - while (true) + try { - try - { - r = c.ExecuteReader(); - } - catch (Exception) - { - Thread.Sleep(500); - - m_Connection.Close(); - m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); - m_Connection.Open(); - c.Connection = m_Connection; - - if (!errorSeen) - { - errorSeen = true; - continue; - } - throw; - } - - break; + r = c.ExecuteReader(); + } + catch (Exception e) + { + m_log.Error("[REGION DB]: MySQL error in ExecuteReader: " + e.Message); + throw; } return r; @@ -124,32 +103,14 @@ namespace OpenSim.Data.MySQL private void ExecuteNonQuery(MySqlCommand c) { - bool errorSeen = false; - - while (true) + try { - try - { - c.ExecuteNonQuery(); - } - catch (Exception) - { - Thread.Sleep(500); - - m_Connection.Close(); - m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); - m_Connection.Open(); - c.Connection = m_Connection; - - if (!errorSeen) - { - errorSeen = true; - continue; - } - throw; - } - - break; + c.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error("[REGION DB]: MySQL error in ExecuteNonQuery: " + e.Message); + throw; } } @@ -166,115 +127,119 @@ namespace OpenSim.Data.MySQL if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) return; - lock (m_Connection) + lock (m_dbLock) { - MySqlCommand cmd = m_Connection.CreateCommand(); - - foreach (SceneObjectPart prim in obj.Children.Values) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.Parameters.Clear(); + dbcon.Open(); + MySqlCommand cmd = dbcon.CreateCommand(); - cmd.CommandText = "replace into prims ("+ - "UUID, CreationDate, "+ - "Name, Text, Description, "+ - "SitName, TouchName, ObjectFlags, "+ - "OwnerMask, NextOwnerMask, GroupMask, "+ - "EveryoneMask, BaseMask, PositionX, "+ - "PositionY, PositionZ, GroupPositionX, "+ - "GroupPositionY, GroupPositionZ, VelocityX, "+ - "VelocityY, VelocityZ, AngularVelocityX, "+ - "AngularVelocityY, AngularVelocityZ, "+ - "AccelerationX, AccelerationY, "+ - "AccelerationZ, RotationX, "+ - "RotationY, RotationZ, "+ - "RotationW, SitTargetOffsetX, "+ - "SitTargetOffsetY, SitTargetOffsetZ, "+ - "SitTargetOrientW, SitTargetOrientX, "+ - "SitTargetOrientY, SitTargetOrientZ, "+ - "RegionUUID, CreatorID, "+ - "OwnerID, GroupID, "+ - "LastOwnerID, SceneGroupID, "+ - "PayPrice, PayButton1, "+ - "PayButton2, PayButton3, "+ - "PayButton4, LoopedSound, "+ - "LoopedSoundGain, TextureAnimation, "+ - "OmegaX, OmegaY, OmegaZ, "+ - "CameraEyeOffsetX, CameraEyeOffsetY, "+ - "CameraEyeOffsetZ, CameraAtOffsetX, "+ - "CameraAtOffsetY, CameraAtOffsetZ, "+ - "ForceMouselook, ScriptAccessPin, "+ - "AllowedDrop, DieAtEdge, "+ - "SalePrice, SaleType, "+ - "ColorR, ColorG, ColorB, ColorA, "+ - "ParticleSystem, ClickAction, Material, "+ - "CollisionSound, CollisionSoundVolume, "+ - "PassTouches, "+ - "LinkNumber) values (" + "?UUID, "+ - "?CreationDate, ?Name, ?Text, "+ - "?Description, ?SitName, ?TouchName, "+ - "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, "+ - "?GroupMask, ?EveryoneMask, ?BaseMask, "+ - "?PositionX, ?PositionY, ?PositionZ, "+ - "?GroupPositionX, ?GroupPositionY, "+ - "?GroupPositionZ, ?VelocityX, "+ - "?VelocityY, ?VelocityZ, ?AngularVelocityX, "+ - "?AngularVelocityY, ?AngularVelocityZ, "+ - "?AccelerationX, ?AccelerationY, "+ - "?AccelerationZ, ?RotationX, "+ - "?RotationY, ?RotationZ, "+ - "?RotationW, ?SitTargetOffsetX, "+ - "?SitTargetOffsetY, ?SitTargetOffsetZ, "+ - "?SitTargetOrientW, ?SitTargetOrientX, "+ - "?SitTargetOrientY, ?SitTargetOrientZ, "+ - "?RegionUUID, ?CreatorID, ?OwnerID, "+ - "?GroupID, ?LastOwnerID, ?SceneGroupID, "+ - "?PayPrice, ?PayButton1, ?PayButton2, "+ - "?PayButton3, ?PayButton4, ?LoopedSound, "+ - "?LoopedSoundGain, ?TextureAnimation, "+ - "?OmegaX, ?OmegaY, ?OmegaZ, "+ - "?CameraEyeOffsetX, ?CameraEyeOffsetY, "+ - "?CameraEyeOffsetZ, ?CameraAtOffsetX, "+ - "?CameraAtOffsetY, ?CameraAtOffsetZ, "+ - "?ForceMouselook, ?ScriptAccessPin, "+ - "?AllowedDrop, ?DieAtEdge, ?SalePrice, "+ - "?SaleType, ?ColorR, ?ColorG, "+ - "?ColorB, ?ColorA, ?ParticleSystem, "+ - "?ClickAction, ?Material, ?CollisionSound, "+ - "?CollisionSoundVolume, ?PassTouches, ?LinkNumber)"; + foreach (SceneObjectPart prim in obj.Children.Values) + { + cmd.Parameters.Clear(); - FillPrimCommand(cmd, prim, obj.UUID, regionUUID); + cmd.CommandText = "replace into prims (" + + "UUID, CreationDate, " + + "Name, Text, Description, " + + "SitName, TouchName, ObjectFlags, " + + "OwnerMask, NextOwnerMask, GroupMask, " + + "EveryoneMask, BaseMask, PositionX, " + + "PositionY, PositionZ, GroupPositionX, " + + "GroupPositionY, GroupPositionZ, VelocityX, " + + "VelocityY, VelocityZ, AngularVelocityX, " + + "AngularVelocityY, AngularVelocityZ, " + + "AccelerationX, AccelerationY, " + + "AccelerationZ, RotationX, " + + "RotationY, RotationZ, " + + "RotationW, SitTargetOffsetX, " + + "SitTargetOffsetY, SitTargetOffsetZ, " + + "SitTargetOrientW, SitTargetOrientX, " + + "SitTargetOrientY, SitTargetOrientZ, " + + "RegionUUID, CreatorID, " + + "OwnerID, GroupID, " + + "LastOwnerID, SceneGroupID, " + + "PayPrice, PayButton1, " + + "PayButton2, PayButton3, " + + "PayButton4, LoopedSound, " + + "LoopedSoundGain, TextureAnimation, " + + "OmegaX, OmegaY, OmegaZ, " + + "CameraEyeOffsetX, CameraEyeOffsetY, " + + "CameraEyeOffsetZ, CameraAtOffsetX, " + + "CameraAtOffsetY, CameraAtOffsetZ, " + + "ForceMouselook, ScriptAccessPin, " + + "AllowedDrop, DieAtEdge, " + + "SalePrice, SaleType, " + + "ColorR, ColorG, ColorB, ColorA, " + + "ParticleSystem, ClickAction, Material, " + + "CollisionSound, CollisionSoundVolume, " + + "PassTouches, " + + "LinkNumber) values (" + "?UUID, " + + "?CreationDate, ?Name, ?Text, " + + "?Description, ?SitName, ?TouchName, " + + "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + + "?GroupMask, ?EveryoneMask, ?BaseMask, " + + "?PositionX, ?PositionY, ?PositionZ, " + + "?GroupPositionX, ?GroupPositionY, " + + "?GroupPositionZ, ?VelocityX, " + + "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + + "?AngularVelocityY, ?AngularVelocityZ, " + + "?AccelerationX, ?AccelerationY, " + + "?AccelerationZ, ?RotationX, " + + "?RotationY, ?RotationZ, " + + "?RotationW, ?SitTargetOffsetX, " + + "?SitTargetOffsetY, ?SitTargetOffsetZ, " + + "?SitTargetOrientW, ?SitTargetOrientX, " + + "?SitTargetOrientY, ?SitTargetOrientZ, " + + "?RegionUUID, ?CreatorID, ?OwnerID, " + + "?GroupID, ?LastOwnerID, ?SceneGroupID, " + + "?PayPrice, ?PayButton1, ?PayButton2, " + + "?PayButton3, ?PayButton4, ?LoopedSound, " + + "?LoopedSoundGain, ?TextureAnimation, " + + "?OmegaX, ?OmegaY, ?OmegaZ, " + + "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + + "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + + "?CameraAtOffsetY, ?CameraAtOffsetZ, " + + "?ForceMouselook, ?ScriptAccessPin, " + + "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + + "?SaleType, ?ColorR, ?ColorG, " + + "?ColorB, ?ColorA, ?ParticleSystem, " + + "?ClickAction, ?Material, ?CollisionSound, " + + "?CollisionSoundVolume, ?PassTouches, ?LinkNumber)"; - ExecuteNonQuery(cmd); + FillPrimCommand(cmd, prim, obj.UUID, regionUUID); - cmd.Parameters.Clear(); + ExecuteNonQuery(cmd); - cmd.CommandText = "replace into primshapes ("+ - "UUID, Shape, ScaleX, ScaleY, "+ - "ScaleZ, PCode, PathBegin, PathEnd, "+ - "PathScaleX, PathScaleY, PathShearX, "+ - "PathShearY, PathSkew, PathCurve, "+ - "PathRadiusOffset, PathRevolutions, "+ - "PathTaperX, PathTaperY, PathTwist, "+ - "PathTwistBegin, ProfileBegin, ProfileEnd, "+ - "ProfileCurve, ProfileHollow, Texture, "+ - "ExtraParams, State) values (?UUID, "+ - "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, "+ - "?PCode, ?PathBegin, ?PathEnd, "+ - "?PathScaleX, ?PathScaleY, "+ - "?PathShearX, ?PathShearY, "+ - "?PathSkew, ?PathCurve, ?PathRadiusOffset, "+ - "?PathRevolutions, ?PathTaperX, "+ - "?PathTaperY, ?PathTwist, "+ - "?PathTwistBegin, ?ProfileBegin, "+ - "?ProfileEnd, ?ProfileCurve, "+ - "?ProfileHollow, ?Texture, ?ExtraParams, "+ - "?State)"; + cmd.Parameters.Clear(); - FillShapeCommand(cmd, prim); + cmd.CommandText = "replace into primshapes (" + + "UUID, Shape, ScaleX, ScaleY, " + + "ScaleZ, PCode, PathBegin, PathEnd, " + + "PathScaleX, PathScaleY, PathShearX, " + + "PathShearY, PathSkew, PathCurve, " + + "PathRadiusOffset, PathRevolutions, " + + "PathTaperX, PathTaperY, PathTwist, " + + "PathTwistBegin, ProfileBegin, ProfileEnd, " + + "ProfileCurve, ProfileHollow, Texture, " + + "ExtraParams, State) values (?UUID, " + + "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + + "?PCode, ?PathBegin, ?PathEnd, " + + "?PathScaleX, ?PathScaleY, " + + "?PathShearX, ?PathShearY, " + + "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + + "?PathRevolutions, ?PathTaperX, " + + "?PathTaperY, ?PathTwist, " + + "?PathTwistBegin, ?ProfileBegin, " + + "?ProfileEnd, ?ProfileCurve, " + + "?ProfileHollow, ?Texture, ?ExtraParams, " + + "?State)"; - ExecuteNonQuery(cmd); + FillShapeCommand(cmd, prim); + + ExecuteNonQuery(cmd); + } + cmd.Dispose(); } - cmd.Dispose(); } } @@ -290,22 +255,27 @@ namespace OpenSim.Data.MySQL // cause the loss of a prim, but is cleaner. // It's also faster because it uses the primary key. // - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "select UUID from prims where SceneGroupID= ?UUID"; - cmd.Parameters.AddWithValue("UUID", obj.ToString()); + dbcon.Open(); - using (IDataReader reader = ExecuteReader(cmd)) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - while (reader.Read()) - uuids.Add(new UUID(reader["UUID"].ToString())); - } + cmd.CommandText = "select UUID from prims where SceneGroupID= ?UUID"; + cmd.Parameters.AddWithValue("UUID", obj.ToString()); - // delete the main prims - cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; - ExecuteNonQuery(cmd); + using (IDataReader reader = ExecuteReader(cmd)) + { + while (reader.Read()) + uuids.Add(new UUID(reader["UUID"].ToString())); + } + + // delete the main prims + cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; + ExecuteNonQuery(cmd); + } } } @@ -326,14 +296,19 @@ namespace OpenSim.Data.MySQL /// the Item UUID private void RemoveItems(UUID uuid) { - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "delete from primitems where PrimID = ?PrimID"; - cmd.Parameters.AddWithValue("PrimID", uuid.ToString()); + dbcon.Open(); - ExecuteNonQuery(cmd); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from primitems where PrimID = ?PrimID"; + cmd.Parameters.AddWithValue("PrimID", uuid.ToString()); + + ExecuteNonQuery(cmd); + } } } } @@ -345,29 +320,33 @@ namespace OpenSim.Data.MySQL /// the list of UUIDs private void RemoveShapes(List uuids) { - lock (m_Connection) + lock (m_dbLock) { string sql = "delete from primshapes where "; - - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - for (int i = 0; i < uuids.Count; i++) + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) { - if ((i + 1) == uuids.Count) - {// end of the list - sql += "(UUID = ?UUID" + i + ")"; - } - else + for (int i = 0; i < uuids.Count; i++) { - sql += "(UUID = ?UUID" + i + ") or "; + if ((i + 1) == uuids.Count) + {// end of the list + sql += "(UUID = ?UUID" + i + ")"; + } + else + { + sql += "(UUID = ?UUID" + i + ") or "; + } } + cmd.CommandText = sql; + + for (int i = 0; i < uuids.Count; i++) + cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString()); + + ExecuteNonQuery(cmd); } - cmd.CommandText = sql; - - for (int i = 0; i < uuids.Count; i++) - cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString()); - - ExecuteNonQuery(cmd); } } } @@ -379,30 +358,34 @@ namespace OpenSim.Data.MySQL /// the list of UUIDs private void RemoveItems(List uuids) { - lock (m_Connection) + lock (m_dbLock) { string sql = "delete from primitems where "; - - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - for (int i = 0; i < uuids.Count; i++) + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) { - if ((i + 1) == uuids.Count) + for (int i = 0; i < uuids.Count; i++) { - // end of the list - sql += "(PrimID = ?PrimID" + i + ")"; - } - else - { - sql += "(PrimID = ?PrimID" + i + ") or "; + if ((i + 1) == uuids.Count) + { + // end of the list + sql += "(PrimID = ?PrimID" + i + ")"; + } + else + { + sql += "(PrimID = ?PrimID" + i + ") or "; + } } + cmd.CommandText = sql; + + for (int i = 0; i < uuids.Count; i++) + cmd.Parameters.AddWithValue("PrimID" + i, uuids[i].ToString()); + + ExecuteNonQuery(cmd); } - cmd.CommandText = sql; - - for (int i = 0; i < uuids.Count; i++) - cmd.Parameters.AddWithValue("PrimID" + i, uuids[i].ToString()); - - ExecuteNonQuery(cmd); } } } @@ -417,33 +400,38 @@ namespace OpenSim.Data.MySQL #region Prim Loading - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = - "SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID"; - cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + dbcon.Open(); - using (IDataReader reader = ExecuteReader(cmd)) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - while (reader.Read()) + cmd.CommandText = + "SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + using (IDataReader reader = ExecuteReader(cmd)) { - SceneObjectPart prim = BuildPrim(reader); - if (reader["Shape"] is DBNull) - prim.Shape = PrimitiveBaseShape.Default; - else - prim.Shape = BuildShape(reader); + while (reader.Read()) + { + SceneObjectPart prim = BuildPrim(reader); + if (reader["Shape"] is DBNull) + prim.Shape = PrimitiveBaseShape.Default; + else + prim.Shape = BuildShape(reader); - UUID parentID = new UUID(reader["SceneGroupID"].ToString()); - if (parentID != prim.UUID) - prim.ParentUUID = parentID; + UUID parentID = new UUID(reader["SceneGroupID"].ToString()); + if (parentID != prim.UUID) + prim.ParentUUID = parentID; - prims[prim.UUID] = prim; + prims[prim.UUID] = prim; - ++count; - if (count % ROWS_PER_QUERY == 0) - m_log.Debug("[REGION DB]: Loaded " + count + " prims..."); + ++count; + if (count % ROWS_PER_QUERY == 0) + m_log.Debug("[REGION DB]: Loaded " + count + " prims..."); + } } } } @@ -497,20 +485,25 @@ namespace OpenSim.Data.MySQL // list from DB of all prims which have items and // LoadItems only on those List primsWithInventory = new List(); - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand itemCmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - itemCmd.CommandText = "SELECT DISTINCT primID FROM primitems"; - using (IDataReader itemReader = ExecuteReader(itemCmd)) + dbcon.Open(); + + using (MySqlCommand itemCmd = dbcon.CreateCommand()) { - while (itemReader.Read()) + itemCmd.CommandText = "SELECT DISTINCT primID FROM primitems"; + using (IDataReader itemReader = ExecuteReader(itemCmd)) { - if (!(itemReader["primID"] is DBNull)) + while (itemReader.Read()) { - UUID primID = new UUID(itemReader["primID"].ToString()); - if (prims.ContainsKey(primID)) - primsWithInventory.Add(prims[primID]); + if (!(itemReader["primID"] is DBNull)) + { + UUID primID = new UUID(itemReader["primID"].ToString()); + if (prims.ContainsKey(primID)) + primsWithInventory.Add(prims[primID]); + } } } } @@ -535,23 +528,28 @@ namespace OpenSim.Data.MySQL /// The prim private void LoadItems(SceneObjectPart prim) { - lock (m_Connection) + lock (m_dbLock) { List inventory = new List(); - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "select * from primitems where PrimID = ?PrimID"; - cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString()); + dbcon.Open(); - using (IDataReader reader = ExecuteReader(cmd)) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - while (reader.Read()) - { - TaskInventoryItem item = BuildItem(reader); + cmd.CommandText = "select * from primitems where PrimID = ?PrimID"; + cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString()); - item.ParentID = prim.UUID; // Values in database are often wrong - inventory.Add(item); + using (IDataReader reader = ExecuteReader(cmd)) + { + while (reader.Read()) + { + TaskInventoryItem item = BuildItem(reader); + + item.ParentID = prim.UUID; // Values in database are often wrong + inventory.Add(item); + } } } } @@ -564,22 +562,27 @@ namespace OpenSim.Data.MySQL { m_log.Info("[REGION DB]: Storing terrain"); - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID"; - cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + dbcon.Open(); - ExecuteNonQuery(cmd); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); - cmd.CommandText = "insert into terrain (RegionUUID, " + - "Revision, Heightfield) values (?RegionUUID, " + - "1, ?Heightfield)"; + ExecuteNonQuery(cmd); - cmd.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter)); + cmd.CommandText = "insert into terrain (RegionUUID, " + + "Revision, Heightfield) values (?RegionUUID, " + + "1, ?Heightfield)"; - ExecuteNonQuery(cmd); + cmd.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter)); + + ExecuteNonQuery(cmd); + } } } } @@ -588,38 +591,43 @@ namespace OpenSim.Data.MySQL { double[,] terrain = null; - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "select RegionUUID, Revision, Heightfield " + - "from terrain where RegionUUID = ?RegionUUID " + - "order by Revision desc limit 1"; - cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + dbcon.Open(); - using (IDataReader reader = ExecuteReader(cmd)) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - while (reader.Read()) + cmd.CommandText = "select RegionUUID, Revision, Heightfield " + + "from terrain where RegionUUID = ?RegionUUID " + + "order by Revision desc limit 1"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + using (IDataReader reader = ExecuteReader(cmd)) { - int rev = Convert.ToInt32(reader["Revision"]); - - terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; - terrain.Initialize(); - - using (MemoryStream mstr = new MemoryStream((byte[])reader["Heightfield"])) + while (reader.Read()) { - using (BinaryReader br = new BinaryReader(mstr)) + int rev = Convert.ToInt32(reader["Revision"]); + + terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; + terrain.Initialize(); + + using (MemoryStream mstr = new MemoryStream((byte[])reader["Heightfield"])) { - for (int x = 0; x < (int)Constants.RegionSize; x++) + using (BinaryReader br = new BinaryReader(mstr)) { - for (int y = 0; y < (int)Constants.RegionSize; y++) + for (int x = 0; x < (int)Constants.RegionSize; x++) { - terrain[x, y] = br.ReadDouble(); + for (int y = 0; y < (int)Constants.RegionSize; y++) + { + terrain[x, y] = br.ReadDouble(); + } } } - } - m_log.InfoFormat("[REGION DB]: Loaded terrain revision r{0}", rev); + m_log.InfoFormat("[REGION DB]: Loaded terrain revision r{0}", rev); + } } } } @@ -631,63 +639,73 @@ namespace OpenSim.Data.MySQL public void RemoveLandObject(UUID globalID) { - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "delete from land where UUID = ?UUID"; - cmd.Parameters.AddWithValue("UUID", globalID.ToString()); + dbcon.Open(); - ExecuteNonQuery(cmd); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from land where UUID = ?UUID"; + cmd.Parameters.AddWithValue("UUID", globalID.ToString()); + + ExecuteNonQuery(cmd); + } } } } public void StoreLandObject(ILandObject parcel) { - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "replace into land (UUID, RegionUUID, " + - "LocalLandID, Bitmap, Name, Description, " + - "OwnerUUID, IsGroupOwned, Area, AuctionID, " + - "Category, ClaimDate, ClaimPrice, GroupUUID, " + - "SalePrice, LandStatus, LandFlags, LandingType, " + - "MediaAutoScale, MediaTextureUUID, MediaURL, " + - "MusicURL, PassHours, PassPrice, SnapshotUUID, " + - "UserLocationX, UserLocationY, UserLocationZ, " + - "UserLookAtX, UserLookAtY, UserLookAtZ, " + - "AuthbuyerID, OtherCleanTime, Dwell) values (" + - "?UUID, ?RegionUUID, " + - "?LocalLandID, ?Bitmap, ?Name, ?Description, " + - "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " + - "?Category, ?ClaimDate, ?ClaimPrice, ?GroupUUID, " + - "?SalePrice, ?LandStatus, ?LandFlags, ?LandingType, " + - "?MediaAutoScale, ?MediaTextureUUID, ?MediaURL, " + - "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " + - "?UserLocationX, ?UserLocationY, ?UserLocationZ, " + - "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + - "?AuthbuyerID, ?OtherCleanTime, ?Dwell)"; + dbcon.Open(); - FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID); - - ExecuteNonQuery(cmd); - - cmd.CommandText = "delete from landaccesslist where LandUUID = ?UUID"; - - ExecuteNonQuery(cmd); - - cmd.Parameters.Clear(); - cmd.CommandText = "insert into landaccesslist (LandUUID, " + - "AccessUUID, Flags) values (?LandUUID, ?AccessUUID, " + - "?Flags)"; - - foreach (ParcelManager.ParcelAccessEntry entry in parcel.LandData.ParcelAccessList) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - FillLandAccessCommand(cmd, entry, parcel.LandData.GlobalID); + cmd.CommandText = "replace into land (UUID, RegionUUID, " + + "LocalLandID, Bitmap, Name, Description, " + + "OwnerUUID, IsGroupOwned, Area, AuctionID, " + + "Category, ClaimDate, ClaimPrice, GroupUUID, " + + "SalePrice, LandStatus, LandFlags, LandingType, " + + "MediaAutoScale, MediaTextureUUID, MediaURL, " + + "MusicURL, PassHours, PassPrice, SnapshotUUID, " + + "UserLocationX, UserLocationY, UserLocationZ, " + + "UserLookAtX, UserLookAtY, UserLookAtZ, " + + "AuthbuyerID, OtherCleanTime, Dwell) values (" + + "?UUID, ?RegionUUID, " + + "?LocalLandID, ?Bitmap, ?Name, ?Description, " + + "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " + + "?Category, ?ClaimDate, ?ClaimPrice, ?GroupUUID, " + + "?SalePrice, ?LandStatus, ?LandFlags, ?LandingType, " + + "?MediaAutoScale, ?MediaTextureUUID, ?MediaURL, " + + "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " + + "?UserLocationX, ?UserLocationY, ?UserLocationZ, " + + "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + + "?AuthbuyerID, ?OtherCleanTime, ?Dwell)"; + + FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID); + ExecuteNonQuery(cmd); + + cmd.CommandText = "delete from landaccesslist where LandUUID = ?UUID"; + + ExecuteNonQuery(cmd); + cmd.Parameters.Clear(); + cmd.CommandText = "insert into landaccesslist (LandUUID, " + + "AccessUUID, Flags) values (?LandUUID, ?AccessUUID, " + + "?Flags)"; + + foreach (ParcelManager.ParcelAccessEntry entry in parcel.LandData.ParcelAccessList) + { + FillLandAccessCommand(cmd, entry, parcel.LandData.GlobalID); + ExecuteNonQuery(cmd); + cmd.Parameters.Clear(); + } } } } @@ -697,27 +715,32 @@ namespace OpenSim.Data.MySQL { RegionSettings rs = null; - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "select * from regionsettings where regionUUID = ?RegionUUID"; - cmd.Parameters.AddWithValue("regionUUID", regionUUID); + dbcon.Open(); - using (IDataReader reader = ExecuteReader(cmd)) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - if (reader.Read()) - { - rs = BuildRegionSettings(reader); - rs.OnSave += StoreRegionSettings; - } - else - { - rs = new RegionSettings(); - rs.RegionUUID = regionUUID; - rs.OnSave += StoreRegionSettings; + cmd.CommandText = "select * from regionsettings where regionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("regionUUID", regionUUID); - StoreRegionSettings(rs); + using (IDataReader reader = ExecuteReader(cmd)) + { + if (reader.Read()) + { + rs = BuildRegionSettings(reader); + rs.OnSave += StoreRegionSettings; + } + else + { + rs = new RegionSettings(); + rs.RegionUUID = regionUUID; + rs.OnSave += StoreRegionSettings; + + StoreRegionSettings(rs); + } } } } @@ -728,46 +751,51 @@ namespace OpenSim.Data.MySQL public void StoreRegionSettings(RegionSettings rs) { - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "replace into regionsettings (regionUUID, " + - "block_terraform, block_fly, allow_damage, " + - "restrict_pushing, allow_land_resell, " + - "allow_land_join_divide, block_show_in_search, " + - "agent_limit, object_bonus, maturity, " + - "disable_scripts, disable_collisions, " + - "disable_physics, terrain_texture_1, " + - "terrain_texture_2, terrain_texture_3, " + - "terrain_texture_4, elevation_1_nw, " + - "elevation_2_nw, elevation_1_ne, " + - "elevation_2_ne, elevation_1_se, " + - "elevation_2_se, elevation_1_sw, " + - "elevation_2_sw, water_height, " + - "terrain_raise_limit, terrain_lower_limit, " + - "use_estate_sun, fixed_sun, sun_position, " + - "covenant, Sandbox, sunvectorx, sunvectory, " + - "sunvectorz, loaded_creation_datetime, " + - "loaded_creation_id) values (?RegionUUID, ?BlockTerraform, " + - "?BlockFly, ?AllowDamage, ?RestrictPushing, " + - "?AllowLandResell, ?AllowLandJoinDivide, " + - "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + - "?Maturity, ?DisableScripts, ?DisableCollisions, " + - "?DisablePhysics, ?TerrainTexture1, " + - "?TerrainTexture2, ?TerrainTexture3, " + - "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + - "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + - "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + - "?WaterHeight, ?TerrainRaiseLimit, " + - "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + - "?SunPosition, ?Covenant, ?Sandbox, " + - "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + - "?LoadedCreationDateTime, ?LoadedCreationID)"; + dbcon.Open(); - FillRegionSettingsCommand(cmd, rs); + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "replace into regionsettings (regionUUID, " + + "block_terraform, block_fly, allow_damage, " + + "restrict_pushing, allow_land_resell, " + + "allow_land_join_divide, block_show_in_search, " + + "agent_limit, object_bonus, maturity, " + + "disable_scripts, disable_collisions, " + + "disable_physics, terrain_texture_1, " + + "terrain_texture_2, terrain_texture_3, " + + "terrain_texture_4, elevation_1_nw, " + + "elevation_2_nw, elevation_1_ne, " + + "elevation_2_ne, elevation_1_se, " + + "elevation_2_se, elevation_1_sw, " + + "elevation_2_sw, water_height, " + + "terrain_raise_limit, terrain_lower_limit, " + + "use_estate_sun, fixed_sun, sun_position, " + + "covenant, Sandbox, sunvectorx, sunvectory, " + + "sunvectorz, loaded_creation_datetime, " + + "loaded_creation_id) values (?RegionUUID, ?BlockTerraform, " + + "?BlockFly, ?AllowDamage, ?RestrictPushing, " + + "?AllowLandResell, ?AllowLandJoinDivide, " + + "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + + "?Maturity, ?DisableScripts, ?DisableCollisions, " + + "?DisablePhysics, ?TerrainTexture1, " + + "?TerrainTexture2, ?TerrainTexture3, " + + "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + + "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + + "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + + "?WaterHeight, ?TerrainRaiseLimit, " + + "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + + "?SunPosition, ?Covenant, ?Sandbox, " + + "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + + "?LoadedCreationDateTime, ?LoadedCreationID)"; - ExecuteNonQuery(cmd); + FillRegionSettingsCommand(cmd, rs); + + ExecuteNonQuery(cmd); + } } } } @@ -776,36 +804,41 @@ namespace OpenSim.Data.MySQL { List landData = new List(); - lock (m_Connection) + lock (m_dbLock) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "select * from land where RegionUUID = ?RegionUUID"; - cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); + dbcon.Open(); - using (IDataReader reader = ExecuteReader(cmd)) + using (MySqlCommand cmd = dbcon.CreateCommand()) { - while (reader.Read()) - { - LandData newLand = BuildLandData(reader); - landData.Add(newLand); - } - } - } - - using (MySqlCommand cmd = m_Connection.CreateCommand()) - { - foreach (LandData land in landData) - { - cmd.Parameters.Clear(); - cmd.CommandText = "select * from landaccesslist where LandUUID = ?LandUUID"; - cmd.Parameters.AddWithValue("LandUUID", land.GlobalID.ToString()); + cmd.CommandText = "select * from land where RegionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); using (IDataReader reader = ExecuteReader(cmd)) { while (reader.Read()) { - land.ParcelAccessList.Add(BuildLandAccessData(reader)); + LandData newLand = BuildLandData(reader); + landData.Add(newLand); + } + } + } + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + foreach (LandData land in landData) + { + cmd.Parameters.Clear(); + cmd.CommandText = "select * from landaccesslist where LandUUID = ?LandUUID"; + cmd.Parameters.AddWithValue("LandUUID", land.GlobalID.ToString()); + + using (IDataReader reader = ExecuteReader(cmd)) + { + while (reader.Read()) + { + land.ParcelAccessList.Add(BuildLandAccessData(reader)); + } } } } @@ -1513,41 +1546,46 @@ namespace OpenSim.Data.MySQL public void StorePrimInventory(UUID primID, ICollection items) { - lock (m_Connection) + lock (m_dbLock) { RemoveItems(primID); - MySqlCommand cmd = m_Connection.CreateCommand(); - - if (items.Count == 0) - return; - - cmd.CommandText = "insert into primitems ("+ - "invType, assetType, name, "+ - "description, creationDate, nextPermissions, "+ - "currentPermissions, basePermissions, "+ - "everyonePermissions, groupPermissions, "+ - "flags, itemID, primID, assetID, "+ - "parentFolderID, creatorID, ownerID, "+ - "groupID, lastOwnerID) values (?invType, "+ - "?assetType, ?name, ?description, "+ - "?creationDate, ?nextPermissions, "+ - "?currentPermissions, ?basePermissions, "+ - "?everyonePermissions, ?groupPermissions, "+ - "?flags, ?itemID, ?primID, ?assetID, "+ - "?parentFolderID, ?creatorID, ?ownerID, "+ - "?groupID, ?lastOwnerID)"; - - foreach (TaskInventoryItem item in items) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.Parameters.Clear(); + dbcon.Open(); - FillItemCommand(cmd, item); + MySqlCommand cmd = dbcon.CreateCommand(); - ExecuteNonQuery(cmd); + if (items.Count == 0) + return; + + cmd.CommandText = "insert into primitems (" + + "invType, assetType, name, " + + "description, creationDate, nextPermissions, " + + "currentPermissions, basePermissions, " + + "everyonePermissions, groupPermissions, " + + "flags, itemID, primID, assetID, " + + "parentFolderID, creatorID, ownerID, " + + "groupID, lastOwnerID) values (?invType, " + + "?assetType, ?name, ?description, " + + "?creationDate, ?nextPermissions, " + + "?currentPermissions, ?basePermissions, " + + "?everyonePermissions, ?groupPermissions, " + + "?flags, ?itemID, ?primID, ?assetID, " + + "?parentFolderID, ?creatorID, ?ownerID, " + + "?groupID, ?lastOwnerID)"; + + foreach (TaskInventoryItem item in items) + { + cmd.Parameters.Clear(); + + FillItemCommand(cmd, item); + + ExecuteNonQuery(cmd); + } + + cmd.Dispose(); } - - cmd.Dispose(); } } } diff --git a/OpenSim/Data/MySQL/MySQLLogData.cs b/OpenSim/Data/MySQL/MySQLLogData.cs index 8f67eebad4..304883cb36 100644 --- a/OpenSim/Data/MySQL/MySQLLogData.cs +++ b/OpenSim/Data/MySQL/MySQLLogData.cs @@ -79,14 +79,19 @@ namespace OpenSim.Data.MySQL // This actually does the roll forward assembly stuff Assembly assem = GetType().Assembly; - Migration m = new Migration(database.Connection, assem, "LogStore"); - // TODO: After rev 6000, remove this. People should have - // been rolled onto the new migration code by then. - TestTables(m); + using (MySql.Data.MySqlClient.MySqlConnection dbcon = new MySql.Data.MySqlClient.MySqlConnection(connect)) + { + dbcon.Open(); - m.Update(); + Migration m = new Migration(dbcon, assem, "LogStore"); + // TODO: After rev 6000, remove this. People should have + // been rolled onto the new migration code by then. + TestTables(m); + + m.Update(); + } } /// @@ -128,7 +133,6 @@ namespace OpenSim.Data.MySQL } catch { - database.Reconnect(); } } diff --git a/OpenSim/Data/MySQL/MySQLManager.cs b/OpenSim/Data/MySQL/MySQLManager.cs index 243394e9db..ace20279a9 100644 --- a/OpenSim/Data/MySQL/MySQLManager.cs +++ b/OpenSim/Data/MySQL/MySQLManager.cs @@ -45,16 +45,13 @@ namespace OpenSim.Data.MySQL { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - /// - /// The database connection object - /// - private MySqlConnection dbcon; - /// /// Connection string for ADO.net /// private string connectionString; + private object m_dbLock = new object(); + private const string m_waitTimeoutSelect = "select @@wait_timeout"; /// @@ -109,11 +106,11 @@ namespace OpenSim.Data.MySQL try { connectionString = connect; - dbcon = new MySqlConnection(connectionString); + //dbcon = new MySqlConnection(connectionString); try { - dbcon.Open(); + //dbcon.Open(); } catch(Exception e) { @@ -134,18 +131,21 @@ namespace OpenSim.Data.MySQL /// protected void GetWaitTimeout() { - MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon); - - using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) { - if (dbReader.Read()) - { - m_waitTimeout - = Convert.ToInt32(dbReader["@@wait_timeout"]) * TimeSpan.TicksPerSecond + m_waitTimeoutLeeway; - } + dbcon.Open(); - dbReader.Close(); - cmd.Dispose(); + using (MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon)) + { + using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + { + if (dbReader.Read()) + { + m_waitTimeout + = Convert.ToInt32(dbReader["@@wait_timeout"]) * TimeSpan.TicksPerSecond + m_waitTimeoutLeeway; + } + } + } } m_lastConnectionUse = DateTime.Now.Ticks; @@ -154,66 +154,9 @@ namespace OpenSim.Data.MySQL "[REGION DB]: Connection wait timeout {0} seconds", m_waitTimeout / TimeSpan.TicksPerSecond); } - /// - /// Should be called before any db operation. This checks to see if the connection has not timed out - /// - public void CheckConnection() + public string ConnectionString { - //m_log.Debug("[REGION DB]: Checking connection"); - - long timeNow = DateTime.Now.Ticks; - if (timeNow - m_lastConnectionUse > m_waitTimeout || dbcon.State != ConnectionState.Open) - { - m_log.DebugFormat("[REGION DB]: Database connection has gone away - reconnecting"); - Reconnect(); - } - - // Strictly, we should set this after the actual db operation. But it's more convenient to set here rather - // than require the code to call another method - the timeout leeway should be large enough to cover the - // inaccuracy. - m_lastConnectionUse = timeNow; - } - - /// - /// Get the connection being used - /// - /// MySqlConnection Object - public MySqlConnection Connection - { - get { return dbcon; } - } - - /// - /// Shuts down the database connection - /// - public void Close() - { - dbcon.Close(); - dbcon = null; - } - - /// - /// Reconnects to the database - /// - public void Reconnect() - { - m_log.Info("[REGION DB] Reconnecting database"); - - lock (dbcon) - { - try - { - // Close the DB connection - dbcon.Close(); - // Try reopen it - dbcon = new MySqlConnection(connectionString); - dbcon.Open(); - } - catch (Exception e) - { - m_log.Error("Unable to reconnect to database " + e.ToString()); - } - } + get { return connectionString; } } /// @@ -264,9 +207,13 @@ namespace OpenSim.Data.MySQL /// name of embedded resource public void ExecuteResourceSql(string name) { - CheckConnection(); - MySqlCommand cmd = new MySqlCommand(getResourceString(name), dbcon); - cmd.ExecuteNonQuery(); + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) + { + dbcon.Open(); + + MySqlCommand cmd = new MySqlCommand(getResourceString(name), dbcon); + cmd.ExecuteNonQuery(); + } } /// @@ -275,22 +222,29 @@ namespace OpenSim.Data.MySQL /// sql string to execute public void ExecuteSql(string sql) { - CheckConnection(); - MySqlCommand cmd = new MySqlCommand(sql, dbcon); - cmd.ExecuteNonQuery(); + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) + { + dbcon.Open(); + + MySqlCommand cmd = new MySqlCommand(sql, dbcon); + cmd.ExecuteNonQuery(); + } } public void ExecuteParameterizedSql(string sql, Dictionary parameters) { - CheckConnection(); - - MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand(); - cmd.CommandText = sql; - foreach (KeyValuePair param in parameters) + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) { - cmd.Parameters.AddWithValue(param.Key, param.Value); + dbcon.Open(); + + MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand(); + cmd.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + cmd.Parameters.AddWithValue(param.Key, param.Value); + } + cmd.ExecuteNonQuery(); } - cmd.ExecuteNonQuery(); } /// @@ -299,35 +253,37 @@ namespace OpenSim.Data.MySQL /// public void GetTableVersion(Dictionary tableList) { - lock (dbcon) + lock (m_dbLock) { - CheckConnection(); - - MySqlCommand tablesCmd = - new MySqlCommand( - "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname", - dbcon); - tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database); - - using (MySqlDataReader tables = tablesCmd.ExecuteReader()) + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) { - while (tables.Read()) + dbcon.Open(); + + using (MySqlCommand tablesCmd = new MySqlCommand( + "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname", dbcon)) { - try + tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database); + + using (MySqlDataReader tables = tablesCmd.ExecuteReader()) { - string tableName = (string) tables["TABLE_NAME"]; - string comment = (string) tables["TABLE_COMMENT"]; - if (tableList.ContainsKey(tableName)) + while (tables.Read()) { - tableList[tableName] = comment; + try + { + string tableName = (string)tables["TABLE_NAME"]; + string comment = (string)tables["TABLE_COMMENT"]; + if (tableList.ContainsKey(tableName)) + { + tableList[tableName] = comment; + } + } + catch (Exception e) + { + m_log.Error(e.Message, e); + } } } - catch (Exception e) - { - m_log.Error(e.ToString()); - } } - tables.Close(); } } } @@ -337,28 +293,27 @@ namespace OpenSim.Data.MySQL /// /// Runs a query with protection against SQL Injection by using parameterised input. /// + /// Database connection /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y /// The parameters - index so that @y is indexed as 'y' /// A MySQL DB Command - public IDbCommand Query(string sql, Dictionary parameters) + public IDbCommand Query(MySqlConnection dbcon, string sql, Dictionary parameters) { try { - CheckConnection(); // Not sure if this one is necessary - - MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand(); + MySqlCommand dbcommand = (MySqlCommand)dbcon.CreateCommand(); dbcommand.CommandText = sql; foreach (KeyValuePair param in parameters) { dbcommand.Parameters.AddWithValue(param.Key, param.Value); } - return (IDbCommand) dbcommand; + return (IDbCommand)dbcommand; } catch (Exception e) { // Return null if it fails. - m_log.Error("Failed during Query generation: " + e.ToString()); + m_log.Error("Failed during Query generation: " + e.Message, e); return null; } } @@ -694,8 +649,6 @@ namespace OpenSim.Data.MySQL ret.Add(attachpoint, item); } - r.Close(); - return ret; } @@ -727,12 +680,17 @@ namespace OpenSim.Data.MySQL try { - IDbCommand result = Query(sql, parameters); + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) + { + dbcon.Open(); - if (result.ExecuteNonQuery() == 1) - returnval = true; + IDbCommand result = Query(dbcon, sql, parameters); - result.Dispose(); + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } } catch (Exception e) { @@ -828,12 +786,17 @@ namespace OpenSim.Data.MySQL try { - IDbCommand result = Query(sql, parameters); + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) + { + dbcon.Open(); - if (result.ExecuteNonQuery() == 1) - returnval = true; + IDbCommand result = Query(dbcon, sql, parameters); - result.Dispose(); + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } } catch (Exception e) { @@ -927,12 +890,17 @@ namespace OpenSim.Data.MySQL bool returnval = false; try { - IDbCommand result = Query(sql, parameters); + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) + { + dbcon.Open(); - if (result.ExecuteNonQuery() == 1) - returnval = true; + IDbCommand result = Query(dbcon, sql, parameters); - result.Dispose(); + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } } catch (Exception e) { @@ -1030,18 +998,23 @@ namespace OpenSim.Data.MySQL try { - IDbCommand result = Query(sql, parameters); - - // int x; - // if ((x = result.ExecuteNonQuery()) > 0) - // { - // returnval = true; - // } - if (result.ExecuteNonQuery() > 0) + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) { - returnval = true; + dbcon.Open(); + + IDbCommand result = Query(dbcon, sql, parameters); + + // int x; + // if ((x = result.ExecuteNonQuery()) > 0) + // { + // returnval = true; + // } + if (result.ExecuteNonQuery() > 0) + { + returnval = true; + } + result.Dispose(); } - result.Dispose(); } catch (Exception e) { @@ -1070,18 +1043,23 @@ namespace OpenSim.Data.MySQL { parameters["?uuid"] = uuid; - IDbCommand result = Query(sql, parameters); - - // int x; - // if ((x = result.ExecuteNonQuery()) > 0) - // { - // returnval = true; - // } - if (result.ExecuteNonQuery() > 0) + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) { - returnval = true; + dbcon.Open(); + + IDbCommand result = Query(dbcon, sql, parameters); + + // int x; + // if ((x = result.ExecuteNonQuery()) > 0) + // { + // returnval = true; + // } + if (result.ExecuteNonQuery() > 0) + { + returnval = true; + } + result.Dispose(); } - result.Dispose(); } catch (Exception e) { @@ -1122,18 +1100,23 @@ namespace OpenSim.Data.MySQL try { - IDbCommand result = Query(sql, parameters); - - // int x; - // if ((x = result.ExecuteNonQuery()) > 0) - // { - // returnval = true; - // } - if (result.ExecuteNonQuery() > 0) + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) { - returnval = true; + dbcon.Open(); + + IDbCommand result = Query(dbcon, sql, parameters); + + // int x; + // if ((x = result.ExecuteNonQuery()) > 0) + // { + // returnval = true; + // } + if (result.ExecuteNonQuery() > 0) + { + returnval = true; + } + result.Dispose(); } - result.Dispose(); } catch (Exception e) { @@ -1167,45 +1150,51 @@ namespace OpenSim.Data.MySQL bool returnval = false; // we want to send in byte data, which means we can't just pass down strings - try { - MySqlCommand cmd = (MySqlCommand) dbcon.CreateCommand(); - cmd.CommandText = sql; - cmd.Parameters.AddWithValue("?owner", appearance.Owner.ToString()); - cmd.Parameters.AddWithValue("?serial", appearance.Serial); - cmd.Parameters.AddWithValue("?visual_params", appearance.VisualParams); - cmd.Parameters.AddWithValue("?texture", appearance.Texture.GetBytes()); - cmd.Parameters.AddWithValue("?avatar_height", appearance.AvatarHeight); - cmd.Parameters.AddWithValue("?body_item", appearance.BodyItem.ToString()); - cmd.Parameters.AddWithValue("?body_asset", appearance.BodyAsset.ToString()); - cmd.Parameters.AddWithValue("?skin_item", appearance.SkinItem.ToString()); - cmd.Parameters.AddWithValue("?skin_asset", appearance.SkinAsset.ToString()); - cmd.Parameters.AddWithValue("?hair_item", appearance.HairItem.ToString()); - cmd.Parameters.AddWithValue("?hair_asset", appearance.HairAsset.ToString()); - cmd.Parameters.AddWithValue("?eyes_item", appearance.EyesItem.ToString()); - cmd.Parameters.AddWithValue("?eyes_asset", appearance.EyesAsset.ToString()); - cmd.Parameters.AddWithValue("?shirt_item", appearance.ShirtItem.ToString()); - cmd.Parameters.AddWithValue("?shirt_asset", appearance.ShirtAsset.ToString()); - cmd.Parameters.AddWithValue("?pants_item", appearance.PantsItem.ToString()); - cmd.Parameters.AddWithValue("?pants_asset", appearance.PantsAsset.ToString()); - cmd.Parameters.AddWithValue("?shoes_item", appearance.ShoesItem.ToString()); - cmd.Parameters.AddWithValue("?shoes_asset", appearance.ShoesAsset.ToString()); - cmd.Parameters.AddWithValue("?socks_item", appearance.SocksItem.ToString()); - cmd.Parameters.AddWithValue("?socks_asset", appearance.SocksAsset.ToString()); - cmd.Parameters.AddWithValue("?jacket_item", appearance.JacketItem.ToString()); - cmd.Parameters.AddWithValue("?jacket_asset", appearance.JacketAsset.ToString()); - cmd.Parameters.AddWithValue("?gloves_item", appearance.GlovesItem.ToString()); - cmd.Parameters.AddWithValue("?gloves_asset", appearance.GlovesAsset.ToString()); - cmd.Parameters.AddWithValue("?undershirt_item", appearance.UnderShirtItem.ToString()); - cmd.Parameters.AddWithValue("?undershirt_asset", appearance.UnderShirtAsset.ToString()); - cmd.Parameters.AddWithValue("?underpants_item", appearance.UnderPantsItem.ToString()); - cmd.Parameters.AddWithValue("?underpants_asset", appearance.UnderPantsAsset.ToString()); - cmd.Parameters.AddWithValue("?skirt_item", appearance.SkirtItem.ToString()); - cmd.Parameters.AddWithValue("?skirt_asset", appearance.SkirtAsset.ToString()); + try + { + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) + { + dbcon.Open(); - if (cmd.ExecuteNonQuery() > 0) - returnval = true; + using (MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand()) + { + cmd.CommandText = sql; + cmd.Parameters.AddWithValue("?owner", appearance.Owner.ToString()); + cmd.Parameters.AddWithValue("?serial", appearance.Serial); + cmd.Parameters.AddWithValue("?visual_params", appearance.VisualParams); + cmd.Parameters.AddWithValue("?texture", appearance.Texture.GetBytes()); + cmd.Parameters.AddWithValue("?avatar_height", appearance.AvatarHeight); + cmd.Parameters.AddWithValue("?body_item", appearance.BodyItem.ToString()); + cmd.Parameters.AddWithValue("?body_asset", appearance.BodyAsset.ToString()); + cmd.Parameters.AddWithValue("?skin_item", appearance.SkinItem.ToString()); + cmd.Parameters.AddWithValue("?skin_asset", appearance.SkinAsset.ToString()); + cmd.Parameters.AddWithValue("?hair_item", appearance.HairItem.ToString()); + cmd.Parameters.AddWithValue("?hair_asset", appearance.HairAsset.ToString()); + cmd.Parameters.AddWithValue("?eyes_item", appearance.EyesItem.ToString()); + cmd.Parameters.AddWithValue("?eyes_asset", appearance.EyesAsset.ToString()); + cmd.Parameters.AddWithValue("?shirt_item", appearance.ShirtItem.ToString()); + cmd.Parameters.AddWithValue("?shirt_asset", appearance.ShirtAsset.ToString()); + cmd.Parameters.AddWithValue("?pants_item", appearance.PantsItem.ToString()); + cmd.Parameters.AddWithValue("?pants_asset", appearance.PantsAsset.ToString()); + cmd.Parameters.AddWithValue("?shoes_item", appearance.ShoesItem.ToString()); + cmd.Parameters.AddWithValue("?shoes_asset", appearance.ShoesAsset.ToString()); + cmd.Parameters.AddWithValue("?socks_item", appearance.SocksItem.ToString()); + cmd.Parameters.AddWithValue("?socks_asset", appearance.SocksAsset.ToString()); + cmd.Parameters.AddWithValue("?jacket_item", appearance.JacketItem.ToString()); + cmd.Parameters.AddWithValue("?jacket_asset", appearance.JacketAsset.ToString()); + cmd.Parameters.AddWithValue("?gloves_item", appearance.GlovesItem.ToString()); + cmd.Parameters.AddWithValue("?gloves_asset", appearance.GlovesAsset.ToString()); + cmd.Parameters.AddWithValue("?undershirt_item", appearance.UnderShirtItem.ToString()); + cmd.Parameters.AddWithValue("?undershirt_asset", appearance.UnderShirtAsset.ToString()); + cmd.Parameters.AddWithValue("?underpants_item", appearance.UnderPantsItem.ToString()); + cmd.Parameters.AddWithValue("?underpants_asset", appearance.UnderPantsAsset.ToString()); + cmd.Parameters.AddWithValue("?skirt_item", appearance.SkirtItem.ToString()); + cmd.Parameters.AddWithValue("?skirt_asset", appearance.SkirtAsset.ToString()); - cmd.Dispose(); + if (cmd.ExecuteNonQuery() > 0) + returnval = true; + } + } } catch (Exception e) { @@ -1221,33 +1210,38 @@ namespace OpenSim.Data.MySQL { string sql = "delete from avatarattachments where UUID = ?uuid"; - MySqlCommand cmd = (MySqlCommand) dbcon.CreateCommand(); - cmd.CommandText = sql; - cmd.Parameters.AddWithValue("?uuid", agentID.ToString()); - - cmd.ExecuteNonQuery(); - - if (data == null) - return; - - sql = "insert into avatarattachments (UUID, attachpoint, item, asset) values (?uuid, ?attachpoint, ?item, ?asset)"; - - cmd = (MySqlCommand) dbcon.CreateCommand(); - cmd.CommandText = sql; - - foreach (DictionaryEntry e in data) + using (MySqlConnection dbcon = new MySqlConnection(connectionString)) { - int attachpoint = Convert.ToInt32(e.Key); + dbcon.Open(); - Hashtable item = (Hashtable)e.Value; - - cmd.Parameters.Clear(); + MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand(); + cmd.CommandText = sql; cmd.Parameters.AddWithValue("?uuid", agentID.ToString()); - cmd.Parameters.AddWithValue("?attachpoint", attachpoint); - cmd.Parameters.AddWithValue("?item", item["item"]); - cmd.Parameters.AddWithValue("?asset", item["asset"]); cmd.ExecuteNonQuery(); + + if (data == null) + return; + + sql = "insert into avatarattachments (UUID, attachpoint, item, asset) values (?uuid, ?attachpoint, ?item, ?asset)"; + + cmd = (MySqlCommand)dbcon.CreateCommand(); + cmd.CommandText = sql; + + foreach (DictionaryEntry e in data) + { + int attachpoint = Convert.ToInt32(e.Key); + + Hashtable item = (Hashtable)e.Value; + + cmd.Parameters.Clear(); + cmd.Parameters.AddWithValue("?uuid", agentID.ToString()); + cmd.Parameters.AddWithValue("?attachpoint", attachpoint); + cmd.Parameters.AddWithValue("?item", item["item"]); + cmd.Parameters.AddWithValue("?asset", item["asset"]); + + cmd.ExecuteNonQuery(); + } } } } diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index b0075e8528..a1a08b1934 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -38,16 +38,21 @@ namespace OpenSim.Data.MySQL public class MySqlRegionData : MySqlFramework, IRegionData { private string m_Realm; - private List m_ColumnNames = null; -// private int m_LastExpire = 0; + private List m_ColumnNames; + //private string m_connectionString; public MySqlRegionData(string connectionString, string realm) : base(connectionString) { m_Realm = realm; + m_connectionString = connectionString; - Migration m = new Migration(m_Connection, GetType().Assembly, "GridStore"); - m.Update(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + Migration m = new Migration(dbcon, GetType().Assembly, "GridStore"); + m.Update(); + } } public List Get(string regionName, UUID scopeID) @@ -56,12 +61,13 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - MySqlCommand cmd = new MySqlCommand(command); + using (MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Parameters.AddWithValue("?regionName", regionName); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - cmd.Parameters.AddWithValue("?regionName", regionName); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - - return RunCommand(cmd); + return RunCommand(cmd); + } } public RegionData Get(int posX, int posY, UUID scopeID) @@ -70,17 +76,18 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - MySqlCommand cmd = new MySqlCommand(command); + using (MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Parameters.AddWithValue("?posX", posX.ToString()); + cmd.Parameters.AddWithValue("?posY", posY.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - cmd.Parameters.AddWithValue("?posX", posX.ToString()); - cmd.Parameters.AddWithValue("?posY", posY.ToString()); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + List ret = RunCommand(cmd); + if (ret.Count == 0) + return null; - List ret = RunCommand(cmd); - if (ret.Count == 0) - return null; - - return ret[0]; + return ret[0]; + } } public RegionData Get(UUID regionID, UUID scopeID) @@ -89,16 +96,17 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - MySqlCommand cmd = new MySqlCommand(command); + using (MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + List ret = RunCommand(cmd); + if (ret.Count == 0) + return null; - List ret = RunCommand(cmd); - if (ret.Count == 0) - return null; - - return ret[0]; + return ret[0]; + } } public List Get(int startX, int startY, int endX, int endY, UUID scopeID) @@ -107,74 +115,79 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - MySqlCommand cmd = new MySqlCommand(command); + using (MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Parameters.AddWithValue("?startX", startX.ToString()); + cmd.Parameters.AddWithValue("?startY", startY.ToString()); + cmd.Parameters.AddWithValue("?endX", endX.ToString()); + cmd.Parameters.AddWithValue("?endY", endY.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - cmd.Parameters.AddWithValue("?startX", startX.ToString()); - cmd.Parameters.AddWithValue("?startY", startY.ToString()); - cmd.Parameters.AddWithValue("?endX", endX.ToString()); - cmd.Parameters.AddWithValue("?endY", endY.ToString()); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - - return RunCommand(cmd); + return RunCommand(cmd); + } } public List RunCommand(MySqlCommand cmd) { List retList = new List(); - IDataReader result = ExecuteReader(cmd); - - while (result.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - RegionData ret = new RegionData(); - ret.Data = new Dictionary(); + dbcon.Open(); + cmd.Connection = dbcon; - UUID regionID; - UUID.TryParse(result["uuid"].ToString(), out regionID); - ret.RegionID = regionID; - UUID scope; - UUID.TryParse(result["ScopeID"].ToString(), out scope); - ret.ScopeID = scope; - ret.RegionName = result["regionName"].ToString(); - ret.posX = Convert.ToInt32(result["locX"]); - ret.posY = Convert.ToInt32(result["locY"]); - ret.sizeX = Convert.ToInt32(result["sizeX"]); - ret.sizeY = Convert.ToInt32(result["sizeY"]); - - if (m_ColumnNames == null) + using (IDataReader result = cmd.ExecuteReader()) { - m_ColumnNames = new List(); + while (result.Read()) + { + RegionData ret = new RegionData(); + ret.Data = new Dictionary(); - DataTable schemaTable = result.GetSchemaTable(); - foreach (DataRow row in schemaTable.Rows) + UUID regionID; + UUID.TryParse(result["uuid"].ToString(), out regionID); + ret.RegionID = regionID; + UUID scope; + UUID.TryParse(result["ScopeID"].ToString(), out scope); + ret.ScopeID = scope; + ret.RegionName = result["regionName"].ToString(); + ret.posX = Convert.ToInt32(result["locX"]); + ret.posY = Convert.ToInt32(result["locY"]); + ret.sizeX = Convert.ToInt32(result["sizeX"]); + ret.sizeY = Convert.ToInt32(result["sizeY"]); + + if (m_ColumnNames == null) { - if (row["ColumnName"] != null) - m_ColumnNames.Add(row["ColumnName"].ToString()); + m_ColumnNames = new List(); + + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + { + if (row["ColumnName"] != null) + m_ColumnNames.Add(row["ColumnName"].ToString()); + } } + + foreach (string s in m_ColumnNames) + { + if (s == "uuid") + continue; + if (s == "ScopeID") + continue; + if (s == "regionName") + continue; + if (s == "locX") + continue; + if (s == "locY") + continue; + + ret.Data[s] = result[s].ToString(); + } + + retList.Add(ret); } - - foreach (string s in m_ColumnNames) - { - if (s == "uuid") - continue; - if (s == "ScopeID") - continue; - if (s == "regionName") - continue; - if (s == "locX") - continue; - if (s == "locY") - continue; - - ret.Data[s] = result[s].ToString(); } - - retList.Add(ret); } - result.Close(); - CloseReaderCommand(cmd); - return retList; } @@ -201,76 +214,72 @@ namespace OpenSim.Data.MySQL string[] fields = new List(data.Data.Keys).ToArray(); - MySqlCommand cmd = new MySqlCommand(); - - string update = "update `"+m_Realm+"` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY"; - foreach (string field in fields) + using (MySqlCommand cmd = new MySqlCommand()) { - update += ", "; - update += "`" + field + "` = ?"+field; + string update = "update `" + m_Realm + "` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY"; + foreach (string field in fields) + { + update += ", "; + update += "`" + field + "` = ?" + field; - cmd.Parameters.AddWithValue("?"+field, data.Data[field]); - } + cmd.Parameters.AddWithValue("?" + field, data.Data[field]); + } - update += " where uuid = ?regionID"; + update += " where uuid = ?regionID"; - if (data.ScopeID != UUID.Zero) - update += " and ScopeID = ?scopeID"; + if (data.ScopeID != UUID.Zero) + update += " and ScopeID = ?scopeID"; - cmd.CommandText = update; - cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString()); - cmd.Parameters.AddWithValue("?regionName", data.RegionName); - cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); - cmd.Parameters.AddWithValue("?posX", data.posX.ToString()); - cmd.Parameters.AddWithValue("?posY", data.posY.ToString()); - cmd.Parameters.AddWithValue("?sizeX", data.sizeX.ToString()); - cmd.Parameters.AddWithValue("?sizeY", data.sizeY.ToString()); - - if (ExecuteNonQuery(cmd) < 1) - { - string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `locX`, `locY`, `sizeX`, `sizeY`, `regionName`, `" + - String.Join("`, `", fields) + - "`) values ( ?regionID, ?scopeID, ?posX, ?posY, ?sizeX, ?sizeY, ?regionName, ?" + String.Join(", ?", fields) + ")"; - - cmd.CommandText = insert; + cmd.CommandText = update; + cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString()); + cmd.Parameters.AddWithValue("?regionName", data.RegionName); + cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); + cmd.Parameters.AddWithValue("?posX", data.posX.ToString()); + cmd.Parameters.AddWithValue("?posY", data.posY.ToString()); + cmd.Parameters.AddWithValue("?sizeX", data.sizeX.ToString()); + cmd.Parameters.AddWithValue("?sizeY", data.sizeY.ToString()); if (ExecuteNonQuery(cmd) < 1) { - cmd.Dispose(); - return false; + string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `locX`, `locY`, `sizeX`, `sizeY`, `regionName`, `" + + String.Join("`, `", fields) + + "`) values ( ?regionID, ?scopeID, ?posX, ?posY, ?sizeX, ?sizeY, ?regionName, ?" + String.Join(", ?", fields) + ")"; + + cmd.CommandText = insert; + + if (ExecuteNonQuery(cmd) < 1) + { + return false; + } } } - cmd.Dispose(); - return true; } public bool SetDataItem(UUID regionID, string item, string value) { - MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + - "` set `" + item + "` = ?" + item + " where uuid = ?UUID"); + using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where uuid = ?UUID")) + { + cmd.Parameters.AddWithValue("?" + item, value); + cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); - - cmd.Parameters.AddWithValue("?"+item, value); - cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); - - if (ExecuteNonQuery(cmd) > 0) - return true; + if (ExecuteNonQuery(cmd) > 0) + return true; + } return false; } public bool Delete(UUID regionID) { - MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + - "` where uuid = ?UUID"); + using (MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + "` where uuid = ?UUID")) + { + cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); - - cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); - - if (ExecuteNonQuery(cmd) > 0) - return true; + if (ExecuteNonQuery(cmd) > 0) + return true; + } return false; } diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs index d48144d2e8..3cb00104a8 100644 --- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs @@ -38,16 +38,21 @@ namespace OpenSim.Data.MySQL public class MySqlUserAccountData : MySqlFramework, IUserAccountData { private string m_Realm; - private List m_ColumnNames = null; -// private int m_LastExpire = 0; + private List m_ColumnNames; + // private string m_connectionString; public MySqlUserAccountData(string connectionString, string realm) : base(connectionString) { m_Realm = realm; + m_connectionString = connectionString; - Migration m = new Migration(m_Connection, GetType().Assembly, "UserStore"); - m.Update(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + Migration m = new Migration(dbcon, GetType().Assembly, "UserStore"); + m.Update(); + } } public List Query(UUID principalID, UUID scopeID, string query) @@ -64,49 +69,49 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - MySqlCommand cmd = new MySqlCommand(command); - - cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - - IDataReader result = ExecuteReader(cmd); - - if (result.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - ret.PrincipalID = principalID; - UUID scope; - UUID.TryParse(result["ScopeID"].ToString(), out scope); - ret.ScopeID = scope; + dbcon.Open(); + MySqlCommand cmd = new MySqlCommand(command, dbcon); - if (m_ColumnNames == null) + cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + IDataReader result = cmd.ExecuteReader(); + + if (result.Read()) { - m_ColumnNames = new List(); + ret.PrincipalID = principalID; + UUID scope; + UUID.TryParse(result["ScopeID"].ToString(), out scope); + ret.ScopeID = scope; - DataTable schemaTable = result.GetSchemaTable(); - foreach (DataRow row in schemaTable.Rows) - m_ColumnNames.Add(row["ColumnName"].ToString()); + if (m_ColumnNames == null) + { + m_ColumnNames = new List(); + + DataTable schemaTable = result.GetSchemaTable(); + foreach (DataRow row in schemaTable.Rows) + m_ColumnNames.Add(row["ColumnName"].ToString()); + } + + foreach (string s in m_ColumnNames) + { + if (s == "UUID") + continue; + if (s == "ScopeID") + continue; + + ret.Data[s] = result[s].ToString(); + } + + return ret; } - - foreach (string s in m_ColumnNames) + else { - if (s == "UUID") - continue; - if (s == "ScopeID") - continue; - - ret.Data[s] = result[s].ToString(); + return null; } - - result.Close(); - CloseReaderCommand(cmd); - - return ret; } - - result.Close(); - CloseReaderCommand(cmd); - - return null; } public bool Store(UserAccountData data) @@ -118,61 +123,60 @@ namespace OpenSim.Data.MySQL string[] fields = new List(data.Data.Keys).ToArray(); - MySqlCommand cmd = new MySqlCommand(); - - string update = "update `"+m_Realm+"` set "; - bool first = true; - foreach (string field in fields) + using (MySqlCommand cmd = new MySqlCommand()) { - if (!first) - update += ", "; - update += "`" + field + "` = ?"+field; + string update = "update `" + m_Realm + "` set "; + bool first = true; + foreach (string field in fields) + { + if (!first) + update += ", "; + update += "`" + field + "` = ?" + field; - first = false; + first = false; - cmd.Parameters.AddWithValue("?"+field, data.Data[field]); - } + cmd.Parameters.AddWithValue("?" + field, data.Data[field]); + } - update += " where UUID = ?principalID"; + update += " where UUID = ?principalID"; - if (data.ScopeID != UUID.Zero) - update += " and ScopeID = ?scopeID"; + if (data.ScopeID != UUID.Zero) + update += " and ScopeID = ?scopeID"; - cmd.CommandText = update; - cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); - cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); - - if (ExecuteNonQuery(cmd) < 1) - { - string insert = "insert into `" + m_Realm + "` (`UUID`, `ScopeID`, `" + - String.Join("`, `", fields) + - "`) values (?principalID, ?scopeID, ?" + String.Join(", ?", fields) + ")"; - - cmd.CommandText = insert; + cmd.CommandText = update; + cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); + cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); if (ExecuteNonQuery(cmd) < 1) { - cmd.Dispose(); - return false; + string insert = "insert into `" + m_Realm + "` (`UUID`, `ScopeID`, `" + + String.Join("`, `", fields) + + "`) values (?principalID, ?scopeID, ?" + String.Join(", ?", fields) + ")"; + + cmd.CommandText = insert; + + if (ExecuteNonQuery(cmd) < 1) + { + cmd.Dispose(); + return false; + } } } - cmd.Dispose(); - return true; } public bool SetDataItem(UUID principalID, string item, string value) { - MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + - "` set `" + item + "` = ?" + item + " where UUID = ?UUID"); + using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" + + item + "` = ?" + item + " where UUID = ?UUID")) + { + cmd.Parameters.AddWithValue("?" + item, value); + cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); - - cmd.Parameters.AddWithValue("?"+item, value); - cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); - - if (ExecuteNonQuery(cmd) > 0) - return true; + if (ExecuteNonQuery(cmd) > 0) + return true; + } return false; } diff --git a/OpenSim/Data/MySQL/MySQLUserData.cs b/OpenSim/Data/MySQL/MySQLUserData.cs index 04f872f249..2cf88b876e 100644 --- a/OpenSim/Data/MySQL/MySQLUserData.cs +++ b/OpenSim/Data/MySQL/MySQLUserData.cs @@ -33,6 +33,7 @@ using System.Reflection; using System.Text.RegularExpressions; using System.Threading; using log4net; +using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; @@ -45,15 +46,9 @@ namespace OpenSim.Data.MySQL { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - /// - /// Database manager for MySQL - /// - public MySQLManager database; - - /// - /// Better DB manager. Swap-in replacement too. - /// - public Dictionary m_dbconnections = new Dictionary(); + private MySQLManager m_database; + private string m_connectionString; + private object m_dbLock = new object(); public int m_maxConnections = 10; public int m_lastConnect; @@ -63,7 +58,6 @@ namespace OpenSim.Data.MySQL private string m_userFriendsTableName = "userfriends"; private string m_appearanceTableName = "avatarappearance"; private string m_attachmentsTableName = "avatarattachments"; - private string m_connectString; public override void Initialise() { @@ -71,41 +65,6 @@ namespace OpenSim.Data.MySQL throw new PluginNotInitialisedException(Name); } - public MySQLSuperManager GetLockedConnection(string why) - { - int lockedCons = 0; - while (true) - { - m_lastConnect++; - - // Overflow protection - if (m_lastConnect == int.MaxValue) - m_lastConnect = 0; - - MySQLSuperManager x = m_dbconnections[m_lastConnect%m_maxConnections]; - if (!x.Locked) - { - x.GetLock(); - x.Running = why; - return x; - } - - lockedCons++; - if (lockedCons > m_maxConnections) - { - lockedCons = 0; - Thread.Sleep(1000); // Wait some time before searching them again. - m_log.Debug( - "WARNING: All threads are in use. Probable cause: Something didnt release a mutex properly, or high volume of requests inbound."); - m_log.Debug("Current connections-in-use dump:"); - foreach (KeyValuePair kvp in m_dbconnections) - { - m_log.Debug(kvp.Value.Running); - } - } - } - } - /// /// Initialise User Interface /// Loads and initialises the MySQL storage plugin @@ -115,55 +74,18 @@ namespace OpenSim.Data.MySQL /// connect string. public override void Initialise(string connect) { - if (connect == String.Empty) - { - // TODO: actually do something with our connect string - // instead of loading the second config - - m_log.Warn("Using obsoletely mysql_connection.ini, try using user_source connect string instead"); - IniFile iniFile = new IniFile("mysql_connection.ini"); - string settingHostname = iniFile.ParseFileReadValue("hostname"); - string settingDatabase = iniFile.ParseFileReadValue("database"); - string settingUsername = iniFile.ParseFileReadValue("username"); - string settingPassword = iniFile.ParseFileReadValue("password"); - string settingPooling = iniFile.ParseFileReadValue("pooling"); - string settingPort = iniFile.ParseFileReadValue("port"); - - m_connectString = "Server=" + settingHostname + ";Port=" + settingPort + ";Database=" + settingDatabase + - ";User ID=" + - settingUsername + ";Password=" + settingPassword + ";Pooling=" + settingPooling + ";"; - - m_log.Info("Creating " + m_maxConnections + " DB connections..."); - for (int i = 0; i < m_maxConnections; i++) - { - m_log.Info("Connecting to DB... [" + i + "]"); - MySQLSuperManager msm = new MySQLSuperManager(); - msm.Manager = new MySQLManager(m_connectString); - m_dbconnections.Add(i, msm); - } - - database = new MySQLManager(m_connectString); - } - else - { - m_connectString = connect; - database = new MySQLManager(m_connectString); - - m_log.Info("Creating " + m_maxConnections + " DB connections..."); - for (int i = 0; i < m_maxConnections; i++) - { - m_log.Info("Connecting to DB... [" + i + "]"); - MySQLSuperManager msm = new MySQLSuperManager(); - msm.Manager = new MySQLManager(m_connectString); - m_dbconnections.Add(i, msm); - } - } + m_connectionString = connect; + m_database = new MySQLManager(connect); // This actually does the roll forward assembly stuff Assembly assem = GetType().Assembly; - Migration m = new Migration(database.Connection, assem, "UserStore"); - m.Update(); + using (MySql.Data.MySqlClient.MySqlConnection dbcon = new MySql.Data.MySqlClient.MySqlConnection(m_connectionString)) + { + dbcon.Open(); + Migration m = new Migration(dbcon, assem, "UserStore"); + m.Update(); + } } public override void Dispose() @@ -173,35 +95,32 @@ namespace OpenSim.Data.MySQL // see IUserDataPlugin public override UserProfileData GetUserByName(string user, string last) { - MySQLSuperManager dbm = GetLockedConnection("GetUserByName"); - try { Dictionary param = new Dictionary(); param["?first"] = user; param["?second"] = last; - IDbCommand result = - dbm.Manager.Query( - "SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param); - IDataReader reader = result.ExecuteReader(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - UserProfileData row = dbm.Manager.readUserRow(reader); - - reader.Dispose(); - result.Dispose(); - return row; + using (IDbCommand result = m_database.Query(dbcon, + "SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + UserProfileData row = m_database.readUserRow(reader); + return row; + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } #region User Friends List Data @@ -216,38 +135,38 @@ namespace OpenSim.Data.MySQL param["?friendPerms"] = perms.ToString(); param["?datetimestamp"] = dtvalue.ToString(); - MySQLSuperManager dbm = GetLockedConnection("AddNewUserFriend"); - try { - IDbCommand adder = - dbm.Manager.Query( + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (IDbCommand adder = m_database.Query(dbcon, "INSERT INTO `" + m_userFriendsTableName + "` " + "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + "VALUES " + "(?ownerID,?friendID,?friendPerms,?datetimestamp)", - param); - adder.ExecuteNonQuery(); + param)) + { + adder.ExecuteNonQuery(); + } - adder = - dbm.Manager.Query( + using (IDbCommand adder = m_database.Query(dbcon, "INSERT INTO `" + m_userFriendsTableName + "` " + "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + "VALUES " + "(?friendID,?ownerID,?friendPerms,?datetimestamp)", - param); - adder.ExecuteNonQuery(); + param)) + { + adder.ExecuteNonQuery(); + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return; } - finally - { - dbm.Release(); - } } public override void RemoveUserFriend(UUID friendlistowner, UUID friend) @@ -256,32 +175,32 @@ namespace OpenSim.Data.MySQL param["?ownerID"] = friendlistowner.ToString(); param["?friendID"] = friend.ToString(); - MySQLSuperManager dbm = GetLockedConnection("RemoveUserFriend"); - try { - IDbCommand updater = - dbm.Manager.Query( - "delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID", - param); - updater.ExecuteNonQuery(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - updater = - dbm.Manager.Query( - "delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID", - param); - updater.ExecuteNonQuery(); + using (IDbCommand updater = m_database.Query(dbcon, + "delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID", + param)) + { + updater.ExecuteNonQuery(); + } + + using (IDbCommand updater = m_database.Query(dbcon, + "delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID", + param)) + { + updater.ExecuteNonQuery(); + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return; } - finally - { - dbm.Release(); - } } public override void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms) @@ -291,28 +210,27 @@ namespace OpenSim.Data.MySQL param["?friendID"] = friend.ToString(); param["?friendPerms"] = perms.ToString(); - MySQLSuperManager dbm = GetLockedConnection("UpdateUserFriendPerms"); - try { - IDbCommand updater = - dbm.Manager.Query( - "update " + m_userFriendsTableName + - " SET friendPerms = ?friendPerms " + - "where ownerID = ?ownerID and friendID = ?friendID", - param); - updater.ExecuteNonQuery(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (IDbCommand updater = m_database.Query(dbcon, + "update " + m_userFriendsTableName + + " SET friendPerms = ?friendPerms " + + "where ownerID = ?ownerID and friendID = ?friendID", + param)) + { + updater.ExecuteNonQuery(); + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return; } - finally - { - dbm.Release(); - } } public override List GetUserFriendList(UUID friendlistowner) @@ -322,87 +240,83 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?ownerID"] = friendlistowner.ToString(); - MySQLSuperManager dbm = GetLockedConnection("GetUserFriendList"); - try { - //Left Join userfriends to itself - IDbCommand result = - dbm.Manager.Query( + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + //Left Join userfriends to itself + using (IDbCommand result = m_database.Query(dbcon, "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " + m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" + " where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID", - param); - IDataReader reader = result.ExecuteReader(); + param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + while (reader.Read()) + { + FriendListItem fli = new FriendListItem(); + fli.FriendListOwner = new UUID((string)reader["ownerID"]); + fli.Friend = new UUID((string)reader["friendID"]); + fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]); - while (reader.Read()) - { - FriendListItem fli = new FriendListItem(); - fli.FriendListOwner = new UUID((string) reader["ownerID"]); - fli.Friend = new UUID((string) reader["friendID"]); - fli.FriendPerms = (uint) Convert.ToInt32(reader["friendPerms"]); + // This is not a real column in the database table, it's a joined column from the opposite record + fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]); - // This is not a real column in the database table, it's a joined column from the opposite record - fli.FriendListOwnerPerms = (uint) Convert.ToInt32(reader["ownerperms"]); - - Lfli.Add(fli); + Lfli.Add(fli); + } + } + } } - - reader.Dispose(); - result.Dispose(); } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return Lfli; } - finally - { - dbm.Release(); - } return Lfli; } override public Dictionary GetFriendRegionInfos (List uuids) { - MySQLSuperManager dbm = GetLockedConnection("GetFriendRegionInfos"); Dictionary infos = new Dictionary(); try { - foreach (UUID uuid in uuids) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - Dictionary param = new Dictionary(); - param["?uuid"] = uuid.ToString(); - IDbCommand result = - dbm.Manager.Query("select agentOnline,currentHandle from " + m_agentsTableName + - " where UUID = ?uuid", param); + dbcon.Open(); - IDataReader reader = result.ExecuteReader(); - while (reader.Read()) + foreach (UUID uuid in uuids) { - FriendRegionInfo fri = new FriendRegionInfo(); - fri.isOnline = (sbyte)reader["agentOnline"] != 0; - fri.regionHandle = (ulong)reader["currentHandle"]; + Dictionary param = new Dictionary(); + param["?uuid"] = uuid.ToString(); - infos[uuid] = fri; + using (IDbCommand result = m_database.Query(dbcon, "select agentOnline,currentHandle from " + m_agentsTableName + + " where UUID = ?uuid", param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + while (reader.Read()) + { + FriendRegionInfo fri = new FriendRegionInfo(); + fri.isOnline = (sbyte)reader["agentOnline"] != 0; + fri.regionHandle = (ulong)reader["currentHandle"]; + + infos[uuid] = fri; + } + } + } } - - reader.Dispose(); - result.Dispose(); } } catch (Exception e) { m_log.Warn("[MYSQL]: Got exception on trying to find friends regions:", e); - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); - } - finally - { - dbm.Release(); + m_log.Error(e.Message, e); } return infos; @@ -423,76 +337,73 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%"; param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], String.Empty) + "%"; - MySQLSuperManager dbm = GetLockedConnection("GeneratePickerResults"); try { - IDbCommand result = - dbm.Manager.Query( + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (IDbCommand result = m_database.Query(dbcon, "SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username like ?first AND lastname like ?second LIMIT 100", - param); - IDataReader reader = result.ExecuteReader(); - - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new UUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["lastname"]; - returnlist.Add(user); + param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + while (reader.Read()) + { + AvatarPickerAvatar user = new AvatarPickerAvatar(); + user.AvatarID = new UUID((string)reader["UUID"]); + user.firstName = (string)reader["username"]; + user.lastName = (string)reader["lastname"]; + returnlist.Add(user); + } + } + } } - reader.Dispose(); - result.Dispose(); } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return returnlist; } - finally - { - dbm.Release(); - } } else { - MySQLSuperManager dbm = GetLockedConnection("GeneratePickerResults"); - try { Dictionary param = new Dictionary(); param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%"; - IDbCommand result = - dbm.Manager.Query( + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (IDbCommand result = m_database.Query(dbcon, "SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username like ?first OR lastname like ?first LIMIT 100", - param); - IDataReader reader = result.ExecuteReader(); - - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new UUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["lastname"]; - returnlist.Add(user); + param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + while (reader.Read()) + { + AvatarPickerAvatar user = new AvatarPickerAvatar(); + user.AvatarID = new UUID((string)reader["UUID"]); + user.firstName = (string)reader["username"]; + user.lastName = (string)reader["lastname"]; + returnlist.Add(user); + } + } + } } - reader.Dispose(); - result.Dispose(); } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return returnlist; } - finally - { - dbm.Release(); - } } return returnlist; } @@ -504,32 +415,30 @@ namespace OpenSim.Data.MySQL /// User profile data public override UserProfileData GetUserByUUID(UUID uuid) { - MySQLSuperManager dbm = GetLockedConnection("GetUserByUUID"); try { Dictionary param = new Dictionary(); param["?uuid"] = uuid.ToString(); - IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param); - IDataReader reader = result.ExecuteReader(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - UserProfileData row = dbm.Manager.readUserRow(reader); - - reader.Dispose(); - result.Dispose(); - - return row; + using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + UserProfileData row = m_database.readUserRow(reader); + return row; + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } /// @@ -565,25 +474,18 @@ namespace OpenSim.Data.MySQL param["?UUID"] = AgentID.ToString(); param["?webLoginKey"] = WebLoginKey.ToString(); - MySQLSuperManager dbm = GetLockedConnection("StoreWebLoginKey"); - try { - dbm.Manager.ExecuteParameterizedSql( - "update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " + - "where UUID = ?UUID", - param); + m_database.ExecuteParameterizedSql( + "update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " + + "where UUID = ?UUID", + param); } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return; } - finally - { - dbm.Release(); - } } /// @@ -593,34 +495,30 @@ namespace OpenSim.Data.MySQL /// The users session public override UserAgentData GetAgentByUUID(UUID uuid) { - MySQLSuperManager dbm = GetLockedConnection("GetAgentByUUID"); - try { Dictionary param = new Dictionary(); param["?uuid"] = uuid.ToString(); - IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", - param); - IDataReader reader = result.ExecuteReader(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - UserAgentData row = dbm.Manager.readAgentRow(reader); - - reader.Dispose(); - result.Dispose(); - - return row; + using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + UserAgentData row = m_database.readAgentRow(reader); + return row; + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } /// @@ -634,27 +532,22 @@ namespace OpenSim.Data.MySQL { return; } - MySQLSuperManager dbm = GetLockedConnection("AddNewUserProfile"); try { - dbm.Manager.insertUserRow(user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt, - user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y, - user.HomeLocation.Z, - user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, - user.LastLogin, user.UserInventoryURI, user.UserAssetURI, - user.CanDoMask, user.WantDoMask, - user.AboutText, user.FirstLifeAboutText, user.Image, - user.FirstLifeImage, user.WebLoginKey, user.UserFlags, user.GodLevel, user.CustomType, user.Partner); + m_database.insertUserRow( + user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt, + user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y, + user.HomeLocation.Z, + user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, + user.LastLogin, user.UserInventoryURI, user.UserAssetURI, + user.CanDoMask, user.WantDoMask, + user.AboutText, user.FirstLifeAboutText, user.Image, + user.FirstLifeImage, user.WebLoginKey, user.UserFlags, user.GodLevel, user.CustomType, user.Partner); } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); - } - finally - { - dbm.Release(); + m_log.Error(e.Message, e); } } @@ -668,19 +561,13 @@ namespace OpenSim.Data.MySQL if (agent.ProfileID == zero || agent.SessionID == zero) return; - MySQLSuperManager dbm = GetLockedConnection("AddNewUserAgent"); try { - dbm.Manager.insertAgentRow(agent); + m_database.insertAgentRow(agent); } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); - } - finally - { - dbm.Release(); + m_log.Error(e.Message, e); } } @@ -690,24 +577,24 @@ namespace OpenSim.Data.MySQL /// The profile data to use to update the DB public override bool UpdateUserProfile(UserProfileData user) { - MySQLSuperManager dbm = GetLockedConnection("UpdateUserProfile"); try { - dbm.Manager.updateUserRow(user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt, - user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y, - user.HomeLocation.Z, user.HomeLookAt.X, - user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, user.LastLogin, - user.UserInventoryURI, - user.UserAssetURI, user.CanDoMask, user.WantDoMask, user.AboutText, - user.FirstLifeAboutText, user.Image, user.FirstLifeImage, user.WebLoginKey, - user.UserFlags, user.GodLevel, user.CustomType, user.Partner); - } - finally - { - dbm.Release(); - } + m_database.updateUserRow( + user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt, + user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y, + user.HomeLocation.Z, user.HomeLookAt.X, + user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, user.LastLogin, + user.UserInventoryURI, + user.UserAssetURI, user.CanDoMask, user.WantDoMask, user.AboutText, + user.FirstLifeAboutText, user.Image, user.FirstLifeImage, user.WebLoginKey, + user.UserFlags, user.GodLevel, user.CustomType, user.Partner); - return true; + return true; + } + catch + { + return false; + } } /// @@ -742,41 +629,40 @@ namespace OpenSim.Data.MySQL /// public override AvatarAppearance GetUserAppearance(UUID user) { - MySQLSuperManager dbm = GetLockedConnection("GetUserAppearance"); try { Dictionary param = new Dictionary(); param["?owner"] = user.ToString(); - IDbCommand result = dbm.Manager.Query( - "SELECT * FROM " + m_appearanceTableName + " WHERE owner = ?owner", param); - IDataReader reader = result.ExecuteReader(); - - AvatarAppearance appearance = dbm.Manager.readAppearanceRow(reader); - - reader.Dispose(); - result.Dispose(); - - if (null == appearance) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - m_log.WarnFormat("[USER DB] No appearance found for user {0}", user.ToString()); - return null; - } - - appearance.SetAttachments(GetUserAttachments(user)); + dbcon.Open(); - return appearance; + using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_appearanceTableName + " WHERE owner = ?owner", param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + AvatarAppearance appearance = m_database.readAppearanceRow(reader); + + if (appearance == null) + { + m_log.WarnFormat("[USER DB] No appearance found for user {0}", user.ToString()); + return null; + } + else + { + appearance.SetAttachments(GetUserAttachments(user)); + return appearance; + } + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } /// @@ -787,22 +673,16 @@ namespace OpenSim.Data.MySQL // override public override void UpdateUserAppearance(UUID user, AvatarAppearance appearance) { - MySQLSuperManager dbm = GetLockedConnection("UpdateUserAppearance"); try { appearance.Owner = user; - dbm.Manager.insertAppearanceRow(appearance); + m_database.insertAppearanceRow(appearance); UpdateUserAttachments(user, appearance.GetAttachments()); } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); - } - finally - { - dbm.Release(); + m_log.Error(e.Message, e); } } @@ -829,43 +709,33 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?uuid"] = agentID.ToString(); - MySQLSuperManager dbm = GetLockedConnection("GetUserAttachments"); - try { - IDbCommand result = dbm.Manager.Query( - "SELECT attachpoint, item, asset from " + m_attachmentsTableName + " WHERE UUID = ?uuid", param); - IDataReader reader = result.ExecuteReader(); + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); - Hashtable ret = dbm.Manager.readAttachments(reader); - - reader.Dispose(); - result.Dispose(); - return ret; + using (IDbCommand result = m_database.Query(dbcon, + "SELECT attachpoint, item, asset from " + m_attachmentsTableName + " WHERE UUID = ?uuid", param)) + { + using (IDataReader reader = result.ExecuteReader()) + { + Hashtable ret = m_database.readAttachments(reader); + return ret; + } + } + } } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return null; } - finally - { - dbm.Release(); - } } public void UpdateUserAttachments(UUID agentID, Hashtable data) { - MySQLSuperManager dbm = GetLockedConnection("UpdateUserAttachments"); - try - { - dbm.Manager.writeAttachments(agentID, data); - } - finally - { - dbm.Release(); - } + m_database.writeAttachments(agentID, data); } public override void ResetAttachments(UUID userID) @@ -873,19 +743,10 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?uuid"] = userID.ToString(); - MySQLSuperManager dbm = GetLockedConnection("ResetAttachments"); - - try - { - dbm.Manager.ExecuteParameterizedSql( - "UPDATE " + m_attachmentsTableName + - " SET asset = '00000000-0000-0000-0000-000000000000' WHERE UUID = ?uuid", - param); - } - finally - { - dbm.Release(); - } + m_database.ExecuteParameterizedSql( + "UPDATE " + m_attachmentsTableName + + " SET asset = '00000000-0000-0000-0000-000000000000' WHERE UUID = ?uuid", + param); } public override void LogoutUsers(UUID regionID) @@ -893,25 +754,18 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?regionID"] = regionID.ToString(); - MySQLSuperManager dbm = GetLockedConnection("LogoutUsers"); - try { - dbm.Manager.ExecuteParameterizedSql( - "update " + m_agentsTableName + " SET agentOnline = 0 " + - "where currentRegion = ?regionID", - param); + m_database.ExecuteParameterizedSql( + "update " + m_agentsTableName + " SET agentOnline = 0 " + + "where currentRegion = ?regionID", + param); } catch (Exception e) { - dbm.Manager.Reconnect(); - m_log.Error(e.ToString()); + m_log.Error(e.Message, e); return; } - finally - { - dbm.Release(); - } } } } diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index 0eebc9c7fd..b5866cbf57 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -110,47 +110,58 @@ namespace OpenSim.Data.MySQL public bool MoveItem(string id, string newParent) { - MySqlCommand cmd = new MySqlCommand(); + using (MySqlCommand cmd = new MySqlCommand()) + { - cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm); - cmd.Parameters.AddWithValue("?ParentFolderID", newParent); - cmd.Parameters.AddWithValue("?InventoryID", id); + cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm); + cmd.Parameters.AddWithValue("?ParentFolderID", newParent); + cmd.Parameters.AddWithValue("?InventoryID", id); - return ExecuteNonQuery(cmd) == 0 ? false : true; + return ExecuteNonQuery(cmd) == 0 ? false : true; + } } public XInventoryItem[] GetActiveGestures(UUID principalID) { - MySqlCommand cmd = new MySqlCommand(); - cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags = 1", m_Realm); + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags = 1", m_Realm); - cmd.Parameters.AddWithValue("?uuid", principalID.ToString()); - cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); + cmd.Parameters.AddWithValue("?uuid", principalID.ToString()); + cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); - return DoQuery(cmd); + return DoQuery(cmd); + } } public int GetAssetPermissions(UUID principalID, UUID assetID) { - MySqlCommand cmd = new MySqlCommand(); - - cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm); - cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); - cmd.Parameters.AddWithValue("?AssetID", assetID.ToString()); - - IDataReader reader = ExecuteReader(cmd); - - int perms = 0; - - if (reader.Read()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); + dbcon.Open(); + + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.Connection = dbcon; + + cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); + cmd.Parameters.AddWithValue("?AssetID", assetID.ToString()); + + using (IDataReader reader = cmd.ExecuteReader()) + { + + int perms = 0; + + if (reader.Read()) + { + perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); + } + + return perms; + } + } } - - reader.Close(); - CloseReaderCommand(cmd); - - return perms; } } } diff --git a/OpenSim/Data/MySQL/Tests/MySQLGridTest.cs b/OpenSim/Data/MySQL/Tests/MySQLGridTest.cs index d1d5c2a2e6..82723160e3 100644 --- a/OpenSim/Data/MySQL/Tests/MySQLGridTest.cs +++ b/OpenSim/Data/MySQL/Tests/MySQLGridTest.cs @@ -31,6 +31,7 @@ using OpenSim.Data.Tests; using log4net; using System.Reflection; using OpenSim.Tests.Common; +using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL.Tests { @@ -65,9 +66,13 @@ namespace OpenSim.Data.MySQL.Tests // This actually does the roll forward assembly stuff Assembly assem = GetType().Assembly; - Migration m = new Migration(database.Connection, assem, "GridStore"); - m.Update(); + using (MySqlConnection dbcon = new MySqlConnection(connect)) + { + dbcon.Open(); + Migration m = new Migration(dbcon, assem, "AssetStore"); + m.Update(); + } } [TestFixtureTearDown] From 59f6606ecf4ea7ac3928aec20d1528222961458b Mon Sep 17 00:00:00 2001 From: "Teravus Ovares (Dan Olivares)" Date: Sat, 6 Feb 2010 00:37:07 -0500 Subject: [PATCH 6/8] Endline fix --- .../DynamicTexture/DynamicTextureModule.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 679c871441..e3c7bbf500 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -358,18 +358,18 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture // tmptex.DefaultTexture.Fullbright = true; part.UpdateTexture(tmptex); - } - - if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) - { - if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); - if (oldAsset != null) - { - if (oldAsset.Temporary == true) - { - scene.AssetService.Delete(oldID.ToString()); - } - } + } + + if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) + { + if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); + if (oldAsset != null) + { + if (oldAsset.Temporary == true) + { + scene.AssetService.Delete(oldID.ToString()); + } + } } } From fabf10f1cf29a20332f5ab3b5b467a6954a83b34 Mon Sep 17 00:00:00 2001 From: "Teravus Ovares (Dan Olivares)" Date: Sat, 6 Feb 2010 00:38:22 -0500 Subject: [PATCH 7/8] endline fix 2 --- .../Interregion/RESTInterregionComms.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs index 44458d175f..fa3681a689 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs @@ -436,12 +436,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion } OSDMap resp = new OSDMap(2); - string reason = String.Empty; - uint teleportFlags = 0; - if (args.ContainsKey("teleport_flags")) - { - teleportFlags = args["teleport_flags"].AsUInteger(); - } + string reason = String.Empty; + uint teleportFlags = 0; + if (args.ContainsKey("teleport_flags")) + { + teleportFlags = args["teleport_flags"].AsUInteger(); + } // This is the meaning of POST agent m_regionClient.AdjustUserInformation(aCircuit); From 70a0d7aa4677c240ad12527adde6725df946e572 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 8 Feb 2010 15:21:35 +0000 Subject: [PATCH 8/8] Adding the Careminster "Configger" tool to OpenSim. The tool will, when launched in place of OpenSim, dump the config to stdout. Use -f xml, -f ini or -f mysql to get a condensed ini file, an xml file suitable for webloading, or a set of mysql insert statements. --- .../Tools/Configger/ConfigurationLoader.cs | 251 ++++++++++++++++++ OpenSim/Tools/Configger/Main.cs | 108 ++++++++ OpenSim/Tools/Configger/Util.cs | 79 ++++++ prebuild.xml | 22 ++ 4 files changed, 460 insertions(+) create mode 100644 OpenSim/Tools/Configger/ConfigurationLoader.cs create mode 100644 OpenSim/Tools/Configger/Main.cs create mode 100644 OpenSim/Tools/Configger/Util.cs diff --git a/OpenSim/Tools/Configger/ConfigurationLoader.cs b/OpenSim/Tools/Configger/ConfigurationLoader.cs new file mode 100644 index 0000000000..49af4172a8 --- /dev/null +++ b/OpenSim/Tools/Configger/ConfigurationLoader.cs @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Threading; +using System.Xml; +using log4net; +using Nini.Config; + +namespace Careminster +{ + /// + /// Loads the Configuration files into nIni + /// + public class ConfigurationLoader + { + /// + /// A source of Configuration data + /// + protected IConfigSource m_config; + + /// + /// Console logger + /// + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + public ConfigurationLoader() + { + } + + /// + /// Loads the region configuration + /// + /// Parameters passed into the process when started + /// + /// + /// A configuration that gets passed to modules + public IConfigSource LoadConfigSettings() + { + bool iniFileExists = false; + + List sources = new List(); + + string iniFileName = "OpenSim.ini"; + string iniFilePath = Path.Combine(".", iniFileName); + + if (IsUri(iniFileName)) + { + if (!sources.Contains(iniFileName)) + sources.Add(iniFileName); + } + else + { + if (File.Exists(iniFilePath)) + { + if (!sources.Contains(iniFilePath)) + sources.Add(iniFilePath); + } + } + + m_config = new IniConfigSource(); + m_config.Merge(DefaultConfig()); + + m_log.Info("[CONFIG] Reading configuration settings"); + + if (sources.Count == 0) + { + m_log.FatalFormat("[CONFIG] Could not load any configuration"); + m_log.FatalFormat("[CONFIG] Did you copy the OpenSim.ini.example file to OpenSim.ini?"); + Environment.Exit(1); + } + + for (int i = 0 ; i < sources.Count ; i++) + { + if (ReadConfig(sources[i])) + iniFileExists = true; + AddIncludes(sources); + } + + if (!iniFileExists) + { + m_log.FatalFormat("[CONFIG] Could not load any configuration"); + m_log.FatalFormat("[CONFIG] Configuration exists, but there was an error loading it!"); + Environment.Exit(1); + } + + return m_config; + } + + /// + /// Adds the included files as ini configuration files + /// + /// List of URL strings or filename strings + private void AddIncludes(List sources) + { + //loop over config sources + foreach (IConfig config in m_config.Configs) + { + // Look for Include-* in the key name + string[] keys = config.GetKeys(); + foreach (string k in keys) + { + if (k.StartsWith("Include-")) + { + // read the config file to be included. + string file = config.GetString(k); + if (IsUri(file)) + { + if (!sources.Contains(file)) + sources.Add(file); + } + else + { + string basepath = Path.GetFullPath("."); + string path = Path.Combine(basepath, file); + string[] paths = Util.Glob(path); + foreach (string p in paths) + { + if (!sources.Contains(p)) + sources.Add(p); + } + } + } + } + } + } + /// + /// Check if we can convert the string to a URI + /// + /// String uri to the remote resource + /// true if we can convert the string to a Uri object + bool IsUri(string file) + { + Uri configUri; + + return Uri.TryCreate(file, UriKind.Absolute, + out configUri) && configUri.Scheme == Uri.UriSchemeHttp; + } + + /// + /// Provide same ini loader functionality for standard ini and master ini - file system or XML over http + /// + /// Full path to the ini + /// + private bool ReadConfig(string iniPath) + { + bool success = false; + + if (!IsUri(iniPath)) + { + m_log.InfoFormat("[CONFIG] Reading configuration file {0}", + Path.GetFullPath(iniPath)); + + m_config.Merge(new IniConfigSource(iniPath)); + success = true; + } + else + { + m_log.InfoFormat("[CONFIG] {0} is a http:// URI, fetching ...", + iniPath); + + // The ini file path is a http URI + // Try to read it + // + try + { + XmlReader r = XmlReader.Create(iniPath); + XmlConfigSource cs = new XmlConfigSource(r); + m_config.Merge(cs); + + success = true; + } + catch (Exception e) + { + m_log.FatalFormat("[CONFIG] Exception reading config from URI {0}\n" + e.ToString(), iniPath); + Environment.Exit(1); + } + } + return success; + } + + /// + /// Setup a default config values in case they aren't present in the ini file + /// + /// A Configuration source containing the default configuration + private static IConfigSource DefaultConfig() + { + IConfigSource defaultConfig = new IniConfigSource(); + + { + IConfig config = defaultConfig.Configs["Startup"]; + + if (null == config) + config = defaultConfig.AddConfig("Startup"); + + config.Set("region_info_source", "filesystem"); + + config.Set("gridmode", false); + config.Set("physics", "OpenDynamicsEngine"); + config.Set("meshing", "Meshmerizer"); + config.Set("physical_prim", true); + config.Set("see_into_this_sim_from_neighbor", true); + config.Set("serverside_object_permissions", false); + config.Set("storage_plugin", "OpenSim.Data.SQLite.dll"); + config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3"); + config.Set("storage_prim_inventories", true); + config.Set("startup_console_commands_file", String.Empty); + config.Set("shutdown_console_commands_file", String.Empty); + config.Set("DefaultScriptEngine", "XEngine"); + config.Set("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll"); + // life doesn't really work without this + config.Set("EventQueue", true); + } + + { + IConfig config = defaultConfig.Configs["StandAlone"]; + + if (null == config) + config = defaultConfig.AddConfig("StandAlone"); + + config.Set("accounts_authenticate", true); + config.Set("welcome_message", "Welcome to OpenSimulator"); + config.Set("inventory_plugin", "OpenSim.Data.SQLite.dll"); + config.Set("inventory_source", ""); + config.Set("userDatabase_plugin", "OpenSim.Data.SQLite.dll"); + config.Set("user_source", ""); + config.Set("LibrariesXMLFile", string.Format(".{0}inventory{0}Libraries.xml", Path.DirectorySeparatorChar)); + } + + { + IConfig config = defaultConfig.Configs["Network"]; + + if (null == config) + config = defaultConfig.AddConfig("Network"); + + config.Set("default_location_x", 1000); + config.Set("default_location_y", 1000); + config.Set("grid_send_key", "null"); + config.Set("grid_recv_key", "null"); + config.Set("user_send_key", "null"); + config.Set("user_recv_key", "null"); + config.Set("secure_inventory_server", "true"); + } + + return defaultConfig; + } + + } +} diff --git a/OpenSim/Tools/Configger/Main.cs b/OpenSim/Tools/Configger/Main.cs new file mode 100644 index 0000000000..c85f0d28eb --- /dev/null +++ b/OpenSim/Tools/Configger/Main.cs @@ -0,0 +1,108 @@ +using Nini.Config; +using System; + +namespace Careminster +{ + public class Configger + { + public static int Main(string[] args) + { + ArgvConfigSource argvConfig = new ArgvConfigSource(args); + argvConfig.AddSwitch("Startup", "format", "f"); + + IConfig startupConfig = argvConfig.Configs["Startup"]; + + string format = startupConfig.GetString("format", "ini"); + + ConfigurationLoader loader = new ConfigurationLoader(); + + IConfigSource s = loader.LoadConfigSettings(); + + if (format == "mysql") + { + foreach (IConfig c in s.Configs) + { + foreach (string k in c.GetKeys()) + { + string v = c.GetString(k); + + if (k.StartsWith("Include-")) + continue; + Console.WriteLine("insert ignore into config (section, name, value) values ('{0}', '{1}', '{2}');", c.Name, k, v); + } + } + } + else if (format == "xml") + { + Console.WriteLine(""); + + foreach (IConfig c in s.Configs) + { + int count = 0; + + foreach (string k in c.GetKeys()) + { + if (k.StartsWith("Include-")) + continue; + + count++; + } + + if (count > 0) + { + Console.WriteLine("
", c.Name); + + foreach (string k in c.GetKeys()) + { + string v = c.GetString(k); + + if (k.StartsWith("Include-")) + continue; + Console.WriteLine(" ", k, v); + + Console.WriteLine("
"); + } + } + } + Console.WriteLine("
"); + } + else if (format == "ini") + { + foreach (IConfig c in s.Configs) + { + int count = 0; + + foreach (string k in c.GetKeys()) + { + if (k.StartsWith("Include-")) + continue; + + count++; + } + + if (count > 0) + { + Console.WriteLine("[{0}]", c.Name); + + foreach (string k in c.GetKeys()) + { + string v = c.GetString(k); + + if (k.StartsWith("Include-")) + continue; + Console.WriteLine("{0} = \"{1}\"", k, v); + } + + Console.WriteLine(); + } + } + } + else + { + Console.WriteLine("Error: unknown format: {0}", format); + } + + return 0; + } + } +} diff --git a/OpenSim/Tools/Configger/Util.cs b/OpenSim/Tools/Configger/Util.cs new file mode 100644 index 0000000000..6f8aa76411 --- /dev/null +++ b/OpenSim/Tools/Configger/Util.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.IO.Compression; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using log4net; +using Nini.Config; + +namespace Careminster +{ + public static class Util + { + public static string[] Glob(string path) + { + string vol=String.Empty; + + if (Path.VolumeSeparatorChar != Path.DirectorySeparatorChar) + { + string[] vcomps = path.Split(new char[] {Path.VolumeSeparatorChar}, 2, StringSplitOptions.RemoveEmptyEntries); + + if (vcomps.Length > 1) + { + path = vcomps[1]; + vol = vcomps[0]; + } + } + + string[] comps = path.Split(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}, StringSplitOptions.RemoveEmptyEntries); + + // Glob + + path = vol; + if (vol != String.Empty) + path += new String(new char[] {Path.VolumeSeparatorChar, Path.DirectorySeparatorChar}); + else + path = new String(new char[] {Path.DirectorySeparatorChar}); + + List paths = new List(); + List found = new List(); + paths.Add(path); + + int compIndex = -1; + foreach (string c in comps) + { + compIndex++; + + List addpaths = new List(); + foreach (string p in paths) + { + string[] dirs = Directory.GetDirectories(p, c); + + if (dirs.Length != 0) + { + foreach (string dir in dirs) + addpaths.Add(Path.Combine(path, dir)); + } + + // Only add files if that is the last path component + if (compIndex == comps.Length - 1) + { + string[] files = Directory.GetFiles(p, c); + foreach (string f in files) + found.Add(f); + } + } + paths = addpaths; + } + + return found.ToArray(); + } + } +} diff --git a/prebuild.xml b/prebuild.xml index 46a10578de..ac4400dc68 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2886,6 +2886,28 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + +