JellyfinDbContext.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. using System;
  2. using System.Linq;
  3. using Jellyfin.Data.Entities;
  4. using Jellyfin.Data.Entities.Security;
  5. using Jellyfin.Data.Interfaces;
  6. using Microsoft.EntityFrameworkCore;
  7. using Microsoft.EntityFrameworkCore.Metadata.Builders;
  8. using Microsoft.EntityFrameworkCore.Metadata.Conventions;
  9. using Microsoft.Extensions.Logging;
  10. namespace Jellyfin.Server.Implementations;
  11. /// <inheritdoc/>
  12. /// <summary>
  13. /// Initializes a new instance of the <see cref="JellyfinDbContext"/> class.
  14. /// </summary>
  15. /// <param name="options">The database context options.</param>
  16. /// <param name="logger">Logger.</param>
  17. public class JellyfinDbContext(DbContextOptions<JellyfinDbContext> options, ILogger<JellyfinDbContext> logger) : DbContext(options)
  18. {
  19. /// <summary>
  20. /// Gets the <see cref="DbSet{TEntity}"/> containing the access schedules.
  21. /// </summary>
  22. public DbSet<AccessSchedule> AccessSchedules => Set<AccessSchedule>();
  23. /// <summary>
  24. /// Gets the <see cref="DbSet{TEntity}"/> containing the activity logs.
  25. /// </summary>
  26. public DbSet<ActivityLog> ActivityLogs => Set<ActivityLog>();
  27. /// <summary>
  28. /// Gets the <see cref="DbSet{TEntity}"/> containing the API keys.
  29. /// </summary>
  30. public DbSet<ApiKey> ApiKeys => Set<ApiKey>();
  31. /// <summary>
  32. /// Gets the <see cref="DbSet{TEntity}"/> containing the devices.
  33. /// </summary>
  34. public DbSet<Device> Devices => Set<Device>();
  35. /// <summary>
  36. /// Gets the <see cref="DbSet{TEntity}"/> containing the device options.
  37. /// </summary>
  38. public DbSet<DeviceOptions> DeviceOptions => Set<DeviceOptions>();
  39. /// <summary>
  40. /// Gets the <see cref="DbSet{TEntity}"/> containing the display preferences.
  41. /// </summary>
  42. public DbSet<DisplayPreferences> DisplayPreferences => Set<DisplayPreferences>();
  43. /// <summary>
  44. /// Gets the <see cref="DbSet{TEntity}"/> containing the image infos.
  45. /// </summary>
  46. public DbSet<ImageInfo> ImageInfos => Set<ImageInfo>();
  47. /// <summary>
  48. /// Gets the <see cref="DbSet{TEntity}"/> containing the item display preferences.
  49. /// </summary>
  50. public DbSet<ItemDisplayPreferences> ItemDisplayPreferences => Set<ItemDisplayPreferences>();
  51. /// <summary>
  52. /// Gets the <see cref="DbSet{TEntity}"/> containing the custom item display preferences.
  53. /// </summary>
  54. public DbSet<CustomItemDisplayPreferences> CustomItemDisplayPreferences => Set<CustomItemDisplayPreferences>();
  55. /// <summary>
  56. /// Gets the <see cref="DbSet{TEntity}"/> containing the permissions.
  57. /// </summary>
  58. public DbSet<Permission> Permissions => Set<Permission>();
  59. /// <summary>
  60. /// Gets the <see cref="DbSet{TEntity}"/> containing the preferences.
  61. /// </summary>
  62. public DbSet<Preference> Preferences => Set<Preference>();
  63. /// <summary>
  64. /// Gets the <see cref="DbSet{TEntity}"/> containing the users.
  65. /// </summary>
  66. public DbSet<User> Users => Set<User>();
  67. /// <summary>
  68. /// Gets the <see cref="DbSet{TEntity}"/> containing the trickplay metadata.
  69. /// </summary>
  70. public DbSet<TrickplayInfo> TrickplayInfos => Set<TrickplayInfo>();
  71. /// <summary>
  72. /// Gets the <see cref="DbSet{TEntity}"/> containing the media segments.
  73. /// </summary>
  74. public DbSet<MediaSegment> MediaSegments => Set<MediaSegment>();
  75. /// <summary>
  76. /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
  77. /// </summary>
  78. public DbSet<UserData> UserData => Set<UserData>();
  79. /// <summary>
  80. /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
  81. /// </summary>
  82. public DbSet<AncestorId> AncestorIds => Set<AncestorId>();
  83. /// <summary>
  84. /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
  85. /// </summary>
  86. public DbSet<AttachmentStreamInfo> AttachmentStreamInfos => Set<AttachmentStreamInfo>();
  87. /// <summary>
  88. /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
  89. /// </summary>
  90. public DbSet<BaseItemEntity> BaseItems => Set<BaseItemEntity>();
  91. /// <summary>
  92. /// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
  93. /// </summary>
  94. public DbSet<Chapter> Chapters => Set<Chapter>();
  95. /// <summary>
  96. /// Gets the <see cref="DbSet{TEntity}"/>.
  97. /// </summary>
  98. public DbSet<ItemValue> ItemValues => Set<ItemValue>();
  99. /// <summary>
  100. /// Gets the <see cref="DbSet{TEntity}"/>.
  101. /// </summary>
  102. public DbSet<ItemValueMap> ItemValuesMap => Set<ItemValueMap>();
  103. /// <summary>
  104. /// Gets the <see cref="DbSet{TEntity}"/>.
  105. /// </summary>
  106. public DbSet<MediaStreamInfo> MediaStreamInfos => Set<MediaStreamInfo>();
  107. /// <summary>
  108. /// Gets the <see cref="DbSet{TEntity}"/>.
  109. /// </summary>
  110. public DbSet<People> Peoples => Set<People>();
  111. /// <summary>
  112. /// Gets the <see cref="DbSet{TEntity}"/>.
  113. /// </summary>
  114. public DbSet<PeopleBaseItemMap> PeopleBaseItemMap => Set<PeopleBaseItemMap>();
  115. /// <summary>
  116. /// Gets the <see cref="DbSet{TEntity}"/> containing the referenced Providers with ids.
  117. /// </summary>
  118. public DbSet<BaseItemProvider> BaseItemProviders => Set<BaseItemProvider>();
  119. /// <summary>
  120. /// Gets the <see cref="DbSet{TEntity}"/>.
  121. /// </summary>
  122. public DbSet<BaseItemImageInfo> BaseItemImageInfos => Set<BaseItemImageInfo>();
  123. /// <summary>
  124. /// Gets the <see cref="DbSet{TEntity}"/>.
  125. /// </summary>
  126. public DbSet<BaseItemMetadataField> BaseItemMetadataFields => Set<BaseItemMetadataField>();
  127. /// <summary>
  128. /// Gets the <see cref="DbSet{TEntity}"/>.
  129. /// </summary>
  130. public DbSet<BaseItemTrailerType> BaseItemTrailerTypes => Set<BaseItemTrailerType>();
  131. /*public DbSet<Artwork> Artwork => Set<Artwork>();
  132. public DbSet<Book> Books => Set<Book>();
  133. public DbSet<BookMetadata> BookMetadata => Set<BookMetadata>();
  134. public DbSet<Chapter> Chapters => Set<Chapter>();
  135. public DbSet<Collection> Collections => Set<Collection>();
  136. public DbSet<CollectionItem> CollectionItems => Set<CollectionItem>();
  137. public DbSet<Company> Companies => Set<Company>();
  138. public DbSet<CompanyMetadata> CompanyMetadata => Set<CompanyMetadata>();
  139. public DbSet<CustomItem> CustomItems => Set<CustomItem>();
  140. public DbSet<CustomItemMetadata> CustomItemMetadata => Set<CustomItemMetadata>();
  141. public DbSet<Episode> Episodes => Set<Episode>();
  142. public DbSet<EpisodeMetadata> EpisodeMetadata => Set<EpisodeMetadata>();
  143. public DbSet<Genre> Genres => Set<Genre>();
  144. public DbSet<Group> Groups => Set<Groups>();
  145. public DbSet<Library> Libraries => Set<Library>();
  146. public DbSet<LibraryItem> LibraryItems => Set<LibraryItems>();
  147. public DbSet<LibraryRoot> LibraryRoot => Set<LibraryRoot>();
  148. public DbSet<MediaFile> MediaFiles => Set<MediaFiles>();
  149. public DbSet<MediaFileStream> MediaFileStream => Set<MediaFileStream>();
  150. public DbSet<Metadata> Metadata => Set<Metadata>();
  151. public DbSet<MetadataProvider> MetadataProviders => Set<MetadataProvider>();
  152. public DbSet<MetadataProviderId> MetadataProviderIds => Set<MetadataProviderId>();
  153. public DbSet<Movie> Movies => Set<Movie>();
  154. public DbSet<MovieMetadata> MovieMetadata => Set<MovieMetadata>();
  155. public DbSet<MusicAlbum> MusicAlbums => Set<MusicAlbum>();
  156. public DbSet<MusicAlbumMetadata> MusicAlbumMetadata => Set<MusicAlbumMetadata>();
  157. public DbSet<Person> People => Set<Person>();
  158. public DbSet<PersonRole> PersonRoles => Set<PersonRole>();
  159. public DbSet<Photo> Photo => Set<Photo>();
  160. public DbSet<PhotoMetadata> PhotoMetadata => Set<PhotoMetadata>();
  161. public DbSet<ProviderMapping> ProviderMappings => Set<ProviderMapping>();
  162. public DbSet<Rating> Ratings => Set<Rating>();
  163. /// <summary>
  164. /// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to
  165. /// store review ratings, not age ratings.
  166. /// </summary>
  167. public DbSet<RatingSource> RatingSources => Set<RatingSource>();
  168. public DbSet<Release> Releases => Set<Release>();
  169. public DbSet<Season> Seasons => Set<Season>();
  170. public DbSet<SeasonMetadata> SeasonMetadata => Set<SeasonMetadata>();
  171. public DbSet<Series> Series => Set<Series>();
  172. public DbSet<SeriesMetadata> SeriesMetadata => Set<SeriesMetadata();
  173. public DbSet<Track> Tracks => Set<Track>();
  174. public DbSet<TrackMetadata> TrackMetadata => Set<TrackMetadata>();*/
  175. /// <inheritdoc/>
  176. public override int SaveChanges()
  177. {
  178. foreach (var saveEntity in ChangeTracker.Entries()
  179. .Where(e => e.State == EntityState.Modified)
  180. .Select(entry => entry.Entity)
  181. .OfType<IHasConcurrencyToken>())
  182. {
  183. saveEntity.OnSavingChanges();
  184. }
  185. try
  186. {
  187. return base.SaveChanges();
  188. }
  189. catch (Exception e)
  190. {
  191. logger.LogError(e, "Error trying to save changes.");
  192. throw;
  193. }
  194. }
  195. /// <inheritdoc />
  196. protected override void OnModelCreating(ModelBuilder modelBuilder)
  197. {
  198. modelBuilder.SetDefaultDateTimeKind(DateTimeKind.Utc);
  199. base.OnModelCreating(modelBuilder);
  200. // Configuration for each entity is in its own class inside 'ModelConfiguration'.
  201. modelBuilder.ApplyConfigurationsFromAssembly(typeof(JellyfinDbContext).Assembly);
  202. }
  203. /// <inheritdoc/>
  204. protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
  205. {
  206. configurationBuilder.Conventions.Add(_ => new DoNotUseReturningClauseConvention());
  207. }
  208. private class DoNotUseReturningClauseConvention : IModelFinalizingConvention
  209. {
  210. public void ProcessModelFinalizing(
  211. IConventionModelBuilder modelBuilder,
  212. IConventionContext<IConventionModelBuilder> context)
  213. {
  214. foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
  215. {
  216. entityType.UseSqlReturningClause(false);
  217. }
  218. }
  219. }
  220. }