aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs')
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs804
1 files changed, 804 insertions, 0 deletions
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs
new file mode 100644
index 0000000..7d6c0c2
--- /dev/null
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs
@@ -0,0 +1,804 @@
1/*
2 * Copyright (c) 2008 Intel Corporation
3 * All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * -- Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * -- Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * -- Neither the name of the Intel Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30using System;
31using System.Collections.Generic;
32using System.Net;
33using System.Data;
34using MySql.Data.MySqlClient;
35using ExtensionLoader;
36using ExtensionLoader.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39
40namespace OpenSim.Grid.AssetInventoryServer.Extensions
41{
42 public class OpenSimMySQLInventory : IExtension<AssetInventoryServer>, IInventoryProvider
43 {
44 const string EXTENSION_NAME = "OpenSimMySQLInventory"; // Used in metrics reporting
45
46 AssetInventoryServer server;
47
48 public OpenSimMySQLInventory()
49 {
50 }
51
52 #region Required Interfaces
53
54 public void Start(AssetInventoryServer server)
55 {
56 this.server = server;
57
58 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
59 {
60 try
61 {
62 dbConnection.Open();
63 Logger.Log.Info("Connected to MySQL inventory backend: " + dbConnection.ServerVersion);
64 }
65 catch (MySqlException ex)
66 {
67 Logger.Log.Error("Connection to MySQL inventory backend failed: " + ex.Message);
68 }
69 }
70 }
71
72 public void Stop()
73 {
74 }
75
76 public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item)
77 {
78 item = null;
79 BackendResponse ret;
80
81 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
82 {
83 IDataReader reader;
84
85 try
86 {
87 dbConnection.Open();
88
89 IDbCommand command = dbConnection.CreateCommand();
90 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
91 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
92 "creationDate,groupID,groupOwned,flags,avatarID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE inventoryID='{0}'",
93 itemID.ToString());
94 reader = command.ExecuteReader();
95
96 if (reader.Read())
97 {
98 item = new InventoryItem();
99 item.ID = itemID;
100 item.AssetID = UUID.Parse(reader.GetString(0));
101 item.AssetType = reader.GetInt32(1);
102 item.Name = reader.GetString(2);
103 item.Description = reader.GetString(3);
104 item.NextPermissions = (uint)reader.GetInt32(4);
105 item.CurrentPermissions = (uint)reader.GetInt32(5);
106 item.InvType = reader.GetInt32(6);
107 item.Creator = UUID.Parse(reader.GetString(7));
108 item.BasePermissions = (uint)reader.GetInt32(8);
109 item.EveryOnePermissions = (uint)reader.GetInt32(9);
110 item.SalePrice = reader.GetInt32(10);
111 item.SaleType = reader.GetByte(11);
112 item.CreationDate = reader.GetInt32(12);
113 item.GroupID = UUID.Parse(reader.GetString(13));
114 item.GroupOwned = reader.GetBoolean(14);
115 item.Flags = (uint)reader.GetInt32(15);
116 item.Owner = UUID.Parse(reader.GetString(16));
117 item.Folder = UUID.Parse(reader.GetString(17));
118 item.GroupPermissions = (uint)reader.GetInt32(18);
119
120 ret = BackendResponse.Success;
121 }
122 else
123 {
124 ret = BackendResponse.NotFound;
125 }
126 }
127 catch (MySqlException ex)
128 {
129 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
130 ret = BackendResponse.Failure;
131 }
132 }
133
134 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
135 return ret;
136 }
137
138 public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder)
139 {
140 folder = null;
141 BackendResponse ret;
142
143 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
144 {
145 IDataReader reader;
146
147 try
148 {
149 dbConnection.Open();
150
151 IDbCommand command = dbConnection.CreateCommand();
152 command.CommandText = String.Format("SELECT folderName,type,version,agentID,parentFolderID FROM inventoryfolders WHERE folderID='{0}'",
153 folderID.ToString());
154 reader = command.ExecuteReader();
155
156 if (reader.Read())
157 {
158 folder = new InventoryFolder();
159 folder.Children = null; // This call only returns data for the folder itself, no children data
160 folder.ID = folderID;
161 folder.Name = reader.GetString(0);
162 folder.Type = reader.GetInt16(1);
163 folder.Version = (ushort)reader.GetInt16(2);
164 folder.Owner = UUID.Parse(reader.GetString(3));
165 folder.ParentID = UUID.Parse(reader.GetString(4));
166
167 ret = BackendResponse.Success;
168 }
169 else
170 {
171 ret = BackendResponse.NotFound;
172 }
173 }
174 catch (MySqlException ex)
175 {
176 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
177 ret = BackendResponse.Failure;
178 }
179 }
180
181 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
182 return ret;
183 }
184
185 public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents)
186 {
187 contents = null;
188 BackendResponse ret;
189
190 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
191 {
192 IDataReader reader;
193
194 try
195 {
196 dbConnection.Open();
197
198 contents = new InventoryCollection();
199
200 #region Folder retrieval
201
202 IDbCommand command = dbConnection.CreateCommand();
203 command.CommandText = String.Format("SELECT folderName,type,version,agentID,folderID FROM inventoryfolders WHERE parentFolderID='{0}'",
204 folderID.ToString());
205 reader = command.ExecuteReader();
206
207 contents.Folders = new Dictionary<UUID, InventoryFolder>();
208
209 while (reader.Read())
210 {
211 InventoryFolder folder = new InventoryFolder();
212 folder.ParentID = folderID;
213 folder.Children = null; // This call doesn't do recursion
214 folder.Name = reader.GetString(0);
215 folder.Type = reader.GetInt16(1);
216 folder.Version = (ushort)reader.GetInt16(2);
217 folder.Owner = UUID.Parse(reader.GetString(3));
218 folder.ID = UUID.Parse(reader.GetString(4));
219
220 contents.Folders.Add(folder.ID, folder);
221 contents.UserID = folder.Owner;
222 }
223
224 reader.Close();
225
226 #endregion Folder retrieval
227
228 #region Item retrieval
229
230 command = dbConnection.CreateCommand();
231 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
232 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
233 "creationDate,groupID,groupOwned,flags,avatarID,inventoryID,inventoryGroupPermissions FROM inventoryitems WHERE parentFolderID='{0}'",
234 folderID.ToString());
235 reader = command.ExecuteReader();
236
237 contents.Items = new Dictionary<UUID, InventoryItem>();
238
239 while (reader.Read())
240 {
241 InventoryItem item = new InventoryItem();
242 item.Folder = folderID;
243 item.AssetID = UUID.Parse(reader.GetString(0));
244 item.AssetType = reader.GetInt32(1);
245 item.Name = reader.GetString(2);
246 item.Description = reader.GetString(3);
247 item.NextPermissions = (uint)reader.GetInt32(4);
248 item.CurrentPermissions = (uint)reader.GetInt32(5);
249 item.InvType = reader.GetInt32(6);
250 item.Creator = UUID.Parse(reader.GetString(7));
251 item.BasePermissions = (uint)reader.GetInt32(8);
252 item.EveryOnePermissions = (uint)reader.GetInt32(9);
253 item.SalePrice = reader.GetInt32(10);
254 item.SaleType = reader.GetByte(11);
255 item.CreationDate = reader.GetInt32(12);
256 item.GroupID = UUID.Parse(reader.GetString(13));
257 item.GroupOwned = reader.GetBoolean(14);
258 item.Flags = (uint)reader.GetInt32(15);
259 item.Owner = UUID.Parse(reader.GetString(16));
260 item.ID = UUID.Parse(reader.GetString(17));
261 item.GroupPermissions = (uint)reader.GetInt32(18);
262
263 contents.Items.Add(item.ID, item);
264 contents.UserID = item.Owner;
265 }
266
267 #endregion Item retrieval
268
269 ret = BackendResponse.Success;
270 }
271 catch (MySqlException ex)
272 {
273 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
274 ret = BackendResponse.Failure;
275 }
276 }
277
278 server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
279 return ret;
280 }
281
282 public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders)
283 {
284 folders = null;
285 BackendResponse ret;
286 UUID ownerID;
287
288 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
289 {
290 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
291 {
292 IDataReader reader;
293
294 try
295 {
296 dbConnection.Open();
297 folders = new List<InventoryFolder>();
298
299 IDbCommand command = dbConnection.CreateCommand();
300 command.CommandText = String.Format("SELECT folderName,type,version,folderID,parentFolderID FROM inventoryfolders WHERE agentID='{0}'",
301 ownerID.ToString());
302 reader = command.ExecuteReader();
303
304 while (reader.Read())
305 {
306 InventoryFolder folder = new InventoryFolder();
307 folder.Owner = ownerID;
308 folder.Children = null; // This call does not create a folder hierarchy
309 folder.Name = reader.GetString(0);
310 folder.Type = reader.GetInt16(1);
311 folder.Version = (ushort)reader.GetInt16(2);
312 folder.ID = UUID.Parse(reader.GetString(3));
313 folder.ParentID = UUID.Parse(reader.GetString(4));
314
315 folders.Add(folder);
316 }
317
318 ret = BackendResponse.Success;
319 }
320 catch (MySqlException ex)
321 {
322 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
323 ret = BackendResponse.Failure;
324 }
325 }
326 }
327 else
328 {
329 ret = BackendResponse.NotFound;
330 }
331
332 server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now);
333 return ret;
334 }
335
336 public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory)
337 {
338 inventory = null;
339 BackendResponse ret;
340 List<InventoryFolder> folders;
341 UUID ownerID;
342
343 ret = TryFetchFolderList(owner, out folders);
344
345 if (ret == BackendResponse.Success)
346 {
347 // Add the retrieved folders to the inventory collection
348 inventory = new InventoryCollection();
349 inventory.Folders = new Dictionary<UUID, InventoryFolder>(folders.Count);
350 foreach (InventoryFolder folder in folders)
351 inventory.Folders[folder.ID] = folder;
352
353 // Fetch inventory items
354 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
355 {
356 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
357 {
358 IDataReader reader;
359
360 try
361 {
362 dbConnection.Open();
363
364 IDbCommand command = dbConnection.CreateCommand();
365 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
366 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
367 "creationDate,groupID,groupOwned,flags,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " +
368 "avatarID='{0}'", ownerID.ToString());
369 reader = command.ExecuteReader();
370
371 inventory.UserID = ownerID;
372 inventory.Items = new Dictionary<UUID, InventoryItem>();
373
374 while (reader.Read())
375 {
376 InventoryItem item = new InventoryItem();
377 item.Owner = ownerID;
378 item.AssetID = UUID.Parse(reader.GetString(0));
379 item.AssetType = reader.GetInt32(1);
380 item.Name = reader.GetString(2);
381 item.Description = reader.GetString(3);
382 item.NextPermissions = (uint)reader.GetInt32(4);
383 item.CurrentPermissions = (uint)reader.GetInt32(5);
384 item.InvType = reader.GetInt32(6);
385 item.Creator = UUID.Parse(reader.GetString(7));
386 item.BasePermissions = (uint)reader.GetInt32(8);
387 item.EveryOnePermissions = (uint)reader.GetInt32(9);
388 item.SalePrice = reader.GetInt32(10);
389 item.SaleType = reader.GetByte(11);
390 item.CreationDate = reader.GetInt32(12);
391 item.GroupID = UUID.Parse(reader.GetString(13));
392 item.GroupOwned = reader.GetBoolean(14);
393 item.Flags = (uint)reader.GetInt32(15);
394 item.ID = UUID.Parse(reader.GetString(16));
395 item.Folder = UUID.Parse(reader.GetString(17));
396 item.GroupPermissions = (uint)reader.GetInt32(18);
397
398 inventory.Items.Add(item.ID, item);
399 }
400
401 ret = BackendResponse.Success;
402 }
403 catch (MySqlException ex)
404 {
405 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
406 ret = BackendResponse.Failure;
407 }
408 }
409 }
410 else
411 {
412 ret = BackendResponse.NotFound;
413 }
414 }
415
416 server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now);
417 return ret;
418 }
419
420 public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures)
421 {
422 gestures = null;
423 BackendResponse ret;
424 UUID ownerID;
425
426 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
427 {
428 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
429 {
430 IDataReader reader;
431
432 try
433 {
434 dbConnection.Open();
435
436 MySqlCommand command = new MySqlCommand("SELECT assetID,inventoryName,inventoryDescription,inventoryNextPermissions," +
437 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
438 "creationDate,groupID,groupOwned,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " +
439 "avatarId=?uuid AND assetType=?type AND flags=1", dbConnection);
440 command.Parameters.AddWithValue("?uuid", ownerID.ToString());
441 command.Parameters.AddWithValue("?type", (int)AssetType.Gesture);
442 reader = command.ExecuteReader();
443
444 while (reader.Read())
445 {
446 InventoryItem item = new InventoryItem();
447 item.Owner = ownerID;
448 item.AssetType = (int)AssetType.Gesture;
449 item.Flags = (uint)1;
450 item.AssetID = UUID.Parse(reader.GetString(0));
451 item.Name = reader.GetString(1);
452 item.Description = reader.GetString(2);
453 item.NextPermissions = (uint)reader.GetInt32(3);
454 item.CurrentPermissions = (uint)reader.GetInt32(4);
455 item.InvType = reader.GetInt32(5);
456 item.Creator = UUID.Parse(reader.GetString(6));
457 item.BasePermissions = (uint)reader.GetInt32(7);
458 item.EveryOnePermissions = (uint)reader.GetInt32(8);
459 item.SalePrice = reader.GetInt32(9);
460 item.SaleType = reader.GetByte(10);
461 item.CreationDate = reader.GetInt32(11);
462 item.GroupID = UUID.Parse(reader.GetString(12));
463 item.GroupOwned = reader.GetBoolean(13);
464 item.ID = UUID.Parse(reader.GetString(14));
465 item.Folder = UUID.Parse(reader.GetString(15));
466 item.GroupPermissions = (uint)reader.GetInt32(16);
467
468 gestures.Add(item);
469 }
470
471 ret = BackendResponse.Success;
472 }
473 catch (MySqlException ex)
474 {
475 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
476 ret = BackendResponse.Failure;
477 }
478 }
479 }
480 else
481 {
482 ret = BackendResponse.NotFound;
483 }
484
485 server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now);
486 return ret;
487 }
488
489 public BackendResponse TryCreateItem(Uri owner, InventoryItem item)
490 {
491 BackendResponse ret;
492
493 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
494 {
495 try
496 {
497 dbConnection.Open();
498
499 MySqlCommand command = new MySqlCommand(
500 "REPLACE INTO inventoryitems (assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
501 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
502 "creationDate,groupID,groupOwned,flags,inventoryID,avatarID,parentFolderID,inventoryGroupPermissions) VALUES " +
503
504 "(?assetID,?assetType,?inventoryName,?inventoryDescription,?inventoryNextPermissions,?inventoryCurrentPermissions,?invType," +
505 "?creatorID,?inventoryBasePermissions,?inventoryEveryOnePermissions,?salePrice,?saleType,?creationDate,?groupID,?groupOwned," +
506 "?flags,?inventoryID,?avatarID,?parentFolderID,?inventoryGroupPermissions)", dbConnection);
507
508 command.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
509 command.Parameters.AddWithValue("?assetType", item.AssetType);
510 command.Parameters.AddWithValue("?inventoryName", item.Name);
511 command.Parameters.AddWithValue("?inventoryDescription", item.Description);
512 command.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions);
513 command.Parameters.AddWithValue("?inventoryCurrentPermissions", item.CurrentPermissions);
514 command.Parameters.AddWithValue("?invType", item.InvType);
515 command.Parameters.AddWithValue("?creatorID", item.Creator.ToString());
516 command.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
517 command.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
518 command.Parameters.AddWithValue("?salePrice", item.SalePrice);
519 command.Parameters.AddWithValue("?saleType", item.SaleType);
520 command.Parameters.AddWithValue("?creationDate", item.CreationDate);
521 command.Parameters.AddWithValue("?groupID", item.GroupID.ToString());
522 command.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
523 command.Parameters.AddWithValue("?flags", item.Flags);
524 command.Parameters.AddWithValue("?inventoryID", item.ID);
525 command.Parameters.AddWithValue("?avatarID", item.Owner);
526 command.Parameters.AddWithValue("?parentFolderID", item.Folder);
527 command.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions);
528
529 int rowsAffected = command.ExecuteNonQuery();
530 if (rowsAffected == 1)
531 {
532 ret = BackendResponse.Success;
533 }
534 else if (rowsAffected == 2)
535 {
536 Logger.Log.Info("Replaced inventory item " + item.ID.ToString());
537 ret = BackendResponse.Success;
538 }
539 else
540 {
541 Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected);
542 ret = BackendResponse.Failure;
543 }
544 }
545 catch (MySqlException ex)
546 {
547 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
548 ret = BackendResponse.Failure;
549 }
550 }
551
552 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now);
553 return ret;
554 }
555
556 public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder)
557 {
558 BackendResponse ret;
559
560 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
561 {
562 try
563 {
564 dbConnection.Open();
565
566 MySqlCommand command = new MySqlCommand(
567 "REPLACE INTO inventoryfolders (folderName,type,version,folderID,agentID,parentFolderID) VALUES " +
568 "(?folderName,?type,?version,?folderID,?agentID,?parentFolderID)", dbConnection);
569
570 command.Parameters.AddWithValue("?folderName", folder.Name);
571 command.Parameters.AddWithValue("?type", folder.Type);
572 command.Parameters.AddWithValue("?version", folder.Version);
573 command.Parameters.AddWithValue("?folderID", folder.ID);
574 command.Parameters.AddWithValue("?agentID", folder.Owner);
575 command.Parameters.AddWithValue("?parentFolderID", folder.ParentID);
576
577 int rowsAffected = command.ExecuteNonQuery();
578 if (rowsAffected == 1)
579 {
580 ret = BackendResponse.Success;
581 }
582 else if (rowsAffected == 2)
583 {
584 Logger.Log.Info("Replaced inventory folder " + folder.ID.ToString());
585 ret = BackendResponse.Success;
586 }
587 else
588 {
589 Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected);
590 ret = BackendResponse.Failure;
591 }
592 }
593 catch (MySqlException ex)
594 {
595 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
596 ret = BackendResponse.Failure;
597 }
598 }
599
600 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now);
601 return ret;
602 }
603
604 public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder)
605 {
606 return TryCreateFolder(owner, rootFolder);
607 }
608
609 public BackendResponse TryDeleteItem(Uri owner, UUID itemID)
610 {
611 BackendResponse ret;
612 UUID ownerID;
613
614 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
615 {
616 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
617 {
618 try
619 {
620 dbConnection.Open();
621
622 MySqlCommand command = new MySqlCommand(
623 "DELETE FROM inventoryitems WHERE inventoryID=?inventoryID AND avatarID=?avatarID", dbConnection);
624
625 command.Parameters.AddWithValue("?inventoryID", itemID.ToString());
626 command.Parameters.AddWithValue("?avatarID", ownerID.ToString());
627
628 int rowsAffected = command.ExecuteNonQuery();
629 if (rowsAffected == 1)
630 {
631 ret = BackendResponse.Success;
632 }
633 else
634 {
635 Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected);
636 ret = BackendResponse.NotFound;
637 }
638 }
639 catch (MySqlException ex)
640 {
641 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
642 ret = BackendResponse.Failure;
643 }
644 }
645 }
646 else
647 {
648 ret = BackendResponse.NotFound;
649 }
650
651 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
652 return ret;
653 }
654
655 public BackendResponse TryDeleteFolder(Uri owner, UUID folderID)
656 {
657 BackendResponse ret;
658 UUID ownerID;
659
660 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
661 {
662 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
663 {
664 try
665 {
666 dbConnection.Open();
667
668 MySqlCommand command = new MySqlCommand(
669 "DELETE FROM inventoryfolders WHERE folderID=?folderID AND agentID=?agentID", dbConnection);
670
671 command.Parameters.AddWithValue("?folderID", folderID.ToString());
672 command.Parameters.AddWithValue("?agentID", ownerID.ToString());
673
674 int rowsAffected = command.ExecuteNonQuery();
675 if (rowsAffected == 1)
676 {
677 ret = BackendResponse.Success;
678 }
679 else
680 {
681 Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected);
682 ret = BackendResponse.NotFound;
683 }
684 }
685 catch (MySqlException ex)
686 {
687 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
688 ret = BackendResponse.Failure;
689 }
690 }
691 }
692 else
693 {
694 ret = BackendResponse.NotFound;
695 }
696
697 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
698 return ret;
699 }
700
701 public BackendResponse TryPurgeFolder(Uri owner, UUID folderID)
702 {
703 BackendResponse ret;
704 UUID ownerID;
705
706 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
707 {
708 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
709 {
710 try
711 {
712 dbConnection.Open();
713
714 #region Delete items
715
716 MySqlCommand command = new MySqlCommand(
717 "DELETE FROM inventoryitems WHERE parentFolderID=?parentFolderID AND avatarID=?avatarID", dbConnection);
718
719 command.Parameters.AddWithValue("?parentFolderID", folderID.ToString());
720 command.Parameters.AddWithValue("?avatarID", ownerID.ToString());
721
722 int rowsAffected = command.ExecuteNonQuery();
723
724 #endregion Delete items
725
726 #region Delete folders
727
728 command = new MySqlCommand(
729 "DELETE FROM inventoryfolders WHERE parentFolderID=?parentFolderID AND agentID=?agentID", dbConnection);
730
731 command.Parameters.AddWithValue("?parentFolderID", folderID.ToString());
732 command.Parameters.AddWithValue("?agentID", ownerID.ToString());
733
734 rowsAffected += command.ExecuteNonQuery();
735
736 #endregion Delete folders
737
738 Logger.Log.DebugFormat("Deleted {0} inventory objects from MySQL in a folder purge", rowsAffected);
739
740 ret = BackendResponse.Success;
741 }
742 catch (MySqlException ex)
743 {
744 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
745 ret = BackendResponse.Failure;
746 }
747 }
748 }
749 else
750 {
751 ret = BackendResponse.NotFound;
752 }
753
754 server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
755 return ret;
756 }
757
758 public int ForEach(Action<Metadata> action, int start, int count)
759 {
760 int rowCount = 0;
761
762 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
763 {
764 MySqlDataReader reader;
765
766 try
767 {
768 dbConnection.Open();
769
770 MySqlCommand command = dbConnection.CreateCommand();
771 command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}",
772 start, count);
773 reader = command.ExecuteReader();
774 }
775 catch (MySqlException ex)
776 {
777 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
778 return 0;
779 }
780
781 while (reader.Read())
782 {
783 Metadata metadata = new Metadata();
784 metadata.CreationDate = OpenMetaverse.Utils.Epoch;
785 metadata.Description = reader.GetString(1);
786 metadata.ID = UUID.Parse(reader.GetString(5));
787 metadata.Name = reader.GetString(0);
788 metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4));
789 metadata.Temporary = reader.GetBoolean(3);
790 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2));
791
792 action(metadata);
793 ++rowCount;
794 }
795
796 reader.Close();
797 }
798
799 return rowCount;
800 }
801
802 #endregion Required Interfaces
803 }
804}