From 46fe6e2f978ef03a20768e629e9cd2437c707bba Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Mon, 21 Jan 2008 16:42:53 +0000
Subject: * Scripts edited within a prim will now be persisted correctly * On
 restart the latest save will be restored rather than the very first dragged
 in scripts * Also add previously missed out database commits to separate prim
 inventory commit path (sigh)

---
 OpenSim/Framework/Data.MySQL/MySQLDataStore.cs     | 106 +++++++--------------
 OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs  |  93 +++++++-----------
 .../Environment/Interfaces/IRegionDataStore.cs     |   2 +-
 .../Scenes/SceneObjectPart.Inventory.cs            |   5 +-
 .../OpenSim.DataStore.MSSQL/MSSQLDataStore.cs      |   2 +-
 .../OpenSim.DataStore.NullStorage/NullDataStore.cs |   2 +-
 6 files changed, 71 insertions(+), 139 deletions(-)

(limited to 'OpenSim')

diff --git a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
index 47b3c43..2bd4e32 100644
--- a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
+++ b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
@@ -167,7 +167,6 @@ namespace OpenSim.Framework.Data.MySQL
 
             DataTable prims = m_primTable;
             DataTable shapes = m_shapeTable;
-            DataTable items = m_itemsTable;
 
             string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'";
             lock (m_dataSet)
@@ -185,14 +184,7 @@ namespace OpenSim.Framework.Data.MySQL
                     
                     if (persistPrimInventories)
                     {                    
-                        // Remove items rows
-                        String sql = String.Format("primID = '{0}'", uuid);            
-                        DataRow[] itemRows = items.Select(sql);
-                
-                        foreach (DataRow itemRow in itemRows)
-                        {
-                            itemRow.Delete();
-                        }                    
+                        RemoveItems(uuid);
                     }
                     
                     // Remove prim row
@@ -204,6 +196,21 @@ namespace OpenSim.Framework.Data.MySQL
         }
 
         /// <summary>
+        /// Remove all persisted items of the given prim.
+        /// The caller must acquire the necessrary synchronization locks and commit or rollback changes.
+        /// </summary>
+        private void RemoveItems(LLUUID uuid)
+        {
+            String sql = String.Format("primID = '{0}'", uuid);            
+            DataRow[] itemRows = m_itemsTable.Select(sql);
+    
+            foreach (DataRow itemRow in itemRows)
+            {
+                itemRow.Delete();
+            }
+        }
+        
+        /// <summary>
         /// Load persisted objects from region storage.
         /// </summary>        
         public List<SceneObjectGroup> LoadObjects(LLUUID regionUUID)
@@ -1196,83 +1203,34 @@ namespace OpenSim.Framework.Data.MySQL
         }
         
         // see IRegionDatastore
