OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
MySQLInventoryData.cs
Go to the documentation of this file.
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.Reflection;
31 using log4net;
32 using MySql.Data.MySqlClient;
33 using OpenMetaverse;
34 using OpenSim.Framework;
35 using OpenSim.Data;
36 
37 namespace OpenSim.Data.MySQL
38 {
43  {
44  private static readonly ILog m_log
45  = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 
47  private string m_connectionString;
48  private object m_dbLock = new object();
49 
50  public string Version { get { return "1.0.0.0"; } }
51 
52  public void Initialise()
53  {
54  m_log.Info("[MySQLInventoryData]: " + Name + " cannot be default-initialized!");
55  throw new PluginNotInitialisedException (Name);
56  }
57 
69  public void Initialise(string connect)
70  {
71  m_connectionString = connect;
72 
73  // This actually does the roll forward assembly stuff
74  Assembly assem = GetType().Assembly;
75 
76  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
77  {
78  dbcon.Open();
79  Migration m = new Migration(dbcon, assem, "InventoryStore");
80  m.Update();
81  }
82  }
83 
88  public string Name
89  {
90  get { return "MySQL Inventory Data Interface"; }
91  }
92 
97  public void Dispose()
98  {
99  // Do nothing.
100  }
101 
107  public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
108  {
109  try
110  {
111  lock (m_dbLock)
112  {
113  List<InventoryItemBase> items = new List<InventoryItemBase>();
114 
115  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
116  {
117  dbcon.Open();
118 
119  using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", dbcon))
120  {
121  result.Parameters.AddWithValue("?uuid", folderID.ToString());
122 
123  using (MySqlDataReader reader = result.ExecuteReader())
124  {
125  while (reader.Read())
126  {
127  // A null item (because something went wrong) breaks everything in the folder
128  InventoryItemBase item = readInventoryItem(reader);
129  if (item != null)
130  items.Add(item);
131  }
132 
133  return items;
134  }
135  }
136  }
137  }
138  }
139  catch (Exception e)
140  {
141  m_log.Error(e.Message, e);
142  return null;
143  }
144  }
145 
151  public List<InventoryFolderBase> getUserRootFolders(UUID user)
152  {
153  try
154  {
155  lock (m_dbLock)
156  {
157  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
158  {
159  dbcon.Open();
160 
161  using (MySqlCommand result = new MySqlCommand(
162  "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon))
163  {
164  result.Parameters.AddWithValue("?uuid", user.ToString());
165  result.Parameters.AddWithValue("?zero", UUID.Zero.ToString());
166 
167  using (MySqlDataReader reader = result.ExecuteReader())
168  {
169  List<InventoryFolderBase> items = new List<InventoryFolderBase>();
170  while (reader.Read())
171  items.Add(readInventoryFolder(reader));
172 
173  return items;
174  }
175  }
176  }
177  }
178  }
179  catch (Exception e)
180  {
181  m_log.Error(e.Message, e);
182  return null;
183  }
184  }
185 
186 
193  {
194  try
195  {
196  lock (m_dbLock)
197  {
198  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
199  {
200  dbcon.Open();
201 
202  using (MySqlCommand result = new MySqlCommand(
203  "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon))
204  {
205  result.Parameters.AddWithValue("?uuid", user.ToString());
206  result.Parameters.AddWithValue("?zero", UUID.Zero.ToString());
207 
208  using (MySqlDataReader reader = result.ExecuteReader())
209  {
210  List<InventoryFolderBase> items = new List<InventoryFolderBase>();
211  while (reader.Read())
212  items.Add(readInventoryFolder(reader));
213 
214  InventoryFolderBase rootFolder = null;
215 
216  // There should only ever be one root folder for a user. However, if there's more
217  // than one we'll simply use the first one rather than failing. It would be even
218  // nicer to print some message to this effect, but this feels like it's too low a
219  // to put such a message out, and it's too minor right now to spare the time to
220  // suitably refactor.
221  if (items.Count > 0)
222  rootFolder = items[0];
223 
224  return rootFolder;
225  }
226  }
227  }
228  }
229  }
230  catch (Exception e)
231  {
232  m_log.Error(e.Message, e);
233  return null;
234  }
235  }
236 
244  public List<InventoryFolderBase> getInventoryFolders(UUID parentID)
245  {
246  try
247  {
248  lock (m_dbLock)
249  {
250  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
251  {
252  dbcon.Open();
253 
254  using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", dbcon))
255  {
256  result.Parameters.AddWithValue("?uuid", parentID.ToString());
257  using (MySqlDataReader reader = result.ExecuteReader())
258  {
259  List<InventoryFolderBase> items = new List<InventoryFolderBase>();
260 
261  while (reader.Read())
262  items.Add(readInventoryFolder(reader));
263 
264  return items;
265  }
266  }
267  }
268  }
269  }
270  catch (Exception e)
271  {
272  m_log.Error(e.Message, e);
273  return null;
274  }
275  }
276 
282  private static InventoryItemBase readInventoryItem(MySqlDataReader reader)
283  {
284  try
285  {
287 
288  // TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these.
289  // (DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero)
290  item.CreatorId = reader["creatorID"].ToString();
291 
292  // Be a bit safer in parsing these because the
293  // database doesn't enforce them to be not null, and
294  // the inventory still works if these are weird in the
295  // db
296 
297  // (Empty is Ok, but "weird" will throw!)
298  item.Owner = DBGuid.FromDB(reader["avatarID"]);
299  item.GroupID = DBGuid.FromDB(reader["groupID"]);
300 
301  // Rest of the parsing. If these UUID's fail, we're dead anyway
302  item.ID = DBGuid.FromDB(reader["inventoryID"]);
303  item.AssetID = DBGuid.FromDB(reader["assetID"]);
304  item.AssetType = (int) reader["assetType"];
305  item.Folder = DBGuid.FromDB(reader["parentFolderID"]);
306  item.Name = (string)(reader["inventoryName"] ?? String.Empty);
307  item.Description = (string)(reader["inventoryDescription"] ?? String.Empty);
308  item.NextPermissions = (uint) reader["inventoryNextPermissions"];
309  item.CurrentPermissions = (uint) reader["inventoryCurrentPermissions"];
310  item.InvType = (int) reader["invType"];
311  item.BasePermissions = (uint) reader["inventoryBasePermissions"];
312  item.EveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"];
313  item.GroupPermissions = (uint) reader["inventoryGroupPermissions"];
314  item.SalePrice = (int) reader["salePrice"];
315  item.SaleType = unchecked((byte)(Convert.ToSByte(reader["saleType"])));
316  item.CreationDate = (int) reader["creationDate"];
317  item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]);
318  item.Flags = (uint) reader["flags"];
319 
320  return item;
321  }
322  catch (MySqlException e)
323  {
324  m_log.Error(e.ToString());
325  }
326 
327  return null;
328  }
329 
336  {
337  try
338  {
339  lock (m_dbLock)
340  {
341  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
342  {
343  dbcon.Open();
344 
345  using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", dbcon))
346  {
347  result.Parameters.AddWithValue("?uuid", itemID.ToString());
348 
349  using (MySqlDataReader reader = result.ExecuteReader())
350  {
351  InventoryItemBase item = null;
352  if (reader.Read())
353  item = readInventoryItem(reader);
354 
355  return item;
356  }
357  }
358  }
359  }
360  }
361  catch (Exception e)
362  {
363  m_log.Error(e.Message, e);
364  }
365  return null;
366  }
367 
373  protected static InventoryFolderBase readInventoryFolder(MySqlDataReader reader)
374  {
375  try
376  {
378  folder.Owner = DBGuid.FromDB(reader["agentID"]);
379  folder.ParentID = DBGuid.FromDB(reader["parentFolderID"]);
380  folder.ID = DBGuid.FromDB(reader["folderID"]);
381  folder.Name = (string) reader["folderName"];
382  folder.Type = (short) reader["type"];
383  folder.Version = (ushort) ((int) reader["version"]);
384  return folder;
385  }
386  catch (Exception e)
387  {
388  m_log.Error(e.Message, e);
389  }
390 
391  return null;
392  }
393 
394 
401  {
402  try
403  {
404  lock (m_dbLock)
405  {
406  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
407  {
408  dbcon.Open();
409 
410  using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon))
411  {
412  result.Parameters.AddWithValue("?uuid", folderID.ToString());
413 
414  using (MySqlDataReader reader = result.ExecuteReader())
415  {
416  InventoryFolderBase folder = null;
417  if (reader.Read())
418  folder = readInventoryFolder(reader);
419 
420  return folder;
421  }
422  }
423  }
424  }
425  }
426  catch (Exception e)
427  {
428  m_log.Error(e.Message, e);
429  return null;
430  }
431  }
432 
438  {
439  string sql =
440  "REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName"
441  + ", inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType"
442  + ", creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, inventoryGroupPermissions, salePrice, saleType"
443  + ", creationDate, groupID, groupOwned, flags) VALUES ";
444  sql +=
445  "(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription"
446  + ", ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID"
447  + ", ?inventoryBasePermissions, ?inventoryEveryOnePermissions, ?inventoryGroupPermissions, ?salePrice, ?saleType, ?creationDate"
448  + ", ?groupID, ?groupOwned, ?flags)";
449 
450  string itemName = item.Name;
451  if (item.Name.Length > 64)
452  {
453  itemName = item.Name.Substring(0, 64);
454  m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length + " to " + itemName.Length + " characters on add item");
455  }
456 
457  string itemDesc = item.Description;
458  if (item.Description.Length > 128)
459  {
460  itemDesc = item.Description.Substring(0, 128);
461  m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length + " to " + itemDesc.Length + " characters on add item");
462  }
463 
464  try
465  {
466  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
467  {
468  dbcon.Open();
469 
470  using (MySqlCommand result = new MySqlCommand(sql, dbcon))
471  {
472  result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
473  result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
474  result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
475  result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString());
476  result.Parameters.AddWithValue("?avatarID", item.Owner.ToString());
477  result.Parameters.AddWithValue("?inventoryName", itemName);
478  result.Parameters.AddWithValue("?inventoryDescription", itemDesc);
479  result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString());
480  result.Parameters.AddWithValue("?inventoryCurrentPermissions",
481  item.CurrentPermissions.ToString());
482  result.Parameters.AddWithValue("?invType", item.InvType);
483  result.Parameters.AddWithValue("?creatorID", item.CreatorId);
484  result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
485  result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
486  result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions);
487  result.Parameters.AddWithValue("?salePrice", item.SalePrice);
488  result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType));
489  result.Parameters.AddWithValue("?creationDate", item.CreationDate);
490  result.Parameters.AddWithValue("?groupID", item.GroupID);
491  result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
492  result.Parameters.AddWithValue("?flags", item.Flags);
493 
494  lock (m_dbLock)
495  result.ExecuteNonQuery();
496 
497  result.Dispose();
498  }
499 
500  using (MySqlCommand result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon))
501  {
502  result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
503 
504  lock (m_dbLock)
505  result.ExecuteNonQuery();
506  }
507  }
508  }
509  catch (MySqlException e)
510  {
511  m_log.Error(e.ToString());
512  }
513  }
514 
520  {
521  addInventoryItem(item);
522  }
523 
528  public void deleteInventoryItem(UUID itemID)
529  {
530  try
531  {
532  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
533  {
534  dbcon.Open();
535 
536  using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon))
537  {
538  cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
539 
540  lock (m_dbLock)
541  cmd.ExecuteNonQuery();
542  }
543  }
544  }
545  catch (MySqlException e)
546  {
547  m_log.Error(e.Message, e);
548  }
549  }
550 
552  {
553  return getInventoryItem(itemID);
554  }
555 
557  {
558  return getInventoryFolder(folderID);
559  }
560 
566  {
567  string sql =
568  "REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES ";
569  sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)";
570 
571  string folderName = folder.Name;
572  if (folderName.Length > 64)
573  {
574  folderName = folderName.Substring(0, 64);
575  m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length + " to " + folderName.Length + " characters on add folder");
576  }
577 
578  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
579  {
580  dbcon.Open();
581 
582  using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
583  {
584  cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
585  cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
586  cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
587  cmd.Parameters.AddWithValue("?folderName", folderName);
588  cmd.Parameters.AddWithValue("?type", folder.Type);
589  cmd.Parameters.AddWithValue("?version", folder.Version);
590 
591  try
592  {
593  lock (m_dbLock)
594  {
595  cmd.ExecuteNonQuery();
596  }
597  }
598  catch (Exception e)
599  {
600  m_log.Error(e.ToString());
601  }
602  }
603  }
604  }
605 
611  {
612  addInventoryFolder(folder);
613  }
614 
621  {
622  string sql =
623  "UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID";
624 
625  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
626  {
627  dbcon.Open();
628 
629  using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
630  {
631  cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
632  cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
633 
634  try
635  {
636  lock (m_dbLock)
637  {
638  cmd.ExecuteNonQuery();
639  }
640  }
641  catch (Exception e)
642  {
643  m_log.Error(e.ToString());
644  }
645  }
646  }
647  }
648 
654  protected void getInventoryFolders(ref List<InventoryFolderBase> folders, UUID parentID)
655  {
656  List<InventoryFolderBase> subfolderList = getInventoryFolders(parentID);
657 
658  foreach (InventoryFolderBase f in subfolderList)
659  folders.Add(f);
660  }
661 
662 
668  public List<InventoryFolderBase> getFolderHierarchy(UUID parentID)
669  {
670  /* Note: There are subtle changes between this implementation of getFolderHierarchy and the previous one
671  * - We will only need to hit the database twice instead of n times.
672  * - We assume the database is well-formed - no stranded/dangling folders, all folders in heirarchy owned
673  * by the same person, each user only has 1 inventory heirarchy
674  * - The returned list is not ordered, instead of breadth-first ordered
675  There are basically 2 usage cases for getFolderHeirarchy:
676  1) Getting the user's entire inventory heirarchy when they log in
677  2) Finding a subfolder heirarchy to delete when emptying the trash.
678  This implementation will pull all inventory folders from the database, and then prune away any folder that
679  is not part of the requested sub-heirarchy. The theory is that it is cheaper to make 1 request from the
680  database than to make n requests. This pays off only if requested heirarchy is large.
681  By making this choice, we are making the worst case better at the cost of making the best case worse.
682  This way is generally better because we don't have to rebuild the connection/sql query per subfolder,
683  even if we end up getting more data from the SQL server than we need.
684  - Francis
685  */
686  try
687  {
688  List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
689  Dictionary<UUID, List<InventoryFolderBase>> hashtable = new Dictionary<UUID, List<InventoryFolderBase>>(); ;
690  List<InventoryFolderBase> parentFolder = new List<InventoryFolderBase>();
691  bool buildResultsFromHashTable = false;
692 
693  lock (m_dbLock)
694  {
695  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
696  {
697  dbcon.Open();
698 
699  /* Fetch the parent folder from the database to determine the agent ID, and if
700  * we're querying the root of the inventory folder tree */
701  using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon))
702  {
703  result.Parameters.AddWithValue("?uuid", parentID.ToString());
704 
705  using (MySqlDataReader reader = result.ExecuteReader())
706  {
707  // Should be at most 1 result
708  while (reader.Read())
709  parentFolder.Add(readInventoryFolder(reader));
710  }
711  }
712 
713  if (parentFolder.Count >= 1) // No result means parent folder does not exist
714  {
715  if (parentFolder[0].ParentID == UUID.Zero) // We are querying the root folder
716  {
717  /* Get all of the agent's folders from the database, put them in a list and return it */
718  using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon))
719  {
720  result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString());
721 
722  using (MySqlDataReader reader = result.ExecuteReader())
723  {
724  while (reader.Read())
725  {
726  InventoryFolderBase curFolder = readInventoryFolder(reader);
727  if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list
728  folders.Add(curFolder);
729  }
730  }
731  }
732  } // if we are querying the root folder
733  else // else we are querying a subtree of the inventory folder tree
734  {
735  /* Get all of the agent's folders from the database, put them all in a hash table
736  * indexed by their parent ID */
737  using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon))
738  {
739  result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString());
740 
741  using (MySqlDataReader reader = result.ExecuteReader())
742  {
743  while (reader.Read())
744  {
745  InventoryFolderBase curFolder = readInventoryFolder(reader);
746  if (hashtable.ContainsKey(curFolder.ParentID)) // Current folder already has a sibling
747  hashtable[curFolder.ParentID].Add(curFolder); // append to sibling list
748  else // else current folder has no known (yet) siblings
749  {
750  List<InventoryFolderBase> siblingList = new List<InventoryFolderBase>();
751  siblingList.Add(curFolder);
752  // Current folder has no known (yet) siblings
753  hashtable.Add(curFolder.ParentID, siblingList);
754  }
755  } // while more items to read from the database
756  }
757  }
758 
759  // Set flag so we know we need to build the results from the hash table after
760  // we unlock the database
761  buildResultsFromHashTable = true;
762 
763  } // else we are querying a subtree of the inventory folder tree
764  } // if folder parentID exists
765 
766  if (buildResultsFromHashTable)
767  {
768  /* We have all of the user's folders stored in a hash table indexed by their parent ID
769  * and we need to return the requested subtree. We will build the requested subtree
770  * by performing a breadth-first-search on the hash table */
771  if (hashtable.ContainsKey(parentID))
772  folders.AddRange(hashtable[parentID]);
773  for (int i = 0; i < folders.Count; i++) // **Note: folders.Count is *not* static
774  if (hashtable.ContainsKey(folders[i].ID))
775  folders.AddRange(hashtable[folders[i].ID]);
776  }
777  }
778  } // lock (database)
779 
780  return folders;
781  }
782  catch (Exception e)
783  {
784  m_log.Error(e.Message, e);
785  return null;
786  }
787  }
788 
793  protected void deleteOneFolder(UUID folderID)
794  {
795  try
796  {
797  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
798  {
799  dbcon.Open();
800 
801  // System folders can never be deleted. Period.
802  using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid and type=-1", dbcon))
803  {
804  cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
805 
806  lock (m_dbLock)
807  cmd.ExecuteNonQuery();
808  }
809  }
810  }
811  catch (MySqlException e)
812  {
813  m_log.Error(e.Message, e);
814  }
815  }
816 
821  protected void deleteItemsInFolder(UUID folderID)
822  {
823  try
824  {
825  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
826  {
827  dbcon.Open();
828 
829  using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", dbcon))
830  {
831  cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
832 
833  lock (m_dbLock)
834  cmd.ExecuteNonQuery();
835  }
836  }
837  }
838  catch (MySqlException e)
839  {
840  m_log.Error(e.ToString());
841  }
842  }
843 
848  public void deleteInventoryFolder(UUID folderID)
849  {
850  List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
851 
852  //Delete all sub-folders
853  foreach (InventoryFolderBase f in subFolders)
854  {
855  deleteOneFolder(f.ID);
856  deleteItemsInFolder(f.ID);
857  }
858 
859  //Delete the actual row
860  deleteOneFolder(folderID);
861  deleteItemsInFolder(folderID);
862  }
863 
864  public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
865  {
866  lock (m_dbLock)
867  {
868  try
869  {
870  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
871  {
872  dbcon.Open();
873 
874  using (MySqlCommand sqlCmd = new MySqlCommand(
875  "SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags & 1", dbcon))
876  {
877  sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString());
878  sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture);
879 
880  using (MySqlDataReader result = sqlCmd.ExecuteReader())
881  {
882  List<InventoryItemBase> list = new List<InventoryItemBase>();
883  while (result.Read())
884  {
885  InventoryItemBase item = readInventoryItem(result);
886  if (item != null)
887  list.Add(item);
888  }
889  return list;
890  }
891  }
892  }
893  }
894  catch (Exception e)
895  {
896  m_log.Error(e.Message, e);
897  return null;
898  }
899  }
900  }
901  }
902 }
void updateInventoryFolder(InventoryFolderBase folder)
Updates an inventory folder
InventoryFolderBase queryInventoryFolder(UUID folderID)
A MySQL interface for the inventory server
void deleteItemsInFolder(UUID folderID)
Delete all item in a folder
void addInventoryItem(InventoryItemBase item)
Adds a specified item to the database
void getInventoryFolders(ref List< InventoryFolderBase > folders, UUID parentID)
Append a list of all the child folders of a parent folder
InventoryFolderBase getUserRootFolder(UUID user)
see InventoryItemBase.getUserRootFolder
void addInventoryFolder(InventoryFolderBase folder)
Creates a new inventory folder
InventoryItemBase getInventoryItem(UUID itemID)
Returns a specified inventory item
List< InventoryFolderBase > getUserRootFolders(UUID user)
Returns a list of the root folders within a users inventory
void deleteInventoryItem(UUID itemID)
Detele the specified inventory item
void moveInventoryFolder(InventoryFolderBase folder)
Move an inventory folder
void updateInventoryItem(InventoryItemBase item)
Updates the specified inventory item
Inventory Item - contains all the properties associated with an individual inventory piece...
Exception thrown if Initialise has been called, but failed.
Definition: IPlugin.cs:35
List< InventoryItemBase > fetchActiveGestures(UUID avatarID)
Returns all activated gesture-items in the inventory of the specified avatar.
InventoryFolderBase getInventoryFolder(UUID folderID)
Returns a specified inventory folder
UUID ID
A UUID containing the ID for the inventory node itself
List< InventoryFolderBase > getInventoryFolders(UUID parentID)
Return a list of folders in a users inventory contained within the specified folder. This method is only used in tests - in normal operation the user always have one, and only one, root folder.
void Initialise()
Default-initialises the plugin
List< InventoryItemBase > getInventoryInFolder(UUID folderID)
Returns a list of items in a specified folder
virtual string Name
The name of the node (64 characters or less)
void deleteOneFolder(UUID folderID)
Delete a folder from database
static InventoryFolderBase readInventoryFolder(MySqlDataReader reader)
Reads a list of inventory folders returned by a query.
void deleteInventoryFolder(UUID folderID)
Deletes an inventory folder
void Dispose()
Closes this DB provider
List< InventoryFolderBase > getFolderHierarchy(UUID parentID)
See IInventoryDataPlugin
InventoryItemBase queryInventoryItem(UUID itemID)
An interface for accessing inventory data from a storage server