diff options
Diffstat (limited to 'OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs')
-rw-r--r-- | OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs | 121 |
1 files changed, 117 insertions, 4 deletions
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs index 733e4c4..cc0ff7a 100644 --- a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs +++ b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs | |||
@@ -43,10 +43,12 @@ namespace OpenSim.DataStore.MonoSqlite | |||
43 | { | 43 | { |
44 | private const string primSelect = "select * from prims"; | 44 | private const string primSelect = "select * from prims"; |
45 | private const string shapeSelect = "select * from primshapes"; | 45 | private const string shapeSelect = "select * from primshapes"; |
46 | private const string terrainSelect = "select * from terrain"; | ||
46 | 47 | ||
47 | private DataSet ds; | 48 | private DataSet ds; |
48 | private SqliteDataAdapter primDa; | 49 | private SqliteDataAdapter primDa; |
49 | private SqliteDataAdapter shapeDa; | 50 | private SqliteDataAdapter shapeDa; |
51 | private SqliteDataAdapter terrainDa; | ||
50 | 52 | ||
51 | /*********************************************************************** | 53 | /*********************************************************************** |
52 | * | 54 | * |
@@ -70,6 +72,8 @@ namespace OpenSim.DataStore.MonoSqlite | |||
70 | shapeDa = new SqliteDataAdapter(shapeSelectCmd); | 72 | shapeDa = new SqliteDataAdapter(shapeSelectCmd); |
71 | // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa); | 73 | // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa); |
72 | 74 | ||
75 | SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn); | ||
76 | terrainDa = new SqliteDataAdapter(terrainSelectCmd); | ||
73 | 77 | ||
74 | // We fill the data set, now we've got copies in memory for the information | 78 | // We fill the data set, now we've got copies in memory for the information |
75 | // TODO: see if the linkage actually holds. | 79 | // TODO: see if the linkage actually holds. |
@@ -83,6 +87,10 @@ namespace OpenSim.DataStore.MonoSqlite | |||
83 | 87 | ||
84 | ds.Tables.Add(createShapeTable()); | 88 | ds.Tables.Add(createShapeTable()); |
85 | setupShapeCommands(shapeDa, conn); | 89 | setupShapeCommands(shapeDa, conn); |
90 | |||
91 | ds.Tables.Add(createTerrainTable()); | ||
92 | setupTerrainCommands(terrainDa, conn); | ||
93 | terrainDa.Fill(ds.Tables["terrain"]); | ||
86 | 94 | ||
87 | // WORKAROUND: This is a work around for sqlite on | 95 | // WORKAROUND: This is a work around for sqlite on |
88 | // windows, which gets really unhappy with blob columns | 96 | // windows, which gets really unhappy with blob columns |
@@ -210,14 +218,57 @@ namespace OpenSim.DataStore.MonoSqlite | |||
210 | } | 218 | } |
211 | 219 | ||
212 | 220 | ||
213 | public void StoreTerrain(double[,] ter) | 221 | public void StoreTerrain(double[,] ter, LLUUID regionID) |
214 | { | 222 | { |
223 | int revision = OpenSim.Framework.Utilities.Util.UnixTimeSinceEpoch(); | ||
224 | |||
225 | MainLog.Instance.Verbose("DATASTORE", "Storing terrain revision r" + revision.ToString()); | ||
226 | |||
227 | DataTable terrain = ds.Tables["terrain"]; | ||
228 | |||
229 | DataRow newrow = terrain.NewRow(); | ||
230 | fillTerrainRow(newrow, regionID, revision, ter); | ||
231 | terrain.Rows.Add(newrow); | ||
215 | 232 | ||
233 | Commit(); | ||
216 | } | 234 | } |
217 | 235 | ||
218 | public double[,] LoadTerrain() | 236 | public double[,] LoadTerrain(LLUUID regionID) |
219 | { | 237 | { |
220 | return null; | 238 | double[,] terret = new double[256, 256]; |
239 | terret.Initialize(); | ||
240 | |||
241 | DataTable terrain = ds.Tables["terrain"]; | ||
242 | |||
243 | DataRow[] rows = terrain.Select("RegionUUID = '" + regionID.ToString() + "'","Revision DESC"); | ||
244 | |||
245 | int rev = 0; | ||
246 | |||
247 | if (rows.Length > 0) | ||
248 | { | ||
249 | DataRow row = rows[0]; | ||
250 | |||
251 | byte[] heightmap = (byte[])row["Heightfield"]; | ||
252 | for (int x = 0; x < 256; x++) | ||
253 | { | ||
254 | for (int y = 0; y < 256; y++) | ||
255 | { | ||
256 | terret[x, y] = BitConverter.ToDouble(heightmap, ((x * 256) + y) * 8); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | rev = (int)row["Revision"]; | ||
261 | } | ||
262 | else | ||
263 | { | ||
264 | MainLog.Instance.Verbose("DATASTORE", "No terrain found for region"); | ||
265 | return null; | ||
266 | } | ||
267 | |||
268 | |||
269 | MainLog.Instance.Verbose("DATASTORE", "Loaded terrain revision r" + rev.ToString()); | ||
270 | |||
271 | return terret; | ||
221 | } | 272 | } |
222 | 273 | ||
223 | public void RemoveLandObject(uint id) | 274 | public void RemoveLandObject(uint id) |
@@ -240,6 +291,7 @@ namespace OpenSim.DataStore.MonoSqlite | |||
240 | lock (ds) { | 291 | lock (ds) { |
241 | primDa.Update(ds, "prims"); | 292 | primDa.Update(ds, "prims"); |
242 | shapeDa.Update(ds, "primshapes"); | 293 | shapeDa.Update(ds, "primshapes"); |
294 | terrainDa.Update(ds, "terrain"); | ||
243 | ds.AcceptChanges(); | 295 | ds.AcceptChanges(); |
244 | } | 296 | } |
245 | } | 297 | } |
@@ -263,6 +315,22 @@ namespace OpenSim.DataStore.MonoSqlite | |||
263 | dt.Columns.Add(col); | 315 | dt.Columns.Add(col); |
264 | } | 316 | } |
265 | 317 | ||
318 | private DataTable createTerrainTable() | ||
319 | { | ||
320 | DataTable terrain = new DataTable("terrain"); | ||
321 | |||
322 | createCol(terrain, "RegionUUID", typeof(System.String)); | ||
323 | createCol(terrain, "Revision", typeof(System.Int32)); | ||
324 | createCol(terrain, "Heightfield", typeof(System.Byte[])); | ||
325 | |||
326 | /* // Attempting to work out requirements to get SQLite to actually *save* the data. | ||
327 | createCol(terrain, "PrIndex", typeof(System.String)); | ||
328 | terrain.PrimaryKey = new DataColumn[] { terrain.Columns["PrIndex"] }; | ||
329 | */ | ||
330 | |||
331 | return terrain; | ||
332 | } | ||
333 | |||
266 | private DataTable createPrimTable() | 334 | private DataTable createPrimTable() |
267 | { | 335 | { |
268 | DataTable prims = new DataTable("prims"); | 336 | DataTable prims = new DataTable("prims"); |
@@ -431,6 +499,22 @@ namespace OpenSim.DataStore.MonoSqlite | |||
431 | return prim; | 499 | return prim; |
432 | } | 500 | } |
433 | 501 | ||
502 | private void fillTerrainRow(DataRow row, LLUUID regionUUID, int rev, double[,] val) | ||
503 | { | ||
504 | row["RegionUUID"] = regionUUID; | ||
505 | row["Revision"] = rev; | ||
506 | |||
507 | System.IO.MemoryStream str = new System.IO.MemoryStream(65536 * sizeof(double)); | ||
508 | System.IO.BinaryWriter bw = new System.IO.BinaryWriter(str); | ||
509 | |||
510 | // TODO: COMPATIBILITY - Add byte-order conversions | ||
511 | for (int x = 0; x < 256; x++) | ||
512 | for (int y = 0; y < 256; y++) | ||
513 | bw.Write(val[x, y]); | ||
514 | |||
515 | row["Heightfield"] = str.ToArray(); | ||
516 | } | ||
517 | |||
434 | private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) | 518 | private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) |
435 | { | 519 | { |
436 | row["UUID"] = prim.UUID; | 520 | row["UUID"] = prim.UUID; |
@@ -692,7 +776,7 @@ namespace OpenSim.DataStore.MonoSqlite | |||
692 | subsql += ",\n"; | 776 | subsql += ",\n"; |
693 | } | 777 | } |
694 | subsql += col.ColumnName + " " + sqliteType(col.DataType); | 778 | subsql += col.ColumnName + " " + sqliteType(col.DataType); |
695 | if (col == dt.PrimaryKey[0]) | 779 | if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0]) |
696 | { | 780 | { |
697 | subsql += " primary key"; | 781 | subsql += " primary key"; |
698 | } | 782 | } |
@@ -746,6 +830,12 @@ namespace OpenSim.DataStore.MonoSqlite | |||
746 | da.DeleteCommand = delete; | 830 | da.DeleteCommand = delete; |
747 | } | 831 | } |
748 | 832 | ||
833 | private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
834 | { | ||
835 | da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]); | ||
836 | da.InsertCommand.Connection = conn; | ||
837 | } | ||
838 | |||
749 | private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn) | 839 | private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn) |
750 | { | 840 | { |
751 | da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]); | 841 | da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]); |
@@ -764,12 +854,15 @@ namespace OpenSim.DataStore.MonoSqlite | |||
764 | { | 854 | { |
765 | string createPrims = defineTable(createPrimTable()); | 855 | string createPrims = defineTable(createPrimTable()); |
766 | string createShapes = defineTable(createShapeTable()); | 856 | string createShapes = defineTable(createShapeTable()); |
857 | string createTerrain = defineTable(createTerrainTable()); | ||
767 | 858 | ||
768 | SqliteCommand pcmd = new SqliteCommand(createPrims, conn); | 859 | SqliteCommand pcmd = new SqliteCommand(createPrims, conn); |
769 | SqliteCommand scmd = new SqliteCommand(createShapes, conn); | 860 | SqliteCommand scmd = new SqliteCommand(createShapes, conn); |
861 | SqliteCommand tcmd = new SqliteCommand(createTerrain, conn); | ||
770 | conn.Open(); | 862 | conn.Open(); |
771 | pcmd.ExecuteNonQuery(); | 863 | pcmd.ExecuteNonQuery(); |
772 | scmd.ExecuteNonQuery(); | 864 | scmd.ExecuteNonQuery(); |
865 | tcmd.ExecuteNonQuery(); | ||
773 | conn.Close(); | 866 | conn.Close(); |
774 | } | 867 | } |
775 | 868 | ||
@@ -779,12 +872,15 @@ namespace OpenSim.DataStore.MonoSqlite | |||
779 | SqliteDataAdapter pDa = new SqliteDataAdapter(primSelectCmd); | 872 | SqliteDataAdapter pDa = new SqliteDataAdapter(primSelectCmd); |
780 | SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, conn); | 873 | SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, conn); |
781 | SqliteDataAdapter sDa = new SqliteDataAdapter(shapeSelectCmd); | 874 | SqliteDataAdapter sDa = new SqliteDataAdapter(shapeSelectCmd); |
875 | SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn); | ||
876 | SqliteDataAdapter tDa = new SqliteDataAdapter(terrainSelectCmd); | ||
782 | 877 | ||
783 | DataSet tmpDS = new DataSet(); | 878 | DataSet tmpDS = new DataSet(); |
784 | try | 879 | try |
785 | { | 880 | { |
786 | pDa.Fill(tmpDS, "prims"); | 881 | pDa.Fill(tmpDS, "prims"); |
787 | sDa.Fill(tmpDS, "primshapes"); | 882 | sDa.Fill(tmpDS, "primshapes"); |
883 | tDa.Fill(tmpDS, "terrain"); | ||
788 | } | 884 | } |
789 | catch (Mono.Data.SqliteClient.SqliteSyntaxException) | 885 | catch (Mono.Data.SqliteClient.SqliteSyntaxException) |
790 | { | 886 | { |
@@ -794,6 +890,7 @@ namespace OpenSim.DataStore.MonoSqlite | |||
794 | 890 | ||
795 | pDa.Fill(tmpDS, "prims"); | 891 | pDa.Fill(tmpDS, "prims"); |
796 | sDa.Fill(tmpDS, "primshapes"); | 892 | sDa.Fill(tmpDS, "primshapes"); |
893 | tDa.Fill(tmpDS, "terrain"); | ||
797 | 894 | ||
798 | foreach (DataColumn col in createPrimTable().Columns) | 895 | foreach (DataColumn col in createPrimTable().Columns) |
799 | { | 896 | { |
@@ -811,6 +908,14 @@ namespace OpenSim.DataStore.MonoSqlite | |||
811 | return false; | 908 | return false; |
812 | } | 909 | } |
813 | } | 910 | } |
911 | foreach (DataColumn col in createTerrainTable().Columns) | ||
912 | { | ||
913 | if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName)) | ||
914 | { | ||
915 | MainLog.Instance.Verbose("DATASTORE", "Missing require column:" + col.ColumnName); | ||
916 | return false; | ||
917 | } | ||
918 | } | ||
814 | return true; | 919 | return true; |
815 | } | 920 | } |
816 | 921 | ||
@@ -834,6 +939,14 @@ namespace OpenSim.DataStore.MonoSqlite | |||
834 | { | 939 | { |
835 | return DbType.Double; | 940 | return DbType.Double; |
836 | } | 941 | } |
942 | else if (type == typeof(System.Byte)) | ||
943 | { | ||
944 | return DbType.Byte; | ||
945 | } | ||
946 | else if (type == typeof(System.Double)) | ||
947 | { | ||
948 | return DbType.Double; | ||
949 | } | ||
837 | else if (type == typeof(System.Byte[])) | 950 | else if (type == typeof(System.Byte[])) |
838 | { | 951 | { |
839 | return DbType.Binary; | 952 | return DbType.Binary; |