NHibernateRegionData.cs 13 KB

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