From 3f9f10529548599d1810ca8a630734586ed3fa9d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 17 Sep 2016 15:45:11 +0100 Subject: [PATCH] add to databases a table to store baked terrain. --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 47 ++++++++++++++++ .../MySQL/Resources/RegionStore.migrations | 11 ++++ OpenSim/Data/Null/NullSimulationData.cs | 8 +++ OpenSim/Data/PGSQL/PGSQLSimulationData.cs | 43 +++++++++++++++ .../PGSQL/Resources/RegionStore.migrations | 13 +++++ .../SQLite/Resources/RegionStore.migrations | 11 ++++ OpenSim/Data/SQLite/SQLiteSimulationData.cs | 53 +++++++++++++++---- .../Interfaces/ISimulationDataService.cs | 9 +++- .../Interfaces/ISimulationDataStore.cs | 10 +++- .../SimulationDataService.cs | 5 ++ .../Tests/Common/Mock/MockRegionDataPlugin.cs | 11 ++++ 11 files changed, 208 insertions(+), 13 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 46364a5a7c..1a571995ba 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -639,6 +639,53 @@ namespace OpenSim.Data.MySQL }); } + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + Util.FireAndForget(delegate(object x) + { + m_log.Info("[REGION DB]: Storing Baked terrain"); + + lock (m_dbLock) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from bakedterrain where RegionUUID = ?RegionUUID"; + cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + + using (MySqlCommand cmd2 = dbcon.CreateCommand()) + { + try + { + cmd2.CommandText = "insert into bakedterrain (RegionUUID, " + + "Revision, Heightfield) values (?RegionUUID, " + + "?Revision, ?Heightfield)"; + + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); + cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); + cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); + + ExecuteNonQuery(cmd); + ExecuteNonQuery(cmd2); + } + catch (Exception e) + { + m_log.ErrorFormat(e.ToString()); + } + } + } + } + } + }); + } + // Legacy region loading public virtual double[,] LoadTerrain(UUID regionID) { diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index c32f645539..1de5a01cfc 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -379,3 +379,14 @@ ALTER TABLE `prims` ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default ' COMMIT; +:VERSION 54 #----- add baked terrain store + +BEGIN; + +CREATE TABLE IF NOT EXISTS `bakedterrain` ( + `RegionUUID` varchar(255) DEFAULT NULL, + `Revision` int(11) DEFAULT NULL, + `Heightfield` longblob +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +COMMIT; diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index 339e7f45b0..5ea8bfaa9a 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs @@ -133,6 +133,7 @@ namespace OpenSim.Data.Null } Dictionary m_terrains = new Dictionary(); + Dictionary m_bakedterrains = new Dictionary(); public void StoreTerrain(TerrainData ter, UUID regionID) { if (m_terrains.ContainsKey(regionID)) @@ -140,6 +141,13 @@ namespace OpenSim.Data.Null m_terrains.Add(regionID, ter); } + public void StoreBakedTerrain(TerrainData ter, UUID regionID) + { + if (m_bakedterrains.ContainsKey(regionID)) + m_bakedterrains.Remove(regionID); + m_bakedterrains.Add(regionID, ter); + } + // Legacy. Just don't do this. public void StoreTerrain(double[,] ter, UUID regionID) { diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index 25e1a7f84b..e6161a2dc5 100755 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -623,6 +623,49 @@ namespace OpenSim.Data.PGSQL } + /// + /// Stores the baked terrain map to DB. + /// + /// terrain map data. + /// regionID. + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + //Delete old terrain map + string sql = @"delete from bakedterrain where ""RegionUUID""=:RegionUUID"; + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) + { + using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); + conn.Open(); + cmd.ExecuteNonQuery(); + + _Log.InfoFormat("{0} Deleted bakedterrain id = {1}", LogHeader, regionID); + } + } + + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + sql = @"insert into bakedterrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)"; + + using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) + { + using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); + cmd.Parameters.Add(_Database.CreateParameter("Revision", terrainDBRevision)); + cmd.Parameters.Add(_Database.CreateParameter("Heightfield", terrainDBblob)); + conn.Open(); + cmd.ExecuteNonQuery(); + + _Log.InfoFormat("{0} Stored bakedterrain id = {1}, terrainSize = <{2},{3}>", + LogHeader, regionID, terrData.SizeX, terrData.SizeY); + } + } + } + /// /// Loads all the land objects of a region. /// diff --git a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations index 9a2c19b83d..c08593917d 100644 --- a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations @@ -1182,3 +1182,16 @@ BEGIN TRANSACTION; ALTER TABLE prims ADD "RotationAxisLocks" smallint NOT NULL DEFAULT (0); COMMIT; + +:VERSION 44 #---- add baked terrain store + +BEGIN TRANSACTION; + +CREATE TABLE bakedterrain + ( + "RegionUUID" uuid NULL, + "Revision" int NULL, + "Heightfield" bytea NULL + ); + +COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index 25f3ad96fb..64624db9b0 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -352,3 +352,14 @@ BEGIN; ALTER TABLE prims ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default '0'; COMMIT; + +:VERSION 34 #---- add baked terrain store + +BEGIN; + +CREATE TABLE IF NOT EXISTS bakedterrain( + RegionUUID varchar(255), + Revision integer, + Heightfield blob); + +COMMIT; diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index cd20c4e777..76b367a46e 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -827,7 +827,7 @@ namespace OpenSim.Data.SQLite } /// - /// Store a terrain revision in region storage + /// Store a terrain in region storage /// /// terrain heightfield /// region UUID @@ -851,7 +851,44 @@ namespace OpenSim.Data.SQLite Array terrainDBblob; terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); - m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision); + m_log.DebugFormat("{0} Storing terrain format {1}", LogHeader, terrainDBRevision); + + using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision)); + cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob)); + cmd.ExecuteNonQuery(); + } + } + } + + /// + /// Store baked terrain in region storage + /// + /// terrain heightfield + /// region UUID + public void StoreBakedTerrain(TerrainData terrData, UUID regionID) + { + lock (ds) + { + using ( + SqliteCommand cmd = new SqliteCommand("delete from bakedterrain where RegionUUID=:RegionUUID", m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); + cmd.ExecuteNonQuery(); + } + + // the following is an work around for .NET. The perf + // issues associated with it aren't as bad as you think. + String sql = "insert into bakedterrain(RegionUUID, Revision, Heightfield)" + + " values(:RegionUUID, :Revision, :Heightfield)"; + + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + + m_log.DebugFormat("{0} Storing bakedterrain format {1}", LogHeader, terrainDBRevision); using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) { @@ -1354,7 +1391,7 @@ namespace OpenSim.Data.SQLite createCol(land, "Name", typeof(String)); createCol(land, "Desc", typeof(String)); createCol(land, "OwnerUUID", typeof(String)); - createCol(land, "IsGroupOwned", typeof(String)); + createCol(land, "IsGroupOwned", typeof(Boolean)); createCol(land, "Area", typeof(Int32)); createCol(land, "AuctionID", typeof(Int32)); //Unemplemented createCol(land, "Category", typeof(Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory @@ -1387,9 +1424,6 @@ namespace OpenSim.Data.SQLite createCol(land, "MediaLoop", typeof(Boolean)); createCol(land, "ObscureMedia", typeof(Boolean)); createCol(land, "ObscureMusic", typeof(Boolean)); - createCol(land, "SeeAVs", typeof(Boolean)); - createCol(land, "AnyAVSounds", typeof(Boolean)); - createCol(land, "GroupAVSounds", typeof(Boolean)); land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] }; @@ -1832,7 +1866,7 @@ namespace OpenSim.Data.SQLite newData.Name = (String)row["Name"]; newData.Description = (String)row["Desc"]; newData.OwnerID = (UUID)(String)row["OwnerUUID"]; - newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); + newData.IsGroupOwned = (Boolean)row["IsGroupOwned"]; newData.Area = Convert.ToInt32(row["Area"]); newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); @@ -2248,7 +2282,7 @@ namespace OpenSim.Data.SQLite row["Name"] = land.Name; row["Desc"] = land.Description; row["OwnerUUID"] = land.OwnerID.ToString(); - row["IsGroupOwned"] = land.IsGroupOwned.ToString(); + row["IsGroupOwned"] = land.IsGroupOwned; row["Area"] = land.Area; row["AuctionID"] = land.AuctionID; //Unemplemented row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory @@ -2942,9 +2976,6 @@ namespace OpenSim.Data.SQLite { return DbType.Binary; } - else if (type == typeof(Boolean)) { - return DbType.Boolean; - } else { return DbType.String; diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs index 13358cb360..d5e3f7a950 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs @@ -64,12 +64,19 @@ namespace OpenSim.Region.Framework.Interfaces List LoadObjects(UUID regionUUID); /// - /// Store a terrain revision in region storage + /// Store terrain in region storage /// /// HeightField data /// region UUID void StoreTerrain(TerrainData terrain, UUID regionID); + /// + /// Store baked terrain in region storage + /// + /// HeightField data + /// region UUID + void StoreBakedTerrain(TerrainData terrain, UUID regionID); + // Legacy version kept for downward compabibility void StoreTerrain(double[,] terrain, UUID regionID); diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs index e09f775642..4940a28a2f 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs @@ -75,12 +75,20 @@ namespace OpenSim.Region.Framework.Interfaces List LoadObjects(UUID regionUUID); /// - /// Store a terrain revision in region storage + /// Store a terrain in region storage /// /// HeightField data /// region UUID void StoreTerrain(TerrainData terrain, UUID regionID); + /// + /// Store baked terrain in region storage + /// + /// HeightField data + /// region UUID + void StoreBakedTerrain(TerrainData terrain, UUID regionID); + + // Legacy version kept for downward compabibility void StoreTerrain(double[,] terrain, UUID regionID); diff --git a/OpenSim/Services/SimulationService/SimulationDataService.cs b/OpenSim/Services/SimulationService/SimulationDataService.cs index 7a544fa9ed..4ec8293d5c 100644 --- a/OpenSim/Services/SimulationService/SimulationDataService.cs +++ b/OpenSim/Services/SimulationService/SimulationDataService.cs @@ -104,6 +104,11 @@ namespace OpenSim.Services.SimulationService m_database.StoreTerrain(terrain, regionID); } + public void StoreBakedTerrain(TerrainData terrain, UUID regionID) + { + m_database.StoreBakedTerrain(terrain, regionID); + } + public void StoreTerrain(double[,] terrain, UUID regionID) { m_database.StoreTerrain(terrain, regionID); diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs index 3ab90207a5..61fee4b2e7 100644 --- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs @@ -74,6 +74,11 @@ namespace OpenSim.Data.Null m_store.StoreTerrain(terrain, regionID); } + public void StoreBakedTerrain(TerrainData terrain, UUID regionID) + { + m_store.StoreBakedTerrain(terrain, regionID); + } + public double[,] LoadTerrain(UUID regionID) { return m_store.LoadTerrain(regionID); @@ -170,6 +175,7 @@ namespace OpenSim.Data.Null protected Dictionary> m_primItems = new Dictionary>(); protected Dictionary m_terrains = new Dictionary(); + protected Dictionary m_bakedterrains = new Dictionary(); protected Dictionary m_landData = new Dictionary(); public void Initialise(string dbfile) @@ -319,6 +325,11 @@ namespace OpenSim.Data.Null m_terrains[regionID] = ter; } + public void StoreBakedTerrain(TerrainData ter, UUID regionID) + { + m_bakedterrains[regionID] = ter; + } + public void StoreTerrain(double[,] ter, UUID regionID) { m_terrains[regionID] = new HeightmapTerrainData(ter);