diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 53c212ea1..ff93141e5 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -129,9 +129,11 @@ namespace Ombi.DependencyInjection public static void RegisterStore(this IServiceCollection services) { services.AddEntityFrameworkSqlite().AddDbContext(); services.AddEntityFrameworkSqlite().AddDbContext(); + services.AddEntityFrameworkSqlite().AddDbContext(); services.AddScoped(); // https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6 services.AddScoped(); // https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6 + services.AddScoped(); // https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6 services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -146,6 +148,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(typeof(ISettingsService<>), typeof(SettingsService<>)); services.AddTransient(typeof(IRepository<>), typeof(Repository<>)); + services.AddTransient(typeof(IExternalRepository<>), typeof(ExternalRepository<>)); } public static void RegisterServices(this IServiceCollection services) { diff --git a/src/Ombi.Store/Context/ExternalContext.cs b/src/Ombi.Store/Context/ExternalContext.cs new file mode 100644 index 000000000..e77013d42 --- /dev/null +++ b/src/Ombi.Store/Context/ExternalContext.cs @@ -0,0 +1,67 @@ +using System.IO; +using Microsoft.EntityFrameworkCore; +using Ombi.Helpers; +using Ombi.Store.Entities; + +namespace Ombi.Store.Context +{ + public sealed class ExternalContext : DbContext, IExternalContext + { + private static bool _created; + public ExternalContext() + { + if (_created) return; + + _created = true; + Database.Migrate(); + } + + public DbSet PlexServerContent { get; set; } + public DbSet PlexEpisode { get; set; } + public DbSet RadarrCache { get; set; } + public DbSet CouchPotatoCache { get; set; } + public DbSet EmbyContent { get; set; } + public DbSet EmbyEpisode { get; set; } + + public DbSet SonarrCache { get; set; } + public DbSet LidarrArtistCache { get; set; } + public DbSet LidarrAlbumCache { get; set; } + public DbSet SonarrEpisodeCache { get; set; } + public DbSet SickRageCache { get; set; } + public DbSet SickRageEpisodeCache { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + var i = StoragePathSingleton.Instance; + if (string.IsNullOrEmpty(i.StoragePath)) + { + i.StoragePath = string.Empty; + } + optionsBuilder.UseSqlite($"Data Source={Path.Combine(i.StoragePath, "ExternalOmbi.db")}"); + } + + protected override void OnModelCreating(ModelBuilder builder) + { + builder.Entity().HasMany(x => x.Episodes) + .WithOne(x => x.Series) + .HasPrincipalKey(x => x.Key) + .HasForeignKey(x => x.GrandparentKey); + + builder.Entity() + .HasOne(p => p.Series) + .WithMany(b => b.Episodes) + .HasPrincipalKey(x => x.EmbyId) + .HasForeignKey(p => p.ParentId); + + base.OnModelCreating(builder); + } + + + public void Seed() + { + // VACUUM; + Database.ExecuteSqlCommand("VACUUM;"); + SaveChanges(); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Context/IExternalContext.cs b/src/Ombi.Store/Context/IExternalContext.cs new file mode 100644 index 000000000..3f5d79a79 --- /dev/null +++ b/src/Ombi.Store/Context/IExternalContext.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using Ombi.Store.Entities; + +namespace Ombi.Store.Context +{ + public interface IExternalContext : IDbContext + { + DbSet CouchPotatoCache { get; set; } + DbSet EmbyContent { get; set; } + DbSet EmbyEpisode { get; set; } + DbSet LidarrAlbumCache { get; set; } + DbSet LidarrArtistCache { get; set; } + DbSet PlexEpisode { get; set; } + DbSet PlexServerContent { get; set; } + DbSet RadarrCache { get; set; } + DbSet SickRageCache { get; set; } + DbSet SickRageEpisodeCache { get; set; } + DbSet SonarrCache { get; set; } + DbSet SonarrEpisodeCache { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Repository/BaseRepository.cs b/src/Ombi.Store/Repository/BaseRepository.cs new file mode 100644 index 000000000..1679035dd --- /dev/null +++ b/src/Ombi.Store/Repository/BaseRepository.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query; +using Ombi.Store.Context; +using Ombi.Store.Entities; + +namespace Ombi.Store.Repository +{ + public class BaseRepository : IRepository where T : Entity where U : IDbContext + { + public BaseRepository(U ctx) + { + _ctx = ctx; + _db = _ctx.Set(); + } + public DbSet _db { get; } + private readonly U _ctx; + + public async Task Find(object key) + { + return await _db.FindAsync(key); + } + + public IQueryable GetAll() + { + return _db.AsQueryable(); + } + + public async Task FirstOrDefaultAsync(Expression> predicate) + { + return await _db.FirstOrDefaultAsync(predicate); + } + + public async Task AddRange(IEnumerable content, bool save = true) + { + _db.AddRange(content); + if (save) + { + await _ctx.SaveChangesAsync(); + } + } + + public async Task Add(T content) + { + await _db.AddAsync(content); + await _ctx.SaveChangesAsync(); + return content; + } + + public async Task Delete(T request) + { + _db.Remove(request); + await _ctx.SaveChangesAsync(); + } + + public async Task DeleteRange(IEnumerable req) + { + _db.RemoveRange(req); + await _ctx.SaveChangesAsync(); + } + + public async Task SaveChangesAsync() + { + return await _ctx.SaveChangesAsync(); + } + + public IIncludableQueryable Include( + IQueryable source, Expression> navigationPropertyPath) + where TEntity : class + { + return source.Include(navigationPropertyPath); + } + + public async Task ExecuteSql(string sql) + { + await _ctx.Database.ExecuteSqlCommandAsync(sql); + } + + + private bool _disposed; + // Protected implementation of Dispose pattern. + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _ctx?.Dispose(); + } + + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Repository/ExternalRepository.cs b/src/Ombi.Store/Repository/ExternalRepository.cs new file mode 100644 index 000000000..d7494afd4 --- /dev/null +++ b/src/Ombi.Store/Repository/ExternalRepository.cs @@ -0,0 +1,12 @@ +using Ombi.Store.Context; +using Ombi.Store.Entities; + +namespace Ombi.Store.Repository +{ + public class ExternalRepository : BaseRepository, IExternalRepository where T : Entity + { + public ExternalRepository(IExternalContext ctx) : base(ctx) + { + } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IExternalRepository.cs b/src/Ombi.Store/Repository/IExternalRepository.cs new file mode 100644 index 000000000..de8b6db67 --- /dev/null +++ b/src/Ombi.Store/Repository/IExternalRepository.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query; +using Ombi.Store.Entities; + +namespace Ombi.Store.Repository +{ + public interface IExternalRepository : IDisposable where T : Entity + { + Task Find(object key); + IQueryable GetAll(); + Task FirstOrDefaultAsync(Expression> predicate); + Task AddRange(IEnumerable content, bool save = true); + Task Add(T content); + Task DeleteRange(IEnumerable req); + Task Delete(T request); + Task SaveChangesAsync(); + + IIncludableQueryable Include( + IQueryable source, Expression> navigationPropertyPath) + where TEntity : class; + + Task ExecuteSql(string sql); + DbSet _db { get; } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Repository/Repository.cs b/src/Ombi.Store/Repository/Repository.cs index 8c07c2371..9d49ded58 100644 --- a/src/Ombi.Store/Repository/Repository.cs +++ b/src/Ombi.Store/Repository/Repository.cs @@ -1,105 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Query; -using Ombi.Store.Context; +using Ombi.Store.Context; using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public class Repository : IRepository where T : Entity + public class Repository : BaseRepository, IRepository where T : Entity { - public Repository(IOmbiContext ctx) + public Repository(IOmbiContext ctx) : base(ctx) { - _ctx = ctx; - _db = _ctx.Set(); - } - public DbSet _db { get; } - private readonly IOmbiContext _ctx; - - public async Task Find(object key) - { - return await _db.FindAsync(key); - } - - public IQueryable GetAll() - { - return _db.AsQueryable(); - } - - public async Task FirstOrDefaultAsync(Expression> predicate) - { - return await _db.FirstOrDefaultAsync(predicate); - } - - public async Task AddRange(IEnumerable content, bool save = true) - { - _db.AddRange(content); - if (save) - { - await _ctx.SaveChangesAsync(); - } - } - - public async Task Add(T content) - { - await _db.AddAsync(content); - await _ctx.SaveChangesAsync(); - return content; - } - - public async Task Delete(T request) - { - _db.Remove(request); - await _ctx.SaveChangesAsync(); - } - - public async Task DeleteRange(IEnumerable req) - { - _db.RemoveRange(req); - await _ctx.SaveChangesAsync(); - } - - public async Task SaveChangesAsync() - { - return await _ctx.SaveChangesAsync(); - } - - public IIncludableQueryable Include( - IQueryable source, Expression> navigationPropertyPath) - where TEntity : class - { - return source.Include(navigationPropertyPath); - } - - public async Task ExecuteSql(string sql) - { - await _ctx.Database.ExecuteSqlCommandAsync(sql); - } - - - private bool _disposed; - // Protected implementation of Dispose pattern. - protected virtual void Dispose(bool disposing) - { - if (_disposed) - return; - - if (disposing) - { - _ctx?.Dispose(); - } - - _disposed = true; - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); } } } \ No newline at end of file