diff --git a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs index 47b3c43480..2bd4e32f71 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 @@ -203,6 +195,21 @@ namespace OpenSim.Framework.Data.MySQL Commit(); } + /// + /// Remove all persisted items of the given prim. + /// The caller must acquire the necessrary synchronization locks and commit or rollback changes. + /// + 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(); + } + } + /// /// Load persisted objects from region storage. /// @@ -1196,83 +1203,34 @@ namespace OpenSim.Framework.Data.MySQL } // see IRegionDatastore - public void StorePrimInventory(LLUUID primID, IDictionary items) + public void StorePrimInventory(LLUUID primID, ICollection 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); + { + RemoveItems(primID); - // Build structures for manipulation purposes - IDictionary dbItemsToRemove = new Dictionary(); - ICollection itemsToAdd = new List(); - - foreach (DataRow row in dbItemRows) + // repalce with current inventory details + foreach (TaskInventoryItem newItem in items) { - // MainLog.Instance.Verbose( - // "DATASTORE", - // "Found item {0}, {1} in prim id {2}", - // row["name"], row["itemID"], primID); +// MainLog.Instance.Verbose( +// "DATASTORE", +// "Adding item {0}, {1} to prim ID {2}", +// newItem.Name, newItem.ItemID, newItem.ParentPartID); - 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(); - } - - // 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); - - 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 0035311e30..6553192a33 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 @@ -245,6 +237,23 @@ namespace OpenSim.Framework.Data.SQLite Commit(); } + /// + /// Remove all persisted items of the given prim. + /// The caller must acquire the necessrary synchronization locks and commit or rollback changes. + /// + 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(); + } + } + /// /// Load persisted objects from region storage. /// @@ -1251,74 +1260,36 @@ namespace OpenSim.Framework.Data.SQLite } // see IRegionDatastore - public void StorePrimInventory(LLUUID primID, IDictionary items) + public void StorePrimInventory(LLUUID primID, ICollection 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); + RemoveItems(primID); - // Build structures for manipulation purposes - IDictionary dbItemsToRemove = new Dictionary(); - ICollection itemsToAdd - = new List(); - - 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 47768b7e51..d0b5680a53 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 /// /// - void StorePrimInventory(LLUUID primID, IDictionary items); + void StorePrimInventory(LLUUID primID, ICollection items); List LoadObjects(LLUUID regionUUID); diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs index a70097456d..d4e2102b1d 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 6aeb808c6e..28df4e7c86 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 items) + public void StorePrimInventory(LLUUID primID, ICollection 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 8039e516dd..29d64a2b7d 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 items) + public void StorePrimInventory(LLUUID primID, ICollection items) { }