diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs index 2ab08fd8d3..121d395ba3 100644 --- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs +++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs @@ -130,8 +130,8 @@ namespace MediaBrowser.Api.UserLibrary if (request is GetAlbumArtists) { return items + .Where(i => !i.IsFolder) .OfType() - .Where(i => !(i is MusicAlbum)) .SelectMany(i => i.AlbumArtists) .Distinct(StringComparer.OrdinalIgnoreCase) .Select(name => @@ -150,8 +150,8 @@ namespace MediaBrowser.Api.UserLibrary } return items + .Where(i => !i.IsFolder) .OfType() - .Where(i => !(i is MusicAlbum)) .SelectMany(i => i.AllArtists) .Distinct(StringComparer.OrdinalIgnoreCase) .Select(name => diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 15b1f6dba4..9b5ef3a981 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -169,8 +169,6 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "ExcludeLocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string ExcludeLocationTypes { get; set; } - public bool IncludeIndexContainers { get; set; } - [ApiMember(Name = "IsMissing", Description = "Optional filter by items that are missing episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool? IsMissing { get; set; } @@ -396,52 +394,29 @@ namespace MediaBrowser.Api.UserLibrary else if (request.Recursive) { - if (user == null) - { - items = ((Folder)item).GetRecursiveChildren(); + var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); - items = _libraryManager.ReplaceVideosWithPrimaryVersions(items); - } - else - { - var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)); - - return new Tuple, bool>(result, true); - } + return new Tuple, bool>(result, true); } else { if (user == null) { - items = ((Folder)item).Children; + var result = await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false); - items = _libraryManager.ReplaceVideosWithPrimaryVersions(items); + return new Tuple, bool>(result, true); } - else - { - var userRoot = item as UserRootFolder; - if (userRoot == null) - { - var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)); + var userRoot = item as UserRootFolder; - return new Tuple, bool>(result, true); - } + if (userRoot == null) + { + var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); - items = ((Folder)item).GetChildren(user, true); + return new Tuple, bool>(result, true); } - } - - if (request.IncludeIndexContainers) - { - var list = items.ToList(); - - var containers = list.Select(i => i.IndexContainer) - .Where(i => i != null); - - list.AddRange(containers); - items = list.Distinct(); + items = ((Folder)item).GetChildren(user, true); } return new Tuple, bool>(new QueryResult diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 50f33f5c06..e85dee354a 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -787,9 +787,20 @@ namespace MediaBrowser.Controller.Entities Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); - var items = query.Recursive - ? GetRecursiveChildren(user, filter) - : GetChildren(user, true).Where(filter); + IEnumerable items; + + if (query.User == null) + { + items = query.Recursive + ? GetRecursiveChildren(filter) + : Children.Where(filter); + } + else + { + items = query.Recursive + ? GetRecursiveChildren(user, filter) + : GetChildren(user, true).Where(filter); + } var result = PostFilterAndSort(items, query); diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml index b70cc10c2e..7062afc69a 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml @@ -26,8 +26,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml index 6250e0f0e6..9ff1ae8336 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml @@ -31,8 +31,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml index 0079b5f8d8..746b7f5c40 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml @@ -32,8 +32,6 @@ 10 true true - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml index d338b2b6d4..4a70e3d4c5 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml @@ -33,8 +33,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml index ba72f63065..471917a13f 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml @@ -32,8 +32,6 @@ 10 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml index 829ce70686..5fe441945b 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml @@ -30,8 +30,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml index 78ba4aba39..35775892c8 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml @@ -32,8 +32,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml index 88160b0ce3..36c5289298 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml @@ -33,8 +33,6 @@ 10 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml index d6acd65caf..0749dbeac7 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml @@ -26,8 +26,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml index bd113b9c7d..9e61df43ed 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml @@ -32,8 +32,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml index 3104f5c688..91aa767bee 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml @@ -32,8 +32,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml index 57a32607ed..a6ea108408 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml @@ -34,8 +34,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml index b7325c53ce..0c3bdc4c5f 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml @@ -34,8 +34,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml index 59157baddd..0269c05c16 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml @@ -34,8 +34,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml index d2d9c181ff..9aa614faae 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml @@ -34,8 +34,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml index 7b3d95b9d8..231db2091f 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml @@ -34,8 +34,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml index 454dabe5d4..153b66be81 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml @@ -34,8 +34,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml index 2829bfb473..d51669cfb8 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml @@ -33,8 +33,6 @@ 5 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index 76e4a6c31f..96b728bdc1 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -33,8 +33,6 @@ 40 true true - false - false true diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml index c8c0a52024..063cebebc3 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml @@ -33,8 +33,6 @@ 40 false false - false - false false diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml index 7a8f3a09d4..de7c03c481 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml @@ -32,8 +32,6 @@ 0 false false - false - false false diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 03802fc28f..8b489453ec 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -41,7 +41,7 @@ namespace MediaBrowser.Model.ApiClient /// Occurs when [authenticated]. /// event EventHandler> Authenticated; - + /// /// Gets the API URL. /// @@ -201,7 +201,7 @@ namespace MediaBrowser.Model.ApiClient /// The cancellation token. /// Task<HttpResponse>. Task GetResponse(string url, CancellationToken cancellationToken = default(CancellationToken)); - + /// /// Updates the user configuration. /// @@ -225,7 +225,7 @@ namespace MediaBrowser.Model.ApiClient /// The query. /// Task<QueryResult<BaseItemDto>>. Task GetLatestItems(LatestItemsQuery query); - + /// /// Gets the intros async. /// @@ -324,7 +324,7 @@ namespace MediaBrowser.Model.ApiClient /// The cancellation token. /// Task<ItemsResult>. Task GetUserViews(string userId, CancellationToken cancellationToken = default(CancellationToken)); - + /// /// Gets the instant mix from song async. /// @@ -563,7 +563,7 @@ namespace MediaBrowser.Model.ApiClient /// The identifier. /// Task<UserDto>. Task GetOfflineUserAsync(string id); - + /// /// Gets the parental ratings async. /// @@ -761,7 +761,7 @@ namespace MediaBrowser.Model.ApiClient /// The password. /// Task. /// userId - Task AuthenticateUserAsync(string username, + Task AuthenticateUserAsync(string username, string password); /// @@ -874,7 +874,7 @@ namespace MediaBrowser.Model.ApiClient /// The access token. /// The user identifier. void SetAuthenticationInfo(string accessToken, string userId); - + /// /// Sets the authentication information. /// @@ -921,7 +921,7 @@ namespace MediaBrowser.Model.ApiClient /// /// Task. Task StopReceivingSyncJobsUpdates(); - + /// /// Starts the receiving session updates. /// @@ -934,7 +934,7 @@ namespace MediaBrowser.Model.ApiClient /// /// Task. Task StopReceivingSessionUpdates(); - + /// /// Gets the image URL. /// @@ -1378,7 +1378,7 @@ namespace MediaBrowser.Model.ApiClient /// The file. /// The cancellation token. /// Task. - Task UploadFile(Stream stream, + Task UploadFile(Stream stream, LocalFileInfo file, CancellationToken cancellationToken); @@ -1439,7 +1439,7 @@ namespace MediaBrowser.Model.ApiClient /// The cancellation token. /// Task<Stream>. Task GetSyncJobItemAdditionalFile(string id, string name, CancellationToken cancellationToken); - + /// /// Opens the web socket. /// @@ -1503,5 +1503,14 @@ namespace MediaBrowser.Model.ApiClient /// The identifier. /// Task. Task EnableCancelledSyncJobItem(string id); + /// + /// Gets the synchronize options. + /// + /// The user identifier. + /// The item ids. + /// The parent identifier. + /// The category. + /// Task<SyncOptions>. + Task GetSyncOptions(IEnumerable itemIds, string userId, string parentId = null, SyncCategory? category = null); } } \ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs index dd6dad2610..cddfd89559 100644 --- a/MediaBrowser.Model/Dlna/AudioOptions.cs +++ b/MediaBrowser.Model/Dlna/AudioOptions.cs @@ -47,6 +47,17 @@ namespace MediaBrowser.Model.Dlna /// The audio transcoding bitrate. public int? AudioTranscodingBitrate { get; set; } + /// + /// Gets or sets a value indicating whether [supports direct remote content]. + /// + /// true if [supports direct remote content]; otherwise, false. + public bool SupportsDirectRemoteContent { get; set; } + /// + /// Gets or sets a value indicating whether [supports custom HTTP headers]. + /// + /// true if [supports custom HTTP headers]; otherwise, false. + public bool SupportsCustomHttpHeaders { get; set; } + /// /// Gets the maximum bitrate. /// diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 3bbef28c57..4b137a268c 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -76,8 +76,6 @@ namespace MediaBrowser.Model.Dlna public bool RequiresPlainVideoItems { get; set; } public bool RequiresPlainFolders { get; set; } - public bool SupportsDirectRemoteContent { get; set; } - public bool SupportsCustomHttpHeaders { get; set; } public bool EnableMSMediaReceiverRegistrar { get; set; } public XmlAttribute[] XmlRootAttributes { get; set; } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 8b929425a1..6076637b44 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -258,7 +258,7 @@ namespace MediaBrowser.Model.Dlna if (IsEligibleForDirectPlay(item, maxBitrateSetting, subtitleStream, options)) { // See if it can be direct played - var directPlay = GetVideoDirectPlayProfile(options.Profile, item, videoStream, audioStream); + var directPlay = GetVideoDirectPlayProfile(options, options.Profile, item, videoStream, audioStream); if (directPlay != null) { @@ -380,7 +380,8 @@ namespace MediaBrowser.Model.Dlna return 128000; } - private PlayMethod? GetVideoDirectPlayProfile(DeviceProfile profile, + private PlayMethod? GetVideoDirectPlayProfile(VideoOptions options, + DeviceProfile profile, MediaSourceInfo mediaSource, MediaStream videoStream, MediaStream audioStream) @@ -504,12 +505,12 @@ namespace MediaBrowser.Model.Dlna if (mediaSource.Protocol == MediaProtocol.Http) { - if (!profile.SupportsDirectRemoteContent) + if (!options.SupportsDirectRemoteContent) { return null; } - if (mediaSource.RequiredHttpHeaders.Count > 0 && !profile.SupportsCustomHttpHeaders) + if (mediaSource.RequiredHttpHeaders.Count > 0 && !options.SupportsCustomHttpHeaders) { return null; } diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs index 77953ee43b..3903c62b1e 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs @@ -74,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security ValidateUserAccess(user, request, authAttribtues, auth); } - var info = (AuthenticationInfo)request.Items["OriginalAuthenticationInfo"]; + var info = GetTokenInfo(request); if (!IsExemptFromRoles(auth, authAttribtues, info)) { @@ -199,6 +199,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security } } + private AuthenticationInfo GetTokenInfo(IServiceRequest request) + { + object info; + request.Items.TryGetValue("OriginalAuthenticationInfo", out info); + return info as AuthenticationInfo; + } + private bool IsValidConnectKey(string token) { if (string.IsNullOrEmpty(token)) @@ -216,7 +223,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security throw new SecurityException("Access token is invalid or expired."); } - var info = (AuthenticationInfo)request.Items["OriginalAuthenticationInfo"]; + var info = GetTokenInfo(request); if (info == null) { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 99c59abc5d..3ffe31ed18 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -203,6 +203,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cancellationToken.ThrowIfCancellationRequested(); + CheckDisposed(); + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); IDbTransaction transaction = null; @@ -271,6 +273,8 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("id"); } + CheckDisposed(); + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = "select type,data from TypedBaseItems where guid = @guid"; @@ -355,6 +359,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// id public IEnumerable GetChapters(Guid id) { + CheckDisposed(); return _chapterRepository.GetChapters(id); } @@ -367,6 +372,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// id public ChapterInfo GetChapter(Guid id, int index) { + CheckDisposed(); return _chapterRepository.GetChapter(id, index); } @@ -386,6 +392,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// public Task SaveChapters(Guid id, IEnumerable chapters, CancellationToken cancellationToken) { + CheckDisposed(); return _chapterRepository.SaveChapters(id, chapters, cancellationToken); } @@ -400,6 +407,15 @@ namespace MediaBrowser.Server.Implementations.Persistence private readonly object _disposeLock = new object(); + private bool _disposed; + private void CheckDisposed() + { + if (_disposed) + { + throw new ObjectDisposedException(GetType().Name + " has been disposed and cannot be accessed."); + } + } + /// /// Releases unmanaged and - optionally - managed resources. /// @@ -408,6 +424,8 @@ namespace MediaBrowser.Server.Implementations.Persistence { if (dispose) { + _disposed = true; + try { lock (_disposeLock) @@ -456,6 +474,8 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("parentId"); } + CheckDisposed(); + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = "select ItemId from ChildrenIds where ParentId = @ParentId"; @@ -479,6 +499,8 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("parentId"); } + CheckDisposed(); + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = "select type,data from TypedBaseItems where guid in (select ItemId from ChildrenIds where ParentId = @ParentId)"; @@ -507,6 +529,8 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("type"); } + CheckDisposed(); + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = "select type,data from TypedBaseItems where type = @type"; @@ -535,6 +559,8 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("id"); } + CheckDisposed(); + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); IDbTransaction transaction = null; @@ -598,6 +624,8 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("children"); } + CheckDisposed(); + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); IDbTransaction transaction = null; @@ -659,11 +687,13 @@ namespace MediaBrowser.Server.Implementations.Persistence public IEnumerable GetMediaStreams(MediaStreamQuery query) { + CheckDisposed(); return _mediaStreamsRepository.GetMediaStreams(query); } public Task SaveMediaStreams(Guid id, IEnumerable streams, CancellationToken cancellationToken) { + CheckDisposed(); return _mediaStreamsRepository.SaveMediaStreams(id, streams, cancellationToken); } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 5a07a41e9c..05d804cbb6 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -172,6 +172,8 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentNullException("id"); } + CheckDisposed(); + var guid = new Guid(id); if (guid == Guid.Empty) @@ -277,6 +279,8 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentNullException("job"); } + CheckDisposed(); + await _writeLock.WaitAsync().ConfigureAwait(false); IDbTransaction transaction = null; @@ -348,6 +352,8 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentNullException("id"); } + CheckDisposed(); + await _writeLock.WaitAsync().ConfigureAwait(false); IDbTransaction transaction = null; @@ -407,6 +413,8 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentNullException("query"); } + CheckDisposed(); + using (var cmd = _connection.CreateCommand()) { cmd.CommandText = BaseJobSelectText; @@ -491,6 +499,8 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentNullException("id"); } + CheckDisposed(); + var guid = new Guid(id); using (var cmd = _connection.CreateCommand()) @@ -618,6 +628,8 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentNullException("jobItem"); } + CheckDisposed(); + await _writeLock.WaitAsync().ConfigureAwait(false); IDbTransaction transaction = null; @@ -764,6 +776,15 @@ namespace MediaBrowser.Server.Implementations.Sync GC.SuppressFinalize(this); } + private bool _disposed; + private void CheckDisposed() + { + if (_disposed) + { + throw new ObjectDisposedException(GetType().Name + " has been disposed and cannot be accessed."); + } + } + private readonly object _disposeLock = new object(); /// @@ -774,6 +795,8 @@ namespace MediaBrowser.Server.Implementations.Sync { if (dispose) { + _disposed = true; + try { lock (_disposeLock)