aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data')
-rw-r--r--OpenSim/Data/IRegionData.cs4
-rw-r--r--OpenSim/Data/MSSQL/MSSQLSimulationData.cs107
-rw-r--r--OpenSim/Data/MySQL/MySQLSimulationData.cs86
-rw-r--r--OpenSim/Data/MySQL/MySQLUserProfilesData.cs20
-rw-r--r--OpenSim/Data/Null/NullSimulationData.cs22
-rw-r--r--OpenSim/Data/PGSQL/PGSQLSimulationData.cs121
-rw-r--r--OpenSim/Data/SQLite/SQLiteSimulationData.cs101
-rw-r--r--OpenSim/Data/SQLite/SQLiteUserProfilesData.cs3
8 files changed, 211 insertions, 253 deletions
diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs
index 463c621..50433ba 100644
--- a/OpenSim/Data/IRegionData.cs
+++ b/OpenSim/Data/IRegionData.cs
@@ -54,12 +54,12 @@ namespace OpenSim.Data
54 /// <summary> 54 /// <summary>
55 /// Return the x-coordinate of this region. 55 /// Return the x-coordinate of this region.
56 /// </summary> 56 /// </summary>
57 public int coordX { get { return posX / (int)Constants.RegionSize; } } 57 public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
58 58
59 /// <summary> 59 /// <summary>
60 /// Return the y-coordinate of this region. 60 /// Return the y-coordinate of this region.
61 /// </summary> 61 /// </summary>
62 public int coordY { get { return posY / (int)Constants.RegionSize; } } 62 public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
63 63
64 public Dictionary<string, object> Data; 64 public Dictionary<string, object> Data;
65 } 65 }
diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
index f41f60c..1a5ecd6 100644
--- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
@@ -49,6 +49,7 @@ namespace OpenSim.Data.MSSQL
49 49
50 // private static FileSystemDataStore Instance = new FileSystemDataStore(); 50 // private static FileSystemDataStore Instance = new FileSystemDataStore();
51 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 private static string LogHeader = "[REGION DB MSSQL]";
52 53
53 /// <summary> 54 /// <summary>
54 /// The database manager 55 /// The database manager
@@ -530,43 +531,53 @@ ELSE
530 /// <returns></returns> 531 /// <returns></returns>
531 public double[,] LoadTerrain(UUID regionID) 532 public double[,] LoadTerrain(UUID regionID)
532 { 533 {
533 double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; 534 double[,] ret = null;
534 terrain.Initialize(); 535 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
536 if (terrData != null)
537 ret = terrData.GetDoubles();
538 return ret;
539 }
540
541 // Returns 'null' if region not found
542 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
543 {
544 TerrainData terrData = null;
535 545
536 string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc"; 546 string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc";
537 547
538 using (SqlConnection conn = new SqlConnection(m_connectionString)) 548 using (SqlConnection conn = new SqlConnection(m_connectionString))
539 using (SqlCommand cmd = new SqlCommand(sql, conn))
540 { 549 {
541 // MySqlParameter param = new MySqlParameter(); 550 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 { 551 {
546 int rev; 552 // MySqlParameter param = new MySqlParameter();
547 if (reader.Read()) 553 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
554 conn.Open();
555 using (SqlDataReader reader = cmd.ExecuteReader())
548 { 556 {
549 MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); 557 int rev;
550 BinaryReader br = new BinaryReader(str); 558 if (reader.Read())
551 for (int x = 0; x < (int)Constants.RegionSize; x++)
552 { 559 {
553 for (int y = 0; y < (int)Constants.RegionSize; y++) 560 rev = (int)reader["Revision"];
554 { 561 byte[] blob = (byte[])reader["Heightfield"];
555 terrain[x, y] = br.ReadDouble(); 562 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
556 }
557 } 563 }
558 rev = (int)reader["Revision"]; 564 else
559 } 565 {
560 else 566 _Log.Info("[REGION DB]: No terrain found for region");
561 { 567 return null;
562 _Log.Info("[REGION DB]: No terrain found for region"); 568 }
563 return null; 569 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
564 } 570 }
565 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
566 } 571 }
567 } 572 }
568 573
569 return terrain; 574 return terrData;
575 }
576
577 // Legacy entry point for when terrain was always a 256x256 hieghtmap
578 public void StoreTerrain(double[,] ter, UUID regionID)
579 {
580 StoreTerrain(new HeightmapTerrainData(ter), regionID);
570 } 581 }
571 582
572 /// <summary> 583 /// <summary>
@@ -574,10 +585,8 @@ ELSE
574 /// </summary> 585 /// </summary>
575 /// <param name="terrain">terrain map data.</param> 586 /// <param name="terrain">terrain map data.</param>
576 /// <param name="regionID">regionID.</param> 587 /// <param name="regionID">regionID.</param>
577 public void StoreTerrain(double[,] terrain, UUID regionID) 588 public void StoreTerrain(TerrainData terrData, UUID regionID)
578 { 589 {
579 int revision = Util.UnixTimeSinceEpoch();
580
581 //Delete old terrain map 590 //Delete old terrain map
582 string sql = "delete from terrain where RegionUUID=@RegionUUID"; 591 string sql = "delete from terrain where RegionUUID=@RegionUUID";
583 using (SqlConnection conn = new SqlConnection(m_connectionString)) 592 using (SqlConnection conn = new SqlConnection(m_connectionString))
@@ -590,17 +599,23 @@ ELSE
590 599
591 sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)"; 600 sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)";
592 601
602 int terrainDBRevision;
603 Array terrainDBblob;
604 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
605
593 using (SqlConnection conn = new SqlConnection(m_connectionString)) 606 using (SqlConnection conn = new SqlConnection(m_connectionString))
594 using (SqlCommand cmd = new SqlCommand(sql, conn))
595 { 607 {
596 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID)); 608 using (SqlCommand cmd = new SqlCommand(sql, conn))
597 cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision)); 609 {
598 cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain))); 610 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
599 conn.Open(); 611 cmd.Parameters.Add(_Database.CreateParameter("@Revision", terrainDBRevision));
600 cmd.ExecuteNonQuery(); 612 cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", terrainDBblob));
613 conn.Open();
614 cmd.ExecuteNonQuery();
615 }
601 } 616 }
602 617
603 _Log.Info("[REGION DB]: Stored terrain revision r " + revision); 618 _Log.InfoFormat("{0} Stored terrain revision r={1}", LogHeader, terrainDBRevision);
604 } 619 }
605 620
606 /// <summary> 621 /// <summary>
@@ -1345,30 +1360,6 @@ VALUES
1345 #region Private Methods 1360 #region Private Methods
1346 1361
1347 /// <summary> 1362 /// <summary>
1348 /// Serializes the terrain data for storage in DB.
1349 /// </summary>
1350 /// <param name="val">terrain data</param>
1351 /// <returns></returns>
1352 private static Array serializeTerrain(double[,] val)
1353 {
1354 MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double));
1355 BinaryWriter bw = new BinaryWriter(str);
1356
1357 // TODO: COMPATIBILITY - Add byte-order conversions
1358 for (int x = 0; x < (int)Constants.RegionSize; x++)
1359 for (int y = 0; y < (int)Constants.RegionSize; y++)
1360 {
1361 double height = val[x, y];
1362 if (height == 0.0)
1363 height = double.Epsilon;
1364
1365 bw.Write(height);
1366 }
1367
1368 return str.ToArray();
1369 }
1370
1371 /// <summary>
1372 /// Stores new regionsettings. 1363 /// Stores new regionsettings.
1373 /// </summary> 1364 /// </summary>
1374 /// <param name="regionSettings">The region settings.</param> 1365 /// <param name="regionSettings">The region settings.</param>
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index b03a904..2921c1c 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -48,6 +48,7 @@ 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;
53 private object m_dbLock = new object(); 54 private object m_dbLock = new object();
@@ -91,7 +92,7 @@ namespace OpenSim.Data.MySQL
91 } 92 }
92 catch (Exception e) 93 catch (Exception e)
93 { 94 {
94 m_log.Error("[REGION DB]: MySQL error in ExecuteReader: " + e.Message); 95 m_log.ErrorFormat("{0} MySQL error in ExecuteReader: {1}", LogHeader, e);
95 throw; 96 throw;
96 } 97 }
97 98
@@ -572,10 +573,14 @@ namespace OpenSim.Data.MySQL
572 } 573 }
573 } 574 }
574 575
576 // Legacy entry point for when terrain was always a 256x256 hieghtmap
575 public void StoreTerrain(double[,] ter, UUID regionID) 577 public void StoreTerrain(double[,] ter, UUID regionID)
576 { 578 {
577 m_log.Info("[REGION DB]: Storing terrain"); 579 StoreTerrain(new HeightmapTerrainData(ter), regionID);
580 }
578 581
582 public void StoreTerrain(TerrainData terrData, UUID regionID)
583 {
579 lock (m_dbLock) 584 lock (m_dbLock)
580 { 585 {
581 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 586 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
@@ -589,11 +594,18 @@ namespace OpenSim.Data.MySQL
589 594
590 ExecuteNonQuery(cmd); 595 ExecuteNonQuery(cmd);
591 596
592 cmd.CommandText = "insert into terrain (RegionUUID, " + 597 int terrainDBRevision;
593 "Revision, Heightfield) values (?RegionUUID, " + 598 Array terrainDBblob;
594 "1, ?Heightfield)"; 599 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
595 600
596 cmd.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter)); 601 m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}",
602 LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision);
603
604 cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)"
605 + "values (?RegionUUID, ?Revision, ?Heightfield)";
606
607 cmd.Parameters.AddWithValue("Revision", terrainDBRevision);
608 cmd.Parameters.AddWithValue("Heightfield", terrainDBblob);
597 609
598 ExecuteNonQuery(cmd); 610 ExecuteNonQuery(cmd);
599 } 611 }
@@ -601,9 +613,20 @@ namespace OpenSim.Data.MySQL
601 } 613 }
602 } 614 }
603 615
616 // Legacy region loading
604 public double[,] LoadTerrain(UUID regionID) 617 public double[,] LoadTerrain(UUID regionID)
605 { 618 {
606 double[,] terrain = null; 619 double[,] ret = null;
620 TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
621 if (terrData != null)
622 ret = terrData.GetDoubles();
623 return ret;
624 }
625
626 // Returns 'null' if region not found
627 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
628 {
629 TerrainData terrData = null;
607 630
608 lock (m_dbLock) 631 lock (m_dbLock)
609 { 632 {
@@ -623,32 +646,15 @@ namespace OpenSim.Data.MySQL
623 while (reader.Read()) 646 while (reader.Read())
624 { 647 {
625 int rev = Convert.ToInt32(reader["Revision"]); 648 int rev = Convert.ToInt32(reader["Revision"]);
626 649 byte[] blob = (byte[])reader["Heightfield"];
627 terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; 650 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
628 terrain.Initialize();
629
630 using (MemoryStream mstr = new MemoryStream((byte[])reader["Heightfield"]))
631 {
632 using (BinaryReader br = new BinaryReader(mstr))
633 {
634 for (int x = 0; x < (int)Constants.RegionSize; x++)
635 {
636 for (int y = 0; y < (int)Constants.RegionSize; y++)
637 {
638 terrain[x, y] = br.ReadDouble();
639 }
640 }
641 }
642
643 m_log.InfoFormat("[REGION DB]: Loaded terrain revision r{0}", rev);
644 }
645 } 651 }
646 } 652 }
647 } 653 }
648 } 654 }
649 } 655 }
650 656
651 return terrain; 657 return terrData;
652 } 658 }
653 659
654 public void RemoveLandObject(UUID globalID) 660 public void RemoveLandObject(UUID globalID)
@@ -1525,30 +1531,6 @@ namespace OpenSim.Data.MySQL
1525 } 1531 }
1526 1532
1527 /// <summary> 1533 /// <summary>
1528 ///
1529 /// </summary>
1530 /// <param name="val"></param>
1531 /// <returns></returns>
1532 private static Array SerializeTerrain(double[,] val)
1533 {
1534 MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double));
1535 BinaryWriter bw = new BinaryWriter(str);
1536
1537 // TODO: COMPATIBILITY - Add byte-order conversions
1538 for (int x = 0; x < (int)Constants.RegionSize; x++)
1539 for (int y = 0; y < (int)Constants.RegionSize; y++)
1540 {
1541 double height = val[x, y];
1542 if (height == 0.0)
1543 height = double.Epsilon;
1544
1545 bw.Write(height);
1546 }
1547
1548 return str.ToArray();
1549 }
1550
1551 /// <summary>
1552 /// Fill the prim command with prim values 1534 /// Fill the prim command with prim values
1553 /// </summary> 1535 /// </summary>
1554 /// <param name="row"></param> 1536 /// <param name="row"></param>
diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
index 63492c2..6ed3b06 100644
--- a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
+++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
@@ -546,6 +546,10 @@ namespace OpenSim.Data.MySQL
546 reader.Read(); 546 reader.Read();
547 notes.Notes = OSD.FromString((string)reader["notes"]); 547 notes.Notes = OSD.FromString((string)reader["notes"]);
548 } 548 }
549 else
550 {
551 notes.Notes = OSD.FromString("");
552 }
549 } 553 }
550 } 554 }
551 } 555 }
@@ -925,15 +929,19 @@ namespace OpenSim.Data.MySQL
925 } 929 }
926 else 930 else
927 { 931 {
932 dbcon.Close();
933 dbcon.Open();
934
935 query = "INSERT INTO usersettings VALUES ";
936 query += "(?uuid,'false','false', ?Email)";
937
928 using (MySqlCommand put = new MySqlCommand(query, dbcon)) 938 using (MySqlCommand put = new MySqlCommand(query, dbcon))
929 { 939 {
930 query = "INSERT INTO usersettings VALUES ";
931 query += "(?Id,'false','false', '')";
932 940
933 lock(Lock) 941 put.Parameters.AddWithValue("?Email", pref.EMail);
934 { 942 put.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
935 put.ExecuteNonQuery(); 943
936 } 944 put.ExecuteNonQuery();
937 } 945 }
938 } 946 }
939 } 947 }
diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs
index d11ad72..deeaced 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 354d749..77d87d4 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,44 +524,54 @@ 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; ";
531 541
532 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) 542 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
533 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
534 { 543 {
535 // PGSqlParameter param = new PGSqlParameter(); 544 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
536 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
537 conn.Open();
538 using (NpgsqlDataReader reader = cmd.ExecuteReader())
539 { 545 {
540 int rev; 546 // PGSqlParameter param = new PGSqlParameter();
541 if (reader.Read()) 547 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
548 conn.Open();
549 using (NpgsqlDataReader reader = cmd.ExecuteReader())
542 { 550 {
543 MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]); 551 int rev;
544 BinaryReader br = new BinaryReader(str); 552 if (reader.Read())
545 for (int x = 0; x < (int)Constants.RegionSize; x++)
546 { 553 {
547 for (int y = 0; y < (int)Constants.RegionSize; y++) 554 rev = Convert.ToInt32(reader["Revision"]);
548 { 555 byte[] blob = (byte[])reader["Heightfield"];
549 terrain[x, y] = br.ReadDouble(); 556 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
550 }
551 } 557 }
552 rev = (int)reader["Revision"]; 558 else
553 } 559 {
554 else 560 _Log.Info("[REGION DB]: No terrain found for region");
555 { 561 return null;
556 _Log.Info("[REGION DB]: No terrain found for region"); 562 }
557 return null; 563 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
558 } 564 }
559 _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
560 } 565 }
561 } 566 }
562 567
563 return terrain; 568 return terrData;
569 }
570
571 // Legacy entry point for when terrain was always a 256x256 heightmap
572 public void StoreTerrain(double[,] terrain, UUID regionID)
573 {
574 StoreTerrain(new HeightmapTerrainData(terrain), regionID);
564 } 575 }
565 576
566 /// <summary> 577 /// <summary>
@@ -568,35 +579,43 @@ namespace OpenSim.Data.PGSQL
568 /// </summary> 579 /// </summary>
569 /// <param name="terrain">terrain map data.</param> 580 /// <param name="terrain">terrain map data.</param>
570 /// <param name="regionID">regionID.</param> 581 /// <param name="regionID">regionID.</param>
571 public void StoreTerrain(double[,] terrain, UUID regionID) 582 public void StoreTerrain(TerrainData terrData, UUID regionID)
572 { 583 {
573 int revision = Util.UnixTimeSinceEpoch();
574
575 //Delete old terrain map 584 //Delete old terrain map
576 string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID"; 585 string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID";
577 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) 586 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
578 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
579 { 587 {
580 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); 588 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
581 conn.Open(); 589 {
582 cmd.ExecuteNonQuery(); 590 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
591 conn.Open();
592 cmd.ExecuteNonQuery();
593
594 _Log.InfoFormat("{0} Deleted terrain revision id = {1}", LogHeader, regionID);
595 }
583 } 596 }
584 597
585 _Log.Info("[REGION DB]: Deleted terrain revision r " + revision); 598 int terrainDBRevision;
599 Array terrainDBblob;
600 terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
586 601
587 sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)"; 602 sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)";
588 603
589 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) 604 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
590 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
591 { 605 {
592 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID)); 606 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
593 cmd.Parameters.Add(_Database.CreateParameter("Revision", revision)); 607 {
594 cmd.Parameters.Add(_Database.CreateParameter("Heightfield", serializeTerrain(terrain))); 608 cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
595 conn.Open(); 609 cmd.Parameters.Add(_Database.CreateParameter("Revision", terrainDBRevision));
596 cmd.ExecuteNonQuery(); 610 cmd.Parameters.Add(_Database.CreateParameter("Heightfield", terrainDBblob));
611 conn.Open();
612 cmd.ExecuteNonQuery();
613
614 _Log.InfoFormat("{0} Stored terrain id = {1}, terrainSize = <{2},{3}>",
615 LogHeader, regionID, terrData.SizeX, terrData.SizeY);
616 }
597 } 617 }
598 618
599 _Log.Info("[REGION DB]: Stored terrain revision r " + revision);
600 } 619 }
601 620
602 /// <summary> 621 /// <summary>
@@ -1350,30 +1369,6 @@ namespace OpenSim.Data.PGSQL
1350 #region Private Methods 1369 #region Private Methods
1351 1370
1352 /// <summary> 1371 /// <summary>
1353 /// Serializes the terrain data for storage in DB.
1354 /// </summary>
1355 /// <param name="val">terrain data</param>
1356 /// <returns></returns>
1357 private static Array serializeTerrain(double[,] val)
1358 {
1359 MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double));
1360 BinaryWriter bw = new BinaryWriter(str);
1361
1362 // TODO: COMPATIBILITY - Add byte-order conversions
1363 for (int x = 0; x < (int)Constants.RegionSize; x++)
1364 for (int y = 0; y < (int)Constants.RegionSize; y++)
1365 {
1366 double height = val[x, y];
1367 if (height == 0.0)
1368 height = double.Epsilon;
1369
1370 bw.Write(height);
1371 }
1372
1373 return str.ToArray();
1374 }
1375
1376 /// <summary>
1377 /// Stores new regionsettings. 1372 /// Stores new regionsettings.
1378 /// </summary> 1373 /// </summary>
1379 /// <param name="regionSettings">The region settings.</param> 1374 /// <param name="regionSettings">The region settings.</param>
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>
diff --git a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs
index 916a226..90d45e9 100644
--- a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs
+++ b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs
@@ -808,11 +808,12 @@ namespace OpenSim.Data.SQLite
808 else 808 else
809 { 809 {
810 query = "INSERT INTO usersettings VALUES "; 810 query = "INSERT INTO usersettings VALUES ";
811 query += "(:Id,'false','false', '')"; 811 query += "(:Id,'false','false', :Email)";
812 812
813 using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand()) 813 using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand())
814 { 814 {
815 put.Parameters.AddWithValue(":Id", pref.UserId.ToString()); 815 put.Parameters.AddWithValue(":Id", pref.UserId.ToString());
816 put.Parameters.AddWithValue(":Email", pref.EMail);
816 put.ExecuteNonQuery(); 817 put.ExecuteNonQuery();
817 818
818 } 819 }