From 909d4dca8211c63444bec553a45a39e91390a5b5 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 9 Nov 2012 00:59:18 +0000 Subject: [PATCH] Update parent inventory folder version numbers when folders are moved/created/deleted to match version numbers cached by viewers. This is done in the way that one would expect (e.g. moving a folder increments version number on both source and destination parent folders). This should hopefully improve viewer reuse of its cached inventory information. Currently MySQL only but will be implement for SQLite/MSSQL if there are no issues. --- OpenSim/Data/IXInventoryData.cs | 15 ++ OpenSim/Data/MSSQL/MSSQLXInventoryData.cs | 130 ++++++++++++------ OpenSim/Data/MySQL/MySQLXInventoryData.cs | 94 ++++++++++++- OpenSim/Data/SQLite/SQLiteXInventoryData.cs | 30 +++- .../InventoryService/XInventoryService.cs | 11 +- .../Common/Mock/TestXInventoryDataPlugin.cs | 1 + 6 files changed, 223 insertions(+), 58 deletions(-) diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs index e64a82820d..0df71f5cad 100644 --- a/OpenSim/Data/IXInventoryData.cs +++ b/OpenSim/Data/IXInventoryData.cs @@ -116,7 +116,22 @@ namespace OpenSim.Data /// true if the delete was successful, false if it was not bool DeleteItems(string[] fields, string[] vals); + /// + /// Move an item to a new folder. + /// + /// /returns> + /// UUID of the item + /// UUID of the new folder. bool MoveItem(string id, string newParent); + + /// + /// Move a folder to a new folder. + /// + /// /returns> + /// UUID of the item + /// UUID of the new folder. + bool MoveFolder(string id, string newParent); + XInventoryItem[] GetActiveGestures(UUID principalID); int GetAssetPermissions(UUID principalID, UUID assetID); } diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs index b19a0da872..7ab0ebbe7b 100644 --- a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs +++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs @@ -43,12 +43,12 @@ namespace OpenSim.Data.MSSQL // private static readonly ILog m_log = LogManager.GetLogger( // MethodBase.GetCurrentMethod().DeclaringType); - private MSSQLGenericTableHandler m_Folders; + private MSSQLFolderHandler m_Folders; private MSSQLItemHandler m_Items; public MSSQLXInventoryData(string conn, string realm) { - m_Folders = new MSSQLGenericTableHandler( + m_Folders = new MSSQLFolderHandler( conn, "inventoryfolders", "InventoryStore"); m_Items = new MSSQLItemHandler( conn, "inventoryitems", String.Empty); @@ -85,6 +85,7 @@ namespace OpenSim.Data.MSSQL { return m_Folders.Delete(field, val); } + public bool DeleteFolders(string[] fields, string[] vals) { return m_Folders.Delete(fields, vals); @@ -94,15 +95,22 @@ namespace OpenSim.Data.MSSQL { 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); } + public bool MoveFolder(string id, string newParent) + { + return m_Folders.MoveFolder(id, newParent); + } + public XInventoryItem[] GetActiveGestures(UUID principalID) { return m_Items.GetActiveGestures(principalID); @@ -124,79 +132,115 @@ namespace OpenSim.Data.MSSQL public bool MoveItem(string id, string newParent) { using (SqlConnection conn = new SqlConnection(m_ConnectionString)) - using (SqlCommand cmd = new SqlCommand()) { + using (SqlCommand cmd = new SqlCommand()) + { - cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm); - cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent)); - cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id)); - cmd.Connection = conn; - conn.Open(); - return cmd.ExecuteNonQuery() == 0 ? false : true; + cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm); + cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent)); + cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id)); + cmd.Connection = conn; + conn.Open(); + return cmd.ExecuteNonQuery() == 0 ? false : true; + } } } public XInventoryItem[] GetActiveGestures(UUID principalID) { using (SqlConnection conn = new SqlConnection(m_ConnectionString)) - using (SqlCommand cmd = new SqlCommand()) { - cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm); + using (SqlCommand cmd = new SqlCommand()) + { + cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm); - cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString())); - cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture)); - cmd.Connection = conn; - conn.Open(); - return DoQuery(cmd); + cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture)); + cmd.Connection = conn; + conn.Open(); + return DoQuery(cmd); + } } } public int GetAssetPermissions(UUID principalID, UUID assetID) { using (SqlConnection conn = new SqlConnection(m_ConnectionString)) - using (SqlCommand cmd = new SqlCommand()) { - 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.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString())); - cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString())); - cmd.Connection = conn; - conn.Open(); - using (SqlDataReader reader = cmd.ExecuteReader()) + using (SqlCommand cmd = new SqlCommand()) { - - int perms = 0; - - if (reader.Read()) + 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.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString())); + cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString())); + cmd.Connection = conn; + conn.Open(); + using (SqlDataReader reader = cmd.ExecuteReader()) { - perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); + + int perms = 0; + + if (reader.Read()) + { + perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); + } + + return perms; } - return perms; } - } } + public override bool Store(XInventoryItem item) { if (!base.Store(item)) return false; + string sql = "update inventoryfolders set version=version+1 where folderID = @folderID"; using (SqlConnection conn = new SqlConnection(m_ConnectionString)) - using (SqlCommand cmd = new SqlCommand(sql, conn)) { - conn.Open(); + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + conn.Open(); - cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString()); - try - { - cmd.ExecuteNonQuery(); - } - catch (Exception) - { - return false; - } + cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString()); + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception) + { + return false; + } + } + + return true; } - return true; } } -} + + public class MSSQLFolderHandler : MSSQLGenericTableHandler + { + public MSSQLFolderHandler(string c, string t, string m) : + base(c, t, m) + { + } + + public bool MoveFolder(string id, string newParentFolderID) + { + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + { + using (SqlCommand cmd = new SqlCommand()) + { + + cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where folderID = @folderID", m_Realm); + cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParentFolderID)); + cmd.Parameters.Add(m_database.CreateParameter("@folderID", id)); + cmd.Connection = conn; + conn.Open(); + return cmd.ExecuteNonQuery() == 0 ? false : true; + } + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index cccc500861..7a3b5b4084 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -42,12 +42,12 @@ namespace OpenSim.Data.MySQL /// public class MySQLXInventoryData : IXInventoryData { - private MySQLGenericTableHandler m_Folders; + private MySqlFolderHandler m_Folders; private MySqlItemHandler m_Items; public MySQLXInventoryData(string conn, string realm) { - m_Folders = new MySQLGenericTableHandler( + m_Folders = new MySqlFolderHandler( conn, "inventoryfolders", "InventoryStore"); m_Items = new MySqlItemHandler( conn, "inventoryitems", String.Empty); @@ -106,6 +106,11 @@ namespace OpenSim.Data.MySQL return m_Items.MoveItem(id, newParent); } + public bool MoveFolder(string id, string newParent) + { + return m_Folders.MoveFolder(id, newParent); + } + public XInventoryItem[] GetActiveGestures(UUID principalID) { return m_Items.GetActiveGestures(principalID); @@ -275,4 +280,89 @@ namespace OpenSim.Data.MySQL return true; } } + + public class MySqlFolderHandler : MySQLGenericTableHandler + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public MySqlFolderHandler(string c, string t, string m) : + base(c, t, m) + { + } + + public bool MoveFolder(string id, string newParentFolderID) + { + XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id }); + + if (folders.Length == 0) + return false; + + UUID oldParentFolderUUID = folders[0].parentFolderID; + + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText + = String.Format( + "update {0} set parentFolderID = ?ParentFolderID where folderID = ?folderID", m_Realm); + cmd.Parameters.AddWithValue("?ParentFolderID", newParentFolderID); + cmd.Parameters.AddWithValue("?folderID", id); + + if (ExecuteNonQuery(cmd) == 0) + return false; + } + + IncrementFolderVersion(oldParentFolderUUID); + IncrementFolderVersion(newParentFolderID); + + return true; + } + + public override bool Store(XInventoryFolder folder) + { + if (!base.Store(folder)) + return false; + + IncrementFolderVersion(folder.parentFolderID); + + return true; + } + + private bool IncrementFolderVersion(UUID folderID) + { + return IncrementFolderVersion(folderID.ToString()); + } + + private bool IncrementFolderVersion(string folderID) + { +// m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID); +// Util.PrintCallStack(); + + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.Connection = dbcon; + + cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID"); + cmd.Parameters.AddWithValue("?folderID", folderID); + + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception) + { + return false; + } + cmd.Dispose(); + } + + dbcon.Close(); + } + + return true; + } + } } \ No newline at end of file diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs index 1f369867ce..75f8c8754c 100644 --- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs @@ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private SQLiteGenericTableHandler m_Folders; + private SqliteFolderHandler m_Folders; private SqliteItemHandler m_Items; public SQLiteXInventoryData(string conn, string realm) @@ -55,7 +55,7 @@ namespace OpenSim.Data.SQLite if (Util.IsWindows()) Util.LoadArchSpecificWindowsDll("sqlite3.dll"); - m_Folders = new SQLiteGenericTableHandler( + m_Folders = new SqliteFolderHandler( conn, "inventoryfolders", "XInventoryStore"); m_Items = new SqliteItemHandler( conn, "inventoryitems", String.Empty); @@ -114,6 +114,11 @@ namespace OpenSim.Data.SQLite return m_Items.MoveItem(id, newParent); } + public bool MoveFolder(string id, string newParent) + { + return m_Folders.MoveFolder(id, newParent); + } + public XInventoryItem[] GetActiveGestures(UUID principalID) { return m_Items.GetActiveGestures(principalID); @@ -177,4 +182,23 @@ namespace OpenSim.Data.SQLite return perms; } } -} + + public class SqliteFolderHandler : SQLiteGenericTableHandler + { + public SqliteFolderHandler(string c, string t, string m) : + base(c, t, m) + { + } + + public bool MoveFolder(string id, string newParentFolderID) + { + SqliteCommand cmd = new SqliteCommand(); + + cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm); + cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID)); + cmd.Parameters.Add(new SqliteParameter(":FolderID", id)); + + return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true; + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 309dab4501..9abc5e4f72 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -400,16 +400,7 @@ namespace OpenSim.Services.InventoryService public virtual bool MoveFolder(InventoryFolderBase folder) { - XInventoryFolder[] x = m_Database.GetFolders( - new string[] { "folderID" }, - new string[] { folder.ID.ToString() }); - - if (x.Length == 0) - return false; - - x[0].parentFolderID = folder.ParentID; - - return m_Database.StoreFolder(x[0]); + return m_Database.MoveFolder(folder.ID.ToString(), folder.ParentID.ToString()); } // We don't check the principal's ID here diff --git a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs index bca5979e50..f9bf768da3 100644 --- a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs @@ -125,6 +125,7 @@ namespace OpenSim.Tests.Common.Mock } public bool MoveItem(string id, string newParent) { throw new NotImplementedException(); } + public bool MoveFolder(string id, string newParent) { throw new NotImplementedException(); } public XInventoryItem[] GetActiveGestures(UUID principalID) { throw new NotImplementedException(); } public int GetAssetPermissions(UUID principalID, UUID assetID) { throw new NotImplementedException(); } }