clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Collections.Generic;
30 using System.Data;
31 using System.Drawing;
32 using System.IO;
33 using System.Reflection;
34 using log4net;
35 #if CSharpSqlite
36 using Community.CsharpSqlite.Sqlite;
37 #else
38 using Mono.Data.Sqlite;
39 #endif
40 using OpenMetaverse;
41 using OpenMetaverse.StructuredData;
42 using OpenSim.Framework;
43 using OpenSim.Region.Framework.Interfaces;
44 using OpenSim.Region.Framework.Scenes;
45  
46 namespace OpenSim.Data.SQLite
47 {
48 /// <summary>
49 /// A RegionData Interface to the SQLite database
50 /// </summary>
51 public class SQLiteSimulationData : ISimulationDataStore
52 {
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 private static readonly string LogHeader = "[REGION DB SQLLITE]";
55  
56 private const string primSelect = "select * from prims";
57 private const string shapeSelect = "select * from primshapes";
58 private const string itemsSelect = "select * from primitems";
59 private const string terrainSelect = "select * from terrain limit 1";
60 private const string landSelect = "select * from land";
61 private const string landAccessListSelect = "select distinct * from landaccesslist";
62 private const string regionbanListSelect = "select * from regionban";
63 private const string regionSettingsSelect = "select * from regionsettings";
64 private const string regionWindlightSelect = "select * from regionwindlight";
65 private const string regionEnvironmentSelect = "select * from regionenvironment";
66 private const string regionSpawnPointsSelect = "select * from spawn_points";
67  
68 private DataSet ds;
69 private SqliteDataAdapter primDa;
70 private SqliteDataAdapter shapeDa;
71 private SqliteDataAdapter itemsDa;
72 private SqliteDataAdapter terrainDa;
73 private SqliteDataAdapter landDa;
74 private SqliteDataAdapter landAccessListDa;
75 private SqliteDataAdapter regionSettingsDa;
76 private SqliteDataAdapter regionWindlightDa;
77 private SqliteDataAdapter regionEnvironmentDa;
78 private SqliteDataAdapter regionSpawnPointsDa;
79  
80 private SqliteConnection m_conn;
81 private String m_connectionString;
82  
83 protected virtual Assembly Assembly
84 {
85 get { return GetType().Assembly; }
86 }
87  
88 public SQLiteSimulationData()
89 {
90 }
91  
92 public SQLiteSimulationData(string connectionString)
93 {
94 Initialise(connectionString);
95 }
96  
97 // Temporary attribute while this is experimental
98  
99 /***********************************************************************
100 *
101 * Public Interface Functions
102 *
103 **********************************************************************/
104  
105 /// <summary>
106 /// <list type="bullet">
107 /// <item>Initialises RegionData Interface</item>
108 /// <item>Loads and initialises a new SQLite connection and maintains it.</item>
109 /// </list>
110 /// </summary>
111 /// <param name="connectionString">the connection string</param>
112 public void Initialise(string connectionString)
113 {
114 try
115 {
116 if (Util.IsWindows())
117 Util.LoadArchSpecificWindowsDll("sqlite3.dll");
118  
119 m_connectionString = connectionString;
120  
121 ds = new DataSet("Region");
122  
123 m_log.Info("[SQLITE REGION DB]: Sqlite - connecting: " + connectionString);
124 m_conn = new SqliteConnection(m_connectionString);
125 m_conn.Open();
126  
127 SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn);
128 primDa = new SqliteDataAdapter(primSelectCmd);
129  
130 SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn);
131 shapeDa = new SqliteDataAdapter(shapeSelectCmd);
132 // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa);
133  
134 SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn);
135 itemsDa = new SqliteDataAdapter(itemsSelectCmd);
136  
137 SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn);
138 terrainDa = new SqliteDataAdapter(terrainSelectCmd);
139  
140 SqliteCommand landSelectCmd = new SqliteCommand(landSelect, m_conn);
141 landDa = new SqliteDataAdapter(landSelectCmd);
142  
143 SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, m_conn);
144 landAccessListDa = new SqliteDataAdapter(landAccessListSelectCmd);
145  
146 SqliteCommand regionSettingsSelectCmd = new SqliteCommand(regionSettingsSelect, m_conn);
147 regionSettingsDa = new SqliteDataAdapter(regionSettingsSelectCmd);
148  
149 SqliteCommand regionWindlightSelectCmd = new SqliteCommand(regionWindlightSelect, m_conn);
150 regionWindlightDa = new SqliteDataAdapter(regionWindlightSelectCmd);
151  
152 SqliteCommand regionEnvironmentSelectCmd = new SqliteCommand(regionEnvironmentSelect, m_conn);
153 regionEnvironmentDa = new SqliteDataAdapter(regionEnvironmentSelectCmd);
154  
155 SqliteCommand regionSpawnPointsSelectCmd = new SqliteCommand(regionSpawnPointsSelect, m_conn);
156 regionSpawnPointsDa = new SqliteDataAdapter(regionSpawnPointsSelectCmd);
157  
158 // This actually does the roll forward assembly stuff
159 Migration m = new Migration(m_conn, Assembly, "RegionStore");
160 m.Update();
161  
162 lock (ds)
163 {
164 ds.Tables.Add(createPrimTable());
165 setupPrimCommands(primDa, m_conn);
166  
167 ds.Tables.Add(createShapeTable());
168 setupShapeCommands(shapeDa, m_conn);
169  
170 ds.Tables.Add(createItemsTable());
171 setupItemsCommands(itemsDa, m_conn);
172  
173 ds.Tables.Add(createTerrainTable());
174 setupTerrainCommands(terrainDa, m_conn);
175  
176 ds.Tables.Add(createLandTable());
177 setupLandCommands(landDa, m_conn);
178  
179 ds.Tables.Add(createLandAccessListTable());
180 setupLandAccessCommands(landAccessListDa, m_conn);
181  
182 ds.Tables.Add(createRegionSettingsTable());
183 setupRegionSettingsCommands(regionSettingsDa, m_conn);
184  
185 ds.Tables.Add(createRegionWindlightTable());
186 setupRegionWindlightCommands(regionWindlightDa, m_conn);
187  
188 ds.Tables.Add(createRegionEnvironmentTable());
189 setupRegionEnvironmentCommands(regionEnvironmentDa, m_conn);
190  
191 ds.Tables.Add(createRegionSpawnPointsTable());
192 setupRegionSpawnPointsCommands(regionSpawnPointsDa, m_conn);
193  
194 // WORKAROUND: This is a work around for sqlite on
195 // windows, which gets really unhappy with blob columns
196 // that have no sample data in them. At some point we
197 // need to actually find a proper way to handle this.
198 try
199 {
200 primDa.Fill(ds.Tables["prims"]);
201 }
202 catch (Exception e)
203 {
204 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on prims table :{0}", e.Message);
205 }
206  
207 try
208 {
209 shapeDa.Fill(ds.Tables["primshapes"]);
210 }
211 catch (Exception e)
212 {
213 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on primshapes table :{0}", e.Message);
214 }
215  
216 try
217 {
218 itemsDa.Fill(ds.Tables["primitems"]);
219 }
220 catch (Exception e)
221 {
222 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on primitems table :{0}", e.Message);
223 }
224  
225 try
226 {
227 terrainDa.Fill(ds.Tables["terrain"]);
228 }
229 catch (Exception e)
230 {
231 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on terrain table :{0}", e.Message);
232 }
233  
234 try
235 {
236 landDa.Fill(ds.Tables["land"]);
237 }
238 catch (Exception e)
239 {
240 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on land table :{0}", e.Message);
241 }
242  
243 try
244 {
245 landAccessListDa.Fill(ds.Tables["landaccesslist"]);
246 }
247 catch (Exception e)
248 {
249 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on landaccesslist table :{0}", e.Message);
250 }
251  
252 try
253 {
254 regionSettingsDa.Fill(ds.Tables["regionsettings"]);
255 }
256 catch (Exception e)
257 {
258 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionsettings table :{0}", e.Message);
259 }
260  
261 try
262 {
263 regionWindlightDa.Fill(ds.Tables["regionwindlight"]);
264 }
265 catch (Exception e)
266 {
267 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionwindlight table :{0}", e.Message);
268 }
269  
270 try
271 {
272 regionEnvironmentDa.Fill(ds.Tables["regionenvironment"]);
273 }
274 catch (Exception e)
275 {
276 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionenvironment table :{0}", e.Message);
277 }
278  
279 try
280 {
281 regionSpawnPointsDa.Fill(ds.Tables["spawn_points"]);
282 }
283 catch (Exception e)
284 {
285 m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on spawn_points table :{0}", e.Message);
286 }
287  
288 // We have to create a data set mapping for every table, otherwise the IDataAdaptor.Update() will not populate rows with values!
289 // Not sure exactly why this is - this kind of thing was not necessary before - justincc 20100409
290 // Possibly because we manually set up our own DataTables before connecting to the database
291 CreateDataSetMapping(primDa, "prims");
292 CreateDataSetMapping(shapeDa, "primshapes");
293 CreateDataSetMapping(itemsDa, "primitems");
294 CreateDataSetMapping(terrainDa, "terrain");
295 CreateDataSetMapping(landDa, "land");
296 CreateDataSetMapping(landAccessListDa, "landaccesslist");
297 CreateDataSetMapping(regionSettingsDa, "regionsettings");
298 CreateDataSetMapping(regionWindlightDa, "regionwindlight");
299 CreateDataSetMapping(regionEnvironmentDa, "regionenvironment");
300 CreateDataSetMapping(regionSpawnPointsDa, "spawn_points");
301 }
302 }
303 catch (Exception e)
304 {
305 m_log.ErrorFormat("[SQLITE REGION DB]: {0} - {1}", e.Message, e.StackTrace);
306 Environment.Exit(23);
307 }
308 return;
309 }
310  
311 public void Dispose()
312 {
313 if (m_conn != null)
314 {
315 m_conn.Close();
316 m_conn = null;
317 }
318 if (ds != null)
319 {
320 ds.Dispose();
321 ds = null;
322 }
323 if (primDa != null)
324 {
325 primDa.Dispose();
326 primDa = null;
327 }
328 if (shapeDa != null)
329 {
330 shapeDa.Dispose();
331 shapeDa = null;
332 }
333 if (itemsDa != null)
334 {
335 itemsDa.Dispose();
336 itemsDa = null;
337 }
338 if (terrainDa != null)
339 {
340 terrainDa.Dispose();
341 terrainDa = null;
342 }
343 if (landDa != null)
344 {
345 landDa.Dispose();
346 landDa = null;
347 }
348 if (landAccessListDa != null)
349 {
350 landAccessListDa.Dispose();
351 landAccessListDa = null;
352 }
353 if (regionSettingsDa != null)
354 {
355 regionSettingsDa.Dispose();
356 regionSettingsDa = null;
357 }
358 if (regionWindlightDa != null)
359 {
360 regionWindlightDa.Dispose();
361 regionWindlightDa = null;
362 }
363 if (regionEnvironmentDa != null)
364 {
365 regionEnvironmentDa.Dispose();
366 regionEnvironmentDa = null;
367 }
368 if (regionSpawnPointsDa != null)
369 {
370 regionSpawnPointsDa.Dispose();
371 regionWindlightDa = null;
372 }
373 }
374  
375 public void StoreRegionSettings(RegionSettings rs)
376 {
377 lock (ds)
378 {
379 DataTable regionsettings = ds.Tables["regionsettings"];
380  
381 DataRow settingsRow = regionsettings.Rows.Find(rs.RegionUUID.ToString());
382 if (settingsRow == null)
383 {
384 settingsRow = regionsettings.NewRow();
385 fillRegionSettingsRow(settingsRow, rs);
386 regionsettings.Rows.Add(settingsRow);
387 }
388 else
389 {
390 fillRegionSettingsRow(settingsRow, rs);
391 }
392  
393 StoreSpawnPoints(rs);
394  
395 Commit();
396 }
397  
398 }
399  
400 public void StoreSpawnPoints(RegionSettings rs)
401 {
402 lock (ds)
403 {
404 // DataTable spawnpoints = ds.Tables["spawn_points"];
405  
406 // remove region's spawnpoints
407 using (
408 SqliteCommand cmd =
409 new SqliteCommand("delete from spawn_points where RegionID=:RegionID",
410 m_conn))
411 {
412  
413 cmd.Parameters.Add(new SqliteParameter(":RegionID", rs.RegionUUID.ToString()));
414 cmd.ExecuteNonQuery();
415 }
416 }
417  
418 foreach (SpawnPoint sp in rs.SpawnPoints())
419 {
420 using (SqliteCommand cmd = new SqliteCommand("insert into spawn_points(RegionID, Yaw, Pitch, Distance)" +
421 "values ( :RegionID, :Yaw, :Pitch, :Distance)", m_conn))
422 {
423 cmd.Parameters.Add(new SqliteParameter(":RegionID", rs.RegionUUID.ToString()));
424 cmd.Parameters.Add(new SqliteParameter(":Yaw", sp.Yaw));
425 cmd.Parameters.Add(new SqliteParameter(":Pitch", sp.Pitch));
426 cmd.Parameters.Add(new SqliteParameter(":Distance", sp.Distance));
427 cmd.ExecuteNonQuery();
428 }
429 }
430 }
431  
432 /// <summary>
433 /// Load windlight settings from region storage
434 /// </summary>
435 /// <param name="regionUUID">RegionID</param>
436 public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
437 {
438 RegionLightShareData wl = null;
439  
440 lock (ds)
441 {
442 DataTable windlightTable = ds.Tables["regionwindlight"];
443 DataRow windlightRow = windlightTable.Rows.Find(regionUUID.ToString());
444 if (windlightRow == null)
445 {
446 wl = new RegionLightShareData();
447 wl.regionID = regionUUID;
448 StoreRegionWindlightSettings(wl);
449 return wl;
450 }
451 wl = buildRegionWindlight(windlightRow);
452 return wl;
453 }
454 }
455  
456 /// <summary>
457 /// Remove windlight settings from region storage
458 /// </summary>
459 /// <param name="regionID">RegionID</param>
460 public void RemoveRegionWindlightSettings(UUID regionID)
461 {
462 lock (ds)
463 {
464 DataTable windlightTable = ds.Tables["regionwindlight"];
465 DataRow windlightRow = windlightTable.Rows.Find(regionID.ToString());
466  
467 if (windlightRow != null)
468 {
469 windlightRow.Delete();
470 }
471 }
472 Commit();
473 }
474  
475 /// <summary>
476 /// Adds an windlight into region storage
477 /// </summary>
478 /// <param name="wl">RegionLightShareData</param>
479 public void StoreRegionWindlightSettings(RegionLightShareData wl)
480 {
481 lock (ds)
482 {
483 DataTable windlightTable = ds.Tables["regionwindlight"];
484 DataRow windlightRow = windlightTable.Rows.Find(wl.regionID.ToString());
485  
486 if (windlightRow == null)
487 {
488 windlightRow = windlightTable.NewRow();
489 fillRegionWindlightRow(windlightRow, wl);
490 windlightTable.Rows.Add(windlightRow);
491 }
492 else
493 {
494 fillRegionWindlightRow(windlightRow, wl);
495 }
496  
497 Commit();
498 }
499 }
500  
501 #region Region Environment Settings
502 public string LoadRegionEnvironmentSettings(UUID regionUUID)
503 {
504 lock (ds)
505 {
506 DataTable environmentTable = ds.Tables["regionenvironment"];
507 DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
508 if (row == null)
509 {
510 return String.Empty;
511 }
512  
513 return (String)row["llsd_settings"];
514 }
515 }
516  
517 public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
518 {
519 lock (ds)
520 {
521 DataTable environmentTable = ds.Tables["regionenvironment"];
522 DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
523  
524 if (row == null)
525 {
526 row = environmentTable.NewRow();
527 row["region_id"] = regionUUID.ToString();
528 row["llsd_settings"] = settings;
529 environmentTable.Rows.Add(row);
530 }
531 else
532 {
533 row["llsd_settings"] = settings;
534 }
535  
536 regionEnvironmentDa.Update(ds, "regionenvironment");
537 }
538 }
539  
540 public void RemoveRegionEnvironmentSettings(UUID regionUUID)
541 {
542 lock (ds)
543 {
544 DataTable environmentTable = ds.Tables["regionenvironment"];
545 DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
546  
547 if (row != null)
548 {
549 row.Delete();
550 }
551  
552 regionEnvironmentDa.Update(ds, "regionenvironment");
553 }
554 }
555  
556 #endregion
557  
558 public RegionSettings LoadRegionSettings(UUID regionUUID)
559 {
560 lock (ds)
561 {
562 DataTable regionsettings = ds.Tables["regionsettings"];
563  
564 string searchExp = "regionUUID = '" + regionUUID.ToString() + "'";
565 DataRow[] rawsettings = regionsettings.Select(searchExp);
566 if (rawsettings.Length == 0)
567 {
568 RegionSettings rs = new RegionSettings();
569 rs.RegionUUID = regionUUID;
570 rs.OnSave += StoreRegionSettings;
571  
572 StoreRegionSettings(rs);
573  
574 return rs;
575 }
576 DataRow row = rawsettings[0];
577  
578 RegionSettings newSettings = buildRegionSettings(row);
579 newSettings.OnSave += StoreRegionSettings;
580  
581 LoadSpawnPoints(newSettings);
582  
583 return newSettings;
584 }
585 }
586  
587 private void LoadSpawnPoints(RegionSettings rs)
588 {
589 rs.ClearSpawnPoints();
590  
591 DataTable spawnpoints = ds.Tables["spawn_points"];
592 string byRegion = "RegionID = '" + rs.RegionUUID + "'";
593 DataRow[] spForRegion = spawnpoints.Select(byRegion);
594  
595 foreach (DataRow spRow in spForRegion)
596 {
597 SpawnPoint sp = new SpawnPoint();
598 sp.Pitch = (float)spRow["Pitch"];
599 sp.Yaw = (float)spRow["Yaw"];
600 sp.Distance = (float)spRow["Distance"];
601  
602 rs.AddSpawnPoint(sp);
603 }
604 }
605  
606 /// <summary>
607 /// Adds an object into region storage
608 /// </summary>
609 /// <param name="obj">the object</param>
610 /// <param name="regionUUID">the region UUID</param>
611 public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
612 {
613 uint flags = obj.RootPart.GetEffectiveObjectFlags();
614  
615 // Eligibility check
616 //
617 if ((flags & (uint)PrimFlags.Temporary) != 0)
618 return;
619 if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
620 return;
621  
622 lock (ds)
623 {
624 foreach (SceneObjectPart prim in obj.Parts)
625 {
626 // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
627 addPrim(prim, obj.UUID, regionUUID);
628 }
629 }
630  
631 Commit();
632 // m_log.Info("[Dump of prims]: " + ds.GetXml());
633 }
634  
635 /// <summary>
636 /// Removes an object from region storage
637 /// </summary>
638 /// <param name="obj">the object</param>
639 /// <param name="regionUUID">the region UUID</param>
640 public void RemoveObject(UUID obj, UUID regionUUID)
641 {
642 // m_log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", obj.Guid, regionUUID);
643  
644 DataTable prims = ds.Tables["prims"];
645 DataTable shapes = ds.Tables["primshapes"];
646  
647 string selectExp = "SceneGroupID = '" + obj + "' and RegionUUID = '" + regionUUID + "'";
648 lock (ds)
649 {
650 DataRow[] primRows = prims.Select(selectExp);
651 foreach (DataRow row in primRows)
652 {
653 // Remove shape rows
654 UUID uuid = new UUID((string)row["UUID"]);
655 DataRow shapeRow = shapes.Rows.Find(uuid.ToString());
656 if (shapeRow != null)
657 {
658 shapeRow.Delete();
659 }
660  
661 RemoveItems(uuid);
662  
663 // Remove prim row
664 row.Delete();
665 }
666 }
667  
668 Commit();
669 }
670  
671 /// <summary>
672 /// Remove all persisted items of the given prim.
673 /// The caller must acquire the necessrary synchronization locks and commit or rollback changes.
674 /// </summary>
675 /// <param name="uuid">The item UUID</param>
676 private void RemoveItems(UUID uuid)
677 {
678 DataTable items = ds.Tables["primitems"];
679  
680 String sql = String.Format("primID = '{0}'", uuid);
681 DataRow[] itemRows = items.Select(sql);
682  
683 foreach (DataRow itemRow in itemRows)
684 {
685 itemRow.Delete();
686 }
687 }
688  
689 /// <summary>
690 /// Load persisted objects from region storage.
691 /// </summary>
692 /// <param name="regionUUID">The region UUID</param>
693 /// <returns>List of loaded groups</returns>
694 public List<SceneObjectGroup> LoadObjects(UUID regionUUID)
695 {
696 Dictionary<UUID, SceneObjectGroup> createdObjects = new Dictionary<UUID, SceneObjectGroup>();
697  
698 List<SceneObjectGroup> retvals = new List<SceneObjectGroup>();
699  
700 DataTable prims = ds.Tables["prims"];
701 DataTable shapes = ds.Tables["primshapes"];
702  
703 string byRegion = "RegionUUID = '" + regionUUID + "'";
704  
705 lock (ds)
706 {
707 DataRow[] primsForRegion = prims.Select(byRegion);
708 // m_log.Info("[SQLITE REGION DB]: Loaded " + primsForRegion.Length + " prims for region: " + regionUUID);
709  
710 // First, create all groups
711 foreach (DataRow primRow in primsForRegion)
712 {
713 try
714 {
715 SceneObjectPart prim = null;
716  
717 string uuid = (string)primRow["UUID"];
718 string objID = (string)primRow["SceneGroupID"];
719  
720 if (uuid == objID) //is new SceneObjectGroup ?
721 {
722 prim = buildPrim(primRow);
723 DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
724 if (shapeRow != null)
725 {
726 prim.Shape = buildShape(shapeRow);
727 }
728 else
729 {
730 m_log.Warn(
731 "[SQLITE REGION DB]: No shape found for prim in storage, so setting default box shape");
732 prim.Shape = PrimitiveBaseShape.Default;
733 }
734  
735 SceneObjectGroup group = new SceneObjectGroup(prim);
736  
737 createdObjects.Add(group.UUID, group);
738 retvals.Add(group);
739 LoadItems(prim);
740  
741  
742 }
743 }
744 catch (Exception e)
745 {
746 m_log.Error("[SQLITE REGION DB]: Failed create prim object in new group, exception and data follows");
747 m_log.Error("[SQLITE REGION DB]: ", e);
748 foreach (DataColumn col in prims.Columns)
749 {
750 m_log.Error("[SQLITE REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]);
751 }
752 }
753 }
754  
755 // Now fill the groups with part data
756 foreach (DataRow primRow in primsForRegion)
757 {
758 try
759 {
760 SceneObjectPart prim = null;
761  
762 string uuid = (string)primRow["UUID"];
763 string objID = (string)primRow["SceneGroupID"];
764 if (uuid != objID) //is new SceneObjectGroup ?
765 {
766 prim = buildPrim(primRow);
767 DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
768 if (shapeRow != null)
769 {
770 prim.Shape = buildShape(shapeRow);
771 }
772 else
773 {
774 m_log.Warn(
775 "[SQLITE REGION DB]: No shape found for prim in storage, so setting default box shape");
776 prim.Shape = PrimitiveBaseShape.Default;
777 }
778  
779 createdObjects[new UUID(objID)].AddPart(prim);
780 LoadItems(prim);
781 }
782 }
783 catch (Exception e)
784 {
785 m_log.Error("[SQLITE REGION DB]: Failed create prim object in group, exception and data follows");
786 m_log.Error("[SQLITE REGION DB]: ", e);
787 foreach (DataColumn col in prims.Columns)
788 {
789 m_log.Error("[SQLITE REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]);
790 }
791 }
792 }
793 }
794 return retvals;
795 }
796  
797 /// <summary>
798 /// Load in a prim's persisted inventory.
799 /// </summary>
800 /// <param name="prim">the prim</param>
801 private void LoadItems(SceneObjectPart prim)
802 {
803 // m_log.DebugFormat("[SQLITE REGION DB]: Loading inventory for {0} {1}", prim.Name, prim.UUID);
804  
805 DataTable dbItems = ds.Tables["primitems"];
806 String sql = String.Format("primID = '{0}'", prim.UUID.ToString());
807 DataRow[] dbItemRows = dbItems.Select(sql);
808 IList<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
809  
810 // m_log.DebugFormat("[SQLITE REGION DB]: Found {0} items for {1} {2}", dbItemRows.Length, prim.Name, prim.UUID);
811  
812 foreach (DataRow row in dbItemRows)
813 {
814 TaskInventoryItem item = buildItem(row);
815 inventory.Add(item);
816  
817 // m_log.DebugFormat("[SQLITE REGION DB]: Restored item {0} {1}", item.Name, item.ItemID);
818 }
819  
820 prim.Inventory.RestoreInventoryItems(inventory);
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  
829 /// <summary>
830 /// Store a terrain revision in region storage
831 /// </summary>
832 /// <param name="ter">terrain heightfield</param>
833 /// <param name="regionID">region UUID</param>
834 public void StoreTerrain(TerrainData terrData, UUID regionID)
835 {
836 lock (ds)
837 {
838 using (
839 SqliteCommand cmd = new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID", m_conn))
840 {
841 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
842 cmd.ExecuteNonQuery();
843 }
844  
845 // the following is an work around for .NET. The perf
846 // issues associated with it aren't as bad as you think.
847 String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
848 " values(:RegionUUID, :Revision, :Heightfield)";
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))
857 {
858 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
859 cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision));
860 cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob));
861 cmd.ExecuteNonQuery();
862 }
863 }
864 }
865  
866 /// <summary>
867 /// Load the latest terrain revision from region storage
868 /// </summary>
869 /// <param name="regionID">the region UUID</param>
870 /// <returns>Heightfield data</returns>
871 public double[,] LoadTerrain(UUID regionID)
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  
885 lock (ds)
886 {
887 String sql = "select RegionUUID, Revision, Heightfield from terrain" +
888 " where RegionUUID=:RegionUUID order by Revision desc";
889  
890 using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
891 {
892 cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
893  
894 using (IDataReader row = cmd.ExecuteReader())
895 {
896 int rev = 0;
897 if (row.Read())
898 {
899 rev = Convert.ToInt32(row["Revision"]);
900 byte[] blob = (byte[])row["Heightfield"];
901 terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
902 }
903 else
904 {
905 m_log.Warn("[SQLITE REGION DB]: No terrain found for region");
906 return null;
907 }
908  
909 m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString());
910 }
911 }
912 }
913 return terrData;
914 }
915  
916 public void RemoveLandObject(UUID globalID)
917 {
918 lock (ds)
919 {
920 // Can't use blanket SQL statements when using SqlAdapters unless you re-read the data into the adapter
921 // after you're done.
922 // replaced below code with the SqliteAdapter version.
923 //using (SqliteCommand cmd = new SqliteCommand("delete from land where UUID=:UUID", m_conn))
924 //{
925 // cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
926 // cmd.ExecuteNonQuery();
927 //}
928  
929 //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:UUID", m_conn))
930 //{
931 // cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
932 // cmd.ExecuteNonQuery();
933 //}
934  
935 DataTable land = ds.Tables["land"];
936 DataTable landaccesslist = ds.Tables["landaccesslist"];
937 DataRow landRow = land.Rows.Find(globalID.ToString());
938 if (landRow != null)
939 {
940 landRow.Delete();
941 }
942 List<DataRow> rowsToDelete = new List<DataRow>();
943 foreach (DataRow rowToCheck in landaccesslist.Rows)
944 {
945 if (rowToCheck["LandUUID"].ToString() == globalID.ToString())
946 rowsToDelete.Add(rowToCheck);
947 }
948 for (int iter = 0; iter < rowsToDelete.Count; iter++)
949 {
950 rowsToDelete[iter].Delete();
951 }
952 }
953 Commit();
954 }
955  
956 /// <summary>
957 ///
958 /// </summary>
959 /// <param name="parcel"></param>
960 public void StoreLandObject(ILandObject parcel)
961 {
962 lock (ds)
963 {
964 DataTable land = ds.Tables["land"];
965 DataTable landaccesslist = ds.Tables["landaccesslist"];
966  
967 DataRow landRow = land.Rows.Find(parcel.LandData.GlobalID.ToString());
968 if (landRow == null)
969 {
970 landRow = land.NewRow();
971 fillLandRow(landRow, parcel.LandData, parcel.RegionUUID);
972 land.Rows.Add(landRow);
973 }
974 else
975 {
976 fillLandRow(landRow, parcel.LandData, parcel.RegionUUID);
977 }
978  
979 // I know this caused someone issues before, but OpenSim is unusable if we leave this stuff around
980 //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:LandUUID", m_conn))
981 //{
982 // cmd.Parameters.Add(new SqliteParameter(":LandUUID", parcel.LandData.GlobalID.ToString()));
983 // cmd.ExecuteNonQuery();
984  
985 // }
986  
987 // This is the slower.. but more appropriate thing to do
988  
989 // We can't modify the table with direct queries before calling Commit() and re-filling them.
990 List<DataRow> rowsToDelete = new List<DataRow>();
991 foreach (DataRow rowToCheck in landaccesslist.Rows)
992 {
993 if (rowToCheck["LandUUID"].ToString() == parcel.LandData.GlobalID.ToString())
994 rowsToDelete.Add(rowToCheck);
995 }
996 for (int iter = 0; iter < rowsToDelete.Count; iter++)
997 {
998 rowsToDelete[iter].Delete();
999 landaccesslist.Rows.Remove(rowsToDelete[iter]);
1000 }
1001 rowsToDelete.Clear();
1002 foreach (LandAccessEntry entry in parcel.LandData.ParcelAccessList)
1003 {
1004 DataRow newAccessRow = landaccesslist.NewRow();
1005 fillLandAccessRow(newAccessRow, entry, parcel.LandData.GlobalID);
1006 landaccesslist.Rows.Add(newAccessRow);
1007 }
1008 }
1009  
1010 Commit();
1011 }
1012  
1013 /// <summary>
1014 ///
1015 /// </summary>
1016 /// <param name="regionUUID"></param>
1017 /// <returns></returns>
1018 public List<LandData> LoadLandObjects(UUID regionUUID)
1019 {
1020 List<LandData> landDataForRegion = new List<LandData>();
1021 lock (ds)
1022 {
1023 DataTable land = ds.Tables["land"];
1024 DataTable landaccesslist = ds.Tables["landaccesslist"];
1025 string searchExp = "RegionUUID = '" + regionUUID + "'";
1026 DataRow[] rawDataForRegion = land.Select(searchExp);
1027 foreach (DataRow rawDataLand in rawDataForRegion)
1028 {
1029 LandData newLand = buildLandData(rawDataLand);
1030 string accessListSearchExp = "LandUUID = '" + newLand.GlobalID + "'";
1031 DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp);
1032 foreach (DataRow rawDataLandAccess in rawDataForLandAccessList)
1033 {
1034 newLand.ParcelAccessList.Add(buildLandAccessData(rawDataLandAccess));
1035 }
1036  
1037 landDataForRegion.Add(newLand);
1038 }
1039 }
1040 return landDataForRegion;
1041 }
1042  
1043 /// <summary>
1044 ///
1045 /// </summary>
1046 public void Commit()
1047 {
1048 // m_log.Debug("[SQLITE]: Starting commit");
1049 lock (ds)
1050 {
1051 primDa.Update(ds, "prims");
1052 shapeDa.Update(ds, "primshapes");
1053  
1054 itemsDa.Update(ds, "primitems");
1055  
1056 terrainDa.Update(ds, "terrain");
1057 landDa.Update(ds, "land");
1058 landAccessListDa.Update(ds, "landaccesslist");
1059 try
1060 {
1061 regionSettingsDa.Update(ds, "regionsettings");
1062 regionWindlightDa.Update(ds, "regionwindlight");
1063 }
1064 catch (SqliteException SqlEx)
1065 {
1066 throw new Exception(
1067 "There was a SQL error or connection string configuration error when saving the region settings. This could be a bug, it could also happen if ConnectionString is defined in the [DatabaseService] section of StandaloneCommon.ini in the config_include folder. This could also happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. If this is your first time running OpenSimulator, please restart the simulator and bug a developer to fix this!",
1068 SqlEx);
1069 }
1070 ds.AcceptChanges();
1071 }
1072 }
1073  
1074 /// <summary>
1075 /// See <see cref="Commit"/>
1076 /// </summary>
1077 public void Shutdown()
1078 {
1079 Commit();
1080 }
1081  
1082 /***********************************************************************
1083 *
1084 * Database Definition Functions
1085 *
1086 * This should be db agnostic as we define them in ADO.NET terms
1087 *
1088 **********************************************************************/
1089  
1090 protected void CreateDataSetMapping(IDataAdapter da, string tableName)
1091 {
1092 ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName);
1093 foreach (DataColumn col in ds.Tables[tableName].Columns)
1094 {
1095 dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName);
1096 }
1097 }
1098  
1099 /// <summary>
1100 ///
1101 /// </summary>
1102 /// <param name="dt"></param>
1103 /// <param name="name"></param>
1104 /// <param name="type"></param>
1105 private static void createCol(DataTable dt, string name, Type type)
1106 {
1107 DataColumn col = new DataColumn(name, type);
1108 dt.Columns.Add(col);
1109 }
1110  
1111 /// <summary>
1112 /// Creates the "terrain" table
1113 /// </summary>
1114 /// <returns>terrain table DataTable</returns>
1115 private static DataTable createTerrainTable()
1116 {
1117 DataTable terrain = new DataTable("terrain");
1118  
1119 createCol(terrain, "RegionUUID", typeof(String));
1120 createCol(terrain, "Revision", typeof(Int32));
1121 createCol(terrain, "Heightfield", typeof(Byte[]));
1122  
1123 return terrain;
1124 }
1125  
1126 /// <summary>
1127 /// Creates the "prims" table
1128 /// </summary>
1129 /// <returns>prim table DataTable</returns>
1130 private static DataTable createPrimTable()
1131 {
1132 DataTable prims = new DataTable("prims");
1133  
1134 createCol(prims, "UUID", typeof(String));
1135 createCol(prims, "RegionUUID", typeof(String));
1136 createCol(prims, "CreationDate", typeof(Int32));
1137 createCol(prims, "Name", typeof(String));
1138 createCol(prims, "SceneGroupID", typeof(String));
1139 // various text fields
1140 createCol(prims, "Text", typeof(String));
1141 createCol(prims, "ColorR", typeof(Int32));
1142 createCol(prims, "ColorG", typeof(Int32));
1143 createCol(prims, "ColorB", typeof(Int32));
1144 createCol(prims, "ColorA", typeof(Int32));
1145 createCol(prims, "Description", typeof(String));
1146 createCol(prims, "SitName", typeof(String));
1147 createCol(prims, "TouchName", typeof(String));
1148 // permissions
1149 createCol(prims, "ObjectFlags", typeof(Int32));
1150 createCol(prims, "CreatorID", typeof(String));
1151 createCol(prims, "OwnerID", typeof(String));
1152 createCol(prims, "GroupID", typeof(String));
1153 createCol(prims, "LastOwnerID", typeof(String));
1154 createCol(prims, "OwnerMask", typeof(Int32));
1155 createCol(prims, "NextOwnerMask", typeof(Int32));
1156 createCol(prims, "GroupMask", typeof(Int32));
1157 createCol(prims, "EveryoneMask", typeof(Int32));
1158 createCol(prims, "BaseMask", typeof(Int32));
1159 // vectors
1160 createCol(prims, "PositionX", typeof(Double));
1161 createCol(prims, "PositionY", typeof(Double));
1162 createCol(prims, "PositionZ", typeof(Double));
1163 createCol(prims, "GroupPositionX", typeof(Double));
1164 createCol(prims, "GroupPositionY", typeof(Double));
1165 createCol(prims, "GroupPositionZ", typeof(Double));
1166 createCol(prims, "VelocityX", typeof(Double));
1167 createCol(prims, "VelocityY", typeof(Double));
1168 createCol(prims, "VelocityZ", typeof(Double));
1169 createCol(prims, "AngularVelocityX", typeof(Double));
1170 createCol(prims, "AngularVelocityY", typeof(Double));
1171 createCol(prims, "AngularVelocityZ", typeof(Double));
1172 createCol(prims, "AccelerationX", typeof(Double));
1173 createCol(prims, "AccelerationY", typeof(Double));
1174 createCol(prims, "AccelerationZ", typeof(Double));
1175 // quaternions
1176 createCol(prims, "RotationX", typeof(Double));
1177 createCol(prims, "RotationY", typeof(Double));
1178 createCol(prims, "RotationZ", typeof(Double));
1179 createCol(prims, "RotationW", typeof(Double));
1180  
1181 // sit target
1182 createCol(prims, "SitTargetOffsetX", typeof(Double));
1183 createCol(prims, "SitTargetOffsetY", typeof(Double));
1184 createCol(prims, "SitTargetOffsetZ", typeof(Double));
1185  
1186 createCol(prims, "SitTargetOrientW", typeof(Double));
1187 createCol(prims, "SitTargetOrientX", typeof(Double));
1188 createCol(prims, "SitTargetOrientY", typeof(Double));
1189 createCol(prims, "SitTargetOrientZ", typeof(Double));
1190  
1191 createCol(prims, "PayPrice", typeof(Int32));
1192 createCol(prims, "PayButton1", typeof(Int32));
1193 createCol(prims, "PayButton2", typeof(Int32));
1194 createCol(prims, "PayButton3", typeof(Int32));
1195 createCol(prims, "PayButton4", typeof(Int32));
1196  
1197 createCol(prims, "LoopedSound", typeof(String));
1198 createCol(prims, "LoopedSoundGain", typeof(Double));
1199 createCol(prims, "TextureAnimation", typeof(String));
1200 createCol(prims, "ParticleSystem", typeof(String));
1201  
1202 createCol(prims, "OmegaX", typeof(Double));
1203 createCol(prims, "OmegaY", typeof(Double));
1204 createCol(prims, "OmegaZ", typeof(Double));
1205  
1206 createCol(prims, "CameraEyeOffsetX", typeof(Double));
1207 createCol(prims, "CameraEyeOffsetY", typeof(Double));
1208 createCol(prims, "CameraEyeOffsetZ", typeof(Double));
1209  
1210 createCol(prims, "CameraAtOffsetX", typeof(Double));
1211 createCol(prims, "CameraAtOffsetY", typeof(Double));
1212 createCol(prims, "CameraAtOffsetZ", typeof(Double));
1213  
1214 createCol(prims, "ForceMouselook", typeof(Int16));
1215  
1216 createCol(prims, "ScriptAccessPin", typeof(Int32));
1217  
1218 createCol(prims, "AllowedDrop", typeof(Int16));
1219 createCol(prims, "DieAtEdge", typeof(Int16));
1220  
1221 createCol(prims, "SalePrice", typeof(Int32));
1222 createCol(prims, "SaleType", typeof(Int16));
1223  
1224 // click action
1225 createCol(prims, "ClickAction", typeof(Byte));
1226  
1227 createCol(prims, "Material", typeof(Byte));
1228  
1229 createCol(prims, "CollisionSound", typeof(String));
1230 createCol(prims, "CollisionSoundVolume", typeof(Double));
1231  
1232 createCol(prims, "VolumeDetect", typeof(Int16));
1233  
1234 createCol(prims, "MediaURL", typeof(String));
1235  
1236 createCol(prims, "AttachedPosX", typeof(Double));
1237 createCol(prims, "AttachedPosY", typeof(Double));
1238 createCol(prims, "AttachedPosZ", typeof(Double));
1239  
1240 createCol(prims, "DynAttrs", typeof(String));
1241  
1242 createCol(prims, "PhysicsShapeType", typeof(Byte));
1243 createCol(prims, "Density", typeof(Double));
1244 createCol(prims, "GravityModifier", typeof(Double));
1245 createCol(prims, "Friction", typeof(Double));
1246 createCol(prims, "Restitution", typeof(Double));
1247  
1248 createCol(prims, "KeyframeMotion", typeof(Byte[]));
1249 // Add in contraints
1250 prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] };
1251  
1252 return prims;
1253 }
1254  
1255 /// <summary>
1256 /// Creates "primshapes" table
1257 /// </summary>
1258 /// <returns>shape table DataTable</returns>
1259 private static DataTable createShapeTable()
1260 {
1261 DataTable shapes = new DataTable("primshapes");
1262 createCol(shapes, "UUID", typeof(String));
1263 // shape is an enum
1264 createCol(shapes, "Shape", typeof(Int32));
1265 // vectors
1266 createCol(shapes, "ScaleX", typeof(Double));
1267 createCol(shapes, "ScaleY", typeof(Double));
1268 createCol(shapes, "ScaleZ", typeof(Double));
1269 // paths
1270 createCol(shapes, "PCode", typeof(Int32));
1271 createCol(shapes, "PathBegin", typeof(Int32));
1272 createCol(shapes, "PathEnd", typeof(Int32));
1273 createCol(shapes, "PathScaleX", typeof(Int32));
1274 createCol(shapes, "PathScaleY", typeof(Int32));
1275 createCol(shapes, "PathShearX", typeof(Int32));
1276 createCol(shapes, "PathShearY", typeof(Int32));
1277 createCol(shapes, "PathSkew", typeof(Int32));
1278 createCol(shapes, "PathCurve", typeof(Int32));
1279 createCol(shapes, "PathRadiusOffset", typeof(Int32));
1280 createCol(shapes, "PathRevolutions", typeof(Int32));
1281 createCol(shapes, "PathTaperX", typeof(Int32));
1282 createCol(shapes, "PathTaperY", typeof(Int32));
1283 createCol(shapes, "PathTwist", typeof(Int32));
1284 createCol(shapes, "PathTwistBegin", typeof(Int32));
1285 // profile
1286 createCol(shapes, "ProfileBegin", typeof(Int32));
1287 createCol(shapes, "ProfileEnd", typeof(Int32));
1288 createCol(shapes, "ProfileCurve", typeof(Int32));
1289 createCol(shapes, "ProfileHollow", typeof(Int32));
1290 createCol(shapes, "State", typeof(Int32));
1291 // text TODO: this isn't right, but I'm not sure the right
1292 // way to specify this as a blob atm
1293 createCol(shapes, "Texture", typeof(Byte[]));
1294 createCol(shapes, "ExtraParams", typeof(Byte[]));
1295 createCol(shapes, "Media", typeof(String));
1296  
1297 shapes.PrimaryKey = new DataColumn[] { shapes.Columns["UUID"] };
1298  
1299 return shapes;
1300 }
1301  
1302 /// <summary>
1303 /// creates "primitems" table
1304 /// </summary>
1305 /// <returns>item table DataTable</returns>
1306 private static DataTable createItemsTable()
1307 {
1308 DataTable items = new DataTable("primitems");
1309  
1310 createCol(items, "itemID", typeof(String));
1311 createCol(items, "primID", typeof(String));
1312 createCol(items, "assetID", typeof(String));
1313 createCol(items, "parentFolderID", typeof(String));
1314  
1315 createCol(items, "invType", typeof(Int32));
1316 createCol(items, "assetType", typeof(Int32));
1317  
1318 createCol(items, "name", typeof(String));
1319 createCol(items, "description", typeof(String));
1320  
1321 createCol(items, "creationDate", typeof(Int64));
1322 createCol(items, "creatorID", typeof(String));
1323 createCol(items, "ownerID", typeof(String));
1324 createCol(items, "lastOwnerID", typeof(String));
1325 createCol(items, "groupID", typeof(String));
1326  
1327 createCol(items, "nextPermissions", typeof(UInt32));
1328 createCol(items, "currentPermissions", typeof(UInt32));
1329 createCol(items, "basePermissions", typeof(UInt32));
1330 createCol(items, "everyonePermissions", typeof(UInt32));
1331 createCol(items, "groupPermissions", typeof(UInt32));
1332 createCol(items, "flags", typeof(UInt32));
1333  
1334 items.PrimaryKey = new DataColumn[] { items.Columns["itemID"] };
1335  
1336 return items;
1337 }
1338  
1339 /// <summary>
1340 /// Creates "land" table
1341 /// </summary>
1342 /// <returns>land table DataTable</returns>
1343 private static DataTable createLandTable()
1344 {
1345 DataTable land = new DataTable("land");
1346 createCol(land, "UUID", typeof(String));
1347 createCol(land, "RegionUUID", typeof(String));
1348 createCol(land, "LocalLandID", typeof(UInt32));
1349  
1350 // Bitmap is a byte[512]
1351 createCol(land, "Bitmap", typeof(Byte[]));
1352  
1353 createCol(land, "Name", typeof(String));
1354 createCol(land, "Desc", typeof(String));
1355 createCol(land, "OwnerUUID", typeof(String));
1356 createCol(land, "IsGroupOwned", typeof(Boolean));
1357 createCol(land, "Area", typeof(Int32));
1358 createCol(land, "AuctionID", typeof(Int32)); //Unemplemented
1359 createCol(land, "Category", typeof(Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory
1360 createCol(land, "ClaimDate", typeof(Int32));
1361 createCol(land, "ClaimPrice", typeof(Int32));
1362 createCol(land, "GroupUUID", typeof(string));
1363 createCol(land, "SalePrice", typeof(Int32));
1364 createCol(land, "LandStatus", typeof(Int32)); //Enum. OpenMetaverse.Parcel.ParcelStatus
1365 createCol(land, "LandFlags", typeof(UInt32));
1366 createCol(land, "LandingType", typeof(Byte));
1367 createCol(land, "MediaAutoScale", typeof(Byte));
1368 createCol(land, "MediaTextureUUID", typeof(String));
1369 createCol(land, "MediaURL", typeof(String));
1370 createCol(land, "MusicURL", typeof(String));
1371 createCol(land, "PassHours", typeof(Double));
1372 createCol(land, "PassPrice", typeof(UInt32));
1373 createCol(land, "SnapshotUUID", typeof(String));
1374 createCol(land, "UserLocationX", typeof(Double));
1375 createCol(land, "UserLocationY", typeof(Double));
1376 createCol(land, "UserLocationZ", typeof(Double));
1377 createCol(land, "UserLookAtX", typeof(Double));
1378 createCol(land, "UserLookAtY", typeof(Double));
1379 createCol(land, "UserLookAtZ", typeof(Double));
1380 createCol(land, "AuthbuyerID", typeof(String));
1381 createCol(land, "OtherCleanTime", typeof(Int32));
1382 createCol(land, "Dwell", typeof(Int32));
1383 createCol(land, "MediaType", typeof(String));
1384 createCol(land, "MediaDescription", typeof(String));
1385 createCol(land, "MediaSize", typeof(String));
1386 createCol(land, "MediaLoop", typeof(Boolean));
1387 createCol(land, "ObscureMedia", typeof(Boolean));
1388 createCol(land, "ObscureMusic", typeof(Boolean));
1389  
1390 land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] };
1391  
1392 return land;
1393 }
1394  
1395 /// <summary>
1396 /// create "landaccesslist" table
1397 /// </summary>
1398 /// <returns>Landacceslist DataTable</returns>
1399 private static DataTable createLandAccessListTable()
1400 {
1401 DataTable landaccess = new DataTable("landaccesslist");
1402 createCol(landaccess, "LandUUID", typeof(String));
1403 createCol(landaccess, "AccessUUID", typeof(String));
1404 createCol(landaccess, "Flags", typeof(UInt32));
1405  
1406 return landaccess;
1407 }
1408  
1409 private static DataTable createRegionSettingsTable()
1410 {
1411 DataTable regionsettings = new DataTable("regionsettings");
1412 createCol(regionsettings, "regionUUID", typeof(String));
1413 createCol(regionsettings, "block_terraform", typeof(Int32));
1414 createCol(regionsettings, "block_fly", typeof(Int32));
1415 createCol(regionsettings, "allow_damage", typeof(Int32));
1416 createCol(regionsettings, "restrict_pushing", typeof(Int32));
1417 createCol(regionsettings, "allow_land_resell", typeof(Int32));
1418 createCol(regionsettings, "allow_land_join_divide", typeof(Int32));
1419 createCol(regionsettings, "block_show_in_search", typeof(Int32));
1420 createCol(regionsettings, "agent_limit", typeof(Int32));
1421 createCol(regionsettings, "object_bonus", typeof(Double));
1422 createCol(regionsettings, "maturity", typeof(Int32));
1423 createCol(regionsettings, "disable_scripts", typeof(Int32));
1424 createCol(regionsettings, "disable_collisions", typeof(Int32));
1425 createCol(regionsettings, "disable_physics", typeof(Int32));
1426 createCol(regionsettings, "terrain_texture_1", typeof(String));
1427 createCol(regionsettings, "terrain_texture_2", typeof(String));
1428 createCol(regionsettings, "terrain_texture_3", typeof(String));
1429 createCol(regionsettings, "terrain_texture_4", typeof(String));
1430 createCol(regionsettings, "elevation_1_nw", typeof(Double));
1431 createCol(regionsettings, "elevation_2_nw", typeof(Double));
1432 createCol(regionsettings, "elevation_1_ne", typeof(Double));
1433 createCol(regionsettings, "elevation_2_ne", typeof(Double));
1434 createCol(regionsettings, "elevation_1_se", typeof(Double));
1435 createCol(regionsettings, "elevation_2_se", typeof(Double));
1436 createCol(regionsettings, "elevation_1_sw", typeof(Double));
1437 createCol(regionsettings, "elevation_2_sw", typeof(Double));
1438 createCol(regionsettings, "water_height", typeof(Double));
1439 createCol(regionsettings, "terrain_raise_limit", typeof(Double));
1440 createCol(regionsettings, "terrain_lower_limit", typeof(Double));
1441 createCol(regionsettings, "use_estate_sun", typeof(Int32));
1442 createCol(regionsettings, "sandbox", typeof(Int32));
1443 createCol(regionsettings, "sunvectorx", typeof(Double));
1444 createCol(regionsettings, "sunvectory", typeof(Double));
1445 createCol(regionsettings, "sunvectorz", typeof(Double));
1446 createCol(regionsettings, "fixed_sun", typeof(Int32));
1447 createCol(regionsettings, "sun_position", typeof(Double));
1448 createCol(regionsettings, "covenant", typeof(String));
1449 createCol(regionsettings, "covenant_datetime", typeof(Int32));
1450 createCol(regionsettings, "map_tile_ID", typeof(String));
1451 createCol(regionsettings, "TelehubObject", typeof(String));
1452 createCol(regionsettings, "parcel_tile_ID", typeof(String));
1453 regionsettings.PrimaryKey = new DataColumn[] { regionsettings.Columns["regionUUID"] };
1454 return regionsettings;
1455 }
1456  
1457 /// <summary>
1458 /// create "regionwindlight" table
1459 /// </summary>
1460 /// <returns>RegionWindlight DataTable</returns>
1461 private static DataTable createRegionWindlightTable()
1462 {
1463 DataTable regionwindlight = new DataTable("regionwindlight");
1464 createCol(regionwindlight, "region_id", typeof(String));
1465 createCol(regionwindlight, "water_color_r", typeof(Double));
1466 createCol(regionwindlight, "water_color_g", typeof(Double));
1467 createCol(regionwindlight, "water_color_b", typeof(Double));
1468 createCol(regionwindlight, "water_color_i", typeof(Double));
1469 createCol(regionwindlight, "water_fog_density_exponent", typeof(Double));
1470 createCol(regionwindlight, "underwater_fog_modifier", typeof(Double));
1471 createCol(regionwindlight, "reflection_wavelet_scale_1", typeof(Double));
1472 createCol(regionwindlight, "reflection_wavelet_scale_2", typeof(Double));
1473 createCol(regionwindlight, "reflection_wavelet_scale_3", typeof(Double));
1474 createCol(regionwindlight, "fresnel_scale", typeof(Double));
1475 createCol(regionwindlight, "fresnel_offset", typeof(Double));
1476 createCol(regionwindlight, "refract_scale_above", typeof(Double));
1477 createCol(regionwindlight, "refract_scale_below", typeof(Double));
1478 createCol(regionwindlight, "blur_multiplier", typeof(Double));
1479 createCol(regionwindlight, "big_wave_direction_x", typeof(Double));
1480 createCol(regionwindlight, "big_wave_direction_y", typeof(Double));
1481 createCol(regionwindlight, "little_wave_direction_x", typeof(Double));
1482 createCol(regionwindlight, "little_wave_direction_y", typeof(Double));
1483 createCol(regionwindlight, "normal_map_texture", typeof(String));
1484 createCol(regionwindlight, "horizon_r", typeof(Double));
1485 createCol(regionwindlight, "horizon_g", typeof(Double));
1486 createCol(regionwindlight, "horizon_b", typeof(Double));
1487 createCol(regionwindlight, "horizon_i", typeof(Double));
1488 createCol(regionwindlight, "haze_horizon", typeof(Double));
1489 createCol(regionwindlight, "blue_density_r", typeof(Double));
1490 createCol(regionwindlight, "blue_density_g", typeof(Double));
1491 createCol(regionwindlight, "blue_density_b", typeof(Double));
1492 createCol(regionwindlight, "blue_density_i", typeof(Double));
1493 createCol(regionwindlight, "haze_density", typeof(Double));
1494 createCol(regionwindlight, "density_multiplier", typeof(Double));
1495 createCol(regionwindlight, "distance_multiplier", typeof(Double));
1496 createCol(regionwindlight, "max_altitude", typeof(Int32));
1497 createCol(regionwindlight, "sun_moon_color_r", typeof(Double));
1498 createCol(regionwindlight, "sun_moon_color_g", typeof(Double));
1499 createCol(regionwindlight, "sun_moon_color_b", typeof(Double));
1500 createCol(regionwindlight, "sun_moon_color_i", typeof(Double));
1501 createCol(regionwindlight, "sun_moon_position", typeof(Double));
1502 createCol(regionwindlight, "ambient_r", typeof(Double));
1503 createCol(regionwindlight, "ambient_g", typeof(Double));
1504 createCol(regionwindlight, "ambient_b", typeof(Double));
1505 createCol(regionwindlight, "ambient_i", typeof(Double));
1506 createCol(regionwindlight, "east_angle", typeof(Double));
1507 createCol(regionwindlight, "sun_glow_focus", typeof(Double));
1508 createCol(regionwindlight, "sun_glow_size", typeof(Double));
1509 createCol(regionwindlight, "scene_gamma", typeof(Double));
1510 createCol(regionwindlight, "star_brightness", typeof(Double));
1511 createCol(regionwindlight, "cloud_color_r", typeof(Double));
1512 createCol(regionwindlight, "cloud_color_g", typeof(Double));
1513 createCol(regionwindlight, "cloud_color_b", typeof(Double));
1514 createCol(regionwindlight, "cloud_color_i", typeof(Double));
1515 createCol(regionwindlight, "cloud_x", typeof(Double));
1516 createCol(regionwindlight, "cloud_y", typeof(Double));
1517 createCol(regionwindlight, "cloud_density", typeof(Double));
1518 createCol(regionwindlight, "cloud_coverage", typeof(Double));
1519 createCol(regionwindlight, "cloud_scale", typeof(Double));
1520 createCol(regionwindlight, "cloud_detail_x", typeof(Double));
1521 createCol(regionwindlight, "cloud_detail_y", typeof(Double));
1522 createCol(regionwindlight, "cloud_detail_density", typeof(Double));
1523 createCol(regionwindlight, "cloud_scroll_x", typeof(Double));
1524 createCol(regionwindlight, "cloud_scroll_x_lock", typeof(Int32));
1525 createCol(regionwindlight, "cloud_scroll_y", typeof(Double));
1526 createCol(regionwindlight, "cloud_scroll_y_lock", typeof(Int32));
1527 createCol(regionwindlight, "draw_classic_clouds", typeof(Int32));
1528  
1529 regionwindlight.PrimaryKey = new DataColumn[] { regionwindlight.Columns["region_id"] };
1530 return regionwindlight;
1531 }
1532  
1533 private static DataTable createRegionEnvironmentTable()
1534 {
1535 DataTable regionEnvironment = new DataTable("regionenvironment");
1536 createCol(regionEnvironment, "region_id", typeof(String));
1537 createCol(regionEnvironment, "llsd_settings", typeof(String));
1538  
1539 regionEnvironment.PrimaryKey = new DataColumn[] { regionEnvironment.Columns["region_id"] };
1540  
1541 return regionEnvironment;
1542 }
1543  
1544 private static DataTable createRegionSpawnPointsTable()
1545 {
1546 DataTable spawn_points = new DataTable("spawn_points");
1547 createCol(spawn_points, "regionID", typeof(String));
1548 createCol(spawn_points, "Yaw", typeof(float));
1549 createCol(spawn_points, "Pitch", typeof(float));
1550 createCol(spawn_points, "Distance", typeof(float));
1551  
1552 return spawn_points;
1553 }
1554  
1555 /***********************************************************************
1556 *
1557 * Convert between ADO.NET <=> OpenSim Objects
1558 *
1559 * These should be database independant
1560 *
1561 **********************************************************************/
1562  
1563 /// <summary>
1564 ///
1565 /// </summary>
1566 /// <param name="row"></param>
1567 /// <returns></returns>
1568 private SceneObjectPart buildPrim(DataRow row)
1569 {
1570 // Code commented. Uncomment to test the unit test inline.
1571  
1572 // The unit test mentions this commented code for the purposes
1573 // of debugging a unit test failure
1574  
1575 // SceneObjectGroup sog = new SceneObjectGroup();
1576 // SceneObjectPart sop = new SceneObjectPart();
1577 // sop.LocalId = 1;
1578 // sop.Name = "object1";
1579 // sop.Description = "object1";
1580 // sop.Text = "";
1581 // sop.SitName = "";
1582 // sop.TouchName = "";
1583 // sop.UUID = UUID.Random();
1584 // sop.Shape = PrimitiveBaseShape.Default;
1585 // sog.SetRootPart(sop);
1586 // Add breakpoint in above line. Check sop fields.
1587  
1588 // TODO: this doesn't work yet because something more
1589 // interesting has to be done to actually get these values
1590 // back out. Not enough time to figure it out yet.
1591  
1592 SceneObjectPart prim = new SceneObjectPart();
1593 prim.UUID = new UUID((String)row["UUID"]);
1594 // explicit conversion of integers is required, which sort
1595 // of sucks. No idea if there is a shortcut here or not.
1596 prim.CreationDate = Convert.ToInt32(row["CreationDate"]);
1597 prim.Name = row["Name"] == DBNull.Value ? string.Empty : (string)row["Name"];
1598 // various text fields
1599 prim.Text = (String)row["Text"];
1600 prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]),
1601 Convert.ToInt32(row["ColorR"]),
1602 Convert.ToInt32(row["ColorG"]),
1603 Convert.ToInt32(row["ColorB"]));
1604 prim.Description = (String)row["Description"];
1605 prim.SitName = (String)row["SitName"];
1606 prim.TouchName = (String)row["TouchName"];
1607 // permissions
1608 prim.Flags = (PrimFlags)Convert.ToUInt32(row["ObjectFlags"]);
1609 prim.CreatorIdentification = (String)row["CreatorID"];
1610 prim.OwnerID = new UUID((String)row["OwnerID"]);
1611 prim.GroupID = new UUID((String)row["GroupID"]);
1612 prim.LastOwnerID = new UUID((String)row["LastOwnerID"]);
1613 prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]);
1614 prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]);
1615 prim.GroupMask = Convert.ToUInt32(row["GroupMask"]);
1616 prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]);
1617 prim.BaseMask = Convert.ToUInt32(row["BaseMask"]);
1618 // vectors
1619 prim.OffsetPosition = new Vector3(
1620 Convert.ToSingle(row["PositionX"]),
1621 Convert.ToSingle(row["PositionY"]),
1622 Convert.ToSingle(row["PositionZ"])
1623 );
1624 prim.GroupPosition = new Vector3(
1625 Convert.ToSingle(row["GroupPositionX"]),
1626 Convert.ToSingle(row["GroupPositionY"]),
1627 Convert.ToSingle(row["GroupPositionZ"])
1628 );
1629 prim.Velocity = new Vector3(
1630 Convert.ToSingle(row["VelocityX"]),
1631 Convert.ToSingle(row["VelocityY"]),
1632 Convert.ToSingle(row["VelocityZ"])
1633 );
1634 prim.AngularVelocity = new Vector3(
1635 Convert.ToSingle(row["AngularVelocityX"]),
1636 Convert.ToSingle(row["AngularVelocityY"]),
1637 Convert.ToSingle(row["AngularVelocityZ"])
1638 );
1639 prim.Acceleration = new Vector3(
1640 Convert.ToSingle(row["AccelerationX"]),
1641 Convert.ToSingle(row["AccelerationY"]),
1642 Convert.ToSingle(row["AccelerationZ"])
1643 );
1644 // quaternions
1645 prim.RotationOffset = new Quaternion(
1646 Convert.ToSingle(row["RotationX"]),
1647 Convert.ToSingle(row["RotationY"]),
1648 Convert.ToSingle(row["RotationZ"]),
1649 Convert.ToSingle(row["RotationW"])
1650 );
1651  
1652 prim.SitTargetPositionLL = new Vector3(
1653 Convert.ToSingle(row["SitTargetOffsetX"]),
1654 Convert.ToSingle(row["SitTargetOffsetY"]),
1655 Convert.ToSingle(row["SitTargetOffsetZ"]));
1656 prim.SitTargetOrientationLL = new Quaternion(
1657 Convert.ToSingle(
1658 row["SitTargetOrientX"]),
1659 Convert.ToSingle(
1660 row["SitTargetOrientY"]),
1661 Convert.ToSingle(
1662 row["SitTargetOrientZ"]),
1663 Convert.ToSingle(
1664 row["SitTargetOrientW"]));
1665  
1666 prim.ClickAction = Convert.ToByte(row["ClickAction"]);
1667 prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]);
1668 prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]);
1669 prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]);
1670 prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]);
1671 prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]);
1672  
1673 prim.Sound = new UUID(row["LoopedSound"].ToString());
1674 prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]);
1675 prim.SoundFlags = 1; // If it's persisted at all, it's looped
1676  
1677 if (!row.IsNull("TextureAnimation"))
1678 prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString());
1679 if (!row.IsNull("ParticleSystem"))
1680 prim.ParticleSystem = Convert.FromBase64String(row["ParticleSystem"].ToString());
1681  
1682 prim.AngularVelocity = new Vector3(
1683 Convert.ToSingle(row["OmegaX"]),
1684 Convert.ToSingle(row["OmegaY"]),
1685 Convert.ToSingle(row["OmegaZ"])
1686 );
1687  
1688 prim.SetCameraEyeOffset(new Vector3(
1689 Convert.ToSingle(row["CameraEyeOffsetX"]),
1690 Convert.ToSingle(row["CameraEyeOffsetY"]),
1691 Convert.ToSingle(row["CameraEyeOffsetZ"])
1692 ));
1693  
1694 prim.SetCameraAtOffset(new Vector3(
1695 Convert.ToSingle(row["CameraAtOffsetX"]),
1696 Convert.ToSingle(row["CameraAtOffsetY"]),
1697 Convert.ToSingle(row["CameraAtOffsetZ"])
1698 ));
1699  
1700 if (Convert.ToInt16(row["ForceMouselook"]) != 0)
1701 prim.SetForceMouselook(true);
1702  
1703 prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]);
1704  
1705 if (Convert.ToInt16(row["AllowedDrop"]) != 0)
1706 prim.AllowedDrop = true;
1707  
1708 if (Convert.ToInt16(row["DieAtEdge"]) != 0)
1709 prim.DIE_AT_EDGE = true;
1710  
1711 prim.SalePrice = Convert.ToInt32(row["SalePrice"]);
1712 prim.ObjectSaleType = Convert.ToByte(row["SaleType"]);
1713  
1714 prim.Material = Convert.ToByte(row["Material"]);
1715  
1716 prim.CollisionSound = new UUID(row["CollisionSound"].ToString());
1717 prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]);
1718  
1719 if (Convert.ToInt16(row["VolumeDetect"]) != 0)
1720 prim.VolumeDetectActive = true;
1721  
1722 if (!(row["MediaURL"] is System.DBNull))
1723 {
1724 // m_log.DebugFormat("[SQLITE]: MediaUrl type [{0}]", row["MediaURL"].GetType());
1725 prim.MediaUrl = (string)row["MediaURL"];
1726 }
1727  
1728 prim.AttachedPos = new Vector3(
1729 Convert.ToSingle(row["AttachedPosX"]),
1730 Convert.ToSingle(row["AttachedPosY"]),
1731 Convert.ToSingle(row["AttachedPosZ"])
1732 );
1733  
1734 if (!(row["DynAttrs"] is System.DBNull))
1735 {
1736 //m_log.DebugFormat("[SQLITE]: DynAttrs type [{0}]", row["DynAttrs"].GetType());
1737 prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]);
1738 }
1739 else
1740 {
1741 prim.DynAttrs = new DAMap();
1742 }
1743  
1744 prim.PhysicsShapeType = Convert.ToByte(row["PhysicsShapeType"]);
1745 prim.Density = Convert.ToSingle(row["Density"]);
1746 prim.GravityModifier = Convert.ToSingle(row["GravityModifier"]);
1747 prim.Friction = Convert.ToSingle(row["Friction"]);
1748 prim.Restitution = Convert.ToSingle(row["Restitution"]);
1749  
1750  
1751 if (!(row["KeyframeMotion"] is DBNull))
1752 {
1753 Byte[] data = (byte[])row["KeyframeMotion"];
1754 if (data.Length > 0)
1755 prim.KeyframeMotion = KeyframeMotion.FromData(null, data);
1756 else
1757 prim.KeyframeMotion = null;
1758 }
1759 else
1760 {
1761 prim.KeyframeMotion = null;
1762 }
1763  
1764 return prim;
1765 }
1766  
1767 /// <summary>
1768 /// Build a prim inventory item from the persisted data.
1769 /// </summary>
1770 /// <param name="row"></param>
1771 /// <returns></returns>
1772 private static TaskInventoryItem buildItem(DataRow row)
1773 {
1774 TaskInventoryItem taskItem = new TaskInventoryItem();
1775  
1776 taskItem.ItemID = new UUID((String)row["itemID"]);
1777 taskItem.ParentPartID = new UUID((String)row["primID"]);
1778 taskItem.AssetID = new UUID((String)row["assetID"]);
1779 taskItem.ParentID = new UUID((String)row["parentFolderID"]);
1780  
1781 taskItem.InvType = Convert.ToInt32(row["invType"]);
1782 taskItem.Type = Convert.ToInt32(row["assetType"]);
1783  
1784 taskItem.Name = (String)row["name"];
1785 taskItem.Description = (String)row["description"];
1786 taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
1787 taskItem.CreatorIdentification = (String)row["creatorID"];
1788 taskItem.OwnerID = new UUID((String)row["ownerID"]);
1789 taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]);
1790 taskItem.GroupID = new UUID((String)row["groupID"]);
1791  
1792 taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
1793 taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]);
1794 taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]);
1795 taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]);
1796 taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]);
1797 taskItem.Flags = Convert.ToUInt32(row["flags"]);
1798  
1799 return taskItem;
1800 }
1801  
1802 /// <summary>
1803 /// Build a Land Data from the persisted data.
1804 /// </summary>
1805 /// <param name="row"></param>
1806 /// <returns></returns>
1807 private LandData buildLandData(DataRow row)
1808 {
1809 LandData newData = new LandData();
1810  
1811 newData.GlobalID = new UUID((String)row["UUID"]);
1812 newData.LocalID = Convert.ToInt32(row["LocalLandID"]);
1813  
1814 // Bitmap is a byte[512]
1815 newData.Bitmap = (Byte[])row["Bitmap"];
1816  
1817 newData.Name = (String)row["Name"];
1818 newData.Description = (String)row["Desc"];
1819 newData.OwnerID = (UUID)(String)row["OwnerUUID"];
1820 newData.IsGroupOwned = (Boolean)row["IsGroupOwned"];
1821 newData.Area = Convert.ToInt32(row["Area"]);
1822 newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented
1823 newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]);
1824 //Enum OpenMetaverse.Parcel.ParcelCategory
1825 newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]);
1826 newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]);
1827 newData.GroupID = new UUID((String)row["GroupUUID"]);
1828 newData.SalePrice = Convert.ToInt32(row["SalePrice"]);
1829 newData.Status = (ParcelStatus)Convert.ToInt32(row["LandStatus"]);
1830 //Enum. OpenMetaverse.Parcel.ParcelStatus
1831 newData.Flags = Convert.ToUInt32(row["LandFlags"]);
1832 newData.LandingType = (Byte)row["LandingType"];
1833 newData.MediaAutoScale = (Byte)row["MediaAutoScale"];
1834 newData.MediaID = new UUID((String)row["MediaTextureUUID"]);
1835 newData.MediaURL = (String)row["MediaURL"];
1836 newData.MusicURL = (String)row["MusicURL"];
1837 newData.PassHours = Convert.ToSingle(row["PassHours"]);
1838 newData.PassPrice = Convert.ToInt32(row["PassPrice"]);
1839 newData.SnapshotID = (UUID)(String)row["SnapshotUUID"];
1840 newData.Dwell = Convert.ToInt32(row["Dwell"]);
1841 newData.MediaType = (String)row["MediaType"];
1842 newData.MediaDescription = (String)row["MediaDescription"];
1843 newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]);
1844 newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]);
1845 newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]);
1846 newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]);
1847 newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]);
1848 try
1849 {
1850 newData.UserLocation =
1851 new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]),
1852 Convert.ToSingle(row["UserLocationZ"]));
1853 newData.UserLookAt =
1854 new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]),
1855 Convert.ToSingle(row["UserLookAtZ"]));
1856  
1857 }
1858 catch (InvalidCastException)
1859 {
1860 m_log.ErrorFormat("[SQLITE REGION DB]: unable to get parcel telehub settings for {1}", newData.Name);
1861 newData.UserLocation = Vector3.Zero;
1862 newData.UserLookAt = Vector3.Zero;
1863 }
1864 newData.ParcelAccessList = new List<LandAccessEntry>();
1865 UUID authBuyerID = UUID.Zero;
1866  
1867 UUID.TryParse((string)row["AuthbuyerID"], out authBuyerID);
1868  
1869 newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
1870  
1871 return newData;
1872 }
1873  
1874 private RegionSettings buildRegionSettings(DataRow row)
1875 {
1876 RegionSettings newSettings = new RegionSettings();
1877  
1878 newSettings.RegionUUID = new UUID((string)row["regionUUID"]);
1879 newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]);
1880 newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]);
1881 newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]);
1882 newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]);
1883 newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]);
1884 newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]);
1885 newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]);
1886 newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]);
1887 newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]);
1888 newSettings.Maturity = Convert.ToInt32(row["maturity"]);
1889 newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]);
1890 newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]);
1891 newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]);
1892 newSettings.TerrainTexture1 = new UUID((String)row["terrain_texture_1"]);
1893 newSettings.TerrainTexture2 = new UUID((String)row["terrain_texture_2"]);
1894 newSettings.TerrainTexture3 = new UUID((String)row["terrain_texture_3"]);
1895 newSettings.TerrainTexture4 = new UUID((String)row["terrain_texture_4"]);
1896 newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]);
1897 newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]);
1898 newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]);
1899 newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]);
1900 newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]);
1901 newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]);
1902 newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]);
1903 newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]);
1904 newSettings.WaterHeight = Convert.ToDouble(row["water_height"]);
1905 newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
1906 newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
1907 newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
1908 newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
1909 newSettings.SunVector = new Vector3(
1910 Convert.ToSingle(row["sunvectorx"]),
1911 Convert.ToSingle(row["sunvectory"]),
1912 Convert.ToSingle(row["sunvectorz"])
1913 );
1914 newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]);
1915 newSettings.SunPosition = Convert.ToDouble(row["sun_position"]);
1916 newSettings.Covenant = new UUID((String)row["covenant"]);
1917 newSettings.CovenantChangedDateTime = Convert.ToInt32(row["covenant_datetime"]);
1918 newSettings.TerrainImageID = new UUID((String)row["map_tile_ID"]);
1919 newSettings.TelehubObject = new UUID((String)row["TelehubObject"]);
1920 newSettings.ParcelImageID = new UUID((String)row["parcel_tile_ID"]);
1921  
1922 return newSettings;
1923 }
1924  
1925 /// <summary>
1926 /// Build a windlight entry from the persisted data.
1927 /// </summary>
1928 /// <param name="row"></param>
1929 /// <returns>RegionLightShareData</returns>
1930 private RegionLightShareData buildRegionWindlight(DataRow row)
1931 {
1932 RegionLightShareData windlight = new RegionLightShareData();
1933  
1934 windlight.regionID = new UUID((string)row["region_id"]);
1935 windlight.waterColor.X = Convert.ToSingle(row["water_color_r"]);
1936 windlight.waterColor.Y = Convert.ToSingle(row["water_color_g"]);
1937 windlight.waterColor.Z = Convert.ToSingle(row["water_color_b"]);
1938 //windlight.waterColor.W = Convert.ToSingle(row["water_color_i"]); //not implemented
1939 windlight.waterFogDensityExponent = Convert.ToSingle(row["water_fog_density_exponent"]);
1940 windlight.underwaterFogModifier = Convert.ToSingle(row["underwater_fog_modifier"]);
1941 windlight.reflectionWaveletScale.X = Convert.ToSingle(row["reflection_wavelet_scale_1"]);
1942 windlight.reflectionWaveletScale.Y = Convert.ToSingle(row["reflection_wavelet_scale_2"]);
1943 windlight.reflectionWaveletScale.Z = Convert.ToSingle(row["reflection_wavelet_scale_3"]);
1944 windlight.fresnelScale = Convert.ToSingle(row["fresnel_scale"]);
1945 windlight.fresnelOffset = Convert.ToSingle(row["fresnel_offset"]);
1946 windlight.refractScaleAbove = Convert.ToSingle(row["refract_scale_above"]);
1947 windlight.refractScaleBelow = Convert.ToSingle(row["refract_scale_below"]);
1948 windlight.blurMultiplier = Convert.ToSingle(row["blur_multiplier"]);
1949 windlight.bigWaveDirection.X = Convert.ToSingle(row["big_wave_direction_x"]);
1950 windlight.bigWaveDirection.Y = Convert.ToSingle(row["big_wave_direction_y"]);
1951 windlight.littleWaveDirection.X = Convert.ToSingle(row["little_wave_direction_x"]);
1952 windlight.littleWaveDirection.Y = Convert.ToSingle(row["little_wave_direction_y"]);
1953 windlight.normalMapTexture = new UUID((string)row["normal_map_texture"]);
1954 windlight.horizon.X = Convert.ToSingle(row["horizon_r"]);
1955 windlight.horizon.Y = Convert.ToSingle(row["horizon_g"]);
1956 windlight.horizon.Z = Convert.ToSingle(row["horizon_b"]);
1957 windlight.horizon.W = Convert.ToSingle(row["horizon_i"]);
1958 windlight.hazeHorizon = Convert.ToSingle(row["haze_horizon"]);
1959 windlight.blueDensity.X = Convert.ToSingle(row["blue_density_r"]);
1960 windlight.blueDensity.Y = Convert.ToSingle(row["blue_density_g"]);
1961 windlight.blueDensity.Z = Convert.ToSingle(row["blue_density_b"]);
1962 windlight.blueDensity.W = Convert.ToSingle(row["blue_density_i"]);
1963 windlight.hazeDensity = Convert.ToSingle(row["haze_density"]);
1964 windlight.densityMultiplier = Convert.ToSingle(row["density_multiplier"]);
1965 windlight.distanceMultiplier = Convert.ToSingle(row["distance_multiplier"]);
1966 windlight.maxAltitude = Convert.ToUInt16(row["max_altitude"]);
1967 windlight.sunMoonColor.X = Convert.ToSingle(row["sun_moon_color_r"]);
1968 windlight.sunMoonColor.Y = Convert.ToSingle(row["sun_moon_color_g"]);
1969 windlight.sunMoonColor.Z = Convert.ToSingle(row["sun_moon_color_b"]);
1970 windlight.sunMoonColor.W = Convert.ToSingle(row["sun_moon_color_i"]);
1971 windlight.sunMoonPosition = Convert.ToSingle(row["sun_moon_position"]);
1972 windlight.ambient.X = Convert.ToSingle(row["ambient_r"]);
1973 windlight.ambient.Y = Convert.ToSingle(row["ambient_g"]);
1974 windlight.ambient.Z = Convert.ToSingle(row["ambient_b"]);
1975 windlight.ambient.W = Convert.ToSingle(row["ambient_i"]);
1976 windlight.eastAngle = Convert.ToSingle(row["east_angle"]);
1977 windlight.sunGlowFocus = Convert.ToSingle(row["sun_glow_focus"]);
1978 windlight.sunGlowSize = Convert.ToSingle(row["sun_glow_size"]);
1979 windlight.sceneGamma = Convert.ToSingle(row["scene_gamma"]);
1980 windlight.starBrightness = Convert.ToSingle(row["star_brightness"]);
1981 windlight.cloudColor.X = Convert.ToSingle(row["cloud_color_r"]);
1982 windlight.cloudColor.Y = Convert.ToSingle(row["cloud_color_g"]);
1983 windlight.cloudColor.Z = Convert.ToSingle(row["cloud_color_b"]);
1984 windlight.cloudColor.W = Convert.ToSingle(row["cloud_color_i"]);
1985 windlight.cloudXYDensity.X = Convert.ToSingle(row["cloud_x"]);
1986 windlight.cloudXYDensity.Y = Convert.ToSingle(row["cloud_y"]);
1987 windlight.cloudXYDensity.Z = Convert.ToSingle(row["cloud_density"]);
1988 windlight.cloudCoverage = Convert.ToSingle(row["cloud_coverage"]);
1989 windlight.cloudScale = Convert.ToSingle(row["cloud_scale"]);
1990 windlight.cloudDetailXYDensity.X = Convert.ToSingle(row["cloud_detail_x"]);
1991 windlight.cloudDetailXYDensity.Y = Convert.ToSingle(row["cloud_detail_y"]);
1992 windlight.cloudDetailXYDensity.Z = Convert.ToSingle(row["cloud_detail_density"]);
1993 windlight.cloudScrollX = Convert.ToSingle(row["cloud_scroll_x"]);
1994 windlight.cloudScrollXLock = Convert.ToBoolean(row["cloud_scroll_x_lock"]);
1995 windlight.cloudScrollY = Convert.ToSingle(row["cloud_scroll_y"]);
1996 windlight.cloudScrollYLock = Convert.ToBoolean(row["cloud_scroll_y_lock"]);
1997 windlight.drawClassicClouds = Convert.ToBoolean(row["draw_classic_clouds"]);
1998  
1999 return windlight;
2000 }
2001  
2002 /// <summary>
2003 /// Build a land access entry from the persisted data.
2004 /// </summary>
2005 /// <param name="row"></param>
2006 /// <returns></returns>
2007 private static LandAccessEntry buildLandAccessData(DataRow row)
2008 {
2009 LandAccessEntry entry = new LandAccessEntry();
2010 entry.AgentID = new UUID((string)row["AccessUUID"]);
2011 entry.Flags = (AccessList)row["Flags"];
2012 entry.Expires = 0;
2013 return entry;
2014 }
2015  
2016 /// <summary>
2017 ///
2018 /// </summary>
2019 /// <param name="row"></param>
2020 /// <param name="prim"></param>
2021 /// <param name="sceneGroupID"></param>
2022 /// <param name="regionUUID"></param>
2023 private static void fillPrimRow(DataRow row, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
2024 {
2025 row["UUID"] = prim.UUID.ToString();
2026 row["RegionUUID"] = regionUUID.ToString();
2027 row["CreationDate"] = prim.CreationDate;
2028 row["Name"] = prim.Name;
2029 row["SceneGroupID"] = sceneGroupID.ToString();
2030 // the UUID of the root part for this SceneObjectGroup
2031 // various text fields
2032 row["Text"] = prim.Text;
2033 row["Description"] = prim.Description;
2034 row["SitName"] = prim.SitName;
2035 row["TouchName"] = prim.TouchName;
2036 // permissions
2037 row["ObjectFlags"] = (uint)prim.Flags;
2038 row["CreatorID"] = prim.CreatorIdentification.ToString();
2039 row["OwnerID"] = prim.OwnerID.ToString();
2040 row["GroupID"] = prim.GroupID.ToString();
2041 row["LastOwnerID"] = prim.LastOwnerID.ToString();
2042 row["OwnerMask"] = prim.OwnerMask;
2043 row["NextOwnerMask"] = prim.NextOwnerMask;
2044 row["GroupMask"] = prim.GroupMask;
2045 row["EveryoneMask"] = prim.EveryoneMask;
2046 row["BaseMask"] = prim.BaseMask;
2047 // vectors
2048 row["PositionX"] = prim.OffsetPosition.X;
2049 row["PositionY"] = prim.OffsetPosition.Y;
2050 row["PositionZ"] = prim.OffsetPosition.Z;
2051 row["GroupPositionX"] = prim.GroupPosition.X;
2052 row["GroupPositionY"] = prim.GroupPosition.Y;
2053 row["GroupPositionZ"] = prim.GroupPosition.Z;
2054 row["VelocityX"] = prim.Velocity.X;
2055 row["VelocityY"] = prim.Velocity.Y;
2056 row["VelocityZ"] = prim.Velocity.Z;
2057 row["AngularVelocityX"] = prim.AngularVelocity.X;
2058 row["AngularVelocityY"] = prim.AngularVelocity.Y;
2059 row["AngularVelocityZ"] = prim.AngularVelocity.Z;
2060 row["AccelerationX"] = prim.Acceleration.X;
2061 row["AccelerationY"] = prim.Acceleration.Y;
2062 row["AccelerationZ"] = prim.Acceleration.Z;
2063 // quaternions
2064 row["RotationX"] = prim.RotationOffset.X;
2065 row["RotationY"] = prim.RotationOffset.Y;
2066 row["RotationZ"] = prim.RotationOffset.Z;
2067 row["RotationW"] = prim.RotationOffset.W;
2068  
2069 // Sit target
2070 Vector3 sitTargetPos = prim.SitTargetPositionLL;
2071 row["SitTargetOffsetX"] = sitTargetPos.X;
2072 row["SitTargetOffsetY"] = sitTargetPos.Y;
2073 row["SitTargetOffsetZ"] = sitTargetPos.Z;
2074  
2075 Quaternion sitTargetOrient = prim.SitTargetOrientationLL;
2076 row["SitTargetOrientW"] = sitTargetOrient.W;
2077 row["SitTargetOrientX"] = sitTargetOrient.X;
2078 row["SitTargetOrientY"] = sitTargetOrient.Y;
2079 row["SitTargetOrientZ"] = sitTargetOrient.Z;
2080 row["ColorR"] = Convert.ToInt32(prim.Color.R);
2081 row["ColorG"] = Convert.ToInt32(prim.Color.G);
2082 row["ColorB"] = Convert.ToInt32(prim.Color.B);
2083 row["ColorA"] = Convert.ToInt32(prim.Color.A);
2084 row["PayPrice"] = prim.PayPrice[0];
2085 row["PayButton1"] = prim.PayPrice[1];
2086 row["PayButton2"] = prim.PayPrice[2];
2087 row["PayButton3"] = prim.PayPrice[3];
2088 row["PayButton4"] = prim.PayPrice[4];
2089  
2090 row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
2091 row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
2092  
2093 row["OmegaX"] = prim.AngularVelocity.X;
2094 row["OmegaY"] = prim.AngularVelocity.Y;
2095 row["OmegaZ"] = prim.AngularVelocity.Z;
2096  
2097 row["CameraEyeOffsetX"] = prim.GetCameraEyeOffset().X;
2098 row["CameraEyeOffsetY"] = prim.GetCameraEyeOffset().Y;
2099 row["CameraEyeOffsetZ"] = prim.GetCameraEyeOffset().Z;
2100  
2101 row["CameraAtOffsetX"] = prim.GetCameraAtOffset().X;
2102 row["CameraAtOffsetY"] = prim.GetCameraAtOffset().Y;
2103 row["CameraAtOffsetZ"] = prim.GetCameraAtOffset().Z;
2104  
2105  
2106 if ((prim.SoundFlags & 1) != 0) // Looped
2107 {
2108 row["LoopedSound"] = prim.Sound.ToString();
2109 row["LoopedSoundGain"] = prim.SoundGain;
2110 }
2111 else
2112 {
2113 row["LoopedSound"] = UUID.Zero.ToString();
2114 row["LoopedSoundGain"] = 0.0f;
2115 }
2116  
2117 if (prim.GetForceMouselook())
2118 row["ForceMouselook"] = 1;
2119 else
2120 row["ForceMouselook"] = 0;
2121  
2122 row["ScriptAccessPin"] = prim.ScriptAccessPin;
2123  
2124 if (prim.AllowedDrop)
2125 row["AllowedDrop"] = 1;
2126 else
2127 row["AllowedDrop"] = 0;
2128  
2129 if (prim.DIE_AT_EDGE)
2130 row["DieAtEdge"] = 1;
2131 else
2132 row["DieAtEdge"] = 0;
2133  
2134 row["SalePrice"] = prim.SalePrice;
2135 row["SaleType"] = Convert.ToInt16(prim.ObjectSaleType);
2136  
2137 // click action
2138 row["ClickAction"] = prim.ClickAction;
2139  
2140 row["SalePrice"] = prim.SalePrice;
2141 row["Material"] = prim.Material;
2142  
2143 row["CollisionSound"] = prim.CollisionSound.ToString();
2144 row["CollisionSoundVolume"] = prim.CollisionSoundVolume;
2145 if (prim.VolumeDetectActive)
2146 row["VolumeDetect"] = 1;
2147 else
2148 row["VolumeDetect"] = 0;
2149  
2150 row["MediaURL"] = prim.MediaUrl;
2151  
2152 row["AttachedPosX"] = prim.AttachedPos.X;
2153 row["AttachedPosY"] = prim.AttachedPos.Y;
2154 row["AttachedPosZ"] = prim.AttachedPos.Z;
2155  
2156 if (prim.DynAttrs.CountNamespaces > 0)
2157 row["DynAttrs"] = prim.DynAttrs.ToXml();
2158 else
2159 row["DynAttrs"] = null;
2160  
2161 row["PhysicsShapeType"] = prim.PhysicsShapeType;
2162 row["Density"] = (double)prim.Density;
2163 row["GravityModifier"] = (double)prim.GravityModifier;
2164 row["Friction"] = (double)prim.Friction;
2165 row["Restitution"] = (double)prim.Restitution;
2166  
2167 if (prim.KeyframeMotion != null)
2168 row["KeyframeMotion"] = prim.KeyframeMotion.Serialize();
2169 else
2170 row["KeyframeMotion"] = new Byte[0];
2171  
2172  
2173 }
2174  
2175 /// <summary>
2176 ///
2177 /// </summary>
2178 /// <param name="row"></param>
2179 /// <param name="taskItem"></param>
2180 private static void fillItemRow(DataRow row, TaskInventoryItem taskItem)
2181 {
2182 row["itemID"] = taskItem.ItemID.ToString();
2183 row["primID"] = taskItem.ParentPartID.ToString();
2184 row["assetID"] = taskItem.AssetID.ToString();
2185 row["parentFolderID"] = taskItem.ParentID.ToString();
2186  
2187 row["invType"] = taskItem.InvType;
2188 row["assetType"] = taskItem.Type;
2189  
2190 row["name"] = taskItem.Name;
2191 row["description"] = taskItem.Description;
2192 row["creationDate"] = taskItem.CreationDate;
2193 row["creatorID"] = taskItem.CreatorIdentification.ToString();
2194 row["ownerID"] = taskItem.OwnerID.ToString();
2195 row["lastOwnerID"] = taskItem.LastOwnerID.ToString();
2196 row["groupID"] = taskItem.GroupID.ToString();
2197 row["nextPermissions"] = taskItem.NextPermissions;
2198 row["currentPermissions"] = taskItem.CurrentPermissions;
2199 row["basePermissions"] = taskItem.BasePermissions;
2200 row["everyonePermissions"] = taskItem.EveryonePermissions;
2201 row["groupPermissions"] = taskItem.GroupPermissions;
2202 row["flags"] = taskItem.Flags;
2203 }
2204  
2205 /// <summary>
2206 ///
2207 /// </summary>
2208 /// <param name="row"></param>
2209 /// <param name="land"></param>
2210 /// <param name="regionUUID"></param>
2211 private static void fillLandRow(DataRow row, LandData land, UUID regionUUID)
2212 {
2213 row["UUID"] = land.GlobalID.ToString();
2214 row["RegionUUID"] = regionUUID.ToString();
2215 row["LocalLandID"] = land.LocalID;
2216  
2217 // Bitmap is a byte[512]
2218 row["Bitmap"] = land.Bitmap;
2219  
2220 row["Name"] = land.Name;
2221 row["Desc"] = land.Description;
2222 row["OwnerUUID"] = land.OwnerID.ToString();
2223 row["IsGroupOwned"] = land.IsGroupOwned;
2224 row["Area"] = land.Area;
2225 row["AuctionID"] = land.AuctionID; //Unemplemented
2226 row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory
2227 row["ClaimDate"] = land.ClaimDate;
2228 row["ClaimPrice"] = land.ClaimPrice;
2229 row["GroupUUID"] = land.GroupID.ToString();
2230 row["SalePrice"] = land.SalePrice;
2231 row["LandStatus"] = land.Status; //Enum. OpenMetaverse.Parcel.ParcelStatus
2232 row["LandFlags"] = land.Flags;
2233 row["LandingType"] = land.LandingType;
2234 row["MediaAutoScale"] = land.MediaAutoScale;
2235 row["MediaTextureUUID"] = land.MediaID.ToString();
2236 row["MediaURL"] = land.MediaURL;
2237 row["MusicURL"] = land.MusicURL;
2238 row["PassHours"] = land.PassHours;
2239 row["PassPrice"] = land.PassPrice;
2240 row["SnapshotUUID"] = land.SnapshotID.ToString();
2241 row["UserLocationX"] = land.UserLocation.X;
2242 row["UserLocationY"] = land.UserLocation.Y;
2243 row["UserLocationZ"] = land.UserLocation.Z;
2244 row["UserLookAtX"] = land.UserLookAt.X;
2245 row["UserLookAtY"] = land.UserLookAt.Y;
2246 row["UserLookAtZ"] = land.UserLookAt.Z;
2247 row["AuthbuyerID"] = land.AuthBuyerID.ToString();
2248 row["OtherCleanTime"] = land.OtherCleanTime;
2249 row["Dwell"] = land.Dwell;
2250 row["MediaType"] = land.MediaType;
2251 row["MediaDescription"] = land.MediaDescription;
2252 row["MediaSize"] = String.Format("{0},{1}", land.MediaWidth, land.MediaHeight);
2253 row["MediaLoop"] = land.MediaLoop;
2254 row["ObscureMusic"] = land.ObscureMusic;
2255 row["ObscureMedia"] = land.ObscureMedia;
2256 }
2257  
2258 /// <summary>
2259 ///
2260 /// </summary>
2261 /// <param name="row"></param>
2262 /// <param name="entry"></param>
2263 /// <param name="parcelID"></param>
2264 private static void fillLandAccessRow(DataRow row, LandAccessEntry entry, UUID parcelID)
2265 {
2266 row["LandUUID"] = parcelID.ToString();
2267 row["AccessUUID"] = entry.AgentID.ToString();
2268 row["Flags"] = entry.Flags;
2269 }
2270  
2271 private static void fillRegionSettingsRow(DataRow row, RegionSettings settings)
2272 {
2273 row["regionUUID"] = settings.RegionUUID.ToString();
2274 row["block_terraform"] = settings.BlockTerraform;
2275 row["block_fly"] = settings.BlockFly;
2276 row["allow_damage"] = settings.AllowDamage;
2277 row["restrict_pushing"] = settings.RestrictPushing;
2278 row["allow_land_resell"] = settings.AllowLandResell;
2279 row["allow_land_join_divide"] = settings.AllowLandJoinDivide;
2280 row["block_show_in_search"] = settings.BlockShowInSearch;
2281 row["agent_limit"] = settings.AgentLimit;
2282 row["object_bonus"] = settings.ObjectBonus;
2283 row["maturity"] = settings.Maturity;
2284 row["disable_scripts"] = settings.DisableScripts;
2285 row["disable_collisions"] = settings.DisableCollisions;
2286 row["disable_physics"] = settings.DisablePhysics;
2287 row["terrain_texture_1"] = settings.TerrainTexture1.ToString();
2288 row["terrain_texture_2"] = settings.TerrainTexture2.ToString();
2289 row["terrain_texture_3"] = settings.TerrainTexture3.ToString();
2290 row["terrain_texture_4"] = settings.TerrainTexture4.ToString();
2291 row["elevation_1_nw"] = settings.Elevation1NW;
2292 row["elevation_2_nw"] = settings.Elevation2NW;
2293 row["elevation_1_ne"] = settings.Elevation1NE;
2294 row["elevation_2_ne"] = settings.Elevation2NE;
2295 row["elevation_1_se"] = settings.Elevation1SE;
2296 row["elevation_2_se"] = settings.Elevation2SE;
2297 row["elevation_1_sw"] = settings.Elevation1SW;
2298 row["elevation_2_sw"] = settings.Elevation2SW;
2299 row["water_height"] = settings.WaterHeight;
2300 row["terrain_raise_limit"] = settings.TerrainRaiseLimit;
2301 row["terrain_lower_limit"] = settings.TerrainLowerLimit;
2302 row["use_estate_sun"] = settings.UseEstateSun;
2303 row["sandbox"] = settings.Sandbox; // unlike other database modules, sqlite uses a lower case s for sandbox!
2304 row["sunvectorx"] = settings.SunVector.X;
2305 row["sunvectory"] = settings.SunVector.Y;
2306 row["sunvectorz"] = settings.SunVector.Z;
2307 row["fixed_sun"] = settings.FixedSun;
2308 row["sun_position"] = settings.SunPosition;
2309 row["covenant"] = settings.Covenant.ToString();
2310 row["covenant_datetime"] = settings.CovenantChangedDateTime;
2311 row["map_tile_ID"] = settings.TerrainImageID.ToString();
2312 row["TelehubObject"] = settings.TelehubObject.ToString();
2313 row["parcel_tile_ID"] = settings.ParcelImageID.ToString();
2314 }
2315  
2316 /// <summary>
2317 ///
2318 /// </summary>
2319 /// <param name="row"></param>
2320 /// <param name="windlight"></param>
2321 private static void fillRegionWindlightRow(DataRow row, RegionLightShareData windlight)
2322 {
2323 row["region_id"] = windlight.regionID.ToString();
2324 row["water_color_r"] = windlight.waterColor.X;
2325 row["water_color_g"] = windlight.waterColor.Y;
2326 row["water_color_b"] = windlight.waterColor.Z;
2327 row["water_color_i"] = 1; //windlight.waterColor.W; //not implemented
2328 row["water_fog_density_exponent"] = windlight.waterFogDensityExponent;
2329 row["underwater_fog_modifier"] = windlight.underwaterFogModifier;
2330 row["reflection_wavelet_scale_1"] = windlight.reflectionWaveletScale.X;
2331 row["reflection_wavelet_scale_2"] = windlight.reflectionWaveletScale.Y;
2332 row["reflection_wavelet_scale_3"] = windlight.reflectionWaveletScale.Z;
2333 row["fresnel_scale"] = windlight.fresnelScale;
2334 row["fresnel_offset"] = windlight.fresnelOffset;
2335 row["refract_scale_above"] = windlight.refractScaleAbove;
2336 row["refract_scale_below"] = windlight.refractScaleBelow;
2337 row["blur_multiplier"] = windlight.blurMultiplier;
2338 row["big_wave_direction_x"] = windlight.bigWaveDirection.X;
2339 row["big_wave_direction_y"] = windlight.bigWaveDirection.Y;
2340 row["little_wave_direction_x"] = windlight.littleWaveDirection.X;
2341 row["little_wave_direction_y"] = windlight.littleWaveDirection.Y;
2342 row["normal_map_texture"] = windlight.normalMapTexture.ToString();
2343 row["horizon_r"] = windlight.horizon.X;
2344 row["horizon_g"] = windlight.horizon.Y;
2345 row["horizon_b"] = windlight.horizon.Z;
2346 row["horizon_i"] = windlight.horizon.W;
2347 row["haze_horizon"] = windlight.hazeHorizon;
2348 row["blue_density_r"] = windlight.blueDensity.X;
2349 row["blue_density_g"] = windlight.blueDensity.Y;
2350 row["blue_density_b"] = windlight.blueDensity.Z;
2351 row["blue_density_i"] = windlight.blueDensity.W;
2352 row["haze_density"] = windlight.hazeDensity;
2353 row["density_multiplier"] = windlight.densityMultiplier;
2354 row["distance_multiplier"] = windlight.distanceMultiplier;
2355 row["max_altitude"] = windlight.maxAltitude;
2356 row["sun_moon_color_r"] = windlight.sunMoonColor.X;
2357 row["sun_moon_color_g"] = windlight.sunMoonColor.Y;
2358 row["sun_moon_color_b"] = windlight.sunMoonColor.Z;
2359 row["sun_moon_color_i"] = windlight.sunMoonColor.W;
2360 row["sun_moon_position"] = windlight.sunMoonPosition;
2361 row["ambient_r"] = windlight.ambient.X;
2362 row["ambient_g"] = windlight.ambient.Y;
2363 row["ambient_b"] = windlight.ambient.Z;
2364 row["ambient_i"] = windlight.ambient.W;
2365 row["east_angle"] = windlight.eastAngle;
2366 row["sun_glow_focus"] = windlight.sunGlowFocus;
2367 row["sun_glow_size"] = windlight.sunGlowSize;
2368 row["scene_gamma"] = windlight.sceneGamma;
2369 row["star_brightness"] = windlight.starBrightness;
2370 row["cloud_color_r"] = windlight.cloudColor.X;
2371 row["cloud_color_g"] = windlight.cloudColor.Y;
2372 row["cloud_color_b"] = windlight.cloudColor.Z;
2373 row["cloud_color_i"] = windlight.cloudColor.W;
2374 row["cloud_x"] = windlight.cloudXYDensity.X;
2375 row["cloud_y"] = windlight.cloudXYDensity.Y;
2376 row["cloud_density"] = windlight.cloudXYDensity.Z;
2377 row["cloud_coverage"] = windlight.cloudCoverage;
2378 row["cloud_scale"] = windlight.cloudScale;
2379 row["cloud_detail_x"] = windlight.cloudDetailXYDensity.X;
2380 row["cloud_detail_y"] = windlight.cloudDetailXYDensity.Y;
2381 row["cloud_detail_density"] = windlight.cloudDetailXYDensity.Z;
2382 row["cloud_scroll_x"] = windlight.cloudScrollX;
2383 row["cloud_scroll_x_lock"] = windlight.cloudScrollXLock;
2384 row["cloud_scroll_y"] = windlight.cloudScrollY;
2385 row["cloud_scroll_y_lock"] = windlight.cloudScrollYLock;
2386 row["draw_classic_clouds"] = windlight.drawClassicClouds;
2387 }
2388  
2389 /// <summary>
2390 ///
2391 /// </summary>
2392 /// <param name="row"></param>
2393 /// <returns></returns>
2394 private PrimitiveBaseShape buildShape(DataRow row)
2395 {
2396 PrimitiveBaseShape s = new PrimitiveBaseShape();
2397 s.Scale = new Vector3(
2398 Convert.ToSingle(row["ScaleX"]),
2399 Convert.ToSingle(row["ScaleY"]),
2400 Convert.ToSingle(row["ScaleZ"])
2401 );
2402 // paths
2403 s.PCode = Convert.ToByte(row["PCode"]);
2404 s.PathBegin = Convert.ToUInt16(row["PathBegin"]);
2405 s.PathEnd = Convert.ToUInt16(row["PathEnd"]);
2406 s.PathScaleX = Convert.ToByte(row["PathScaleX"]);
2407 s.PathScaleY = Convert.ToByte(row["PathScaleY"]);
2408 s.PathShearX = Convert.ToByte(row["PathShearX"]);
2409 s.PathShearY = Convert.ToByte(row["PathShearY"]);
2410 s.PathSkew = Convert.ToSByte(row["PathSkew"]);
2411 s.PathCurve = Convert.ToByte(row["PathCurve"]);
2412 s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]);
2413 s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]);
2414 s.PathTaperX = Convert.ToSByte(row["PathTaperX"]);
2415 s.PathTaperY = Convert.ToSByte(row["PathTaperY"]);
2416 s.PathTwist = Convert.ToSByte(row["PathTwist"]);
2417 s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]);
2418 // profile
2419 s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]);
2420 s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]);
2421 s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]);
2422 s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]);
2423 s.State = Convert.ToByte(row["State"]);
2424 s.LastAttachPoint = Convert.ToByte(row["LastAttachPoint"]);
2425  
2426 byte[] textureEntry = (byte[])row["Texture"];
2427 s.TextureEntry = textureEntry;
2428  
2429 s.ExtraParams = (byte[])row["ExtraParams"];
2430  
2431 if (!(row["Media"] is System.DBNull))
2432 s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
2433  
2434 return s;
2435 }
2436  
2437 /// <summary>
2438 ///
2439 /// </summary>
2440 /// <param name="row"></param>
2441 /// <param name="prim"></param>
2442 private static void fillShapeRow(DataRow row, SceneObjectPart prim)
2443 {
2444 PrimitiveBaseShape s = prim.Shape;
2445 row["UUID"] = prim.UUID.ToString();
2446 // shape is an enum
2447 row["Shape"] = 0;
2448 // vectors
2449 row["ScaleX"] = s.Scale.X;
2450 row["ScaleY"] = s.Scale.Y;
2451 row["ScaleZ"] = s.Scale.Z;
2452 // paths
2453 row["PCode"] = s.PCode;
2454 row["PathBegin"] = s.PathBegin;
2455 row["PathEnd"] = s.PathEnd;
2456 row["PathScaleX"] = s.PathScaleX;
2457 row["PathScaleY"] = s.PathScaleY;
2458 row["PathShearX"] = s.PathShearX;
2459 row["PathShearY"] = s.PathShearY;
2460 row["PathSkew"] = s.PathSkew;
2461 row["PathCurve"] = s.PathCurve;
2462 row["PathRadiusOffset"] = s.PathRadiusOffset;
2463 row["PathRevolutions"] = s.PathRevolutions;
2464 row["PathTaperX"] = s.PathTaperX;
2465 row["PathTaperY"] = s.PathTaperY;
2466 row["PathTwist"] = s.PathTwist;
2467 row["PathTwistBegin"] = s.PathTwistBegin;
2468 // profile
2469 row["ProfileBegin"] = s.ProfileBegin;
2470 row["ProfileEnd"] = s.ProfileEnd;
2471 row["ProfileCurve"] = s.ProfileCurve;
2472 row["ProfileHollow"] = s.ProfileHollow;
2473 row["State"] = s.State;
2474 row["LastAttachPoint"] = s.LastAttachPoint;
2475  
2476 row["Texture"] = s.TextureEntry;
2477 row["ExtraParams"] = s.ExtraParams;
2478  
2479 if (s.Media != null)
2480 row["Media"] = s.Media.ToXml();
2481 }
2482  
2483 /// <summary>
2484 /// Persistently store a prim.
2485 /// </summary>
2486 /// <param name="prim"></param>
2487 /// <param name="sceneGroupID"></param>
2488 /// <param name="regionUUID"></param>
2489 private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
2490 {
2491 DataTable prims = ds.Tables["prims"];
2492 DataTable shapes = ds.Tables["primshapes"];
2493  
2494 DataRow primRow = prims.Rows.Find(prim.UUID.ToString());
2495 if (primRow == null)
2496 {
2497 primRow = prims.NewRow();
2498 fillPrimRow(primRow, prim, sceneGroupID, regionUUID);
2499 prims.Rows.Add(primRow);
2500 }
2501 else
2502 {
2503 fillPrimRow(primRow, prim, sceneGroupID, regionUUID);
2504 }
2505  
2506 DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
2507 if (shapeRow == null)
2508 {
2509 shapeRow = shapes.NewRow();
2510 fillShapeRow(shapeRow, prim);
2511 shapes.Rows.Add(shapeRow);
2512 }
2513 else
2514 {
2515 fillShapeRow(shapeRow, prim);
2516 }
2517 }
2518  
2519 /// <summary>
2520 /// </summary>
2521 /// <param name="primID"></param>
2522 /// <param name="items"></param>
2523 public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
2524 {
2525 // m_log.DebugFormat("[SQLITE REGION DB]: Entered StorePrimInventory with prim ID {0}", primID);
2526  
2527 DataTable dbItems = ds.Tables["primitems"];
2528  
2529 // For now, we're just going to crudely remove all the previous inventory items
2530 // no matter whether they have changed or not, and replace them with the current set.
2531 lock (ds)
2532 {
2533 RemoveItems(primID);
2534  
2535 // repalce with current inventory details
2536 foreach (TaskInventoryItem newItem in items)
2537 {
2538 // m_log.InfoFormat(
2539 // "[DATASTORE]: ",
2540 // "Adding item {0}, {1} to prim ID {2}",
2541 // newItem.Name, newItem.ItemID, newItem.ParentPartID);
2542  
2543 DataRow newItemRow = dbItems.NewRow();
2544 fillItemRow(newItemRow, newItem);
2545 dbItems.Rows.Add(newItemRow);
2546 }
2547 }
2548  
2549 Commit();
2550 }
2551  
2552 /***********************************************************************
2553 *
2554 * SQL Statement Creation Functions
2555 *
2556 * These functions create SQL statements for update, insert, and create.
2557 * They can probably be factored later to have a db independant
2558 * portion and a db specific portion
2559 *
2560 **********************************************************************/
2561  
2562 /// <summary>
2563 /// Create an insert command
2564 /// </summary>
2565 /// <param name="table">table name</param>
2566 /// <param name="dt">data table</param>
2567 /// <returns>the created command</returns>
2568 /// <remarks>
2569 /// This is subtle enough to deserve some commentary.
2570 /// Instead of doing *lots* and *lots of hardcoded strings
2571 /// for database definitions we'll use the fact that
2572 /// realistically all insert statements look like "insert
2573 /// into A(b, c) values(:b, :c) on the parameterized query
2574 /// front. If we just have a list of b, c, etc... we can
2575 /// generate these strings instead of typing them out.
2576 /// </remarks>
2577 private static SqliteCommand createInsertCommand(string table, DataTable dt)
2578 {
2579 string[] cols = new string[dt.Columns.Count];
2580 for (int i = 0; i < dt.Columns.Count; i++)
2581 {
2582 DataColumn col = dt.Columns[i];
2583 cols[i] = col.ColumnName;
2584 }
2585  
2586 string sql = "insert into " + table + "(";
2587 sql += String.Join(", ", cols);
2588 // important, the first ':' needs to be here, the rest get added in the join
2589 sql += ") values (:";
2590 sql += String.Join(", :", cols);
2591 sql += ")";
2592 // m_log.DebugFormat("[SQLITE]: Created insert command {0}", sql);
2593 SqliteCommand cmd = new SqliteCommand(sql);
2594  
2595 // this provides the binding for all our parameters, so
2596 // much less code than it used to be
2597 foreach (DataColumn col in dt.Columns)
2598 {
2599 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
2600 }
2601 return cmd;
2602 }
2603  
2604  
2605 /// <summary>
2606 /// create an update command
2607 /// </summary>
2608 /// <param name="table">table name</param>
2609 /// <param name="pk"></param>
2610 /// <param name="dt"></param>
2611 /// <returns>the created command</returns>
2612 private static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt)
2613 {
2614 string sql = "update " + table + " set ";
2615 string subsql = String.Empty;
2616 foreach (DataColumn col in dt.Columns)
2617 {
2618 if (subsql.Length > 0)
2619 {
2620 // a map function would rock so much here
2621 subsql += ", ";
2622 }
2623 subsql += col.ColumnName + "= :" + col.ColumnName;
2624 }
2625 sql += subsql;
2626 sql += " where " + pk;
2627 SqliteCommand cmd = new SqliteCommand(sql);
2628  
2629 // this provides the binding for all our parameters, so
2630 // much less code than it used to be
2631  
2632 foreach (DataColumn col in dt.Columns)
2633 {
2634 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
2635 }
2636 return cmd;
2637 }
2638  
2639 /// <summary>
2640 /// create an update command
2641 /// </summary>
2642 /// <param name="table">table name</param>
2643 /// <param name="pk"></param>
2644 /// <param name="dt"></param>
2645 /// <returns>the created command</returns>
2646 private static SqliteCommand createUpdateCommand(string table, string pk1, string pk2, DataTable dt)
2647 {
2648 string sql = "update " + table + " set ";
2649 string subsql = String.Empty;
2650 foreach (DataColumn col in dt.Columns)
2651 {
2652 if (subsql.Length > 0)
2653 {
2654 // a map function would rock so much here
2655 subsql += ", ";
2656 }
2657 subsql += col.ColumnName + "= :" + col.ColumnName;
2658 }
2659 sql += subsql;
2660 sql += " where " + pk1 + " and " + pk2;
2661 SqliteCommand cmd = new SqliteCommand(sql);
2662  
2663 // this provides the binding for all our parameters, so
2664 // much less code than it used to be
2665  
2666 foreach (DataColumn col in dt.Columns)
2667 {
2668 cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
2669 }
2670 return cmd;
2671 }
2672  
2673 /// <summary>
2674 ///
2675 /// </summary>
2676 /// <param name="dt">Data Table</param>
2677 /// <returns></returns>
2678 // private static string defineTable(DataTable dt)
2679 // {
2680 // string sql = "create table " + dt.TableName + "(";
2681 // string subsql = String.Empty;
2682 // foreach (DataColumn col in dt.Columns)
2683 // {
2684 // if (subsql.Length > 0)
2685 // {
2686 // // a map function would rock so much here
2687 // subsql += ",\n";
2688 // }
2689 // subsql += col.ColumnName + " " + sqliteType(col.DataType);
2690 // if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0])
2691 // {
2692 // subsql += " primary key";
2693 // }
2694 // }
2695 // sql += subsql;
2696 // sql += ")";
2697 // return sql;
2698 // }
2699  
2700 /***********************************************************************
2701 *
2702 * Database Binding functions
2703 *
2704 * These will be db specific due to typing, and minor differences
2705 * in databases.
2706 *
2707 **********************************************************************/
2708  
2709 ///<summary>
2710 /// This is a convenience function that collapses 5 repetitive
2711 /// lines for defining SqliteParameters to 2 parameters:
2712 /// column name and database type.
2713 ///
2714 /// It assumes certain conventions like :param as the param
2715 /// name to replace in parametrized queries, and that source
2716 /// version is always current version, both of which are fine
2717 /// for us.
2718 ///</summary>
2719 ///<returns>a built sqlite parameter</returns>
2720 private static SqliteParameter createSqliteParameter(string name, Type type)
2721 {
2722 SqliteParameter param = new SqliteParameter();
2723 param.ParameterName = ":" + name;
2724 param.DbType = dbtypeFromType(type);
2725 param.SourceColumn = name;
2726 param.SourceVersion = DataRowVersion.Current;
2727 return param;
2728 }
2729  
2730 /// <summary>
2731 ///
2732 /// </summary>
2733 /// <param name="da"></param>
2734 /// <param name="conn"></param>
2735 private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn)
2736 {
2737 da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]);
2738 da.InsertCommand.Connection = conn;
2739  
2740 da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]);
2741 da.UpdateCommand.Connection = conn;
2742  
2743 SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID");
2744 delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
2745 delete.Connection = conn;
2746 da.DeleteCommand = delete;
2747 }
2748  
2749 /// <summary>
2750 ///
2751 /// </summary>
2752 /// <param name="da"></param>
2753 /// <param name="conn"></param>
2754 private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn)
2755 {
2756 da.InsertCommand = createInsertCommand("primitems", ds.Tables["primitems"]);
2757 da.InsertCommand.Connection = conn;
2758  
2759 da.UpdateCommand = createUpdateCommand("primitems", "itemID = :itemID", ds.Tables["primitems"]);
2760 da.UpdateCommand.Connection = conn;
2761  
2762 SqliteCommand delete = new SqliteCommand("delete from primitems where itemID = :itemID");
2763 delete.Parameters.Add(createSqliteParameter("itemID", typeof(String)));
2764 delete.Connection = conn;
2765 da.DeleteCommand = delete;
2766 }
2767  
2768 /// <summary>
2769 ///
2770 /// </summary>
2771 /// <param name="da"></param>
2772 /// <param name="conn"></param>
2773 private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn)
2774 {
2775 da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]);
2776 da.InsertCommand.Connection = conn;
2777 }
2778  
2779 /// <summary>
2780 ///
2781 /// </summary>
2782 /// <param name="da"></param>
2783 /// <param name="conn"></param>
2784 private void setupLandCommands(SqliteDataAdapter da, SqliteConnection conn)
2785 {
2786 da.InsertCommand = createInsertCommand("land", ds.Tables["land"]);
2787 da.InsertCommand.Connection = conn;
2788  
2789 da.UpdateCommand = createUpdateCommand("land", "UUID=:UUID", ds.Tables["land"]);
2790 da.UpdateCommand.Connection = conn;
2791  
2792 SqliteCommand delete = new SqliteCommand("delete from land where UUID=:UUID");
2793 delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
2794 da.DeleteCommand = delete;
2795 da.DeleteCommand.Connection = conn;
2796 }
2797  
2798 /// <summary>
2799 ///
2800 /// </summary>
2801 /// <param name="da"></param>
2802 /// <param name="conn"></param>
2803 private void setupLandAccessCommands(SqliteDataAdapter da, SqliteConnection conn)
2804 {
2805 da.InsertCommand = createInsertCommand("landaccesslist", ds.Tables["landaccesslist"]);
2806 da.InsertCommand.Connection = conn;
2807  
2808 da.UpdateCommand = createUpdateCommand("landaccesslist", "LandUUID=:landUUID", "AccessUUID=:AccessUUID", ds.Tables["landaccesslist"]);
2809 da.UpdateCommand.Connection = conn;
2810  
2811 SqliteCommand delete = new SqliteCommand("delete from landaccesslist where LandUUID= :LandUUID and AccessUUID= :AccessUUID");
2812 delete.Parameters.Add(createSqliteParameter("LandUUID", typeof(String)));
2813 delete.Parameters.Add(createSqliteParameter("AccessUUID", typeof(String)));
2814 da.DeleteCommand = delete;
2815 da.DeleteCommand.Connection = conn;
2816 }
2817  
2818 private void setupRegionSettingsCommands(SqliteDataAdapter da, SqliteConnection conn)
2819 {
2820 da.InsertCommand = createInsertCommand("regionsettings", ds.Tables["regionsettings"]);
2821 da.InsertCommand.Connection = conn;
2822 da.UpdateCommand = createUpdateCommand("regionsettings", "regionUUID=:regionUUID", ds.Tables["regionsettings"]);
2823 da.UpdateCommand.Connection = conn;
2824 }
2825  
2826 /// <summary>
2827 ///
2828 /// </summary>
2829 /// <param name="da"></param>
2830 /// <param name="conn"></param>
2831 private void setupRegionWindlightCommands(SqliteDataAdapter da, SqliteConnection conn)
2832 {
2833 da.InsertCommand = createInsertCommand("regionwindlight", ds.Tables["regionwindlight"]);
2834 da.InsertCommand.Connection = conn;
2835 da.UpdateCommand = createUpdateCommand("regionwindlight", "region_id=:region_id", ds.Tables["regionwindlight"]);
2836 da.UpdateCommand.Connection = conn;
2837 }
2838  
2839 private void setupRegionEnvironmentCommands(SqliteDataAdapter da, SqliteConnection conn)
2840 {
2841 da.InsertCommand = createInsertCommand("regionenvironment", ds.Tables["regionenvironment"]);
2842 da.InsertCommand.Connection = conn;
2843 da.UpdateCommand = createUpdateCommand("regionenvironment", "region_id=:region_id", ds.Tables["regionenvironment"]);
2844 da.UpdateCommand.Connection = conn;
2845 }
2846  
2847 private void setupRegionSpawnPointsCommands(SqliteDataAdapter da, SqliteConnection conn)
2848 {
2849 da.InsertCommand = createInsertCommand("spawn_points", ds.Tables["spawn_points"]);
2850 da.InsertCommand.Connection = conn;
2851 da.UpdateCommand = createUpdateCommand("spawn_points", "RegionID=:RegionID", ds.Tables["spawn_points"]);
2852 da.UpdateCommand.Connection = conn;
2853 }
2854  
2855 /// <summary>
2856 ///
2857 /// </summary>
2858 /// <param name="da"></param>
2859 /// <param name="conn"></param>
2860 private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn)
2861 {
2862 da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]);
2863 da.InsertCommand.Connection = conn;
2864  
2865 da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", ds.Tables["primshapes"]);
2866 da.UpdateCommand.Connection = conn;
2867  
2868 SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID");
2869 delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
2870 delete.Connection = conn;
2871 da.DeleteCommand = delete;
2872 }
2873  
2874 /***********************************************************************
2875 *
2876 * Type conversion functions
2877 *
2878 **********************************************************************/
2879  
2880 /// <summary>
2881 /// Type conversion function
2882 /// </summary>
2883 /// <param name="type"></param>
2884 /// <returns></returns>
2885 private static DbType dbtypeFromType(Type type)
2886 {
2887 if (type == typeof(String))
2888 {
2889 return DbType.String;
2890 }
2891 else if (type == typeof(Int32))
2892 {
2893 return DbType.Int32;
2894 }
2895 else if (type == typeof(Double))
2896 {
2897 return DbType.Double;
2898 }
2899 else if (type == typeof(Byte))
2900 {
2901 return DbType.Byte;
2902 }
2903 else if (type == typeof(Double))
2904 {
2905 return DbType.Double;
2906 }
2907 else if (type == typeof(Byte[]))
2908 {
2909 return DbType.Binary;
2910 }
2911 else
2912 {
2913 return DbType.String;
2914 }
2915 }
2916  
2917 static void PrintDataSet(DataSet ds)
2918 {
2919 // Print out any name and extended properties.
2920 Console.WriteLine("DataSet is named: {0}", ds.DataSetName);
2921 foreach (System.Collections.DictionaryEntry de in ds.ExtendedProperties)
2922 {
2923 Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
2924 }
2925 Console.WriteLine();
2926 foreach (DataTable dt in ds.Tables)
2927 {
2928 Console.WriteLine("=> {0} Table:", dt.TableName);
2929 // Print out the column names.
2930 for (int curCol = 0; curCol < dt.Columns.Count; curCol++)
2931 {
2932 Console.Write(dt.Columns[curCol].ColumnName + "\t");
2933 }
2934 Console.WriteLine("\n----------------------------------");
2935 // Print the DataTable.
2936 for (int curRow = 0; curRow < dt.Rows.Count; curRow++)
2937 {
2938 for (int curCol = 0; curCol < dt.Columns.Count; curCol++)
2939 {
2940 Console.Write(dt.Rows[curRow][curCol].ToString() + "\t");
2941 }
2942 Console.WriteLine();
2943 }
2944 }
2945 }
2946  
2947 public void SaveExtra(UUID regionID, string name, string value)
2948 {
2949 }
2950  
2951 public void RemoveExtra(UUID regionID, string name)
2952 {
2953 }
2954  
2955 public Dictionary<string, string> GetExtra(UUID regionID)
2956 {
2957 return null;
2958 }
2959 }
2960 }