aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data')
-rw-r--r--OpenSim/Data/MSSQL/MSSQLSimulationData.cs83
-rw-r--r--OpenSim/Data/MySQL/MySQLSimulationData.cs66
-rw-r--r--OpenSim/Data/Null/NullSimulationData.cs22
-rw-r--r--OpenSim/Data/PGSQL/PGSQLSimulationData.cs72
-rw-r--r--OpenSim/Data/SQLite/SQLiteSimulationData.cs54
5 files changed, 184 insertions, 113 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
index 0d09be6..145b9c0 100644
--- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
@@ -530,43 +530,52 @@ ELSE
530 /// <returns></returns> 530 /// <returns></returns>
531 public double[,] LoadTerrain(UUID regionID) 531 public double[,] LoadTerrain(UUID regionID)
532 { 532 {
533 double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; 533 double[,] ret = null;
534 terrain.Initialize(); 534 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
535 if (terrData != null)
536 ret = terrData.GetDoubles();
537 return ret;
538 }
539
540 // Returns 'null' if region not found
541 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
542 {
543 TerrainData terrData = null;
535 544
536 string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; 545 string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc";
537 546
538 using (SqlConnection conn = new SqlConnection(m_connectionString)) 547 using (SqlConnection conn = new SqlConnection(m_connectionString))
539 using (SqlCommand cmd = new SqlCommand(sql, conn))
540 { 548 {
541 // MySqlParameter param = new MySqlParameter(); 549 using (SqlCommand cmd = new SqlCommand(sql, conn))
542 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
543 conn.Open();
544 using (SqlDataReader reader = cmd.ExecuteReader())
545 { 550 {
546 int rev; 551 // MySqlParameter param = new MySqlParameter();
547 if (reader.Read()) 552 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
553 conn.Open();
554 using (SqlDataReader reader = cmd.ExecuteReader())
548 { 555 {
549 MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); 556 if (reader.Read())
550 BinaryReader br = new BinaryReader(str);
551 for (int x = 0; x < (int)Constants.RegionSize; x++)
552 { 557 {
553 for (int y = 0; y < (int)Constants.RegionSize; y++) 558 int rev = (int)reader["Revision"];
554 { 559 byte[] blob = (byte[])reader["Heightfield"];
555 terrain[x, y] = br.ReadDouble(); 560 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
556 }
557 } 561 }
558 rev = (int)reader["Revision"]; 562 else
559 } 563 {
560 else 564 _Log.Info("[REGION DB]: No terrain found for region");
561 { 565 return null;
562 _Log.Info("[REGION DB]: No terrain found for region"); 566 }
563 return null; 567 _Log.Info("[REGION DB]: Loaded terrain");
564 } 568 }
565 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
566 } 569 }
567 } 570 }
568 571
569 return terrain; 572 return terrData;
573 }
574
575 // Legacy entry point for when terrain was always a 256x256 hieghtmap
576 public void StoreTerrain(double[,] ter, UUID regionID)
577 {
578 StoreTerrain(new HeightmapTerrainData(ter), regionID);
570 } 579 }
571 580
572 /// <summary> 581 /// <summary>
@@ -574,10 +583,8 @@ ELSE
574 /// </summary> 583 /// </summary>
575 /// <param name="terrain">terrain map data.</param> 584 /// <param name="terrain">terrain map data.</param>
576 /// <param name="regionID">regionID.</param> 585 /// <param name="regionID">regionID.</param>
577 public void StoreTerrain(double[,] terrain, UUID regionID) 586 public void StoreTerrain(TerrainData terrData, UUID regionID)
578 { 587 {
579 int revision = Util.UnixTimeSinceEpoch();
580
581 //Delete old terrain map 588 //Delete old terrain map
582 string sql = "delete from terrain where RegionUUID=@RegionUUID"; 589 string sql = "delete from terrain where RegionUUID=@RegionUUID";
583 using (SqlConnection conn = new SqlConnection(m_connectionString)) 590 using (SqlConnection conn = new SqlConnection(m_connectionString))
@@ -590,17 +597,23 @@ ELSE
590 597
591 sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; 598 sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)";
592 599
600 int terrainDBRevision;
601 Array terrainDBblob;
602 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
603
593 using (SqlConnection conn = new SqlConnection(m_connectionString)) 604 using (SqlConnection conn = new SqlConnection(m_connectionString))
594 using (SqlCommand cmd = new SqlCommand(sql, conn))
595 { 605 {
596 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); 606 using (SqlCommand cmd = new SqlCommand(sql, conn))
597 cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); 607 {
598 cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); 608 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
599 conn.Open(); 609 cmd.Parameters.Add(_Database.CreateParameter("@Revision", terrainDBRevision));
600 cmd.ExecuteNonQuery(); 610 cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", terrainDBblob));
611 conn.Open();
612 cmd.ExecuteNonQuery();
613 }
601 } 614 }
602 615
603 _Log.Info("[REGION DB]: Stored terrain revision r " + revision); 616 _Log.Info("[REGION DB]: Stored terrain");
604 } 617 }
605 618
606 /// <summary> 619 /// <summary>
@@ -1344,6 +1357,7 @@ VALUES
1344 1357
1345 #region Private Methods 1358 #region Private Methods
1346 1359
1360 /*
1347 /// <summary> 1361 /// <summary>
1348 /// Serializes the terrain data for storage in DB. 1362 /// Serializes the terrain data for storage in DB.
1349 /// </summary> 1363 /// </summary>
@@ -1367,6 +1381,7 @@ VALUES
1367 1381
1368 return str.ToArray(); 1382 return str.ToArray();
1369 } 1383 }
1384 */
1370 1385
1371 /// <summary> 1386 /// <summary>
1372 /// Stores new regionsettings. 1387 /// Stores new regionsettings.
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index cc844ae..f910e44 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -48,8 +48,18 @@ namespace OpenSim.Data.MySQL
48 public class MySQLSimulationData : ISimulationDataStore 48 public class MySQLSimulationData : ISimulationDataStore
49 { 49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private static string LogHeader = "[REGION DB MYSQL]";
51 52
52 private string m_connectionString; 53 private string m_connectionString;
54
55 /// <summary>
56 /// This lock was being used to serialize database operations when the connection was shared, but this has
57 /// been unnecessary for a long time after we switched to using MySQL's underlying connection pooling instead.
58 /// FIXME: However, the locks remain in many places since they are effectively providing a level of
59 /// transactionality. This should be replaced by more efficient database transactions which would not require
60 /// unrelated operations to block each other or unrelated operations on the same tables from blocking each
61 /// other.
62 /// </summary>
53 private object m_dbLock = new object(); 63 private object m_dbLock = new object();
54 64
55 protected virtual Assembly Assembly 65 protected virtual Assembly Assembly
@@ -91,7 +101,7 @@ namespace OpenSim.Data.MySQL
91 } 101 }
92 catch (Exception e) 102 catch (Exception e)
93 { 103 {
94 m_log.Error("[REGION DB]: MySQL error in ExecuteReader: " + e.Message); 104 m_log.ErrorFormat("{0} MySQL error in ExecuteReader: {1}", LogHeader, e);
95 throw; 105 throw;
96 } 106 }
97 107
@@ -574,12 +584,16 @@ namespace OpenSim.Data.MySQL
574 } 584 }
575 } 585 }
576 586
577 public virtual void StoreTerrain(double[,] ter, UUID regionID) 587 // Legacy entry point for when terrain was always a 256x256 hieghtmap
588 public void StoreTerrain(double[,] ter, UUID regionID)
589 {
590 StoreTerrain(new HeightmapTerrainData(ter), regionID);
591 }
592
593 public void StoreTerrain(TerrainData terrData, UUID regionID)
578 { 594 {
579 Util.FireAndForget(delegate(object x) 595 Util.FireAndForget(delegate(object x)
580 { 596 {
581 double[,] oldTerrain = LoadTerrain(regionID);
582
583 m_log.Info("[REGION DB]: Storing terrain"); 597 m_log.Info("[REGION DB]: Storing terrain");
584 598
585 lock (m_dbLock) 599 lock (m_dbLock)
@@ -601,8 +615,12 @@ namespace OpenSim.Data.MySQL
601 "Revision, Heightfield) values (?RegionUUID, " + 615 "Revision, Heightfield) values (?RegionUUID, " +
602 "1, ?Heightfield)"; 616 "1, ?Heightfield)";
603 617
604 cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); 618 int terrainDBRevision;
605 cmd2.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter, oldTerrain)); 619 Array terrainDBblob;
620 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
621
622 cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
623 cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
606 624
607 ExecuteNonQuery(cmd); 625 ExecuteNonQuery(cmd);
608 ExecuteNonQuery(cmd2); 626 ExecuteNonQuery(cmd2);
@@ -618,9 +636,20 @@ namespace OpenSim.Data.MySQL
618 }); 636 });
619 } 637 }
620 638
639 // Legacy region loading
621 public virtual double[,] LoadTerrain(UUID regionID) 640 public virtual double[,] LoadTerrain(UUID regionID)
622 { 641 {
623 double[,] terrain = null; 642 double[,] ret = null;
643 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
644 if (terrData != null)
645 ret = terrData.GetDoubles();
646 return ret;
647 }
648
649 // Returns 'null' if region not found
650 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
651 {
652 TerrainData terrData = null;
624 653
625 lock (m_dbLock) 654 lock (m_dbLock)
626 { 655 {
@@ -640,32 +669,15 @@ namespace OpenSim.Data.MySQL
640 while (reader.Read()) 669 while (reader.Read())
641 { 670 {
642 int rev = Convert.ToInt32(reader["Revision"]); 671 int rev = Convert.ToInt32(reader["Revision"]);
643 672 byte[] blob = (byte[])reader["Heightfield"];
644 terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; 673 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
645 terrain.Initialize();
646
647 using (MemoryStream mstr = new MemoryStream((byte[])reader["Heightfield"]))
648 {
649 using (BinaryReader br = new BinaryReader(mstr))
650 {
651 for (int x = 0; x < (int)Constants.RegionSize; x++)
652 {
653 for (int y = 0; y < (int)Constants.RegionSize; y++)
654 {
655 terrain[x, y] = br.ReadDouble();
656 }
657 }
658 }
659
660 m_log.InfoFormat("[REGION DB]: Loaded terrain revision r{0}", rev);
661 }
662 } 674 }
663 } 675 }
664 } 676 }
665 } 677 }
666 } 678 }
667 679
668 return terrain; 680 return terrData;
669 } 681 }
670 682
671 public virtual void RemoveLandObject(UUID globalID) 683 public virtual void RemoveLandObject(UUID globalID)
diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs
index 15824a9..339e7f4 100644
--- a/OpenSim/Data/Null/NullSimulationData.cs
+++ b/OpenSim/Data/Null/NullSimulationData.cs
@@ -132,18 +132,36 @@ namespace OpenSim.Data.Null
132 return new List<SceneObjectGroup>(); 132 return new List<SceneObjectGroup>();
133 } 133 }
134 134
135 Dictionary<UUID, double[,]> m_terrains = new Dictionary<UUID, double[,]>(); 135 Dictionary<UUID, TerrainData> m_terrains = new Dictionary<UUID, TerrainData>();
136 public void StoreTerrain(double[,] ter, UUID regionID) 136 public void StoreTerrain(TerrainData ter, UUID regionID)
137 { 137 {
138 if (m_terrains.ContainsKey(regionID)) 138 if (m_terrains.ContainsKey(regionID))
139 m_terrains.Remove(regionID); 139 m_terrains.Remove(regionID);
140 m_terrains.Add(regionID, ter); 140 m_terrains.Add(regionID, ter);
141 } 141 }
142 142
143 // Legacy. Just don't do this.
144 public void StoreTerrain(double[,] ter, UUID regionID)
145 {
146 TerrainData terrData = new HeightmapTerrainData(ter);
147 StoreTerrain(terrData, regionID);
148 }
149
150 // Legacy. Just don't do this.
151 // Returns 'null' if region not found
143 public double[,] LoadTerrain(UUID regionID) 152 public double[,] LoadTerrain(UUID regionID)
144 { 153 {
145 if (m_terrains.ContainsKey(regionID)) 154 if (m_terrains.ContainsKey(regionID))
146 { 155 {
156 return m_terrains[regionID].GetDoubles();
157 }
158 return null;
159 }
160
161 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
162 {
163 if (m_terrains.ContainsKey(regionID))
164 {
147 return m_terrains[regionID]; 165 return m_terrains[regionID];
148 } 166 }
149 return null; 167 return null;
diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
index 3243635..cd02e05 100644
--- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
+++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
@@ -46,6 +46,7 @@ namespace OpenSim.Data.PGSQL
46 public class PGSQLSimulationData : ISimulationDataStore 46 public class PGSQLSimulationData : ISimulationDataStore
47 { 47 {
48 private const string _migrationStore = "RegionStore"; 48 private const string _migrationStore = "RegionStore";
49 private const string LogHeader = "[REGION DB PGSQL]";
49 50
50 // private static FileSystemDataStore Instance = new FileSystemDataStore(); 51 // private static FileSystemDataStore Instance = new FileSystemDataStore();
51 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -523,8 +524,17 @@ namespace OpenSim.Data.PGSQL
523 /// <returns></returns> 524 /// <returns></returns>
524 public double[,] LoadTerrain(UUID regionID) 525 public double[,] LoadTerrain(UUID regionID)
525 { 526 {
526 double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; 527 double[,] ret = null;
527 terrain.Initialize(); 528 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
529 if (terrData != null)
530 ret = terrData.GetDoubles();
531 return ret;
532 }
533
534 // Returns 'null' if region not found
535 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
536 {
537 TerrainData terrData = null;
528 538
529 string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain 539 string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain
530 where ""RegionUUID"" = :RegionUUID order by ""Revision"" desc limit 1; "; 540 where ""RegionUUID"" = :RegionUUID order by ""Revision"" desc limit 1; ";
@@ -540,16 +550,9 @@ namespace OpenSim.Data.PGSQL
540 int rev; 550 int rev;
541 if (reader.Read()) 551 if (reader.Read())
542 { 552 {
543 MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); 553 rev = Convert.ToInt32(reader["Revision"]);
544 BinaryReader br = new BinaryReader(str); 554 byte[] blob = (byte[])reader["Heightfield"];
545 for (int x = 0; x < (int)Constants.RegionSize; x++) 555 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
546 {
547 for (int y = 0; y < (int)Constants.RegionSize; y++)
548 {
549 terrain[x, y] = br.ReadDouble();
550 }
551 }
552 rev = (int)reader["Revision"];
553 } 556 }
554 else 557 else
555 { 558 {
@@ -560,7 +563,13 @@ namespace OpenSim.Data.PGSQL
560 } 563 }
561 } 564 }
562 565
563 return terrain; 566 return terrData;
567 }
568
569 // Legacy entry point for when terrain was always a 256x256 heightmap
570 public void StoreTerrain(double[,] terrain, UUID regionID)
571 {
572 StoreTerrain(new HeightmapTerrainData(terrain), regionID);
564 } 573 }
565 574
566 /// <summary> 575 /// <summary>
@@ -568,35 +577,38 @@ namespace OpenSim.Data.PGSQL
568 /// </summary> 577 /// </summary>
569 /// <param name="terrain">terrain map data.</param> 578 /// <param name="terrain">terrain map data.</param>
570 /// <param name="regionID">regionID.</param> 579 /// <param name="regionID">regionID.</param>
571 public void StoreTerrain(double[,] terrain, UUID regionID) 580 public void StoreTerrain(TerrainData terrData, UUID regionID)
572 { 581 {
573 int revision = Util.UnixTimeSinceEpoch();
574
575 //Delete old terrain map 582 //Delete old terrain map
576 string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID"; 583 string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID";
577 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) 584 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
578 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
579 { 585 {
580 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); 586 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
581 conn.Open(); 587 {
582 cmd.ExecuteNonQuery(); 588 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
589 conn.Open();
590 cmd.ExecuteNonQuery();
591 }
583 } 592 }
584 593 int terrainDBRevision;
585 _Log.Info("[REGION DB]: Deleted terrain revision r " + revision); 594 Array terrainDBblob;
595 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
586 596
587 sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)"; 597 sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)";
588 598
589 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) 599 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
590 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
591 { 600 {
592 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); 601 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
593 cmd.Parameters.Add(_Database.CreateParameter("Revision", revision)); 602 {
594 cmd.Parameters.Add(_Database.CreateParameter("Heightfield", serializeTerrain(terrain))); 603 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
595 conn.Open(); 604 cmd.Parameters.Add(_Database.CreateParameter("Revision", terrainDBRevision));
596 cmd.ExecuteNonQuery(); 605 cmd.Parameters.Add(_Database.CreateParameter("Heightfield", terrainDBblob));
606 conn.Open();
607 cmd.ExecuteNonQuery();
608 }
597 } 609 }
598 610
599 _Log.Info("[REGION DB]: Stored terrain revision r " + revision); 611 _Log.Info("[REGION DB]: Stored terrain revision r " + terrainDBRevision);
600 } 612 }
601 613
602 /// <summary> 614 /// <summary>
@@ -1349,6 +1361,7 @@ namespace OpenSim.Data.PGSQL
1349 1361
1350 #region Private Methods 1362 #region Private Methods
1351 1363
1364 /*
1352 /// <summary> 1365 /// <summary>
1353 /// Serializes the terrain data for storage in DB. 1366 /// Serializes the terrain data for storage in DB.
1354 /// </summary> 1367 /// </summary>
@@ -1372,6 +1385,7 @@ namespace OpenSim.Data.PGSQL
1372 1385
1373 return str.ToArray(); 1386 return str.ToArray();
1374 } 1387 }
1388 */
1375 1389
1376 /// <summary> 1390 /// <summary>
1377 /// Stores new regionsettings. 1391 /// Stores new regionsettings.
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
index 4d6a80a..d28c227 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,12 +820,18 @@ 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 {
@@ -853,11 +860,17 @@ namespace OpenSim.Data.SQLite
853 String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + 860 String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
854 " values(:RegionUUID, :Revision, :Heightfield)"; 861 " values(:RegionUUID, :Revision, :Heightfield)";
855 862
863 int terrainDBRevision;
864 Array terrainDBblob;
865 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
866
867 m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision);
868
856 using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) 869 using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
857 { 870 {
858 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); 871 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
859 cmd.Parameters.Add(new SqliteParameter(":Revision", revision)); 872 cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision));
860 cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter))); 873 cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob));
861 cmd.ExecuteNonQuery(); 874 cmd.ExecuteNonQuery();
862 } 875 }
863 } 876 }
@@ -870,11 +883,20 @@ namespace OpenSim.Data.SQLite
870 /// <returns>Heightfield data</returns> 883 /// <returns>Heightfield data</returns>
871 public double[,] LoadTerrain(UUID regionID) 884 public double[,] LoadTerrain(UUID regionID)
872 { 885 {
886 double[,] ret = null;
887 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
888 if (terrData != null)
889 ret = terrData.GetDoubles();
890 return ret;
891 }
892
893 // Returns 'null' if region not found
894 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
895 {
896 TerrainData terrData = null;
897
873 lock (ds) 898 lock (ds)
874 { 899 {
875 double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
876 terret.Initialize();
877
878 String sql = "select RegionUUID, Revision, Heightfield from terrain" + 900 String sql = "select RegionUUID, Revision, Heightfield from terrain" +
879 " where RegionUUID=:RegionUUID order by Revision desc"; 901 " where RegionUUID=:RegionUUID order by Revision desc";
880 902
@@ -887,21 +909,9 @@ namespace OpenSim.Data.SQLite
887 int rev = 0; 909 int rev = 0;
888 if (row.Read()) 910 if (row.Read())
889 { 911 {
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"]); 912 rev = Convert.ToInt32(row["Revision"]);
913 byte[] blob = (byte[])row["Heightfield"];
914 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
905 } 915 }
906 else 916 else
907 { 917 {
@@ -912,8 +922,8 @@ namespace OpenSim.Data.SQLite
912 m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString()); 922 m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString());
913 } 923 }
914 } 924 }
915 return terret;
916 } 925 }
926 return terrData;
917 } 927 }
918 928
919 public void RemoveLandObject(UUID globalID) 929 public void RemoveLandObject(UUID globalID)
@@ -2016,6 +2026,7 @@ namespace OpenSim.Data.SQLite
2016 return entry; 2026 return entry;
2017 } 2027 }
2018 2028
2029 /*
2019 /// <summary> 2030 /// <summary>
2020 /// 2031 ///
2021 /// </summary> 2032 /// </summary>
@@ -2033,6 +2044,7 @@ namespace OpenSim.Data.SQLite
2033 2044
2034 return str.ToArray(); 2045 return str.ToArray();
2035 } 2046 }
2047 */
2036 2048
2037 // private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val) 2049 // private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val)
2038 // { 2050 // {