Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
            }
        }
Ejemplo n.º 3
0
        /// <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);
        }