예제 #1
0
        /// <summary>
        /// Updates the database with new or changed transformations.
        /// </summary>
        /// <returns>An update result which may or may not have succeeded.</returns>
        public async Task <UpdateTransformationsResult> UpdateTransformationDatabaseAsync()
        {
            uint addedSpecies   = 0;
            uint updatedSpecies = 0;

            var bundledSpeciesResult = await _content.DiscoverBundledSpeciesAsync();

            if (!bundledSpeciesResult.IsSuccess)
            {
                return(UpdateTransformationsResult.FromError(bundledSpeciesResult));
            }

            foreach (var species in bundledSpeciesResult.Entity.OrderBy(s => s.GetSpeciesDepth()))
            {
                if (await IsSpeciesNameUniqueAsync(species.Name))
                {
                    // Add a new species
                    await _database.Species.AddAsync(species);

                    ++addedSpecies;
                }
                else
                {
                    // There's an existing species with this name
                    var existingSpecies = (await GetSpeciesByNameAsync(species.Name)).Entity;

                    species.ID = existingSpecies.ID;

                    var existingEntry = _database.Entry(existingSpecies);
                    existingEntry.CurrentValues.SetValues(species);

                    if (existingEntry.State == EntityState.Modified)
                    {
                        ++updatedSpecies;
                    }
                }

                await _database.SaveChangesAsync();
            }

            uint addedTransformations   = 0;
            uint updatedTransformations = 0;

            var availableSpecies = await GetAvailableSpeciesAsync();

            foreach (var species in availableSpecies)
            {
                var bundledTransformationsResult = await _content.DiscoverBundledTransformationsAsync(this, species);

                if (!bundledTransformationsResult.IsSuccess)
                {
                    return(UpdateTransformationsResult.FromError(bundledTransformationsResult));
                }

                foreach (var transformation in bundledTransformationsResult.Entity)
                {
                    if (await IsPartAndSpeciesCombinationUniqueAsync(transformation.Part, transformation.Species))
                    {
                        // Add a new transformation
                        await _database.Transformations.AddAsync(transformation);

                        ++addedTransformations;
                    }
                    else
                    {
                        // We just take the first one, since species can't define composite parts individually
                        var existingTransformation =
                            (
                                await GetTransformationsByPartAndSpeciesAsync
                                (
                                    transformation.Part,
                                    transformation.Species
                                )
                            ).Entity.First();

                        // Override the new data's ID to match the existing one
                        transformation.ID = existingTransformation.ID;

                        var existingEntry = _database.Entry(existingTransformation);
                        existingEntry.CurrentValues.SetValues(transformation);

                        // Workarounds for some broken EF core behaviour
                        var baseColourNeedsUpdate = !existingTransformation.DefaultBaseColour
                                                    .IsSameColourAs(transformation.DefaultBaseColour);

                        if (baseColourNeedsUpdate)
                        {
                            // This catches null-to-null changes
                            if (existingTransformation.DefaultBaseColour != transformation.DefaultBaseColour)
                            {
                                existingEntry.State = EntityState.Modified;
                            }

                            existingTransformation.DefaultBaseColour =
                                transformation.DefaultBaseColour.Clone();
                        }

                        var patternColourNeedsUpdate = existingTransformation.DefaultPatternColour is null ||
                                                       !existingTransformation.DefaultPatternColour
                                                       .IsSameColourAs(transformation.DefaultPatternColour);

                        if (patternColourNeedsUpdate)
                        {
                            // This catches null-to-null changes
                            if (existingTransformation.DefaultPatternColour != transformation.DefaultPatternColour)
                            {
                                existingEntry.State = EntityState.Modified;
                            }

                            existingTransformation.DefaultPatternColour =
                                transformation.DefaultPatternColour?.Clone();
                        }

                        if (existingEntry.State == EntityState.Modified)
                        {
                            ++updatedTransformations;
                        }
                    }

                    await _database.SaveChangesAsync();
                }
            }

            return(UpdateTransformationsResult.FromSuccess
                   (
                       addedSpecies,
                       addedTransformations,
                       updatedSpecies,
                       updatedTransformations
                   ));
        }