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;
}