< Summary - Jellyfin

Information
Class: Jellyfin.Database.Implementations.JellyfinDbContext
Assembly: Jellyfin.Database.Implementations
File(s): /srv/git/jellyfin/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs
Line coverage
83%
Covered lines: 45
Uncovered lines: 9
Coverable lines: 54
Total lines: 326
Line coverage: 83.3%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

File(s)

/srv/git/jellyfin/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs

#LineLine coverage
 1using System;
 2using System.Data.Common;
 3using System.Linq;
 4using System.Threading;
 5using System.Threading.Tasks;
 6using Jellyfin.Database.Implementations.Entities;
 7using Jellyfin.Database.Implementations.Entities.Security;
 8using Jellyfin.Database.Implementations.Interfaces;
 9using Jellyfin.Database.Implementations.Locking;
 10using Microsoft.EntityFrameworkCore;
 11using Microsoft.EntityFrameworkCore.Diagnostics;
 12using Microsoft.Extensions.Logging;
 13
 14namespace Jellyfin.Database.Implementations;
 15
 16/// <inheritdoc/>
 17/// <summary>
 18/// Initializes a new instance of the <see cref="JellyfinDbContext"/> class.
 19/// </summary>
 20/// <param name="options">The database context options.</param>
 21/// <param name="logger">Logger.</param>
 22/// <param name="jellyfinDatabaseProvider">The provider for the database engine specific operations.</param>
 23/// <param name="entityFrameworkCoreLocking">The locking behavior.</param>
 6524public class JellyfinDbContext(DbContextOptions<JellyfinDbContext> options, ILogger<JellyfinDbContext> logger, IJellyfin
 25{
 26    /// <summary>
 27    /// Gets the <see cref="DbSet{TEntity}"/> containing the access schedules.
 28    /// </summary>
 029    public DbSet<AccessSchedule> AccessSchedules => Set<AccessSchedule>();
 30
 31    /// <summary>
 32    /// Gets the <see cref="DbSet{TEntity}"/> containing the activity logs.
 33    /// </summary>
 3534    public DbSet<ActivityLog> ActivityLogs => Set<ActivityLog>();
 35
 36    /// <summary>
 37    /// Gets the <see cref="DbSet{TEntity}"/> containing the API keys.
 38    /// </summary>
 039    public DbSet<ApiKey> ApiKeys => Set<ApiKey>();
 40
 41    /// <summary>
 42    /// Gets the <see cref="DbSet{TEntity}"/> containing the devices.
 43    /// </summary>
 3644    public DbSet<Device> Devices => Set<Device>();
 45
 46    /// <summary>
 47    /// Gets the <see cref="DbSet{TEntity}"/> containing the device options.
 48    /// </summary>
 2149    public DbSet<DeviceOptions> DeviceOptions => Set<DeviceOptions>();
 50
 51    /// <summary>
 52    /// Gets the <see cref="DbSet{TEntity}"/> containing the display preferences.
 53    /// </summary>
 054    public DbSet<DisplayPreferences> DisplayPreferences => Set<DisplayPreferences>();
 55
 56    /// <summary>
 57    /// Gets the <see cref="DbSet{TEntity}"/> containing the image infos.
 58    /// </summary>
 059    public DbSet<ImageInfo> ImageInfos => Set<ImageInfo>();
 60
 61    /// <summary>
 62    /// Gets the <see cref="DbSet{TEntity}"/> containing the item display preferences.
 63    /// </summary>
 264    public DbSet<ItemDisplayPreferences> ItemDisplayPreferences => Set<ItemDisplayPreferences>();
 65
 66    /// <summary>
 67    /// Gets the <see cref="DbSet{TEntity}"/> containing the custom item display preferences.
 68    /// </summary>
 269    public DbSet<CustomItemDisplayPreferences> CustomItemDisplayPreferences => Set<CustomItemDisplayPreferences>();
 70
 71    /// <summary>
 72    /// Gets the <see cref="DbSet{TEntity}"/> containing the permissions.
 73    /// </summary>
 074    public DbSet<Permission> Permissions => Set<Permission>();
 75
 76    /// <summary>
 77    /// Gets the <see cref="DbSet{TEntity}"/> containing the preferences.
 78    /// </summary>
 079    public DbSet<Preference> Preferences => Set<Preference>();
 80
 81    /// <summary>
 82    /// Gets the <see cref="DbSet{TEntity}"/> containing the users.
 83    /// </summary>
 7584    public DbSet<User> Users => Set<User>();
 85
 86    /// <summary>
 87    /// Gets the <see cref="DbSet{TEntity}"/> containing the trickplay metadata.
 88    /// </summary>
 2389    public DbSet<TrickplayInfo> TrickplayInfos => Set<TrickplayInfo>();
 90
 91    /// <summary>
 92    /// Gets the <see cref="DbSet{TEntity}"/> containing the media segments.
 93    /// </summary>
 294    public DbSet<MediaSegment> MediaSegments => Set<MediaSegment>();
 95
 96    /// <summary>
 97    /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
 98    /// </summary>
 299    public DbSet<UserData> UserData => Set<UserData>();
 100
 101    /// <summary>
 102    /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
 103    /// </summary>
 190104    public DbSet<AncestorId> AncestorIds => Set<AncestorId>();
 105
 106    /// <summary>
 107    /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
 108    /// </summary>
 2109    public DbSet<AttachmentStreamInfo> AttachmentStreamInfos => Set<AttachmentStreamInfo>();
 110
 111    /// <summary>
 112    /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
 113    /// </summary>
 787114    public DbSet<BaseItemEntity> BaseItems => Set<BaseItemEntity>();
 115
 116    /// <summary>
 117    /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
 118    /// </summary>
 2119    public DbSet<Chapter> Chapters => Set<Chapter>();
 120
 121    /// <summary>
 122    /// Gets the <see cref="DbSet{TEntity}"/>.
 123    /// </summary>
 224124    public DbSet<ItemValue> ItemValues => Set<ItemValue>();
 125
 126    /// <summary>
 127    /// Gets the <see cref="DbSet{TEntity}"/>.
 128    /// </summary>
 233129    public DbSet<ItemValueMap> ItemValuesMap => Set<ItemValueMap>();
 130
 131    /// <summary>
 132    /// Gets the <see cref="DbSet{TEntity}"/>.
 133    /// </summary>
 2134    public DbSet<MediaStreamInfo> MediaStreamInfos => Set<MediaStreamInfo>();
 135
 136    /// <summary>
 137    /// Gets the <see cref="DbSet{TEntity}"/>.
 138    /// </summary>
 2139    public DbSet<People> Peoples => Set<People>();
 140
 141    /// <summary>
 142    /// Gets the <see cref="DbSet{TEntity}"/>.
 143    /// </summary>
 2144    public DbSet<PeopleBaseItemMap> PeopleBaseItemMap => Set<PeopleBaseItemMap>();
 145
 146    /// <summary>
 147    /// Gets the <see cref="DbSet{TEntity}"/> containing the referenced Providers with ids.
 148    /// </summary>
 46149    public DbSet<BaseItemProvider> BaseItemProviders => Set<BaseItemProvider>();
 150
 151    /// <summary>
 152    /// Gets the <see cref="DbSet{TEntity}"/>.
 153    /// </summary>
 2154    public DbSet<BaseItemImageInfo> BaseItemImageInfos => Set<BaseItemImageInfo>();
 155
 156    /// <summary>
 157    /// Gets the <see cref="DbSet{TEntity}"/>.
 158    /// </summary>
 2159    public DbSet<BaseItemMetadataField> BaseItemMetadataFields => Set<BaseItemMetadataField>();
 160
 161    /// <summary>
 162    /// Gets the <see cref="DbSet{TEntity}"/>.
 163    /// </summary>
 2164    public DbSet<BaseItemTrailerType> BaseItemTrailerTypes => Set<BaseItemTrailerType>();
 165
 166    /// <summary>
 167    /// Gets the <see cref="DbSet{TEntity}"/>.
 168    /// </summary>
 2169    public DbSet<KeyframeData> KeyframeData => Set<KeyframeData>();
 170
 171    /*public DbSet<Artwork> Artwork => Set<Artwork>();
 172
 173    public DbSet<Book> Books => Set<Book>();
 174
 175    public DbSet<BookMetadata> BookMetadata => Set<BookMetadata>();
 176
 177    public DbSet<Chapter> Chapters => Set<Chapter>();
 178
 179    public DbSet<Collection> Collections => Set<Collection>();
 180
 181    public DbSet<CollectionItem> CollectionItems => Set<CollectionItem>();
 182
 183    public DbSet<Company> Companies => Set<Company>();
 184
 185    public DbSet<CompanyMetadata> CompanyMetadata => Set<CompanyMetadata>();
 186
 187    public DbSet<CustomItem> CustomItems => Set<CustomItem>();
 188
 189    public DbSet<CustomItemMetadata> CustomItemMetadata => Set<CustomItemMetadata>();
 190
 191    public DbSet<Episode> Episodes => Set<Episode>();
 192
 193    public DbSet<EpisodeMetadata> EpisodeMetadata => Set<EpisodeMetadata>();
 194
 195    public DbSet<Genre> Genres => Set<Genre>();
 196
 197    public DbSet<Group> Groups => Set<Groups>();
 198
 199    public DbSet<Library> Libraries => Set<Library>();
 200
 201    public DbSet<LibraryItem> LibraryItems => Set<LibraryItems>();
 202
 203    public DbSet<LibraryRoot> LibraryRoot => Set<LibraryRoot>();
 204
 205    public DbSet<MediaFile> MediaFiles => Set<MediaFiles>();
 206
 207    public DbSet<MediaFileStream> MediaFileStream => Set<MediaFileStream>();
 208
 209    public DbSet<Metadata> Metadata => Set<Metadata>();
 210
 211    public DbSet<MetadataProvider> MetadataProviders => Set<MetadataProvider>();
 212
 213    public DbSet<MetadataProviderId> MetadataProviderIds => Set<MetadataProviderId>();
 214
 215    public DbSet<Movie> Movies => Set<Movie>();
 216
 217    public DbSet<MovieMetadata> MovieMetadata => Set<MovieMetadata>();
 218
 219    public DbSet<MusicAlbum> MusicAlbums => Set<MusicAlbum>();
 220
 221    public DbSet<MusicAlbumMetadata> MusicAlbumMetadata => Set<MusicAlbumMetadata>();
 222
 223    public DbSet<Person> People => Set<Person>();
 224
 225    public DbSet<PersonRole> PersonRoles => Set<PersonRole>();
 226
 227    public DbSet<Photo> Photo => Set<Photo>();
 228
 229    public DbSet<PhotoMetadata> PhotoMetadata => Set<PhotoMetadata>();
 230
 231    public DbSet<ProviderMapping> ProviderMappings => Set<ProviderMapping>();
 232
 233    public DbSet<Rating> Ratings => Set<Rating>();
 234
 235    /// <summary>
 236    /// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to
 237    /// store review ratings, not age ratings.
 238    /// </summary>
 239    public DbSet<RatingSource> RatingSources => Set<RatingSource>();
 240
 241    public DbSet<Release> Releases => Set<Release>();
 242
 243    public DbSet<Season> Seasons => Set<Season>();
 244
 245    public DbSet<SeasonMetadata> SeasonMetadata => Set<SeasonMetadata>();
 246
 247    public DbSet<Series> Series => Set<Series>();
 248
 249    public DbSet<SeriesMetadata> SeriesMetadata => Set<SeriesMetadata();
 250
 251    public DbSet<Track> Tracks => Set<Track>();
 252
 253    public DbSet<TrackMetadata> TrackMetadata => Set<TrackMetadata>();*/
 254
 255    /// <inheritdoc/>
 256    public override async Task<int> SaveChangesAsync(
 257        bool acceptAllChangesOnSuccess,
 258        CancellationToken cancellationToken = default)
 259    {
 260        HandleConcurrencyToken();
 261
 262        try
 263        {
 264            var result = -1;
 265            await entityFrameworkCoreLocking.OnSaveChangesAsync(this, async () =>
 266            {
 267                result = await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken).ConfigureAwait(false)
 268            }).ConfigureAwait(false);
 269            return result;
 270        }
 271        catch (Exception e)
 272        {
 273            logger.LogError(e, "Error trying to save changes.");
 274            throw;
 275        }
 276    }
 277
 278    /// <inheritdoc/>
 279    public override int SaveChanges(bool acceptAllChangesOnSuccess) // SaveChanges(bool) is beeing called by SaveChanges
 280    {
 383281        HandleConcurrencyToken();
 282
 283        try
 284        {
 383285            var result = -1;
 383286            entityFrameworkCoreLocking.OnSaveChanges(this, () =>
 383287            {
 383288                result = base.SaveChanges(acceptAllChangesOnSuccess);
 383289            });
 383290            return result;
 291        }
 0292        catch (Exception e)
 293        {
 0294            logger.LogError(e, "Error trying to save changes.");
 0295            throw;
 296        }
 383297    }
 298
 299    private void HandleConcurrencyToken()
 300    {
 2380301        foreach (var saveEntity in ChangeTracker.Entries()
 468302                     .Where(e => e.State == EntityState.Modified)
 468303                     .Select(entry => entry.Entity)
 468304                     .OfType<IHasConcurrencyToken>())
 305        {
 722306            saveEntity.OnSavingChanges();
 307        }
 468308    }
 309
 310    /// <inheritdoc />
 311    protected override void OnModelCreating(ModelBuilder modelBuilder)
 312    {
 2313        jellyfinDatabaseProvider.OnModelCreating(modelBuilder);
 2314        base.OnModelCreating(modelBuilder);
 315
 316        // Configuration for each entity is in its own class inside 'ModelConfiguration'.
 2317        modelBuilder.ApplyConfigurationsFromAssembly(typeof(JellyfinDbContext).Assembly);
 2318    }
 319
 320    /// <inheritdoc />
 321    protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
 322    {
 2323        jellyfinDatabaseProvider.ConfigureConventions(configurationBuilder);
 2324        base.ConfigureConventions(configurationBuilder);
 2325    }
 326}