From 1f6dcedafb30bb5107703fe00851fc342d3b255b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 15 Dec 2022 23:30:08 +0000 Subject: [PATCH] a few more changes to Xinventory service --- OpenSim/Data/IXInventoryData.cs | 4 +- OpenSim/Data/MySQL/MySQLSimulationData.cs | 9 +- OpenSim/Data/MySQL/MySQLUserProfilesData.cs | 2 - OpenSim/Data/MySQL/MySQLXInventoryData.cs | 208 +++++++++++++++++- OpenSim/Data/PGSQL/PGSQLXInventoryData.cs | 17 ++ .../Data/SQLite/SQLiteGenericTableHandler.cs | 40 +++- 6 files changed, 263 insertions(+), 17 deletions(-) diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs index ca4750660a..1cee22a859 100644 --- a/OpenSim/Data/IXInventoryData.cs +++ b/OpenSim/Data/IXInventoryData.cs @@ -80,6 +80,8 @@ namespace OpenSim.Data { XInventoryFolder[] GetFolders(string[] fields, string[] vals); XInventoryItem[] GetItems(string[] fields, string[] vals); + XInventoryItem[] GetItems(string idfield, string[] ids); + XInventoryItem[] GetItems(string idfield, string id); bool StoreFolder(XInventoryFolder folder); bool StoreItem(XInventoryItem item); @@ -123,7 +125,7 @@ namespace OpenSim.Data /// UUID of the item /// UUID of the new parent folder. bool MoveItem(string id, string newParentFolderID); - + bool MoveItems(string[] ids, string[] newParents); /// /// Move a folder to another folder. /// diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 2a5b765324..b594a37148 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -1582,12 +1582,9 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); - if (prim.AttachedPos != null) - { - cmd.Parameters.AddWithValue("AttachedPosX", prim.AttachedPos.X); - cmd.Parameters.AddWithValue("AttachedPosY", prim.AttachedPos.Y); - cmd.Parameters.AddWithValue("AttachedPosZ", prim.AttachedPos.Z); - } + cmd.Parameters.AddWithValue("AttachedPosX", prim.AttachedPos.X); + cmd.Parameters.AddWithValue("AttachedPosY", prim.AttachedPos.Y); + cmd.Parameters.AddWithValue("AttachedPosZ", prim.AttachedPos.Z); if (prim.KeyframeMotion != null) cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize()); diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs index 2669aca4d2..c545c7e008 100644 --- a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs +++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs @@ -176,8 +176,6 @@ namespace OpenSim.Data.MySQL if(string.IsNullOrEmpty(ad.ParcelName)) ad.ParcelName = "Unknown"; - if(ad.ParcelId == null) - ad.ParcelId = UUID.Zero; if(string.IsNullOrEmpty(ad.Description)) ad.Description = "No Description"; diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index 501999425d..34106e663d 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -28,7 +28,7 @@ using System; using System.Collections.Generic; using System.Data; -using System.Linq; +using System.Text; using System.Reflection; using log4net; using MySql.Data.MySqlClient; @@ -45,6 +45,7 @@ namespace OpenSim.Data.MySQL private MySqlFolderHandler m_Folders; private MySqlItemHandler m_Items; + public MySQLXInventoryData(string conn, string realm) { m_Folders = new MySqlFolderHandler( @@ -63,6 +64,16 @@ namespace OpenSim.Data.MySQL return m_Items.Get(fields, vals); } + public XInventoryItem[] GetItems(string field, string[] vals) + { + return m_Items.Get(field, vals); + } + + public XInventoryItem[] GetItems(string fields, string val) + { + return m_Items.Get(fields, val); + } + public bool StoreFolder(XInventoryFolder folder) { if (folder.folderName.Length > 64) @@ -106,6 +117,11 @@ namespace OpenSim.Data.MySQL return m_Items.MoveItem(id, newParent); } + public bool MoveItems(string[] ids, string[] newParents) + { + return m_Items.MoveItems(ids, newParents); + } + public bool MoveFolder(string id, string newParent) { return m_Folders.MoveFolder(id, newParent); @@ -124,7 +140,7 @@ namespace OpenSim.Data.MySQL public class MySqlItemHandler : MySqlInventoryHandler { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public MySqlItemHandler(string c, string t, string m) : base(c, t, m) @@ -140,8 +156,7 @@ namespace OpenSim.Data.MySQL if (!base.Delete(field, val)) return false; - // Don't increment folder version here since Delete(string, string) calls Delete(string[], string[]) -// IncrementFolderVersion(retrievedItems[0].parentFolderID); + IncrementFolderVersion(retrievedItems[0].parentFolderID); return true; } @@ -167,7 +182,7 @@ namespace OpenSim.Data.MySQL public bool MoveItem(string id, string newParent) { - XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id }); + XInventoryItem[] retrievedItems = Get("inventoryID", id); if (retrievedItems.Length == 0) return false; @@ -183,8 +198,188 @@ namespace OpenSim.Data.MySQL return false; } - IncrementFolderVersion(oldParent); IncrementFolderVersion(newParent); + if(oldParent.ToString() != newParent) + IncrementFolderVersion(oldParent); + + return true; + } + + public bool MoveItems(string[] ids, string[] newParents) + { + int len = ids.Length; + if(len == 0) + return false; + + MySqlConnection dbcon; + MySqlCommand cmd; + MySqlDataReader rdr; + try + { + dbcon = new MySqlConnection(m_connectionString); + dbcon.Open(); + } + catch + { + return false; + } + + HashSet changedfolders = new HashSet(); + try + { + UUID utmp; + + int flast = len - 1; + StringBuilder sb = new StringBuilder(1024); + sb.AppendFormat("select parentFolderID from {0} where inventoryID IN ('", m_Realm); + for (int i = 0 ; i < len ; ++i) + { + sb.Append(ids[i]); + if(i < flast) + sb.Append("','"); + else + sb.Append("')"); + } + + string[] oldparents = new string[len]; + int l = 0; + using (cmd = new MySqlCommand()) + { + cmd.CommandText = sb.ToString(); + cmd.Connection = dbcon; + rdr = cmd.ExecuteReader(); + while (rdr.Read() && l < len) + { + if(!(rdr[0] is string)) + oldparents[l++] = null; + else + oldparents[l++] = (string)rdr[0]; + } + rdr.Close(); + } + + if(l == 0) + return false; + + l = 0; + sb = new StringBuilder(1024); + string sbformat = String.Format("insert into {0} (inventoryID,parentFolderID) values{1} on duplicate key update parentFolderID = values(parentFolderID)", m_Realm,"{0}"); + + for(int k = 0; k < len; k++) + { + string oldid = oldparents[k]; + if(String.IsNullOrWhiteSpace(oldid) || !UUID.TryParse(oldid, out utmp)) + continue; + + string newParent = newParents[k]; + if(String.IsNullOrWhiteSpace(newParent) || !UUID.TryParse(newParent, out utmp)) + continue; + + string id = ids[k]; + if(id == oldid) + continue; + + sb.AppendFormat("(\'{0}\',\'{1}\')",id, newParent); + if(k < flast) + sb.Append(","); + if(!changedfolders.Contains(newParent)) + changedfolders.Add(newParent); + + if(!changedfolders.Contains(oldid)) + changedfolders.Add(oldid); + + ++l; + } + + + if(l == 0) + return false; + + oldparents = null; + newParents = null; + ids = null; + + using (cmd = new MySqlCommand()) + { + using(MySqlTransaction trans = dbcon.BeginTransaction()) + { + cmd.Connection = dbcon; + cmd.Transaction = trans; + + try + { + cmd.CommandText = string.Format(sbformat,sb.ToString()); + int r = cmd.ExecuteNonQuery(); + + if(r == 2 * l) + trans.Commit(); + else + { + // we did got insertions so need to bail out + trans.Rollback(); + return false; + } + } + catch + { + trans.Rollback(); + return false; + } + } + } + + if(changedfolders.Count == 0) + return true; + + sb = new StringBuilder(256); + sb.Append("insert into inventoryfolders (folderID) values"); + + l = 0; + flast = changedfolders.Count - 1; + foreach(UUID uu in changedfolders) + { + sb.AppendFormat("(\'{0}\')",uu); + if(l < flast) + sb.Append(","); + ++l; + } + + changedfolders = null; + + sb.Append(" on duplicate key update version = version + 1"); + using (cmd = new MySqlCommand()) + { + using(MySqlTransaction trans = dbcon.BeginTransaction()) + { + cmd.Connection = dbcon; + cmd.Transaction = trans; + cmd.CommandText = sb.ToString(); + try + { + int r = cmd.ExecuteNonQuery(); + if(r == 2 * l) + trans.Commit(); + else + { + // we did got insertions so need to bail out + trans.Rollback(); + } + } + catch + { + trans.Rollback(); + } + } + } + } + catch + { + return false; + } + finally + { + dbcon.Close(); + } return true; } @@ -223,7 +418,6 @@ namespace OpenSim.Data.MySQL using (IDataReader reader = cmd.ExecuteReader()) { - int perms = 0; if (reader.Read()) diff --git a/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs b/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs index 4c10ac99b7..61e39febe9 100644 --- a/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs +++ b/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs @@ -74,6 +74,16 @@ namespace OpenSim.Data.PGSQL return m_Items.Get(fields, vals); } + public XInventoryItem[] GetItems(string field, string[] vals) + { + return m_Items.Get(field, vals); + } + + public XInventoryItem[] GetItems(string field, string id) + { + return m_Items.Get(field, id); + } + public bool StoreFolder(XInventoryFolder folder) { if (folder.folderName.Length > 64) @@ -116,6 +126,13 @@ namespace OpenSim.Data.PGSQL return m_Items.MoveItem(id, newParent); } + public bool MoveItems(string[] ids, string[] newParents) + { + for(int i = 0; i< ids.Length; ++i) + m_Items.MoveItem(ids[i], newParents[i]); + return true; + } + public bool MoveFolder(string id, string newParent) { return m_Folders.MoveFolder(id, newParent); diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs index a4b84b1d15..aeb61a7de2 100644 --- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Reflection; +using System.Text; using log4net; #if CSharpSqlite using Community.CsharpSqlite.Sqlite; @@ -122,7 +123,44 @@ namespace OpenSim.Data.SQLite public virtual T[] Get(string field, string key) { - return Get(new string[] { field }, new string[] { key }); + List terms = new List(); + + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.Parameters.Add(new SqliteParameter(":" + field, key)); + string query = String.Format("select * from {0} where `{1}` = :{1}",m_Realm, field); + + cmd.CommandText = query; + + return DoQuery(cmd); + } + } + + public virtual T[] Get(string field, string[] keys) + { + int flen = keys.Length; + if(flen == 0) + return new T[0]; + + int flast = flen - 1; + StringBuilder sb = new StringBuilder(1024); + sb.AppendFormat("select * from {0} where {1} IN('", m_Realm, field); + + using (SqliteCommand cmd = new SqliteCommand()) + { + for (int i = 0 ; i < flen ; i++) + { + sb.Append(keys[i]); + if(i < flast) + sb.Append("','"); + else + sb.Append("')"); + } + + cmd.CommandText = sb.ToString(); + + return DoQuery(cmd); + } } public virtual T[] Get(string[] fields, string[] keys)