1
0

NHibernateRegionData.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  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 OpenSim 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. using System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.IO;
  31. using System.Reflection;
  32. using System.Text.RegularExpressions;
  33. using OpenMetaverse;
  34. using log4net;
  35. using NHibernate;
  36. using NHibernate.Criterion;
  37. using OpenSim.Framework;
  38. using OpenSim.Region.Environment.Interfaces;
  39. using OpenSim.Region.Environment.Scenes;
  40. using Environment=NHibernate.Cfg.Environment;
  41. namespace OpenSim.Data.NHibernate
  42. {
  43. /// <summary>
  44. /// A RegionData Interface to the NHibernate database
  45. /// </summary>
  46. public class NHibernateRegionData : IRegionDataStore
  47. {
  48. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  49. public NHibernateManager manager;
  50. public void Initialise(string connect)
  51. {
  52. m_log.InfoFormat("[NHIBERNATE] Initializing NHibernateRegionData");
  53. manager = new NHibernateManager(connect, "RegionStore");
  54. }
  55. /***********************************************************************
  56. *
  57. * Public Interface Functions
  58. *
  59. **********************************************************************/
  60. public void Dispose() {}
  61. public void StoreRegionSettings(RegionSettings rs)
  62. {
  63. RegionSettings oldRegionSettings = (RegionSettings)manager.Load(typeof(RegionSettings), rs.RegionUUID);
  64. if (oldRegionSettings != null)
  65. {
  66. manager.Update(rs);
  67. }
  68. else
  69. {
  70. manager.Save(rs);
  71. }
  72. }
  73. public RegionSettings LoadRegionSettings(UUID regionUUID)
  74. {
  75. RegionSettings regionSettings = (RegionSettings) manager.Load(typeof(RegionSettings), regionUUID);
  76. if (regionSettings == null)
  77. {
  78. regionSettings = new RegionSettings();
  79. regionSettings.RegionUUID = regionUUID;
  80. manager.Save(regionSettings);
  81. }
  82. regionSettings.OnSave += StoreRegionSettings;
  83. return regionSettings;
  84. }
  85. // This looks inefficient, but it turns out that it isn't
  86. // based on trial runs with nhibernate 1.2
  87. private void SaveOrUpdate(SceneObjectPart p)
  88. {
  89. try
  90. {
  91. SceneObjectPart old = (SceneObjectPart)manager.Load(typeof(SceneObjectPart), p.UUID);
  92. if (old != null)
  93. {
  94. m_log.InfoFormat("[NHIBERNATE] updating object {0}", p.UUID);
  95. manager.Update(p);
  96. }
  97. else
  98. {
  99. m_log.InfoFormat("[NHIBERNATE] saving object {0}", p.UUID);
  100. manager.Save(p);
  101. }
  102. }
  103. catch (Exception e)
  104. {
  105. m_log.Error("[NHIBERNATE] issue saving part", e);
  106. }
  107. }
  108. private void SaveOrUpdate(Terrain t)
  109. {
  110. try
  111. {
  112. Terrain old = (Terrain)manager.Load(typeof(Terrain), t.RegionID);
  113. if (old != null)
  114. {
  115. m_log.InfoFormat("[NHIBERNATE] updating terrain {0}", t.RegionID);
  116. manager.Update(t);
  117. }
  118. else
  119. {
  120. m_log.InfoFormat("[NHIBERNATE] saving terrain {0}", t.RegionID);
  121. manager.Save(t);
  122. }
  123. }
  124. catch (Exception e)
  125. {
  126. m_log.Error("[NHIBERNATE] issue saving terrain", e);
  127. }
  128. }
  129. /// <summary>
  130. /// Adds an object into region storage
  131. /// </summary>
  132. /// <param name="obj">the object</param>
  133. /// <param name="regionUUID">the region UUID</param>
  134. public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
  135. {
  136. uint flags = obj.RootPart.GetEffectiveObjectFlags();
  137. // Eligibility check
  138. if ((flags & (uint)PrimFlags.Temporary) != 0)
  139. return;
  140. if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
  141. return;
  142. try
  143. {
  144. foreach (SceneObjectPart part in obj.Children.Values)
  145. {
  146. m_log.InfoFormat("Storing part {0}", part.UUID);
  147. SaveOrUpdate(part);
  148. }
  149. }
  150. catch (Exception e)
  151. {
  152. m_log.Error("Can't save: ", e);
  153. }
  154. }
  155. private SceneObjectGroup LoadObject(UUID uuid, UUID region)
  156. {
  157. SceneObjectGroup group = new SceneObjectGroup();
  158. ICriteria criteria = manager.GetSession().CreateCriteria(typeof(SceneObjectPart));
  159. criteria.Add(Expression.Eq("RegionID", region));
  160. criteria.Add(Expression.Eq("ParentUUID", uuid));
  161. criteria.AddOrder( Order.Asc("ParentID") );
  162. foreach (SceneObjectPart p in criteria.List())
  163. {
  164. // root part
  165. if (p.UUID == uuid)
  166. {
  167. group.SetRootPart(p);
  168. }
  169. else
  170. {
  171. group.AddPart(p);
  172. }
  173. }
  174. return group;
  175. }
  176. /// <summary>
  177. /// Removes an object from region storage
  178. /// </summary>
  179. /// <param name="obj">the object</param>
  180. /// <param name="regionUUID">the region UUID</param>
  181. public void RemoveObject(UUID obj, UUID regionUUID)
  182. {
  183. SceneObjectGroup g = LoadObject(obj, regionUUID);
  184. foreach (SceneObjectPart p in g.Children.Values)
  185. {
  186. manager.Delete(p);
  187. }
  188. m_log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", obj.Guid, regionUUID);
  189. }
  190. /// <summary>
  191. /// Load persisted objects from region storage.
  192. /// </summary>
  193. /// <param name="regionUUID">The region UUID</param>
  194. /// <returns>List of loaded groups</returns>
  195. public List<SceneObjectGroup> LoadObjects(UUID regionUUID)
  196. {
  197. Dictionary<UUID, SceneObjectGroup> SOG = new Dictionary<UUID, SceneObjectGroup>();
  198. List<SceneObjectGroup> ret = new List<SceneObjectGroup>();
  199. ICriteria criteria = manager.GetSession().CreateCriteria(typeof(SceneObjectPart));
  200. criteria.Add(Expression.Eq("RegionID", regionUUID));
  201. criteria.AddOrder(Order.Asc("ParentID"));
  202. criteria.AddOrder(Order.Asc("LinkNum"));
  203. foreach (SceneObjectPart p in criteria.List())
  204. {
  205. // root part
  206. if (p.UUID == p.ParentUUID)
  207. {
  208. SceneObjectGroup group = new SceneObjectGroup();
  209. group.SetRootPart(p);
  210. SOG.Add(p.ParentUUID, group);
  211. }
  212. else
  213. {
  214. SOG[p.ParentUUID].AddPart(p);
  215. }
  216. // get the inventory
  217. ICriteria InvCriteria = manager.GetSession().CreateCriteria(typeof(TaskInventoryItem));
  218. InvCriteria.Add(Expression.Eq("ParentPartID", p.UUID));
  219. IList<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
  220. foreach (TaskInventoryItem i in InvCriteria.List())
  221. {
  222. inventory.Add(i);
  223. }
  224. if (inventory.Count > 0)
  225. p.Inventory.RestoreInventoryItems(inventory);
  226. }
  227. foreach (SceneObjectGroup g in SOG.Values)
  228. {
  229. ret.Add(g);
  230. }
  231. return ret;
  232. }
  233. /// <summary>
  234. /// Store a terrain revision in region storage
  235. /// </summary>
  236. /// <param name="ter">terrain heightfield</param>
  237. /// <param name="regionID">region UUID</param>
  238. public void StoreTerrain(double[,] ter, UUID regionID)
  239. {
  240. lock (this) {
  241. Terrain t = new Terrain(regionID, ter);
  242. SaveOrUpdate(t);
  243. }
  244. }
  245. /// <summary>
  246. /// Load the latest terrain revision from region storage
  247. /// </summary>
  248. /// <param name="regionID">the region UUID</param>
  249. /// <returns>Heightfield data</returns>
  250. public double[,] LoadTerrain(UUID regionID)
  251. {
  252. Terrain t = (Terrain)manager.Load(typeof(Terrain), regionID);
  253. if (t != null)
  254. {
  255. return t.Doubles;
  256. }
  257. m_log.Info("No terrain yet");
  258. return null;
  259. }
  260. /// <summary>
  261. ///
  262. /// </summary>
  263. /// <param name="globalID"></param>
  264. public void RemoveLandObject(UUID globalID)
  265. {
  266. }
  267. /// <summary>
  268. ///
  269. /// </summary>
  270. /// <param name="parcel"></param>
  271. public void StoreLandObject(ILandObject parcel)
  272. {
  273. }
  274. /// <summary>
  275. ///
  276. /// </summary>
  277. /// <param name="regionUUID"></param>
  278. /// <returns></returns>
  279. public List<LandData> LoadLandObjects(UUID regionUUID)
  280. {
  281. List<LandData> landDataForRegion = new List<LandData>();
  282. return landDataForRegion;
  283. }
  284. /// <summary>
  285. /// See <see cref="Commit"/>
  286. /// </summary>
  287. public void Shutdown()
  288. {
  289. //session.Flush();
  290. }
  291. /// <summary>
  292. /// Load a region banlist
  293. /// </summary>
  294. /// <param name="regionUUID">the region UUID</param>
  295. /// <returns>The banlist</returns>
  296. public List<EstateBan> LoadRegionBanList(UUID regionUUID)
  297. {
  298. List<EstateBan> regionbanlist = new List<EstateBan>();
  299. return regionbanlist;
  300. }
  301. /// <summary>
  302. /// Add en entry into region banlist
  303. /// </summary>
  304. /// <param name="item"></param>
  305. public void AddToRegionBanlist(EstateBan item)
  306. {
  307. }
  308. /// <summary>
  309. /// remove an entry from the region banlist
  310. /// </summary>
  311. /// <param name="item"></param>
  312. public void RemoveFromRegionBanlist(EstateBan item)
  313. {
  314. }
  315. /// <summary>
  316. ///
  317. /// </summary>
  318. /// <param name="val"></param>
  319. /// <returns></returns>
  320. // private static Array serializeTerrain(double[,] val)
  321. // {
  322. // MemoryStream str = new MemoryStream(65536*sizeof (double));
  323. // BinaryWriter bw = new BinaryWriter(str);
  324. //
  325. // // TODO: COMPATIBILITY - Add byte-order conversions
  326. // for (int x = 0; x < 256; x++)
  327. // for (int y = 0; y < 256; y++)
  328. // bw.Write(val[x, y]);
  329. //
  330. // return str.ToArray();
  331. // }
  332. /// <summary>
  333. /// see IRegionDatastore
  334. /// </summary>
  335. /// <param name="primID"></param>
  336. /// <param name="items"></param>
  337. public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
  338. {
  339. ICriteria criteria = manager.GetSession().CreateCriteria(typeof(TaskInventoryItem));
  340. criteria.Add(Expression.Eq("ParentPartID", primID));
  341. try
  342. {
  343. foreach (TaskInventoryItem i in criteria.List())
  344. {
  345. manager.Delete(i);
  346. }
  347. foreach (TaskInventoryItem i in items)
  348. {
  349. manager.Save(i);
  350. }
  351. }
  352. catch (Exception e)
  353. {
  354. m_log.Error("[NHIBERNATE] StoreInvetory", e);
  355. }
  356. }
  357. }
  358. }