diff options
Diffstat (limited to 'OpenSim/Data/SQLite/SQLiteSimulationData.cs')
-rw-r--r-- | OpenSim/Data/SQLite/SQLiteSimulationData.cs | 101 |
1 files changed, 32 insertions, 69 deletions
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index d938b6b..9466e99 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs | |||
@@ -51,6 +51,7 @@ namespace OpenSim.Data.SQLite | |||
51 | public class SQLiteSimulationData : ISimulationDataStore | 51 | public class SQLiteSimulationData : ISimulationDataStore |
52 | { | 52 | { |
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
54 | private static readonly string LogHeader = "[REGION DB SQLLITE]"; | ||
54 | 55 | ||
55 | private const string primSelect = "select * from prims"; | 56 | private const string primSelect = "select * from prims"; |
56 | private const string shapeSelect = "select * from primshapes"; | 57 | private const string shapeSelect = "select * from primshapes"; |
@@ -819,45 +820,44 @@ namespace OpenSim.Data.SQLite | |||
819 | prim.Inventory.RestoreInventoryItems(inventory); | 820 | prim.Inventory.RestoreInventoryItems(inventory); |
820 | } | 821 | } |
821 | 822 | ||
823 | // Legacy entry point for when terrain was always a 256x256 hieghtmap | ||
824 | public void StoreTerrain(double[,] ter, UUID regionID) | ||
825 | { | ||
826 | StoreTerrain(new HeightmapTerrainData(ter), regionID); | ||
827 | } | ||
828 | |||
822 | /// <summary> | 829 | /// <summary> |
823 | /// Store a terrain revision in region storage | 830 | /// Store a terrain revision in region storage |
824 | /// </summary> | 831 | /// </summary> |
825 | /// <param name="ter">terrain heightfield</param> | 832 | /// <param name="ter">terrain heightfield</param> |
826 | /// <param name="regionID">region UUID</param> | 833 | /// <param name="regionID">region UUID</param> |
827 | public void StoreTerrain(double[,] ter, UUID regionID) | 834 | public void StoreTerrain(TerrainData terrData, UUID regionID) |
828 | { | 835 | { |
829 | lock (ds) | 836 | lock (ds) |
830 | { | 837 | { |
831 | int revision = Util.UnixTimeSinceEpoch(); | ||
832 | |||
833 | // This is added to get rid of the infinitely growing | ||
834 | // terrain databases which negatively impact on SQLite | ||
835 | // over time. Before reenabling this feature there | ||
836 | // needs to be a limitter put on the number of | ||
837 | // revisions in the database, as this old | ||
838 | // implementation is a DOS attack waiting to happen. | ||
839 | |||
840 | using ( | 838 | using ( |
841 | SqliteCommand cmd = | 839 | SqliteCommand cmd = new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID", m_conn)) |
842 | new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision <= :Revision", | ||
843 | m_conn)) | ||
844 | { | 840 | { |
845 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); | 841 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); |
846 | cmd.Parameters.Add(new SqliteParameter(":Revision", revision)); | ||
847 | cmd.ExecuteNonQuery(); | 842 | cmd.ExecuteNonQuery(); |
848 | } | 843 | } |
849 | 844 | ||
850 | // the following is an work around for .NET. The perf | 845 | // the following is an work around for .NET. The perf |
851 | // issues associated with it aren't as bad as you think. | 846 | // issues associated with it aren't as bad as you think. |
852 | m_log.Debug("[SQLITE REGION DB]: Storing terrain revision r" + revision.ToString()); | ||
853 | String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + | 847 | String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + |
854 | " values(:RegionUUID, :Revision, :Heightfield)"; | 848 | " values(:RegionUUID, :Revision, :Heightfield)"; |
855 | 849 | ||
850 | int terrainDBRevision; | ||
851 | Array terrainDBblob; | ||
852 | terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); | ||
853 | |||
854 | m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision); | ||
855 | |||
856 | using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) | 856 | using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) |
857 | { | 857 | { |
858 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); | 858 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); |
859 | cmd.Parameters.Add(new SqliteParameter(":Revision", revision)); | 859 | cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision)); |
860 | cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter))); | 860 | cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob)); |
861 | cmd.ExecuteNonQuery(); | 861 | cmd.ExecuteNonQuery(); |
862 | } | 862 | } |
863 | } | 863 | } |
@@ -870,11 +870,20 @@ namespace OpenSim.Data.SQLite | |||
870 | /// <returns>Heightfield data</returns> | 870 | /// <returns>Heightfield data</returns> |
871 | public double[,] LoadTerrain(UUID regionID) | 871 | public double[,] LoadTerrain(UUID regionID) |
872 | { | 872 | { |
873 | double[,] ret = null; | ||
874 | TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); | ||
875 | if (terrData != null) | ||
876 | ret = terrData.GetDoubles(); | ||
877 | return ret; | ||
878 | } | ||
879 | |||
880 | // Returns 'null' if region not found | ||
881 | public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) | ||
882 | { | ||
883 | TerrainData terrData = null; | ||
884 | |||
873 | lock (ds) | 885 | lock (ds) |
874 | { | 886 | { |
875 | double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; | ||
876 | terret.Initialize(); | ||
877 | |||
878 | String sql = "select RegionUUID, Revision, Heightfield from terrain" + | 887 | String sql = "select RegionUUID, Revision, Heightfield from terrain" + |
879 | " where RegionUUID=:RegionUUID order by Revision desc"; | 888 | " where RegionUUID=:RegionUUID order by Revision desc"; |
880 | 889 | ||
@@ -887,21 +896,9 @@ namespace OpenSim.Data.SQLite | |||
887 | int rev = 0; | 896 | int rev = 0; |
888 | if (row.Read()) | 897 | if (row.Read()) |
889 | { | 898 | { |
890 | // TODO: put this into a function | ||
891 | using (MemoryStream str = new MemoryStream((byte[])row["Heightfield"])) | ||
892 | { | ||
893 | using (BinaryReader br = new BinaryReader(str)) | ||
894 | { | ||
895 | for (int x = 0; x < (int)Constants.RegionSize; x++) | ||
896 | { | ||
897 | for (int y = 0; y < (int)Constants.RegionSize; y++) | ||
898 | { | ||
899 | terret[x, y] = br.ReadDouble(); | ||
900 | } | ||
901 | } | ||
902 | } | ||
903 | } | ||
904 | rev = Convert.ToInt32(row["Revision"]); | 899 | rev = Convert.ToInt32(row["Revision"]); |
900 | byte[] blob = (byte[])row["Heightfield"]; | ||
901 | terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); | ||
905 | } | 902 | } |
906 | else | 903 | else |
907 | { | 904 | { |
@@ -912,8 +909,8 @@ namespace OpenSim.Data.SQLite | |||
912 | m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString()); | 909 | m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString()); |
913 | } | 910 | } |
914 | } | 911 | } |
915 | return terret; | ||
916 | } | 912 | } |
913 | return terrData; | ||
917 | } | 914 | } |
918 | 915 | ||
919 | public void RemoveLandObject(UUID globalID) | 916 | public void RemoveLandObject(UUID globalID) |
@@ -2019,40 +2016,6 @@ namespace OpenSim.Data.SQLite | |||
2019 | /// <summary> | 2016 | /// <summary> |
2020 | /// | 2017 | /// |
2021 | /// </summary> | 2018 | /// </summary> |
2022 | /// <param name="val"></param> | ||
2023 | /// <returns></returns> | ||
2024 | private static Array serializeTerrain(double[,] val) | ||
2025 | { | ||
2026 | MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double)); | ||
2027 | BinaryWriter bw = new BinaryWriter(str); | ||
2028 | |||
2029 | // TODO: COMPATIBILITY - Add byte-order conversions | ||
2030 | for (int x = 0; x < (int)Constants.RegionSize; x++) | ||
2031 | for (int y = 0; y < (int)Constants.RegionSize; y++) | ||
2032 | bw.Write(val[x, y]); | ||
2033 | |||
2034 | return str.ToArray(); | ||
2035 | } | ||
2036 | |||
2037 | // private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val) | ||
2038 | // { | ||
2039 | // row["RegionUUID"] = regionUUID; | ||
2040 | // row["Revision"] = rev; | ||
2041 | |||
2042 | // MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize)*sizeof (double)); | ||
2043 | // BinaryWriter bw = new BinaryWriter(str); | ||
2044 | |||
2045 | // // TODO: COMPATIBILITY - Add byte-order conversions | ||
2046 | // for (int x = 0; x < (int)Constants.RegionSize; x++) | ||
2047 | // for (int y = 0; y < (int)Constants.RegionSize; y++) | ||
2048 | // bw.Write(val[x, y]); | ||
2049 | |||
2050 | // row["Heightfield"] = str.ToArray(); | ||
2051 | // } | ||
2052 | |||
2053 | /// <summary> | ||
2054 | /// | ||
2055 | /// </summary> | ||
2056 | /// <param name="row"></param> | 2019 | /// <param name="row"></param> |
2057 | /// <param name="prim"></param> | 2020 | /// <param name="prim"></param> |
2058 | /// <param name="sceneGroupID"></param> | 2021 | /// <param name="sceneGroupID"></param> |