/// <summary> /// Import an item from an <see cref="ArchiveReader"/>. /// </summary> /// <param name="archive">The archive to be imported.</param> public TModel Import(ArchiveReader archive) { TModel item = null; delayEvents(); try { using (var write = ContextFactory.GetForWrite()) // used to share a context for full import. keep in mind this will block all writes. { try { if (!write.IsTransactionLeader) { throw new InvalidOperationException($"Ensure there is no parent transaction so errors can correctly be handled by {this}"); } // create a new model (don't yet add to database) item = CreateModel(archive); var existing = CheckForExisting(item); if (existing != null) { Logger.Log($"Found existing {typeof(TModel)} for {archive.Name} (ID {existing.ID}). Skipping import.", LoggingTarget.Database); return(existing); } item.Files = createFileInfos(archive, Files); Populate(item, archive); // import to store ModelStore.Add(item); } catch (Exception e) { write.Errors.Add(e); throw; } } Logger.Log($"Import of {archive.Name} successfully completed!", LoggingTarget.Database); } catch (Exception e) { Logger.Error(e, $"Import of {archive.Name} failed and has been rolled back.", LoggingTarget.Database); item = null; } finally { // we only want to flush events after we've confirmed the write context didn't have any errors. flushEvents(item != null); } return(item); }
/// <summary> /// Import an item from an <see cref="ArchiveReader"/>. /// </summary> /// <param name="archive">The archive to be imported.</param> public TModel Import(ArchiveReader archive) { using (ContextFactory.GetForWrite()) // used to share a context for full import. keep in mind this will block all writes. { // create a new model (don't yet add to database) var item = CreateModel(archive); var existing = CheckForExisting(item); if (existing != null) { return(existing); } item.Files = createFileInfos(archive, Files); Populate(item, archive); // import to store ModelStore.Add(item); return(item); } }
/// <summary> /// Import an item from a <see cref="TModel"/>. /// </summary> /// <param name="item">The model to be imported.</param> /// <param name="archive">An optional archive to use for model population.</param> public TModel Import(TModel item, ArchiveReader archive = null) { delayEvents(); try { Logger.Log($"Importing {item}...", LoggingTarget.Database); using (var write = ContextFactory.GetForWrite()) // used to share a context for full import. keep in mind this will block all writes. { try { if (!write.IsTransactionLeader) { throw new InvalidOperationException($"Ensure there is no parent transaction so errors can correctly be handled by {this}"); } if (archive != null) { item.Files = createFileInfos(archive, Files); } Populate(item, archive); var existing = CheckForExisting(item); if (existing != null) { if (CanUndelete(existing, item)) { Undelete(existing); Logger.Log($"Found existing {typeof(TModel)} for {item} (ID {existing.ID}). Skipping import.", LoggingTarget.Database); handleEvent(() => ItemAdded?.Invoke(existing, true)); return(existing); } else { Delete(existing); ModelStore.PurgeDeletable(s => s.ID == existing.ID); } } PreImport(item); // import to store ModelStore.Add(item); } catch (Exception e) { write.Errors.Add(e); throw; } } Logger.Log($"Import of {item} successfully completed!", LoggingTarget.Database); } catch (Exception e) { Logger.Error(e, $"Import of {item} failed and has been rolled back.", LoggingTarget.Database); item = null; } finally { // we only want to flush events after we've confirmed the write context didn't have any errors. flushEvents(item != null); } return(item); }