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