diff --git a/Roadie.Api.Library.Tests/Roadie.Library.Tests.csproj b/Roadie.Api.Library.Tests/Roadie.Library.Tests.csproj index fd8c493..d8fb547 100644 --- a/Roadie.Api.Library.Tests/Roadie.Library.Tests.csproj +++ b/Roadie.Api.Library.Tests/Roadie.Library.Tests.csproj @@ -25,7 +25,6 @@ - all diff --git a/Roadie.Api.Library.Tests/TokenHelperTests.cs b/Roadie.Api.Library.Tests/TokenHelperTests.cs index eea1664..01cfd21 100644 --- a/Roadie.Api.Library.Tests/TokenHelperTests.cs +++ b/Roadie.Api.Library.Tests/TokenHelperTests.cs @@ -18,7 +18,7 @@ namespace Roadie.Library.Tests { var sw = Stopwatch.StartNew(); - var token = ServiceBase.TrackPlayToken(new ApplicationUser + var token = ServiceBase.TrackPlayToken(new User { Id = 1, CreatedDate = DateTime.UtcNow diff --git a/Roadie.Api.Library/Configuration/DbContexts.cs b/Roadie.Api.Library/Configuration/DbContexts.cs index 5dbb81f..1ade496 100644 --- a/Roadie.Api.Library/Configuration/DbContexts.cs +++ b/Roadie.Api.Library/Configuration/DbContexts.cs @@ -1,12 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Roadie.Library.Configuration +namespace Roadie.Library.Configuration { public enum DbContexts : short { - MySQL = 1, - File = 2 + Unknown = 0, + SQLite = 1, + File = 2, + MySQL = 3 } -} +} \ No newline at end of file diff --git a/Roadie.Api.Library/Configuration/FileDatabaseOptions.cs b/Roadie.Api.Library/Configuration/FileDatabaseOptions.cs index 28775ea..7d0c6ac 100644 --- a/Roadie.Api.Library/Configuration/FileDatabaseOptions.cs +++ b/Roadie.Api.Library/Configuration/FileDatabaseOptions.cs @@ -19,7 +19,7 @@ namespace Roadie.Library.Configuration { DatabaseFormat = FileDatabaseFormat.BSON; DatabaseName = "roadie"; - DatabaseFolder = @"M:\db"; + DatabaseFolder = "data/db"; } } } diff --git a/Roadie.Api.Library/Configuration/Integrations.cs b/Roadie.Api.Library/Configuration/Integrations.cs index d601d1f..1c6fe05 100644 --- a/Roadie.Api.Library/Configuration/Integrations.cs +++ b/Roadie.Api.Library/Configuration/Integrations.cs @@ -19,8 +19,7 @@ namespace Roadie.Library.Configuration var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey"); if (keySetting != null) return keySetting.Key; - Trace.WriteLine( - "Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled"); + Trace.WriteLine("Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled", "Warning"); return null; } } @@ -32,8 +31,7 @@ namespace Roadie.Library.Configuration var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "DiscogsConsumerKey"); if (keySetting != null) return keySetting.KeySecret; - Trace.WriteLine( - "Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled"); + Trace.WriteLine("Unable To Find Api Key with Key Name of 'DiscogsConsumerKey', Discogs Integration Disabled", "Warning"); return null; } } @@ -77,7 +75,7 @@ namespace Roadie.Library.Configuration var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey"); if (keySetting != null) return keySetting.Key; - Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled"); + Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled", "Warning"); return null; } } @@ -89,7 +87,7 @@ namespace Roadie.Library.Configuration var keySetting = ApiKeys.FirstOrDefault(x => x.ApiName == "LastFMApiKey"); if (keySetting != null) return keySetting.KeySecret; - Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled"); + Trace.WriteLine("Unable To Find Api Key with Key Name of 'LastFMApiKey', Last FM Integration Disabled", "Warning"); return null; } } diff --git a/Roadie.Api.Library/Configuration/RoadieSettings.cs b/Roadie.Api.Library/Configuration/RoadieSettings.cs index f892a95..31f6c1a 100644 --- a/Roadie.Api.Library/Configuration/RoadieSettings.cs +++ b/Roadie.Api.Library/Configuration/RoadieSettings.cs @@ -9,7 +9,7 @@ namespace Roadie.Library.Configuration { public static string RoadieImageFolder = "__roadie_images"; - public DbContexts DbContextToUse { get; set; } + public DbContexts DbContextToUse { get; set; } = DbContexts.SQLite; /// /// If the artist name is found in the values then use the key. @@ -81,7 +81,6 @@ namespace Roadie.Library.Configuration } public ImageSize LargeImageSize { get; set; } - public string LibraryFolder { get; set; } public string ListenAddress { get; set; } @@ -151,7 +150,7 @@ namespace Roadie.Library.Configuration public RoadieSettings() { - DbContextToUse = DbContexts.MySQL; + DbContextToUse = DbContexts.SQLite; ArtistNameReplace = new Dictionary> { { "AC/DC", new List{ "AC; DC", "AC;DC", "AC/ DC", "AC DC" }}, @@ -159,10 +158,10 @@ namespace Roadie.Library.Configuration }; DefaultTimeZone = "US / Central"; DontDoMetaDataProvidersSearchArtists = new List { "Various Artists", "Sound Tracks" }; - FileExtensionsToDelete = new List { ".accurip", ".bmp", ".cue", ".dat", ".db", ".exe", ".gif", ".htm", ".html", ".ini", ".log", ".jpg", ".jpeg", ".par", ".par2", ".pdf", ".png", ".md5", ".mht", ".mpg", ".m3u", ".nfo", ".nzb", ".pls", ".sfv", ".srr", ".txt", ".url" }; - InboundFolder = "M:/inbound"; + FileExtensionsToDelete = new List { ".accurip", ".cue", ".dat", ".db", ".exe", ".htm", ".html", ".ini", ".log", ".par", ".par2", ".pdf", ".md5", ".mht", ".mpg", ".m3u", ".nfo", ".nzb", ".pls", ".sfv", ".srr", ".txt", ".url" }; + InboundFolder = "data/inbound"; LargeImageSize = new ImageSize { Width = 500, Height = 500 }; - LibraryFolder = "M:/library"; + LibraryFolder = "data/library"; MaximumImageSize = new ImageSize { Width = 2048, Height = 2048 }; MediumImageSize = new ImageSize { Width = 320, Height = 320 }; RecordNoResultSearches = true; @@ -174,7 +173,6 @@ namespace Roadie.Library.Configuration SmtpFromAddress = "noreply@roadie.rocks"; SmtpPort = 587; SmtpUsername = "roadie"; - SmtpHost = "smtp.roadie.rocks"; SmtpUseSSl = true; Inspector = new Inspector(); diff --git a/Roadie.Api.Library/Data/Artist.cs b/Roadie.Api.Library/Data/Artist.cs index d9910ad..9b250b4 100644 --- a/Roadie.Api.Library/Data/Artist.cs +++ b/Roadie.Api.Library/Data/Artist.cs @@ -1,5 +1,4 @@ using Roadie.Library.Enums; -using Roadie.Library.Imaging; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -10,12 +9,18 @@ namespace Roadie.Library.Data [Table("artist")] public partial class Artist : BeginAndEndNamedEntityBase { - [Column("amgId")] [MaxLength(100)] public string AmgId { get; set; } + [Column("amgId")] + [MaxLength(100)] + public string AmgId { get; set; } [Column("artistType", TypeName = "enum")] public string ArtistType { get; set; } - [InverseProperty("Artist")] public ICollection AssociatedArtists { get; set; } + /// + /// Artists who this Artist is Associated To + /// + [InverseProperty("Artist")] + public virtual ICollection AssociatedArtists { get; set; } [Column("bandStatus", TypeName = "enum")] public BandStatus? BandStatus { get; set; } @@ -27,46 +32,77 @@ namespace Roadie.Library.Data [Column("birthDate", TypeName = "date")] public DateTime? BirthDate { get; set; } - public ICollection Comments { get; set; } + [InverseProperty("Artist")] + public virtual ICollection Comments { get; set; } - [Column("discogsId")] [MaxLength(50)] public string DiscogsId { get; set; } + [InverseProperty("Artist")] + public virtual ICollection Credits { get; set; } - public ICollection Genres { get; set; } + [Column("discogsId")] + [MaxLength(50)] + public string DiscogsId { get; set; } + + [InverseProperty("Artist")] + public virtual ICollection Genres { get; set; } + + /// + /// Where the Artist is the Artist on the Track not on an Artist Release + /// + [InverseProperty("TrackArtist")] + public virtual ICollection Tracks { get; set; } [Column("isniList", TypeName = "text")] [MaxLength(65535)] public string ISNI { get; set; } - [Column("iTunesId")] [MaxLength(100)] public string ITunesId { get; set; } + [Column("iTunesId")] + [MaxLength(100)] + public string ITunesId { get; set; } - [Column("lastPlayed")] public DateTime? LastPlayed { get; set; } + [Column("lastPlayed")] + public DateTime? LastPlayed { get; set; } [Column("musicBrainzId")] [MaxLength(100)] public string MusicBrainzId { get; set; } - [Column("playedCount")] public int? PlayedCount { get; set; } + [Column("playedCount")] + public int? PlayedCount { get; set; } [Column("profile", TypeName = "text")] [MaxLength(65535)] public string Profile { get; set; } - [Column("rank")] public decimal? Rank { get; set; } + [Column("rank")] + public decimal? Rank { get; set; } - [Column("rating")] public short? Rating { get; set; } + [Column("rating")] + public short? Rating { get; set; } - [Column("realName")] [MaxLength(500)] public string RealName { get; set; } + [Column("realName")] + [MaxLength(500)] + public string RealName { get; set; } - [Column("releaseCount")] public int? ReleaseCount { get; set; } + [Column("releaseCount")] + public int? ReleaseCount { get; set; } - //public List Releases { get; set; } - public ICollection Releases { get; set; } + public virtual ICollection Releases { get; set; } - [InverseProperty("Artist")] public ICollection SimilarArtists { get; set; } + /// + /// Artists who are similiar to this Artist + /// + [InverseProperty("Artist")] + public virtual ICollection SimilarArtists { get; set; } - [Column("spotifyId")] [MaxLength(100)] public string SpotifyId { get; set; } + [Column("spotifyId")] + [MaxLength(100)] + public string SpotifyId { get; set; } - [Column("trackCount")] public int? TrackCount { get; set; } + [Column("trackCount")] + public int? TrackCount { get; set; } + + [InverseProperty("Artist")] + public virtual ICollection UserArtists { get; set; } public Artist() { @@ -75,6 +111,8 @@ namespace Roadie.Library.Data AssociatedArtists = new HashSet(); SimilarArtists = new HashSet(); Comments = new HashSet(); + UserArtists = new HashSet(); + Rating = 0; Status = Statuses.Ok; } diff --git a/Roadie.Api.Library/Data/ArtistAssociation.cs b/Roadie.Api.Library/Data/ArtistAssociation.cs index 9348d7d..41928d6 100644 --- a/Roadie.Api.Library/Data/ArtistAssociation.cs +++ b/Roadie.Api.Library/Data/ArtistAssociation.cs @@ -6,15 +6,20 @@ namespace Roadie.Library.Data [Table("artistAssociation")] public class ArtistAssociation { - //[ForeignKey("artistId")] - public Artist Artist { get; set; } + [ForeignKey(nameof(ArtistId))] + [InverseProperty("AssociatedArtists")] + public virtual Artist Artist { get; set; } - [Column("artistId")] [Required] public int ArtistId { get; set; } + [Column("artistId")] + [Required] + public int ArtistId { get; set; } - //[ForeignKey("associatedArtistId")] - public Artist AssociatedArtist { get; set; } + [ForeignKey(nameof(AssociatedArtistId))] + public virtual Artist AssociatedArtist { get; set; } - [Column("associatedArtistId")] public int AssociatedArtistId { get; set; } + [Column("associatedArtistId")] + [Required] + public int AssociatedArtistId { get; set; } [Key] [Column("id")] diff --git a/Roadie.Api.Library/Data/ArtistGenre.cs b/Roadie.Api.Library/Data/ArtistGenre.cs index a7931cb..e38d28f 100644 --- a/Roadie.Api.Library/Data/ArtistGenre.cs +++ b/Roadie.Api.Library/Data/ArtistGenre.cs @@ -6,17 +6,25 @@ namespace Roadie.Library.Data [Table("artistGenreTable")] public class ArtistGenre { - public Artist Artist { get; set; } - - [Column("artistId")] [Required] public int ArtistId { get; set; } - - public Genre Genre { get; set; } - - [Column("genreId")] [Required] public int? GenreId { get; set; } - - [Column("id")] [Key] + [Column("id")] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } + + [Column("artistId")] + [Required] + public int ArtistId { get; set; } + + [Column("genreId")] + [Required] + public int GenreId { get; set; } + + [ForeignKey(nameof(ArtistId))] + [InverseProperty("Genres")] + public virtual Artist Artist { get; set; } + + [ForeignKey(nameof(GenreId))] + [InverseProperty("Artists")] + public virtual Genre Genre { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/ArtistPartial.cs b/Roadie.Api.Library/Data/ArtistPartial.cs index 9851bfe..9d0cfc7 100644 --- a/Roadie.Api.Library/Data/ArtistPartial.cs +++ b/Roadie.Api.Library/Data/ArtistPartial.cs @@ -3,8 +3,6 @@ using Roadie.Library.Utility; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Security.Cryptography; namespace Roadie.Library.Data { @@ -29,8 +27,6 @@ namespace Roadie.Library.Data public bool IsValid => !string.IsNullOrEmpty(Name); - public string SortNameValue => string.IsNullOrEmpty(SortName) ? Name : SortName; - public string GroupBy => SortNameValue.Substring(0, 1).ToUpper(); public static string CacheRegionUrn(Guid Id) @@ -55,7 +51,7 @@ namespace Roadie.Library.Data public override string ToString() { - return $"Id [{ Id }], Status [{ Status }], Name [{ Name }], SortName [{ SortNameValue}], RoadieId [{ RoadieId}]"; + return $"Id [{ Id }], Status [{ Status }], Name [{ Name }], SortName [{ SortName }], RoadieId [{ RoadieId}]"; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/ArtistSimiliar.cs b/Roadie.Api.Library/Data/ArtistSimiliar.cs index b1525b9..9d88597 100644 --- a/Roadie.Api.Library/Data/ArtistSimiliar.cs +++ b/Roadie.Api.Library/Data/ArtistSimiliar.cs @@ -6,19 +6,23 @@ namespace Roadie.Library.Data [Table("artistSimilar")] public class ArtistSimilar { - //[ForeignKey("artistId")] - public Artist Artist { get; set; } + [ForeignKey(nameof(ArtistId))] + [InverseProperty("SimilarArtists")] + public virtual Artist Artist { get; set; } - [Column("artistId")] [Required] public int ArtistId { get; set; } + [Column("artistId")] + [Required] + public int ArtistId { get; set; } [Key] [Column("id")] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } - //[ForeignKey("associatedArtistId")] - public Artist SimilarArtist { get; set; } + [ForeignKey(nameof(SimilarArtistId))] + public virtual Artist SimilarArtist { get; set; } - [Column("similarArtistId")] public int SimilarArtistId { get; set; } + [Column("similarArtistId")] + public int SimilarArtistId { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/BeginAndEndEntityBase.cs b/Roadie.Api.Library/Data/BeginAndEndEntityBase.cs index 060bf8c..3abddbf 100644 --- a/Roadie.Api.Library/Data/BeginAndEndEntityBase.cs +++ b/Roadie.Api.Library/Data/BeginAndEndEntityBase.cs @@ -8,6 +8,7 @@ namespace Roadie.Library.Data [Column("beginDate", TypeName = "date")] public DateTime? BeginDate { get; set; } - [Column("endDate", TypeName = "date")] public DateTime? EndDate { get; set; } + [Column("endDate", TypeName = "date")] + public DateTime? EndDate { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/BeginAndEndNamedEntityBase.cs b/Roadie.Api.Library/Data/BeginAndEndNamedEntityBase.cs index ddfc25c..e157eaa 100644 --- a/Roadie.Api.Library/Data/BeginAndEndNamedEntityBase.cs +++ b/Roadie.Api.Library/Data/BeginAndEndNamedEntityBase.cs @@ -5,8 +5,10 @@ namespace Roadie.Library.Data { public abstract class BeginAndEndNamedEntityBase : NamedEntityBase { - [Column("beginDate")] public DateTime? BeginDate { get; set; } + [Column("beginDate")] + public DateTime? BeginDate { get; set; } - [Column("endDate")] public DateTime? EndDate { get; set; } + [Column("endDate")] + public DateTime? EndDate { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/Bookmark.cs b/Roadie.Api.Library/Data/Bookmark.cs index 694c72a..bcc12a5 100644 --- a/Roadie.Api.Library/Data/Bookmark.cs +++ b/Roadie.Api.Library/Data/Bookmark.cs @@ -8,16 +8,27 @@ namespace Roadie.Library.Data [Table("bookmark")] public partial class Bookmark : EntityBase { - [Column("bookmarkTargetId")] public int BookmarkTargetId { get; set; } + [Column("bookmarkTargetId")] + public int BookmarkTargetId { get; set; } // public short? Type { get; set; } - [Column("bookmarkType")] public BookmarkType? BookmarkType { get; set; } + [Column("bookmarkType")] + public BookmarkType? BookmarkType { get; set; } - [Column("Comment")] [MaxLength(4000)] public string Comment { get; set; } - [Column("position")] public int? Position { get; set; } - public ApplicationUser User { get; set; } + [Column("Comment")] + [MaxLength(4000)] + public string Comment { get; set; } - [Column("userId")] [Required] public int UserId { get; set; } + [Column("position")] + public int? Position { get; set; } + + [ForeignKey(nameof(UserId))] + [InverseProperty("Bookmarks")] + public virtual User User { get; set; } + + [Column("userId")] + [Required] + public int UserId { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/ChatMessage.cs b/Roadie.Api.Library/Data/ChatMessage.cs index 369ad09..c9bd8d0 100644 --- a/Roadie.Api.Library/Data/ChatMessage.cs +++ b/Roadie.Api.Library/Data/ChatMessage.cs @@ -12,8 +12,12 @@ namespace Roadie.Library.Data [MaxLength(5000)] public string Message { get; set; } - public ApplicationUser User { get; set; } + [ForeignKey(nameof(UserId))] + [InverseProperty("ChatMessages")] + public virtual User User { get; set; } - [Column("userId")] [Required] public int UserId { get; set; } + [Column("userId")] + [Required] + public int UserId { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/Collection.cs b/Roadie.Api.Library/Data/Collection.cs index a26c354..7552a2a 100644 --- a/Roadie.Api.Library/Data/Collection.cs +++ b/Roadie.Api.Library/Data/Collection.cs @@ -1,4 +1,5 @@ using Roadie.Library.Enums; +using Roadie.Library.Identity; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -11,17 +12,18 @@ namespace Roadie.Library.Data [Column("collectionCount")] public int CollectionCount { get; set; } - [Column("collectionType")] + [Column("collectionType")] public CollectionType? CollectionType { get; set; } - public ICollection Comments { get; set; } + [InverseProperty("Collection")] + public virtual ICollection Comments { get; set; } [Column("description")] [MaxLength(4000)] public string Description { get; set; } - [Column("edition")] - [MaxLength(200)] + [Column("edition")] + [MaxLength(200)] public string Edition { get; set; } [Column("listInCSV", TypeName = "text")] @@ -32,9 +34,17 @@ namespace Roadie.Library.Data [MaxLength(200)] public string ListInCSVFormat { get; set; } - [Column("maintainerId")] + [Column("maintainerId")] public int MaintainerId { get; set; } - public ICollection Releases { get; set; } + [ForeignKey(nameof(MaintainerId))] + [InverseProperty(nameof(User.Collections))] + public virtual User Maintainer { get; set; } + + [InverseProperty("Collection")] + public virtual ICollection Releases { get; set; } + + [InverseProperty("Collection")] + public virtual ICollection MissingReleases { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/CollectionMissing.cs b/Roadie.Api.Library/Data/CollectionMissing.cs index ac25df2..eef99b6 100644 --- a/Roadie.Api.Library/Data/CollectionMissing.cs +++ b/Roadie.Api.Library/Data/CollectionMissing.cs @@ -6,18 +6,30 @@ namespace Roadie.Library.Data [Table("collectionMissing")] public class CollectionMissing { - [Column("artist")] [MaxLength(1000)] public string Artist { get; set; } + [Column("artist")] + [MaxLength(1000)] + public string Artist { get; set; } - [Column("collectionId")] public int CollectionId { get; set; } + [Column("collectionId")] + public int CollectionId { get; set; } + + [ForeignKey(nameof(CollectionId))] + [InverseProperty("MissingReleases")] + public virtual Collection Collection { get; set; } [Column("id")] [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } - [Column("isArtistFound")] public bool IsArtistFound { get; set; } + [Column("isArtistFound")] + public bool IsArtistFound { get; set; } - [Column("position")] public int Position { get; set; } - [Column("release")] [MaxLength(1000)] public string Release { get; set; } + [Column("position")] + public int Position { get; set; } + + [Column("release")] + [MaxLength(1000)] + public string Release { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/CollectionPartial.cs b/Roadie.Api.Library/Data/CollectionPartial.cs index 9279208..c9b8aa6 100644 --- a/Roadie.Api.Library/Data/CollectionPartial.cs +++ b/Roadie.Api.Library/Data/CollectionPartial.cs @@ -98,7 +98,9 @@ namespace Roadie.Library.Data public Collection() { Releases = new HashSet(); + MissingReleases = new HashSet(); Comments = new HashSet(); + ListInCSVFormat = "Position,Release,Artist"; CollectionType = Enums.CollectionType.Rank; } @@ -128,19 +130,21 @@ namespace Roadie.Library.Data }; configuration.BadDataFound = context => { - Trace.WriteLine($"PositionArtistReleases: Bad data found on row '{context.RawRow}'"); + Trace.WriteLine($"PositionArtistReleases: Bad data found on row '{context.RawRow}'", "Warning"); }; - var csv = new CsvReader(sr, configuration); - while (csv.Read()) + using (var csv = new CsvReader(sr, configuration)) { - index++; - rows.Add(new PositionArtistRelease + while (csv.Read()) { - Index = index, - Position = csv.GetField(PositionColumn), - Artist = SafeParser.ToString(csv.GetField(ArtistColumn)), - Release = SafeParser.ToString(csv.GetField(ReleaseColumn)) - }); + index++; + rows.Add(new PositionArtistRelease + { + Index = index, + Position = csv.GetField(PositionColumn), + Artist = SafeParser.ToString(csv.GetField(ArtistColumn)), + Release = SafeParser.ToString(csv.GetField(ReleaseColumn)) + }); + } } } @@ -156,30 +160,5 @@ namespace Roadie.Library.Data } } - [Serializable] - public class PositionArtistRelease - { - public string Artist { get; set; } - /// - /// This is the index (position in the list regardless of the position number) - /// - [JsonIgnore] - public int Index { get; set; } - - /// - /// This is the position number for the list (can be a year "1984" can be a number "14") - /// - public int Position { get; set; } - - public string Release { get; set; } - [JsonIgnore] public Statuses Status { get; set; } - - [JsonProperty("Status")] public string StatusVerbose => Status.ToString(); - - public override string ToString() - { - return string.Format("Position [{0}], Artist [{1}], Release [{2}]", Position, Artist, Release); - } - } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/CollectionRelease.cs b/Roadie.Api.Library/Data/CollectionRelease.cs index 592f13e..394dfe9 100644 --- a/Roadie.Api.Library/Data/CollectionRelease.cs +++ b/Roadie.Api.Library/Data/CollectionRelease.cs @@ -6,14 +6,23 @@ namespace Roadie.Library.Data [Table("collectionrelease")] public class CollectionRelease : EntityBase { - public Collection Collection { get; set; } + [ForeignKey(nameof(CollectionId))] + [InverseProperty("Releases")] + public virtual Collection Collection { get; set; } - [Column("collectionId")] [Required] public int CollectionId { get; set; } + [Column("collectionId")] + [Required] + public int CollectionId { get; set; } - [Column("listNumber")] public int ListNumber { get; set; } + [Column("listNumber")] + public int ListNumber { get; set; } - public Release Release { get; set; } + [ForeignKey(nameof(ReleaseId))] + [InverseProperty("Collections")] + public virtual Release Release { get; set; } - [Column("releaseId")] [Required] public int ReleaseId { get; set; } + [Column("releaseId")] + [Required] + public int ReleaseId { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/Comment.cs b/Roadie.Api.Library/Data/Comment.cs index e35f1e5..8379081 100644 --- a/Roadie.Api.Library/Data/Comment.cs +++ b/Roadie.Api.Library/Data/Comment.cs @@ -9,34 +9,76 @@ namespace Roadie.Library.Data [Table("comment")] public partial class Comment : EntityBase { - [Column("artistId")] public int? ArtistId { get; set; } + [Column("artistId")] + public int? ArtistId { get; set; } + + [ForeignKey(nameof(ArtistId))] + [InverseProperty("Comments")] + public virtual Artist Artist { get; set; } [Column("comment")] [MaxLength(25500)] [Required] public string Cmt { get; set; } - [Column("collectionId")] public int? CollectionId { get; set; } + [Column("collectionId")] + public int? CollectionId { get; set; } - [Column("genreId")] public int? GenreId { get; set; } + [ForeignKey(nameof(CollectionId))] + [InverseProperty("Comments")] + public virtual Collection Collection { get; set; } - [NotMapped] public new bool? IsLocked { get; set; } + [Column("genreId")] + public int? GenreId { get; set; } - [Column("labelId")] public int? LabelId { get; set; } + [ForeignKey(nameof(GenreId))] + [InverseProperty("Comments")] + public virtual Genre Genre { get; set; } - [Column("playlistId")] public int? PlaylistId { get; set; } + [NotMapped] + public new bool? IsLocked { get; set; } - public ICollection Reactions { get; set; } + [Column("labelId")] + public int? LabelId { get; set; } - [Column("releaseId")] public int? ReleaseId { get; set; } + [ForeignKey(nameof(LabelId))] + [InverseProperty("Comments")] + public virtual Label Label { get; set; } - [Column("replyToCommentId")] public int? ReplyToCommentId { get; set; } + [Column("playlistId")] + public int? PlaylistId { get; set; } - [Column("trackId")] public int? TrackId { get; set; } + [ForeignKey(nameof(PlaylistId))] + [InverseProperty("Comments")] + public virtual Playlist Playlist { get; set; } - public ApplicationUser User { get; set; } + [InverseProperty("Comment")] + public virtual ICollection Reactions { get; set; } - [Column("userId")] [Required] public int UserId { get; set; } + [Column("releaseId")] + public int? ReleaseId { get; set; } + + [ForeignKey(nameof(ReleaseId))] + [InverseProperty("Comments")] + public virtual Release Release { get; set; } + + [Column("replyToCommentId")] + public int? ReplyToCommentId { get; set; } + + [Column("trackId")] + public int? TrackId { get; set; } + + [ForeignKey(nameof(TrackId))] + [InverseProperty("Comments")] + public virtual Track Track { get; set; } + + [ForeignKey(nameof(UserId))] + [InverseProperty("Comments")] + public virtual User User { get; set; } + + [Column("userId")] + [Required] + public int UserId { get; set; } public Comment() { diff --git a/Roadie.Api.Library/Data/CommentReaction.cs b/Roadie.Api.Library/Data/CommentReaction.cs index db2c983..1ded411 100644 --- a/Roadie.Api.Library/Data/CommentReaction.cs +++ b/Roadie.Api.Library/Data/CommentReaction.cs @@ -10,14 +10,25 @@ namespace Roadie.Library.Data { public Comment Comment { get; set; } - [Column("commentId")] [Required] public int CommentId { get; set; } - [NotMapped] public new bool? IsLocked { get; set; } - [Column("reaction")] public string Reaction { get; set; } + [Column("commentId")] + [Required] + public int CommentId { get; set; } + + [NotMapped] + public new bool? IsLocked { get; set; } + + [Column("reaction")] + public string Reaction { get; set; } [NotMapped] public Enums.CommentReaction ReactionValue => SafeParser.ToEnum(Reaction ?? "Unknown"); - public ApplicationUser User { get; set; } - [Column("userId")] [Required] public int UserId { get; set; } + [ForeignKey(nameof(UserId))] + [InverseProperty("CommentReactions")] + public virtual User User { get; set; } + + [Column("userId")] + [Required] + public int UserId { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Data/Context/DbContextFactory.cs b/Roadie.Api.Library/Data/Context/DbContextFactory.cs index 4b809c7..20cffad 100644 --- a/Roadie.Api.Library/Data/Context/DbContextFactory.cs +++ b/Roadie.Api.Library/Data/Context/DbContextFactory.cs @@ -1,9 +1,9 @@ using FileContextCore; using Microsoft.EntityFrameworkCore; -using Pomelo.EntityFrameworkCore.MySql.Infrastructure; using Roadie.Library.Configuration; using Roadie.Library.Data.Context.Implementation; using System; +using System.IO; namespace Roadie.Library.Data.Context { @@ -13,6 +13,12 @@ namespace Roadie.Library.Data.Context { switch (configuration.DbContextToUse) { + case DbContexts.SQLite: + var sqlLiteOptionsBuilder = new DbContextOptionsBuilder(); + var databaseName = Path.Combine(configuration.FileDatabaseOptions.DatabaseFolder, $"{ configuration.FileDatabaseOptions.DatabaseName }.db"); + sqlLiteOptionsBuilder.UseSqlite($"Filename={databaseName}"); + return new SQLiteRoadieDbContext(sqlLiteOptionsBuilder.Options); + case DbContexts.File: var fileOptionsBuilder = new DbContextOptionsBuilder(); fileOptionsBuilder.UseFileContextDatabase(configuration.FileDatabaseOptions.DatabaseFormat.ToString().ToLower(), @@ -20,17 +26,19 @@ namespace Roadie.Library.Data.Context location: configuration.FileDatabaseOptions.DatabaseFolder); return new FileRoadieDbContext(fileOptionsBuilder.Options); - default: + case DbContexts.MySQL: var mysqlOptionsBuilder = new DbContextOptionsBuilder(); mysqlOptionsBuilder.UseMySql(configuration.ConnectionString, mySqlOptions => { - mySqlOptions.ServerVersion(new Version(5, 5), ServerType.MariaDb); mySqlOptions.EnableRetryOnFailure( 10, TimeSpan.FromSeconds(30), null); }); return new MySQLRoadieDbContext(mysqlOptionsBuilder.Options); + + default: + throw new NotImplementedException("Unknown DbContext Type"); } } } diff --git a/Roadie.Api.Library/Data/Context/IRoadieDbContext.cs b/Roadie.Api.Library/Data/Context/IRoadieDbContext.cs index 9d34a36..e002e84 100644 --- a/Roadie.Api.Library/Data/Context/IRoadieDbContext.cs +++ b/Roadie.Api.Library/Data/Context/IRoadieDbContext.cs @@ -42,8 +42,8 @@ namespace Roadie.Library.Data.Context DbSet UserArtists { get; set; } DbSet UserQues { get; set; } DbSet UserReleases { get; set; } - DbSet UserRoles { get; set; } - DbSet Users { get; set; } + DbSet UserRoles { get; set; } + DbSet Users { get; set; } DbSet UserTracks { get; set; } DbSet InviteTokens { get; set; } diff --git a/Roadie.Api.Library/Data/Context/Implementation/LinqDbContextBase.cs b/Roadie.Api.Library/Data/Context/Implementation/LinqDbContextBase.cs index 7c76668..d00ed2c 100644 --- a/Roadie.Api.Library/Data/Context/Implementation/LinqDbContextBase.cs +++ b/Roadie.Api.Library/Data/Context/Implementation/LinqDbContextBase.cs @@ -169,11 +169,11 @@ namespace Roadie.Library.Data.Context.Implementation } else { - randomReleases = await(from r in Releases - join ur in UserReleases on r.Id equals ur.ReleaseId into urg - from ur in urg.DefaultIfEmpty() - where (ur == null || (ur.UserId == userId && ur.IsDisliked == false)) - select r) + randomReleases = await (from r in Releases + join ur in UserReleases on r.Id equals ur.ReleaseId into urg + from ur in urg.DefaultIfEmpty() + where (ur == null || (ur.UserId == userId && ur.IsDisliked == false)) + select r) .OrderBy(x => Guid.NewGuid()) .Take(randomLimit) .ToListAsync(); diff --git a/Roadie.Api.Library/Data/Context/Implementation/MysqlRoadieDbContext.cs b/Roadie.Api.Library/Data/Context/Implementation/MysqlRoadieDbContext.cs index 37c8405..4351adc 100644 --- a/Roadie.Api.Library/Data/Context/Implementation/MysqlRoadieDbContext.cs +++ b/Roadie.Api.Library/Data/Context/Implementation/MysqlRoadieDbContext.cs @@ -188,7 +188,7 @@ namespace Roadie.Library.Data.Context.Implementation WHERE ut.userId = {1} AND ut.isFavorite = 1) AND {2} = 1) OR {2} = 0) order BY RIGHT( HEX( (1<<24) * (1+RAND()) ), 6) LIMIT 0, {0}"; - var ids = await Releases.FromSqlRaw(sql, randomLimit, userId, doOnlyFavorites ? "1" : "0", doOnlyRated ? "1" : "0").Select(x => x.Id).ToListAsync(); + var ids = await Tracks.FromSqlRaw(sql, randomLimit, userId, doOnlyFavorites ? "1" : "0", doOnlyRated ? "1" : "0").Select(x => x.Id).ToListAsync(); var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value); return new SortedDictionary(dict); } diff --git a/Roadie.Api.Library/Data/Context/Implementation/SQLiteRoadieDbContext.cs b/Roadie.Api.Library/Data/Context/Implementation/SQLiteRoadieDbContext.cs new file mode 100644 index 0000000..cc33f04 --- /dev/null +++ b/Roadie.Api.Library/Data/Context/Implementation/SQLiteRoadieDbContext.cs @@ -0,0 +1,111 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Roadie.Library.Data.Context.Implementation +{ + /// + /// SQLite implementation of DbContext + /// + public sealed class SQLiteRoadieDbContext : LinqDbContextBase + { + private static bool _created = false; + + public SQLiteRoadieDbContext(DbContextOptions options) + : base(options) + { + if (!_created) + { + _created = true; + Database.EnsureCreated(); + } + } + + public override async Task> RandomArtistIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false) + { + // TODO Rating? + var sql = @"SELECT a.id + FROM artist a + WHERE(a.id NOT IN(select artistId FROM userartist where userId = {1} and isDisliked = 1)) + OR(a.id IN (select artistId FROM userartist where userId = {1} and isFavorite = 1) + AND {2} = 1) + order by random() + LIMIT 0, {0}"; + var ids = await Artists.FromSqlRaw(sql, randomLimit, userId, doOnlyFavorites ? "1" : "0").Select(x => x.Id).ToListAsync(); + var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value); + return new SortedDictionary(dict); + } + + public override async Task> RandomGenreIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false) + { + var sql = @"SELECT g.id + FROM genre g + order by random() + LIMIT 0, {0}"; + var ids = await Genres.FromSqlRaw(sql, randomLimit).Select(x => x.Id).ToListAsync(); + var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value); + return new SortedDictionary(dict); + } + + public override async Task> RandomLabelIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false) + { + var sql = @"SELECT l.id + FROM label l + order by random() + LIMIT 0, {0}"; + var ids = await Labels.FromSqlRaw(sql, randomLimit).Select(x => x.Id).ToListAsync(); + var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value); + return new SortedDictionary(dict); + } + + public override async Task> RandomReleaseIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false) + { + // TODO Rating? + var sql = @"SELECT r.id + FROM release r + WHERE (r.id NOT IN (select releaseId FROM userrelease where userId = {1} and isDisliked = 1)) + OR (r.id IN (select releaseId FROM userrelease where userId = {1} and isFavorite = 1) + AND {2} = 1) + order by random() + LIMIT 0, {0}"; + var ids = await Releases.FromSqlRaw(sql, randomLimit, userId, doOnlyFavorites ? "1" : "0").Select(x => x.Id).ToListAsync(); + var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value); + return new SortedDictionary(dict); + } + + public override async Task> RandomTrackIds(int userId, int randomLimit, bool doOnlyFavorites = false, bool doOnlyRated = false) + { + // When using the regular 'FromSqlRaw' with parameters SQLite returns no records. + + var df = doOnlyFavorites ? "1" : "0"; + var dr = doOnlyRated ? "1" : "0"; + var sql = @$"SELECT t.id + FROM track t + WHERE ((t.rating > 0 AND {dr} = 1) OR {dr} = 0) + AND ((t.id NOT IN (select tt.id + FROM track tt + JOIN releasemedia rm on (tt.releaseMediaId = rm.id) + JOIN userartist ua on (rm.id = ua.artistId) + WHERE ua.userId = {userId} AND ua.isDisliked = 1)) + AND (t.id NOT IN (select tt.id + FROM track tt + JOIN releasemedia rm on (tt.releaseMediaId = rm.id) + JOIN userrelease ur on (rm.releaseId = ur.releaseId) + WHERE ur.userId = {userId} AND ur.isDisliked = 1)) + AND (t.id NOT IN (select tt.id + FROM track tt + JOIN usertrack ut on (tt.id = ut.trackId) + WHERE ut.userId = {userId} AND ut.isDisliked = 1))) + AND ((t.id IN (select tt.id + FROM track tt + JOIN usertrack ut on (tt.id = ut.trackId) + WHERE ut.userId = {userId} AND ut.isFavorite = 1) AND {df} = 1) OR {df} = 0) + order by random() + LIMIT 0, {randomLimit}"; + var ids = await Tracks.FromSqlRaw(sql, randomLimit).Select(x => x.Id).ToListAsync(); + var dict = ids.Select((id, i) => new { key = i, value = id }).ToDictionary(x => x.key, x => x.value); + return new SortedDictionary(dict); + } + } +} \ No newline at end of file diff --git a/Roadie.Api.Library/Data/Context/RoadieDbContext.cs b/Roadie.Api.Library/Data/Context/RoadieDbContext.cs index 37cfdad..2fab447 100644 --- a/Roadie.Api.Library/Data/Context/RoadieDbContext.cs +++ b/Roadie.Api.Library/Data/Context/RoadieDbContext.cs @@ -65,9 +65,9 @@ namespace Roadie.Library.Data.Context public DbSet UserReleases { get; set; } - public DbSet UserRoles { get; set; } + public DbSet UserRoles { get; set; } - public DbSet Users { get; set; } + public DbSet Users { get; set; } public DbSet UserTracks { get; set; } public DbSet InviteTokens { get; set; } @@ -79,142 +79,737 @@ namespace Roadie.Library.Data.Context protected override void OnModelCreating(ModelBuilder builder) { - base.OnModelCreating(builder); + // base.OnModelCreating(builder); - //builder - // .Entity() - // .Property(e => e.Status) - // .HasConversion( - // v => v.ToString(), - // v => string.IsNullOrEmpty(v) ? Statuses.Ok : (Statuses)Enum.Parse(typeof(Statuses), v)) - // .HasDefaultValue(Statuses.Ok); + builder.Entity(entity => + { + entity + .Property(e => e.BandStatus) + .HasConversion( + v => v.ToString(), + v => string.IsNullOrEmpty(v) ? BandStatus.Unknown : (BandStatus)Enum.Parse(typeof(BandStatus), v)) + .HasDefaultValue(BandStatus.Unknown); - //builder - // .Entity() - // .Property(e => e.Status) - // .HasConversion( - // v => v.ToString(), - // v => string.IsNullOrEmpty(v) ? Statuses.Incomplete : (Statuses)Enum.Parse(typeof(Statuses), v)) - // .HasDefaultValue(Statuses.Incomplete); + entity.HasIndex(e => e.Name) + .HasName("ix_artist_name") + .IsUnique(); - builder - .Entity() - .Property(e => e.ReleaseType) - .HasConversion( - v => v.ToString(), - v => string.IsNullOrEmpty(v) - ? ReleaseType.Unknown - : (ReleaseType)Enum.Parse(typeof(ReleaseType), v)) - .HasDefaultValue(ReleaseType.Release); + entity.HasIndex(e => e.RoadieId) + .HasName("ix_artist_roadieId"); - builder - .Entity() - .Property(e => e.LibraryStatus) - .HasConversion( - v => v.ToString(), - v => string.IsNullOrEmpty(v) - ? LibraryStatus.Incomplete - : (LibraryStatus)Enum.Parse(typeof(LibraryStatus), v)) - .HasDefaultValue(LibraryStatus.Incomplete); + entity.HasIndex(e => e.SortName) + .HasName("ix_artist_sortname") + .IsUnique(); + }); - builder - .Entity() - .Property(e => e.CollectionType) - .HasConversion( - v => v.ToString(), - v => string.IsNullOrEmpty(v) - ? CollectionType.Unknown - : (CollectionType)Enum.Parse(typeof(CollectionType), v)) - .HasDefaultValue(CollectionType.Unknown); + builder.Entity(entity => + { + entity.HasIndex(e => e.AssociatedArtistId) + .HasName("ix_associatedArtistId"); - builder - .Entity() - .Property(e => e.BandStatus) - .HasConversion( - v => v.ToString(), - v => string.IsNullOrEmpty(v) ? BandStatus.Unknown : (BandStatus)Enum.Parse(typeof(BandStatus), v)) - .HasDefaultValue(BandStatus.Unknown); + entity.HasIndex(e => new { e.ArtistId, e.AssociatedArtistId }) + .HasName("ix__artistAssociation"); - //builder - // .Entity() - // .Property(e => e.BookmarkType) - // .HasConversion( - // v => v.ToString(), - // v => string.IsNullOrEmpty(v) ? BookmarkType.Unknown : (BookmarkType)Enum.Parse(typeof(BookmarkType), v)) - // .HasDefaultValue(BookmarkType.Unknown); + entity.HasOne(d => d.Artist) + .WithMany(p => p.AssociatedArtists) + .HasForeignKey(d => d.ArtistId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("artistAssociation_ibfk_1"); + }); - builder.Entity() - .HasOne(d => d.Artist) - .WithMany(p => p.Releases) - .HasForeignKey(d => d.ArtistId) - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("release_ibfk_1"); + builder.Entity(entity => + { + entity.HasIndex(e => e.ArtistId) + .HasName("ix_artistGenreTable_artistId"); - builder.Entity() - .HasOne(rl => rl.Release) - .WithMany(r => r.Labels) - .HasForeignKey(rl => rl.ReleaseId); + entity.HasIndex(e => e.GenreId) + .HasName("ix_artistGenre_genreId"); - builder.Entity() - .HasOne(rl => rl.Label) - .WithMany(l => l.ReleaseLabels) - .HasForeignKey(rl => rl.LabelId); + entity.HasIndex(e => new { e.ArtistId, e.GenreId }) + .HasName("ix__artistGenreAssociation"); - builder.Entity() - .HasMany(rm => rm.Tracks) - .WithOne(t => t.ReleaseMedia) - .HasForeignKey(rm => rm.ReleaseMediaId); + entity.HasOne(d => d.Artist) + .WithMany(p => p.Genres) + .HasForeignKey(d => d.ArtistId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("artistGenreTable_ibfk_1"); - builder.Entity() - .HasOne(rm => rm.Release) - .WithMany(r => r.Medias) - .HasForeignKey(r => r.ReleaseId); + entity.HasOne(d => d.Genre) + .WithMany(p => p.Artists) + .HasForeignKey(d => d.GenreId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("artistGenreTable_ibfk_2"); + }); - builder.Entity() - .HasKey(rg => new { rg.ReleaseId, rg.GenreId }); + builder.Entity(entity => + { + entity.HasIndex(e => e.SimilarArtistId) + .HasName("ix_similarArtistId"); - builder.Entity() - .HasOne(rg => rg.Release) - .WithMany(r => r.Genres) - .HasForeignKey(rg => rg.ReleaseId); + entity.HasIndex(e => new { e.ArtistId, e.SimilarArtistId }) + .HasName("ix_artistSimilar"); - builder.Entity() - .HasOne(rg => rg.Genre) - .WithMany(g => g.Releases) - .HasForeignKey(rg => rg.GenreId); + entity.HasOne(d => d.Artist) + .WithMany(p => p.SimilarArtists) + .HasForeignKey(d => d.ArtistId) + .HasConstraintName("artistSimilar_ibfk_1"); + }); - builder.Entity() - .HasKey(rg => new { rg.ArtistId, rg.GenreId }); + builder.Entity(entity => + { + entity.HasIndex(e => e.RoadieId) + .HasName("ix_bookmark_roadieId"); - builder.Entity() - .HasOne(rg => rg.Artist) - .WithMany(r => r.Genres) - .HasForeignKey(rg => rg.ArtistId); + entity.HasIndex(e => e.UserId) + .HasName("ix_bookmark_userId"); - builder.Entity() - .HasOne(rg => rg.Genre) - .WithMany(g => g.Artists) - .HasForeignKey(rg => rg.GenreId); + entity.HasIndex(e => new { e.BookmarkType, e.BookmarkTargetId, e.UserId }) + .HasName("ix_bookmark_bookmarkType") + .IsUnique(); - builder.Entity() - .HasOne(cr => cr.Release) - .WithMany(r => r.Collections) - .HasForeignKey(cr => cr.ReleaseId); + entity.HasOne(d => d.User) + .WithMany(p => p.Bookmarks) + .HasForeignKey(d => d.UserId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("bookmark_ibfk_1"); + }); - builder.Entity() - .HasOne(cr => cr.Collection) - .WithMany(c => c.Releases) - .HasForeignKey(cr => cr.CollectionId); + builder.Entity(entity => + { + entity.HasIndex(e => e.UserId) + .HasName("ix__chatMessage_user"); - builder.Entity() - .HasOne(b => b.User) - .WithMany(u => u.Bookmarks) - .HasForeignKey(b => b.UserId); + entity.HasOne(d => d.User) + .WithMany(p => p.ChatMessages) + .HasForeignKey(d => d.UserId) + .HasConstraintName("chatMessage_ibfk_1"); + }); - //builder.Entity() - // .HasOne(t => t.TrackArtist) - // .WithMany(a => a.Tracks) - // .HasForeignKey(t => t.ArtistId); + builder.Entity(entity => + { + entity + .Property(e => e.CollectionType) + .HasConversion( + v => v.ToString(), + v => string.IsNullOrEmpty(v) + ? CollectionType.Unknown + : (CollectionType)Enum.Parse(typeof(CollectionType), v)) + .HasDefaultValue(CollectionType.Unknown); + + entity.HasIndex(e => e.MaintainerId) + .HasName("ix_collection_maintainerId"); + + entity.HasIndex(e => e.Name) + .HasName("ix_collection_name") + .IsUnique(); + + entity.HasIndex(e => e.RoadieId) + .HasName("ix_collection_roadieId"); + + entity.HasOne(d => d.Maintainer) + .WithMany(p => p.Collections) + .HasForeignKey(d => d.MaintainerId) + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("collection_ibfk_1"); + }); + + builder.Entity(entity => + { + entity.HasIndex(e => e.CollectionId) + .HasName("ix_collection_collectionId"); + + entity.HasOne(d => d.Collection) + .WithMany(p => p.MissingReleases) + .HasForeignKey(d => d.CollectionId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("collection_missing_ibfk_1"); + }); + + builder.Entity(entity => + { + entity.HasIndex(e => e.ReleaseId) + .HasName("ix_collectionrelease_releaseId"); + + entity.HasIndex(e => e.RoadieId) + .HasName("ix_collectionrelease_roadieId"); + + entity.HasIndex(e => new { e.CollectionId, e.ReleaseId }) + .HasName("ix__collection_release"); + + entity.HasOne(d => d.Collection) + .WithMany(p => p.Releases) + .HasForeignKey(d => d.CollectionId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("collectionrelease_ibfk_2"); + + entity.HasOne(d => d.Release) + .WithMany(p => p.Collections) + .HasForeignKey(d => d.ReleaseId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("collectionrelease_ibfk_1"); + }); + + builder.Entity(entity => + { + entity.HasIndex(e => e.ArtistId) + .HasName("ix_commentartist_ibfk_1"); + + entity.HasIndex(e => e.CollectionId) + .HasName("ix_commentcollection_ibfk_1"); + + entity.HasIndex(e => e.GenreId) + .HasName("ix_commentgenre_ibfk_1"); + + entity.HasIndex(e => e.LabelId) + .HasName("ix_commentlabel_ibfk_1"); + + entity.HasIndex(e => e.PlaylistId) + .HasName("ix_commentplaylist_ibfk_1"); + + entity.HasIndex(e => e.ReleaseId) + .HasName("ix_commentrelease_ibfk_1"); + + entity.HasIndex(e => e.RoadieId) + .HasName("ix_comment_roadieId"); + + entity.HasIndex(e => e.TrackId) + .HasName("ix_commenttrack_ibfk_1"); + + entity.HasIndex(e => e.UserId) + .HasName("ix_commentuser_ibfk_1"); + + entity.HasOne(d => d.Artist) + .WithMany(p => p.Comments) + .HasForeignKey(d => d.ArtistId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("commentartist_ibfk_1"); + + entity.HasOne(d => d.Collection) + .WithMany(p => p.Comments) + .HasForeignKey(d => d.CollectionId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("commentcollection_ibfk_1"); + + entity.HasOne(d => d.Genre) + .WithMany(p => p.Comments) + .HasForeignKey(d => d.GenreId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("commentgenre_ibfk_1"); + + entity.HasOne(d => d.Label) + .WithMany(p => p.Comments) + .HasForeignKey(d => d.LabelId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("commentlabel_ibfk_1"); + + entity.HasOne(d => d.Playlist) + .WithMany(p => p.Comments) + .HasForeignKey(d => d.PlaylistId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("commentplaylist_ibfk_1"); + + entity.HasOne(d => d.Release) + .WithMany(p => p.Comments) + .HasForeignKey(d => d.ReleaseId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("commentrelease_ibfk_1"); + + entity.HasOne(d => d.Track) + .WithMany(p => p.Comments) + .HasForeignKey(d => d.TrackId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("commenttrack_ibfk_1"); + + entity.HasOne(d => d.User) + .WithMany(p => p.Comments) + .HasForeignKey(d => d.UserId) + .HasConstraintName("commentuser_ibfk_1"); + }); + + builder.Entity(entity => + { + entity.HasIndex(e => e.CommentId) + .HasName("ix_commentReactioncomment_ibfk_1"); + + entity.HasIndex(e => e.RoadieId) + .HasName("ix_commentReaction_roadieId"); + + entity.HasIndex(e => e.UserId) + .HasName("ix_commentReactionuser_ibfk_1"); + + entity.HasIndex(e => new { e.UserId, e.CommentId }) + .HasName("ix_commentReaction_userId") + .IsUnique(); + + entity.HasOne(d => d.Comment) + .WithMany(p => p.Reactions) + .HasForeignKey(d => d.CommentId) + .HasConstraintName("commentReactioncomment_ibfk_1"); + + entity.HasOne(d => d.User) + .WithMany(p => p.CommentReactions) + .HasForeignKey(d => d.UserId) + .HasConstraintName("commentReactionuser_ibfk_1"); + }); + + builder.Entity(entity => + { + entity.HasIndex(e => e.ArtistId) + .HasName("ix_credit_artist_ibfk_1"); + + entity.HasIndex(e => e.CreditCategoryId) + .HasName("ix_credit_category_ibfk_1"); + + entity.HasIndex(e => e.RoadieId) + .HasName("ix_credit_roadieId"); + + entity.HasIndex(e => new { e.ReleaseId, e.Id }) + .HasName("ix_creditCreditandRelease"); + + entity.HasIndex(e => new { e.TrackId, e.Id }) + .HasName("ix_creditCreditandTrack"); + + entity.HasOne(d => d.Artist) + .WithMany(p => p.Credits) + .HasForeignKey(d => d.ArtistId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("credit_artist_ibfk_1"); + + entity.HasOne(d => d.CreditCategory) + .WithMany(p => p.Credits) + .HasForeignKey(d => d.CreditCategoryId) + .HasConstraintName("credit_category_ibfk_1"); + + entity.HasOne(d => d.Release) + .WithMany(p => p.Credits) + .HasForeignKey(d => d.ReleaseId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("credit_release_ibfk_1"); + + entity.HasOne(d => d.Track) + .WithMany(p => p.Credits) + .HasForeignKey(d => d.TrackId) + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("credit_track_ibfk_1"); + }); + + builder.Entity(entity => + { + entity.HasIndex(e => e.RoadieId) + .HasName("ix_creditCategory_roadieId"); + }); + + builder.Entity(entity => + { + entity.HasIndex(e => e.Name) + .HasName("ix_genre_name") + .IsUnique(); + + entity.HasIndex(e => e.NormalizedName) + .HasName("ix_genre_normalizedName"); + + entity.HasIndex(e => e.RoadieId) + .HasName("ix_genre_roadieId"); + }); + + builder.Entity(entity => + { + entity.HasIndex(e => e.CreatedByUserId) + .HasName("inviteToken_fk_1"); + + entity.HasIndex(e => e.RoadieId) + .HasName("ix_inviteToken_roadieId"); + + entity.HasOne(d => d.CreatedByUser) + .WithMany(p => p.InviteTokens) + .HasForeignKey(d => d.CreatedByUserId) + .HasConstraintName("inviteToken_fk_1"); + }); + + builder.Entity public async Task> DeleteBookmark(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { if (!request.TrackId.HasValue) return new subsonic.SubsonicOperationResult( @@ -374,7 +371,7 @@ namespace Roadie.Api.Services /// /// Deletes a saved playlist. /// - public async Task> DeletePlaylist(subsonic.Request request, User roadieUser) + public async Task> DeletePlaylist(subsonic.Request request, Library.Models.Users.User roadieUser) { //request.PlaylistId.Value @@ -410,7 +407,7 @@ namespace Roadie.Api.Services /// Returns details for an album, including a list of songs. This method organizes music according to ID3 tags. /// public async Task> GetAlbum(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { try { @@ -474,7 +471,7 @@ namespace Roadie.Api.Services /// /// Returns album notes, image URLs etc, using data from last.fm. /// - public async Task> GetAlbumInfo(subsonic.Request request, User roadieUser, subsonic.AlbumInfoVersion version) + public async Task> GetAlbumInfo(subsonic.Request request, Library.Models.Users.User roadieUser, subsonic.AlbumInfoVersion version) { var releaseId = SafeParser.ToGuid(request.id); if (!releaseId.HasValue) @@ -521,7 +518,7 @@ namespace Roadie.Api.Services /// Subsonic web interface. /// public async Task> GetAlbumList(subsonic.Request request, - User roadieUser, subsonic.AlbumListVersions version) + Library.Models.Users.User roadieUser, subsonic.AlbumListVersions version) { var releaseResult = new PagedResult(); @@ -597,7 +594,7 @@ namespace Roadie.Api.Services /// Returns details for an artist, including a list of albums. This method organizes music according to ID3 tags. /// public async Task> GetArtist(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { var artistId = SafeParser.ToGuid(request.id); if (!artistId.HasValue) @@ -678,7 +675,7 @@ namespace Roadie.Api.Services /// Similar to getIndexes, but organizes music according to ID3 tags. /// public async Task> GetArtists(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { var cacheKey = $"urn:subsonic_artists:{roadieUser.UserName}"; return await CacheManager.GetAsync(cacheKey, @@ -690,7 +687,7 @@ namespace Roadie.Api.Services /// Returns all bookmarks for this user. A bookmark is a position within a certain media file. /// public async Task> GetBookmarks(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { var pagedRequest = request.PagedRequest; pagedRequest.Sort = "LastUpdated"; @@ -719,7 +716,7 @@ namespace Roadie.Api.Services /// Returns the current visible (non-expired) chat messages. /// public Task> GetChatMessages(subsonic.Request request, - User roadieUser, long? since) + Library.Models.Users.User roadieUser, long? since) { var messagesSince = since.HasValue ? (DateTime?)since.Value.FromUnixTime() : null; var chatMessages = (from cm in DbContext.ChatMessages @@ -859,7 +856,7 @@ namespace Roadie.Api.Services /// time (in milliseconds since 1 Jan 1970). /// public async Task> GetIndexes(subsonic.Request request, - User roadieUser, long? ifModifiedSince = null) + Library.Models.Users.User roadieUser, long? ifModifiedSince = null) { var cacheKey = "urn:subsonic_indexes"; return await CacheManager.GetAsync(cacheKey, async () => @@ -928,7 +925,7 @@ namespace Roadie.Api.Services /// getMusicDirectory. /// /// - public async Task> GetMusicDirectory(subsonic.Request request, User roadieUser) + public async Task> GetMusicDirectory(subsonic.Request request, Library.Models.Users.User roadieUser) { var directory = new subsonic.Directory(); var user = await GetUser(roadieUser?.UserId); @@ -1048,7 +1045,7 @@ namespace Roadie.Api.Services /// Returns what is currently being played by all users. Takes no extra parameters. /// public async Task> GetNowPlaying(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { var pagedRequest = request.PagedRequest; pagedRequest.Sort = "PlayedDateDateTime"; @@ -1097,7 +1094,7 @@ namespace Roadie.Api.Services /// Returns a listing of files in a saved playlist. /// public async Task> GetPlaylist(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { var playListId = SafeParser.ToGuid(request.id); if (!playListId.HasValue) @@ -1131,7 +1128,7 @@ namespace Roadie.Api.Services /// Returns all playlists a user is allowed to play. /// public async Task> GetPlaylists(subsonic.Request request, - User roadieUser, string filterToUserName) + Library.Models.Users.User roadieUser, string filterToUserName) { var pagedRequest = request.PagedRequest; pagedRequest.Sort = "Playlist.Text"; @@ -1160,7 +1157,7 @@ namespace Roadie.Api.Services /// between different clients/apps while retaining the same play queue (for instance when listening to an audio book). /// public async Task> GetPlayQueue(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { var user = await GetUser(roadieUser.UserId); @@ -1231,7 +1228,7 @@ namespace Roadie.Api.Services /// Returns random songs matching the given criteria. /// public async Task> GetRandomSongs(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { var songs = new List(); @@ -1258,7 +1255,7 @@ namespace Roadie.Api.Services /// used for artist radio features. /// public Task> GetSimliarSongs(subsonic.Request request, - User roadieUser, subsonic.SimilarSongsVersion version, int? count = 50) + Library.Models.Users.User roadieUser, subsonic.SimilarSongsVersion version, int? count = 50) { // TODO How to determine similar songs? Perhaps by genre? @@ -1307,7 +1304,7 @@ namespace Roadie.Api.Services /// Returns details for a song. /// public async Task> GetSong(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { if (!request.TrackId.HasValue) return new subsonic.SubsonicOperationResult( @@ -1337,7 +1334,7 @@ namespace Roadie.Api.Services /// Returns songs in a given genre. /// public async Task> GetSongsByGenre(subsonic.Request request, - User roadieUser) + Library.Models.Users.User roadieUser) { var pagedRequest = request.PagedRequest; pagedRequest.FilterByGenre = request.Genre; @@ -1364,7 +1361,7 @@ namespace Roadie.Api.Services /// Returns starred songs, albums and artists. /// public async Task> GetStarred(subsonic.Request request, - User roadieUser, subsonic.StarredVersion version) + Library.Models.Users.User roadieUser, subsonic.StarredVersion version) { var pagedRequest = request.PagedRequest; pagedRequest.FilterFavoriteOnly = true; @@ -1423,7 +1420,7 @@ namespace Roadie.Api.Services /// Returns top songs for the given artist, using data from last.fm. /// public async Task> GetTopSongs(subsonic.Request request, - User roadieUser, int? count = 50) + Library.Models.Users.User roadieUser, int? count = 50) { data.Artist artist = null; if (!string.IsNullOrEmpty(request.ArtistName)) @@ -1521,7 +1518,7 @@ namespace Roadie.Api.Services /// while retaining the same play queue (for instance when listening to an audio book). /// public async Task> SavePlayQueue(subsonic.Request request, - User roadieUser, string current, long? position) + Library.Models.Users.User roadieUser, string current, long? position) { // Remove any existing Que for User var user = await GetUser(roadieUser.UserId); @@ -1569,7 +1566,7 @@ namespace Roadie.Api.Services /// Returns albums, artists and songs matching the given search criteria. Supports paging through the result. /// public async Task> Search(subsonic.Request request, - User roadieUser, subsonic.SearchVersion version) + Library.Models.Users.User roadieUser, subsonic.SearchVersion version) { var query = HttpEncoder.UrlDecode(request.Query).Replace("*", "").Replace("%", "").Replace(";", ""); @@ -1652,7 +1649,7 @@ namespace Roadie.Api.Services /// Sets the rating for a music file. If rating is zero then remove rating. /// public async Task> SetRating(subsonic.Request request, - User roadieUser, short rating) + Library.Models.Users.User roadieUser, short rating) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -1700,7 +1697,7 @@ namespace Roadie.Api.Services /// Attaches a star to a song, album or artist. /// public async Task> ToggleStar(subsonic.Request request, - User roadieUser, bool star, string[] albumIds = null, string[] artistIds = null) + Library.Models.Users.User roadieUser, bool star, string[] albumIds = null, string[] artistIds = null) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -1783,7 +1780,7 @@ namespace Roadie.Api.Services /// Add this song with this ID to the playlist. Multiple parameters allowed /// Remove the song at this position in the playlist. Multiple parameters allowed. public async Task> UpdatePlaylist(subsonic.Request request, - User roadieUser, string playListId, string name = null, string comment = null, bool? isPublic = null, + Library.Models.Users.User roadieUser, string playListId, string name = null, string comment = null, bool? isPublic = null, string[] songIdsToAdd = null, int[] songIndexesToRemove = null) { request.id = playListId ?? request.id; @@ -1862,7 +1859,7 @@ namespace Roadie.Api.Services } private async Task> GetArtistsAction( - subsonic.Request request, User roadieUser) + subsonic.Request request, Library.Models.Users.User roadieUser) { var indexes = new List(); var musicFolder = MusicFolders().FirstOrDefault(x => x.id == (request.MusicFolderId ?? 2)); @@ -1905,7 +1902,7 @@ namespace Roadie.Api.Services } private async Task> GetIndexesAction( - subsonic.Request request, User roadieUser, long? ifModifiedSince = null) + subsonic.Request request, Library.Models.Users.User roadieUser, long? ifModifiedSince = null) { var modifiedSinceFilter = ifModifiedSince.HasValue ? (DateTime?)ifModifiedSince.Value.FromUnixTime() : null; @@ -1988,7 +1985,7 @@ namespace Roadie.Api.Services } private new async Task> SetArtistRating(Guid artistId, - ApplicationUser user, short rating) + Library.Identity.User user, short rating) { var r = await base.SetArtistRating(artistId, user, rating); if (r.IsNotFoundResult) @@ -2002,7 +1999,7 @@ namespace Roadie.Api.Services } private new async Task> SetReleaseRating(Guid releaseId, - ApplicationUser user, short rating) + Library.Identity.User user, short rating) { var r = await base.SetReleaseRating(releaseId, user, rating); if (r.IsNotFoundResult) @@ -2016,7 +2013,7 @@ namespace Roadie.Api.Services } private new async Task> SetTrackRating(Guid trackId, - ApplicationUser user, short rating) + Library.Identity.User user, short rating) { var r = await base.SetTrackRating(trackId, user, rating); if (r.IsNotFoundResult) @@ -2303,7 +2300,7 @@ namespace Roadie.Api.Services return playlists.Select(x => SubsonicPlaylistForPlaylist(x)).ToArray(); } - private async Task SubsonicUserForUser(ApplicationUser user) + private async Task SubsonicUserForUser(Library.Identity.User user) { var isAdmin = await UserManger.IsInRoleAsync(user, "Admin"); var isEditor = await UserManger.IsInRoleAsync(user, "Editor"); @@ -2332,7 +2329,7 @@ namespace Roadie.Api.Services }; } - private async Task> ToggleArtistStar(Guid artistId, ApplicationUser user, bool starred) + private async Task> ToggleArtistStar(Guid artistId, Library.Identity.User user, bool starred) { var r = await ToggleArtistFavorite(artistId, user, starred); if (r.IsNotFoundResult) @@ -2346,7 +2343,7 @@ namespace Roadie.Api.Services }; } - private async Task> ToggleReleaseStar(Guid releaseId, ApplicationUser user, bool starred) + private async Task> ToggleReleaseStar(Guid releaseId, Library.Identity.User user, bool starred) { var r = await ToggleReleaseFavorite(releaseId, user, starred); if (r.IsNotFoundResult) @@ -2360,7 +2357,7 @@ namespace Roadie.Api.Services }; } - private async Task> ToggleTrackStar(Guid trackId, ApplicationUser user, bool starred) + private async Task> ToggleTrackStar(Guid trackId, Library.Identity.User user, bool starred) { var r = await ToggleTrackFavorite(trackId, user, starred); if (r.IsNotFoundResult) diff --git a/Roadie.Api.Services/TokenService.cs b/Roadie.Api.Services/TokenService.cs index e66ec3f..e234d67 100644 --- a/Roadie.Api.Services/TokenService.cs +++ b/Roadie.Api.Services/TokenService.cs @@ -20,7 +20,7 @@ namespace Roadie.Api.Services _configuration = configuration; } - public async Task GenerateToken(ApplicationUser user, UserManager userManager) + public async Task GenerateToken(User user, UserManager userManager) { var utcNow = DateTime.UtcNow; diff --git a/Roadie.Api.Services/TrackService.cs b/Roadie.Api.Services/TrackService.cs index ff64fb1..2972821 100644 --- a/Roadie.Api.Services/TrackService.cs +++ b/Roadie.Api.Services/TrackService.cs @@ -110,7 +110,7 @@ namespace Roadie.Api.Services return result; } - public async Task> ById(User roadieUser, Guid id, IEnumerable includes) + public async Task> ById(Library.Models.Users.User roadieUser, Guid id, IEnumerable includes) { var timings = new Dictionary(); var tsw = new Stopwatch(); @@ -144,9 +144,7 @@ namespace Roadie.Api.Services var userBookmarkResult = await BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Track); if (userBookmarkResult.IsSuccess) { - result.Data.UserBookmarked = - userBookmarkResult?.Rows?.FirstOrDefault(x => x.Bookmark.Value == track.RoadieId.ToString()) != - null; + result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x?.Bookmark?.Value == track?.RoadieId.ToString()) != null; } tsw.Stop(); timings.Add("userBookmarks", tsw.ElapsedMilliseconds); @@ -199,7 +197,7 @@ namespace Roadie.Api.Services }; } - public async Task> List(PagedRequest request, User roadieUser, bool? doRandomize = false, Guid? releaseId = null) + public async Task> List(PagedRequest request, Library.Models.Users.User roadieUser, bool? doRandomize = false, Guid? releaseId = null) { try { @@ -396,7 +394,7 @@ namespace Roadie.Api.Services LibraryStatus = r.LibraryStatus, MediaCount = r.MediaCount, Rating = r.Rating, - Rank = r.Rank, + Rank = (double?)r.Rank, ReleaseDateDateTime = r.ReleaseDate, ReleasePlayUrl = $"{HttpContext.BaseUrl}/play/release/{r.RoadieId}", Status = r.Status, @@ -413,7 +411,7 @@ namespace Roadie.Api.Services Artist = new DataToken { Text = trackArtist.Name, Value = trackArtist.RoadieId.ToString() }, Rating = trackArtist.Rating, - Rank = trackArtist.Rank, + Rank = (double?)trackArtist.Rank, CreatedDate = trackArtist.CreatedDate, LastUpdated = trackArtist.LastUpdated, LastPlayed = trackArtist.LastPlayed, @@ -430,7 +428,7 @@ namespace Roadie.Api.Services Artist = new DataToken { Text = releaseArtist.Name, Value = releaseArtist.RoadieId.ToString() }, Rating = releaseArtist.Rating, - Rank = releaseArtist.Rank, + Rank = (double?)releaseArtist.Rank, CreatedDate = releaseArtist.CreatedDate, LastUpdated = releaseArtist.LastUpdated, LastPlayed = releaseArtist.LastPlayed, @@ -489,7 +487,7 @@ namespace Roadie.Api.Services if (!doRandomize ?? false) { - if (request.Action == User.ActionKeyUserRated) + if (request.Action == Library.Models.Users.User.ActionKeyUserRated) { sortBy = string.IsNullOrEmpty(request.Sort) ? request.OrderValue(new Dictionary { { "UserTrack.Rating", "DESC" }, { "MediaNumber", "ASC" }, { "TrackNumber", "ASC" } }) @@ -645,7 +643,7 @@ namespace Roadie.Api.Services /// /// Fast as possible check if exists and return minimum information on Track /// - public OperationResult StreamCheckAndInfo(User roadieUser, Guid id) + public OperationResult StreamCheckAndInfo(Library.Models.Users.User roadieUser, Guid id) { var track = DbContext.Tracks.FirstOrDefault(x => x.RoadieId == id); if (track == null) @@ -660,7 +658,7 @@ namespace Roadie.Api.Services }; } - public async Task> TrackStreamInfo(Guid trackId, long beginBytes, long endBytes, User roadieUser) + public async Task> TrackStreamInfo(Guid trackId, long beginBytes, long endBytes, Library.Models.Users.User roadieUser) { var track = DbContext.Tracks.FirstOrDefault(x => x.RoadieId == trackId); if (!(track?.IsValid ?? true)) @@ -672,7 +670,7 @@ namespace Roadie.Api.Services select r).FirstOrDefault(); if (!release.IsLocked ?? false && roadieUser != null) { - await AdminService.ScanRelease(new ApplicationUser + await AdminService.ScanRelease(new Library.Identity.User { Id = roadieUser.Id.Value }, release.RoadieId, false, true); @@ -711,7 +709,7 @@ namespace Roadie.Api.Services select r).FirstOrDefault(); if (!release.IsLocked ?? false && roadieUser != null) { - await AdminService.ScanRelease(new ApplicationUser + await AdminService.ScanRelease(new Library.Identity.User { Id = roadieUser.Id.Value }, release.RoadieId, false, true); @@ -799,7 +797,7 @@ namespace Roadie.Api.Services }; } - public async Task> UpdateTrack(User user, Track model) + public async Task> UpdateTrack(Library.Models.Users.User user, Track model) { var didChangeTrack = false; var sw = new Stopwatch(); diff --git a/Roadie.Api.Services/UserService.cs b/Roadie.Api.Services/UserService.cs index 8e70840..3c4f290 100644 --- a/Roadie.Api.Services/UserService.cs +++ b/Roadie.Api.Services/UserService.cs @@ -34,7 +34,7 @@ namespace Roadie.Api.Services { private ILastFmHelper LastFmHelper { get; } - private UserManager UserManager { get; } + private UserManager UserManager { get; } public UserService(IRoadieSettings configuration, IHttpEncoder httpEncoder, @@ -42,7 +42,7 @@ namespace Roadie.Api.Services IRoadieDbContext context, ICacheManager cacheManager, ILogger logger, - UserManager userManager, + UserManager userManager, ILastFmHelper lastFmHelper ) : base(configuration, httpEncoder, context, cacheManager, logger, httpContext) @@ -52,13 +52,13 @@ namespace Roadie.Api.Services ; } - public async Task> ById(User user, Guid id, IEnumerable includes, bool isAccountSettingsEdit = false) + public async Task> ById(models.Users.User user, Guid id, IEnumerable includes, bool isAccountSettingsEdit = false) { if (isAccountSettingsEdit) { if (user.UserId != id && !user.IsAdmin) { - var r = new OperationResult("Access Denied") + var r = new OperationResult("Access Denied") { IsAccessDeniedResult = true }; @@ -72,7 +72,7 @@ namespace Roadie.Api.Services { var rr = await UserByIdAction(id, includes); return rr; - }, ApplicationUser.CacheRegionUrn(id)); + }, Library.Identity.User.CacheRegionUrn(id)); sw.Stop(); if (result?.Data != null) { @@ -83,7 +83,7 @@ namespace Roadie.Api.Services result.Data.ConcurrencyStamp = null; } } - return new OperationResult(result.Messages) + return new OperationResult(result.Messages) { Data = result?.Data, Errors = result?.Errors, @@ -172,7 +172,7 @@ namespace Roadie.Api.Services }); } - public async Task> DeleteAllBookmarks(User roadieUser) + public async Task> DeleteAllBookmarks(models.Users.User roadieUser) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -192,7 +192,7 @@ namespace Roadie.Api.Services }; } - public async Task> SetArtistBookmark(Guid artistId, User roadieUser, bool isBookmarked) + public async Task> SetArtistBookmark(Guid artistId, models.Users.User roadieUser, bool isBookmarked) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -215,7 +215,7 @@ namespace Roadie.Api.Services }; } - public async Task> SetArtistDisliked(Guid artistId, User roadieUser, bool isDisliked) + public async Task> SetArtistDisliked(Guid artistId, models.Users.User roadieUser, bool isDisliked) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -225,7 +225,7 @@ namespace Roadie.Api.Services return await ToggleArtistDisliked(artistId, user, isDisliked); } - public async Task> SetArtistFavorite(Guid artistId, User roadieUser, bool isFavorite) + public async Task> SetArtistFavorite(Guid artistId, models.Users.User roadieUser, bool isFavorite) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -235,7 +235,7 @@ namespace Roadie.Api.Services return await ToggleArtistFavorite(artistId, user, isFavorite); } - public async Task> SetArtistRating(Guid artistId, User roadieUser, short rating) + public async Task> SetArtistRating(Guid artistId, models.Users.User roadieUser, short rating) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -245,7 +245,7 @@ namespace Roadie.Api.Services return await SetArtistRating(artistId, user, rating); } - public async Task> SetCollectionBookmark(Guid collectionId, User roadieUser, bool isBookmarked) + public async Task> SetCollectionBookmark(Guid collectionId, models.Users.User roadieUser, bool isBookmarked) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -268,7 +268,7 @@ namespace Roadie.Api.Services }; } - public async Task> SetLabelBookmark(Guid labelId, User roadieUser, bool isBookmarked) + public async Task> SetLabelBookmark(Guid labelId, models.Users.User roadieUser, bool isBookmarked) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -291,7 +291,7 @@ namespace Roadie.Api.Services }; } - public async Task> SetPlaylistBookmark(Guid playlistId, User roadieUser, + public async Task> SetPlaylistBookmark(Guid playlistId, models.Users.User roadieUser, bool isBookmarked) { var user = await GetUser(roadieUser.UserId); @@ -315,7 +315,7 @@ namespace Roadie.Api.Services }; } - public async Task> SetReleaseBookmark(Guid releaseid, User roadieUser, bool isBookmarked) + public async Task> SetReleaseBookmark(Guid releaseid, models.Users.User roadieUser, bool isBookmarked) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -338,7 +338,7 @@ namespace Roadie.Api.Services }; } - public async Task> SetReleaseDisliked(Guid releaseId, User roadieUser, bool isDisliked) + public async Task> SetReleaseDisliked(Guid releaseId, models.Users.User roadieUser, bool isDisliked) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -348,7 +348,7 @@ namespace Roadie.Api.Services return await ToggleReleaseDisliked(releaseId, user, isDisliked); } - public async Task> SetReleaseFavorite(Guid releaseId, User roadieUser, bool isFavorite) + public async Task> SetReleaseFavorite(Guid releaseId, models.Users.User roadieUser, bool isFavorite) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -358,7 +358,7 @@ namespace Roadie.Api.Services return await ToggleReleaseFavorite(releaseId, user, isFavorite); } - public async Task> SetReleaseRating(Guid releaseId, User roadieUser, short rating) + public async Task> SetReleaseRating(Guid releaseId, models.Users.User roadieUser, short rating) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -368,7 +368,7 @@ namespace Roadie.Api.Services return await base.SetReleaseRating(releaseId, user, rating); } - public async Task> SetTrackBookmark(Guid trackId, User roadieUser, bool isBookmarked) + public async Task> SetTrackBookmark(Guid trackId, models.Users.User roadieUser, bool isBookmarked) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -391,7 +391,7 @@ namespace Roadie.Api.Services }; } - public async Task> SetTrackDisliked(Guid trackId, User roadieUser, bool isDisliked) + public async Task> SetTrackDisliked(Guid trackId, models.Users.User roadieUser, bool isDisliked) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -401,7 +401,7 @@ namespace Roadie.Api.Services return await ToggleTrackDisliked(trackId, user, isDisliked); } - public async Task> SetTrackFavorite(Guid trackId, User roadieUser, bool isFavorite) + public async Task> SetTrackFavorite(Guid trackId, models.Users.User roadieUser, bool isFavorite) { var user = await GetUser(roadieUser.UserId); if (user == null) @@ -411,7 +411,7 @@ namespace Roadie.Api.Services return await ToggleTrackFavorite(trackId, user, isFavorite); } - public async Task> SetTrackRating(Guid trackId, User roadieUser, short rating) + public async Task> SetTrackRating(Guid trackId, models.Users.User roadieUser, short rating) { var timings = new Dictionary(); var sw = Stopwatch.StartNew(); @@ -446,7 +446,7 @@ namespace Roadie.Api.Services throw new NotImplementedException(); } - public async Task> UpdateProfile(User userPerformingUpdate, User userBeingUpdatedModel) + public async Task> UpdateProfile(models.Users.User userPerformingUpdate, models.Users.User userBeingUpdatedModel) { var user = DbContext.Users.FirstOrDefault(x => x.RoadieId == userBeingUpdatedModel.UserId); if (user == null) @@ -552,7 +552,7 @@ namespace Roadie.Api.Services }; } - CacheManager.ClearRegion(ApplicationUser.CacheRegionUrn(user.RoadieId)); + CacheManager.ClearRegion(Library.Identity.User.CacheRegionUrn(user.RoadieId)); Logger.LogInformation($"User `{userPerformingUpdate}` modifed user `{userBeingUpdatedModel}`"); @@ -563,8 +563,7 @@ namespace Roadie.Api.Services }; } - private async Task> SetBookmark(ApplicationUser user, BookmarkType bookmarktype, - int bookmarkTargetId, bool isBookmarked) + private async Task> SetBookmark(Library.Identity.User user, BookmarkType bookmarktype, int bookmarkTargetId, bool isBookmarked) { var bookmark = DbContext.Bookmarks.FirstOrDefault(x => x.BookmarkTargetId == bookmarkTargetId && x.BookmarkType == bookmarktype && @@ -583,7 +582,7 @@ namespace Roadie.Api.Services // Add bookmark if (bookmark == null) { - DbContext.Bookmarks.Add(new data.Bookmark + await DbContext.Bookmarks.AddAsync(new data.Bookmark { UserId = user.Id, BookmarkTargetId = bookmarkTargetId, @@ -604,7 +603,7 @@ namespace Roadie.Api.Services }; } - private async Task> UpdateLastFMSessionKey(ApplicationUser user, string token) + private async Task> UpdateLastFMSessionKey(Library.Identity.User user, string token) { var lastFmSessionKeyResult = await LastFmHelper.GetSessionKeyForUserToken(token); if (!lastFmSessionKeyResult.IsSuccess) @@ -620,7 +619,7 @@ namespace Roadie.Api.Services user.ConcurrencyStamp = Guid.NewGuid().ToString(); await DbContext.SaveChangesAsync(); - CacheManager.ClearRegion(ApplicationUser.CacheRegionUrn(user.RoadieId)); + CacheManager.ClearRegion(Library.Identity.User.CacheRegionUrn(user.RoadieId)); Logger.LogTrace($"User `{user}` Updated LastFm SessionKey"); @@ -631,7 +630,7 @@ namespace Roadie.Api.Services }; } - private async Task> UserByIdAction(Guid id, IEnumerable includes) + private async Task> UserByIdAction(Guid id, IEnumerable includes) { var timings = new Dictionary(); var tsw = new Stopwatch(); @@ -643,10 +642,10 @@ namespace Roadie.Api.Services if (user == null) { - return new OperationResult(true, string.Format("User Not Found [{0}]", id)); + return new OperationResult(true, string.Format("User Not Found [{0}]", id)); } tsw.Restart(); - var model = user.Adapt(); + var model = user.Adapt(); model.MediumThumbnail = ImageHelper.MakeThumbnailImage(Configuration, HttpContext, id, "user", Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height); model.IsAdmin = user.UserRoles?.Any(x => x.Role?.NormalizedName == "ADMIN") ?? false; model.IsEditor = model.IsAdmin ? true : user.UserRoles?.Any(x => x.Role?.NormalizedName == "EDITOR") ?? false; @@ -664,8 +663,8 @@ namespace Roadie.Api.Services var mostPlayedArtist = await DbContext.MostPlayedArtist(user.Id); var mostPlayedRelease = await DbContext.MostPlayedRelease(user.Id); - var lastPlayedTrack = await DbContext.MostPlayedTrack(user.Id); - var mostPlayedTrack = await DbContext.LastPlayedTrack(user.Id); + var lastPlayedTrack = await GetTrack((await DbContext.MostPlayedTrack(user.Id))?.RoadieId ?? Guid.Empty); + var mostPlayedTrack = await GetTrack((await DbContext.LastPlayedTrack(user.Id))?.RoadieId ?? Guid.Empty); model.Statistics = new UserStatistics { LastPlayedTrack = lastPlayedTrack == null @@ -727,7 +726,7 @@ namespace Roadie.Api.Services } } Logger.LogInformation($"ByIdAction: User `{ user }`: includes [{includes.ToCSV()}], timings: [{ timings.ToTimings() }]"); - return new OperationResult + return new OperationResult { IsSuccess = true, Data = model diff --git a/Roadie.Api/Controllers/AccountController.cs b/Roadie.Api/Controllers/AccountController.cs index 51b11fe..bc1102c 100644 --- a/Roadie.Api/Controllers/AccountController.cs +++ b/Roadie.Api/Controllers/AccountController.cs @@ -29,9 +29,9 @@ namespace Roadie.Api.Controllers public class AccountController : ControllerBase { private readonly ILogger Logger; - private readonly SignInManager SignInManager; + private readonly SignInManager SignInManager; private readonly ITokenService TokenService; - private readonly UserManager UserManager; + private readonly UserManager UserManager; private string _baseUrl; private IAdminService AdminService { get; } @@ -62,7 +62,7 @@ namespace Roadie.Api.Controllers private IRoadieSettings RoadieSettings { get; } - public AccountController(IAdminService adminService, UserManager userManager, SignInManager signInManager, + public AccountController(IAdminService adminService, UserManager userManager, SignInManager signInManager, IConfiguration configuration, ILogger logger, ITokenService tokenService, ICacheManager cacheManager, IEmailSender emailSender, IHttpContext httpContext) { @@ -194,7 +194,7 @@ namespace Roadie.Api.Controllers if (ModelState.IsValid) { var now = DateTime.UtcNow; - var user = new ApplicationUser + var user = new User { UserName = registerModel.Username, RegisteredOn = now, @@ -343,11 +343,11 @@ namespace Roadie.Api.Controllers var token = await UserManager.GeneratePasswordResetTokenAsync(user); callbackUrl = callbackUrl + "?username=" + username + "&token=" + WebEncoders.Base64UrlEncode(Encoding.ASCII.GetBytes(token)); - await EmailSender.SendEmailAsync(user.Email, $"Reset your {RoadieSettings.SiteName} password", - $"A request has been made to reset your password for your {RoadieSettings.SiteName} account. To proceed click here."); - Logger.LogTrace("User [{0}] Email [{1}] Requested Password Reset Callback [{2}]", username, - user.Email, callbackUrl); - return Ok(); + await EmailSender.SendEmailAsync(user.Email, $"Reset your {RoadieSettings.SiteName} password", + $"A request has been made to reset your password for your {RoadieSettings.SiteName} account. To proceed click here."); + Logger.LogTrace("User [{0}] Email [{1}] Requested Password Reset Callback [{2}]", username, + user.Email, callbackUrl); + return Ok(); } catch (Exception ex) { diff --git a/Roadie.Api/Controllers/AdminController.cs b/Roadie.Api/Controllers/AdminController.cs index 1778262..1496628 100644 --- a/Roadie.Api/Controllers/AdminController.cs +++ b/Roadie.Api/Controllers/AdminController.cs @@ -22,7 +22,7 @@ namespace Roadie.Api.Controllers private IAdminService AdminService { get; } public AdminController(IAdminService adminService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; @@ -160,7 +160,6 @@ namespace Roadie.Api.Controllers return Ok(result); } - [HttpPost("delete/track/{id}")] [ProducesResponseType(200)] public async Task DeleteTrack(Guid id, bool? doDeleteFile) @@ -257,7 +256,6 @@ namespace Roadie.Api.Controllers return Ok(result); } - [HttpPost("scan/collection/{id}")] [ProducesResponseType(200)] public async Task ScanCollection(Guid id, bool doPurgeFirst = false) @@ -337,6 +335,5 @@ namespace Roadie.Api.Controllers } return Ok(result); } - } } \ No newline at end of file diff --git a/Roadie.Api/Controllers/ArtistController.cs b/Roadie.Api/Controllers/ArtistController.cs index e921a44..2b3bed8 100644 --- a/Roadie.Api/Controllers/ArtistController.cs +++ b/Roadie.Api/Controllers/ArtistController.cs @@ -26,7 +26,7 @@ namespace Roadie.Api.Controllers private IArtistService ArtistService { get; } public ArtistController(IArtistService artistService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/BookmarkController.cs b/Roadie.Api/Controllers/BookmarkController.cs index af685d4..0f827e9 100644 --- a/Roadie.Api/Controllers/BookmarkController.cs +++ b/Roadie.Api/Controllers/BookmarkController.cs @@ -22,7 +22,7 @@ namespace Roadie.Api.Controllers private IBookmarkService BookmarkService { get; } public BookmarkController(IBookmarkService bookmarkService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/CollectionController.cs b/Roadie.Api/Controllers/CollectionController.cs index b03003d..0deb550 100644 --- a/Roadie.Api/Controllers/CollectionController.cs +++ b/Roadie.Api/Controllers/CollectionController.cs @@ -25,7 +25,7 @@ namespace Roadie.Api.Controllers public CollectionController(ICollectionService collectionService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/CommentController.cs b/Roadie.Api/Controllers/CommentController.cs index b0fa7ff..93654cc 100644 --- a/Roadie.Api/Controllers/CommentController.cs +++ b/Roadie.Api/Controllers/CommentController.cs @@ -24,7 +24,7 @@ namespace Roadie.Api.Controllers private ICommentService CommentService { get; } public CommentController(ILogger logger, ICacheManager cacheManager, - UserManager userManager, + UserManager userManager, IRoadieSettings roadieSettings, ICommentService commentService) : base(cacheManager, roadieSettings, userManager) { diff --git a/Roadie.Api/Controllers/EntityControllerBase.cs b/Roadie.Api/Controllers/EntityControllerBase.cs index 3358894..9d3802a 100644 --- a/Roadie.Api/Controllers/EntityControllerBase.cs +++ b/Roadie.Api/Controllers/EntityControllerBase.cs @@ -13,7 +13,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; -using System.Reflection; using System.Threading.Tasks; using models = Roadie.Library.Models.Users; @@ -31,10 +30,10 @@ namespace Roadie.Api.Controllers protected IRoadieSettings RoadieSettings { get; } - protected UserManager UserManager { get; } + protected UserManager UserManager { get; } public EntityControllerBase(ICacheManager cacheManager, IRoadieSettings roadieSettings, - UserManager userManager) + UserManager userManager) { CacheManager = cacheManager; RoadieSettings = roadieSettings; @@ -144,13 +143,13 @@ namespace Roadie.Api.Controllers return new EmptyResult(); } - protected models.User UserModelForUser(ApplicationUser user) + protected models.User UserModelForUser(User user) { if (user == null) return null; var result = user.Adapt(); result.IsAdmin = User.IsInRole("Admin"); result.IsEditor = User.IsInRole("Editor") || result.IsAdmin; return result; - } + } } } \ No newline at end of file diff --git a/Roadie.Api/Controllers/GenreController.cs b/Roadie.Api/Controllers/GenreController.cs index c99a3f7..57cff05 100644 --- a/Roadie.Api/Controllers/GenreController.cs +++ b/Roadie.Api/Controllers/GenreController.cs @@ -26,7 +26,7 @@ namespace Roadie.Api.Controllers private IGenreService GenreService { get; } public GenreController(IGenreService genreService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; @@ -38,7 +38,7 @@ namespace Roadie.Api.Controllers [ProducesResponseType(404)] public async Task Get(Guid id, string inc = null) { - var result = await GenreService.ById(await CurrentUserModel(), id,(inc ?? models.Genre.DefaultIncludes).ToLower().Split(",")); + var result = await GenreService.ById(await CurrentUserModel(), id, (inc ?? models.Genre.DefaultIncludes).ToLower().Split(",")); if (result == null || result.IsNotFoundResult) return NotFound(); if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError); return Ok(result); @@ -142,6 +142,5 @@ namespace Roadie.Api.Controllers } return Ok(result); } - } } \ No newline at end of file diff --git a/Roadie.Api/Controllers/ImageController.cs b/Roadie.Api/Controllers/ImageController.cs index f2f2365..78dcadf 100644 --- a/Roadie.Api/Controllers/ImageController.cs +++ b/Roadie.Api/Controllers/ImageController.cs @@ -21,7 +21,7 @@ namespace Roadie.Api.Controllers private IImageService ImageService { get; } public ImageController(IImageService imageService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/LabelController.cs b/Roadie.Api/Controllers/LabelController.cs index 11c4113..c88a596 100644 --- a/Roadie.Api/Controllers/LabelController.cs +++ b/Roadie.Api/Controllers/LabelController.cs @@ -26,7 +26,7 @@ namespace Roadie.Api.Controllers private ILabelService LabelService { get; } public LabelController(ILabelService labelService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/LookupController.cs b/Roadie.Api/Controllers/LookupController.cs index 8d27b11..47ce41a 100644 --- a/Roadie.Api/Controllers/LookupController.cs +++ b/Roadie.Api/Controllers/LookupController.cs @@ -21,7 +21,7 @@ namespace Roadie.Api.Controllers private ILookupService LookupService { get; } public LookupController(ILabelService labelService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, ILookupService lookupService, IRoadieSettings roadieSettings) + UserManager userManager, ILookupService lookupService, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; @@ -127,6 +127,5 @@ namespace Roadie.Api.Controllers if (!result.IsSuccess) return StatusCode((int)HttpStatusCode.InternalServerError); return Ok(result); } - } } \ No newline at end of file diff --git a/Roadie.Api/Controllers/PlayActivityController.cs b/Roadie.Api/Controllers/PlayActivityController.cs index 4b8276a..82b1cfd 100644 --- a/Roadie.Api/Controllers/PlayActivityController.cs +++ b/Roadie.Api/Controllers/PlayActivityController.cs @@ -24,7 +24,7 @@ namespace Roadie.Api.Controllers public PlayActivityController(IPlayActivityService playActivityService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/PlayController.cs b/Roadie.Api/Controllers/PlayController.cs index 834ee19..f40e389 100644 --- a/Roadie.Api/Controllers/PlayController.cs +++ b/Roadie.Api/Controllers/PlayController.cs @@ -29,7 +29,7 @@ namespace Roadie.Api.Controllers private ITrackService TrackService { get; } public PlayController(ITrackService trackService, IReleaseService releaseService, IPlayActivityService playActivityService, - ILogger logger, ICacheManager cacheManager, UserManager userManager, + ILogger logger, ICacheManager cacheManager, UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { diff --git a/Roadie.Api/Controllers/PlaylistController.cs b/Roadie.Api/Controllers/PlaylistController.cs index 8d6051c..190f41b 100644 --- a/Roadie.Api/Controllers/PlaylistController.cs +++ b/Roadie.Api/Controllers/PlaylistController.cs @@ -24,7 +24,7 @@ namespace Roadie.Api.Controllers private IPlaylistService PlaylistService { get; } public PlaylistController(IPlaylistService playlistService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; @@ -82,7 +82,7 @@ namespace Roadie.Api.Controllers [ProducesResponseType(404)] public async Task Get(Guid id, string inc = null) { - var result = await PlaylistService.ById(await CurrentUserModel(), id,(inc ?? Playlist.DefaultIncludes).ToLower().Split(",")); + var result = await PlaylistService.ById(await CurrentUserModel(), id, (inc ?? Playlist.DefaultIncludes).ToLower().Split(",")); if (result == null || result.IsNotFoundResult) { return NotFound(); diff --git a/Roadie.Api/Controllers/ReleaseController.cs b/Roadie.Api/Controllers/ReleaseController.cs index 8fa4a9e..21879ab 100644 --- a/Roadie.Api/Controllers/ReleaseController.cs +++ b/Roadie.Api/Controllers/ReleaseController.cs @@ -26,7 +26,7 @@ namespace Roadie.Api.Controllers private IReleaseService ReleaseService { get; } public ReleaseController(IReleaseService releaseService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/StatsController.cs b/Roadie.Api/Controllers/StatsController.cs index c3a0c9e..7349f24 100644 --- a/Roadie.Api/Controllers/StatsController.cs +++ b/Roadie.Api/Controllers/StatsController.cs @@ -21,7 +21,7 @@ namespace Roadie.Api.Controllers private IStatisticsService StatisticsService { get; } public StatsController(IStatisticsService statisticsService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/SubsonicController.cs b/Roadie.Api/Controllers/SubsonicController.cs index b452232..342cbc9 100644 --- a/Roadie.Api/Controllers/SubsonicController.cs +++ b/Roadie.Api/Controllers/SubsonicController.cs @@ -8,7 +8,6 @@ using Roadie.Api.Services; using Roadie.Library.Caching; using Roadie.Library.Configuration; using Roadie.Library.Extensions; -using Roadie.Library.Identity; using Roadie.Library.Models.ThirdPartyApi.Subsonic; using Roadie.Library.Scrobble; using Roadie.Library.Utility; @@ -41,7 +40,7 @@ namespace Roadie.Api.Controllers public SubsonicController(ISubsonicService subsonicService, ITrackService trackService, IReleaseService releaseService, IPlayActivityService playActivityService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; @@ -658,8 +657,10 @@ namespace Roadie.Api.Controllers { var appUser = await SubsonicService.Authenticate(request); if (!(appUser?.IsSuccess ?? false) || (appUser?.IsNotFoundResult ?? false)) + { return BuildResponse(request, appUser.Adapt>()); - SubsonicUser = UserModelForUser(appUser.Data.User); + } + SubsonicUser = UserModelForUser(appUser.Data.SubsonicUser); return null; } diff --git a/Roadie.Api/Controllers/TrackController.cs b/Roadie.Api/Controllers/TrackController.cs index 6fd9fdf..0126c23 100644 --- a/Roadie.Api/Controllers/TrackController.cs +++ b/Roadie.Api/Controllers/TrackController.cs @@ -24,7 +24,7 @@ namespace Roadie.Api.Controllers private ITrackService TrackService { get; } public TrackController(ITrackService trackService, ILogger logger, ICacheManager cacheManager, - UserManager userManager, IRoadieSettings roadieSettings) + UserManager userManager, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { Logger = logger; diff --git a/Roadie.Api/Controllers/UserController.cs b/Roadie.Api/Controllers/UserController.cs index 697b5d1..2682dae 100644 --- a/Roadie.Api/Controllers/UserController.cs +++ b/Roadie.Api/Controllers/UserController.cs @@ -6,9 +6,7 @@ using Microsoft.Extensions.Logging; using Roadie.Api.Services; using Roadie.Library.Caching; using Roadie.Library.Configuration; -using Roadie.Library.Identity; using Roadie.Library.Models.Pagination; -using Roadie.Library.Models.Users; using Roadie.Library.Utility; using System; using System.Collections.Generic; @@ -31,7 +29,7 @@ namespace Roadie.Api.Controllers private IUserService UserService { get; } public UserController(IUserService userService, ILogger logger, ICacheManager cacheManager, - IConfiguration configuration, ITokenService tokenService, UserManager userManager, + IConfiguration configuration, ITokenService tokenService, UserManager userManager, IHttpContext httpContext, IRoadieSettings roadieSettings) : base(cacheManager, roadieSettings, userManager) { @@ -41,7 +39,6 @@ namespace Roadie.Api.Controllers RoadieHttpContext = httpContext; } - [HttpGet("accountsettings/{id}")] [ProducesResponseType(200)] [ProducesResponseType(204)] @@ -70,7 +67,6 @@ namespace Roadie.Api.Controllers return Ok(result); } - [HttpGet("{id}")] [ProducesResponseType(200)] [ProducesResponseType(204)] @@ -275,7 +271,7 @@ namespace Roadie.Api.Controllers [HttpPost("profile/edit")] [ProducesResponseType(200)] - public async Task UpdateProfile(User model) + public async Task UpdateProfile(Library.Models.Users.User model) { if (!ModelState.IsValid) { @@ -286,7 +282,7 @@ namespace Roadie.Api.Controllers if (result == null || result.IsNotFoundResult) return NotFound(); if (!result.IsSuccess) { - if(result.IsAccessDeniedResult) + if (result.IsAccessDeniedResult) { return StatusCode((int)HttpStatusCode.Forbidden); } diff --git a/Roadie.Api/Program.cs b/Roadie.Api/Program.cs index 9e40572..b25a5d0 100644 --- a/Roadie.Api/Program.cs +++ b/Roadie.Api/Program.cs @@ -2,7 +2,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Serilog; -using Serilog.Extensions.Logging; using System; using System.Diagnostics; using System.IO; @@ -11,7 +10,6 @@ namespace Roadie.Api { public class Program { - public static IConfiguration Configuration { get; } = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", false, true) @@ -71,8 +69,30 @@ namespace Roadie.Api public class LoggingTraceListener : TraceListener { - public override void Write(string message) => Log.Verbose(message); + public override void Write(string message) => WriteLog(message); - public override void WriteLine(string message) => Log.Verbose(message); + public override void WriteLine(string message) => WriteLog(message); + + public override void WriteLine(string o, string category) => WriteLog(o, category); + + public override void Write(string o, string category) => WriteLog(o, category); + + private void WriteLog(string message, string category = null) + { + switch (category?.ToLower()) + { + case "warning": + Log.Warning(message); + break; + + case "error": + Log.Error(message); + break; + + default: + Log.Verbose(message); + break; + } + } } } \ No newline at end of file diff --git a/Roadie.Api/Properties/launchSettings.json b/Roadie.Api/Properties/launchSettings.json index e942ed4..4da01d5 100644 --- a/Roadie.Api/Properties/launchSettings.json +++ b/Roadie.Api/Properties/launchSettings.json @@ -3,7 +3,7 @@ "Roadie.Api": { "commandName": "Project", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Production" + "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:5123/" } diff --git a/Roadie.Api/Roadie.Api.csproj b/Roadie.Api/Roadie.Api.csproj index 1d05d3e..5363cc2 100644 --- a/Roadie.Api/Roadie.Api.csproj +++ b/Roadie.Api/Roadie.Api.csproj @@ -1,7 +1,7 @@  - 1.0.2 + 1.1.0 @@ -36,9 +36,9 @@ + - diff --git a/Roadie.Api/Startup.cs b/Roadie.Api/Startup.cs index 9c38937..2e720b9 100644 --- a/Roadie.Api/Startup.cs +++ b/Roadie.Api/Startup.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Routing; +using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -16,7 +17,6 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; -using Pomelo.EntityFrameworkCore.MySql.Infrastructure; using Roadie.Api.Hubs; using Roadie.Api.ModelBinding; using Roadie.Api.Services; @@ -45,6 +45,7 @@ using Serilog; using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Reflection; using System.Text; @@ -105,7 +106,6 @@ namespace Roadie.Api // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - var settings = new RoadieSettings(); _configuration.GetSection("RoadieSettings").Bind(settings); @@ -119,6 +119,8 @@ namespace Roadie.Api return new MemoryCacheManager(logger, new CachePolicy(TimeSpan.FromHours(4))); }); + var dbFolder = new DirectoryInfo(settings.FileDatabaseOptions.DatabaseFolder); + switch (settings.DbContextToUse) { case DbContexts.MySQL: @@ -143,7 +145,31 @@ namespace Roadie.Api } )); break; + + case DbContexts.SQLite: + if (!dbFolder.Exists) + { + dbFolder.Create(); + } + var builder = new SqliteConnectionStringBuilder() + { + DataSource = Path.Combine(settings.FileDatabaseOptions.DatabaseFolder, $"{ settings.FileDatabaseOptions.DatabaseName }.db"), + Mode = SqliteOpenMode.ReadWriteCreate, + Cache = SqliteCacheMode.Shared + }; + services.AddDbContext( + options => options.UseSqlite(builder.ConnectionString) + ); + services.AddDbContext( + options => options.UseSqlite(builder.ConnectionString) + ); + break; + case DbContexts.File: + if (!dbFolder.Exists) + { + dbFolder.Create(); + } services.AddDbContext( options => options.UseFileContextDatabase(settings.FileDatabaseOptions.DatabaseFormat.ToString().ToLower(), databaseName: settings.FileDatabaseOptions.DatabaseName, @@ -155,16 +181,13 @@ namespace Roadie.Api location: settings.FileDatabaseOptions.DatabaseFolder) ); break; + default: throw new NotImplementedException("Unknown DbContext Type"); } - //services.AddDefaultIdentity( - // options => options.SignIn.RequireConfirmedAccount = false) - // .AddEntityFrameworkStores(); - - services.AddIdentity() - .AddRoles() + services.AddIdentity() + .AddRoles() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); @@ -337,6 +360,7 @@ namespace Roadie.Api } private static string _roadieApiVersion = null; + public static string RoadieApiVersion() { if (string.IsNullOrEmpty(_roadieApiVersion)) diff --git a/Roadie.Api/appsettings.Development.json b/Roadie.Api/appsettings.Development.json index ed2ce32..f56ca3f 100644 --- a/Roadie.Api/appsettings.Development.json +++ b/Roadie.Api/appsettings.Development.json @@ -27,7 +27,7 @@ { "Name": "LiteDB", "Args": { - "databaseUrl": "logs\\logs.db", + "databaseUrl": "logs\\logs.litedb", "restrictedToMinimumLevel": "Verbose" } }, @@ -59,6 +59,7 @@ }, "CORSOrigins": "http://localhost:4200|http://localhost:8080|https://localhost:8080|http://localhost:80|https://localhost:80", "RoadieSettings": { + "DbContextToUse": "MySQL", "SiteName": "Roadie Dev", "InboundFolder": "C:\\\\roadie_dev_root\\\\inbound", "LibraryFolder": "C:\\\\roadie_dev_root\\\\library", diff --git a/Roadie.Api/appsettings.DevelopmentFile.json b/Roadie.Api/appsettings.DevelopmentFile.json index 98eb908..4b554e2 100644 --- a/Roadie.Api/appsettings.DevelopmentFile.json +++ b/Roadie.Api/appsettings.DevelopmentFile.json @@ -27,7 +27,7 @@ { "Name": "LiteDB", "Args": { - "databaseUrl": "logs\\logs.db", + "databaseUrl": "logs\\logs.litedb", "restrictedToMinimumLevel": "Verbose" } }, diff --git a/Roadie.Api/appsettings.DevelopmentSQLite.json b/Roadie.Api/appsettings.DevelopmentSQLite.json new file mode 100644 index 0000000..bca5f38 --- /dev/null +++ b/Roadie.Api/appsettings.DevelopmentSQLite.json @@ -0,0 +1,80 @@ +{ + "Kestrel": { + "EndPoints": { + "Http": { + "Url": "http://192.168.1.177:5123/" + } + } + }, + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.RollingFileAlternate", "Serilog.Sinks.LiteDB" ], + "MinimumLevel": { + "Default": "Verbose", + "Override": { + "System": "Warning", + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console", + "restrictedToMinimumLevel": "Verbose" + } + }, + { + "Name": "LiteDB", + "Args": { + "databaseUrl": "logs\\logs.litedb", + "restrictedToMinimumLevel": "Verbose" + } + }, + { + "Name": "LiteDB", + "Args": { + "databaseUrl": "logs\\errors.litedb", + "restrictedToMinimumLevel": "Error" + } + }, + { + "Name": "RollingFileAlternate", + "Args": { + "minimumLevel": "Verbose", + "logDirectory": "logs", + "fileSizeLimitBytes": 26214400, + "retainedFileCountLimit": 30, + "buffered": true + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "WithExceptionDetails" ], + "Properties": { + "Application": "Roadie API" + } + }, + "Tokens": { + "PrivateKey": "!1232bcdb4bebc80a0d080883d6deefuxlsh8bfc920c2a8cskeuxd8349sk412aa785662e594b4df48cb46aa3c652b40b3#", + "PublicKey": "91i4874y24134E50sz7dges68AB08", + "Lifetime": "86400", + "Issuer": "http://localhost:5123", + "Audience": "http://localhost:5500" + }, + "CORSOrigins": "http://localhost:4200|http://localhost:8080|https://localhost:8080|http://localhost:80|https://localhost:80", + "RoadieSettings": { + "DbContextToUse": "SQLite", + "SiteName": "Roadie SQLite", + "FileDatabaseOptions": { + "DatabaseFolder": "C:\\roadie_dev_sqlite_root\\db" + }, + "InboundFolder": "C:\\roadie_dev_sqlite_root\\inbound", + "LibraryFolder": "C:\\roadie_dev_sqlite_root\\library", + "Dlna": { + "IsEnabled": false + }, + "Processing": { + "RemoveStringsRegex": "\\b[0-9]+\\s#\\s\\b" + } + } +} \ No newline at end of file diff --git a/Roadie.Api/appsettings.json b/Roadie.Api/appsettings.json index bbb576a..21ed5df 100644 --- a/Roadie.Api/appsettings.json +++ b/Roadie.Api/appsettings.json @@ -52,6 +52,7 @@ }, "CORSOrigins": "http://localhost:4200|http://localhost:8080|https://localhost:8080|http://localhost:80|https://localhost:80", "RoadieSettings": { + "DbContextToUse": "MySQL", "Dlna": { "Port": 61903, "IsEnabled": false diff --git a/Roadie.Api/logs/errors.litedb b/Roadie.Api/logs/errors.litedb new file mode 100644 index 0000000..3e009a5 Binary files /dev/null and b/Roadie.Api/logs/errors.litedb differ diff --git a/Roadie.Api/logs/logs.litedb b/Roadie.Api/logs/logs.litedb new file mode 100644 index 0000000..f92deba Binary files /dev/null and b/Roadie.Api/logs/logs.litedb differ diff --git a/Roadie.Dlna.Services/Track.cs b/Roadie.Dlna.Services/Track.cs index e0453c7..3be95ec 100644 --- a/Roadie.Dlna.Services/Track.cs +++ b/Roadie.Dlna.Services/Track.cs @@ -50,7 +50,7 @@ namespace Roadie.Dlna.Services } catch (Exception ex) { - Trace.WriteLine($"Failed to access CachedCover Ex [{ ex }]"); + Trace.WriteLine($"Failed to access CachedCover Ex [{ ex }]", "Warning"); } if (MetaAlbum != null) { diff --git a/Roadie.Dlna/Server/Handlers/MediaMount_SOAP.cs b/Roadie.Dlna/Server/Handlers/MediaMount_SOAP.cs index 098fbb6..b0f80c7 100644 --- a/Roadie.Dlna/Server/Handlers/MediaMount_SOAP.cs +++ b/Roadie.Dlna/Server/Handlers/MediaMount_SOAP.cs @@ -375,7 +375,7 @@ namespace Roadie.Dlna.Server } catch (Exception ex) { - Trace.WriteLine($"Not all params provided. Ex [{ ex }]"); + Trace.WriteLine($"Not all params provided. Ex [{ ex }]", "Error"); } var root = GetItem(id, false) as IMediaFolder; diff --git a/Roadie.Dlna/Server/Http/HTTPServer.cs b/Roadie.Dlna/Server/Http/HTTPServer.cs index 5bbc78c..4dd176d 100644 --- a/Roadie.Dlna/Server/Http/HTTPServer.cs +++ b/Roadie.Dlna/Server/Http/HTTPServer.cs @@ -263,7 +263,7 @@ namespace Roadie.Dlna.Server } catch (Exception ex) { - Trace.WriteLine($"Failed to get uname Ex [{ ex }]"); + Trace.WriteLine($"Failed to get uname Ex [{ ex }]", "Warning"); } break; } diff --git a/Scripts/MySQL/Upgrade0010.sql b/Scripts/MySQL/Upgrade0010.sql new file mode 100644 index 0000000..0842f3c --- /dev/null +++ b/Scripts/MySQL/Upgrade0010.sql @@ -0,0 +1,13 @@ +UPDATE `track` +set artistId = NULL +where id in (select t.id +from `track` t +where artistId IS NOT NULL +and artistId NOT IN (select id from `artist`)); + +ALTER TABLE `track` + ADD CONSTRAINT `track_artist_ibfk_1` + FOREIGN KEY (`artistId`) + REFERENCES `artist` (`id`) + ON DELETE SET NULL; + \ No newline at end of file diff --git a/Scripts/MySQL/roadie.sql b/Scripts/MySQL/roadie.sql index ac80339..1bdcb0e 100644 --- a/Scripts/MySQL/roadie.sql +++ b/Scripts/MySQL/roadie.sql @@ -1,11 +1,12 @@ -- /// --- Roadie version 1.0.3.1 new database script, if upgrading skip this and run Upgrade*.sql scripts from your version to current. +-- Roadie version 1.1.0 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) + +-- MySQL dump 10.17 Distrib 10.3.20-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: roadie_dev -- ------------------------------------------------------ --- Server version 10.3.16-MariaDB-log +-- Server version 10.3.20-MariaDB-log /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -62,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=67 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -81,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -101,7 +102,7 @@ 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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=64 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -120,7 +121,7 @@ CREATE TABLE `artistSimilar` ( 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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -147,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -204,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -223,7 +224,7 @@ CREATE TABLE `collectionMissing` ( `release` varchar(1000) COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`id`), KEY `ix_collection_collectionId` (`collectionId`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -249,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=0 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 */; -- @@ -293,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -319,7 +320,66 @@ 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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `credit` +-- + +DROP TABLE IF EXISTS `credit`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `credit` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `artistId` int(11) DEFAULT NULL, + `releaseId` int(11) DEFAULT NULL, + `trackId` int(11) DEFAULT NULL, + `creditCategoryId` int(11) NOT NULL, + `isLocked` tinyint(1) DEFAULT NULL, + `status` smallint(6) DEFAULT NULL, + `roadieId` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `createdDate` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + `creditToName` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `description` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `urls` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `tags` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `ix_credit_roadieId` (`roadieId`), + KEY `idx_creditCreditandRelease` (`releaseId`,`id`), + KEY `idx_creditCreditandTrack` (`trackId`,`id`), + KEY `credit_artist_ibfk_1` (`artistId`), + KEY `credit_category_ibfk_1` (`creditCategoryId`), + CONSTRAINT `credit_artist_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE, + CONSTRAINT `credit_category_ibfk_1` FOREIGN KEY (`creditCategoryId`) REFERENCES `creditCategory` (`id`) ON DELETE CASCADE, + CONSTRAINT `credit_release_ibfk_1` FOREIGN KEY (`releaseId`) REFERENCES `release` (`id`) ON DELETE CASCADE, + CONSTRAINT `credit_track_ibfk_1` FOREIGN KEY (`trackId`) REFERENCES `track` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `creditCategory` +-- + +DROP TABLE IF EXISTS `creditCategory`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `creditCategory` ( + `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, + `createdDate` datetime DEFAULT NULL, + `lastUpdated` datetime DEFAULT NULL, + `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, + `description` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `urls` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `tags` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `alternateNames` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `ix_creditCategory_roadieId` (`roadieId`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -337,17 +397,17 @@ CREATE TABLE `genre` ( `createdDate` datetime DEFAULT NULL, `lastUpdated` datetime DEFAULT NULL, `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, - `sortName` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `normalizedName` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `thumbnail` blob DEFAULT NULL, `alternateNames` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, `description` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `tags` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `sortName` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ix_genre_name` (`name`), KEY `ix_genre_roadieId` (`roadieId`), KEY `genre_normalizedName_IDX` (`normalizedName`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -398,7 +458,7 @@ CREATE TABLE `inviteToken` ( KEY `ix_inviteToken_roadieId` (`roadieId`), KEY `inviteToken_fk_1` (`createdByUserId`), CONSTRAINT `inviteToken_fk_1` FOREIGN KEY (`createdByUserId`) REFERENCES `user` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -433,7 +493,7 @@ CREATE TABLE `label` ( PRIMARY KEY (`id`), UNIQUE KEY `ix_label_name` (`name`), KEY `ix_label_roadieId` (`roadieId`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -466,7 +526,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -492,7 +552,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=694 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -512,7 +572,6 @@ CREATE TABLE `release` ( `lastUpdated` datetime DEFAULT NULL, `isVirtual` tinyint(1) DEFAULT NULL, `title` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL, - `sortTitle` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `alternateNames` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, `releaseDate` date DEFAULT NULL, `rating` smallint(6) NOT NULL, @@ -536,12 +595,13 @@ CREATE TABLE `release` ( `playedCount` int(11) DEFAULT NULL, `duration` int(11) DEFAULT NULL, `rank` decimal(9,2) DEFAULT NULL, + `sortTitle` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_releaseArtistAndTitle` (`artistId`,`title`), 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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -560,7 +620,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -588,7 +648,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -613,7 +673,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -635,7 +695,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=152 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -661,7 +721,7 @@ CREATE TABLE `scanHistory` ( PRIMARY KEY (`id`), KEY `ix_scanHistory_roadieId` (`roadieId`), KEY `rscanHistoryt_ibfk_1` (`userId`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=156 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -728,8 +788,9 @@ CREATE TABLE `track` ( KEY `ix_track_roadieId` (`roadieId`), KEY `track_artistId_IDX` (`artistId`) USING BTREE, KEY `track_releaseMediaId_IDX` (`releaseMediaId`) USING BTREE, + CONSTRAINT `track_artist_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE SET NULL, CONSTRAINT `track_ibfk_1` FOREIGN KEY (`releaseMediaId`) REFERENCES `releasemedia` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=653 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -799,11 +860,12 @@ CREATE TABLE `user` ( `PhoneNumberConfirmed` bit(1) DEFAULT NULL, `removeTrackFromQueAfterPlayed` bit(1) DEFAULT NULL, `lastFMSessionKey` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `defaultRowsPerPage` smallint(6) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`), UNIQUE KEY `ix_user_username` (`username`), KEY `ix_user_roadieId` (`roadieId`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -894,7 +956,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -922,7 +984,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -946,7 +1008,7 @@ CREATE TABLE `userrole` ( PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`), KEY `ix_userrole_roadieId` (`roadieId`) -) ENGINE=InnoDB AUTO_INCREMENT=0 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 */; -- @@ -965,7 +1027,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -995,7 +1057,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=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=304 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1081,4 +1143,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-08-02 11:14:18 +-- Dump completed on 2019-11-27 9:23:57