aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Storage
diff options
context:
space:
mode:
authorSean Dague2007-08-23 15:16:53 +0000
committerSean Dague2007-08-23 15:16:53 +0000
commit8c9f006dd322ba3ef053949040d5ac86ce363c95 (patch)
tree2b411cade3501e125f0013e304e0fef6cdb13063 /OpenSim/Region/Storage
parentremove this sqlite file as the database is actually autogenerated (diff)
downloadopensim-SC_OLD-8c9f006dd322ba3ef053949040d5ac86ce363c95.zip
opensim-SC_OLD-8c9f006dd322ba3ef053949040d5ac86ce363c95.tar.gz
opensim-SC_OLD-8c9f006dd322ba3ef053949040d5ac86ce363c95.tar.bz2
opensim-SC_OLD-8c9f006dd322ba3ef053949040d5ac86ce363c95.tar.xz
grouping of functions to make the overall logic easier to grasp for people,
and start to show how this can be super classed with some common elements.
Diffstat (limited to 'OpenSim/Region/Storage')
-rw-r--r--OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs743
1 files changed, 394 insertions, 349 deletions
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
index fb4f53f..87df8fb 100644
--- a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
+++ b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
@@ -31,6 +31,11 @@ namespace OpenSim.DataStore.MonoSqliteStorage
31 private SqliteDataAdapter primDa; 31 private SqliteDataAdapter primDa;
32 private SqliteDataAdapter shapeDa; 32 private SqliteDataAdapter shapeDa;
33 33
34 /***********************************************************************
35 *
36 * Public Interface Functions
37 *
38 **********************************************************************/
34 public void Initialise(string dbfile, string dbname) 39 public void Initialise(string dbfile, string dbname)
35 { 40 {
36 string connectionString = "URI=file:" + dbfile + ",version=3"; 41 string connectionString = "URI=file:" + dbfile + ",version=3";
@@ -65,129 +70,276 @@ namespace OpenSim.DataStore.MonoSqliteStorage
65 return; 70 return;
66 } 71 }
67 72
68 ///<summary> 73 public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID)
69 /// This is a convenience function that collapses 5 repetitive
70 /// lines for defining SqliteParameters to 2 parameters:
71 /// column name and database type.
72 ///
73 /// It assumes certain conventions like :param as the param
74 /// name to replace in parametrized queries, and that source
75 /// version is always current version, both of which are fine
76 /// for us.
77 ///</summary>
78 ///<returns>a built sqlite parameter</returns>
79 private SqliteParameter createSqliteParameter(string name, System.Type type)
80 { 74 {
81 SqliteParameter param = new SqliteParameter(); 75 foreach (SceneObjectPart prim in obj.Children.Values)
82 param.ParameterName = ":" + name; 76 {
83 param.DbType = dbtypeFromType(type); 77 addPrim(prim, obj.UUID);
84 param.SourceColumn = name; 78 }
85 param.SourceVersion = DataRowVersion.Current; 79
86 return param; 80 // MainLog.Instance.Verbose("Attempting to do database update....");
81 primDa.Update(ds, "prims");
82 shapeDa.Update(ds, "primshapes");
83 // MainLog.Instance.Verbose("Dump of prims:", ds.GetXml());
87 } 84 }
88 85
89 private DbType dbtypeFromType(Type type) 86 public void RemoveObject(LLUUID obj, LLUUID regionUUID)
90 { 87 {
91 if (type == typeof(System.String)) { 88 DataTable prims = ds.Tables["prims"];
92 return DbType.String; 89 DataTable shapes = ds.Tables["primshapes"];
93 } else if (type == typeof(System.Int32)) { 90
94 return DbType.Int32; 91 string selectExp = "SceneGroupID = '" + obj.ToString() + "'";
95 } else if (type == typeof(System.Double)) { 92 DataRow[] primRows = prims.Select(selectExp);
96 return DbType.Double; 93 foreach (DataRow row in primRows)
97 } else if (type == typeof(System.Byte[])) { 94 {
98 return DbType.Binary; 95 LLUUID uuid = new LLUUID((string)row["UUID"]);
99 } else { 96 DataRow shapeRow = shapes.Rows.Find(uuid);
100 return DbType.String; 97 if (shapeRow != null)
98 {
99 shapeRow.Delete();
100 }
101 row.Delete();
101 } 102 }
103
104 primDa.Update(ds, "prims");
105 shapeDa.Update(ds, "primshapes");
102 } 106 }
103 107
104 private SqliteCommand createInsertCommand(string table, DataTable dt) 108 public List<SceneObjectGroup> LoadObjects(LLUUID regionUUID)
105 { 109 {
106 /** 110 Dictionary<LLUUID, SceneObjectGroup> createdObjects = new Dictionary<LLUUID, SceneObjectGroup>();
107 * This is subtle enough to deserve some commentary. 111 List<SceneObjectGroup> retvals = new List<SceneObjectGroup>();
108 * Instead of doing *lots* and *lots of hardcoded strings
109 * for database definitions we'll use the fact that
110 * realistically all insert statements look like "insert
111 * into A(b, c) values(:b, :c) on the parameterized query
112 * front. If we just have a list of b, c, etc... we can
113 * generate these strings instead of typing them out.
114 */
115 string[] cols = new string[dt.Columns.Count];
116 for (int i = 0; i < dt.Columns.Count; i++) {
117 DataColumn col = dt.Columns[i];
118 cols[i] = col.ColumnName;
119 }
120 112
121 string sql = "insert into " + table + "("; 113 DataTable prims = ds.Tables["prims"];
122 sql += String.Join(", ", cols); 114 DataTable shapes = ds.Tables["primshapes"];
123 // important, the first ':' needs to be here, the rest get added in the join
124 sql += ") values (:";
125 sql += String.Join(", :", cols);
126 sql += ")";
127 SqliteCommand cmd = new SqliteCommand(sql);
128 115
129 // this provides the binding for all our parameters, so 116 foreach (DataRow primRow in prims.Rows)
130 // much less code than it used to be
131 foreach (DataColumn col in dt.Columns)
132 { 117 {
133 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); 118 string uuid = (string)primRow["UUID"];
119 string objID = (string)primRow["SceneGroupID"];
120 if (uuid == objID) //is new SceneObjectGroup ?
121 {
122 SceneObjectGroup group = new SceneObjectGroup();
123 SceneObjectPart prim = buildPrim(primRow);
124 DataRow shapeRow = shapes.Rows.Find(prim.UUID);
125 if (shapeRow != null)
126 {
127 prim.Shape = buildShape(shapeRow);
128 }
129 else
130 {
131 Console.WriteLine("No shape found for prim in storage, so setting default box shape");
132 prim.Shape = BoxShape.Default;
133 }
134 group.AddPart(prim);
135 group.RootPart = prim;
136
137 createdObjects.Add(group.UUID, group);
138 retvals.Add(group);
139 }
140 else
141 {
142 SceneObjectPart prim = buildPrim(primRow);
143 DataRow shapeRow = shapes.Rows.Find(prim.UUID);
144 if (shapeRow != null)
145 {
146 prim.Shape = buildShape(shapeRow);
147 }
148 else
149 {
150 Console.WriteLine("No shape found for prim in storage, so setting default box shape");
151 prim.Shape = BoxShape.Default;
152 }
153 createdObjects[new LLUUID(objID)].AddPart(prim);
154 }
134 } 155 }
135 return cmd; 156
157 MainLog.Instance.Verbose("DATASTORE", "Sqlite - LoadObjects found " + prims.Rows.Count + " primitives");
158
159 return retvals;
136 } 160 }
137 161
138 private SqliteCommand createUpdateCommand(string table, string pk, DataTable dt) 162 public void StoreTerrain(double[,] ter)
139 { 163 {
140 string sql = "update " + table + " set "; 164
141 string subsql = ""; 165 }
142 foreach (DataColumn col in dt.Columns) 166
167 public double[,] LoadTerrain()
168 {
169 return null;
170 }
171
172 public void RemoveLandObject(uint id)
173 {
174
175 }
176
177 public void StoreParcel(Land parcel)
178 {
179
180 }
181
182 public List<Land> LoadLandObjects()
183 {
184 return new List<Land>();
185 }
186
187 public void Shutdown()
188 {
189 // TODO: DataSet commit
190 }
191
192 public class TextureBlock
193 {
194 public byte[] TextureData;
195 public byte[] ExtraParams = new byte[1];
196
197 public TextureBlock(byte[] data)
143 { 198 {
144 if (subsql.Length > 0) 199 TextureData = data;
145 { // a map function would rock so much here
146 subsql += ", ";
147 }
148 subsql += col.ColumnName + "= :" + col.ColumnName;
149 } 200 }
150 sql += subsql;
151 sql += " where " + pk;
152 SqliteCommand cmd = new SqliteCommand(sql);
153 201
154 // this provides the binding for all our parameters, so 202 public TextureBlock()
155 // much less code than it used to be 203 {
156 204
157 foreach (DataColumn col in dt.Columns) 205 }
206
207 public string ToXMLString()
158 { 208 {
159 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); 209 StringWriter sw = new StringWriter();
210 XmlTextWriter writer = new XmlTextWriter(sw);
211 XmlSerializer serializer = new XmlSerializer(typeof(TextureBlock));
212 serializer.Serialize(writer, this);
213 return sw.ToString();
214 }
215
216 public static TextureBlock FromXmlString(string xmlData)
217 {
218 TextureBlock textureEntry = null;
219 StringReader sr = new StringReader(xmlData);
220 XmlTextReader reader = new XmlTextReader(sr);
221 XmlSerializer serializer = new XmlSerializer(typeof(TextureBlock));
222 textureEntry = (TextureBlock)serializer.Deserialize(reader);
223 reader.Close();
224 sr.Close();
225 return textureEntry;
160 } 226 }
161 return cmd;
162 } 227 }
163 228
164 private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn) 229 /***********************************************************************
230 *
231 * Database Definition Functions
232 *
233 * This should be db agnostic as we define them in ADO.NET terms
234 *
235 **********************************************************************/
236
237 private void createCol(DataTable dt, string name, System.Type type)
165 { 238 {
166 da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]); 239 DataColumn col = new DataColumn(name, type);
167 da.InsertCommand.Connection = conn; 240 dt.Columns.Add(col);
241 }
168 242
169 da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]); 243 private DataTable createPrimTable()
170 da.UpdateCommand.Connection = conn; 244 {
245 DataTable prims = new DataTable("prims");
171 246
172 SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID"); 247 createCol(prims, "UUID", typeof(System.String));
173 delete.Parameters.Add(createSqliteParameter("UUID", typeof(System.String))); 248 createCol(prims, "ParentID", typeof(System.Int32));
174 delete.Connection = conn; 249 createCol(prims, "CreationDate", typeof(System.Int32));
175 da.DeleteCommand = delete; 250 createCol(prims, "Name", typeof(System.String));
251 createCol(prims, "SceneGroupID", typeof(System.String));
252 // various text fields
253 createCol(prims, "Text", typeof(System.String));
254 createCol(prims, "Description", typeof(System.String));
255 createCol(prims, "SitName", typeof(System.String));
256 createCol(prims, "TouchName", typeof(System.String));
257 // permissions
258 createCol(prims, "CreatorID", typeof(System.String));
259 createCol(prims, "OwnerID", typeof(System.String));
260 createCol(prims, "GroupID", typeof(System.String));
261 createCol(prims, "LastOwnerID", typeof(System.String));
262 createCol(prims, "OwnerMask", typeof(System.Int32));
263 createCol(prims, "NextOwnerMask", typeof(System.Int32));
264 createCol(prims, "GroupMask", typeof(System.Int32));
265 createCol(prims, "EveryoneMask", typeof(System.Int32));
266 createCol(prims, "BaseMask", typeof(System.Int32));
267 // vectors
268 createCol(prims, "PositionX", typeof(System.Double));
269 createCol(prims, "PositionY", typeof(System.Double));
270 createCol(prims, "PositionZ", typeof(System.Double));
271 createCol(prims, "GroupPositionX", typeof(System.Double));
272 createCol(prims, "GroupPositionY", typeof(System.Double));
273 createCol(prims, "GroupPositionZ", typeof(System.Double));
274 createCol(prims, "VelocityX", typeof(System.Double));
275 createCol(prims, "VelocityY", typeof(System.Double));
276 createCol(prims, "VelocityZ", typeof(System.Double));
277 createCol(prims, "AngularVelocityX", typeof(System.Double));
278 createCol(prims, "AngularVelocityY", typeof(System.Double));
279 createCol(prims, "AngularVelocityZ", typeof(System.Double));
280 createCol(prims, "AccelerationX", typeof(System.Double));
281 createCol(prims, "AccelerationY", typeof(System.Double));
282 createCol(prims, "AccelerationZ", typeof(System.Double));
283 // quaternions
284 createCol(prims, "RotationX", typeof(System.Double));
285 createCol(prims, "RotationY", typeof(System.Double));
286 createCol(prims, "RotationZ", typeof(System.Double));
287 createCol(prims, "RotationW", typeof(System.Double));
288
289 // Add in contraints
290 prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] };
291
292 return prims;
176 } 293 }
177 294
178 private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn) 295 private DataTable createShapeTable()
179 { 296 {
180 da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]); 297 DataTable shapes = new DataTable("primshapes");
181 da.InsertCommand.Connection = conn; 298 createCol(shapes, "UUID", typeof(System.String));
299 // shape is an enum
300 createCol(shapes, "Shape", typeof(System.Int32));
301 // vectors
302 createCol(shapes, "ScaleX", typeof(System.Double));
303 createCol(shapes, "ScaleY", typeof(System.Double));
304 createCol(shapes, "ScaleZ", typeof(System.Double));
305 // paths
306 createCol(shapes, "PCode", typeof(System.Int32));
307 createCol(shapes, "PathBegin", typeof(System.Int32));
308 createCol(shapes, "PathEnd", typeof(System.Int32));
309 createCol(shapes, "PathScaleX", typeof(System.Int32));
310 createCol(shapes, "PathScaleY", typeof(System.Int32));
311 createCol(shapes, "PathShearX", typeof(System.Int32));
312 createCol(shapes, "PathShearY", typeof(System.Int32));
313 createCol(shapes, "PathSkew", typeof(System.Int32));
314 createCol(shapes, "PathCurve", typeof(System.Int32));
315 createCol(shapes, "PathRadiusOffset", typeof(System.Int32));
316 createCol(shapes, "PathRevolutions", typeof(System.Int32));
317 createCol(shapes, "PathTaperX", typeof(System.Int32));
318 createCol(shapes, "PathTaperY", typeof(System.Int32));
319 createCol(shapes, "PathTwist", typeof(System.Int32));
320 createCol(shapes, "PathTwistBegin", typeof(System.Int32));
321 // profile
322 createCol(shapes, "ProfileBegin", typeof(System.Int32));
323 createCol(shapes, "ProfileEnd", typeof(System.Int32));
324 createCol(shapes, "ProfileCurve", typeof(System.Int32));
325 createCol(shapes, "ProfileHollow", typeof(System.Int32));
326 // text TODO: this isn't right, but I'm not sure the right
327 // way to specify this as a blob atm
328 createCol(shapes, "Texture", typeof(System.Byte[]));
329 createCol(shapes, "ExtraParams", typeof(System.Byte[]));
182 330
183 da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", ds.Tables["primshapes"]); 331 shapes.PrimaryKey = new DataColumn[] { shapes.Columns["UUID"] };
184 da.UpdateCommand.Connection = conn;
185 332
186 SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID"); 333 return shapes;
187 delete.Parameters.Add(createSqliteParameter("UUID", typeof(System.String)));
188 delete.Connection = conn;
189 da.DeleteCommand = delete;
190 } 334 }
335
336 /***********************************************************************
337 *
338 * Convert between ADO.NET <=> OpenSim Objects
339 *
340 * These should be database independant
341 *
342 **********************************************************************/
191 343
192 private SceneObjectPart buildPrim(DataRow row) 344 private SceneObjectPart buildPrim(DataRow row)
193 { 345 {
@@ -424,163 +576,157 @@ namespace OpenSim.DataStore.MonoSqliteStorage
424 fillShapeRow(shapeRow, prim); 576 fillShapeRow(shapeRow, prim);
425 } 577 }
426 } 578 }
579
580 /***********************************************************************
581 *
582 * SQL Statement Creation Functions
583 *
584 * These functions create SQL statements for update, insert, and create.
585 * They can probably be factored later to have a db independant
586 * portion and a db specific portion
587 *
588 **********************************************************************/
427 589
428 public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) 590 private SqliteCommand createInsertCommand(string table, DataTable dt)
429 { 591 {
430 foreach (SceneObjectPart prim in obj.Children.Values) 592 /**
431 { 593 * This is subtle enough to deserve some commentary.
432 addPrim(prim, obj.UUID); 594 * Instead of doing *lots* and *lots of hardcoded strings
595 * for database definitions we'll use the fact that
596 * realistically all insert statements look like "insert
597 * into A(b, c) values(:b, :c) on the parameterized query
598 * front. If we just have a list of b, c, etc... we can
599 * generate these strings instead of typing them out.
600 */
601 string[] cols = new string[dt.Columns.Count];
602 for (int i = 0; i < dt.Columns.Count; i++) {
603 DataColumn col = dt.Columns[i];
604 cols[i] = col.ColumnName;
433 } 605 }
434 606
435 // MainLog.Instance.Verbose("Attempting to do database update...."); 607 string sql = "insert into " + table + "(";
436 primDa.Update(ds, "prims"); 608 sql += String.Join(", ", cols);
437 shapeDa.Update(ds, "primshapes"); 609 // important, the first ':' needs to be here, the rest get added in the join
438 // MainLog.Instance.Verbose("Dump of prims:", ds.GetXml()); 610 sql += ") values (:";
611 sql += String.Join(", :", cols);
612 sql += ")";
613 SqliteCommand cmd = new SqliteCommand(sql);
614
615 // this provides the binding for all our parameters, so
616 // much less code than it used to be
617 foreach (DataColumn col in dt.Columns)
618 {
619 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
620 }
621 return cmd;
439 } 622 }
440 623
441 public void RemoveObject(LLUUID obj, LLUUID regionUUID) 624 private SqliteCommand createUpdateCommand(string table, string pk, DataTable dt)
442 { 625 {
443 DataTable prims = ds.Tables["prims"]; 626 string sql = "update " + table + " set ";
444 DataTable shapes = ds.Tables["primshapes"]; 627 string subsql = "";
445 628 foreach (DataColumn col in dt.Columns)
446 string selectExp = "SceneGroupID = '" + obj.ToString() + "'";
447 DataRow[] primRows = prims.Select(selectExp);
448 foreach (DataRow row in primRows)
449 { 629 {
450 LLUUID uuid = new LLUUID((string)row["UUID"]); 630 if (subsql.Length > 0)
451 DataRow shapeRow = shapes.Rows.Find(uuid); 631 { // a map function would rock so much here
452 if (shapeRow != null) 632 subsql += ", ";
453 {
454 shapeRow.Delete();
455 } 633 }
456 row.Delete(); 634 subsql += col.ColumnName + "= :" + col.ColumnName;
457 } 635 }
636 sql += subsql;
637 sql += " where " + pk;
638 SqliteCommand cmd = new SqliteCommand(sql);
458 639
459 primDa.Update(ds, "prims"); 640 // this provides the binding for all our parameters, so
460 shapeDa.Update(ds, "primshapes"); 641 // much less code than it used to be
642
643 foreach (DataColumn col in dt.Columns)
644 {
645 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
646 }
647 return cmd;
461 } 648 }
462 649
463 public List<SceneObjectGroup> LoadObjects(LLUUID regionUUID)
464 {
465 Dictionary<LLUUID, SceneObjectGroup> createdObjects = new Dictionary<LLUUID, SceneObjectGroup>();
466 List<SceneObjectGroup> retvals = new List<SceneObjectGroup>();
467 650
468 DataTable prims = ds.Tables["prims"]; 651 private string defineTable(DataTable dt)
469 DataTable shapes = ds.Tables["primshapes"]; 652 {
470 653 string sql = "create table " + dt.TableName + "(";
471 foreach (DataRow primRow in prims.Rows) 654 string subsql = "";
655 foreach (DataColumn col in dt.Columns)
472 { 656 {
473 string uuid = (string)primRow["UUID"]; 657 if (subsql.Length > 0)
474 string objID = (string)primRow["SceneGroupID"]; 658 { // a map function would rock so much here
475 if (uuid == objID) //is new SceneObjectGroup ? 659 subsql += ",\n";
476 {
477 SceneObjectGroup group = new SceneObjectGroup();
478 SceneObjectPart prim = buildPrim(primRow);
479 DataRow shapeRow = shapes.Rows.Find(prim.UUID);
480 if (shapeRow != null)
481 {
482 prim.Shape = buildShape(shapeRow);
483 }
484 else
485 {
486 Console.WriteLine("No shape found for prim in storage, so setting default box shape");
487 prim.Shape = BoxShape.Default;
488 }
489 group.AddPart(prim);
490 group.RootPart = prim;
491
492 createdObjects.Add(group.UUID, group);
493 retvals.Add(group);
494 } 660 }
495 else 661 subsql += col.ColumnName + " " + sqliteType(col.DataType);
662 if(col == dt.PrimaryKey[0])
496 { 663 {
497 SceneObjectPart prim = buildPrim(primRow); 664 subsql += " primary key";
498 DataRow shapeRow = shapes.Rows.Find(prim.UUID);
499 if (shapeRow != null)
500 {
501 prim.Shape = buildShape(shapeRow);
502 }
503 else
504 {
505 Console.WriteLine("No shape found for prim in storage, so setting default box shape");
506 prim.Shape = BoxShape.Default;
507 }
508 createdObjects[new LLUUID(objID)].AddPart(prim);
509 } 665 }
510 } 666 }
511 667 sql += subsql;
512 MainLog.Instance.Verbose("DATASTORE", "Sqlite - LoadObjects found " + prims.Rows.Count + " primitives"); 668 sql += ")";
513 669 return sql;
514 return retvals;
515 }
516
517 public void StoreTerrain(double[,] ter)
518 {
519
520 } 670 }
521 671
522 public double[,] LoadTerrain() 672 /***********************************************************************
523 { 673 *
524 return null; 674 * Database Binding functions
525 } 675 *
676 * These will be db specific due to typing, and minor differences
677 * in databases.
678 *
679 **********************************************************************/
526 680
527 public void RemoveLandObject(uint id) 681 ///<summary>
682 /// This is a convenience function that collapses 5 repetitive
683 /// lines for defining SqliteParameters to 2 parameters:
684 /// column name and database type.
685 ///
686 /// It assumes certain conventions like :param as the param
687 /// name to replace in parametrized queries, and that source
688 /// version is always current version, both of which are fine
689 /// for us.
690 ///</summary>
691 ///<returns>a built sqlite parameter</returns>
692 private SqliteParameter createSqliteParameter(string name, System.Type type)
528 { 693 {
529 694 SqliteParameter param = new SqliteParameter();
695 param.ParameterName = ":" + name;
696 param.DbType = dbtypeFromType(type);
697 param.SourceColumn = name;
698 param.SourceVersion = DataRowVersion.Current;
699 return param;
530 } 700 }
531 701
532 public void StoreParcel(Land parcel) 702 private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn)
533 { 703 {
704 da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]);
705 da.InsertCommand.Connection = conn;
534 706
535 } 707 da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]);
536 708 da.UpdateCommand.Connection = conn;
537 public List<Land> LoadLandObjects()
538 {
539 return new List<Land>();
540 }
541 709
542 public void Shutdown() 710 SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID");
543 { 711 delete.Parameters.Add(createSqliteParameter("UUID", typeof(System.String)));
544 // TODO: DataSet commit 712 delete.Connection = conn;
713 da.DeleteCommand = delete;
545 } 714 }
546 715
547 public class TextureBlock 716 private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn)
548 { 717 {
549 public byte[] TextureData; 718 da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]);
550 public byte[] ExtraParams = new byte[1]; 719 da.InsertCommand.Connection = conn;
551
552 public TextureBlock(byte[] data)
553 {
554 TextureData = data;
555 }
556
557 public TextureBlock()
558 {
559
560 }
561 720
562 public string ToXMLString() 721 da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", ds.Tables["primshapes"]);
563 { 722 da.UpdateCommand.Connection = conn;
564 StringWriter sw = new StringWriter();
565 XmlTextWriter writer = new XmlTextWriter(sw);
566 XmlSerializer serializer = new XmlSerializer(typeof(TextureBlock));
567 serializer.Serialize(writer, this);
568 return sw.ToString();
569 }
570 723
571 public static TextureBlock FromXmlString(string xmlData) 724 SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID");
572 { 725 delete.Parameters.Add(createSqliteParameter("UUID", typeof(System.String)));
573 TextureBlock textureEntry = null; 726 delete.Connection = conn;
574 StringReader sr = new StringReader(xmlData); 727 da.DeleteCommand = delete;
575 XmlTextReader reader = new XmlTextReader(sr);
576 XmlSerializer serializer = new XmlSerializer(typeof(TextureBlock));
577 textureEntry = (TextureBlock)serializer.Deserialize(reader);
578 reader.Close();
579 sr.Close();
580 return textureEntry;
581 }
582 } 728 }
583 729
584 private void InitDB(SqliteConnection conn) 730 private void InitDB(SqliteConnection conn)
585 { 731 {
586 string createPrims = defineTable(createPrimTable()); 732 string createPrims = defineTable(createPrimTable());
@@ -594,42 +740,6 @@ namespace OpenSim.DataStore.MonoSqliteStorage
594 conn.Close(); 740 conn.Close();
595 } 741 }
596 742
597 private string defineTable(DataTable dt)
598 {
599 string sql = "create table " + dt.TableName + "(";
600 string subsql = "";
601 foreach (DataColumn col in dt.Columns)
602 {
603 if (subsql.Length > 0)
604 { // a map function would rock so much here
605 subsql += ",\n";
606 }
607 subsql += col.ColumnName + " " + sqliteType(col.DataType);
608 if(col == dt.PrimaryKey[0])
609 {
610 subsql += " primary key";
611 }
612 }
613 sql += subsql;
614 sql += ")";
615 return sql;
616 }
617
618 private string sqliteType(Type type)
619 {
620 if (type == typeof(System.String)) {
621 return "varchar(255)";
622 } else if (type == typeof(System.Int32)) {
623 return "integer";
624 } else if (type == typeof(System.Double)) {
625 return "float";
626 } else if (type == typeof(System.Byte[])) {
627 return "blob";
628 } else {
629 return "string";
630 }
631 }
632
633 private bool TestTables(SqliteConnection conn) 743 private bool TestTables(SqliteConnection conn)
634 { 744 {
635 SqliteCommand primSelectCmd = new SqliteCommand(primSelect, conn); 745 SqliteCommand primSelectCmd = new SqliteCommand(primSelect, conn);
@@ -664,107 +774,42 @@ namespace OpenSim.DataStore.MonoSqliteStorage
664 return true; 774 return true;
665 } 775 }
666 776
667 /// Methods after this point are big data definition 777 /***********************************************************************
668 /// methods, and aren't really interesting unless you are 778 *
669 /// adjusting the schema. 779 * Type conversion functions
670 780 *
671 private void createCol(DataTable dt, string name, System.Type type) 781 **********************************************************************/
672 { 782
673 DataColumn col = new DataColumn(name, type); 783 private DbType dbtypeFromType(Type type)
674 dt.Columns.Add(col);
675 }
676
677 private DataTable createPrimTable()
678 { 784 {
679 DataTable prims = new DataTable("prims"); 785 if (type == typeof(System.String)) {
680 786 return DbType.String;
681 createCol(prims, "UUID", typeof(System.String)); 787 } else if (type == typeof(System.Int32)) {
682 createCol(prims, "ParentID", typeof(System.Int32)); 788 return DbType.Int32;
683 createCol(prims, "CreationDate", typeof(System.Int32)); 789 } else if (type == typeof(System.Double)) {
684 createCol(prims, "Name", typeof(System.String)); 790 return DbType.Double;
685 createCol(prims, "SceneGroupID", typeof(System.String)); 791 } else if (type == typeof(System.Byte[])) {
686 // various text fields 792 return DbType.Binary;
687 createCol(prims, "Text", typeof(System.String)); 793 } else {
688 createCol(prims, "Description", typeof(System.String)); 794 return DbType.String;
689 createCol(prims, "SitName", typeof(System.String)); 795 }
690 createCol(prims, "TouchName", typeof(System.String));
691 // permissions
692 createCol(prims, "CreatorID", typeof(System.String));
693 createCol(prims, "OwnerID", typeof(System.String));
694 createCol(prims, "GroupID", typeof(System.String));
695 createCol(prims, "LastOwnerID", typeof(System.String));
696 createCol(prims, "OwnerMask", typeof(System.Int32));
697 createCol(prims, "NextOwnerMask", typeof(System.Int32));
698 createCol(prims, "GroupMask", typeof(System.Int32));
699 createCol(prims, "EveryoneMask", typeof(System.Int32));
700 createCol(prims, "BaseMask", typeof(System.Int32));
701 // vectors
702 createCol(prims, "PositionX", typeof(System.Double));
703 createCol(prims, "PositionY", typeof(System.Double));
704 createCol(prims, "PositionZ", typeof(System.Double));
705 createCol(prims, "GroupPositionX", typeof(System.Double));
706 createCol(prims, "GroupPositionY", typeof(System.Double));
707 createCol(prims, "GroupPositionZ", typeof(System.Double));
708 createCol(prims, "VelocityX", typeof(System.Double));
709 createCol(prims, "VelocityY", typeof(System.Double));
710 createCol(prims, "VelocityZ", typeof(System.Double));
711 createCol(prims, "AngularVelocityX", typeof(System.Double));
712 createCol(prims, "AngularVelocityY", typeof(System.Double));
713 createCol(prims, "AngularVelocityZ", typeof(System.Double));
714 createCol(prims, "AccelerationX", typeof(System.Double));
715 createCol(prims, "AccelerationY", typeof(System.Double));
716 createCol(prims, "AccelerationZ", typeof(System.Double));
717 // quaternions
718 createCol(prims, "RotationX", typeof(System.Double));
719 createCol(prims, "RotationY", typeof(System.Double));
720 createCol(prims, "RotationZ", typeof(System.Double));
721 createCol(prims, "RotationW", typeof(System.Double));
722
723 // Add in contraints
724 prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] };
725
726 return prims;
727 } 796 }
728 797
729 private DataTable createShapeTable() 798 // this is something we'll need to implement for each db
799 // slightly differently.
800 private string sqliteType(Type type)
730 { 801 {
731 DataTable shapes = new DataTable("primshapes"); 802 if (type == typeof(System.String)) {
732 createCol(shapes, "UUID", typeof(System.String)); 803 return "varchar(255)";
733 // shape is an enum 804 } else if (type == typeof(System.Int32)) {
734 createCol(shapes, "Shape", typeof(System.Int32)); 805 return "integer";
735 // vectors 806 } else if (type == typeof(System.Double)) {
736 createCol(shapes, "ScaleX", typeof(System.Double)); 807 return "float";
737 createCol(shapes, "ScaleY", typeof(System.Double)); 808 } else if (type == typeof(System.Byte[])) {
738 createCol(shapes, "ScaleZ", typeof(System.Double)); 809 return "blob";
739 // paths 810 } else {
740 createCol(shapes, "PCode", typeof(System.Int32)); 811 return "string";
741 createCol(shapes, "PathBegin", typeof(System.Int32)); 812 }
742 createCol(shapes, "PathEnd", typeof(System.Int32));
743 createCol(shapes, "PathScaleX", typeof(System.Int32));
744 createCol(shapes, "PathScaleY", typeof(System.Int32));
745 createCol(shapes, "PathShearX", typeof(System.Int32));
746 createCol(shapes, "PathShearY", typeof(System.Int32));
747 createCol(shapes, "PathSkew", typeof(System.Int32));
748 createCol(shapes, "PathCurve", typeof(System.Int32));
749 createCol(shapes, "PathRadiusOffset", typeof(System.Int32));
750 createCol(shapes, "PathRevolutions", typeof(System.Int32));
751 createCol(shapes, "PathTaperX", typeof(System.Int32));
752 createCol(shapes, "PathTaperY", typeof(System.Int32));
753 createCol(shapes, "PathTwist", typeof(System.Int32));
754 createCol(shapes, "PathTwistBegin", typeof(System.Int32));
755 // profile
756 createCol(shapes, "ProfileBegin", typeof(System.Int32));
757 createCol(shapes, "ProfileEnd", typeof(System.Int32));
758 createCol(shapes, "ProfileCurve", typeof(System.Int32));
759 createCol(shapes, "ProfileHollow", typeof(System.Int32));
760 // text TODO: this isn't right, but I'm not sure the right
761 // way to specify this as a blob atm
762 createCol(shapes, "Texture", typeof(System.Byte[]));
763 createCol(shapes, "ExtraParams", typeof(System.Byte[]));
764
765 shapes.PrimaryKey = new DataColumn[] { shapes.Columns["UUID"] };
766
767 return shapes;
768 } 813 }
769 } 814 }
770} 815}