diff options
Diffstat (limited to 'OpenSim/Framework/Data.SQLite')
-rw-r--r-- | OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs | 312 |
1 files changed, 177 insertions, 135 deletions
diff --git a/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs b/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs index 5e5d1e4..23b4cb4 100644 --- a/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs +++ b/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs | |||
@@ -48,6 +48,11 @@ namespace OpenSim.Framework.Data.SQLite | |||
48 | private SqliteDataAdapter invFoldersDa; | 48 | private SqliteDataAdapter invFoldersDa; |
49 | 49 | ||
50 | /// <summary> | 50 | /// <summary> |
51 | /// used to manage concurrent access tothe sqlite database files. Only one thread may open, read, write at a time. | ||
52 | /// </summary> | ||
53 | private object InventoryLock = new object(); | ||
54 | |||
55 | /// <summary> | ||
51 | /// Initialises the interface | 56 | /// Initialises the interface |
52 | /// </summary> | 57 | /// </summary> |
53 | public void Initialise() | 58 | public void Initialise() |
@@ -126,58 +131,67 @@ namespace OpenSim.Framework.Data.SQLite | |||
126 | 131 | ||
127 | private void addFolder(InventoryFolderBase folder) | 132 | private void addFolder(InventoryFolderBase folder) |
128 | { | 133 | { |
129 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; | 134 | lock (InventoryLock) |
130 | |||
131 | DataRow inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folder.folderID)); | ||
132 | if (inventoryRow == null) | ||
133 | { | ||
134 | inventoryRow = inventoryFolderTable.NewRow(); | ||
135 | fillFolderRow(inventoryRow, folder); | ||
136 | inventoryFolderTable.Rows.Add(inventoryRow); | ||
137 | } | ||
138 | else | ||
139 | { | 135 | { |
140 | fillFolderRow(inventoryRow, folder); | 136 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; |
141 | } | 137 | |
138 | DataRow inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folder.folderID)); | ||
139 | if (inventoryRow == null) | ||
140 | { | ||
141 | inventoryRow = inventoryFolderTable.NewRow(); | ||
142 | fillFolderRow(inventoryRow, folder); | ||
143 | inventoryFolderTable.Rows.Add(inventoryRow); | ||
144 | } | ||
145 | else | ||
146 | { | ||
147 | fillFolderRow(inventoryRow, folder); | ||
148 | } | ||
142 | 149 | ||
143 | invFoldersDa.Update(ds, "inventoryfolders"); | 150 | invFoldersDa.Update(ds, "inventoryfolders"); |
151 | } | ||
144 | } | 152 | } |
145 | 153 | ||
146 | private void moveFolder(InventoryFolderBase folder) | 154 | private void moveFolder(InventoryFolderBase folder) |
147 | { | 155 | { |
148 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; | 156 | lock (InventoryLock) |
149 | |||
150 | DataRow inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folder.folderID)); | ||
151 | if (inventoryRow == null) | ||
152 | { | 157 | { |
153 | inventoryRow = inventoryFolderTable.NewRow(); | 158 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; |
154 | fillFolderRow(inventoryRow, folder); | 159 | |
155 | inventoryFolderTable.Rows.Add(inventoryRow); | 160 | DataRow inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folder.folderID)); |
156 | } | 161 | if (inventoryRow == null) |
157 | else | 162 | { |
158 | { | 163 | inventoryRow = inventoryFolderTable.NewRow(); |
159 | moveFolderRow(inventoryRow, folder); | 164 | fillFolderRow(inventoryRow, folder); |
160 | } | 165 | inventoryFolderTable.Rows.Add(inventoryRow); |
166 | } | ||
167 | else | ||
168 | { | ||
169 | moveFolderRow(inventoryRow, folder); | ||
170 | } | ||
161 | 171 | ||
162 | invFoldersDa.Update(ds, "inventoryfolders"); | 172 | invFoldersDa.Update(ds, "inventoryfolders"); |
173 | } | ||
163 | } | 174 | } |
164 | 175 | ||
165 | private void addItem(InventoryItemBase item) | 176 | private void addItem(InventoryItemBase item) |
166 | { | 177 | { |
167 | DataTable inventoryItemTable = ds.Tables["inventoryitems"]; | 178 | lock (InventoryLock) |
168 | |||
169 | DataRow inventoryRow = inventoryItemTable.Rows.Find(Util.ToRawUuidString(item.inventoryID)); | ||
170 | if (inventoryRow == null) | ||
171 | { | ||
172 | inventoryRow = inventoryItemTable.NewRow(); | ||
173 | fillItemRow(inventoryRow, item); | ||
174 | inventoryItemTable.Rows.Add(inventoryRow); | ||
175 | } | ||
176 | else | ||
177 | { | 179 | { |
178 | fillItemRow(inventoryRow, item); | 180 | DataTable inventoryItemTable = ds.Tables["inventoryitems"]; |
181 | |||
182 | DataRow inventoryRow = inventoryItemTable.Rows.Find(Util.ToRawUuidString(item.inventoryID)); | ||
183 | if (inventoryRow == null) | ||
184 | { | ||
185 | inventoryRow = inventoryItemTable.NewRow(); | ||
186 | fillItemRow(inventoryRow, item); | ||
187 | inventoryItemTable.Rows.Add(inventoryRow); | ||
188 | } | ||
189 | else | ||
190 | { | ||
191 | fillItemRow(inventoryRow, item); | ||
192 | } | ||
193 | invItemsDa.Update(ds, "inventoryitems"); | ||
179 | } | 194 | } |
180 | invItemsDa.Update(ds, "inventoryitems"); | ||
181 | } | 195 | } |
182 | 196 | ||
183 | public void Shutdown() | 197 | public void Shutdown() |
@@ -224,16 +238,19 @@ namespace OpenSim.Framework.Data.SQLite | |||
224 | /// <returns>A List of InventoryItemBase items</returns> | 238 | /// <returns>A List of InventoryItemBase items</returns> |
225 | public List<InventoryItemBase> getInventoryInFolder(LLUUID folderID) | 239 | public List<InventoryItemBase> getInventoryInFolder(LLUUID folderID) |
226 | { | 240 | { |
227 | List<InventoryItemBase> retval = new List<InventoryItemBase>(); | 241 | lock (InventoryLock) |
228 | DataTable inventoryItemTable = ds.Tables["inventoryitems"]; | ||
229 | string selectExp = "parentFolderID = '" + Util.ToRawUuidString(folderID) + "'"; | ||
230 | DataRow[] rows = inventoryItemTable.Select(selectExp); | ||
231 | foreach (DataRow row in rows) | ||
232 | { | 242 | { |
233 | retval.Add(buildItem(row)); | 243 | List<InventoryItemBase> retval = new List<InventoryItemBase>(); |
234 | } | 244 | DataTable inventoryItemTable = ds.Tables["inventoryitems"]; |
245 | string selectExp = "parentFolderID = '" + Util.ToRawUuidString(folderID) + "'"; | ||
246 | DataRow[] rows = inventoryItemTable.Select(selectExp); | ||
247 | foreach (DataRow row in rows) | ||
248 | { | ||
249 | retval.Add(buildItem(row)); | ||
250 | } | ||
235 | 251 | ||
236 | return retval; | 252 | return retval; |
253 | } | ||
237 | } | 254 | } |
238 | 255 | ||
239 | /// <summary> | 256 | /// <summary> |
@@ -249,27 +266,30 @@ namespace OpenSim.Framework.Data.SQLite | |||
249 | // see InventoryItemBase.getUserRootFolder | 266 | // see InventoryItemBase.getUserRootFolder |
250 | public InventoryFolderBase getUserRootFolder(LLUUID user) | 267 | public InventoryFolderBase getUserRootFolder(LLUUID user) |
251 | { | 268 | { |
252 | List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); | 269 | lock (InventoryLock) |
253 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; | ||
254 | string selectExp = "agentID = '" + Util.ToRawUuidString(user) + "' AND parentID = '" + | ||
255 | Util.ToRawUuidString(LLUUID.Zero) + "'"; | ||
256 | DataRow[] rows = inventoryFolderTable.Select(selectExp); | ||
257 | foreach (DataRow row in rows) | ||
258 | { | 270 | { |
259 | folders.Add(buildFolder(row)); | 271 | List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); |
260 | } | 272 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; |
273 | string selectExp = "agentID = '" + Util.ToRawUuidString(user) + "' AND parentID = '" + | ||
274 | Util.ToRawUuidString(LLUUID.Zero) + "'"; | ||
275 | DataRow[] rows = inventoryFolderTable.Select(selectExp); | ||
276 | foreach (DataRow row in rows) | ||
277 | { | ||
278 | folders.Add(buildFolder(row)); | ||
279 | } | ||
261 | 280 | ||
262 | // There should only ever be one root folder for a user. However, if there's more | 281 | // There should only ever be one root folder for a user. However, if there's more |
263 | // than one we'll simply use the first one rather than failing. It would be even | 282 | // than one we'll simply use the first one rather than failing. It would be even |
264 | // nicer to print some message to this effect, but this feels like it's too low a | 283 | // nicer to print some message to this effect, but this feels like it's too low a |
265 | // to put such a message out, and it's too minor right now to spare the time to | 284 | // to put such a message out, and it's too minor right now to spare the time to |
266 | // suitably refactor. | 285 | // suitably refactor. |
267 | if (folders.Count > 0) | 286 | if (folders.Count > 0) |
268 | { | 287 | { |
269 | return folders[0]; | 288 | return folders[0]; |
270 | } | 289 | } |
271 | 290 | ||
272 | return null; | 291 | return null; |
292 | } | ||
273 | } | 293 | } |
274 | 294 | ||
275 | /// <summary> | 295 | /// <summary> |
@@ -279,12 +299,15 @@ namespace OpenSim.Framework.Data.SQLite | |||
279 | /// <param name="parentID">ID of parent</param> | 299 | /// <param name="parentID">ID of parent</param> |
280 | protected void getInventoryFolders(ref List<InventoryFolderBase> folders, LLUUID parentID) | 300 | protected void getInventoryFolders(ref List<InventoryFolderBase> folders, LLUUID parentID) |
281 | { | 301 | { |
282 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; | 302 | lock (InventoryLock) |
283 | string selectExp = "parentID = '" + Util.ToRawUuidString(parentID) + "'"; | ||
284 | DataRow[] rows = inventoryFolderTable.Select(selectExp); | ||
285 | foreach (DataRow row in rows) | ||
286 | { | 303 | { |
287 | folders.Add(buildFolder(row)); | 304 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; |
305 | string selectExp = "parentID = '" + Util.ToRawUuidString(parentID) + "'"; | ||
306 | DataRow[] rows = inventoryFolderTable.Select(selectExp); | ||
307 | foreach (DataRow row in rows) | ||
308 | { | ||
309 | folders.Add(buildFolder(row)); | ||
310 | } | ||
288 | } | 311 | } |
289 | } | 312 | } |
290 | 313 | ||
@@ -323,14 +346,17 @@ namespace OpenSim.Framework.Data.SQLite | |||
323 | /// <returns>A class containing item information</returns> | 346 | /// <returns>A class containing item information</returns> |
324 | public InventoryItemBase getInventoryItem(LLUUID item) | 347 | public InventoryItemBase getInventoryItem(LLUUID item) |
325 | { | 348 | { |
326 | DataRow row = ds.Tables["inventoryitems"].Rows.Find(Util.ToRawUuidString(item)); | 349 | lock (InventoryLock) |
327 | if (row != null) | ||
328 | { | ||
329 | return buildItem(row); | ||
330 | } | ||
331 | else | ||
332 | { | 350 | { |
333 | return null; | 351 | DataRow row = ds.Tables["inventoryitems"].Rows.Find(Util.ToRawUuidString(item)); |
352 | if (row != null) | ||
353 | { | ||
354 | return buildItem(row); | ||
355 | } | ||
356 | else | ||
357 | { | ||
358 | return null; | ||
359 | } | ||
334 | } | 360 | } |
335 | } | 361 | } |
336 | 362 | ||
@@ -346,15 +372,17 @@ namespace OpenSim.Framework.Data.SQLite | |||
346 | // better to leave multi region at this point. It does mean | 372 | // better to leave multi region at this point. It does mean |
347 | // that you don't get to see system textures why creating | 373 | // that you don't get to see system textures why creating |
348 | // clothes and the like. :( | 374 | // clothes and the like. :( |
349 | 375 | lock (InventoryLock) | |
350 | DataRow row = ds.Tables["inventoryfolders"].Rows.Find(Util.ToRawUuidString(folder)); | ||
351 | if (row != null) | ||
352 | { | ||
353 | return buildFolder(row); | ||
354 | } | ||
355 | else | ||
356 | { | 376 | { |
357 | return null; | 377 | DataRow row = ds.Tables["inventoryfolders"].Rows.Find(Util.ToRawUuidString(folder)); |
378 | if (row != null) | ||
379 | { | ||
380 | return buildFolder(row); | ||
381 | } | ||
382 | else | ||
383 | { | ||
384 | return null; | ||
385 | } | ||
358 | } | 386 | } |
359 | } | 387 | } |
360 | 388 | ||
@@ -382,17 +410,19 @@ namespace OpenSim.Framework.Data.SQLite | |||
382 | /// <param name="item"></param> | 410 | /// <param name="item"></param> |
383 | public void deleteInventoryItem(LLUUID itemID) | 411 | public void deleteInventoryItem(LLUUID itemID) |
384 | { | 412 | { |
385 | DataTable inventoryItemTable = ds.Tables["inventoryitems"]; | 413 | lock (InventoryLock) |
386 | |||
387 | DataRow inventoryRow = inventoryItemTable.Rows.Find(Util.ToRawUuidString(itemID)); | ||
388 | if (inventoryRow != null) | ||
389 | { | 414 | { |
390 | inventoryRow.Delete(); | 415 | DataTable inventoryItemTable = ds.Tables["inventoryitems"]; |
391 | } | ||
392 | 416 | ||
393 | invItemsDa.Update(ds, "inventoryitems"); | 417 | DataRow inventoryRow = inventoryItemTable.Rows.Find(Util.ToRawUuidString(itemID)); |
394 | } | 418 | if (inventoryRow != null) |
419 | { | ||
420 | inventoryRow.Delete(); | ||
421 | } | ||
395 | 422 | ||
423 | invItemsDa.Update(ds, "inventoryitems"); | ||
424 | } | ||
425 | } | ||
396 | 426 | ||
397 | /// <summary> | 427 | /// <summary> |
398 | /// Delete all items in the specified folder | 428 | /// Delete all items in the specified folder |
@@ -443,31 +473,34 @@ namespace OpenSim.Framework.Data.SQLite | |||
443 | /// <param name="item"></param> | 473 | /// <param name="item"></param> |
444 | public void deleteInventoryFolder(LLUUID folderID) | 474 | public void deleteInventoryFolder(LLUUID folderID) |
445 | { | 475 | { |
446 | List<InventoryFolderBase> subFolders = getFolderHierarchy(Util.ToRawUuidString(folderID)); | 476 | lock (InventoryLock) |
477 | { | ||
478 | List<InventoryFolderBase> subFolders = getFolderHierarchy(Util.ToRawUuidString(folderID)); | ||
447 | 479 | ||
448 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; | 480 | DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; |
449 | DataRow inventoryRow; | 481 | DataRow inventoryRow; |
450 | 482 | ||
451 | //Delete all sub-folders | 483 | //Delete all sub-folders |
452 | foreach (InventoryFolderBase f in subFolders) | 484 | foreach (InventoryFolderBase f in subFolders) |
453 | { | 485 | { |
454 | inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(f.folderID)); | 486 | inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(f.folderID)); |
487 | if (inventoryRow != null) | ||
488 | { | ||
489 | deleteItemsInFolder(Util.ToRawUuidString(f.folderID)); | ||
490 | inventoryRow.Delete(); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | //Delete the actual row | ||
495 | inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folderID)); | ||
455 | if (inventoryRow != null) | 496 | if (inventoryRow != null) |
456 | { | 497 | { |
457 | deleteItemsInFolder(Util.ToRawUuidString(f.folderID)); | 498 | deleteItemsInFolder(Util.ToRawUuidString(folderID)); |
458 | inventoryRow.Delete(); | 499 | inventoryRow.Delete(); |
459 | } | 500 | } |
460 | } | ||
461 | 501 | ||
462 | //Delete the actual row | 502 | invFoldersDa.Update(ds, "inventoryfolders"); |
463 | inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folderID)); | ||
464 | if (inventoryRow != null) | ||
465 | { | ||
466 | deleteItemsInFolder(Util.ToRawUuidString(folderID)); | ||
467 | inventoryRow.Delete(); | ||
468 | } | 503 | } |
469 | |||
470 | invFoldersDa.Update(ds, "inventoryfolders"); | ||
471 | } | 504 | } |
472 | 505 | ||
473 | /*********************************************************************** | 506 | /*********************************************************************** |
@@ -517,30 +550,36 @@ namespace OpenSim.Framework.Data.SQLite | |||
517 | 550 | ||
518 | private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) | 551 | private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) |
519 | { | 552 | { |
520 | da.InsertCommand = createInsertCommand("inventoryitems", ds.Tables["inventoryitems"]); | 553 | lock (InventoryLock) |
521 | da.InsertCommand.Connection = conn; | 554 | { |
555 | da.InsertCommand = createInsertCommand("inventoryitems", ds.Tables["inventoryitems"]); | ||
556 | da.InsertCommand.Connection = conn; | ||
522 | 557 | ||
523 | da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", ds.Tables["inventoryitems"]); | 558 | da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", ds.Tables["inventoryitems"]); |
524 | da.UpdateCommand.Connection = conn; | 559 | da.UpdateCommand.Connection = conn; |
525 | 560 | ||
526 | SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID"); | 561 | SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID"); |
527 | delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); | 562 | delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); |
528 | delete.Connection = conn; | 563 | delete.Connection = conn; |
529 | da.DeleteCommand = delete; | 564 | da.DeleteCommand = delete; |
565 | } | ||
530 | } | 566 | } |
531 | 567 | ||
532 | private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn) | 568 | private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn) |
533 | { | 569 | { |
534 | da.InsertCommand = createInsertCommand("inventoryfolders", ds.Tables["inventoryfolders"]); | 570 | lock (InventoryLock) |
535 | da.InsertCommand.Connection = conn; | 571 | { |
572 | da.InsertCommand = createInsertCommand("inventoryfolders", ds.Tables["inventoryfolders"]); | ||
573 | da.InsertCommand.Connection = conn; | ||
536 | 574 | ||
537 | da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", ds.Tables["inventoryfolders"]); | 575 | da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", ds.Tables["inventoryfolders"]); |
538 | da.UpdateCommand.Connection = conn; | 576 | da.UpdateCommand.Connection = conn; |
539 | 577 | ||
540 | SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID"); | 578 | SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID"); |
541 | delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); | 579 | delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); |
542 | delete.Connection = conn; | 580 | delete.Connection = conn; |
543 | da.DeleteCommand = delete; | 581 | da.DeleteCommand = delete; |
582 | } | ||
544 | } | 583 | } |
545 | 584 | ||
546 | private InventoryFolderBase buildFolder(DataRow row) | 585 | private InventoryFolderBase buildFolder(DataRow row) |
@@ -579,15 +618,18 @@ namespace OpenSim.Framework.Data.SQLite | |||
579 | 618 | ||
580 | private void InitDB(SqliteConnection conn) | 619 | private void InitDB(SqliteConnection conn) |
581 | { | 620 | { |
582 | string createInventoryItems = defineTable(createInventoryItemsTable()); | 621 | lock (InventoryLock) |
583 | string createInventoryFolders = defineTable(createInventoryFoldersTable()); | 622 | { |
584 | 623 | string createInventoryItems = defineTable(createInventoryItemsTable()); | |
585 | SqliteCommand pcmd = new SqliteCommand(createInventoryItems, conn); | 624 | string createInventoryFolders = defineTable(createInventoryFoldersTable()); |
586 | SqliteCommand scmd = new SqliteCommand(createInventoryFolders, conn); | 625 | |
587 | conn.Open(); | 626 | SqliteCommand pcmd = new SqliteCommand(createInventoryItems, conn); |
588 | pcmd.ExecuteNonQuery(); | 627 | SqliteCommand scmd = new SqliteCommand(createInventoryFolders, conn); |
589 | scmd.ExecuteNonQuery(); | 628 | conn.Open(); |
590 | conn.Close(); | 629 | pcmd.ExecuteNonQuery(); |
630 | scmd.ExecuteNonQuery(); | ||
631 | conn.Close(); | ||
632 | } | ||
591 | } | 633 | } |
592 | 634 | ||
593 | private bool TestTables(SqliteConnection conn) | 635 | private bool TestTables(SqliteConnection conn) |
@@ -631,4 +673,4 @@ namespace OpenSim.Framework.Data.SQLite | |||
631 | return true; | 673 | return true; |
632 | } | 674 | } |
633 | } | 675 | } |
634 | } \ No newline at end of file | 676 | } |