MSSQLInventoryData.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  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.Data;
  30. using System.Data.SqlClient;
  31. using System.Reflection;
  32. using OpenMetaverse;
  33. using log4net;
  34. using OpenSim.Framework;
  35. namespace OpenSim.Data.MSSQL
  36. {
  37. /// <summary>
  38. /// A MSSQL interface for the inventory server
  39. /// </summary>
  40. public class MSSQLInventoryData : IInventoryDataPlugin
  41. {
  42. private const string _migrationStore = "InventoryStore";
  43. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  44. /// <summary>
  45. /// The database manager
  46. /// </summary>
  47. private MSSQLManager database;
  48. #region IPlugin members
  49. [Obsolete("Cannot be default-initialized!")]
  50. public void Initialise()
  51. {
  52. m_log.Info("[MSSQLInventoryData]: " + Name + " cannot be default-initialized!");
  53. throw new PluginNotInitialisedException(Name);
  54. }
  55. /// <summary>
  56. /// Loads and initialises the MSSQL inventory storage interface
  57. /// </summary>
  58. /// <param name="connectionString">connect string</param>
  59. /// <remarks>use mssql_connection.ini</remarks>
  60. public void Initialise(string connectionString)
  61. {
  62. if (!string.IsNullOrEmpty(connectionString))
  63. {
  64. database = new MSSQLManager(connectionString);
  65. }
  66. else
  67. {
  68. IniFile gridDataMSSqlFile = new IniFile("mssql_connection.ini");
  69. string settingDataSource = gridDataMSSqlFile.ParseFileReadValue("data_source");
  70. string settingInitialCatalog = gridDataMSSqlFile.ParseFileReadValue("initial_catalog");
  71. string settingPersistSecurityInfo = gridDataMSSqlFile.ParseFileReadValue("persist_security_info");
  72. string settingUserId = gridDataMSSqlFile.ParseFileReadValue("user_id");
  73. string settingPassword = gridDataMSSqlFile.ParseFileReadValue("password");
  74. database =
  75. new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
  76. settingPassword);
  77. }
  78. //New migrations check of store
  79. database.CheckMigration(_migrationStore);
  80. }
  81. /// <summary>
  82. /// The name of this DB provider
  83. /// </summary>
  84. /// <returns>A string containing the name of the DB provider</returns>
  85. public string Name
  86. {
  87. get { return "MSSQL Inventory Data Interface"; }
  88. }
  89. /// <summary>
  90. /// Closes this DB provider
  91. /// </summary>
  92. public void Dispose()
  93. {
  94. database = null;
  95. }
  96. /// <summary>
  97. /// Returns the version of this DB provider
  98. /// </summary>
  99. /// <returns>A string containing the DB provider</returns>
  100. public string Version
  101. {
  102. get { return database.getVersion(); }
  103. }
  104. #endregion
  105. #region Folder methods
  106. /// <summary>
  107. /// Returns a list of the root folders within a users inventory
  108. /// </summary>
  109. /// <param name="user">The user whos inventory is to be searched</param>
  110. /// <returns>A list of folder objects</returns>
  111. public List<InventoryFolderBase> getUserRootFolders(UUID user)
  112. {
  113. return getInventoryFolders(UUID.Zero, user);
  114. }
  115. /// <summary>
  116. /// see InventoryItemBase.getUserRootFolder
  117. /// </summary>
  118. /// <param name="user">the User UUID</param>
  119. /// <returns></returns>
  120. public InventoryFolderBase getUserRootFolder(UUID user)
  121. {
  122. List<InventoryFolderBase> items = getUserRootFolders(user);
  123. InventoryFolderBase rootFolder = null;
  124. // There should only ever be one root folder for a user. However, if there's more
  125. // than one we'll simply use the first one rather than failing. It would be even
  126. // nicer to print some message to this effect, but this feels like it's too low a
  127. // to put such a message out, and it's too minor right now to spare the time to
  128. // suitably refactor.
  129. if (items.Count > 0)
  130. {
  131. rootFolder = items[0];
  132. }
  133. return rootFolder;
  134. }
  135. /// <summary>
  136. /// Returns a list of folders in a users inventory contained within the specified folder
  137. /// </summary>
  138. /// <param name="parentID">The folder to search</param>
  139. /// <returns>A list of inventory folders</returns>
  140. public List<InventoryFolderBase> getInventoryFolders(UUID parentID)
  141. {
  142. return getInventoryFolders(parentID, UUID.Zero);
  143. }
  144. /// <summary>
  145. /// Returns a specified inventory folder
  146. /// </summary>
  147. /// <param name="folderID">The folder to return</param>
  148. /// <returns>A folder class</returns>
  149. public InventoryFolderBase getInventoryFolder(UUID folderID)
  150. {
  151. using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE folderID = @folderID"))
  152. {
  153. command.Parameters.Add(database.CreateParameter("folderID", folderID));
  154. using (IDataReader reader = command.ExecuteReader())
  155. {
  156. if (reader.Read())
  157. {
  158. return readInventoryFolder(reader);
  159. }
  160. }
  161. }
  162. m_log.InfoFormat("[INVENTORY DB] : FOund no inventory folder with ID : {0}", folderID);
  163. return null;
  164. }
  165. /// <summary>
  166. /// Returns all child folders in the hierarchy from the parent folder and down.
  167. /// Does not return the parent folder itself.
  168. /// </summary>
  169. /// <param name="parentID">The folder to get subfolders for</param>
  170. /// <returns>A list of inventory folders</returns>
  171. public List<InventoryFolderBase> getFolderHierarchy(UUID parentID)
  172. {
  173. //Note maybe change this to use a Dataset that loading in all folders of a user and then go throw it that way.
  174. //Note this is changed so it opens only one connection to the database and not everytime it wants to get data.
  175. List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
  176. using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID"))
  177. {
  178. command.Parameters.Add(database.CreateParameter("@parentID", parentID));
  179. folders.AddRange(getInventoryFolders(command));
  180. List<InventoryFolderBase> tempFolders = new List<InventoryFolderBase>();
  181. foreach (InventoryFolderBase folderBase in folders)
  182. {
  183. tempFolders.AddRange(getFolderHierarchy(folderBase.ID, command));
  184. }
  185. if (tempFolders.Count > 0)
  186. {
  187. folders.AddRange(tempFolders);
  188. }
  189. }
  190. return folders;
  191. }
  192. /// <summary>
  193. /// Creates a new inventory folder
  194. /// </summary>
  195. /// <param name="folder">Folder to create</param>
  196. public void addInventoryFolder(InventoryFolderBase folder)
  197. {
  198. string sql =
  199. "INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version]) VALUES ";
  200. sql += "(@folderID, @agentID, @parentFolderID, @folderName, @type, @version);";
  201. using (AutoClosingSqlCommand command = database.Query(sql))
  202. {
  203. command.Parameters.Add(database.CreateParameter("folderID", folder.ID));
  204. command.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
  205. command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
  206. command.Parameters.Add(database.CreateParameter("folderName", folder.Name));
  207. command.Parameters.Add(database.CreateParameter("type", folder.Type));
  208. command.Parameters.Add(database.CreateParameter("version", folder.Version));
  209. try
  210. {
  211. //IDbCommand result = database.Query(sql, param);
  212. command.ExecuteNonQuery();
  213. }
  214. catch (Exception e)
  215. {
  216. m_log.ErrorFormat("[ASSET DB] Error : {0}", e.Message);
  217. }
  218. }
  219. }
  220. /// <summary>
  221. /// Updates an inventory folder
  222. /// </summary>
  223. /// <param name="folder">Folder to update</param>
  224. public void updateInventoryFolder(InventoryFolderBase folder)
  225. {
  226. using (AutoClosingSqlCommand command = database.Query("UPDATE inventoryfolders set folderID = @folderID, " +
  227. "agentID = @agentID, " +
  228. "parentFolderID = @parentFolderID," +
  229. "folderName = @folderName," +
  230. "type = @type," +
  231. "version = @version where " +
  232. "folderID = @keyFolderID;"))
  233. {
  234. command.Parameters.Add(database.CreateParameter("folderID", folder.ID));
  235. command.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
  236. command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
  237. command.Parameters.Add(database.CreateParameter("folderName", folder.Name));
  238. command.Parameters.Add(database.CreateParameter("type", folder.Type));
  239. command.Parameters.Add(database.CreateParameter("version", folder.Version));
  240. command.Parameters.Add(database.CreateParameter("@keyFolderID", folder.ID));
  241. try
  242. {
  243. command.ExecuteNonQuery();
  244. }
  245. catch (Exception e)
  246. {
  247. m_log.ErrorFormat("[ASSET DB] Error : {0}", e.Message);
  248. }
  249. }
  250. }
  251. /// <summary>
  252. /// Updates an inventory folder
  253. /// </summary>
  254. /// <param name="folder">Folder to update</param>
  255. public void moveInventoryFolder(InventoryFolderBase folder)
  256. {
  257. using (IDbCommand command = database.Query("UPDATE inventoryfolders set " +
  258. "parentFolderID = @parentFolderID where " +
  259. "folderID = @folderID;"))
  260. {
  261. command.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
  262. command.Parameters.Add(database.CreateParameter("@folderID", folder.ID));
  263. try
  264. {
  265. command.ExecuteNonQuery();
  266. }
  267. catch (Exception e)
  268. {
  269. m_log.ErrorFormat("[ASSET DB] Error : {0}", e.Message);
  270. }
  271. }
  272. }
  273. /// <summary>
  274. /// Delete an inventory folder
  275. /// </summary>
  276. /// <param name="folderID">Id of folder to delete</param>
  277. public void deleteInventoryFolder(UUID folderID)
  278. {
  279. using (SqlConnection connection = database.DatabaseConnection())
  280. {
  281. List<InventoryFolderBase> subFolders;
  282. using (SqlCommand command = new SqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID", connection))
  283. {
  284. command.Parameters.Add(database.CreateParameter("@parentID", string.Empty));
  285. AutoClosingSqlCommand autoCommand = new AutoClosingSqlCommand(command);
  286. subFolders = getFolderHierarchy(folderID, autoCommand);
  287. }
  288. //Delete all sub-folders
  289. foreach (InventoryFolderBase f in subFolders)
  290. {
  291. DeleteOneFolder(f.ID, connection);
  292. DeleteItemsInFolder(f.ID, connection);
  293. }
  294. //Delete the actual row
  295. DeleteOneFolder(folderID, connection);
  296. DeleteItemsInFolder(folderID, connection);
  297. connection.Close();
  298. }
  299. }
  300. #endregion
  301. #region Item Methods
  302. /// <summary>
  303. /// Returns a list of items in a specified folder
  304. /// </summary>
  305. /// <param name="folderID">The folder to search</param>
  306. /// <returns>A list containing inventory items</returns>
  307. public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
  308. {
  309. using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID"))
  310. {
  311. command.Parameters.Add(database.CreateParameter("parentFolderID", folderID));
  312. List<InventoryItemBase> items = new List<InventoryItemBase>();
  313. using (SqlDataReader reader = command.ExecuteReader())
  314. {
  315. while (reader.Read())
  316. {
  317. items.Add(readInventoryItem(reader));
  318. }
  319. }
  320. return items;
  321. }
  322. }
  323. /// <summary>
  324. /// Returns a specified inventory item
  325. /// </summary>
  326. /// <param name="itemID">The item ID</param>
  327. /// <returns>An inventory item</returns>
  328. public InventoryItemBase getInventoryItem(UUID itemID)
  329. {
  330. using (AutoClosingSqlCommand result = database.Query("SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID"))
  331. {
  332. result.Parameters.Add(database.CreateParameter("inventoryID", itemID));
  333. using (IDataReader reader = result.ExecuteReader())
  334. {
  335. if (reader.Read())
  336. {
  337. return readInventoryItem(reader);
  338. }
  339. }
  340. }
  341. m_log.InfoFormat("[INVENTORY DB] : Found no inventory item with ID : {0}", itemID);
  342. return null;
  343. }
  344. /// <summary>
  345. /// Adds a specified item to the database
  346. /// </summary>
  347. /// <param name="item">The inventory item</param>
  348. public void addInventoryItem(InventoryItemBase item)
  349. {
  350. if (getInventoryItem(item.ID) != null)
  351. {
  352. updateInventoryItem(item);
  353. return;
  354. }
  355. string sql = "INSERT INTO inventoryitems";
  356. sql += "([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName]"
  357. + ", [inventoryDescription], [inventoryNextPermissions], [inventoryCurrentPermissions]"
  358. + ", [invType], [creatorID], [inventoryBasePermissions], [inventoryEveryOnePermissions], [inventoryGroupPermissions]"
  359. + ", [salePrice], [saleType], [creationDate], [groupID], [groupOwned], [flags]) VALUES ";
  360. sql += "(@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription"
  361. + ", @inventoryNextPermissions, @inventoryCurrentPermissions, @invType, @creatorID"
  362. + ", @inventoryBasePermissions, @inventoryEveryOnePermissions, @inventoryGroupPermissions, @salePrice, @saleType"
  363. + ", @creationDate, @groupID, @groupOwned, @flags);";
  364. using (AutoClosingSqlCommand command = database.Query(sql))
  365. {
  366. command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
  367. command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
  368. command.Parameters.Add(database.CreateParameter("assetType", item.AssetType));
  369. command.Parameters.Add(database.CreateParameter("parentFolderID", item.Folder));
  370. command.Parameters.Add(database.CreateParameter("avatarID", item.Owner));
  371. command.Parameters.Add(database.CreateParameter("inventoryName", item.Name));
  372. command.Parameters.Add(database.CreateParameter("inventoryDescription", item.Description));
  373. command.Parameters.Add(database.CreateParameter("inventoryNextPermissions", item.NextPermissions));
  374. command.Parameters.Add(database.CreateParameter("inventoryCurrentPermissions", item.CurrentPermissions));
  375. command.Parameters.Add(database.CreateParameter("invType", item.InvType));
  376. command.Parameters.Add(database.CreateParameter("creatorID", item.Creator));
  377. command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
  378. command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
  379. command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
  380. command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice));
  381. command.Parameters.Add(database.CreateParameter("saleType", item.SaleType));
  382. command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
  383. command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
  384. command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
  385. command.Parameters.Add(database.CreateParameter("flags", item.Flags));
  386. try
  387. {
  388. command.ExecuteNonQuery();
  389. }
  390. catch (Exception e)
  391. {
  392. m_log.Error("[INVENTORY DB] Error inserting item :" + e.Message);
  393. }
  394. }
  395. }
  396. /// <summary>
  397. /// Updates the specified inventory item
  398. /// </summary>
  399. /// <param name="item">Inventory item to update</param>
  400. public void updateInventoryItem(InventoryItemBase item)
  401. {
  402. using (AutoClosingSqlCommand command = database.Query("UPDATE inventoryitems set inventoryID = @inventoryID, " +
  403. "assetID = @assetID, " +
  404. "assetType = @assetType," +
  405. "parentFolderID = @parentFolderID," +
  406. "avatarID = @avatarID," +
  407. "inventoryName = @inventoryName," +
  408. "inventoryDescription = @inventoryDescription," +
  409. "inventoryNextPermissions = @inventoryNextPermissions," +
  410. "inventoryCurrentPermissions = @inventoryCurrentPermissions," +
  411. "invType = @invType," +
  412. "creatorID = @creatorID," +
  413. "inventoryBasePermissions = @inventoryBasePermissions," +
  414. "inventoryEveryOnePermissions = @inventoryEveryOnePermissions," +
  415. "salePrice = @salePrice," +
  416. "saleType = @saleType," +
  417. "creationDate = @creationDate," +
  418. "groupID = @groupID," +
  419. "groupOwned = @groupOwned," +
  420. "flags = @flags where " +
  421. "inventoryID = @keyInventoryID;"))
  422. {
  423. command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
  424. command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
  425. command.Parameters.Add(database.CreateParameter("assetType", item.AssetType));
  426. command.Parameters.Add(database.CreateParameter("parentFolderID", item.Folder));
  427. command.Parameters.Add(database.CreateParameter("avatarID", item.Owner));
  428. command.Parameters.Add(database.CreateParameter("inventoryName", item.Name));
  429. command.Parameters.Add(database.CreateParameter("inventoryDescription", item.Description));
  430. command.Parameters.Add(database.CreateParameter("inventoryNextPermissions", item.NextPermissions));
  431. command.Parameters.Add(database.CreateParameter("inventoryCurrentPermissions", item.CurrentPermissions));
  432. command.Parameters.Add(database.CreateParameter("invType", item.InvType));
  433. command.Parameters.Add(database.CreateParameter("creatorID", item.Creator));
  434. command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
  435. command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
  436. command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice));
  437. command.Parameters.Add(database.CreateParameter("saleType", item.SaleType));
  438. command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
  439. command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
  440. command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
  441. command.Parameters.Add(database.CreateParameter("flags", item.Flags));
  442. command.Parameters.Add(database.CreateParameter("@keyInventoryID", item.ID));
  443. try
  444. {
  445. command.ExecuteNonQuery();
  446. }
  447. catch (Exception e)
  448. {
  449. m_log.Error("[INVENTORY DB] Error updating item :" + e.Message);
  450. }
  451. }
  452. }
  453. // See IInventoryDataPlugin
  454. /// <summary>
  455. /// Delete an item in inventory database
  456. /// </summary>
  457. /// <param name="itemID">the item UUID</param>
  458. public void deleteInventoryItem(UUID itemID)
  459. {
  460. using (AutoClosingSqlCommand command = database.Query("DELETE FROM inventoryitems WHERE inventoryID=@inventoryID"))
  461. {
  462. command.Parameters.Add(database.CreateParameter("inventoryID", itemID));
  463. try
  464. {
  465. command.ExecuteNonQuery();
  466. }
  467. catch (Exception e)
  468. {
  469. m_log.Error("[INVENTORY DB] Error deleting item :" + e.Message);
  470. }
  471. }
  472. }
  473. /// <summary>
  474. /// Returns all activated gesture-items in the inventory of the specified avatar.
  475. /// </summary>
  476. /// <param name="avatarID">The <see cref="UUID"/> of the avatar</param>
  477. /// <returns>
  478. /// The list of gestures (<see cref="InventoryItemBase"/>s)
  479. /// </returns>
  480. public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
  481. {
  482. using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryitems WHERE avatarId = @uuid AND assetType = @assetType and flags = 1"))
  483. {
  484. command.Parameters.Add(database.CreateParameter("uuid", avatarID));
  485. command.Parameters.Add(database.CreateParameter("assetType", (int)AssetType.Gesture));
  486. using (IDataReader reader = command.ExecuteReader())
  487. {
  488. List<InventoryItemBase> gestureList = new List<InventoryItemBase>();
  489. while (reader.Read())
  490. {
  491. gestureList.Add(readInventoryItem(reader));
  492. }
  493. return gestureList;
  494. }
  495. }
  496. }
  497. #endregion
  498. #region Private methods
  499. /// <summary>
  500. /// Delete an item in inventory database
  501. /// </summary>
  502. /// <param name="folderID">the item ID</param>
  503. /// <param name="connection">connection to the database</param>
  504. private void DeleteItemsInFolder(UUID folderID, SqlConnection connection)
  505. {
  506. using (SqlCommand command = new SqlCommand("DELETE FROM inventoryitems WHERE folderID=@folderID", connection))
  507. {
  508. command.Parameters.Add(database.CreateParameter("folderID", folderID));
  509. try
  510. {
  511. command.ExecuteNonQuery();
  512. }
  513. catch (Exception e)
  514. {
  515. m_log.Error("[INVENTORY DB] Error deleting item :" + e.Message);
  516. }
  517. }
  518. }
  519. /// <summary>
  520. /// Gets the folder hierarchy in a loop.
  521. /// </summary>
  522. /// <param name="parentID">parent ID.</param>
  523. /// <param name="command">SQL command/connection to database</param>
  524. /// <returns></returns>
  525. private static List<InventoryFolderBase> getFolderHierarchy(UUID parentID, AutoClosingSqlCommand command)
  526. {
  527. command.Parameters["@parentID"].Value = parentID.ToString();
  528. List<InventoryFolderBase> folders = getInventoryFolders(command);
  529. if (folders.Count > 0)
  530. {
  531. List<InventoryFolderBase> tempFolders = new List<InventoryFolderBase>();
  532. foreach (InventoryFolderBase folderBase in folders)
  533. {
  534. tempFolders.AddRange(getFolderHierarchy(folderBase.ID, command));
  535. }
  536. if (tempFolders.Count > 0)
  537. {
  538. folders.AddRange(tempFolders);
  539. }
  540. }
  541. return folders;
  542. }
  543. /// <summary>
  544. /// Gets the inventory folders.
  545. /// </summary>
  546. /// <param name="parentID">parentID, use UUID.Zero to get root</param>
  547. /// <param name="user">user id, use UUID.Zero, if you want all folders from a parentID.</param>
  548. /// <returns></returns>
  549. private List<InventoryFolderBase> getInventoryFolders(UUID parentID, UUID user)
  550. {
  551. using (AutoClosingSqlCommand command = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID AND agentID LIKE @uuid"))
  552. {
  553. if (user == UUID.Zero)
  554. {
  555. command.Parameters.Add(database.CreateParameter("uuid", "%"));
  556. }
  557. else
  558. {
  559. command.Parameters.Add(database.CreateParameter("uuid", user));
  560. }
  561. command.Parameters.Add(database.CreateParameter("parentID", parentID));
  562. return getInventoryFolders(command);
  563. }
  564. }
  565. /// <summary>
  566. /// Gets the inventory folders.
  567. /// </summary>
  568. /// <param name="command">SQLcommand.</param>
  569. /// <returns></returns>
  570. private static List<InventoryFolderBase> getInventoryFolders(AutoClosingSqlCommand command)
  571. {
  572. using (IDataReader reader = command.ExecuteReader())
  573. {
  574. List<InventoryFolderBase> items = new List<InventoryFolderBase>();
  575. while (reader.Read())
  576. {
  577. items.Add(readInventoryFolder(reader));
  578. }
  579. return items;
  580. }
  581. }
  582. /// <summary>
  583. /// Reads a list of inventory folders returned by a query.
  584. /// </summary>
  585. /// <param name="reader">A MSSQL Data Reader</param>
  586. /// <returns>A List containing inventory folders</returns>
  587. protected static InventoryFolderBase readInventoryFolder(IDataReader reader)
  588. {
  589. try
  590. {
  591. InventoryFolderBase folder = new InventoryFolderBase();
  592. folder.Owner = new UUID((string)reader["agentID"]);
  593. folder.ParentID = new UUID((string)reader["parentFolderID"]);
  594. folder.ID = new UUID((string)reader["folderID"]);
  595. folder.Name = (string)reader["folderName"];
  596. folder.Type = (short)reader["type"];
  597. folder.Version = Convert.ToUInt16(reader["version"]);
  598. return folder;
  599. }
  600. catch (Exception e)
  601. {
  602. m_log.Error("[INVENTORY DB] Error reading inventory folder :" + e.Message);
  603. }
  604. return null;
  605. }
  606. /// <summary>
  607. /// Reads a one item from an SQL result
  608. /// </summary>
  609. /// <param name="reader">The SQL Result</param>
  610. /// <returns>the item read</returns>
  611. private static InventoryItemBase readInventoryItem(IDataRecord reader)
  612. {
  613. try
  614. {
  615. InventoryItemBase item = new InventoryItemBase();
  616. item.ID = new UUID(reader["inventoryID"].ToString());
  617. item.AssetID = new UUID(reader["assetID"].ToString());
  618. item.AssetType = Convert.ToInt32(reader["assetType"].ToString());
  619. item.Folder = new UUID(reader["parentFolderID"].ToString());
  620. item.Owner = new UUID(reader["avatarID"].ToString());
  621. item.Name = reader["inventoryName"].ToString();
  622. item.Description = reader["inventoryDescription"].ToString();
  623. item.NextPermissions = Convert.ToUInt32(reader["inventoryNextPermissions"]);
  624. item.CurrentPermissions = Convert.ToUInt32(reader["inventoryCurrentPermissions"]);
  625. item.InvType = Convert.ToInt32(reader["invType"].ToString());
  626. item.Creator = new UUID(reader["creatorID"].ToString());
  627. item.BasePermissions = Convert.ToUInt32(reader["inventoryBasePermissions"]);
  628. item.EveryOnePermissions = Convert.ToUInt32(reader["inventoryEveryOnePermissions"]);
  629. item.GroupPermissions = Convert.ToUInt32(reader["inventoryGroupPermissions"]);
  630. item.SalePrice = Convert.ToInt32(reader["salePrice"]);
  631. item.SaleType = Convert.ToByte(reader["saleType"]);
  632. item.CreationDate = Convert.ToInt32(reader["creationDate"]);
  633. item.GroupID = new UUID(reader["groupID"].ToString());
  634. item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]);
  635. item.Flags = Convert.ToUInt32(reader["flags"]);
  636. return item;
  637. }
  638. catch (SqlException e)
  639. {
  640. m_log.Error("[INVENTORY DB] Error reading inventory item :" + e.Message);
  641. }
  642. return null;
  643. }
  644. /// <summary>
  645. /// Delete a folder in inventory databasae
  646. /// </summary>
  647. /// <param name="folderID">the folder UUID</param>
  648. /// <param name="connection">connection to database</param>
  649. private void DeleteOneFolder(UUID folderID, SqlConnection connection)
  650. {
  651. try
  652. {
  653. using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID", connection))
  654. {
  655. command.Parameters.Add(database.CreateParameter("folderID", folderID));
  656. command.ExecuteNonQuery();
  657. }
  658. }
  659. catch (SqlException e)
  660. {
  661. m_log.Error("[INVENTORY DB] Error deleting folder :" + e.Message);
  662. }
  663. }
  664. #endregion
  665. }
  666. }