aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Data.MySQL/MySQLDataStore.cs97
-rw-r--r--OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs84
-rw-r--r--OpenSim/Framework/TaskInventoryItem.cs115
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.Inventory.cs17
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs18
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs12
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs90
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectPart.cs13
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs4
-rw-r--r--OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs4
10 files changed, 291 insertions, 163 deletions
diff --git a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
index 26985b3..183a2f9 100644
--- a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
+++ b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs
@@ -163,6 +163,8 @@ namespace OpenSim.Framework.Data.MySQL
163 163
164 public void RemoveObject(LLUUID obj, LLUUID regionUUID) 164 public void RemoveObject(LLUUID obj, LLUUID regionUUID)
165 { 165 {
166 MainLog.Instance.Verbose("DATASTORE", "Removing obj: {0} from region: {1}", obj.UUID, regionUUID);
167
166 DataTable prims = m_primTable; 168 DataTable prims = m_primTable;
167 DataTable shapes = m_shapeTable; 169 DataTable shapes = m_shapeTable;
168 DataTable items = m_itemsTable; 170 DataTable items = m_itemsTable;
@@ -187,9 +189,9 @@ namespace OpenSim.Framework.Data.MySQL
187 String sql = String.Format("primID = '{0}'", uuid); 189 String sql = String.Format("primID = '{0}'", uuid);
188 DataRow[] itemRows = items.Select(sql); 190 DataRow[] itemRows = items.Select(sql);
189 191
190 foreach (DataRow itemsRow in itemRows) 192 foreach (DataRow itemRow in itemRows)
191 { 193 {
192 shapeRow.Delete(); 194 itemRow.Delete();
193 } 195 }
194 } 196 }
195 197
@@ -307,7 +309,7 @@ namespace OpenSim.Framework.Data.MySQL
307 TaskInventoryItem item = buildItem(row); 309 TaskInventoryItem item = buildItem(row);
308 inventory.Add(item); 310 inventory.Add(item);
309 311
310 MainLog.Instance.Verbose("DATASTORE", "Restored item {0}, {1}", item.name, item.item_id); 312 MainLog.Instance.Verbose("DATASTORE", "Restored item {0}, {1}", item.Name, item.ItemID);
311 } 313 }
312 314
313 prim.AddInventoryItems(inventory); 315 prim.AddInventoryItems(inventory);
@@ -316,7 +318,7 @@ namespace OpenSim.Framework.Data.MySQL
316 // every item). This data should really be stored in the prim table itself. 318 // every item). This data should really be stored in the prim table itself.
317 if (dbItemRows.Length > 0) 319 if (dbItemRows.Length > 0)
318 { 320 {
319 prim.FolderID = inventory[0].parent_id; 321 prim.FolderID = inventory[0].ParentID;
320 } 322 }
321 } 323 }
322 324
@@ -853,27 +855,27 @@ namespace OpenSim.Framework.Data.MySQL
853 { 855 {
854 TaskInventoryItem taskItem = new TaskInventoryItem(); 856 TaskInventoryItem taskItem = new TaskInventoryItem();
855 857
856 taskItem.item_id = new LLUUID((String)row["itemID"]); 858 taskItem.ItemID = new LLUUID((String)row["itemID"]);
857 taskItem.ParentPartID = new LLUUID((String)row["primID"]); 859 taskItem.ParentPartID = new LLUUID((String)row["primID"]);
858 taskItem.asset_id = new LLUUID((String)row["assetID"]); 860 taskItem.AssetID = new LLUUID((String)row["assetID"]);
859 taskItem.parent_id = new LLUUID((String)row["parentFolderID"]); 861 taskItem.ParentID = new LLUUID((String)row["parentFolderID"]);
860 862
861 taskItem.inv_type = Convert.ToInt32(row["invType"]); 863 taskItem.InvType = Convert.ToInt32(row["invType"]);
862 taskItem.type = Convert.ToInt32(row["assetType"]); 864 taskItem.Type = Convert.ToInt32(row["assetType"]);
863 865
864 taskItem.name = (String)row["name"]; 866 taskItem.Name = (String)row["name"];
865 taskItem.desc = (String)row["description"]; 867 taskItem.Description = (String)row["description"];
866 taskItem.creation_date = Convert.ToUInt32(row["creationDate"]); 868 taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
867 taskItem.creator_id = new LLUUID((String)row["creatorID"]); 869 taskItem.CreatorID = new LLUUID((String)row["creatorID"]);
868 taskItem.owner_id = new LLUUID((String)row["ownerID"]); 870 taskItem.OwnerID = new LLUUID((String)row["ownerID"]);
869 taskItem.last_owner_id = new LLUUID((String)row["lastOwnerID"]); 871 taskItem.LastOwnerID = new LLUUID((String)row["lastOwnerID"]);
870 taskItem.group_id = new LLUUID((String)row["groupID"]); 872 taskItem.GroupID = new LLUUID((String)row["groupID"]);
871 873
872 taskItem.next_owner_mask = Convert.ToUInt32(row["nextPermissions"]); 874 taskItem.NextOwnerMask = Convert.ToUInt32(row["nextPermissions"]);
873 taskItem.owner_mask = Convert.ToUInt32(row["currentPermissions"]); 875 taskItem.OwnerMask = Convert.ToUInt32(row["currentPermissions"]);
874 taskItem.base_mask = Convert.ToUInt32(row["basePermissions"]); 876 taskItem.BaseMask = Convert.ToUInt32(row["basePermissions"]);
875 taskItem.everyone_mask = Convert.ToUInt32(row["everyonePermissions"]); 877 taskItem.EveryoneMask = Convert.ToUInt32(row["everyonePermissions"]);
876 taskItem.group_mask = Convert.ToUInt32(row["groupPermissions"]); 878 taskItem.GroupMask = Convert.ToUInt32(row["groupPermissions"]);
877 879
878 return taskItem; 880 return taskItem;
879 } 881 }
@@ -1023,26 +1025,26 @@ namespace OpenSim.Framework.Data.MySQL
1023 1025
1024 private void fillItemRow(DataRow row, TaskInventoryItem taskItem) 1026 private void fillItemRow(DataRow row, TaskInventoryItem taskItem)
1025 { 1027 {
1026 row["itemID"] = taskItem.item_id; 1028 row["itemID"] = taskItem.ItemID;
1027 row["primID"] = taskItem.ParentPartID; 1029 row["primID"] = taskItem.ParentPartID;
1028 row["assetID"] = taskItem.asset_id; 1030 row["assetID"] = taskItem.AssetID;
1029 row["parentFolderID"] = taskItem.parent_id; 1031 row["parentFolderID"] = taskItem.ParentID;
1030 1032
1031 row["invType"] = taskItem.inv_type; 1033 row["invType"] = taskItem.InvType;
1032 row["assetType"] = taskItem.type; 1034 row["assetType"] = taskItem.Type;
1033 1035
1034 row["name"] = taskItem.name; 1036 row["name"] = taskItem.Name;
1035 row["description"] = taskItem.desc; 1037 row["description"] = taskItem.Description;
1036 row["creationDate"] = taskItem.creation_date; 1038 row["creationDate"] = taskItem.CreationDate;
1037 row["creatorID"] = taskItem.creator_id; 1039 row["creatorID"] = taskItem.CreatorID;
1038 row["ownerID"] = taskItem.owner_id; 1040 row["ownerID"] = taskItem.OwnerID;
1039 row["lastOwnerID"] = taskItem.last_owner_id; 1041 row["lastOwnerID"] = taskItem.LastOwnerID;
1040 row["groupID"] = taskItem.group_id; 1042 row["groupID"] = taskItem.GroupID;
1041 row["nextPermissions"] = taskItem.next_owner_mask; 1043 row["nextPermissions"] = taskItem.NextOwnerMask;
1042 row["currentPermissions"] = taskItem.owner_mask; 1044 row["currentPermissions"] = taskItem.OwnerMask;
1043 row["basePermissions"] = taskItem.base_mask; 1045 row["basePermissions"] = taskItem.BaseMask;
1044 row["everyonePermissions"] = taskItem.everyone_mask; 1046 row["everyonePermissions"] = taskItem.EveryoneMask;
1045 row["groupPermissions"] = taskItem.group_mask; 1047 row["groupPermissions"] = taskItem.GroupMask;
1046 } 1048 }
1047 1049
1048 private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID) 1050 private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID)
@@ -1216,11 +1218,15 @@ namespace OpenSim.Framework.Data.MySQL
1216 1218
1217 // Build structures for manipulation purposes 1219 // Build structures for manipulation purposes
1218 IDictionary<String, DataRow> dbItemsToRemove = new Dictionary<String, DataRow>(); 1220 IDictionary<String, DataRow> dbItemsToRemove = new Dictionary<String, DataRow>();
1219 ICollection<TaskInventoryItem> itemsToAdd 1221 ICollection<TaskInventoryItem> itemsToAdd = new List<TaskInventoryItem>();
1220 = new List<TaskInventoryItem>();
1221 1222
1222 foreach (DataRow row in dbItemRows) 1223 foreach (DataRow row in dbItemRows)
1223 { 1224 {
1225 MainLog.Instance.Verbose(
1226 "DATASTORE",
1227 "Found item {0}, {1} in prim id {2}",
1228 row["name"], row["itemID"], primID);
1229
1224 dbItemsToRemove.Add((String)row["itemID"], row); 1230 dbItemsToRemove.Add((String)row["itemID"], row);
1225 } 1231 }
1226 1232
@@ -1232,6 +1238,11 @@ namespace OpenSim.Framework.Data.MySQL
1232 1238
1233 if (dbItemsToRemove.ContainsKey(rawItemId)) 1239 if (dbItemsToRemove.ContainsKey(rawItemId))
1234 { 1240 {
1241 MainLog.Instance.Verbose(
1242 "DATASTORE",
1243 "Discarding item {0}, {1} from remove candidates for prim id {2}",
1244 items[itemId].Name, rawItemId, primID);
1245
1235 dbItemsToRemove.Remove(rawItemId); 1246 dbItemsToRemove.Remove(rawItemId);
1236 } 1247 }
1237 else 1248 else
@@ -1256,8 +1267,8 @@ namespace OpenSim.Framework.Data.MySQL
1256 { 1267 {
1257 MainLog.Instance.Verbose( 1268 MainLog.Instance.Verbose(
1258 "DATASTORE", 1269 "DATASTORE",
1259 "Adding item {0}, {1} to prim ID {1}", 1270 "Adding item {0}, {1} to prim ID {2}",
1260 newItem.name, newItem.item_id, newItem.ParentPartID); 1271 newItem.Name, newItem.ItemID, newItem.ParentPartID);
1261 1272
1262 DataRow newItemRow = dbItems.NewRow(); 1273 DataRow newItemRow = dbItems.NewRow();
1263 fillItemRow(newItemRow, newItem); 1274 fillItemRow(newItemRow, newItem);
diff --git a/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs b/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
index 1fd5c47..94c05e1 100644
--- a/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs
@@ -205,6 +205,8 @@ namespace OpenSim.Framework.Data.SQLite
205 205
206 public void RemoveObject(LLUUID obj, LLUUID regionUUID) 206 public void RemoveObject(LLUUID obj, LLUUID regionUUID)
207 { 207 {
208 MainLog.Instance.Verbose("DATASTORE", "Removing obj: {0} from region: {1}", obj.UUID, regionUUID);
209
208 DataTable prims = ds.Tables["prims"]; 210 DataTable prims = ds.Tables["prims"];
209 DataTable shapes = ds.Tables["primshapes"]; 211 DataTable shapes = ds.Tables["primshapes"];
210 DataTable items = ds.Tables["primitems"]; 212 DataTable items = ds.Tables["primitems"];
@@ -229,9 +231,9 @@ namespace OpenSim.Framework.Data.SQLite
229 String sql = String.Format("primID = '{0}'", uuid); 231 String sql = String.Format("primID = '{0}'", uuid);
230 DataRow[] itemRows = items.Select(sql); 232 DataRow[] itemRows = items.Select(sql);
231 233
232 foreach (DataRow itemsRow in itemRows) 234 foreach (DataRow itemRow in itemRows)
233 { 235 {
234 itemsRow.Delete(); 236 itemRow.Delete();
235 } 237 }
236 } 238 }
237 239
@@ -351,7 +353,7 @@ namespace OpenSim.Framework.Data.SQLite
351 TaskInventoryItem item = buildItem(row); 353 TaskInventoryItem item = buildItem(row);
352 inventory.Add(item); 354 inventory.Add(item);
353 355
354 MainLog.Instance.Verbose("DATASTORE", "Restored item {0}, {1}", item.name, item.item_id); 356 MainLog.Instance.Verbose("DATASTORE", "Restored item {0}, {1}", item.Name, item.ItemID);
355 } 357 }
356 358
357 prim.AddInventoryItems(inventory); 359 prim.AddInventoryItems(inventory);
@@ -360,7 +362,7 @@ namespace OpenSim.Framework.Data.SQLite
360 // every item). This data should really be stored in the prim table itself. 362 // every item). This data should really be stored in the prim table itself.
361 if (dbItemRows.Length > 0) 363 if (dbItemRows.Length > 0)
362 { 364 {
363 prim.FolderID = inventory[0].parent_id; 365 prim.FolderID = inventory[0].ParentID;
364 } 366 }
365 } 367 }
366 368
@@ -889,27 +891,27 @@ namespace OpenSim.Framework.Data.SQLite
889 { 891 {
890 TaskInventoryItem taskItem = new TaskInventoryItem(); 892 TaskInventoryItem taskItem = new TaskInventoryItem();
891 893
892 taskItem.item_id = new LLUUID((String)row["itemID"]); 894 taskItem.ItemID = new LLUUID((String)row["itemID"]);
893 taskItem.ParentPartID = new LLUUID((String)row["primID"]); 895 taskItem.ParentPartID = new LLUUID((String)row["primID"]);
894 taskItem.asset_id = new LLUUID((String)row["assetID"]); 896 taskItem.AssetID = new LLUUID((String)row["assetID"]);
895 taskItem.parent_id = new LLUUID((String)row["parentFolderID"]); 897 taskItem.ParentID = new LLUUID((String)row["parentFolderID"]);
896 898
897 taskItem.inv_type = Convert.ToInt32(row["invType"]); 899 taskItem.InvType = Convert.ToInt32(row["invType"]);
898 taskItem.type = Convert.ToInt32(row["assetType"]); 900 taskItem.Type = Convert.ToInt32(row["assetType"]);
899 901
900 taskItem.name = (String)row["name"]; 902 taskItem.Name = (String)row["name"];
901 taskItem.desc = (String)row["description"]; 903 taskItem.Description = (String)row["description"];
902 taskItem.creation_date = Convert.ToUInt32(row["creationDate"]); 904 taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
903 taskItem.creator_id = new LLUUID((String)row["creatorID"]); 905 taskItem.CreatorID = new LLUUID((String)row["creatorID"]);
904 taskItem.owner_id = new LLUUID((String)row["ownerID"]); 906 taskItem.OwnerID = new LLUUID((String)row["ownerID"]);
905 taskItem.last_owner_id = new LLUUID((String)row["lastOwnerID"]); 907 taskItem.LastOwnerID = new LLUUID((String)row["lastOwnerID"]);
906 taskItem.group_id = new LLUUID((String)row["groupID"]); 908 taskItem.GroupID = new LLUUID((String)row["groupID"]);
907 909
908 taskItem.next_owner_mask = Convert.ToUInt32(row["nextPermissions"]); 910 taskItem.NextOwnerMask = Convert.ToUInt32(row["nextPermissions"]);
909 taskItem.owner_mask = Convert.ToUInt32(row["currentPermissions"]); 911 taskItem.OwnerMask = Convert.ToUInt32(row["currentPermissions"]);
910 taskItem.base_mask = Convert.ToUInt32(row["basePermissions"]); 912 taskItem.BaseMask = Convert.ToUInt32(row["basePermissions"]);
911 taskItem.everyone_mask = Convert.ToUInt32(row["everyonePermissions"]); 913 taskItem.EveryoneMask = Convert.ToUInt32(row["everyonePermissions"]);
912 taskItem.group_mask = Convert.ToUInt32(row["groupPermissions"]); 914 taskItem.GroupMask = Convert.ToUInt32(row["groupPermissions"]);
913 915
914 return taskItem; 916 return taskItem;
915 } 917 }
@@ -1059,26 +1061,26 @@ namespace OpenSim.Framework.Data.SQLite
1059 1061
1060 private void fillItemRow(DataRow row, TaskInventoryItem taskItem) 1062 private void fillItemRow(DataRow row, TaskInventoryItem taskItem)
1061 { 1063 {
1062 row["itemID"] = taskItem.item_id; 1064 row["itemID"] = taskItem.ItemID;
1063 row["primID"] = taskItem.ParentPartID; 1065 row["primID"] = taskItem.ParentPartID;
1064 row["assetID"] = taskItem.asset_id; 1066 row["assetID"] = taskItem.AssetID;
1065 row["parentFolderID"] = taskItem.parent_id; 1067 row["parentFolderID"] = taskItem.ParentID;
1066 1068
1067 row["invType"] = taskItem.inv_type; 1069 row["invType"] = taskItem.InvType;
1068 row["assetType"] = taskItem.type; 1070 row["assetType"] = taskItem.Type;
1069 1071
1070 row["name"] = taskItem.name; 1072 row["name"] = taskItem.Name;
1071 row["description"] = taskItem.desc; 1073 row["description"] = taskItem.Description;
1072 row["creationDate"] = taskItem.creation_date; 1074 row["creationDate"] = taskItem.CreationDate;
1073 row["creatorID"] = taskItem.creator_id; 1075 row["creatorID"] = taskItem.CreatorID;
1074 row["ownerID"] = taskItem.owner_id; 1076 row["ownerID"] = taskItem.OwnerID;
1075 row["lastOwnerID"] = taskItem.last_owner_id; 1077 row["lastOwnerID"] = taskItem.LastOwnerID;
1076 row["groupID"] = taskItem.group_id; 1078 row["groupID"] = taskItem.GroupID;
1077 row["nextPermissions"] = taskItem.next_owner_mask; 1079 row["nextPermissions"] = taskItem.NextOwnerMask;
1078 row["currentPermissions"] = taskItem.owner_mask; 1080 row["currentPermissions"] = taskItem.OwnerMask;
1079 row["basePermissions"] = taskItem.base_mask; 1081 row["basePermissions"] = taskItem.BaseMask;
1080 row["everyonePermissions"] = taskItem.everyone_mask; 1082 row["everyonePermissions"] = taskItem.EveryoneMask;
1081 row["groupPermissions"] = taskItem.group_mask; 1083 row["groupPermissions"] = taskItem.GroupMask;
1082 } 1084 }
1083 1085
1084 private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID) 1086 private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID)
@@ -1311,8 +1313,8 @@ namespace OpenSim.Framework.Data.SQLite
1311 { 1313 {
1312 MainLog.Instance.Verbose( 1314 MainLog.Instance.Verbose(
1313 "DATASTORE", 1315 "DATASTORE",
1314 "Adding item {0}, {1} to prim ID {1}", 1316 "Adding item {0}, {1} to prim ID {2}",
1315 newItem.name, newItem.item_id, newItem.ParentPartID); 1317 newItem.Name, newItem.ItemID, newItem.ParentPartID);
1316 1318
1317 DataRow newItemRow = dbItems.NewRow(); 1319 DataRow newItemRow = dbItems.NewRow();
1318 fillItemRow(newItemRow, newItem); 1320 fillItemRow(newItemRow, newItem);
diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs
index 107993b..6e163a9 100644
--- a/OpenSim/Framework/TaskInventoryItem.cs
+++ b/OpenSim/Framework/TaskInventoryItem.cs
@@ -26,11 +26,78 @@
26* 26*
27*/ 27*/
28 28
29using System.Collections.Generic;
30using System.Xml;
31using System.Xml.Schema;
32using System.Xml.Serialization;
33
29using libsecondlife; 34using libsecondlife;
30using System; 35using System;
31 36
32namespace OpenSim.Framework 37namespace OpenSim.Framework
33{ 38{
39 public class TaskInventoryDictionary : Dictionary<LLUUID, TaskInventoryItem>, IXmlSerializable
40 {
41 private static XmlSerializer tiiSerializer = new XmlSerializer(typeof(TaskInventoryItem));
42
43 // The alternative of simply serializing the list doesn't appear to work on mono, since
44 // we get a
45 //
46 // System.TypeInitializationException: An exception was thrown by the type initializer for OpenSim.Framework.TaskInventoryDictionary ---> System.ArgumentOutOfRangeException: < 0
47 // Parameter name: length
48 // at System.String.Substring (Int32 startIndex, Int32 length) [0x00088] in /build/buildd/mono-1.2.4/mcs/class/corlib/System/String.cs:381
49 // at System.Xml.Serialization.TypeTranslator.GetTypeData (System.Type runtimeType, System.String xmlDataType) [0x001f6] in /build/buildd/mono-1.2.4/mcs/class/System.XML/System.Xml.Serialization/TypeTranslator.cs:217
50 // ...
51// private static XmlSerializer tiiSerializer
52// = new XmlSerializer(typeof(Dictionary<LLUUID, TaskInventoryItem>.ValueCollection));
53
54 // see IXmlSerializable
55 public XmlSchema GetSchema()
56 {
57 return null;
58 }
59
60 // see IXmlSerializable
61 public void ReadXml(XmlReader reader)
62 {
63 reader.Read();
64 while (tiiSerializer.CanDeserialize(reader))
65 {
66 TaskInventoryItem item = (TaskInventoryItem)tiiSerializer.Deserialize(reader);
67 Add(item.ItemID, item);
68 }
69
70// reader.Read();
71// while (reader.Name.Equals("TaskInventoryItem"))
72// {
73// TaskInventoryItem item = (TaskInventoryItem)tiiSerializer.Deserialize(reader);
74// Add(item.ItemID, item);
75// }
76
77// ICollection<TaskInventoryItem> items
78// = (ICollection<TaskInventoryItem>)tiiSerializer.Deserialize(reader);
79//
80// foreach (TaskInventoryItem item in items)
81// {
82// Add(item.ItemID, item);
83// }
84 }
85
86 // see IXmlSerializable
87 public void WriteXml(XmlWriter writer)
88 {
89 foreach (TaskInventoryItem item in Values)
90 {
91 tiiSerializer.Serialize(writer, item);
92 }
93
94 //tiiSerializer.Serialize(writer, Values);
95 }
96 }
97
98 /// <summary>
99 /// Represents an item in a task inventory
100 /// </summary>
34 public class TaskInventoryItem 101 public class TaskInventoryItem
35 { 102 {
36 /// <summary> 103 /// <summary>
@@ -75,27 +142,37 @@ namespace OpenSim.Framework
75 "lsltext", 142 "lsltext",
76 String.Empty 143 String.Empty
77 }; 144 };
145
146 /// <summary>
147 /// Reset the LLUUIDs for this item.
148 /// </summary>
149 /// <param name="partID">The new part ID to which this item belongs</param>
150 public void ResetIDs(LLUUID partID)
151 {
152 ItemID = LLUUID.Random();
153 ParentPartID = partID;
154 }
78 155
79 public LLUUID item_id = LLUUID.Zero; 156 public LLUUID ItemID = LLUUID.Zero;
80 public LLUUID parent_id = LLUUID.Zero; //parent folder id 157 public LLUUID ParentID = LLUUID.Zero; //parent folder id
81 158
82 public uint base_mask = FULL_MASK_PERMISSIONS_GENERAL; 159 public uint BaseMask = FULL_MASK_PERMISSIONS_GENERAL;
83 public uint owner_mask = FULL_MASK_PERMISSIONS_GENERAL; 160 public uint OwnerMask = FULL_MASK_PERMISSIONS_GENERAL;
84 public uint group_mask = FULL_MASK_PERMISSIONS_GENERAL; 161 public uint GroupMask = FULL_MASK_PERMISSIONS_GENERAL;
85 public uint everyone_mask = FULL_MASK_PERMISSIONS_GENERAL; 162 public uint EveryoneMask = FULL_MASK_PERMISSIONS_GENERAL;
86 public uint next_owner_mask = FULL_MASK_PERMISSIONS_GENERAL; 163 public uint NextOwnerMask = FULL_MASK_PERMISSIONS_GENERAL;
87 public LLUUID creator_id = LLUUID.Zero; 164 public LLUUID CreatorID = LLUUID.Zero;
88 public LLUUID owner_id = LLUUID.Zero; 165 public LLUUID OwnerID = LLUUID.Zero;
89 public LLUUID last_owner_id = LLUUID.Zero; 166 public LLUUID LastOwnerID = LLUUID.Zero;
90 public LLUUID group_id = LLUUID.Zero; 167 public LLUUID GroupID = LLUUID.Zero;
91 168
92 public LLUUID asset_id = LLUUID.Zero; 169 public LLUUID AssetID = LLUUID.Zero;
93 public int type = 0; 170 public int Type = 0;
94 public int inv_type = 0; 171 public int InvType = 0;
95 public uint flags = 0; 172 public uint Flags = 0;
96 public string name = String.Empty; 173 public string Name = String.Empty;
97 public string desc = String.Empty; 174 public string Description = String.Empty;
98 public uint creation_date = 0; 175 public uint CreationDate = 0;
99 176
100 public LLUUID ParentPartID = LLUUID.Zero; 177 public LLUUID ParentPartID = LLUUID.Zero;
101 } 178 }
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
index 2fd4301..10f4141 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -184,21 +184,21 @@ namespace OpenSim.Region.Environment.Scenes
184 } 184 }
185 185
186 // Create new asset 186 // Create new asset
187 // XXX Hardcoding the numbers is a temporary measure - need an enumeration for this 187 // XXX Hardcoding the numbers is a temporary measure - need an enumeration for this
188 AssetBase asset = 188 // There may well be one in libsecondlife
189 CreateAsset(item.name, item.desc, 10, 10, data); 189 AssetBase asset = CreateAsset(item.Name, item.Description, 10, 10, data);
190 AssetCache.AddAsset(asset); 190 AssetCache.AddAsset(asset);
191 191
192 // Update item with new asset 192 // Update item with new asset
193 item.asset_id = asset.FullID; 193 item.AssetID = asset.FullID;
194 group.UpdateInventoryItem(item); 194 group.UpdateInventoryItem(item);
195 group.GetProperites(remoteClient); 195 group.GetProperites(remoteClient);
196 196
197 // Trigger rerunning of script (use TriggerRezScript event, see RezScript) 197 // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
198 if (isScriptRunning) 198 if (isScriptRunning)
199 { 199 {
200 group.StopScript(part.LocalID, item.item_id); 200 group.StopScript(part.LocalID, item.ItemID);
201 group.StartScript(part.LocalID, item.item_id); 201 group.StartScript(part.LocalID, item.ItemID);
202 } 202 }
203 } 203 }
204 204
@@ -750,12 +750,14 @@ namespace OpenSim.Region.Environment.Scenes
750 private void AddRezObject(string xmlData, LLVector3 pos) 750 private void AddRezObject(string xmlData, LLVector3 pos)
751 { 751 {
752 SceneObjectGroup group = new SceneObjectGroup(this, m_regionHandle, xmlData); 752 SceneObjectGroup group = new SceneObjectGroup(this, m_regionHandle, xmlData);
753 group.GenerateNewIDs(); 753 group.ResetIDs();
754 AddEntity(group); 754 AddEntity(group);
755 group.AbsolutePosition = pos; 755 group.AbsolutePosition = pos;
756 SceneObjectPart rootPart = group.GetChildPart(group.UUID); 756 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
757 rootPart.ApplySanePermissions(); 757 rootPart.ApplySanePermissions();
758 group.ApplyPhysics(m_physicalPrim); 758 group.ApplyPhysics(m_physicalPrim);
759 group.StartScripts();
760
759 //bool UsePhysics = (((rootPart.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) > 0)&& m_physicalPrim); 761 //bool UsePhysics = (((rootPart.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) > 0)&& m_physicalPrim);
760 //if ((rootPart.ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0) 762 //if ((rootPart.ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0)
761 //{ 763 //{
@@ -772,6 +774,7 @@ namespace OpenSim.Region.Environment.Scenes
772 // rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); 774 // rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
773 775
774 // } 776 // }
777 //
775 rootPart.ScheduleFullUpdate(); 778 rootPart.ScheduleFullUpdate();
776 } 779 }
777 } 780 }
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
index a092f5b..c7f5852 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.Inventory.cs
@@ -169,14 +169,14 @@ namespace OpenSim.Region.Environment.Scenes
169 { 169 {
170 TaskInventoryItem taskItem = new TaskInventoryItem(); 170 TaskInventoryItem taskItem = new TaskInventoryItem();
171 171
172 taskItem.item_id = newItemId; 172 taskItem.ItemID = newItemId;
173 taskItem.asset_id = item.assetID; 173 taskItem.AssetID = item.assetID;
174 taskItem.name = item.inventoryName; 174 taskItem.Name = item.inventoryName;
175 taskItem.desc = item.inventoryDescription; 175 taskItem.Description = item.inventoryDescription;
176 taskItem.owner_id = item.avatarID; 176 taskItem.OwnerID = item.avatarID;
177 taskItem.creator_id = item.creatorsID; 177 taskItem.CreatorID = item.creatorsID;
178 taskItem.type = item.assetType; 178 taskItem.Type = item.assetType;
179 taskItem.inv_type = item.invType; 179 taskItem.InvType = item.invType;
180 part.AddInventoryItem(taskItem); 180 part.AddInventoryItem(taskItem);
181 181
182 // It might seem somewhat crude to update the whole group for a single prim inventory change, 182 // It might seem somewhat crude to update the whole group for a single prim inventory change,
@@ -250,7 +250,7 @@ namespace OpenSim.Region.Environment.Scenes
250 MainLog.Instance.Error( 250 MainLog.Instance.Error(
251 "PRIMINVENTORY", 251 "PRIMINVENTORY",
252 "Couldn't find prim ID {0} to update item {1}, {2}", 252 "Couldn't find prim ID {0} to update item {1}, {2}",
253 item.ParentPartID, item.name, item.item_id); 253 item.ParentPartID, item.Name, item.ItemID);
254 } 254 }
255 255
256 return false; 256 return false;
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index 2e0b916..0b7f2a4 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -609,15 +609,19 @@ namespace OpenSim.Region.Environment.Scenes
609 SetPartAsNonRoot(newPart); 609 SetPartAsNonRoot(newPart);
610 } 610 }
611 611
612 612 /// <summary>
613 public void GenerateNewIDs() 613 /// Reset the LLUUIDs for all the prims that make up this group.
614 ///
615 /// This is called by methods which want to add a new group to an existing scene, in order
616 /// to ensure that there are no clashes with groups already present.
617 /// </summary>
618 public void ResetIDs()
614 { 619 {
615 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); 620 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
616 m_parts.Clear(); 621 m_parts.Clear();
617 foreach (SceneObjectPart part in partsList) 622 foreach (SceneObjectPart part in partsList)
618 { 623 {
619 part.UUID = LLUUID.Random(); 624 part.ResetIDs(m_parts.Count);
620 part.LinkNum = m_parts.Count;
621 m_parts.Add(part.UUID, part); 625 m_parts.Add(part.UUID, part);
622 } 626 }
623 } 627 }
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
index fc74c4e..5132a6c 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
@@ -57,30 +57,46 @@ namespace OpenSim.Region.Environment.Scenes
57 get { return m_folderID; } 57 get { return m_folderID; }
58 set { m_folderID = value; } 58 set { m_folderID = value; }
59 } 59 }
60
61 /// <summary>
62 /// Serial count for inventory file , used to tell if inventory has changed
63 /// no need for this to be part of Database backup
64 /// </summary>
65 protected uint m_inventorySerial = 0;
66
67 public uint InventorySerial
68 {
69 get { return m_inventorySerial; }
70 set { m_inventorySerial = value; }
71 }
60 72
61 /// <summary> 73 /// <summary>
62 /// Holds in memory prim inventory 74 /// Holds in memory prim inventory
63 /// </summary> 75 /// </summary>
64 protected IDictionary<LLUUID, TaskInventoryItem> m_taskInventory 76 protected TaskInventoryDictionary m_taskInventory = new TaskInventoryDictionary();
65 = new Dictionary<LLUUID, TaskInventoryItem>();
66 77
67 [XmlIgnore] 78 public TaskInventoryDictionary TaskInventory
68 public IDictionary<LLUUID, TaskInventoryItem> TaskInventory
69 { 79 {
70 get { return m_taskInventory; } 80 get { return m_taskInventory; }
81 set { m_taskInventory = value; }
71 } 82 }
72 83
73 /// <summary> 84 /// <summary>
74 /// Serial count for inventory file , used to tell if inventory has changed 85 /// Reset LLUUIDs for all the items in the prim's inventory. This involves either generating
75 /// no need for this to be part of Database backup 86 /// new ones or setting existing UUIDs to the correct parent UUIDs
76 /// </summary> 87 /// </summary>
77 protected uint m_inventorySerial = 0; 88 /// <param name="linkNum'>Link number for the part</param>
78 89 public void ResetInventoryIDs()
79 public uint InventorySerial
80 { 90 {
81 get { return m_inventorySerial; } 91 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values);
82 } 92 TaskInventory.Clear();
83 93
94 foreach (TaskInventoryItem item in items)
95 {
96 item.ResetIDs(UUID);
97 TaskInventory.Add(item.ItemID, item);
98 }
99 }
84 100
85 /// <summary> 101 /// <summary>
86 /// Start all the scripts contained in this prim's inventory 102 /// Start all the scripts contained in this prim's inventory
@@ -90,7 +106,7 @@ namespace OpenSim.Region.Environment.Scenes
90 foreach (TaskInventoryItem item in m_taskInventory.Values) 106 foreach (TaskInventoryItem item in m_taskInventory.Values)
91 { 107 {
92 // XXX more hardcoding badness. Should be an enum in TaskInventoryItem 108 // XXX more hardcoding badness. Should be an enum in TaskInventoryItem
93 if (10 == item.type) 109 if (10 == item.Type)
94 { 110 {
95 StartScript(item); 111 StartScript(item);
96 } 112 }
@@ -107,21 +123,21 @@ namespace OpenSim.Region.Environment.Scenes
107// MainLog.Instance.Verbose( 123// MainLog.Instance.Verbose(
108// "PRIMINVENTORY", 124// "PRIMINVENTORY",
109// "Starting script {0}, {1} in prim {2}, {3}", 125// "Starting script {0}, {1} in prim {2}, {3}",
110// item.name, item.item_id, Name, UUID); 126// item.Name, item.ItemID, Name, UUID);
111 127
112 AssetBase rezAsset = m_parentGroup.Scene.AssetCache.GetAsset(item.asset_id, false); 128 AssetBase rezAsset = m_parentGroup.Scene.AssetCache.GetAsset(item.AssetID, false);
113 129
114 if (rezAsset != null) 130 if (rezAsset != null)
115 { 131 {
116 string script = Helpers.FieldToUTF8String(rezAsset.Data); 132 string script = Helpers.FieldToUTF8String(rezAsset.Data);
117 m_parentGroup.Scene.EventManager.TriggerRezScript(LocalID, item.item_id, script); 133 m_parentGroup.Scene.EventManager.TriggerRezScript(LocalID, item.ItemID, script);
118 } 134 }
119 else 135 else
120 { 136 {
121 MainLog.Instance.Error( 137 MainLog.Instance.Error(
122 "PRIMINVENTORY", 138 "PRIMINVENTORY",
123 "Couldn't start script {0}, {1} since asset ID {2} could not be found", 139 "Couldn't start script {0}, {1} since asset ID {2} could not be found",
124 item.name, item.item_id, item.asset_id); 140 item.Name, item.ItemID, item.AssetID);
125 } 141 }
126 } 142 }
127 143
@@ -172,10 +188,10 @@ namespace OpenSim.Region.Environment.Scenes
172 /// <param name="item"></param> 188 /// <param name="item"></param>
173 public void AddInventoryItem(TaskInventoryItem item) 189 public void AddInventoryItem(TaskInventoryItem item)
174 { 190 {
175 item.parent_id = m_folderID; 191 item.ParentID = m_folderID;
176 item.creation_date = 1000; 192 item.CreationDate = 1000;
177 item.ParentPartID = UUID; 193 item.ParentPartID = UUID;
178 m_taskInventory.Add(item.item_id, item); 194 m_taskInventory.Add(item.ItemID, item);
179 m_inventorySerial++; 195 m_inventorySerial++;
180 } 196 }
181 197
@@ -188,7 +204,7 @@ namespace OpenSim.Region.Environment.Scenes
188 { 204 {
189 foreach (TaskInventoryItem item in items) 205 foreach (TaskInventoryItem item in items)
190 { 206 {
191 m_taskInventory.Add(item.item_id, item); 207 m_taskInventory.Add(item.ItemID, item);
192 } 208 }
193 209
194 m_inventorySerial++; 210 m_inventorySerial++;
@@ -224,9 +240,9 @@ namespace OpenSim.Region.Environment.Scenes
224 /// <returns>false if the item did not exist, true if the update occurred succesfully</returns> 240 /// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
225 public bool UpdateInventoryItem(TaskInventoryItem item) 241 public bool UpdateInventoryItem(TaskInventoryItem item)
226 { 242 {
227 if (m_taskInventory.ContainsKey(item.item_id)) 243 if (m_taskInventory.ContainsKey(item.ItemID))
228 { 244 {
229 m_taskInventory[item.item_id] = item; 245 m_taskInventory[item.ItemID] = item;
230 m_inventorySerial++; 246 m_inventorySerial++;
231 247
232 return true; 248 return true;
@@ -236,7 +252,7 @@ namespace OpenSim.Region.Environment.Scenes
236 MainLog.Instance.Error( 252 MainLog.Instance.Error(
237 "PRIMINVENTORY", 253 "PRIMINVENTORY",
238 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", 254 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
239 item.item_id, Name, UUID); 255 item.ItemID, Name, UUID);
240 } 256 }
241 257
242 return false; 258 return false;
@@ -252,7 +268,7 @@ namespace OpenSim.Region.Environment.Scenes
252 { 268 {
253 if (m_taskInventory.ContainsKey(itemID)) 269 if (m_taskInventory.ContainsKey(itemID))
254 { 270 {
255 int type = m_taskInventory[itemID].inv_type; 271 int type = m_taskInventory[itemID].InvType;
256 m_taskInventory.Remove(itemID); 272 m_taskInventory.Remove(itemID);
257 m_inventorySerial++; 273 m_inventorySerial++;
258 274
@@ -296,8 +312,8 @@ namespace OpenSim.Region.Environment.Scenes
296 foreach (TaskInventoryItem item in m_taskInventory.Values) 312 foreach (TaskInventoryItem item in m_taskInventory.Values)
297 { 313 {
298 invString.AddItemStart(); 314 invString.AddItemStart();
299 invString.AddNameValueLine("item_id", item.item_id.ToString()); 315 invString.AddNameValueLine("item_id", item.ItemID.ToString());
300 invString.AddNameValueLine("parent_id", item.parent_id.ToString()); 316 invString.AddNameValueLine("parent_id", item.ParentID.ToString());
301 317
302 invString.AddPermissionsStart(); 318 invString.AddPermissionsStart();
303 invString.AddNameValueLine("base_mask", "0x7FFFFFFF"); 319 invString.AddNameValueLine("base_mask", "0x7FFFFFFF");
@@ -305,19 +321,19 @@ namespace OpenSim.Region.Environment.Scenes
305 invString.AddNameValueLine("group_mask", "0x7FFFFFFF"); 321 invString.AddNameValueLine("group_mask", "0x7FFFFFFF");
306 invString.AddNameValueLine("everyone_mask", "0x7FFFFFFF"); 322 invString.AddNameValueLine("everyone_mask", "0x7FFFFFFF");
307 invString.AddNameValueLine("next_owner_mask", "0x7FFFFFFF"); 323 invString.AddNameValueLine("next_owner_mask", "0x7FFFFFFF");
308 invString.AddNameValueLine("creator_id", item.creator_id.ToString()); 324 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
309 invString.AddNameValueLine("owner_id", item.owner_id.ToString()); 325 invString.AddNameValueLine("owner_id", item.OwnerID.ToString());
310 invString.AddNameValueLine("last_owner_id", item.last_owner_id.ToString()); 326 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
311 invString.AddNameValueLine("group_id", item.group_id.ToString()); 327 invString.AddNameValueLine("group_id", item.GroupID.ToString());
312 invString.AddSectionEnd(); 328 invString.AddSectionEnd();
313 329
314 invString.AddNameValueLine("asset_id", item.asset_id.ToString()); 330 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
315 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.type]); 331 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
316 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.inv_type]); 332 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
317 invString.AddNameValueLine("flags", "0x00"); 333 invString.AddNameValueLine("flags", "0x00");
318 invString.AddNameValueLine("name", item.name + "|"); 334 invString.AddNameValueLine("name", item.Name + "|");
319 invString.AddNameValueLine("desc", item.desc + "|"); 335 invString.AddNameValueLine("desc", item.Description + "|");
320 invString.AddNameValueLine("creation_date", item.creation_date.ToString()); 336 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
321 invString.AddSectionEnd(); 337 invString.AddSectionEnd();
322 } 338 }
323 339
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index c1522bc..93073c1 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -991,6 +991,19 @@ namespace OpenSim.Region.Environment.Scenes
991 } 991 }
992 992
993 #endregion 993 #endregion
994
995 /// <summary>
996 /// Reset LLUUIDs for this part. This involves generate this part's own LLUUID and
997 /// generating new LLUUIDs for all the items in the inventory.
998 /// </summary>
999 /// <param name="linkNum'>Link number for the part</param>
1000 public void ResetIDs(int linkNum)
1001 {
1002 UUID = LLUUID.Random();
1003 LinkNum = linkNum;
1004
1005 ResetInventoryIDs();
1006 }
994 1007
995 #region Update Scheduling 1008 #region Update Scheduling
996 1009
diff --git a/OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs b/OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs
index 8c4a951..3b4deaf 100644
--- a/OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Region.Environment.Scenes
68 m_regInfo.RegionHandle, aPrimNode.OuterXml); 68 m_regInfo.RegionHandle, aPrimNode.OuterXml);
69 if (newIDS) 69 if (newIDS)
70 { 70 {
71 obj.GenerateNewIDs(); 71 obj.ResetIDs();
72 } 72 }
73 //if we want this to be a import method then we need new uuids for the object to avoid any clashes 73 //if we want this to be a import method then we need new uuids for the object to avoid any clashes
74 //obj.RegenerateFullIDs(); 74 //obj.RegenerateFullIDs();
@@ -189,4 +189,4 @@ namespace OpenSim.Region.Environment.Scenes
189 file.Close(); 189 file.Close();
190 } 190 }
191 } 191 }
192} \ No newline at end of file 192}
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs
index d6c4675..7884277 100644
--- a/OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs
+++ b/OpenSim/Region/Storage/OpenSim.DataStore.MSSQL/MSSQLDataStore.cs
@@ -140,6 +140,8 @@ namespace OpenSim.DataStore.MSSQL
140 140
141 public void RemoveObject(LLUUID obj, LLUUID regionUUID) 141 public void RemoveObject(LLUUID obj, LLUUID regionUUID)
142 { 142 {
143 MainLog.Instance.Verbose("DATASTORE", "Removing obj: {0} from region: {1}", obj.UUID, regionUUID);
144
143 DataTable prims = ds.Tables["prims"]; 145 DataTable prims = ds.Tables["prims"];
144 DataTable shapes = ds.Tables["primshapes"]; 146 DataTable shapes = ds.Tables["primshapes"];
145 147
@@ -1087,4 +1089,4 @@ namespace OpenSim.DataStore.MSSQL
1087 } 1089 }
1088 } 1090 }
1089 } 1091 }
1090} \ No newline at end of file 1092}