From 26ccb25cf065e0fdc0f6c30b9571f6bdeaf4c689 Mon Sep 17 00:00:00 2001 From: Steven Hildreth Date: Thu, 4 Jul 2019 10:50:31 -0500 Subject: [PATCH] Refactored all SQL statements in LINQ statements, added normalized Genre name, various performance improvements. --- .../ArtistLookupEngineTests.cs | 85 ++++++++++ Roadie.Api.Library/Data/Genre.cs | 2 + .../Engines/ArtistLookupEngine.cs | 43 +++-- .../Engines/ReleaseLookupEngine.cs | 17 +- Roadie.Api.Library/Factories/ArtistFactory.cs | 128 +++++++++------ .../Models/Releases/ReleaseListFromSql.cs | 26 --- .../Models/Statistics/DateAndCount.cs | 11 ++ Roadie.Api.Services/CollectionService.cs | 25 ++- Roadie.Api.Services/IStatisticsService.cs | 2 +- Roadie.Api.Services/LabelService.cs | 10 +- Roadie.Api.Services/StatisticsService.cs | 132 ++++----------- Roadie.Api.Services/TrackService.cs | 133 ++++++--------- Roadie.Api/Controllers/ReleaseController.cs | 10 +- Roadie.Api/Controllers/StatsController.cs | 2 +- Roadie.Api/appsettings.Development.json | 2 +- Roadie.sln | 1 + Upgrade0004.sql | 3 + roadie.sql | 154 ++++++++++-------- 18 files changed, 394 insertions(+), 392 deletions(-) delete mode 100644 Roadie.Api.Library/Models/Releases/ReleaseListFromSql.cs create mode 100644 Upgrade0004.sql diff --git a/Roadie.Api.Library.Tests/ArtistLookupEngineTests.cs b/Roadie.Api.Library.Tests/ArtistLookupEngineTests.cs index 2daed5a..51121b1 100644 --- a/Roadie.Api.Library.Tests/ArtistLookupEngineTests.cs +++ b/Roadie.Api.Library.Tests/ArtistLookupEngineTests.cs @@ -71,6 +71,91 @@ namespace Roadie.Library.Tests } + //[Fact] + //public void Update_Genre_Normalized_Name() + //{ + // var optionsBuilder = new DbContextOptionsBuilder(); + // optionsBuilder.UseMySql("server=viking;userid=roadie;password=MenAtW0rk668;persistsecurityinfo=True;database=roadie;ConvertZeroDateTime=true"); + + // using (var context = new RoadieDbContext(optionsBuilder.Options)) + // { + // var now = DateTime.UtcNow; + // foreach (var genre in context.Genres) + // { + // genre.NormalizedName = genre.Name.ToAlphanumericName(); + // genre.LastUpdated = now; + // } + // context.SaveChanges(); + // } + //} + + //[Fact] + //public void Merge_Genres() + //{ + // var optionsBuilder = new DbContextOptionsBuilder(); + // optionsBuilder.UseMySql("server=viking;userid=roadie;password=MenAtW0rk668;persistsecurityinfo=True;database=roadie;ConvertZeroDateTime=true"); + + // using (var context = new RoadieDbContext(optionsBuilder.Options)) + // { + // var addedArtistToGenre = new List>(); + // var addedReleaseToGenre = new List>(); + // var now = DateTime.UtcNow; + // var groupedGenres = context.Genres.GroupBy(x => x.NormalizedName).ToArray(); + // foreach (var genreGroup in groupedGenres) + // { + // var genre = genreGroup.OrderBy(x => x.Id).First(); + // foreach (var gg in genreGroup.OrderBy(x => x.Id).Skip(1)) + // { + // var artistIdsInDups = (from g in context.Genres + // join ag in context.ArtistGenres on g.Id equals ag.GenreId + // where g.Id == gg.Id + // select ag.ArtistId).Distinct().ToArray(); + + // var releaseIdsInDups = (from g in context.Genres + // join rg in context.ReleaseGenres on g.Id equals rg.GenreId + // where g.Id == gg.Id + // select rg.ReleaseId).Distinct().ToArray(); + + // if (artistIdsInDups != null && artistIdsInDups.Any()) + // { + // foreach (var artistIdsInDup in artistIdsInDups) + // { + // if (!addedArtistToGenre.Any(x => x.Key == artistIdsInDup && x.Value == genre.Id)) + // { + // context.ArtistGenres.Add(new ArtistGenre + // { + // ArtistId = artistIdsInDup, + // GenreId = genre.Id + // }); + // addedArtistToGenre.Add(new KeyValuePair(artistIdsInDup, genre.Id)); + // } + // } + // } + + // if (releaseIdsInDups != null && releaseIdsInDups.Any()) + // { + // foreach (var releaseIdsInDup in releaseIdsInDups) + // { + // if (!addedReleaseToGenre.Any(x => x.Key == releaseIdsInDup && x.Value == genre.Id)) + // { + // context.ReleaseGenres.Add(new ReleaseGenre + // { + // ReleaseId = releaseIdsInDup, + // GenreId = genre.Id + // }); + // addedReleaseToGenre.Add(new KeyValuePair(releaseIdsInDup, genre.Id)); + // } + // } + // } + + // context.Genres.Remove(gg); + // context.SaveChanges(); + // } + // } + // } + //} + + //[Fact] //public void Update_Releases_Special_Name() //{ diff --git a/Roadie.Api.Library/Data/Genre.cs b/Roadie.Api.Library/Data/Genre.cs index de8d6bd..142fdb7 100644 --- a/Roadie.Api.Library/Data/Genre.cs +++ b/Roadie.Api.Library/Data/Genre.cs @@ -13,6 +13,8 @@ namespace Roadie.Library.Data [Column("name")] [MaxLength(100)] public string Name { get; set; } + [Column("normalizedName")] [MaxLength(100)] public string NormalizedName { get; set; } + public ICollection Releases { get; set; } public Genre() diff --git a/Roadie.Api.Library/Engines/ArtistLookupEngine.cs b/Roadie.Api.Library/Engines/ArtistLookupEngine.cs index 6c35a58..89df0e5 100644 --- a/Roadie.Api.Library/Engines/ArtistLookupEngine.cs +++ b/Roadie.Api.Library/Engines/ArtistLookupEngine.cs @@ -65,7 +65,7 @@ namespace Roadie.Library.Engines try { - var ArtistGenreTables = artist.Genres; + var artistGenreTables = artist.Genres; var ArtistImages = artist.Images; var now = DateTime.UtcNow; artist.AlternateNames = @@ -106,34 +106,29 @@ namespace Roadie.Library.Engines if (artist.Id < 1 && addArtistResult.Entity.Id > 0) artist.Id = addArtistResult.Entity.Id; if (inserted > 0 && artist.Id > 0) { - if (ArtistGenreTables != null && ArtistGenreTables.Any(x => x.GenreId == null)) + if (artistGenreTables != null && artistGenreTables.Any(x => x.GenreId == null)) { - string sql = null; - try + foreach (var artistGenreTable in artistGenreTables) { - foreach (var ArtistGenreTable in ArtistGenreTables) + var genre = DbContext.Genres.FirstOrDefault(x => x.NormalizedName == artistGenreTable.Genre.Name.ToAlphanumericName()); + if (genre == null) { - var genre = DbContext.Genres.FirstOrDefault(x => - x.Name.ToLower().Trim() == ArtistGenreTable.Genre.Name.ToLower().Trim()); - if (genre == null) + genre = new Genre { - genre = new Genre - { - Name = ArtistGenreTable.Genre.Name - }; - DbContext.Genres.Add(genre); - await DbContext.SaveChangesAsync(); - } - - if (genre != null && genre.Id > 0) - await DbContext.Database.ExecuteSqlCommandAsync( - "INSERT INTO `artistGenreTable` (artistId, genreId) VALUES ({0}, {1});", - artist.Id, genre.Id); + Name = artistGenreTable.Genre.Name, + NormalizedName = artistGenreTable.Genre.Name.ToAlphanumericName() + }; + DbContext.Genres.Add(genre); + await DbContext.SaveChangesAsync(); + } + if (genre != null && genre.Id > 0) + { + DbContext.ArtistGenres.Add(new ArtistGenre + { + ArtistId = artist.Id, + GenreId = genre.Id + }); } - } - catch (Exception ex) - { - Logger.LogError(ex, "Sql [" + sql + "] Exception [" + ex.Serialize() + "]"); } } diff --git a/Roadie.Api.Library/Engines/ReleaseLookupEngine.cs b/Roadie.Api.Library/Engines/ReleaseLookupEngine.cs index 50ebfcb..df44689 100644 --- a/Roadie.Api.Library/Engines/ReleaseLookupEngine.cs +++ b/Roadie.Api.Library/Engines/ReleaseLookupEngine.cs @@ -134,23 +134,19 @@ namespace Roadie.Library.Engines if (genre != null && genre.Id > 0) { - string sql = null; - try + DbContext.ReleaseGenres.Add(new ReleaseGenre { - await DbContext.Database.ExecuteSqlCommandAsync( - "INSERT INTO `releaseGenreTable` (releaseId, genreId) VALUES ({0}, {1});", - release.Id, genre.Id); - } - catch (Exception ex) - { - Logger.LogError(ex, "Sql [" + sql + "]"); - } + ReleaseId = release.Id, + GenreId = genre.Id + }); + } } if (releaseImages != null && releaseImages.Any(x => x.Status == Statuses.New)) { foreach (var releaseImage in releaseImages) + { DbContext.Images.Add(new Image { ReleaseId = release.Id, @@ -158,6 +154,7 @@ namespace Roadie.Library.Engines Signature = releaseImage.Signature, Bytes = releaseImage.Bytes }); + } try { await DbContext.SaveChangesAsync(); diff --git a/Roadie.Api.Library/Factories/ArtistFactory.cs b/Roadie.Api.Library/Factories/ArtistFactory.cs index d2da9c0..2ea1fd0 100644 --- a/Roadie.Api.Library/Factories/ArtistFactory.cs +++ b/Roadie.Api.Library/Factories/ArtistFactory.cs @@ -111,13 +111,13 @@ namespace Roadie.Library.Factories /// /// Merge one Artist into another one /// - /// The Artist to be merged + /// The Artist to be merged /// The Artist to merge into /// - public async Task> MergeArtists(Artist ArtistToMerge, Artist artistToMergeInto, + public async Task> MergeArtists(Artist artistToMerge, Artist artistToMergeInto, bool doDbUpdates = false) { - SimpleContract.Requires(ArtistToMerge != null, "Invalid Artist"); + SimpleContract.Requires(artistToMerge != null, "Invalid Artist"); SimpleContract.Requires(artistToMergeInto != null, "Invalid Artist"); var result = false; @@ -126,71 +126,97 @@ namespace Roadie.Library.Factories var sw = new Stopwatch(); sw.Start(); - artistToMergeInto.RealName = ArtistToMerge.RealName ?? artistToMergeInto.RealName; - artistToMergeInto.MusicBrainzId = ArtistToMerge.MusicBrainzId ?? artistToMergeInto.MusicBrainzId; - artistToMergeInto.ITunesId = ArtistToMerge.ITunesId ?? artistToMergeInto.ITunesId; - artistToMergeInto.AmgId = ArtistToMerge.AmgId ?? artistToMergeInto.AmgId; - artistToMergeInto.SpotifyId = ArtistToMerge.SpotifyId ?? artistToMergeInto.SpotifyId; - artistToMergeInto.Thumbnail = ArtistToMerge.Thumbnail ?? artistToMergeInto.Thumbnail; - artistToMergeInto.Profile = ArtistToMerge.Profile ?? artistToMergeInto.Profile; - artistToMergeInto.BirthDate = ArtistToMerge.BirthDate ?? artistToMergeInto.BirthDate; - artistToMergeInto.BeginDate = ArtistToMerge.BeginDate ?? artistToMergeInto.BeginDate; - artistToMergeInto.EndDate = ArtistToMerge.EndDate ?? artistToMergeInto.EndDate; - if (!string.IsNullOrEmpty(ArtistToMerge.ArtistType) && - !ArtistToMerge.ArtistType.Equals("Other", StringComparison.OrdinalIgnoreCase)) - artistToMergeInto.ArtistType = ArtistToMerge.ArtistType; - artistToMergeInto.BioContext = ArtistToMerge.BioContext ?? artistToMergeInto.BioContext; - artistToMergeInto.DiscogsId = ArtistToMerge.DiscogsId ?? artistToMergeInto.DiscogsId; - - artistToMergeInto.Tags = - artistToMergeInto.Tags.AddToDelimitedList(ArtistToMerge.Tags.ToListFromDelimited()); - var altNames = ArtistToMerge.AlternateNames.ToListFromDelimited().ToList(); - altNames.Add(ArtistToMerge.Name); - altNames.Add(ArtistToMerge.SortName); + artistToMergeInto.RealName = artistToMerge.RealName ?? artistToMergeInto.RealName; + artistToMergeInto.MusicBrainzId = artistToMerge.MusicBrainzId ?? artistToMergeInto.MusicBrainzId; + artistToMergeInto.ITunesId = artistToMerge.ITunesId ?? artistToMergeInto.ITunesId; + artistToMergeInto.AmgId = artistToMerge.AmgId ?? artistToMergeInto.AmgId; + artistToMergeInto.SpotifyId = artistToMerge.SpotifyId ?? artistToMergeInto.SpotifyId; + artistToMergeInto.Thumbnail = artistToMerge.Thumbnail ?? artistToMergeInto.Thumbnail; + artistToMergeInto.Profile = artistToMerge.Profile ?? artistToMergeInto.Profile; + artistToMergeInto.BirthDate = artistToMerge.BirthDate ?? artistToMergeInto.BirthDate; + artistToMergeInto.BeginDate = artistToMerge.BeginDate ?? artistToMergeInto.BeginDate; + artistToMergeInto.EndDate = artistToMerge.EndDate ?? artistToMergeInto.EndDate; + if (!string.IsNullOrEmpty(artistToMerge.ArtistType) && !artistToMerge.ArtistType.Equals("Other", StringComparison.OrdinalIgnoreCase)) + { + artistToMergeInto.ArtistType = artistToMerge.ArtistType; + } + artistToMergeInto.BioContext = artistToMerge.BioContext ?? artistToMergeInto.BioContext; + artistToMergeInto.DiscogsId = artistToMerge.DiscogsId ?? artistToMergeInto.DiscogsId; + artistToMergeInto.Tags = artistToMergeInto.Tags.AddToDelimitedList(artistToMerge.Tags.ToListFromDelimited()); + var altNames = artistToMerge.AlternateNames.ToListFromDelimited().ToList(); + altNames.Add(artistToMerge.Name); + altNames.Add(artistToMerge.SortName); artistToMergeInto.AlternateNames = artistToMergeInto.AlternateNames.AddToDelimitedList(altNames); - artistToMergeInto.URLs = - artistToMergeInto.URLs.AddToDelimitedList(ArtistToMerge.URLs.ToListFromDelimited()); - artistToMergeInto.ISNI = - artistToMergeInto.ISNI.AddToDelimitedList(ArtistToMerge.ISNI.ToListFromDelimited()); + artistToMergeInto.URLs = artistToMergeInto.URLs.AddToDelimitedList(artistToMerge.URLs.ToListFromDelimited()); + artistToMergeInto.ISNI = artistToMergeInto.ISNI.AddToDelimitedList(artistToMerge.ISNI.ToListFromDelimited()); artistToMergeInto.LastUpdated = now; if (doDbUpdates) { - string sql = null; - - sql = "UPDATE `artistGenreTable` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + - ArtistToMerge.Id + ";"; - await DbContext.Database.ExecuteSqlCommandAsync(sql); - sql = "UPDATE `image` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + - ArtistToMerge.Id + ";"; - await DbContext.Database.ExecuteSqlCommandAsync(sql); - sql = "UPDATE `userartist` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + - ArtistToMerge.Id + ";"; - await DbContext.Database.ExecuteSqlCommandAsync(sql); - sql = "UPDATE `track` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + - ArtistToMerge.Id + ";"; - await DbContext.Database.ExecuteSqlCommandAsync(sql); - try { - sql = "UPDATE `release` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + - ArtistToMerge.Id + ";"; - await DbContext.Database.ExecuteSqlCommandAsync(sql); + var artistGenres = DbContext.ArtistGenres.Where(x => x.ArtistId == artistToMerge.Id).ToArray(); + if (artistGenres != null) + { + foreach (var artistGenre in artistGenres) + { + artistGenre.ArtistId = artistToMergeInto.Id; + } + } + var artistImages = DbContext.Images.Where(x => x.ArtistId == artistToMerge.Id).ToArray(); + if (artistImages != null) + { + foreach (var artistImage in artistImages) + { + artistImage.ArtistId = artistToMergeInto.Id; + } + } + var userArtists = DbContext.UserArtists.Where(x => x.ArtistId == artistToMerge.Id).ToArray(); + if (artistImages != null) + { + foreach (var userArtist in userArtists) + { + userArtist.ArtistId = artistToMergeInto.Id; + } + } + var artistTracks = DbContext.Tracks.Where(x => x.ArtistId == artistToMerge.Id).ToArray(); + if (artistTracks != null) + { + foreach (var artistTrack in artistTracks) + { + artistTrack.ArtistId = artistToMergeInto.Id; + } + } + var artistReleases = DbContext.Releases.Where(x => x.ArtistId == artistToMerge.Id).ToArray(); + if (artistReleases != null) + { + foreach (var artistRelease in artistReleases) + { + // See if there is already a release by the same name for the artist to merge into, if so then merge releases + var artistToMergeHasRelease = DbContext.Releases.FirstOrDefault(x => x.ArtistId == artistToMerge.Id && x.Title == artistRelease.Title); + if (artistToMergeHasRelease != null) + { + await ReleaseFactory.MergeReleases(artistRelease, artistToMergeHasRelease, false); + } + else + { + artistRelease.ArtistId = artistToMerge.Id; + } + } + } } catch (Exception ex) { Logger.LogWarning(ex.ToString()); } - var artistFolder = ArtistToMerge.ArtistFileFolder(Configuration, Configuration.LibraryFolder); - foreach (var release in DbContext.Releases.Include("Artist").Where(x => x.ArtistId == ArtistToMerge.Id) - .ToArray()) + var artistFolder = artistToMerge.ArtistFileFolder(Configuration, Configuration.LibraryFolder); + foreach (var release in DbContext.Releases.Include("Artist").Where(x => x.ArtistId == artistToMerge.Id).ToArray()) { var originalReleaseFolder = release.ReleaseFileFolder(artistFolder); await ReleaseFactory.Update(release, null, originalReleaseFolder); } - - await Delete(ArtistToMerge); + await Delete(artistToMerge); } result = true; diff --git a/Roadie.Api.Library/Models/Releases/ReleaseListFromSql.cs b/Roadie.Api.Library/Models/Releases/ReleaseListFromSql.cs deleted file mode 100644 index 6afd58a..0000000 --- a/Roadie.Api.Library/Models/Releases/ReleaseListFromSql.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Roadie.Library.Enums; -using System; - -namespace Roadie.Library.Models.Releases -{ - /// - /// This is used to perform .FromSql() statements and get results from SQL query - /// - [Serializable] - public class ReleaseListFromSql - { - public string ArtistName { get; set; } - public Guid ArtistRoadieId { get; set; } - public DateTime? CreatedDate { get; set; } - public int? Duration { get; set; } - public DateTime? LastPlayed { get; set; } - public DateTime? LastUpdated { get; set; } - public LibraryStatus? LibraryStatus { get; set; } - public short? Rating { get; set; } - public DateTime? ReleaseDateDateTime { get; set; } - public Guid ReleaseRoadieId { get; set; } - public string ReleaseTitle { get; set; } - public int? TrackCount { get; set; } - public int? TrackPlayedCount { get; set; } - } -} \ No newline at end of file diff --git a/Roadie.Api.Library/Models/Statistics/DateAndCount.cs b/Roadie.Api.Library/Models/Statistics/DateAndCount.cs index 138d775..297230d 100644 --- a/Roadie.Api.Library/Models/Statistics/DateAndCount.cs +++ b/Roadie.Api.Library/Models/Statistics/DateAndCount.cs @@ -6,6 +6,17 @@ namespace Roadie.Library.Models.Statistics public class DateAndCount { public int? Count { get; set; } + public string Date { get; set; } + + //public string Date + //{ + // get + // { + // return DateValue.ToString("yyyy-MM-dd"); + // } + //} + + //public DateTime DateValue { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Services/CollectionService.cs b/Roadie.Api.Services/CollectionService.cs index 1d2cb07..3880116 100644 --- a/Roadie.Api.Services/CollectionService.cs +++ b/Roadie.Api.Services/CollectionService.cs @@ -164,24 +164,21 @@ namespace Roadie.Api.Services IQueryable collections = null; if (artistId.HasValue) { - var sql = @"select DISTINCT c.* - from `collectionrelease` cr - join `collection` c on c.id = cr.collectionId - join `release` r on r.id = cr.releaseId - join `artist` a on r.artistId = a.id - where a.roadieId = {0}"; + collections = (from cr in DbContext.CollectionReleases + join c in DbContext.Collections on cr.CollectionId equals c.Id + join r in DbContext.Releases on cr.ReleaseId equals r.Id + join a in DbContext.Artists on r.ArtistId equals a.Id + where a.RoadieId == artistId + select c).Distinct(); - collections = DbContext.Collections.FromSql(sql, artistId); } else if (releaseId.HasValue) { - var sql = @"select DISTINCT c.* - from `collectionrelease` cr - join `collection` c on c.id = cr.collectionId - join `release` r on r.id = cr.releaseId - where r.roadieId = {0}"; - - collections = DbContext.Collections.FromSql(sql, releaseId); + collections = (from cr in DbContext.CollectionReleases + join c in DbContext.Collections on cr.CollectionId equals c.Id + join r in DbContext.Releases on cr.ReleaseId equals r.Id + where r.RoadieId == releaseId + select c).Distinct(); } else { diff --git a/Roadie.Api.Services/IStatisticsService.cs b/Roadie.Api.Services/IStatisticsService.cs index 0fd0ba9..a983e03 100644 --- a/Roadie.Api.Services/IStatisticsService.cs +++ b/Roadie.Api.Services/IStatisticsService.cs @@ -7,7 +7,7 @@ namespace Roadie.Api.Services { public interface IStatisticsService { - Task> LibraryStatistics(); + OperationResult LibraryStatistics(); Task>> ReleasesByDate(); } diff --git a/Roadie.Api.Services/LabelService.cs b/Roadie.Api.Services/LabelService.cs index 8de4bd7..0888d00 100644 --- a/Roadie.Api.Services/LabelService.cs +++ b/Roadie.Api.Services/LabelService.cs @@ -116,7 +116,7 @@ namespace Roadie.Api.Services { Text = l.Name, Value = l.RoadieId.ToString() - }, + }, SortName = l.SortName, CreatedDate = l.CreatedDate, LastUpdated = l.LastUpdated, @@ -131,12 +131,8 @@ namespace Roadie.Api.Services { var randomLimit = roadieUser?.RandomReleaseLimit ?? 100; request.Limit = request.LimitValue > randomLimit ? randomLimit : request.LimitValue; - var sql = "SELECT l.Id FROM `label` l ORDER BY RAND() LIMIT {0}"; - rows = (from rdn in DbContext.Labels.FromSql(sql, randomLimit) - join rs in result on rdn.Id equals rs.DatabaseId - select rs) - .Take(request.LimitValue) - .ToArray(); + rows = result.OrderBy(x => x.RandomSortId).Take(request.LimitValue).ToArray(); + } else { diff --git a/Roadie.Api.Services/StatisticsService.cs b/Roadie.Api.Services/StatisticsService.cs index a0eb585..ffbade0 100644 --- a/Roadie.Api.Services/StatisticsService.cs +++ b/Roadie.Api.Services/StatisticsService.cs @@ -27,84 +27,30 @@ namespace Roadie.Api.Services { } - public async Task> LibraryStatistics() + public OperationResult LibraryStatistics() { LibraryStats result = null; var sw = new Stopwatch(); sw.Start(); try { - using (var conn = new MySqlConnection(Configuration.ConnectionString)) + result = new LibraryStats { - conn.Open(); - var sql = @"SELECT rm.releaseMediaCount AS releaseMediaCount, COUNT(r.roadieId) AS releaseCount, - ts.trackCount, ts.trackDuration as TotalTrackDuration, ts.trackSize as TotalTrackSize, ac.artistCount, lc.labelCount, pc.playedCount, uc.userCount, cc.collectionCount, pl.playlistCount - FROM `release` r - INNER JOIN ( - SELECT COUNT(1) AS trackCount, SUM(t.duration) AS trackDuration, SUM(t.fileSize) AS trackSize - FROM `track` t - JOIN `releasemedia` rm ON rm.id = t.releaseMediaId - JOIN `release` r ON r.id = rm.releaseId - JOIN `artist` a ON a.id = r.artistId - WHERE t.hash IS NOT NULL) ts - INNER JOIN ( - SELECT COUNT(1) AS artistCount - FROM `artist`) ac - INNER JOIN ( - SELECT COUNT(1) AS labelCount - FROM `label`) lc - INNER JOIN ( - SELECT SUM(playedCount) as playedCount - FROM `usertrack`) pc - INNER JOIN ( - SELECT COUNT(1) as releaseMediaCount - FROM `releasemedia`) rm - INNER JOIN ( - SELECT COUNT(1) as userCount - FROM `user`) uc - INNER JOIN ( - SELECT COUNT(1) as collectionCount - FROM `collection`) cc - INNER JOIN ( - SELECT COUNT(1) as playlistCount - FROM `playlist`) pl;"; - using (var cmd = new MySqlCommand(sql, conn)) - { - try - { - using (var rdr = await cmd.ExecuteReaderAsync()) - { - if (rdr.HasRows) - while (rdr.Read()) - result = new LibraryStats - { - UserCount = SafeParser.ToNumber(rdr["UserCount"]), - CollectionCount = SafeParser.ToNumber(rdr["CollectionCount"]), - PlaylistCount = SafeParser.ToNumber(rdr["PlaylistCount"]), - ArtistCount = SafeParser.ToNumber(rdr["ArtistCount"]), - LabelCount = SafeParser.ToNumber(rdr["LabelCount"]), - ReleaseCount = SafeParser.ToNumber(rdr["ReleaseCount"]), - ReleaseMediaCount = SafeParser.ToNumber(rdr["ReleaseMediaCount"]), - PlayedCount = SafeParser.ToNumber(rdr["PlayedCount"]), - TrackCount = SafeParser.ToNumber(rdr["TrackCount"]), - TotalTrackDuration = SafeParser.ToNumber(rdr["TotalTrackDuration"]), - TotalTrackSize = SafeParser.ToNumber(rdr["TotalTrackSize"]) - }; - } - } - catch (Exception ex) - { - Logger.LogError(ex); - } - finally - { - conn.Close(); - } - } - } - + UserCount = DbContext.Users.Count(), + CollectionCount = DbContext.Collections.Count(), + PlayedCount = DbContext.Playlists.Count(), + ArtistCount = DbContext.Artists.Count(), + LabelCount = DbContext.Labels.Count(), + ReleaseCount = DbContext.Releases.Count(), + ReleaseMediaCount = DbContext.ReleaseMedias.Count() + }; + result.PlayedCount = DbContext.UserTracks.Sum(x => x.PlayedCount); + var tracks = DbContext.Tracks.Where(x => x.Hash != null); + result.TrackCount = tracks.Count(); + result.TotalTrackDuration = tracks.Sum(x => (long?)x.Duration); + result.TotalTrackSize = tracks.Sum(x => (long?)x.FileSize); var lastScan = DbContext.ScanHistories.OrderByDescending(x => x.CreatedDate).FirstOrDefault(); - if (lastScan != null) result.LastScan = lastScan.CreatedDate; + result.LastScan = lastScan?.CreatedDate; sw.Stop(); } catch (Exception ex) @@ -124,46 +70,28 @@ namespace Roadie.Api.Services { var sw = new Stopwatch(); sw.Start(); - var result = new List(); - - using (var conn = new MySqlConnection(Configuration.ConnectionString)) + var dateInfos = (from r in DbContext.Releases + orderby r.CreatedDate + group r by r.CreatedDate.ToString("yyyy-MM-dd") into g + select new + { + date = g.Key, + count = g.Count() + }); + foreach (var dateInfo in dateInfos) { - conn.Open(); - var sql = @"SELECT DATE_FORMAT(createdDate, '%Y-%m-%d') as date, count(1) as count - FROM `release` - group by DATE_FORMAT(createdDate, '%Y-%m-%d') - order by createdDate;"; - using (var cmd = new MySqlCommand(sql, conn)) + result.Add(new DateAndCount { - try - { - using (var rdr = cmd.ExecuteReader()) - { - if (rdr.HasRows) - while (rdr.Read()) - result.Add(new DateAndCount - { - Date = SafeParser.ToString(rdr["date"]), - Count = SafeParser.ToNumber(rdr["count"]) - }); - } - } - catch (Exception ex) - { - Logger.LogError(ex); - } - finally - { - conn.Close(); - } - } + Date = dateInfo.date, + Count = dateInfo.count + }); } - sw.Stop(); return Task.FromResult(new OperationResult> { OperationTime = sw.ElapsedMilliseconds, + IsSuccess = result != null, Data = result }); } diff --git a/Roadie.Api.Services/TrackService.cs b/Roadie.Api.Services/TrackService.cs index 7dd10fb..ccd2ec0 100644 --- a/Roadie.Api.Services/TrackService.cs +++ b/Roadie.Api.Services/TrackService.cs @@ -246,76 +246,49 @@ namespace Roadie.Api.Services where a.RoadieId == request.FilterToArtistId orderby ut.PlayedCount descending select t.Id - ).Skip(request.SkipValue).Take(request.LimitValue); + ).Skip(request.SkipValue) + .Take(request.LimitValue); } int[] randomTrackIds = null; if (doRandomize ?? false) { - request.Limit = roadieUser?.RandomReleaseLimit ?? 50; + var randomLimit = roadieUser?.RandomReleaseLimit ?? request.Limit ?? 50; var userId = roadieUser?.Id ?? -1; - if (!request.FilterRatedOnly && !request.FilterFavoriteOnly) + if (!request.FilterFavoriteOnly) { - var sql = @"SELECT t.id - FROM `track` t - JOIN `releasemedia` rm on (t.releaseMediaId = rm.id) - WHERE t.Hash IS NOT NULL - AND t.id NOT IN (SELECT ut.trackId - FROM `usertrack` ut - WHERE ut.userId = {0} - AND ut.isDisliked = 1) - AND rm.releaseId in (select distinct r.id - FROM `release` r - WHERE r.id NOT IN (SELECT ur.releaseId - FROM `userrelease` ur - WHERE ur.userId = {0} - AND ur.isDisliked = 1) - AND r.artistId IN (select DISTINCT a.id - FROM `artist` a - WHERE a.id NOT IN (select ua.artistId - FROM `userartist` ua - where ua.userId = {0} - AND ua.isDisliked = 1) - ORDER BY RAND()) - ORDER BY RAND()) - ORDER BY RAND() - LIMIT {1}"; - randomTrackIds = DbContext.Tracks.FromSql(sql, userId, request.Limit).Select(x => x.Id) - .ToArray(); + // Select random tracks that are not disliked Artist, Release or Track by user. + var dislikedArtistIds = (from ua in DbContext.UserArtists + where ua.UserId == userId + where ua.IsDisliked == true + select ua.ArtistId).ToArray(); + var dislikedReleaseIds = (from ur in DbContext.UserReleases + where ur.UserId == userId + where ur.IsDisliked == true + select ur.ReleaseId).ToArray(); + var dislikedTrackIds = (from ut in DbContext.UserTracks + where ut.UserId == userId + where ut.IsDisliked == true + select ut.TrackId).ToArray(); + randomTrackIds = (from t in DbContext.Tracks + join rm in DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id + join r in DbContext.Releases on rm.ReleaseId equals r.Id + where !request.FilterRatedOnly || request.FilterRatedOnly && t.Rating > 0 + where !dislikedArtistIds.Contains(r.ArtistId) + where !dislikedArtistIds.Contains(t.ArtistId ?? 0) + where !dislikedReleaseIds.Contains(r.Id) + where !dislikedTrackIds.Contains(t.Id) + where t.Hash != null + select new TrackList + { + DatabaseId = t.Id + }) + .OrderBy(x => x.RandomSortId) + .Take(randomLimit) + .Select(x => x.DatabaseId) + .ToArray(); } - - if (request.FilterRatedOnly && !request.FilterFavoriteOnly) - { - var sql = @"SELECT t.id - FROM `track` t - JOIN `releasemedia` rm on (t.releaseMediaId = rm.id) - WHERE t.Hash IS NOT NULL - AND t.rating > 0 - AND t.id NOT IN (SELECT ut.trackId - FROM `usertrack` ut - WHERE ut.userId = {0} - AND ut.isDisliked = 1) - AND rm.releaseId in (select distinct r.id - FROM `release` r - WHERE r.id NOT IN (SELECT ur.releaseId - FROM `userrelease` ur - WHERE ur.userId = {0} - AND ur.isDisliked = 1) - AND r.artistId IN (select DISTINCT a.id - FROM `artist` a - WHERE a.id NOT IN (select ua.artistId - FROM `userartist` ua - where ua.userId = {0} - AND ua.isDisliked = 1) - ORDER BY RAND()) - ORDER BY RAND()) - ORDER BY RAND() - LIMIT {1}"; - randomTrackIds = DbContext.Tracks.FromSql(sql, userId, request.LimitValue).Select(x => x.Id) - .ToArray(); - } - if (request.FilterFavoriteOnly) { rowCount = favoriteTrackIds.Count(); @@ -349,9 +322,7 @@ namespace Roadie.Api.Services filterToTrackIds = f.ToArray(); } - var normalizedFilterValue = !string.IsNullOrEmpty(request.FilterValue) - ? request.FilterValue.ToAlphanumericName() - : null; + var normalizedFilterValue = !string.IsNullOrEmpty(request.FilterValue) ? request.FilterValue.ToAlphanumericName() : null; var isEqualFilter = false; if (!string.IsNullOrEmpty(request.FilterValue)) @@ -365,7 +336,7 @@ namespace Roadie.Api.Services } } - // Did this for performance against the Track table, with just * selcts the table scans are too much of a performance hit. + // Did this for performance against the Track table, with just * selects the table scans are too much of a performance hit. var resultQuery = from t in DbContext.Tracks join rm in DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id join r in DbContext.Releases on rm.ReleaseId equals r.Id @@ -373,8 +344,9 @@ namespace Roadie.Api.Services join trackArtist in DbContext.Artists on t.ArtistId equals trackArtist.Id into tas from trackArtist in tas.DefaultIfEmpty() where t.Hash != null - where releaseId == null || releaseId != null && r.RoadieId == releaseId + where randomTrackIds == null || randomTrackIds.Contains(t.Id) where filterToTrackIds == null || filterToTrackIds.Contains(t.RoadieId) + where releaseId == null || releaseId != null && r.RoadieId == releaseId where request.FilterMinimumRating == null || t.Rating >= request.FilterMinimumRating.Value where request.FilterValue == "" || t.Title.Contains(request.FilterValue) || t.AlternateNames.Contains(request.FilterValue) || @@ -385,7 +357,6 @@ namespace Roadie.Api.Services where !request.FilterFavoriteOnly || favoriteTrackIds.Contains(t.Id) where request.FilterToPlaylistId == null || playlistTrackIds.Contains(t.Id) where !request.FilterTopPlayedOnly || topTrackids.Contains(t.Id) - where randomTrackIds == null || randomTrackIds.Contains(t.Id) where request.FilterToArtistId == null || request.FilterToArtistId != null && (t.TrackArtist != null && t.TrackArtist.RoadieId == request.FilterToArtistId || r.Artist.RoadieId == request.FilterToArtistId) @@ -530,21 +501,19 @@ namespace Roadie.Api.Services if (request.Action == User.ActionKeyUserRated) { sortBy = string.IsNullOrEmpty(request.Sort) - ? request.OrderValue(new Dictionary - {{"UserTrack.Rating", "DESC"}, {"MediaNumber", "ASC"}, {"TrackNumber", "ASC"}}) + ? request.OrderValue(new Dictionary{{"UserTrack.Rating", "DESC"}, {"MediaNumber", "ASC"}, {"TrackNumber", "ASC"}}) : request.OrderValue(); } else { sortBy = string.IsNullOrEmpty(request.Sort) - ? request.OrderValue(new Dictionary - {{"Release.Release.Text", "ASC"}, {"MediaNumber", "ASC"}, {"TrackNumber", "ASC"}}) + ? request.OrderValue(new Dictionary{{"Release.Release.Text", "ASC"}, {"MediaNumber", "ASC"}, {"TrackNumber", "ASC"}}) : request.OrderValue(); } if (doRandomize ?? false) { - rows = result.OrderBy(x => x.RandomSortId).Take(request.LimitValue).ToArray(); + rows = result.ToArray(); } else { @@ -558,7 +527,6 @@ namespace Roadie.Api.Services where ut.UserId == roadieUser.Id where rowIds.Contains(ut.TrackId) select ut).ToArray(); - foreach (var userTrackRating in userTrackRatings) { var row = rows.FirstOrDefault(x => x.DatabaseId == userTrackRating.TrackId); @@ -577,9 +545,9 @@ namespace Roadie.Api.Services var releaseIds = rows.Select(x => x.Release.DatabaseId).Distinct().ToArray(); var userReleaseRatings = (from ur in DbContext.UserReleases + where ur.UserId == roadieUser.Id where releaseIds.Contains(ur.ReleaseId) select ur).ToArray(); - foreach (var userReleaseRating in userReleaseRatings) { foreach (var row in rows.Where(x => x.Release.DatabaseId == userReleaseRating.ReleaseId)) @@ -605,8 +573,7 @@ namespace Roadie.Api.Services } } - var trackArtistIds = rows.Where(x => x.TrackArtist != null).Select(x => x.TrackArtist.DatabaseId) - .ToArray(); + var trackArtistIds = rows.Where(x => x.TrackArtist != null).Select(x => x.TrackArtist.DatabaseId).ToArray(); if (trackArtistIds != null && trackArtistIds.Any()) { var userTrackArtistRatings = (from ua in DbContext.UserArtists @@ -630,13 +597,14 @@ namespace Roadie.Api.Services if (rows.Any()) { + var rowIds = rows.Select(x => x.DatabaseId).ToArray(); + var favoriteUserTrackRatings = (from ut in DbContext.UserTracks + where ut.IsFavorite ?? false + where rowIds.Contains(ut.TrackId) + select ut).ToArray(); foreach (var row in rows) { - row.FavoriteCount = (from ut in DbContext.UserTracks - join tr in DbContext.Tracks on ut.TrackId equals tr.Id - where ut.TrackId == row.DatabaseId - where ut.IsFavorite ?? false - select ut.Id).Count(); + row.FavoriteCount = favoriteUserTrackRatings.Where(x => x.TrackId == row.DatabaseId).Count(); } } @@ -652,8 +620,7 @@ namespace Roadie.Api.Services } catch (Exception ex) { - Logger.LogError(ex, "Error In List, Request [{0}], User [{1}]", JsonConvert.SerializeObject(request), - roadieUser); + Logger.LogError(ex, "Error In List, Request [{0}], User [{1}]", JsonConvert.SerializeObject(request),roadieUser); return Task.FromResult(new Library.Models.Pagination.PagedResult { Message = "An Error has occured" diff --git a/Roadie.Api/Controllers/ReleaseController.cs b/Roadie.Api/Controllers/ReleaseController.cs index 6e360e3..5f67006 100644 --- a/Roadie.Api/Controllers/ReleaseController.cs +++ b/Roadie.Api/Controllers/ReleaseController.cs @@ -74,11 +74,9 @@ namespace Roadie.Api.Controllers [ProducesResponseType(200)] [ProducesResponseType(404)] [Authorize(Policy = "Editor")] - public async Task MergeReleases(Guid releaseToMergeId, Guid releaseToMergeIntoId, - bool addAsMedia) + public async Task MergeReleases(Guid releaseToMergeId, Guid releaseToMergeIntoId, bool addAsMedia) { - var result = await ReleaseService.MergeReleases(await CurrentUserModel(), releaseToMergeId, - releaseToMergeIntoId, addAsMedia); + var result = await ReleaseService.MergeReleases(await CurrentUserModel(), releaseToMergeId, releaseToMergeIntoId, addAsMedia); if (result == null || result.IsNotFoundResult) return NotFound(); if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError); return Ok(result); @@ -90,9 +88,7 @@ namespace Roadie.Api.Controllers [Authorize(Policy = "Editor")] public async Task SetReleaseImageByUrl(Guid id, string imageUrl) { - var result = - await ReleaseService.SetReleaseImageByUrl(await CurrentUserModel(), id, - HttpUtility.UrlDecode(imageUrl)); + var result = await ReleaseService.SetReleaseImageByUrl(await CurrentUserModel(), id, HttpUtility.UrlDecode(imageUrl)); if (result == null || result.IsNotFoundResult) return NotFound(); if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError); return Ok(result); diff --git a/Roadie.Api/Controllers/StatsController.cs b/Roadie.Api/Controllers/StatsController.cs index abe00fa..10a723d 100644 --- a/Roadie.Api/Controllers/StatsController.cs +++ b/Roadie.Api/Controllers/StatsController.cs @@ -52,7 +52,7 @@ namespace Roadie.Api.Controllers [ProducesResponseType(200)] public async Task Library() { - return Ok(await StatisticsService.LibraryStatistics()); + return Ok(StatisticsService.LibraryStatistics()); } [HttpGet("ping")] diff --git a/Roadie.Api/appsettings.Development.json b/Roadie.Api/appsettings.Development.json index 4766935..65b598f 100644 --- a/Roadie.Api/appsettings.Development.json +++ b/Roadie.Api/appsettings.Development.json @@ -13,7 +13,7 @@ "Override": { "System": "Warning", "Microsoft.AspNetCore": "Warning", - "Microsoft.EntityFrameworkCore": "Warning" + "Microsoft.EntityFrameworkCore": "Information" } }, "WriteTo": [ diff --git a/Roadie.sln b/Roadie.sln index f0ebf86..38652a0 100644 --- a/Roadie.sln +++ b/Roadie.sln @@ -15,6 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{1BA7 Upgrade0001.sql = Upgrade0001.sql Upgrade0002.sql = Upgrade0002.sql Upgrade0003.sql = Upgrade0003.sql + Upgrade0004.sql = Upgrade0004.sql EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roadie.Api.Services", "Roadie.Api.Services\Roadie.Api.Services.csproj", "{7B37031E-F2AE-4BE2-9F6F-005CA7A6FDF1}" diff --git a/Upgrade0004.sql b/Upgrade0004.sql new file mode 100644 index 0000000..c5f7781 --- /dev/null +++ b/Upgrade0004.sql @@ -0,0 +1,3 @@ +-- Add new column to Genre for Normalized Name < 1.0.2.1 database +ALTER TABLE `genre` ADD `normalizedName` varchar(100) NULL; +CREATE INDEX `genre_normalizedName_IDX` USING BTREE ON `genre` (normalizedName); \ No newline at end of file diff --git a/roadie.sql b/roadie.sql index 80a01c2..89e32a0 100644 --- a/roadie.sql +++ b/roadie.sql @@ -1,10 +1,10 @@ -- /// --- Roadie version 1.0.2.0 new database script, if upgrading skip this and run Upgrade*.sql scripts from your version to current. +-- Roadie version 1.0.2.1 new database script, if upgrading skip this and run Upgrade*.sql scripts from your version to current. -- /// -- MySQL dump 10.17 Distrib 10.3.16-MariaDB, for Linux (x86_64) -- --- Host: localhost Database: roadie_dev +-- Host: localhost Database: roadie -- ------------------------------------------------------ -- Server version 10.3.16-MariaDB-log @@ -30,30 +30,30 @@ CREATE TABLE `artist` ( `id` int(11) NOT NULL AUTO_INCREMENT, `isLocked` tinyint(1) DEFAULT NULL, `status` smallint(6) DEFAULT NULL, - `roadieId` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `roadieId` varchar(36) DEFAULT NULL, `createdDate` datetime DEFAULT NULL, `lastUpdated` datetime DEFAULT NULL, - `name` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL, - `sortName` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `name` varchar(250) NOT NULL, + `sortName` varchar(250) DEFAULT NULL, `rating` smallint(6) NOT NULL, - `realName` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `musicBrainzId` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `iTunesId` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `amgId` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `spotifyId` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `realName` varchar(500) DEFAULT NULL, + `musicBrainzId` varchar(100) DEFAULT NULL, + `iTunesId` varchar(100) DEFAULT NULL, + `amgId` varchar(100) DEFAULT NULL, + `spotifyId` varchar(100) DEFAULT NULL, `thumbnail` blob DEFAULT NULL, - `profile` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `profile` text DEFAULT NULL, `birthDate` date DEFAULT NULL, `beginDate` date DEFAULT NULL, `endDate` date DEFAULT NULL, - `artistType` enum('Character','Choir','Group','Meta','Orchestra','Other','Person') COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `bioContext` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `bandStatus` enum('Active','On Hold','Split Up','Deceased') COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `discogsId` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `tags` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `alternateNames` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `urls` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `isniList` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `artistType` enum('Person','Group','Orchestra','Choir','Character','Meta','Other') DEFAULT NULL, + `bioContext` text DEFAULT NULL, + `bandStatus` enum('Active','On Hold','Split Up','Deceased') DEFAULT NULL, + `discogsId` varchar(50) DEFAULT NULL, + `tags` text DEFAULT NULL, + `alternateNames` text DEFAULT NULL, + `urls` text DEFAULT NULL, + `isniList` text DEFAULT NULL, `releaseCount` int(11) DEFAULT NULL, `trackCount` int(11) DEFAULT NULL, `playedCount` int(11) DEFAULT NULL, @@ -63,7 +63,7 @@ CREATE TABLE `artist` ( UNIQUE KEY `ix_artist_name` (`name`), UNIQUE KEY `ix_artist_sortname` (`sortName`), KEY `ix_artist_roadieId` (`roadieId`) -) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=39125 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -82,7 +82,7 @@ CREATE TABLE `artistAssociation` ( KEY `idx_artistAssociation` (`artistId`,`associatedArtistId`), CONSTRAINT `artistAssociation_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE, CONSTRAINT `artistAssociation_ibfk_2` FOREIGN KEY (`associatedArtistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=194 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -102,7 +102,26 @@ CREATE TABLE `artistGenreTable` ( KEY `ix_artistGenreTable_artistId` (`artistId`), CONSTRAINT `artistGenreTable_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE, CONSTRAINT `artistGenreTable_ibfk_2` FOREIGN KEY (`genreId`) REFERENCES `genre` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=63094 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `artistSimilar` +-- + +DROP TABLE IF EXISTS `artistSimilar`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `artistSimilar` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `artistId` int(11) NOT NULL, + `similarArtistId` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `similarArtistId` (`similarArtistId`), + KEY `idx_artistSimilar` (`artistId`,`similarArtistId`), + CONSTRAINT `artistSimilar_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE, + CONSTRAINT `artistSimilar_ibfk_2` FOREIGN KEY (`similarArtistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -129,7 +148,7 @@ CREATE TABLE `bookmark` ( KEY `ix_bookmark_roadieId` (`roadieId`), KEY `ix_bookmark_userId` (`userId`), CONSTRAINT `bookmark_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=603 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -151,7 +170,7 @@ CREATE TABLE `chatMessage` ( PRIMARY KEY (`id`), KEY `idx_user` (`userId`), CONSTRAINT `chatMessage_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=82 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -186,7 +205,7 @@ CREATE TABLE `collection` ( KEY `maintainerId` (`maintainerId`), KEY `ix_collection_roadieId` (`roadieId`), CONSTRAINT `collection_ibfk_1` FOREIGN KEY (`maintainerId`) REFERENCES `user` (`id`) ON DELETE SET NULL -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=124 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -197,13 +216,15 @@ DROP TABLE IF EXISTS `collectionMissing`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `collectionMissing` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `collectionId` int(11) NOT NULL, `isArtistFound` tinyint(1) DEFAULT NULL, `position` int(11) NOT NULL, `artist` varchar(1000) COLLATE utf8mb4_unicode_ci NOT NULL, `release` varchar(1000) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`id`), KEY `ix_collection_collectionId` (`collectionId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=36840 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -229,7 +250,7 @@ CREATE TABLE `collectionrelease` ( KEY `ix_collectionrelease_roadieId` (`roadieId`), CONSTRAINT `collectionrelease_ibfk_1` FOREIGN KEY (`releaseId`) REFERENCES `release` (`id`) ON DELETE CASCADE, CONSTRAINT `collectionrelease_ibfk_2` FOREIGN KEY (`collectionId`) REFERENCES `collection` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=153918 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -273,7 +294,7 @@ CREATE TABLE `comment` ( CONSTRAINT `commentrelease_ibfk_1` FOREIGN KEY (`releaseId`) REFERENCES `release` (`id`) ON DELETE CASCADE, CONSTRAINT `commenttrack_ibfk_1` FOREIGN KEY (`trackId`) REFERENCES `track` (`id`) ON DELETE CASCADE, CONSTRAINT `commentuser_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -299,7 +320,7 @@ CREATE TABLE `commentReaction` ( KEY `commentReactioncomment_ibfk_1` (`commentId`), CONSTRAINT `commentReactioncomment_ibfk_1` FOREIGN KEY (`commentId`) REFERENCES `comment` (`id`) ON DELETE CASCADE, CONSTRAINT `commentReactionuser_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -313,14 +334,16 @@ CREATE TABLE `genre` ( `id` int(11) NOT NULL AUTO_INCREMENT, `isLocked` tinyint(1) DEFAULT NULL, `status` smallint(6) DEFAULT NULL, - `roadieId` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `roadieId` varchar(36) DEFAULT NULL, `createdDate` datetime DEFAULT NULL, `lastUpdated` datetime DEFAULT NULL, - `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(100) NOT NULL, + `normalizedName` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ix_genre_name` (`name`), - KEY `ix_genre_roadieId` (`roadieId`) -) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + KEY `ix_genre_roadieId` (`roadieId`), + KEY `genre_normalizedName_IDX` (`normalizedName`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=2530 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -349,7 +372,7 @@ CREATE TABLE `image` ( KEY `ix_image_artistId` (`artistId`), CONSTRAINT `image_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE, CONSTRAINT `image_ibfk_2` FOREIGN KEY (`releaseId`) REFERENCES `release` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=78565 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -384,7 +407,7 @@ CREATE TABLE `label` ( PRIMARY KEY (`id`), UNIQUE KEY `ix_label_name` (`name`), KEY `ix_label_roadieId` (`roadieId`) -) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=2983 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -417,7 +440,7 @@ CREATE TABLE `playlist` ( KEY `ix_playlist_roadieId` (`roadieId`), KEY `ix_playlist_userId` (`userId`), CONSTRAINT `playlist_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -443,7 +466,7 @@ CREATE TABLE `playlisttrack` ( KEY `ix_playlisttrack_roadieId` (`roadieId`), CONSTRAINT `playlisttrack_ibfk_1` FOREIGN KEY (`trackId`) REFERENCES `track` (`id`) ON DELETE CASCADE, CONSTRAINT `playlisttrack_ibfk_2` FOREIGN KEY (`playListId`) REFERENCES `playlist` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=694 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=1145 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -491,7 +514,7 @@ CREATE TABLE `release` ( KEY `ix_release_roadieId` (`roadieId`), KEY `ix_release_title` (`title`), CONSTRAINT `release_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=35930 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -510,7 +533,7 @@ CREATE TABLE `releaseGenreTable` ( KEY `idx_releaseGenreTableReleaseAndGenre` (`releaseId`,`genreId`), CONSTRAINT `releaseGenreTable_ibfk_1` FOREIGN KEY (`releaseId`) REFERENCES `release` (`id`) ON DELETE CASCADE, CONSTRAINT `releaseGenreTable_ibfk_2` FOREIGN KEY (`genreId`) REFERENCES `genre` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=73 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=106302 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -538,7 +561,7 @@ CREATE TABLE `releaselabel` ( KEY `ix_releaselabel_roadieId` (`roadieId`), CONSTRAINT `releaselabel_ibfk_1` FOREIGN KEY (`releaseId`) REFERENCES `release` (`id`) ON DELETE CASCADE, CONSTRAINT `releaselabel_ibfk_2` FOREIGN KEY (`labelId`) REFERENCES `label` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=12682 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -563,7 +586,7 @@ CREATE TABLE `releasemedia` ( KEY `ix_releasemedia_roadieId` (`roadieId`), KEY `releasemedia_releaseId_IDX` (`releaseId`,`releaseMediaNumber`) USING BTREE, CONSTRAINT `releasemedia_ibfk_1` FOREIGN KEY (`releaseId`) REFERENCES `release` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=34772 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -585,7 +608,7 @@ CREATE TABLE `request` ( KEY `ix_request_roadieId` (`roadieId`), KEY `requestartist_ibfk_1` (`userId`), CONSTRAINT `requestartist_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=1473 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -610,8 +633,9 @@ CREATE TABLE `scanHistory` ( `timeSpanInSeconds` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `ix_scanHistory_roadieId` (`roadieId`), - KEY `rscanHistoryt_ibfk_1` (`userId`) -) ENGINE=InnoDB AUTO_INCREMENT=79 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + KEY `rscanHistoryt_ibfk_1` (`userId`), + CONSTRAINT `scanHistory_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE NO ACTION +) ENGINE=InnoDB AUTO_INCREMENT=2077 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -633,7 +657,7 @@ CREATE TABLE `submission` ( KEY `ix_submission_roadieId` (`roadieId`), KEY `submission_ibfk_1` (`userId`), CONSTRAINT `submission_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE SET NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -647,29 +671,29 @@ CREATE TABLE `track` ( `id` int(11) NOT NULL AUTO_INCREMENT, `isLocked` tinyint(1) DEFAULT NULL, `status` smallint(6) DEFAULT NULL, - `roadieId` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `roadieId` varchar(36) DEFAULT NULL, `createdDate` datetime DEFAULT NULL, `lastUpdated` datetime DEFAULT NULL, - `filePath` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `fileName` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `filePath` varchar(1000) DEFAULT NULL, + `fileName` varchar(500) DEFAULT NULL, `fileSize` int(11) DEFAULT NULL, - `hash` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `hash` varchar(32) DEFAULT NULL, `playedCount` int(11) DEFAULT NULL, `lastPlayed` datetime DEFAULT NULL, - `partTitles` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `partTitles` text DEFAULT NULL, `rating` smallint(6) NOT NULL, - `musicBrainzId` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `lastFMId` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `amgId` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `spotifyId` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `title` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL, - `alternateNames` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `musicBrainzId` varchar(100) DEFAULT NULL, + `lastFMId` varchar(50) DEFAULT NULL, + `amgId` varchar(100) DEFAULT NULL, + `spotifyId` varchar(100) DEFAULT NULL, + `title` varchar(250) NOT NULL, + `alternateNames` text DEFAULT NULL, `trackNumber` smallint(6) NOT NULL, `duration` int(11) DEFAULT NULL, - `tags` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `tags` text DEFAULT NULL, `releaseMediaId` int(11) DEFAULT NULL, `artistId` int(11) DEFAULT NULL, - `isrc` varchar(15) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `isrc` varchar(15) DEFAULT NULL, `thumbnail` blob DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_track_unique_to_eleasemedia` (`releaseMediaId`,`trackNumber`), @@ -679,7 +703,7 @@ CREATE TABLE `track` ( KEY `track_artistId_IDX` (`artistId`) USING BTREE, KEY `track_releaseMediaId_IDX` (`releaseMediaId`) USING BTREE, CONSTRAINT `track_ibfk_1` FOREIGN KEY (`releaseMediaId`) REFERENCES `releasemedia` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=428 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=369906 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -753,7 +777,7 @@ CREATE TABLE `user` ( UNIQUE KEY `email` (`email`), UNIQUE KEY `ix_user_username` (`username`), KEY `ix_user_roadieId` (`roadieId`) -) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -844,7 +868,7 @@ CREATE TABLE `userartist` ( KEY `ix_userartist_roadieId` (`roadieId`), CONSTRAINT `userartist_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE, CONSTRAINT `userartist_ibfk_2` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=108 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -872,7 +896,7 @@ CREATE TABLE `userrelease` ( KEY `ix_userrelease_roadieId` (`roadieId`), CONSTRAINT `userrelease_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE, CONSTRAINT `userrelease_ibfk_2` FOREIGN KEY (`releaseId`) REFERENCES `release` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=232 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -915,7 +939,7 @@ CREATE TABLE `usersInRoles` ( KEY `ix_usersInRoles_userId` (`userId`), CONSTRAINT `usersInRoles_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE, CONSTRAINT `usersInRoles_ibfk_2` FOREIGN KEY (`userRoleId`) REFERENCES `userrole` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -945,7 +969,7 @@ CREATE TABLE `usertrack` ( KEY `ix_usertrack_roadieId` (`roadieId`), CONSTRAINT `usertrack_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE, CONSTRAINT `usertrack_ibfk_2` FOREIGN KEY (`trackId`) REFERENCES `track` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=237 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=32824 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1031,4 +1055,4 @@ SET character_set_client = @saved_cs_client; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2019-06-30 8:12:31 +-- Dump completed on 2019-07-03 21:51:04