* 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)
ThreadPoolClientBranch
Justin Clarke Casey 2008-01-21 16:42:53 +00:00
parent 38991ba0e6
commit 46fe6e2f97
6 changed files with 71 additions and 139 deletions

View File

@ -167,7 +167,6 @@ namespace OpenSim.Framework.Data.MySQL
DataTable prims = m_primTable; DataTable prims = m_primTable;
DataTable shapes = m_shapeTable; DataTable shapes = m_shapeTable;
DataTable items = m_itemsTable;
string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'"; string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'";
lock (m_dataSet) lock (m_dataSet)
@ -185,14 +184,7 @@ namespace OpenSim.Framework.Data.MySQL
if (persistPrimInventories) if (persistPrimInventories)
{ {
// Remove items rows RemoveItems(uuid);
String sql = String.Format("primID = '{0}'", uuid);
DataRow[] itemRows = items.Select(sql);
foreach (DataRow itemRow in itemRows)
{
itemRow.Delete();
}
} }
// Remove prim row // Remove prim row
@ -203,6 +195,21 @@ namespace OpenSim.Framework.Data.MySQL
Commit(); Commit();
} }
/// <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> /// <summary>
/// Load persisted objects from region storage. /// Load persisted objects from region storage.
/// </summary> /// </summary>
@ -1196,83 +1203,34 @@ namespace OpenSim.Framework.Data.MySQL
} }
// see IRegionDatastore // see IRegionDatastore
public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items) public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items)
{ {
if (!persistPrimInventories) if (!persistPrimInventories)
return; 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) lock (m_dataSet)
{ {
// Find all existing inventory rows for this prim RemoveItems(primID);
DataTable dbItems = m_itemsTable;
String sql = String.Format("primID = '{0}'", primID);
DataRow[] dbItemRows = dbItems.Select(sql);
// Build structures for manipulation purposes // repalce with current inventory details
IDictionary<String, DataRow> dbItemsToRemove = new Dictionary<String, DataRow>(); foreach (TaskInventoryItem newItem in items)
ICollection<TaskInventoryItem> itemsToAdd = new List<TaskInventoryItem>();
foreach (DataRow row in dbItemRows)
{ {
// MainLog.Instance.Verbose( // MainLog.Instance.Verbose(
// "DATASTORE", // "DATASTORE",
// "Found item {0}, {1} in prim id {2}", // "Adding item {0}, {1} to prim ID {2}",
// row["name"], row["itemID"], primID); // newItem.Name, newItem.ItemID, newItem.ParentPartID);
dbItemsToRemove.Add((String)row["itemID"], row); DataRow newItemRow = m_itemsTable.NewRow();
}
// 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();
fillItemRow(newItemRow, newItem); fillItemRow(newItemRow, newItem);
dbItems.Rows.Add(newItemRow); m_itemsTable.Rows.Add(newItemRow);
} }
} }
Commit();
} }
/*********************************************************************** /***********************************************************************

View File

@ -209,7 +209,6 @@ namespace OpenSim.Framework.Data.SQLite
DataTable prims = ds.Tables["prims"]; DataTable prims = ds.Tables["prims"];
DataTable shapes = ds.Tables["primshapes"]; DataTable shapes = ds.Tables["primshapes"];
DataTable items = ds.Tables["primitems"];
string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'"; string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'";
lock (ds) lock (ds)
@ -227,14 +226,7 @@ namespace OpenSim.Framework.Data.SQLite
if (persistPrimInventories) if (persistPrimInventories)
{ {
// Remove items rows RemoveItems(uuid);
String sql = String.Format("primID = '{0}'", uuid);
DataRow[] itemRows = items.Select(sql);
foreach (DataRow itemRow in itemRows)
{
itemRow.Delete();
}
} }
// Remove prim row // Remove prim row
@ -245,6 +237,23 @@ namespace OpenSim.Framework.Data.SQLite
Commit(); Commit();
} }
/// <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> /// <summary>
/// Load persisted objects from region storage. /// Load persisted objects from region storage.
/// </summary> /// </summary>
@ -1251,74 +1260,36 @@ namespace OpenSim.Framework.Data.SQLite
} }
// see IRegionDatastore // see IRegionDatastore
public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items) public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items)
{ {
if (!persistPrimInventories) if (!persistPrimInventories)
return; return;
MainLog.Instance.Verbose("DATASTORE", "Entered StorePrimInventory with prim ID {0}", primID); 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) lock (ds)
{ {
// Find all existing inventory rows for this prim RemoveItems(primID);
DataTable dbItems = ds.Tables["primitems"];
String sql = String.Format("primID = '{0}'", primID);
DataRow[] dbItemRows = dbItems.Select(sql);
// Build structures for manipulation purposes // repalce with current inventory details
IDictionary<String, DataRow> dbItemsToRemove = new Dictionary<String, DataRow>(); foreach (TaskInventoryItem newItem in items)
ICollection<TaskInventoryItem> itemsToAdd
= new List<TaskInventoryItem>();
foreach (DataRow row in dbItemRows)
{ {
dbItemsToRemove.Add((String)row["itemID"], row); // MainLog.Instance.Verbose(
} // "DATASTORE",
// "Adding item {0}, {1} to prim ID {2}",
// Eliminate rows from the deletion set which already exist for this prim's inventory // newItem.Name, newItem.ItemID, newItem.ParentPartID);
// 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);
DataRow newItemRow = dbItems.NewRow(); DataRow newItemRow = dbItems.NewRow();
fillItemRow(newItemRow, newItem); fillItemRow(newItemRow, newItem);
dbItems.Rows.Add(newItemRow); dbItems.Rows.Add(newItemRow);
} }
} }
Commit();
} }
/*********************************************************************** /***********************************************************************

View File

@ -63,7 +63,7 @@ namespace OpenSim.Region.Environment.Interfaces
/// Store a prim's inventory /// Store a prim's inventory
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items); void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items);
List<SceneObjectGroup> LoadObjects(LLUUID regionUUID); List<SceneObjectGroup> LoadObjects(LLUUID regionUUID);

View File

@ -401,7 +401,10 @@ namespace OpenSim.Region.Environment.Scenes
{ {
if (HasInventoryChanged) if (HasInventoryChanged)
{ {
datastore.StorePrimInventory(UUID, TaskInventory); lock (TaskInventory)
{
datastore.StorePrimInventory(UUID, TaskInventory.Values);
}
HasInventoryChanged = false; HasInventoryChanged = false;
} }

View File

@ -754,7 +754,7 @@ namespace OpenSim.DataStore.MSSQL
} }
// see IRegionDatastore // see IRegionDatastore
public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items) public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items)
{ {
// No implementation yet // No implementation yet
} }

View File

@ -51,7 +51,7 @@ namespace OpenSim.DataStore.NullStorage
} }
// see IRegionDatastore // see IRegionDatastore
public void StorePrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items) public void StorePrimInventory(LLUUID primID, ICollection<TaskInventoryItem> items)
{ {
} }