diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs index d85a7efb8f..85a5c08d37 100644 --- a/OpenSim/Data/IXInventoryData.cs +++ b/OpenSim/Data/IXInventoryData.cs @@ -74,9 +74,38 @@ namespace OpenSim.Data bool StoreFolder(XInventoryFolder folder); bool StoreItem(XInventoryItem item); + /// + /// Delete folders where field == val + /// + /// + /// + /// true if the delete was successful, false if it was not bool DeleteFolders(string field, string val); + + /// + /// Delete folders where field1 == val1, field2 == val2... + /// + /// + /// + /// true if the delete was successful, false if it was not + bool DeleteFolders(string[] fields, string[] vals); + + /// + /// Delete items where field == val + /// + /// + /// + /// true if the delete was successful, false if it was not bool DeleteItems(string field, string val); + /// + /// Delete items where field1 == val1, field2 == val2... + /// + /// + /// + /// true if the delete was successful, false if it was not + bool DeleteItems(string[] fields, string[] vals); + bool MoveItem(string id, string newParent); XInventoryItem[] GetActiveGestures(UUID principalID); int GetAssetPermissions(UUID principalID, UUID assetID); diff --git a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs index f5492b3050..317afac493 100644 --- a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs +++ b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs @@ -335,24 +335,35 @@ namespace OpenSim.Data.MSSQL } } - public virtual bool Delete(string field, string val) + public virtual bool Delete(string field, string key) { + return Delete(new string[] { field }, new string[] { key }); + } + + public virtual bool Delete(string[] fields, string[] keys) + { + if (fields.Length != keys.Length) + return false; + + List terms = new List(); + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand()) { - string deleteCommand = String.Format("DELETE FROM {0} WHERE [{1}] = @{1}", m_Realm, field); - cmd.CommandText = deleteCommand; - - cmd.Parameters.Add(m_database.CreateParameter(field, val)); - cmd.Connection = conn; - conn.Open(); - - if (cmd.ExecuteNonQuery() > 0) + for (int i = 0; i < fields.Length; i++) { - //m_log.Warn("[MSSQLGenericTable]: " + deleteCommand); - return true; + cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i])); + terms.Add("[" + fields[i] + "] = @" + fields[i]); } - return false; + + string where = String.Join(" AND ", terms.ToArray()); + + string query = String.Format("DELETE * FROM {0} WHERE {1}", m_Realm, where); + + cmd.Connection = conn; + cmd.CommandText = query; + conn.Open(); + return cmd.ExecuteNonQuery() > 0; } } } diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs index 5bc4fe41e5..01689a43e6 100644 --- a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs +++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs @@ -79,11 +79,21 @@ namespace OpenSim.Data.MSSQL return m_Folders.Delete(field, val); } + public bool DeleteFolders(string[] fields, string[] vals) + { + return m_Folders.Delete(fields, vals); + } + public bool DeleteItems(string field, string val) { return m_Items.Delete(field, val); } + public bool DeleteItems(string[] fields, string[] vals) + { + return m_Items.Delete(fields, vals); + } + public bool MoveItem(string id, string newParent) { return m_Items.MoveItem(id, newParent); diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index cfffbd8739..754cf725f0 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -264,18 +264,33 @@ namespace OpenSim.Data.MySQL } } - public virtual bool Delete(string field, string val) + public virtual bool Delete(string field, string key) { + return Delete(new string[] { field }, new string[] { key }); + } + + public virtual bool Delete(string[] fields, string[] keys) + { + if (fields.Length != keys.Length) + return false; + + List terms = new List(); + using (MySqlCommand cmd = new MySqlCommand()) { + for (int i = 0 ; i < fields.Length ; i++) + { + cmd.Parameters.AddWithValue(fields[i], keys[i]); + terms.Add("`" + fields[i] + "` = ?" + fields[i]); + } - cmd.CommandText = String.Format("delete from {0} where `{1}` = ?{1}", m_Realm, field); - cmd.Parameters.AddWithValue(field, val); + string where = String.Join(" and ", terms.ToArray()); - if (ExecuteNonQuery(cmd) > 0) - return true; + string query = String.Format("delete from {0} where {1}", m_Realm, where); - return false; + cmd.CommandText = query; + + return ExecuteNonQuery(cmd) > 0; } } } diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index 481da493a3..caf18a4780 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -85,11 +85,21 @@ namespace OpenSim.Data.MySQL return m_Folders.Delete(field, val); } + public bool DeleteFolders(string[] fields, string[] vals) + { + return m_Folders.Delete(fields, vals); + } + public bool DeleteItems(string field, string val) { return m_Items.Delete(field, val); } + public bool DeleteItems(string[] fields, string[] vals) + { + return m_Items.Delete(fields, vals); + } + public bool MoveItem(string id, string newParent) { return m_Items.MoveItem(id, newParent); diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs index 0d7b001e3f..3fb2d3facb 100644 --- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs @@ -258,17 +258,33 @@ namespace OpenSim.Data.SQLite return false; } - public bool Delete(string field, string val) + public virtual bool Delete(string field, string key) { + return Delete(new string[] { field }, new string[] { key }); + } + + public bool Delete(string[] fields, string[] keys) + { + if (fields.Length != keys.Length) + return false; + + List terms = new List(); + SqliteCommand cmd = new SqliteCommand(); - cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field); - cmd.Parameters.Add(new SqliteParameter(field, val)); + for (int i = 0 ; i < fields.Length ; i++) + { + cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i])); + terms.Add("`" + fields[i] + "` = :" + fields[i]); + } - if (ExecuteNonQuery(cmd, m_Connection) > 0) - return true; + string where = String.Join(" and ", terms.ToArray()); - return false; + string query = String.Format("delete * from {0} where {1}", m_Realm, where); + + cmd.CommandText = query; + + return ExecuteNonQuery(cmd, m_Connection) > 0; } } } diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs index ccbd86e119..02edc30707 100644 --- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs @@ -91,11 +91,21 @@ namespace OpenSim.Data.SQLite return m_Folders.Delete(field, val); } + public bool DeleteFolders(string[] fields, string[] vals) + { + return m_Folders.Delete(fields, vals); + } + public bool DeleteItems(string field, string val) { return m_Items.Delete(field, val); } + public bool DeleteItems(string[] fields, string[] vals) + { + return m_Items.Delete(fields, vals); + } + public bool MoveItem(string id, string newParent) { return m_Items.MoveItem(id, newParent); diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 0af35c84ac..a094a02a43 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -411,12 +411,30 @@ namespace OpenSim.Services.InventoryService public virtual bool DeleteItems(UUID principalID, List itemIDs) { if (!m_AllowDelete) - return false; - - // Just use the ID... *facepalms* - // - foreach (UUID id in itemIDs) - m_Database.DeleteItems("inventoryID", id.ToString()); + { + // We must still allow links and links to folders to be deleted, otherwise they will build up + // in the player's inventory until they can no longer log in. Deletions of links due to code bugs or + // similar is inconvenient but on a par with accidental movement of items. The original item is never + // touched. + foreach (UUID id in itemIDs) + { + if (!m_Database.DeleteItems( + new string[] { "inventoryID", "assetType" }, + new string[] { id.ToString(), ((sbyte)AssetType.Link).ToString() })); + { + m_Database.DeleteItems( + new string[] { "inventoryID", "assetType" }, + new string[] { id.ToString(), ((sbyte)AssetType.LinkFolder).ToString() }); + } + } + } + else + { + // Just use the ID... *facepalms* + // + foreach (UUID id in itemIDs) + m_Database.DeleteItems("inventoryID", id.ToString()); + } return true; }