MySQLInventoryData.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  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 libsecondlife;
  31. using log4net;
  32. using MySql.Data.MySqlClient;
  33. using OpenSim.Framework;
  34. namespace OpenSim.Data.MySQL
  35. {
  36. /// <summary>
  37. /// A MySQL interface for the inventory server
  38. /// </summary>
  39. public class MySQLInventoryData : IInventoryData
  40. {
  41. private static readonly ILog m_log
  42. = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  43. /// <summary>
  44. /// The database manager
  45. /// </summary>
  46. private MySQLManager database;
  47. /// <summary>
  48. /// <para>Initialises Inventory interface</para>
  49. /// <para>
  50. /// <list type="bullet">
  51. /// <item>Loads and initialises the MySQL storage plugin</item>
  52. /// <item>warns and uses the obsolete mysql_connection.ini if connect string is empty.</item>
  53. /// <item>Check for migration</item>
  54. /// </list>
  55. /// </para>
  56. /// </summary>
  57. /// <param name="connect">connect string</param>
  58. public void Initialise(string connect)
  59. {
  60. if (connect != String.Empty)
  61. {
  62. database = new MySQLManager(connect);
  63. }
  64. else
  65. {
  66. m_log.Warn("Reverting to deprecated mysql_connection.ini file for connection info");
  67. IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
  68. string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
  69. string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
  70. string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
  71. string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
  72. string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
  73. string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
  74. database =
  75. new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
  76. settingPort);
  77. }
  78. // This actually does the roll forward assembly stuff
  79. Assembly assem = GetType().Assembly;
  80. Migration m = new Migration(database.Connection, assem, "InventoryStore");
  81. // TODO: After rev 6000, remove this. People should have
  82. // been rolled onto the new migration code by then.
  83. TestTables(database.Connection, m);
  84. m.Update();
  85. }
  86. #region Test and initialization code
  87. /// <summary>
  88. /// <list type="bullet">
  89. /// <item>Execute CreateFoldersTable.sql if oldVersion == null</item>
  90. /// <item>do nothing if oldVersion != null</item>
  91. /// </list>
  92. /// </summary>
  93. /// <param name="oldVersion"></param>
  94. private void UpgradeFoldersTable(string oldVersion)
  95. {
  96. // null as the version, indicates that the table didn't exist
  97. if (oldVersion == null)
  98. {
  99. database.ExecuteResourceSql("CreateFoldersTable.sql");
  100. return;
  101. }
  102. //// if the table is already at the current version, then we can exit immediately
  103. // if (oldVersion == "Rev. 2")
  104. // return;
  105. // database.ExecuteResourceSql("UpgradeFoldersTableToVersion2.sql");
  106. }
  107. /// <summary>
  108. /// <list type="bullet">
  109. /// <item>Execute CreateItemsTable.sql if oldVersion == null</item>
  110. /// <item>Execute "UpgradeItemsTableToVersion3.sql" if oldVersion start with "Rev. 2;"</item>
  111. /// </list>
  112. /// </summary>
  113. /// <param name="oldVersion"></param>
  114. private void UpgradeItemsTable(string oldVersion)
  115. {
  116. // null as the version, indicates that the table didn't exist
  117. if (oldVersion == null)
  118. {
  119. database.ExecuteResourceSql("CreateItemsTable.sql");
  120. return;
  121. }
  122. // if the table is already at the current version, then we can exit immediately
  123. if (oldVersion.StartsWith("Rev. 2;"))
  124. {
  125. m_log.Info("[INVENTORY DB]: Upgrading inventory items table from Rev. 2 to Rev. 3");
  126. database.ExecuteResourceSql("UpgradeItemsTableToVersion3.sql");
  127. }
  128. }
  129. /// <summary>
  130. ///
  131. /// </summary>
  132. /// <param name="conn">MySQL connection handler</param>
  133. /// <param name="m"></param>
  134. private void TestTables(MySqlConnection conn, Migration m)
  135. {
  136. Dictionary<string, string> tableList = new Dictionary<string, string>();
  137. tableList["inventoryfolders"] = null;
  138. tableList["inventoryitems"] = null;
  139. database.GetTableVersion(tableList);
  140. // if we've already started using migrations, get out of
  141. // here, we've got this under control
  142. if (m.Version > 0)
  143. return;
  144. // if there are no tables, get out of here and let
  145. // migrations do their job
  146. if (
  147. tableList["inventoryfolders"] == null &&
  148. tableList["inventoryitems"] == null
  149. )
  150. return;
  151. // otherwise, let the upgrade on legacy proceed...
  152. UpgradeFoldersTable(tableList["inventoryfolders"]);
  153. UpgradeItemsTable(tableList["inventoryitems"]);
  154. // ... and set the version
  155. if (m.Version == 0)
  156. m.Version = 1;
  157. }
  158. #endregion
  159. /// <summary>
  160. /// The name of this DB provider
  161. /// </summary>
  162. /// <returns>Name of DB provider</returns>
  163. public string getName()
  164. {
  165. return "MySQL Inventory Data Interface";
  166. }
  167. /// <summary>
  168. /// Closes this DB provider
  169. /// </summary>
  170. /// <remarks>do nothing</remarks>
  171. public void Close()
  172. {
  173. // Do nothing.
  174. }
  175. /// <summary>
  176. /// Returns the version of this DB provider
  177. /// </summary>
  178. /// <returns>A string containing the DB provider version</returns>
  179. public string getVersion()
  180. {
  181. return database.getVersion();
  182. }
  183. /// <summary>
  184. /// Returns a list of items in a specified folder
  185. /// </summary>
  186. /// <param name="folderID">The folder to search</param>
  187. /// <returns>A list containing inventory items</returns>
  188. public List<InventoryItemBase> getInventoryInFolder(LLUUID folderID)
  189. {
  190. try
  191. {
  192. lock (database)
  193. {
  194. List<InventoryItemBase> items = new List<InventoryItemBase>();
  195. database.CheckConnection();
  196. MySqlCommand result =
  197. new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid",
  198. database.Connection);
  199. result.Parameters.AddWithValue("?uuid", folderID.ToString());
  200. MySqlDataReader reader = result.ExecuteReader();
  201. while (reader.Read())
  202. items.Add(readInventoryItem(reader));
  203. reader.Close();
  204. result.Dispose();
  205. return items;
  206. }
  207. }
  208. catch (Exception e)
  209. {
  210. database.Reconnect();
  211. m_log.Error(e.ToString());
  212. return null;
  213. }
  214. }
  215. /// <summary>
  216. /// Returns a list of the root folders within a users inventory
  217. /// </summary>
  218. /// <param name="user">The user whos inventory is to be searched</param>
  219. /// <returns>A list of folder objects</returns>
  220. public List<InventoryFolderBase> getUserRootFolders(LLUUID user)
  221. {
  222. try
  223. {
  224. lock (database)
  225. {
  226. database.CheckConnection();
  227. MySqlCommand result =
  228. new MySqlCommand(
  229. "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid",
  230. database.Connection);
  231. result.Parameters.AddWithValue("?uuid", user.ToString());
  232. result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString());
  233. MySqlDataReader reader = result.ExecuteReader();
  234. List<InventoryFolderBase> items = new List<InventoryFolderBase>();
  235. while (reader.Read())
  236. items.Add(readInventoryFolder(reader));
  237. reader.Close();
  238. result.Dispose();
  239. return items;
  240. }
  241. }
  242. catch (Exception e)
  243. {
  244. database.Reconnect();
  245. m_log.Error(e.ToString());
  246. return null;
  247. }
  248. }
  249. /// <summary>
  250. /// see <see cref="InventoryItemBase.getUserRootFolder"/>
  251. /// </summary>
  252. /// <param name="user">The user UUID</param>
  253. /// <returns></returns>
  254. public InventoryFolderBase getUserRootFolder(LLUUID user)
  255. {
  256. try
  257. {
  258. lock (database)
  259. {
  260. database.CheckConnection();
  261. MySqlCommand result =
  262. new MySqlCommand(
  263. "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid",
  264. database.Connection);
  265. result.Parameters.AddWithValue("?uuid", user.ToString());
  266. result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString());
  267. MySqlDataReader reader = result.ExecuteReader();
  268. List<InventoryFolderBase> items = new List<InventoryFolderBase>();
  269. while (reader.Read())
  270. items.Add(readInventoryFolder(reader));
  271. InventoryFolderBase rootFolder = null;
  272. // There should only ever be one root folder for a user. However, if there's more
  273. // than one we'll simply use the first one rather than failing. It would be even
  274. // nicer to print some message to this effect, but this feels like it's too low a
  275. // to put such a message out, and it's too minor right now to spare the time to
  276. // suitably refactor.
  277. if (items.Count > 0)
  278. {
  279. rootFolder = items[0];
  280. }
  281. reader.Close();
  282. result.Dispose();
  283. return rootFolder;
  284. }
  285. }
  286. catch (Exception e)
  287. {
  288. database.Reconnect();
  289. m_log.Error(e.ToString());
  290. return null;
  291. }
  292. }
  293. /// <summary>
  294. /// Return a list of folders in a users inventory contained within the specified folder.
  295. /// This method is only used in tests - in normal operation the user always have one,
  296. /// and only one, root folder.
  297. /// </summary>
  298. /// <param name="parentID">The folder to search</param>
  299. /// <returns>A list of inventory folders</returns>
  300. public List<InventoryFolderBase> getInventoryFolders(LLUUID parentID)
  301. {
  302. try
  303. {
  304. lock (database)
  305. {
  306. database.CheckConnection();
  307. MySqlCommand result =
  308. new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid",
  309. database.Connection);
  310. result.Parameters.AddWithValue("?uuid", parentID.ToString());
  311. MySqlDataReader reader = result.ExecuteReader();
  312. List<InventoryFolderBase> items = new List<InventoryFolderBase>();
  313. while (reader.Read())
  314. items.Add(readInventoryFolder(reader));
  315. reader.Close();
  316. result.Dispose();
  317. return items;
  318. }
  319. }
  320. catch (Exception e)
  321. {
  322. database.Reconnect();
  323. m_log.Error(e.ToString());
  324. return null;
  325. }
  326. }
  327. /// <summary>
  328. /// Reads a one item from an SQL result
  329. /// </summary>
  330. /// <param name="reader">The SQL Result</param>
  331. /// <returns>the item read</returns>
  332. private static InventoryItemBase readInventoryItem(MySqlDataReader reader)
  333. {
  334. try
  335. {
  336. InventoryItemBase item = new InventoryItemBase();
  337. item.ID = new LLUUID((string) reader["inventoryID"]);
  338. item.AssetID = new LLUUID((string) reader["assetID"]);
  339. item.AssetType = (int) reader["assetType"];
  340. item.Folder = new LLUUID((string) reader["parentFolderID"]);
  341. item.Owner = new LLUUID((string) reader["avatarID"]);
  342. item.Name = (string) reader["inventoryName"];
  343. item.Description = (string) reader["inventoryDescription"];
  344. item.NextPermissions = (uint) reader["inventoryNextPermissions"];
  345. item.CurrentPermissions = (uint) reader["inventoryCurrentPermissions"];
  346. item.InvType = (int) reader["invType"];
  347. item.Creator = new LLUUID((string) reader["creatorID"]);
  348. item.BasePermissions = (uint) reader["inventoryBasePermissions"];
  349. item.EveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"];
  350. item.SalePrice = (int) reader["salePrice"];
  351. item.SaleType = Convert.ToByte(reader["saleType"]);
  352. item.CreationDate = (int) reader["creationDate"];
  353. item.GroupID = new LLUUID(reader["groupID"].ToString());
  354. item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]);
  355. item.Flags = (uint) reader["flags"];
  356. return item;
  357. }
  358. catch (MySqlException e)
  359. {
  360. m_log.Error(e.ToString());
  361. }
  362. return null;
  363. }
  364. /// <summary>
  365. /// Returns a specified inventory item
  366. /// </summary>
  367. /// <param name="item">The item to return</param>
  368. /// <returns>An inventory item</returns>
  369. public InventoryItemBase getInventoryItem(LLUUID itemID)
  370. {
  371. try
  372. {
  373. lock (database)
  374. {
  375. database.CheckConnection();
  376. MySqlCommand result =
  377. new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection);
  378. result.Parameters.AddWithValue("?uuid", itemID.ToString());
  379. MySqlDataReader reader = result.ExecuteReader();
  380. InventoryItemBase item = null;
  381. if (reader.Read())
  382. item = readInventoryItem(reader);
  383. reader.Close();
  384. result.Dispose();
  385. return item;
  386. }
  387. }
  388. catch (Exception e)
  389. {
  390. database.Reconnect();
  391. m_log.Error(e.ToString());
  392. }
  393. return null;
  394. }
  395. /// <summary>
  396. /// Reads a list of inventory folders returned by a query.
  397. /// </summary>
  398. /// <param name="reader">A MySQL Data Reader</param>
  399. /// <returns>A List containing inventory folders</returns>
  400. protected static InventoryFolderBase readInventoryFolder(MySqlDataReader reader)
  401. {
  402. try
  403. {
  404. InventoryFolderBase folder = new InventoryFolderBase();
  405. folder.Owner = new LLUUID((string) reader["agentID"]);
  406. folder.ParentID = new LLUUID((string) reader["parentFolderID"]);
  407. folder.ID = new LLUUID((string) reader["folderID"]);
  408. folder.Name = (string) reader["folderName"];
  409. folder.Type = (short) reader["type"];
  410. folder.Version = (ushort) ((int) reader["version"]);
  411. return folder;
  412. }
  413. catch (Exception e)
  414. {
  415. m_log.Error(e.ToString());
  416. }
  417. return null;
  418. }
  419. /// <summary>
  420. /// Returns a specified inventory folder
  421. /// </summary>
  422. /// <param name="folder">The folder to return</param>
  423. /// <returns>A folder class</returns>
  424. public InventoryFolderBase getInventoryFolder(LLUUID folderID)
  425. {
  426. try
  427. {
  428. lock (database)
  429. {
  430. database.CheckConnection();
  431. MySqlCommand result =
  432. new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection);
  433. result.Parameters.AddWithValue("?uuid", folderID.ToString());
  434. MySqlDataReader reader = result.ExecuteReader();
  435. reader.Read();
  436. InventoryFolderBase folder = readInventoryFolder(reader);
  437. reader.Close();
  438. result.Dispose();
  439. return folder;
  440. }
  441. }
  442. catch (Exception e)
  443. {
  444. database.Reconnect();
  445. m_log.Error(e.ToString());
  446. return null;
  447. }
  448. }
  449. /// <summary>
  450. /// Adds a specified item to the database
  451. /// </summary>
  452. /// <param name="item">The inventory item</param>
  453. public void addInventoryItem(InventoryItemBase item)
  454. {
  455. string sql =
  456. "REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName"
  457. + ", inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType"
  458. + ", creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, salePrice, saleType"
  459. + ", creationDate, groupID, groupOwned, flags) VALUES ";
  460. sql +=
  461. "(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription"
  462. + ", ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID"
  463. + ", ?inventoryBasePermissions, ?inventoryEveryOnePermissions, ?salePrice, ?saleType, ?creationDate"
  464. + ", ?groupID, ?groupOwned, ?flags)";
  465. try
  466. {
  467. database.CheckConnection();
  468. MySqlCommand result = new MySqlCommand(sql, database.Connection);
  469. result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
  470. result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
  471. result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
  472. result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString());
  473. result.Parameters.AddWithValue("?avatarID", item.Owner.ToString());
  474. result.Parameters.AddWithValue("?inventoryName", item.Name);
  475. result.Parameters.AddWithValue("?inventoryDescription", item.Description);
  476. result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString());
  477. result.Parameters.AddWithValue("?inventoryCurrentPermissions",
  478. item.CurrentPermissions.ToString());
  479. result.Parameters.AddWithValue("?invType", item.InvType);
  480. result.Parameters.AddWithValue("?creatorID", item.Creator.ToString());
  481. result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
  482. result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
  483. result.Parameters.AddWithValue("?salePrice", item.SalePrice);
  484. result.Parameters.AddWithValue("?saleType", item.SaleType);
  485. result.Parameters.AddWithValue("?creationDate", item.CreationDate);
  486. result.Parameters.AddWithValue("?groupID", item.GroupID);
  487. result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
  488. result.Parameters.AddWithValue("?flags", item.Flags);
  489. lock (database)
  490. {
  491. result.ExecuteNonQuery();
  492. }
  493. result.Dispose();
  494. }
  495. catch (MySqlException e)
  496. {
  497. m_log.Error(e.ToString());
  498. }
  499. }
  500. /// <summary>
  501. /// Updates the specified inventory item
  502. /// </summary>
  503. /// <param name="item">Inventory item to update</param>
  504. public void updateInventoryItem(InventoryItemBase item)
  505. {
  506. addInventoryItem(item);
  507. }
  508. /// <summary>
  509. /// Detele the specified inventory item
  510. /// </summary>
  511. /// <param name="item">The inventory item UUID to delete</param>
  512. public void deleteInventoryItem(LLUUID itemID)
  513. {
  514. try
  515. {
  516. database.CheckConnection();
  517. MySqlCommand cmd =
  518. new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", database.Connection);
  519. cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
  520. lock (database)
  521. {
  522. cmd.ExecuteNonQuery();
  523. }
  524. }
  525. catch (MySqlException e)
  526. {
  527. database.Reconnect();
  528. m_log.Error(e.ToString());
  529. }
  530. }
  531. /// <summary>
  532. /// Creates a new inventory folder
  533. /// </summary>
  534. /// <param name="folder">Folder to create</param>
  535. public void addInventoryFolder(InventoryFolderBase folder)
  536. {
  537. string sql =
  538. "REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES ";
  539. sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)";
  540. database.CheckConnection();
  541. MySqlCommand cmd = new MySqlCommand(sql, database.Connection);
  542. cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
  543. cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
  544. cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
  545. cmd.Parameters.AddWithValue("?folderName", folder.Name);
  546. cmd.Parameters.AddWithValue("?type", (short) folder.Type);
  547. cmd.Parameters.AddWithValue("?version", folder.Version);
  548. try
  549. {
  550. lock (database)
  551. {
  552. cmd.ExecuteNonQuery();
  553. }
  554. }
  555. catch (Exception e)
  556. {
  557. m_log.Error(e.ToString());
  558. }
  559. }
  560. /// <summary>
  561. /// Updates an inventory folder
  562. /// </summary>
  563. /// <param name="folder">Folder to update</param>
  564. public void updateInventoryFolder(InventoryFolderBase folder)
  565. {
  566. addInventoryFolder(folder);
  567. }
  568. /// <summary>
  569. /// Move an inventory folder
  570. /// </summary>
  571. /// <param name="folder">Folder to move</param>
  572. /// <remarks>UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID</remarks>
  573. public void moveInventoryFolder(InventoryFolderBase folder)
  574. {
  575. string sql =
  576. "UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID";
  577. database.CheckConnection();
  578. MySqlCommand cmd = new MySqlCommand(sql, database.Connection);
  579. cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
  580. cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
  581. try
  582. {
  583. lock (database)
  584. {
  585. cmd.ExecuteNonQuery();
  586. }
  587. }
  588. catch (Exception e)
  589. {
  590. m_log.Error(e.ToString());
  591. }
  592. }
  593. /// <summary>
  594. /// Append a list of all the child folders of a parent folder
  595. /// </summary>
  596. /// <param name="folders">list where folders will be appended</param>
  597. /// <param name="parentID">ID of parent</param>
  598. protected void getInventoryFolders(ref List<InventoryFolderBase> folders, LLUUID parentID)
  599. {
  600. List<InventoryFolderBase> subfolderList = getInventoryFolders(parentID);
  601. foreach (InventoryFolderBase f in subfolderList)
  602. folders.Add(f);
  603. }
  604. /// <summary>
  605. /// See IInventoryData
  606. /// </summary>
  607. /// <param name="parentID"></param>
  608. /// <returns></returns>
  609. public List<InventoryFolderBase> getFolderHierarchy(LLUUID parentID)
  610. {
  611. List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
  612. getInventoryFolders(ref folders, parentID);
  613. for (int i = 0; i < folders.Count; i++)
  614. getInventoryFolders(ref folders, folders[i].ID);
  615. return folders;
  616. }
  617. /// <summary>
  618. /// Delete a folder from database
  619. /// </summary>
  620. /// <param name="folderID">the folder UUID</param>
  621. protected void deleteOneFolder(LLUUID folderID)
  622. {
  623. try
  624. {
  625. database.CheckConnection();
  626. MySqlCommand cmd =
  627. new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection);
  628. cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
  629. lock (database)
  630. {
  631. cmd.ExecuteNonQuery();
  632. }
  633. }
  634. catch (MySqlException e)
  635. {
  636. database.Reconnect();
  637. m_log.Error(e.ToString());
  638. }
  639. }
  640. /// <summary>
  641. /// Delete all item in a folder
  642. /// </summary>
  643. /// <param name="folderID">the folder UUID</param>
  644. protected void deleteItemsInFolder(LLUUID folderID)
  645. {
  646. try
  647. {
  648. database.CheckConnection();
  649. MySqlCommand cmd =
  650. new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection);
  651. cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
  652. lock (database)
  653. {
  654. cmd.ExecuteNonQuery();
  655. }
  656. }
  657. catch (MySqlException e)
  658. {
  659. database.Reconnect();
  660. m_log.Error(e.ToString());
  661. }
  662. }
  663. /// <summary>
  664. /// Deletes an inventory folder
  665. /// </summary>
  666. /// <param name="folderId">Id of folder to delete</param>
  667. public void deleteInventoryFolder(LLUUID folderID)
  668. {
  669. List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
  670. //Delete all sub-folders
  671. foreach (InventoryFolderBase f in subFolders)
  672. {
  673. deleteOneFolder(f.ID);
  674. deleteItemsInFolder(f.ID);
  675. }
  676. //Delete the actual row
  677. deleteOneFolder(folderID);
  678. deleteItemsInFolder(folderID);
  679. }
  680. }
  681. }