-        public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
+        public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items)
         {
             if (!persistPrimInventories)
                 return;
                      
-            MainLog.Instance.Verbose("DATASTORE", "Entered StorePrimInventory with prim ID {0}", primID);
+            MainLog.Instance.Verbose("DATASTORE", "Persisting Prim Inventory with prim ID {0}", primID);
             
+            // For now, we're just going to crudely remove all the previous inventory items 
+            // no matter whether they have changed or not, and replace them with the current set.
             lock (m_dataSet)
-            {            
-                // Find all existing inventory rows for this prim
-                DataTable dbItems = m_itemsTable;
-    
-                String sql = String.Format("primID = '{0}'", primID);            
-                DataRow[] dbItemRows = dbItems.Select(sql);
-                
-                // Build structures for manipulation purposes
-                IDictionary<String, DataRow> dbItemsToRemove = new Dictionary<String, DataRow>();
-                ICollection<TaskInventoryItem> itemsToAdd = new List<TaskInventoryItem>();
-                
-                foreach (DataRow row in dbItemRows)
-                {
-    //                MainLog.Instance.Verbose(
-    //                    "DATASTORE", 
-    //                    "Found item {0}, {1} in prim id {2}", 
-    //                    row["name"], row["itemID"], primID);
-                    
-                    dbItemsToRemove.Add((String)row["itemID"], row);
-                }
-                
-                // Eliminate rows from the deletion set which already exist for this prim's inventory
-                // TODO Very temporary, need to take account of simple metadata changes soon
-                lock (items)
-                {
-                    foreach (LLUUID itemId in items.Keys)
-                    {
-                        String rawItemId = itemId.ToString();
-                        
-                        if (dbItemsToRemove.ContainsKey(rawItemId))
-                        {
-    //                        MainLog.Instance.Verbose(
-    //                            "DATASTORE", 
-    //                            "Discarding item {0}, {1} from remove candidates for prim id {2}", 
-    //                            items[itemId].Name, rawItemId, primID);
-                            
-                            dbItemsToRemove.Remove(rawItemId);
-                        }
-                        else
-                        {
-                            itemsToAdd.Add(items[itemId]);
-                        }
-                    }    
-                }
-                
-                // Delete excess rows
-                foreach (DataRow row in dbItemsToRemove.Values)
-                {
-                    MainLog.Instance.Verbose(
-                        "DATASTORE", 
-                        "Removing item {0}, {1} from prim ID {2}", 
-                        row["name"], row["itemID"], row["primID"]);
-                    
-                    row.Delete();
-                }
+            {                              
+                RemoveItems(primID);              
                 
-                // Insert items not already present 
-                foreach (TaskInventoryItem newItem in itemsToAdd)
+                // repalce with current inventory details
+                foreach (TaskInventoryItem newItem in items)
                 {
-                    MainLog.Instance.Verbose(
-                        "DATASTORE", 
-                        "Adding item {0}, {1} to prim ID {2}", 
-                        newItem.Name, newItem.ItemID, newItem.ParentPartID);
+//                    MainLog.Instance.Verbose(
+//                        "DATASTORE", 
+//                        "Adding item {0}, {1} to prim ID {2}", 
+//                        newItem.Name, newItem.ItemID, newItem.ParentPartID);
                     
-                    DataRow newItemRow = dbItems.NewRow();
+                    DataRow newItemRow = m_itemsTable.NewRow();
                     fillItemRow(newItemRow, newItem);
-                    dbItems.Rows.Add(newItemRow);                
+                    m_itemsTable.Rows.Add(newItemRow);                
                 }
             }
+            
+            Commit();
         }        
 
         /***********************************************************************
diff --git a/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs b/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
index 0035311..6553192 100644
--- a/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
@@ -209,7 +209,6 @@ namespace OpenSim.Framework.Data.SQLite
             
             DataTable prims = ds.Tables["prims"];
             DataTable shapes = ds.Tables["primshapes"];
-            DataTable items = ds.Tables["primitems"];
 
             string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'";
             lock (ds)
@@ -227,14 +226,7 @@ namespace OpenSim.Framework.Data.SQLite
 
                     if (persistPrimInventories)
                     {
-                        // Remove items rows
-                        String sql = String.Format("primID = '{0}'", uuid);            
-                        DataRow[] itemRows = items.Select(sql);
-                
-                        foreach (DataRow itemRow in itemRows)
-                        {
-                            itemRow.Delete();
-                        }
+                        RemoveItems(uuid);
                     }
 
                     // Remove prim row
@@ -246,6 +238,23 @@ namespace OpenSim.Framework.Data.SQLite
         }
 
         /// <summary>
+        /// Remove all persisted items of the given prim.
+        /// The caller must acquire the necessrary synchronization locks and commit or rollback changes.
+        /// </summary>
+        private void RemoveItems(LLUUID uuid)
+        {
+            DataTable items = ds.Tables["primitems"];            
+
+            String sql = String.Format("primID = '{0}'", uuid);            
+            DataRow[] itemRows = items.Select(sql);
+    
+            foreach (DataRow itemRow in itemRows)
+            {
+                itemRow.Delete();
+            }
+        }
+
+        /// <summary>
         /// Load persisted objects from region storage.
         /// </summary>
         /// <param name="regionUUID"></param>
@@ -1251,74 +1260,36 @@ namespace OpenSim.Framework.Data.SQLite
         }
         
         // see IRegionDatastore
-        public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
+        public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items)
         {
             if (!persistPrimInventories)
                 return;
             
             MainLog.Instance.Verbose("DATASTORE", "Entered StorePrimInventory with prim ID {0}", primID);
             
+            DataTable dbItems = ds.Tables["primitems"]; 
+            
+            // For now, we're just going to crudely remove all the previous inventory items 
+            // no matter whether they have changed or not, and replace them with the current set.            
             lock (ds)
             {
-                // Find all existing inventory rows for this prim
-                DataTable dbItems = ds.Tables["primitems"];
-    
-                String sql = String.Format("primID = '{0}'", primID);            
-                DataRow[] dbItemRows = dbItems.Select(sql);
-                
-                // Build structures for manipulation purposes
-                IDictionary<String, DataRow> dbItemsToRemove = new Dictionary<String, DataRow>();
-                ICollection<TaskInventoryItem> itemsToAdd 
-                    = new List<TaskInventoryItem>();
+                RemoveItems(primID);
                 
-                foreach (DataRow row in dbItemRows)
+                // repalce with current inventory details
+                foreach (TaskInventoryItem newItem in items)
                 {
-                    dbItemsToRemove.Add((String)row["itemID"], row);
-                }
-                
-                // Eliminate rows from the deletion set which already exist for this prim's inventory
-                // TODO Very temporary, need to take account of simple metadata changes soon
-                lock (items)
-                {
-                    foreach (LLUUID itemId in items.Keys)
-                    {
-                        String rawItemId = itemId.ToString();
-                        
-                        if (dbItemsToRemove.ContainsKey(rawItemId))
-                        {
-                            dbItemsToRemove.Remove(rawItemId);
-                        }
-                        else
-                        {
-                            itemsToAdd.Add(items[itemId]);
-                        }
-                    }    
-                }
-                
-                // Delete excess rows
-                foreach (DataRow row in dbItemsToRemove.Values)
-                {
-                    MainLog.Instance.Verbose(
-                        "DATASTORE", 
-                        "Removing item {0}, {1} from prim ID {2}", 
-                        row["name"], row["itemID"], row["primID"]);
-                    
-                    row.Delete();
-                }
-                
-                // Insert items not already present 
-                foreach (TaskInventoryItem newItem in itemsToAdd)
-                {
-                    MainLog.Instance.Verbose(
-                        "DATASTORE", 
-                        "Adding item {0}, {1} to prim ID {2}", 
-                        newItem.Name, newItem.ItemID, newItem.ParentPartID);
+//                    MainLog.Instance.Verbose(
+//                        "DATASTORE", 
+//                        "Adding item {0}, {1} to prim ID {2}", 
+//                        newItem.Name, newItem.ItemID, newItem.ParentPartID);
                     
                     DataRow newItemRow = dbItems.NewRow();
                     fillItemRow(newItemRow, newItem);
                     dbItems.Rows.Add(newItemRow);                
                 }
             }
+            
+            Commit();
         }
 
         /***********************************************************************
diff --git a/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
index 47768b7..d0b5680 100644
--- a/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
+++ b/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
@@ -63,7 +63,7 @@ namespace OpenSim.Region.Environment.Interfaces
         /// Store a prim's inventory
         /// </summary>
         /// <returns></returns>
-        void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items);
+        void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items);
 
         List<SceneObjectGroup> LoadObjects(LLUUID regionUUID);
 
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
index a700974..d4e2102 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
@@ -401,7 +401,10 @@ namespace OpenSim.Region.Environment.Scenes
         {
             if (HasInventoryChanged)
             {
-                datastore.StorePrimInventory(UUID, TaskInventory);
+                lock (TaskInventory)
+                {
+                    datastore.StorePrimInventory(UUID, TaskInventory.Values);
+                }
                 
                 HasInventoryChanged = false;
             }
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs
index 6aeb808..28df4e7 100644
--- a/OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs
+++ b/OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs
@@ -754,7 +754,7 @@ namespace OpenSim.DataStore.MSSQL
         }
         
         // see IRegionDatastore
-        public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
+        public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items)
         {
             // No implementation yet
         }
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
index 8039e51..29d64a2 100644
--- a/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
+++ b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
@@ -51,7 +51,7 @@ namespace OpenSim.DataStore.NullStorage
         }
         
         // see IRegionDatastore
-        public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
+        public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items)
         {
         }        
 
-- 
cgit v1.1