diff --git a/OpenSim/Data/DBGuids.cs b/OpenSim/Data/DBGuids.cs new file mode 100644 index 0000000000..1a13e06f06 --- /dev/null +++ b/OpenSim/Data/DBGuids.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Data +{ + + public static class DBGuid + { + /// This function converts a value returned from the database in one of the + /// supported formats into a UUID. This function is not actually DBMS-specific right + /// now + /// + /// + /// + /// + public static UUID FromDB(object id) + { + if( (id == null) || (id == DBNull.Value)) + return UUID.Zero; + + if (id.GetType() == typeof(Guid)) + return new UUID((Guid)id); + + if (id.GetType() == typeof(byte[])) + { + if (((byte[])id).Length == 0) + return UUID.Zero; + else if (((byte[])id).Length == 36) + return new UUID((byte[])id, 0); + } + else if (id.GetType() == typeof(string)) + { + if (((string)id).Length == 0) + return UUID.Zero; + else if (((string)id).Length == 36) + return new UUID((string)id); + } + + throw new Exception("Failed to convert db value to UUID: " + id.ToString()); + } + } +} diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index 13f5fa2ac6..ec18c28391 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -33,6 +33,7 @@ using log4net; using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Data; namespace OpenSim.Data.MySQL { @@ -320,7 +321,7 @@ namespace OpenSim.Data.MySQL metadata.Type = (sbyte)dbReader["assetType"]; metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); - metadata.FullID = new UUID((string)dbReader["id"]); + metadata.FullID = DBGuid.FromDB(dbReader["id"]); // Current SHA1s are not stored/computed. metadata.SHA1 = new byte[] { }; diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs index 08e21446f2..9158f7a427 100644 --- a/OpenSim/Data/MySQL/MySQLEstateData.cs +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs @@ -34,6 +34,7 @@ using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Data; namespace OpenSim.Data.MySQL { @@ -156,20 +157,13 @@ namespace OpenSim.Data.MySQL foreach (string name in FieldList) { - if (m_FieldMap[name].GetValue(es) is bool) + if (m_FieldMap[name].FieldType == typeof(bool)) { - int v = Convert.ToInt32(r[name]); - if (v != 0) - m_FieldMap[name].SetValue(es, true); - else - m_FieldMap[name].SetValue(es, false); + m_FieldMap[name].SetValue(es, Convert.ToInt32(r[name]) != 0); } - else if (m_FieldMap[name].GetValue(es) is UUID) + else if (m_FieldMap[name].FieldType == typeof(UUID)) { - UUID uuid = UUID.Zero; - - UUID.TryParse(r[name].ToString(), out uuid); - m_FieldMap[name].SetValue(es, uuid); + m_FieldMap[name].SetValue(es, DBGuid.FromDB(r[name])); } else { @@ -385,11 +379,7 @@ namespace OpenSim.Data.MySQL while (r.Read()) { // EstateBan eb = new EstateBan(); - - UUID uuid = new UUID(); - UUID.TryParse(r["uuid"].ToString(), out uuid); - - uuids.Add(uuid); + uuids.Add(DBGuid.FromDB(r["uuid"])); } } } @@ -490,7 +480,7 @@ namespace OpenSim.Data.MySQL using (IDataReader reader = cmd.ExecuteReader()) { while(reader.Read()) - result.Add(new UUID(reader["RegionID"].ToString())); + result.Add(DBGuid.FromDB(reader["RegionID"])); reader.Close(); } } diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 1253e0b455..6cbb2ee9a2 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -148,19 +148,16 @@ namespace OpenSim.Data.MySQL foreach (string name in m_Fields.Keys) { - if (m_Fields[name].GetValue(row) is bool) + if (m_Fields[name].FieldType == typeof(bool)) { int v = Convert.ToInt32(reader[name]); m_Fields[name].SetValue(row, v != 0 ? true : false); } - else if (m_Fields[name].GetValue(row) is UUID) + else if (m_Fields[name].FieldType == typeof(UUID)) { - UUID uuid = UUID.Zero; - - UUID.TryParse(reader[name].ToString(), out uuid); - m_Fields[name].SetValue(row, uuid); + m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); } - else if (m_Fields[name].GetValue(row) is int) + else if (m_Fields[name].FieldType == typeof(int)) { int v = Convert.ToInt32(reader[name]); m_Fields[name].SetValue(row, v); diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index e0e9b9cc99..0aea30ffb9 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -32,6 +32,7 @@ using log4net; using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Data; namespace OpenSim.Data.MySQL { @@ -285,31 +286,23 @@ namespace OpenSim.Data.MySQL InventoryItemBase item = new InventoryItemBase(); // TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these. - if (reader["creatorID"] == null) - { - item.CreatorId = UUID.Zero.ToString(); - } - else - { - item.CreatorId = (string)reader["creatorID"]; - } + // ( DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero ) + item.CreatorId = reader["creatorID"].ToString(); // Be a bit safer in parsing these because the // database doesn't enforce them to be not null, and // the inventory still works if these are weird in the // db - UUID Owner = UUID.Zero; - UUID GroupID = UUID.Zero; - UUID.TryParse((string)reader["avatarID"], out Owner); - UUID.TryParse((string)reader["groupID"], out GroupID); - item.Owner = Owner; - item.GroupID = GroupID; + + // (Empty is Ok, but "weird" will throw!) + item.Owner = DBGuid.FromDB(reader["avatarID"]); + item.GroupID = DBGuid.FromDB(reader["groupID"]); // Rest of the parsing. If these UUID's fail, we're dead anyway - item.ID = new UUID((string) reader["inventoryID"]); - item.AssetID = new UUID((string) reader["assetID"]); + item.ID = DBGuid.FromDB(reader["inventoryID"]); + item.AssetID = DBGuid.FromDB(reader["assetID"]); item.AssetType = (int) reader["assetType"]; - item.Folder = new UUID((string) reader["parentFolderID"]); + item.Folder = DBGuid.FromDB(reader["parentFolderID"]); item.Name = (string)(reader["inventoryName"] ?? String.Empty); item.Description = (string)(reader["inventoryDescription"] ?? String.Empty); item.NextPermissions = (uint) reader["inventoryNextPermissions"]; @@ -382,9 +375,9 @@ namespace OpenSim.Data.MySQL try { InventoryFolderBase folder = new InventoryFolderBase(); - folder.Owner = new UUID((string) reader["agentID"]); - folder.ParentID = new UUID((string) reader["parentFolderID"]); - folder.ID = new UUID((string) reader["folderID"]); + folder.Owner = DBGuid.FromDB(reader["agentID"]); + folder.ParentID = DBGuid.FromDB(reader["parentFolderID"]); + folder.ID = DBGuid.FromDB(reader["folderID"]); folder.Name = (string) reader["folderName"]; folder.Type = (short) reader["type"]; folder.Version = (ushort) ((int) reader["version"]); diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index 07371e7473..bfeae12385 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -38,6 +38,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Data; namespace OpenSim.Data.MySQL { @@ -269,7 +270,7 @@ namespace OpenSim.Data.MySQL using (IDataReader reader = ExecuteReader(cmd)) { while (reader.Read()) - uuids.Add(new UUID(reader["UUID"].ToString())); + uuids.Add(DBGuid.FromDB(reader["UUID"].ToString())); } // delete the main prims @@ -422,7 +423,7 @@ namespace OpenSim.Data.MySQL else prim.Shape = BuildShape(reader); - UUID parentID = new UUID(reader["SceneGroupID"].ToString()); + UUID parentID = DBGuid.FromDB(reader["SceneGroupID"].ToString()); if (parentID != prim.UUID) prim.ParentUUID = parentID; @@ -500,7 +501,7 @@ namespace OpenSim.Data.MySQL { if (!(itemReader["primID"] is DBNull)) { - UUID primID = new UUID(itemReader["primID"].ToString()); + UUID primID = DBGuid.FromDB(itemReader["primID"].ToString()); if (prims.ContainsKey(primID)) primsWithInventory.Add(prims[primID]); } @@ -738,7 +739,7 @@ namespace OpenSim.Data.MySQL } else { - UUID.TryParse(result["region_id"].ToString(), out nWP.regionID); + nWP.regionID = DBGuid.FromDB(result["region_id"]); nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); @@ -1055,7 +1056,14 @@ namespace OpenSim.Data.MySQL private SceneObjectPart BuildPrim(IDataReader row) { SceneObjectPart prim = new SceneObjectPart(); - prim.UUID = new UUID((string)row["UUID"]); + + // depending on the MySQL connector version, CHAR(36) may be already converted to Guid! + prim.UUID = DBGuid.FromDB(row["UUID"]); + prim.CreatorID = DBGuid.FromDB(row["CreatorID"]); + prim.OwnerID = DBGuid.FromDB(row["OwnerID"]); + prim.GroupID = DBGuid.FromDB(row["GroupID"]); + prim.LastOwnerID = DBGuid.FromDB(row["LastOwnerID"]); + // explicit conversion of integers is required, which sort // of sucks. No idea if there is a shortcut here or not. prim.CreationDate = (int)row["CreationDate"]; @@ -1074,15 +1082,12 @@ namespace OpenSim.Data.MySQL prim.TouchName = (string)row["TouchName"]; // Permissions prim.ObjectFlags = (uint)(int)row["ObjectFlags"]; - prim.CreatorID = new UUID((string)row["CreatorID"]); - prim.OwnerID = new UUID((string)row["OwnerID"]); - prim.GroupID = new UUID((string)row["GroupID"]); - prim.LastOwnerID = new UUID((string)row["LastOwnerID"]); prim.OwnerMask = (uint)(int)row["OwnerMask"]; prim.NextOwnerMask = (uint)(int)row["NextOwnerMask"]; prim.GroupMask = (uint)(int)row["GroupMask"]; prim.EveryoneMask = (uint)(int)row["EveryoneMask"]; prim.BaseMask = (uint)(int)row["BaseMask"]; + // Vectors prim.OffsetPosition = new Vector3( (float)(double)row["PositionX"], @@ -1134,7 +1139,7 @@ namespace OpenSim.Data.MySQL prim.PayPrice[3] = (int)row["PayButton3"]; prim.PayPrice[4] = (int)row["PayButton4"]; - prim.Sound = new UUID(row["LoopedSound"].ToString()); + prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString()); prim.SoundGain = (float)(double)row["LoopedSoundGain"]; prim.SoundFlags = 1; // If it's persisted at all, it's looped @@ -1161,16 +1166,10 @@ namespace OpenSim.Data.MySQL (float)(double)row["CameraAtOffsetZ"] )); - if ((sbyte)row["ForceMouselook"] != 0) - prim.SetForceMouselook(true); - + prim.SetForceMouselook((sbyte)row["ForceMouselook"] != 0); prim.ScriptAccessPin = (int)row["ScriptAccessPin"]; - - if ((sbyte)row["AllowedDrop"] != 0) - prim.AllowedDrop = true; - - if ((sbyte)row["DieAtEdge"] != 0) - prim.DIE_AT_EDGE = true; + prim.AllowedDrop = ((sbyte)row["AllowedDrop"] != 0); + prim.DIE_AT_EDGE = ((sbyte)row["DieAtEdge"] != 0); prim.SalePrice = (int)row["SalePrice"]; prim.ObjectSaleType = unchecked((byte)(sbyte)row["SaleType"]); @@ -1180,11 +1179,10 @@ namespace OpenSim.Data.MySQL if (!(row["ClickAction"] is DBNull)) prim.ClickAction = unchecked((byte)(sbyte)row["ClickAction"]); - prim.CollisionSound = new UUID(row["CollisionSound"].ToString()); + prim.CollisionSound = DBGuid.FromDB(row["CollisionSound"]); prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"]; - if ((sbyte)row["PassTouches"] != 0) - prim.PassTouches = true; + prim.PassTouches = ((sbyte)row["PassTouches"] != 0); prim.LinkNum = (int)row["LinkNumber"]; return prim; @@ -1200,10 +1198,10 @@ namespace OpenSim.Data.MySQL { TaskInventoryItem taskItem = new TaskInventoryItem(); - taskItem.ItemID = new UUID((String)row["itemID"]); - taskItem.ParentPartID = new UUID((String)row["primID"]); - taskItem.AssetID = new UUID((String)row["assetID"]); - taskItem.ParentID = new UUID((String)row["parentFolderID"]); + taskItem.ItemID = DBGuid.FromDB(row["itemID"]); + taskItem.ParentPartID = DBGuid.FromDB(row["primID"]); + taskItem.AssetID = DBGuid.FromDB(row["assetID"]); + taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]); taskItem.InvType = Convert.ToInt32(row["invType"]); taskItem.Type = Convert.ToInt32(row["assetType"]); @@ -1211,10 +1209,10 @@ namespace OpenSim.Data.MySQL taskItem.Name = (String)row["name"]; taskItem.Description = (String)row["description"]; taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); - taskItem.CreatorID = new UUID((String)row["creatorID"]); - taskItem.OwnerID = new UUID((String)row["ownerID"]); - taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]); - taskItem.GroupID = new UUID((String)row["groupID"]); + taskItem.CreatorID = DBGuid.FromDB(row["creatorID"]); + taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]); + taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]); + taskItem.GroupID = DBGuid.FromDB(row["groupID"]); taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); @@ -1230,7 +1228,7 @@ namespace OpenSim.Data.MySQL { RegionSettings newSettings = new RegionSettings(); - newSettings.RegionUUID = new UUID((string) row["regionUUID"]); + newSettings.RegionUUID = DBGuid.FromDB(row["regionUUID"]); newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); @@ -1244,10 +1242,10 @@ namespace OpenSim.Data.MySQL newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); - newSettings.TerrainTexture1 = new UUID((String) row["terrain_texture_1"]); - newSettings.TerrainTexture2 = new UUID((String) row["terrain_texture_2"]); - newSettings.TerrainTexture3 = new UUID((String) row["terrain_texture_3"]); - newSettings.TerrainTexture4 = new UUID((String) row["terrain_texture_4"]); + newSettings.TerrainTexture1 = DBGuid.FromDB(row["terrain_texture_1"]); + newSettings.TerrainTexture2 = DBGuid.FromDB(row["terrain_texture_2"]); + newSettings.TerrainTexture3 = DBGuid.FromDB(row["terrain_texture_3"]); + newSettings.TerrainTexture4 = DBGuid.FromDB(row["terrain_texture_4"]); newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); @@ -1268,7 +1266,7 @@ namespace OpenSim.Data.MySQL ); newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); - newSettings.Covenant = new UUID((String) row["covenant"]); + newSettings.Covenant = DBGuid.FromDB(row["covenant"]); newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); @@ -1277,7 +1275,7 @@ namespace OpenSim.Data.MySQL else newSettings.LoadedCreationID = (String) row["loaded_creation_id"]; - newSettings.TerrainImageID = new UUID((String)row["map_tile_ID"]); + newSettings.TerrainImageID = DBGuid.FromDB(row["map_tile_ID"]); return newSettings; } @@ -1291,7 +1289,7 @@ namespace OpenSim.Data.MySQL { LandData newData = new LandData(); - newData.GlobalID = new UUID((String) row["UUID"]); + newData.GlobalID = DBGuid.FromDB(row["UUID"]); newData.LocalID = Convert.ToInt32(row["LocalLandID"]); // Bitmap is a byte[512] @@ -1299,7 +1297,7 @@ namespace OpenSim.Data.MySQL newData.Name = (String) row["Name"]; newData.Description = (String) row["Description"]; - newData.OwnerID = new UUID((String)row["OwnerUUID"]); + newData.OwnerID = DBGuid.FromDB(row["OwnerUUID"]); newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); newData.Area = Convert.ToInt32(row["Area"]); newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unimplemented @@ -1307,14 +1305,14 @@ namespace OpenSim.Data.MySQL //Enum libsecondlife.Parcel.ParcelCategory newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); - newData.GroupID = new UUID((String) row["GroupUUID"]); + newData.GroupID = DBGuid.FromDB(row["GroupUUID"]); newData.SalePrice = Convert.ToInt32(row["SalePrice"]); newData.Status = (ParcelStatus) Convert.ToInt32(row["LandStatus"]); //Enum. libsecondlife.Parcel.ParcelStatus newData.Flags = Convert.ToUInt32(row["LandFlags"]); newData.LandingType = Convert.ToByte(row["LandingType"]); newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); - newData.MediaID = new UUID((String) row["MediaTextureUUID"]); + newData.MediaID = DBGuid.FromDB(row["MediaTextureUUID"]); newData.MediaURL = (String) row["MediaURL"]; newData.MusicURL = (String) row["MusicURL"]; newData.PassHours = Convert.ToSingle(row["PassHours"]); @@ -1358,7 +1356,7 @@ namespace OpenSim.Data.MySQL private static ParcelManager.ParcelAccessEntry BuildLandAccessData(IDataReader row) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = new UUID((string) row["AccessUUID"]); + entry.AgentID = DBGuid.FromDB(row["AccessUUID"]); entry.Flags = (AccessList) Convert.ToInt32(row["Flags"]); entry.Time = new DateTime(); return entry; diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index aa9a104d78..c7bddacd16 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Data; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Data; using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL @@ -143,12 +144,9 @@ namespace OpenSim.Data.MySQL RegionData ret = new RegionData(); ret.Data = new Dictionary(); - UUID regionID; - UUID.TryParse(result["uuid"].ToString(), out regionID); - ret.RegionID = regionID; - UUID scope; - UUID.TryParse(result["ScopeID"].ToString(), out scope); - ret.ScopeID = scope; + ret.RegionID = DBGuid.FromDB(result["uuid"]); + ret.ScopeID = DBGuid.FromDB(result["ScopeID"]); + ret.RegionName = result["regionName"].ToString(); ret.posX = Convert.ToInt32(result["locX"]); ret.posY = Convert.ToInt32(result["locY"]);