aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-01-11 17:00:21 +0000
committerJustin Clarke Casey2008-01-11 17:00:21 +0000
commit48be04df1d804137a736d83de157265555a63d31 (patch)
treef4fbf722ab2dba911da0f7f37138be9c41019067
parentmanually open the db connection. Mono does this automatically, .NET doesn't (diff)
downloadopensim-SC-48be04df1d804137a736d83de157265555a63d31.zip
opensim-SC-48be04df1d804137a736d83de157265555a63d31.tar.gz
opensim-SC-48be04df1d804137a736d83de157265555a63d31.tar.bz2
opensim-SC-48be04df1d804137a736d83de157265555a63d31.tar.xz
* Do database implementation for prim inventory items in mysql
* Properly clean up items when a region object is deleted * Update persisted prim when an inventory script is changed * No user functionality yet
-rw-r--r--OpenSim/Framework/Data.MySQL/MySQLDataStore.cs325
-rw-r--r--OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs51
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs7
3 files changed, 351 insertions, 32 deletions
diff --git a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
index 3c25533..6d33a36 100644
--- a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
+++ b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
@@ -44,6 +44,7 @@ namespace OpenSim.Framework.Data.MySQL
44 { 44 {
45 private const string m_primSelect = "select * from prims"; 45 private const string m_primSelect = "select * from prims";
46 private const string m_shapeSelect = "select * from primshapes"; 46 private const string m_shapeSelect = "select * from primshapes";
47 private const string m_itemsSelect = "select * from primitems";
47 private const string m_terrainSelect = "select * from terrain limit 1"; 48 private const string m_terrainSelect = "select * from terrain limit 1";
48 private const string m_landSelect = "select * from land"; 49 private const string m_landSelect = "select * from land";
49 private const string m_landAccessListSelect = "select * from landaccesslist"; 50 private const string m_landAccessListSelect = "select * from landaccesslist";
@@ -51,15 +52,21 @@ namespace OpenSim.Framework.Data.MySQL
51 private DataSet m_dataSet; 52 private DataSet m_dataSet;
52 private MySqlDataAdapter m_primDataAdapter; 53 private MySqlDataAdapter m_primDataAdapter;
53 private MySqlDataAdapter m_shapeDataAdapter; 54 private MySqlDataAdapter m_shapeDataAdapter;
55 private MySqlDataAdapter m_itemsDataAdapter;
54 private MySqlConnection m_connection; 56 private MySqlConnection m_connection;
55 private MySqlDataAdapter m_terrainDataAdapter; 57 private MySqlDataAdapter m_terrainDataAdapter;
56 private MySqlDataAdapter m_landDataAdapter; 58 private MySqlDataAdapter m_landDataAdapter;
57 private MySqlDataAdapter m_landAccessListDataAdapter; 59 private MySqlDataAdapter m_landAccessListDataAdapter;
60
58 private DataTable m_primTable; 61 private DataTable m_primTable;
59 private DataTable m_shapeTable; 62 private DataTable m_shapeTable;
63 private DataTable m_itemsTable;
60 private DataTable m_terrainTable; 64 private DataTable m_terrainTable;
61 private DataTable m_landTable; 65 private DataTable m_landTable;
62 private DataTable m_landAccessListTable; 66 private DataTable m_landAccessListTable;
67
68 // Temporary attribute while this is experimental
69 private bool persistPrimInventories;
63 70
64 /*********************************************************************** 71 /***********************************************************************
65 * 72 *
@@ -71,6 +78,7 @@ namespace OpenSim.Framework.Data.MySQL
71 public void Initialise(string connectionstring, bool persistPrimInventories) 78 public void Initialise(string connectionstring, bool persistPrimInventories)
72 { 79 {
73 m_dataSet = new DataSet(); 80 m_dataSet = new DataSet();
81 this.persistPrimInventories = persistPrimInventories;
74 82
75 MainLog.Instance.Verbose("DATASTORE", "MySql - connecting: " + connectionstring); 83 MainLog.Instance.Verbose("DATASTORE", "MySql - connecting: " + connectionstring);
76 m_connection = new MySqlConnection(connectionstring); 84 m_connection = new MySqlConnection(connectionstring);
@@ -80,6 +88,9 @@ namespace OpenSim.Framework.Data.MySQL
80 88
81 MySqlCommand shapeSelectCmd = new MySqlCommand(m_shapeSelect, m_connection); 89 MySqlCommand shapeSelectCmd = new MySqlCommand(m_shapeSelect, m_connection);
82 m_shapeDataAdapter = new MySqlDataAdapter(shapeSelectCmd); 90 m_shapeDataAdapter = new MySqlDataAdapter(shapeSelectCmd);
91
92 MySqlCommand itemsSelectCmd = new MySqlCommand(m_itemsSelect, m_connection);
93 m_itemsDataAdapter = new MySqlDataAdapter(itemsSelectCmd);
83 94
84 MySqlCommand terrainSelectCmd = new MySqlCommand(m_terrainSelect, m_connection); 95 MySqlCommand terrainSelectCmd = new MySqlCommand(m_terrainSelect, m_connection);
85 m_terrainDataAdapter = new MySqlDataAdapter(terrainSelectCmd); 96 m_terrainDataAdapter = new MySqlDataAdapter(terrainSelectCmd);
@@ -103,6 +114,14 @@ namespace OpenSim.Framework.Data.MySQL
103 m_dataSet.Tables.Add(m_shapeTable); 114 m_dataSet.Tables.Add(m_shapeTable);
104 SetupShapeCommands(m_shapeDataAdapter, m_connection); 115 SetupShapeCommands(m_shapeDataAdapter, m_connection);
105 m_shapeDataAdapter.Fill(m_shapeTable); 116 m_shapeDataAdapter.Fill(m_shapeTable);
117
118 if (persistPrimInventories)
119 {
120 m_itemsTable = createItemsTable();
121 m_dataSet.Tables.Add(m_itemsTable);
122 SetupItemsCommands(m_itemsDataAdapter, m_connection);
123 m_itemsDataAdapter.Fill(m_itemsTable);
124 }
106 125
107 m_terrainTable = createTerrainTable(); 126 m_terrainTable = createTerrainTable();
108 m_dataSet.Tables.Add(m_terrainTable); 127 m_dataSet.Tables.Add(m_terrainTable);
@@ -146,6 +165,7 @@ namespace OpenSim.Framework.Data.MySQL
146 { 165 {
147 DataTable prims = m_primTable; 166 DataTable prims = m_primTable;
148 DataTable shapes = m_shapeTable; 167 DataTable shapes = m_shapeTable;
168 DataTable items = m_itemsTable;
149 169
150 string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'"; 170 string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'";
151 lock (m_dataSet) 171 lock (m_dataSet)
@@ -153,12 +173,27 @@ namespace OpenSim.Framework.Data.MySQL
153 DataRow[] primRows = prims.Select(selectExp); 173 DataRow[] primRows = prims.Select(selectExp);
154 foreach (DataRow row in primRows) 174 foreach (DataRow row in primRows)
155 { 175 {
176 // Remove shapes row
156 LLUUID uuid = new LLUUID((string) row["UUID"]); 177 LLUUID uuid = new LLUUID((string) row["UUID"]);
157 DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(uuid)); 178 DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(uuid));
158 if (shapeRow != null) 179 if (shapeRow != null)
159 { 180 {
160 shapeRow.Delete(); 181 shapeRow.Delete();
161 } 182 }
183
184 if (persistPrimInventories)
185 {
186 // Remove items rows
187 String sql = String.Format("primID = '{0}'", uuid);
188 DataRow[] itemRows = items.Select(sql);
189
190 foreach (DataRow itemsRow in itemRows)
191 {
192 shapeRow.Delete();
193 }
194 }
195
196 // Remove prim row
162 row.Delete(); 197 row.Delete();
163 } 198 }
164 } 199 }
@@ -166,6 +201,9 @@ namespace OpenSim.Framework.Data.MySQL
166 Commit(); 201 Commit();
167 } 202 }
168 203
204 /// <summary>
205 /// Load persisted objects from region storage.
206 /// </summary>
169 public List<SceneObjectGroup> LoadObjects(LLUUID regionUUID) 207 public List<SceneObjectGroup> LoadObjects(LLUUID regionUUID)
170 { 208 {
171 Dictionary<LLUUID, SceneObjectGroup> createdObjects = new Dictionary<LLUUID, SceneObjectGroup>(); 209 Dictionary<LLUUID, SceneObjectGroup> createdObjects = new Dictionary<LLUUID, SceneObjectGroup>();
@@ -186,14 +224,17 @@ namespace OpenSim.Framework.Data.MySQL
186 224
187 foreach (DataRow primRow in primsForRegion) 225 foreach (DataRow primRow in primsForRegion)
188 { 226 {
189 try 227 try
190 { 228 {
191 string uuid = (string) primRow["UUID"]; 229 string uuid = (string) primRow["UUID"];
192 string objID = (string) primRow["SceneGroupID"]; 230 string objID = (string) primRow["SceneGroupID"];
231
232 SceneObjectPart prim = buildPrim(primRow);
233
193 if (uuid == objID) //is new SceneObjectGroup ? 234 if (uuid == objID) //is new SceneObjectGroup ?
194 { 235 {
195 SceneObjectGroup group = new SceneObjectGroup(); 236 SceneObjectGroup group = new SceneObjectGroup();
196 SceneObjectPart prim = buildPrim(primRow); 237
197 DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); 238 DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID));
198 if (shapeRow != null) 239 if (shapeRow != null)
199 { 240 {
@@ -213,7 +254,6 @@ namespace OpenSim.Framework.Data.MySQL
213 } 254 }
214 else 255 else
215 { 256 {
216 SceneObjectPart prim = buildPrim(primRow);
217 DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); 257 DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID));
218 if (shapeRow != null) 258 if (shapeRow != null)
219 { 259 {
@@ -227,6 +267,11 @@ namespace OpenSim.Framework.Data.MySQL
227 } 267 }
228 createdObjects[new LLUUID(objID)].AddPart(prim); 268 createdObjects[new LLUUID(objID)].AddPart(prim);
229 } 269 }
270
271 if (persistPrimInventories)
272 {
273 LoadItems(prim);
274 }
230 } 275 }
231 catch (Exception e) 276 catch (Exception e)
232 { 277 {
@@ -241,7 +286,39 @@ namespace OpenSim.Framework.Data.MySQL
241 } 286 }
242 return retvals; 287 return retvals;
243 } 288 }
244 289
290 /// <summary>
291 /// Load in a prim's persisted inventory.
292 /// </summary>
293 /// <param name="prim"></param>
294 private void LoadItems(SceneObjectPart prim)
295 {
296 MainLog.Instance.Verbose("DATASTORE", "Loading inventory for {0}, {1}", prim.Name, prim.UUID);
297
298 DataTable dbItems = m_itemsTable;
299
300 String sql = String.Format("primID = '{0}'", prim.UUID.ToString());
301 DataRow[] dbItemRows = dbItems.Select(sql);
302
303 IList<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
304
305 foreach (DataRow row in dbItemRows)
306 {
307 TaskInventoryItem item = buildItem(row);
308 inventory.Add(item);
309
310 MainLog.Instance.Verbose("DATASTORE", "Restored item {0}, {1}", item.name, item.item_id);
311 }
312
313 prim.AddInventoryItems(inventory);
314
315 // XXX A nasty little hack to recover the folder id for the prim (which is currently stored in
316 // every item). This data should really be stored in the prim table itself.
317 if (dbItemRows.Length > 0)
318 {
319 prim.FolderID = inventory[0].parent_id;
320 }
321 }
245 322
246 public void StoreTerrain(double[,] ter, LLUUID regionID) 323 public void StoreTerrain(double[,] ter, LLUUID regionID)
247 { 324 {
@@ -437,6 +514,12 @@ namespace OpenSim.Framework.Data.MySQL
437 514
438 m_primDataAdapter.Update(m_primTable); 515 m_primDataAdapter.Update(m_primTable);
439 m_shapeDataAdapter.Update(m_shapeTable); 516 m_shapeDataAdapter.Update(m_shapeTable);
517
518 if (persistPrimInventories)
519 {
520 m_itemsDataAdapter.Update(m_itemsTable);
521 }
522
440 m_terrainDataAdapter.Update(m_terrainTable); 523 m_terrainDataAdapter.Update(m_terrainTable);
441 m_landDataAdapter.Update(m_landTable); 524 m_landDataAdapter.Update(m_landTable);
442 m_landAccessListDataAdapter.Update(m_landAccessListTable); 525 m_landAccessListDataAdapter.Update(m_landAccessListTable);
@@ -630,6 +713,38 @@ namespace OpenSim.Framework.Data.MySQL
630 713
631 return shapes; 714 return shapes;
632 } 715 }
716
717 private DataTable createItemsTable()
718 {
719 DataTable items = new DataTable("primitems");
720
721 createCol(items, "itemID", typeof (String));
722 createCol(items, "primID", typeof (String));
723 createCol(items, "assetID", typeof (String));
724 createCol(items, "parentFolderID", typeof (String));
725
726 createCol(items, "invType", typeof (Int32));
727 createCol(items, "assetType", typeof (Int32));
728
729 createCol(items, "name", typeof (String));
730 createCol(items, "description", typeof (String));
731
732 createCol(items, "creationDate", typeof (Int64));
733 createCol(items, "creatorID", typeof (String));
734 createCol(items, "ownerID", typeof (String));
735 createCol(items, "lastOwnerID", typeof (String));
736 createCol(items, "groupID", typeof (String));
737
738 createCol(items, "nextPermissions", typeof (Int32));
739 createCol(items, "currentPermissions", typeof (Int32));
740 createCol(items, "basePermissions", typeof (Int32));
741 createCol(items, "everyonePermissions", typeof (Int32));
742 createCol(items, "groupPermissions", typeof (Int32));
743
744 items.PrimaryKey = new DataColumn[] {items.Columns["itemID"]};
745
746 return items;
747 }
633 748
634 /*********************************************************************** 749 /***********************************************************************
635 * 750 *
@@ -727,6 +842,41 @@ namespace OpenSim.Framework.Data.MySQL
727 } 842 }
728 return prim; 843 return prim;
729 } 844 }
845
846
847 /// <summary>
848 /// Build a prim inventory item from the persisted data.
849 /// </summary>
850 /// <param name="row"></param>
851 /// <returns></returns>
852 private TaskInventoryItem buildItem(DataRow row)
853 {
854 TaskInventoryItem taskItem = new TaskInventoryItem();
855
856 taskItem.item_id = new LLUUID((String)row["itemID"]);
857 taskItem.ParentPartID = new LLUUID((String)row["primID"]);
858 taskItem.asset_id = new LLUUID((String)row["assetID"]);
859 taskItem.parent_id = new LLUUID((String)row["parentFolderID"]);
860
861 taskItem.inv_type = Convert.ToInt32(row["invType"]);
862 taskItem.type = Convert.ToInt32(row["assetType"]);
863
864 taskItem.name = (String)row["name"];
865 taskItem.desc = (String)row["description"];
866 taskItem.creation_date = Convert.ToUInt32(row["creationDate"]);
867 taskItem.creator_id = new LLUUID((String)row["creatorID"]);
868 taskItem.owner_id = new LLUUID((String)row["ownerID"]);
869 taskItem.last_owner_id = new LLUUID((String)row["lastOwnerID"]);
870 taskItem.group_id = new LLUUID((String)row["groupID"]);
871
872 taskItem.next_owner_mask = Convert.ToUInt32(row["nextPermissions"]);
873 taskItem.owner_mask = Convert.ToUInt32(row["currentPermissions"]);
874 taskItem.base_mask = Convert.ToUInt32(row["basePermissions"]);
875 taskItem.everyone_mask = Convert.ToUInt32(row["everyonePermissions"]);
876 taskItem.group_mask = Convert.ToUInt32(row["groupPermissions"]);
877
878 return taskItem;
879 }
730 880
731 private LandData buildLandData(DataRow row) 881 private LandData buildLandData(DataRow row)
732 { 882 {
@@ -870,6 +1020,30 @@ namespace OpenSim.Framework.Data.MySQL
870 } 1020 }
871 } 1021 }
872 } 1022 }
1023
1024 private void fillItemRow(DataRow row, TaskInventoryItem taskItem)
1025 {
1026 row["itemID"] = taskItem.item_id;
1027 row["primID"] = taskItem.ParentPartID;
1028 row["assetID"] = taskItem.asset_id;
1029 row["parentFolderID"] = taskItem.parent_id;
1030
1031 row["invType"] = taskItem.inv_type;
1032 row["assetType"] = taskItem.type;
1033
1034 row["name"] = taskItem.name;
1035 row["description"] = taskItem.desc;
1036 row["creationDate"] = taskItem.creation_date;
1037 row["creatorID"] = taskItem.creator_id;
1038 row["ownerID"] = taskItem.owner_id;
1039 row["lastOwnerID"] = taskItem.last_owner_id;
1040 row["groupID"] = taskItem.group_id;
1041 row["nextPermissions"] = taskItem.next_owner_mask;
1042 row["currentPermissions"] = taskItem.owner_mask;
1043 row["basePermissions"] = taskItem.base_mask;
1044 row["everyonePermissions"] = taskItem.everyone_mask;
1045 row["groupPermissions"] = taskItem.group_mask;
1046 }
873 1047
874 private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID) 1048 private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID)
875 { 1049 {
@@ -1017,7 +1191,79 @@ namespace OpenSim.Framework.Data.MySQL
1017 { 1191 {
1018 fillShapeRow(shapeRow, prim); 1192 fillShapeRow(shapeRow, prim);
1019 } 1193 }
1194
1195 if (persistPrimInventories)
1196 {
1197 addPrimInventory(prim.UUID, prim.TaskInventory);
1198 }
1020 } 1199 }
1200
1201 /// <summary>
1202 /// Persist prim inventory. Deletes, updates and inserts rows.
1203 /// </summary>
1204 /// <param name="primID"></param>
1205 /// <param name="items"></param>
1206 /// <returns></returns>
1207 private void addPrimInventory(LLUUID primID, IDictionary<LLUUID, TaskInventoryItem> items)
1208 {
1209 MainLog.Instance.Verbose("DATASTORE", "Entered addPrimInventory with prim ID {0}", primID);
1210
1211 // Find all existing inventory rows for this prim
1212 DataTable dbItems = m_itemsTable;
1213
1214 String sql = String.Format("primID = '{0}'", primID);
1215 DataRow[] dbItemRows = dbItems.Select(sql);
1216
1217 // Build structures for manipulation purposes
1218 IDictionary<String, DataRow> dbItemsToRemove = new Dictionary<String, DataRow>();
1219 ICollection<TaskInventoryItem> itemsToAdd
1220 = new List<TaskInventoryItem>();
1221
1222 foreach (DataRow row in dbItemRows)
1223 {
1224 dbItemsToRemove.Add((String)row["itemID"], row);
1225 }
1226
1227 // Eliminate rows from the deletion set which already exist for this prim's inventory
1228 // TODO Very temporary, need to take account of simple metadata changes soon
1229 foreach (LLUUID itemId in items.Keys)
1230 {
1231 String rawItemId = itemId.ToString();
1232
1233 if (dbItemsToRemove.ContainsKey(rawItemId))
1234 {
1235 dbItemsToRemove.Remove(rawItemId);
1236 }
1237 else
1238 {
1239 itemsToAdd.Add(items[itemId]);
1240 }
1241 }
1242
1243 // Delete excess rows
1244 foreach (DataRow row in dbItemsToRemove.Values)
1245 {
1246 MainLog.Instance.Verbose(
1247 "DATASTORE",
1248 "Removing item {0}, {1} from prim ID {2}",
1249 row["name"], row["itemID"], row["primID"]);
1250
1251 row.Delete();
1252 }
1253
1254 // Insert items not already present
1255 foreach (TaskInventoryItem newItem in itemsToAdd)
1256 {
1257 MainLog.Instance.Verbose(
1258 "DATASTORE",
1259 "Adding item {0}, {1} to prim ID {1}",
1260 newItem.name, newItem.item_id, newItem.ParentPartID);
1261
1262 DataRow newItemRow = dbItems.NewRow();
1263 fillItemRow(newItemRow, newItem);
1264 dbItems.Rows.Add(newItemRow);
1265 }
1266 }
1021 1267
1022 /*********************************************************************** 1268 /***********************************************************************
1023 * 1269 *
@@ -1111,6 +1357,9 @@ namespace OpenSim.Framework.Data.MySQL
1111 } 1357 }
1112 sql += subsql; 1358 sql += subsql;
1113 sql += ")"; 1359 sql += ")";
1360
1361 //MainLog.Instance.Verbose("DATASTORE", "defineTable() sql {0}", sql);
1362
1114 return sql; 1363 return sql;
1115 } 1364 }
1116 1365
@@ -1166,6 +1415,20 @@ namespace OpenSim.Framework.Data.MySQL
1166 delete.Connection = conn; 1415 delete.Connection = conn;
1167 da.DeleteCommand = delete; 1416 da.DeleteCommand = delete;
1168 } 1417 }
1418
1419 private void SetupItemsCommands(MySqlDataAdapter da, MySqlConnection conn)
1420 {
1421 da.InsertCommand = createInsertCommand("primitems", m_itemsTable);
1422 da.InsertCommand.Connection = conn;
1423
1424 da.UpdateCommand = createUpdateCommand("primitems", "itemID = :itemID", m_itemsTable);
1425 da.UpdateCommand.Connection = conn;
1426
1427 MySqlCommand delete = new MySqlCommand("delete from primitems where itemID = :itemID");
1428 delete.Parameters.Add(createMySqlParameter("itemID", typeof (String)));
1429 delete.Connection = conn;
1430 da.DeleteCommand = delete;
1431 }
1169 1432
1170 private void SetupTerrainCommands(MySqlDataAdapter da, MySqlConnection conn) 1433 private void SetupTerrainCommands(MySqlDataAdapter da, MySqlConnection conn)
1171 { 1434 {
@@ -1206,12 +1469,14 @@ namespace OpenSim.Framework.Data.MySQL
1206 { 1469 {
1207 string createPrims = defineTable(createPrimTable()); 1470 string createPrims = defineTable(createPrimTable());
1208 string createShapes = defineTable(createShapeTable()); 1471 string createShapes = defineTable(createShapeTable());
1472 string createItems = defineTable(createItemsTable());
1209 string createTerrain = defineTable(createTerrainTable()); 1473 string createTerrain = defineTable(createTerrainTable());
1210 string createLand = defineTable(createLandTable()); 1474 string createLand = defineTable(createLandTable());
1211 string createLandAccessList = defineTable(createLandAccessListTable()); 1475 string createLandAccessList = defineTable(createLandAccessListTable());
1212 1476
1213 MySqlCommand pcmd = new MySqlCommand(createPrims, conn); 1477 MySqlCommand pcmd = new MySqlCommand(createPrims, conn);
1214 MySqlCommand scmd = new MySqlCommand(createShapes, conn); 1478 MySqlCommand scmd = new MySqlCommand(createShapes, conn);
1479 MySqlCommand icmd = new MySqlCommand(createItems, conn);
1215 MySqlCommand tcmd = new MySqlCommand(createTerrain, conn); 1480 MySqlCommand tcmd = new MySqlCommand(createTerrain, conn);
1216 MySqlCommand lcmd = new MySqlCommand(createLand, conn); 1481 MySqlCommand lcmd = new MySqlCommand(createLand, conn);
1217 MySqlCommand lalcmd = new MySqlCommand(createLandAccessList, conn); 1482 MySqlCommand lalcmd = new MySqlCommand(createLandAccessList, conn);
@@ -1225,45 +1490,54 @@ namespace OpenSim.Framework.Data.MySQL
1225 { 1490 {
1226 pcmd.ExecuteNonQuery(); 1491 pcmd.ExecuteNonQuery();
1227 } 1492 }
1228 catch (MySqlException) 1493 catch (MySqlException e)
1229 { 1494 {
1230 MainLog.Instance.Warn("MySql", "Primitives Table Already Exists"); 1495 MainLog.Instance.Warn("MySql", "Primitives Table Already Exists: {0}", e);
1231 } 1496 }
1232 1497
1233 try 1498 try
1234 { 1499 {
1235 scmd.ExecuteNonQuery(); 1500 scmd.ExecuteNonQuery();
1236 } 1501 }
1237 catch (MySqlException) 1502 catch (MySqlException e)
1238 { 1503 {
1239 MainLog.Instance.Warn("MySql", "Shapes Table Already Exists"); 1504 MainLog.Instance.Warn("MySql", "Shapes Table Already Exists: {0}", e);
1240 } 1505 }
1506
1507 try
1508 {
1509 icmd.ExecuteNonQuery();
1510 }
1511 catch (MySqlException e)
1512 {
1513 MainLog.Instance.Warn("MySql", "Items Table Already Exists: {0}", e);
1514 }
1241 1515
1242 try 1516 try
1243 { 1517 {
1244 tcmd.ExecuteNonQuery(); 1518 tcmd.ExecuteNonQuery();
1245 } 1519 }
1246 catch (MySqlException) 1520 catch (MySqlException e)
1247 { 1521 {
1248 MainLog.Instance.Warn("MySql", "Terrain Table Already Exists"); 1522 MainLog.Instance.Warn("MySql", "Terrain Table Already Exists: {0}", e);
1249 } 1523 }
1250 1524
1251 try 1525 try
1252 { 1526 {
1253 lcmd.ExecuteNonQuery(); 1527 lcmd.ExecuteNonQuery();
1254 } 1528 }
1255 catch (MySqlException) 1529 catch (MySqlException e)
1256 { 1530 {
1257 MainLog.Instance.Warn("MySql", "Land Table Already Exists"); 1531 MainLog.Instance.Warn("MySql", "Land Table Already Exists: {0}", e);
1258 } 1532 }
1259 1533
1260 try 1534 try
1261 { 1535 {
1262 lalcmd.ExecuteNonQuery(); 1536 lalcmd.ExecuteNonQuery();
1263 } 1537 }
1264 catch (MySqlException) 1538 catch (MySqlException e)
1265 { 1539 {
1266 MainLog.Instance.Warn("MySql", "LandAccessList Table Already Exists"); 1540 MainLog.Instance.Warn("MySql", "LandAccessList Table Already Exists: {0}", e);
1267 } 1541 }
1268 conn.Close(); 1542 conn.Close();
1269 } 1543 }
@@ -1274,6 +1548,8 @@ namespace OpenSim.Framework.Data.MySQL
1274 MySqlDataAdapter pDa = new MySqlDataAdapter(primSelectCmd); 1548 MySqlDataAdapter pDa = new MySqlDataAdapter(primSelectCmd);
1275 MySqlCommand shapeSelectCmd = new MySqlCommand(m_shapeSelect, conn); 1549 MySqlCommand shapeSelectCmd = new MySqlCommand(m_shapeSelect, conn);
1276 MySqlDataAdapter sDa = new MySqlDataAdapter(shapeSelectCmd); 1550 MySqlDataAdapter sDa = new MySqlDataAdapter(shapeSelectCmd);
1551 MySqlCommand itemsSelectCmd = new MySqlCommand(m_itemsSelect, conn);
1552 MySqlDataAdapter iDa = new MySqlDataAdapter(itemsSelectCmd);
1277 MySqlCommand terrainSelectCmd = new MySqlCommand(m_terrainSelect, conn); 1553 MySqlCommand terrainSelectCmd = new MySqlCommand(m_terrainSelect, conn);
1278 MySqlDataAdapter tDa = new MySqlDataAdapter(terrainSelectCmd); 1554 MySqlDataAdapter tDa = new MySqlDataAdapter(terrainSelectCmd);
1279 MySqlCommand landSelectCmd = new MySqlCommand(m_landSelect, conn); 1555 MySqlCommand landSelectCmd = new MySqlCommand(m_landSelect, conn);
@@ -1286,6 +1562,10 @@ namespace OpenSim.Framework.Data.MySQL
1286 { 1562 {
1287 pDa.Fill(tmpDS, "prims"); 1563 pDa.Fill(tmpDS, "prims");
1288 sDa.Fill(tmpDS, "primshapes"); 1564 sDa.Fill(tmpDS, "primshapes");
1565
1566 if (persistPrimInventories)
1567 iDa.Fill(tmpDS, "primitems");
1568
1289 tDa.Fill(tmpDS, "terrain"); 1569 tDa.Fill(tmpDS, "terrain");
1290 lDa.Fill(tmpDS, "land"); 1570 lDa.Fill(tmpDS, "land");
1291 lalDa.Fill(tmpDS, "landaccesslist"); 1571 lalDa.Fill(tmpDS, "landaccesslist");
@@ -1298,6 +1578,10 @@ namespace OpenSim.Framework.Data.MySQL
1298 1578
1299 pDa.Fill(tmpDS, "prims"); 1579 pDa.Fill(tmpDS, "prims");
1300 sDa.Fill(tmpDS, "primshapes"); 1580 sDa.Fill(tmpDS, "primshapes");
1581
1582 if (persistPrimInventories)
1583 iDa.Fill(tmpDS, "primitems");
1584
1301 tDa.Fill(tmpDS, "terrain"); 1585 tDa.Fill(tmpDS, "terrain");
1302 lDa.Fill(tmpDS, "land"); 1586 lDa.Fill(tmpDS, "land");
1303 lalDa.Fill(tmpDS, "landaccesslist"); 1587 lalDa.Fill(tmpDS, "landaccesslist");
@@ -1310,6 +1594,7 @@ namespace OpenSim.Framework.Data.MySQL
1310 return false; 1594 return false;
1311 } 1595 }
1312 } 1596 }
1597
1313 foreach (DataColumn col in createShapeTable().Columns) 1598 foreach (DataColumn col in createShapeTable().Columns)
1314 { 1599 {
1315 if (!tmpDS.Tables["primshapes"].Columns.Contains(col.ColumnName)) 1600 if (!tmpDS.Tables["primshapes"].Columns.Contains(col.ColumnName))
@@ -1318,6 +1603,9 @@ namespace OpenSim.Framework.Data.MySQL
1318 return false; 1603 return false;
1319 } 1604 }
1320 } 1605 }
1606
1607 // XXX primitems should probably go here eventually
1608
1321 foreach (DataColumn col in createTerrainTable().Columns) 1609 foreach (DataColumn col in createTerrainTable().Columns)
1322 { 1610 {
1323 if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName)) 1611 if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName))
@@ -1326,6 +1614,7 @@ namespace OpenSim.Framework.Data.MySQL
1326 return false; 1614 return false;
1327 } 1615 }
1328 } 1616 }
1617
1329 foreach (DataColumn col in createLandTable().Columns) 1618 foreach (DataColumn col in createLandTable().Columns)
1330 { 1619 {
1331 if (!tmpDS.Tables["land"].Columns.Contains(col.ColumnName)) 1620 if (!tmpDS.Tables["land"].Columns.Contains(col.ColumnName))
@@ -1334,6 +1623,7 @@ namespace OpenSim.Framework.Data.MySQL
1334 return false; 1623 return false;
1335 } 1624 }
1336 } 1625 }
1626
1337 foreach (DataColumn col in createLandAccessListTable().Columns) 1627 foreach (DataColumn col in createLandAccessListTable().Columns)
1338 { 1628 {
1339 if (!tmpDS.Tables["landaccesslist"].Columns.Contains(col.ColumnName)) 1629 if (!tmpDS.Tables["landaccesslist"].Columns.Contains(col.ColumnName))
@@ -1342,6 +1632,7 @@ namespace OpenSim.Framework.Data.MySQL
1342 return false; 1632 return false;
1343 } 1633 }
1344 } 1634 }
1635
1345 return true; 1636 return true;
1346 } 1637 }
1347 1638
@@ -1395,6 +1686,10 @@ namespace OpenSim.Framework.Data.MySQL
1395 { 1686 {
1396 return "integer"; 1687 return "integer";
1397 } 1688 }
1689 else if (type == typeof (Int64))
1690 {
1691 return "bigint";
1692 }
1398 else if (type == typeof (Double)) 1693 else if (type == typeof (Double))
1399 { 1694 {
1400 return "float"; 1695 return "float";
@@ -1409,4 +1704,4 @@ namespace OpenSim.Framework.Data.MySQL
1409 } 1704 }
1410 } 1705 }
1411 } 1706 }
1412} \ No newline at end of file 1707}
diff --git a/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs b/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
index 96dd5ac..dfd4535 100644
--- a/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
@@ -61,6 +61,7 @@ namespace OpenSim.Framework.Data.SQLite
61 61
62 private String m_connectionString; 62 private String m_connectionString;
63 63
64 // Temporary attribute while this is experimental
64 private bool persistPrimInventories; 65 private bool persistPrimInventories;
65 66
66 /*********************************************************************** 67 /***********************************************************************
@@ -208,6 +209,7 @@ namespace OpenSim.Framework.Data.SQLite
208 { 209 {
209 DataTable prims = ds.Tables["prims"]; 210 DataTable prims = ds.Tables["prims"];
210 DataTable shapes = ds.Tables["primshapes"]; 211 DataTable shapes = ds.Tables["primshapes"];
212 DataTable items = ds.Tables["primitems"];
211 213
212 string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'"; 214 string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'";
213 lock (ds) 215 lock (ds)
@@ -215,13 +217,28 @@ namespace OpenSim.Framework.Data.SQLite
215 DataRow[] primRows = prims.Select(selectExp); 217 DataRow[] primRows = prims.Select(selectExp);
216 foreach (DataRow row in primRows) 218 foreach (DataRow row in primRows)
217 { 219 {
220 // Remove shape rows
218 LLUUID uuid = new LLUUID((string) row["UUID"]); 221 LLUUID uuid = new LLUUID((string) row["UUID"]);
219 DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(uuid)); 222 DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(uuid));
220 if (shapeRow != null) 223 if (shapeRow != null)
221 { 224 {
222 shapeRow.Delete(); 225 shapeRow.Delete();
223 } 226 }
224 row.Delete(); 227
228 if (persistPrimInventories)
229 {
230 // Remove items rows
231 String sql = String.Format("primID = '{0}'", uuid);
232 DataRow[] itemRows = items.Select(sql);
233
234 foreach (DataRow itemsRow in itemRows)
235 {
236 itemsRow.Delete();
237 }
238 }
239
240 // Remove prim row
241 row.Delete();
225 } 242 }
226 } 243 }
227 244
@@ -1444,6 +1461,20 @@ namespace OpenSim.Framework.Data.SQLite
1444 param.SourceColumn = name; 1461 param.SourceColumn = name;
1445 param.SourceVersion = DataRowVersion.Current; 1462 param.SourceVersion = DataRowVersion.Current;
1446 return param; 1463 return param;
1464 }
1465
1466 private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn)
1467 {
1468 da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]);
1469 da.InsertCommand.Connection = conn;
1470
1471 da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]);
1472 da.UpdateCommand.Connection = conn;
1473
1474 SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID");
1475 delete.Parameters.Add(createSqliteParameter("UUID", typeof (String)));
1476 delete.Connection = conn;
1477 da.DeleteCommand = delete;
1447 } 1478 }
1448 1479
1449 private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) 1480 private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn)
@@ -1460,20 +1491,6 @@ namespace OpenSim.Framework.Data.SQLite
1460 da.DeleteCommand = delete; 1491 da.DeleteCommand = delete;
1461 } 1492 }
1462 1493
1463 private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn)
1464 {
1465 da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]);
1466 da.InsertCommand.Connection = conn;
1467
1468 da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]);
1469 da.UpdateCommand.Connection = conn;
1470
1471 SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID");
1472 delete.Parameters.Add(createSqliteParameter("UUID", typeof (String)));
1473 delete.Connection = conn;
1474 da.DeleteCommand = delete;
1475 }
1476
1477 private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn) 1494 private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn)
1478 { 1495 {
1479 da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]); 1496 da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]);
@@ -1656,8 +1673,8 @@ namespace OpenSim.Framework.Data.SQLite
1656 return false; 1673 return false;
1657 } 1674 }
1658 } 1675 }
1659 1676
1660 // TODO Not restoring prim inventories quite yet 1677 // XXX primitems should probably go here eventually
1661 1678
1662 foreach (DataColumn col in createTerrainTable().Columns) 1679 foreach (DataColumn col in createTerrainTable().Columns)
1663 { 1680 {
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
index b188fdd..d694f67 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
@@ -235,6 +235,13 @@ namespace OpenSim.Region.Environment.Scenes
235 if (part != null) 235 if (part != null)
236 { 236 {
237 part.UpdateInventoryItem(item); 237 part.UpdateInventoryItem(item);
238
239 // It might seem somewhat crude to update the whole group for a single prim inventory change,
240 // but it's possible that other prim inventory changes will take place before the region
241 // persistence thread visits this object. In the future, changes can be signalled at a more
242 // granular level, or we could let the datastore worry about whether prims have really
243 // changed since they were last persisted.
244 HasChanged = true;
238 245
239 return true; 246 return true;
240 } 247 }