From bfc8facc60f919f8455d4c6c7f48a4eca17f2812 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Apr 2016 01:05:34 -0400 Subject: fixes #1261 - Sync quality cannot be changed --- .../Sync/SyncJobProcessor.cs | 45 +++++++++------------- .../Sync/SyncManager.cs | 8 ++-- .../Sync/SyncRepository.cs | 2 +- 3 files changed, 23 insertions(+), 32 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 01334c121d..33874b4d4a 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -149,16 +149,6 @@ namespace MediaBrowser.Server.Implementations.Sync { var job = _syncRepo.GetJob(id); - return UpdateJobStatus(job); - } - - private Task UpdateJobStatus(SyncJob job) - { - if (job == null) - { - throw new ArgumentNullException("job"); - } - var result = _syncManager.GetJobItems(new SyncJobItemQuery { JobId = job.Id, @@ -476,14 +466,12 @@ namespace MediaBrowser.Server.Implementations.Sync if (jobItem != null) { - var job = _syncRepo.GetJob(jobItem.JobId); if (jobItem.Status != SyncJobItemStatus.Cancelled) { - await ProcessJobItem(job, jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); + await ProcessJobItem(jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); } - job = _syncRepo.GetJob(jobItem.JobId); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } numComplete++; @@ -493,7 +481,7 @@ namespace MediaBrowser.Server.Implementations.Sync } } - private async Task ProcessJobItem(SyncJob job, SyncJobItem jobItem, bool enableConversion, IProgress progress, CancellationToken cancellationToken) + private async Task ProcessJobItem(SyncJobItem jobItem, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { var item = _libraryManager.GetItemById(jobItem.ItemId); if (item == null) @@ -507,6 +495,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 0; var syncOptions = _config.GetSyncOptions(); + var job = _syncManager.GetJob(jobItem.JobId); var user = _userManager.GetUserById(job.UserId); if (user == null) { @@ -521,7 +510,7 @@ namespace MediaBrowser.Server.Implementations.Sync { AddMetadata = false, ItemId = jobItem.ItemId, - TargetId = job.TargetId, + TargetId = jobItem.TargetId, Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring } }); @@ -531,7 +520,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (duplicateJobItems.Count > 0) { - var syncProvider = _syncManager.GetSyncProvider(jobItem, job) as IHasDuplicateCheck; + var syncProvider = _syncManager.GetSyncProvider(jobItem) as IHasDuplicateCheck; if (!duplicateJobItems.Any(i => AllowDuplicateJobItem(syncProvider, i, jobItem))) { @@ -545,12 +534,12 @@ namespace MediaBrowser.Server.Implementations.Sync var video = item as Video; if (video != null) { - await Sync(jobItem, job, video, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, video, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); } else if (item is Audio) { - await Sync(jobItem, job, (Audio)item, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, (Audio)item, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); } else if (item is Photo) @@ -574,8 +563,9 @@ namespace MediaBrowser.Server.Implementations.Sync return true; } - private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) { + var job = _syncManager.GetJob(jobItem.JobId); var jobOptions = _syncManager.GetVideoOptions(jobItem, job); var conversionOptions = new VideoOptions { @@ -616,7 +606,7 @@ namespace MediaBrowser.Server.Implementations.Sync { // Save the job item now since conversion could take a while await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); try { @@ -630,7 +620,7 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Progress = pct / 2; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } }); @@ -642,7 +632,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); - _syncManager.OnConversionComplete(jobItem, job); + _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) { @@ -775,8 +765,9 @@ namespace MediaBrowser.Server.Implementations.Sync private const int DatabaseProgressUpdateIntervalSeconds = 2; - private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Audio item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) { + var job = _syncManager.GetJob(jobItem.JobId); var jobOptions = _syncManager.GetAudioOptions(jobItem, job); var conversionOptions = new AudioOptions { @@ -803,7 +794,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Status = SyncJobItemStatus.Converting; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); try { @@ -817,7 +808,7 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Progress = pct / 2; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } }); @@ -828,7 +819,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); - _syncManager.OnConversionComplete(jobItem, job); + _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) { diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 2effad2f71..044c8b93a7 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1117,7 +1117,7 @@ namespace MediaBrowser.Server.Implementations.Sync public SyncJobOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job) { var options = GetSyncJobOptions(jobItem.TargetId, null, null); - + if (job.Bitrate.HasValue) { options.DeviceProfile.MaxStaticBitrate = job.Bitrate.Value; @@ -1126,7 +1126,7 @@ namespace MediaBrowser.Server.Implementations.Sync return options; } - public ISyncProvider GetSyncProvider(SyncJobItem jobItem, SyncJob job) + public ISyncProvider GetSyncProvider(SyncJobItem jobItem) { foreach (var provider in _providers) { @@ -1323,9 +1323,9 @@ namespace MediaBrowser.Server.Implementations.Sync return list; } - protected internal void OnConversionComplete(SyncJobItem item, SyncJob job) + protected internal void OnConversionComplete(SyncJobItem item) { - var syncProvider = GetSyncProvider(item, job); + var syncProvider = GetSyncProvider(item); if (syncProvider is AppSyncProvider) { return; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 39153526ab..464e8aa58e 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -104,7 +104,7 @@ namespace MediaBrowser.Server.Implementations.Sync // _updateJobCommand _updateJobCommand = _connection.CreateCommand(); - _updateJobCommand.CommandText = "update SyncJobs set TargetId=@TargetId,Name=@Name,Profile=@Profile,Quality=@Quality,Bitrate=@Bitrate,Status=@Status,Progress=@Progress,UserId=@UserId,ItemIds=@ItemIds,Category=@Category,ParentId=@ParentId,UnwatchedOnly=@UnwatchedOnly,ItemLimit=@ItemLimit,SyncNewContent=@SyncNewContent,DateCreated=@DateCreated,DateLastModified=@DateLastModified,ItemCount=@ItemCount where Id=@ID"; + _updateJobCommand.CommandText = "update SyncJobs set TargetId=@TargetId,Name=@Name,Profile=@Profile,Quality=@Quality,Bitrate=@Bitrate,Status=@Status,Progress=@Progress,UserId=@UserId,ItemIds=@ItemIds,Category=@Category,ParentId=@ParentId,UnwatchedOnly=@UnwatchedOnly,ItemLimit=@ItemLimit,SyncNewContent=@SyncNewContent,DateCreated=@DateCreated,DateLastModified=@DateLastModified,ItemCount=@ItemCount where Id=@Id"; _updateJobCommand.Parameters.Add(_updateJobCommand, "@Id"); _updateJobCommand.Parameters.Add(_updateJobCommand, "@TargetId"); -- cgit v1.2.3 From f7128c7f8f04a39272ec10c699f3a05dac1a8e67 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Apr 2016 16:24:53 -0400 Subject: resync media after changes --- MediaBrowser.Model/Sync/SyncJobItem.cs | 2 ++ .../Sync/SyncJobProcessor.cs | 6 ++++++ MediaBrowser.Server.Implementations/Sync/SyncManager.cs | 16 +++++++++++++++- .../Sync/SyncRepository.cs | 9 ++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs index 77464be58d..1c72ccd523 100644 --- a/MediaBrowser.Model/Sync/SyncJobItem.cs +++ b/MediaBrowser.Model/Sync/SyncJobItem.cs @@ -102,6 +102,8 @@ namespace MediaBrowser.Model.Sync /// The index of the job item. public int JobItemIndex { get; set; } + public long ItemDateModifiedTicks { get; set; } + public SyncJobItem() { AdditionalFiles = new List(); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 33874b4d4a..0bec528bb6 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -632,6 +632,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) @@ -668,6 +669,7 @@ namespace MediaBrowser.Server.Implementations.Sync throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol)); } + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; jobItem.MediaSource = mediaSource; } @@ -819,6 +821,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) @@ -855,6 +858,7 @@ namespace MediaBrowser.Server.Implementations.Sync throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol)); } + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; jobItem.MediaSource = mediaSource; } @@ -871,6 +875,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 50; jobItem.Status = SyncJobItemStatus.ReadyToTransfer; + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } @@ -880,6 +885,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 50; jobItem.Status = SyncJobItemStatus.ReadyToTransfer; + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 044c8b93a7..fe1a7fb28f 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -775,6 +775,13 @@ namespace MediaBrowser.Server.Implementations.Sync removeFromDevice = true; } } + else if (libraryItem != null && libraryItem.DateModified.Ticks != jobItem.ItemDateModifiedTicks && jobItem.ItemDateModifiedTicks > 0) + { + _logger.Info("Setting status to Queued for {0} because the media has been modified since the original sync.", jobItem.ItemId); + jobItem.Status = SyncJobItemStatus.Queued; + jobItem.Progress = 0; + requiresSaving = true; + } } else { @@ -881,6 +888,13 @@ namespace MediaBrowser.Server.Implementations.Sync removeFromDevice = true; } } + else if (libraryItem != null && libraryItem.DateModified.Ticks != jobItem.ItemDateModifiedTicks && jobItem.ItemDateModifiedTicks > 0) + { + _logger.Info("Setting status to Queued for {0} because the media has been modified since the original sync.", jobItem.ItemId); + jobItem.Status = SyncJobItemStatus.Queued; + jobItem.Progress = 0; + requiresSaving = true; + } } else { @@ -1117,7 +1131,7 @@ namespace MediaBrowser.Server.Implementations.Sync public SyncJobOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job) { var options = GetSyncJobOptions(jobItem.TargetId, null, null); - + if (job.Bitrate.HasValue) { options.DeviceProfile.MaxStaticBitrate = job.Bitrate.Value; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 464e8aa58e..249c4212e3 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -50,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Profile TEXT, Quality TEXT, Bitrate INT, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", - "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT)", + "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT, ItemDateModifiedTicks BIGINT)", "create index if not exists idx_SyncJobItems on SyncJobs(Id)", //pragmas @@ -63,6 +63,7 @@ namespace MediaBrowser.Server.Implementations.Sync _connection.AddColumn(Logger, "SyncJobs", "Profile", "TEXT"); _connection.AddColumn(Logger, "SyncJobs", "Bitrate", "INT"); + _connection.AddColumn(Logger, "SyncJobItems", "ItemDateModifiedTicks", "BIGINT"); PrepareStatements(); } @@ -678,6 +679,7 @@ namespace MediaBrowser.Server.Implementations.Sync cmd.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); cmd.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; cmd.GetParameter(index++).Value = jobItem.JobItemIndex; + cmd.GetParameter(index++).Value = jobItem.ItemDateModifiedTicks; cmd.Transaction = transaction; @@ -782,6 +784,11 @@ namespace MediaBrowser.Server.Implementations.Sync info.IsMarkedForRemoval = reader.GetBoolean(13); info.JobItemIndex = reader.GetInt32(14); + if (!reader.IsDBNull(15)) + { + info.ItemDateModifiedTicks = reader.GetInt64(15); + } + return info; } -- cgit v1.2.3 From d54f791159ecdf82e80c54ac663614eedf57f959 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Apr 2016 16:29:27 -0400 Subject: update resync --- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 5 +++++ MediaBrowser.Server.Implementations/Sync/SyncRepository.cs | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 0bec528bb6..10b8727533 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -149,6 +149,11 @@ namespace MediaBrowser.Server.Implementations.Sync { var job = _syncRepo.GetJob(id); + if (job == null) + { + return Task.FromResult(true); + } + var result = _syncManager.GetJobItems(new SyncJobItemQuery { JobId = job.Id, diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 249c4212e3..965c081ebd 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -128,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.Sync // _insertJobItemCommand _insertJobItemCommand = _connection.CreateCommand(); - _insertJobItemCommand.CommandText = "insert into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex)"; + _insertJobItemCommand.CommandText = "insert into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex, ItemDateModifiedTicks) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex, @ItemDateModifiedTicks)"; _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@Id"); _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemId"); @@ -145,10 +145,11 @@ namespace MediaBrowser.Server.Implementations.Sync _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@MediaSource"); _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@IsMarkedForRemoval"); _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@JobItemIndex"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemDateModifiedTicks"); // _updateJobItemCommand _updateJobItemCommand = _connection.CreateCommand(); - _updateJobItemCommand.CommandText = "update SyncJobItems set ItemId=@ItemId,ItemName=@ItemName,MediaSourceId=@MediaSourceId,JobId=@JobId,TemporaryPath=@TemporaryPath,OutputPath=@OutputPath,Status=@Status,TargetId=@TargetId,DateCreated=@DateCreated,Progress=@Progress,AdditionalFiles=@AdditionalFiles,MediaSource=@MediaSource,IsMarkedForRemoval=@IsMarkedForRemoval,JobItemIndex=@JobItemIndex where Id=@Id"; + _updateJobItemCommand.CommandText = "update SyncJobItems set ItemId=@ItemId,ItemName=@ItemName,MediaSourceId=@MediaSourceId,JobId=@JobId,TemporaryPath=@TemporaryPath,OutputPath=@OutputPath,Status=@Status,TargetId=@TargetId,DateCreated=@DateCreated,Progress=@Progress,AdditionalFiles=@AdditionalFiles,MediaSource=@MediaSource,IsMarkedForRemoval=@IsMarkedForRemoval,JobItemIndex=@JobItemIndex,ItemDateModifiedTicks=@ItemDateModifiedTicks where Id=@Id"; _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@Id"); _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemId"); @@ -165,10 +166,11 @@ namespace MediaBrowser.Server.Implementations.Sync _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@MediaSource"); _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@IsMarkedForRemoval"); _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@JobItemIndex"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemDateModifiedTicks"); } private const string BaseJobSelectText = "select Id, TargetId, Name, Profile, Quality, Bitrate, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; - private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex from SyncJobItems"; + private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex, ItemDateModifiedTicks from SyncJobItems"; public SyncJob GetJob(string id) { -- cgit v1.2.3 From a15a762ba114683ffcc4c6aab5974d24f8f32c02 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Apr 2016 15:16:43 -0400 Subject: fixes #1484 - (Feature request) Make emby choose output stream based on ffmpeg config --- MediaBrowser.Api/Playback/MediaInfoService.cs | 7 ++++-- .../MediaEncoding/IMediaEncoder.cs | 3 ++- .../ContentDirectory/ContentDirectory.cs | 8 +++++-- .../ContentDirectory/ControlHandler.cs | 7 ++++-- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 9 +++++--- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 8 +++++-- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 11 +++++---- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 8 +++++-- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 26 ++++++++++++++++++++-- MediaBrowser.Model/Dlna/ILocalPlayer.cs | 13 +++++++++++ MediaBrowser.Model/Dlna/StreamBuilder.cs | 23 +++++++++++++++---- .../Sync/SyncJobProcessor.cs | 4 ++-- .../ApplicationHost.cs | 2 +- .../FFMpeg/FFmpegValidator.cs | 4 +++- 14 files changed, 105 insertions(+), 28 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index ffe7c50c8e..2d9cc40c0a 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -15,6 +15,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Api.Playback { @@ -66,14 +67,16 @@ namespace MediaBrowser.Api.Playback private readonly ILibraryManager _libraryManager; private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; + private readonly IMediaEncoder _mediaEncoder; - public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager) + public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager, IMediaEncoder mediaEncoder) { _mediaSourceManager = mediaSourceManager; _deviceManager = deviceManager; _libraryManager = libraryManager; _config = config; _networkManager = networkManager; + _mediaEncoder = mediaEncoder; } public object Get(GetBitrateTestBytes request) @@ -241,7 +244,7 @@ namespace MediaBrowser.Api.Playback int? subtitleStreamIndex, string playSessionId) { - var streamBuilder = new StreamBuilder(Logger); + var streamBuilder = new StreamBuilder(_mediaEncoder, Logger); var options = new VideoOptions { diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index d2feb41169..7c3959f6e8 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -4,13 +4,14 @@ using System; using System.IO; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Dlna; namespace MediaBrowser.Controller.MediaEncoding { /// /// Interface IMediaEncoder /// - public interface IMediaEncoder + public interface IMediaEncoder : ITranscoderSupport { /// /// Gets the encoder path. diff --git a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs index 21289970e2..093b37df3e 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs @@ -12,6 +12,7 @@ using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.ContentDirectory { @@ -27,6 +28,7 @@ namespace MediaBrowser.Dlna.ContentDirectory private readonly IChannelManager _channelManager; private readonly IMediaSourceManager _mediaSourceManager; private readonly IUserViewManager _userViewManager; + private readonly Func _mediaEncoder; public ContentDirectory(IDlnaManager dlna, IUserDataManager userDataManager, @@ -35,7 +37,7 @@ namespace MediaBrowser.Dlna.ContentDirectory IServerConfigurationManager config, IUserManager userManager, ILogger logger, - IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager) + IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, Func mediaEncoder) : base(logger, httpClient) { _dlna = dlna; @@ -48,6 +50,7 @@ namespace MediaBrowser.Dlna.ContentDirectory _channelManager = channelManager; _mediaSourceManager = mediaSourceManager; _userViewManager = userViewManager; + _mediaEncoder = mediaEncoder; } private int SystemUpdateId @@ -89,7 +92,8 @@ namespace MediaBrowser.Dlna.ContentDirectory _localization, _channelManager, _mediaSourceManager, - _userViewManager) + _userViewManager, + _mediaEncoder()) .ProcessControlRequest(request); } diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 01c7c33b6f..34fb2a6df7 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -23,6 +23,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.ContentDirectory { @@ -34,6 +35,7 @@ namespace MediaBrowser.Dlna.ContentDirectory private readonly IServerConfigurationManager _config; private readonly User _user; private readonly IUserViewManager _userViewManager; + private readonly IMediaEncoder _mediaEncoder; private const string NS_DC = "http://purl.org/dc/elements/1.1/"; private const string NS_DIDL = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"; @@ -47,7 +49,7 @@ namespace MediaBrowser.Dlna.ContentDirectory private readonly DeviceProfile _profile; - public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager) + public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, IMediaEncoder mediaEncoder) : base(config, logger) { _libraryManager = libraryManager; @@ -56,10 +58,11 @@ namespace MediaBrowser.Dlna.ContentDirectory _systemUpdateId = systemUpdateId; _channelManager = channelManager; _userViewManager = userViewManager; + _mediaEncoder = mediaEncoder; _profile = profile; _config = config; - _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, libraryManager); + _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, libraryManager, _mediaEncoder); } protected override IEnumerable> GetResult(string methodName, Headers methodParams) diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs index 89d00eb32b..af833a85cf 100644 --- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs +++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs @@ -19,6 +19,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Xml; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Dlna.Didl @@ -42,8 +43,9 @@ namespace MediaBrowser.Dlna.Didl private readonly IMediaSourceManager _mediaSourceManager; private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; + private readonly IMediaEncoder _mediaEncoder; - public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, string accessToken, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, ILogger logger, ILibraryManager libraryManager) + public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, string accessToken, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, ILogger logger, ILibraryManager libraryManager, IMediaEncoder mediaEncoder) { _profile = profile; _imageProcessor = imageProcessor; @@ -53,6 +55,7 @@ namespace MediaBrowser.Dlna.Didl _mediaSourceManager = mediaSourceManager; _logger = logger; _libraryManager = libraryManager; + _mediaEncoder = mediaEncoder; _accessToken = accessToken; _user = user; } @@ -142,7 +145,7 @@ namespace MediaBrowser.Dlna.Didl { var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user).ToList(); - streamInfo = new StreamBuilder(GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions + streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions { ItemId = GetClientId(video), MediaSources = sources, @@ -385,7 +388,7 @@ namespace MediaBrowser.Dlna.Didl { var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user).ToList(); - streamInfo = new StreamBuilder(GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions + streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions { ItemId = GetClientId(audio), MediaSources = sources, diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 37584f006f..733bda9ae6 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -14,6 +14,7 @@ using MediaBrowser.Dlna.Ssdp; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.Main { @@ -34,6 +35,7 @@ namespace MediaBrowser.Dlna.Main private readonly IUserDataManager _userDataManager; private readonly ILocalizationManager _localization; private readonly IMediaSourceManager _mediaSourceManager; + private readonly IMediaEncoder _mediaEncoder; private readonly SsdpHandler _ssdpHandler; private readonly IDeviceDiscovery _deviceDiscovery; @@ -54,7 +56,7 @@ namespace MediaBrowser.Dlna.Main IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, - ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery) + ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery, IMediaEncoder mediaEncoder) { _config = config; _appHost = appHost; @@ -69,6 +71,7 @@ namespace MediaBrowser.Dlna.Main _localization = localization; _mediaSourceManager = mediaSourceManager; _deviceDiscovery = deviceDiscovery; + _mediaEncoder = mediaEncoder; _ssdpHandler = (SsdpHandler)ssdpHandler; _logger = logManager.GetLogger("Dlna"); } @@ -196,7 +199,8 @@ namespace MediaBrowser.Dlna.Main _config, _userDataManager, _localization, - _mediaSourceManager); + _mediaSourceManager, + _mediaEncoder); _manager.Start(); } diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index db5e0ee293..80bb756ef5 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -18,6 +18,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.PlayTo { @@ -35,6 +36,7 @@ namespace MediaBrowser.Dlna.PlayTo private readonly ILocalizationManager _localization; private readonly IMediaSourceManager _mediaSourceManager; private readonly IConfigurationManager _config; + private readonly IMediaEncoder _mediaEncoder; private readonly IDeviceDiscovery _deviceDiscovery; private readonly string _serverAddress; @@ -74,7 +76,7 @@ namespace MediaBrowser.Dlna.PlayTo get { return IsSessionActive; } } - public PlayToController(SessionInfo session, ISessionManager sessionManager, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, IDeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IConfigurationManager config) + public PlayToController(SessionInfo session, ISessionManager sessionManager, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, IDeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IConfigurationManager config, IMediaEncoder mediaEncoder) { _session = session; _sessionManager = sessionManager; @@ -88,6 +90,7 @@ namespace MediaBrowser.Dlna.PlayTo _localization = localization; _mediaSourceManager = mediaSourceManager; _config = config; + _mediaEncoder = mediaEncoder; _accessToken = accessToken; _logger = logger; _creationTime = DateTime.UtcNow; @@ -478,7 +481,7 @@ namespace MediaBrowser.Dlna.PlayTo playlistItem.StreamUrl = playlistItem.StreamInfo.ToDlnaUrl(_serverAddress, _accessToken); - var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _libraryManager) + var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _libraryManager, _mediaEncoder) .GetItemDidl(_config.GetDlnaConfiguration(), item, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo); playlistItem.Didl = itemXml; @@ -550,7 +553,7 @@ namespace MediaBrowser.Dlna.PlayTo { return new PlaylistItem { - StreamInfo = new StreamBuilder(GetStreamBuilderLogger()).BuildVideoItem(new VideoOptions + StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildVideoItem(new VideoOptions { ItemId = item.Id.ToString("N"), MediaSources = mediaSources, @@ -570,7 +573,7 @@ namespace MediaBrowser.Dlna.PlayTo { return new PlaylistItem { - StreamInfo = new StreamBuilder(GetStreamBuilderLogger()).BuildAudioItem(new AudioOptions + StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildAudioItem(new AudioOptions { ItemId = item.Id.ToString("N"), MediaSources = mediaSources, diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index 18daef331a..bbb9bf6de9 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.PlayTo { @@ -32,11 +33,12 @@ namespace MediaBrowser.Dlna.PlayTo private readonly IDeviceDiscovery _deviceDiscovery; private readonly IMediaSourceManager _mediaSourceManager; + private readonly IMediaEncoder _mediaEncoder; private readonly List _nonRendererUrls = new List(); private DateTime _lastRendererClear; - public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager) + public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder) { _logger = logger; _sessionManager = sessionManager; @@ -51,6 +53,7 @@ namespace MediaBrowser.Dlna.PlayTo _userDataManager = userDataManager; _localization = localization; _mediaSourceManager = mediaSourceManager; + _mediaEncoder = mediaEncoder; } public void Start() @@ -132,7 +135,8 @@ namespace MediaBrowser.Dlna.PlayTo _userDataManager, _localization, _mediaSourceManager, - _config); + _config, + _mediaEncoder); controller.Init(device); diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 01fb31d0c5..399fdead9c 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -96,15 +96,23 @@ namespace MediaBrowser.MediaEncoding.Encoder FFMpegPath = ffMpegPath; } + private List _encoders = new List(); public void SetAvailableEncoders(List list) { - + _encoders = list.ToList(); + //_logger.Info("Supported encoders: {0}", string.Join(",", list.ToArray())); } private List _decoders = new List(); public void SetAvailableDecoders(List list) { _decoders = list.ToList(); + //_logger.Info("Supported decoders: {0}", string.Join(",", list.ToArray())); + } + + public bool SupportsEncoder(string decoder) + { + return _encoders.Contains(decoder, StringComparer.OrdinalIgnoreCase); } public bool SupportsDecoder(string decoder) @@ -112,6 +120,20 @@ namespace MediaBrowser.MediaEncoding.Encoder return _decoders.Contains(decoder, StringComparer.OrdinalIgnoreCase); } + public bool CanEncodeToAudioCodec(string codec) + { + if (string.Equals(codec, "opus", StringComparison.OrdinalIgnoreCase)) + { + codec = "libopus"; + } + else if (string.Equals(codec, "mp3", StringComparison.OrdinalIgnoreCase)) + { + codec = "libmp3lame"; + } + + return SupportsEncoder(codec); + } + /// /// Gets the encoder path. /// @@ -296,7 +318,7 @@ namespace MediaBrowser.MediaEncoding.Encoder formats.Contains("ts", StringComparer.OrdinalIgnoreCase) || formats.Contains("mpegts", StringComparer.OrdinalIgnoreCase) || formats.Contains("wtv", StringComparer.OrdinalIgnoreCase); - + // If it's mpeg based, assume true if ((videoStream.Codec ?? string.Empty).IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) != -1) { diff --git a/MediaBrowser.Model/Dlna/ILocalPlayer.cs b/MediaBrowser.Model/Dlna/ILocalPlayer.cs index 55e11ec4b7..9de360023e 100644 --- a/MediaBrowser.Model/Dlna/ILocalPlayer.cs +++ b/MediaBrowser.Model/Dlna/ILocalPlayer.cs @@ -23,4 +23,17 @@ namespace MediaBrowser.Model.Dlna /// true if this instance [can access URL] the specified URL; otherwise, false. bool CanAccessUrl(string url, bool requiresCustomRequestHeaders); } + + public interface ITranscoderSupport + { + bool CanEncodeToAudioCodec(string codec); + } + + public class FullTranscoderSupport : ITranscoderSupport + { + public bool CanEncodeToAudioCodec(string codec) + { + return true; + } + } } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 98d246980b..07a4b89953 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -13,15 +13,27 @@ namespace MediaBrowser.Model.Dlna { private readonly ILocalPlayer _localPlayer; private readonly ILogger _logger; + private readonly ITranscoderSupport _transcoderSupport; - public StreamBuilder(ILocalPlayer localPlayer, ILogger logger) + public StreamBuilder(ILocalPlayer localPlayer, ITranscoderSupport transcoderSupport, ILogger logger) { + _transcoderSupport = transcoderSupport; _localPlayer = localPlayer; _logger = logger; } + public StreamBuilder(ITranscoderSupport transcoderSupport, ILogger logger) + : this(new NullLocalPlayer(), transcoderSupport, logger) + { + } + + public StreamBuilder(ILocalPlayer localPlayer, ILogger logger) + : this(localPlayer, new FullTranscoderSupport(), logger) + { + } + public StreamBuilder(ILogger logger) - : this(new NullLocalPlayer(), logger) + : this(new NullLocalPlayer(), new FullTranscoderSupport(), logger) { } @@ -185,8 +197,11 @@ namespace MediaBrowser.Model.Dlna { if (i.Type == playlistItem.MediaType && i.Context == options.Context) { - transcodingProfile = i; - break; + if (_transcoderSupport.CanEncodeToAudioCodec(i.AudioCodec ?? i.Container)) + { + transcodingProfile = i; + break; + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 10b8727533..d95a4fefb9 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -582,7 +582,7 @@ namespace MediaBrowser.Server.Implementations.Sync conversionOptions.ItemId = item.Id.ToString("N"); conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList(); - var streamInfo = new StreamBuilder(_logger).BuildVideoItem(conversionOptions); + var streamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildVideoItem(conversionOptions); var mediaSource = streamInfo.MediaSource; // No sense creating external subs if we're already burning one into the video @@ -786,7 +786,7 @@ namespace MediaBrowser.Server.Implementations.Sync conversionOptions.ItemId = item.Id.ToString("N"); conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList(); - var streamInfo = new StreamBuilder(_logger).BuildAudioItem(conversionOptions); + var streamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildAudioItem(conversionOptions); var mediaSource = streamInfo.MediaSource; jobItem.MediaSourceId = streamInfo.MediaSourceId; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 01575e71f6..fd6dee0f6e 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -515,7 +515,7 @@ namespace MediaBrowser.Server.Startup.Common UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager); RegisterSingleInstance(UserViewManager); - var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager); + var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager, () => MediaEncoder); RegisterSingleInstance(contentDirectory); var mediaRegistrar = new MediaReceiverRegistrar(LogManager.GetLogger("MediaReceiverRegistrar"), HttpClient, ServerConfigurationManager); diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs index 5ba5fb44ac..0ae021407b 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs @@ -42,6 +42,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg catch { } + //_logger.Debug("ffmpeg decoder query result: {0}", output ?? string.Empty); var found = new List(); var required = new[] @@ -78,6 +79,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg catch { } + //_logger.Debug("ffmpeg encoder query result: {0}", output ?? string.Empty); var found = new List(); var required = new[] @@ -89,8 +91,8 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg //"libvpx", //"libvpx-vp9", "aac", - "ac3", "libmp3lame", + "libopus", //"libvorbis", "srt" }; -- cgit v1.2.3 From 1f9d32afc52e9bd133ddf22d12bdc468adaf9ebe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Apr 2016 18:05:13 -0400 Subject: limit use of GetUserDataKey --- MediaBrowser.Api/Movies/MoviesService.cs | 4 ++-- .../UserLibrary/BaseItemsByNameService.cs | 8 +++---- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 8 ++----- MediaBrowser.Controller/Entities/BaseItem.cs | 14 +++++------- MediaBrowser.Controller/Entities/Folder.cs | 2 +- .../Entities/UserViewBuilder.cs | 10 ++++----- .../Library/IUserDataManager.cs | 5 +++++ .../ContentDirectory/ControlHandler.cs | 2 +- .../Channels/ChannelManager.cs | 12 +++++------ .../Dto/DtoService.cs | 4 ++-- .../Library/MediaSourceManager.cs | 2 +- .../Library/UserDataManager.cs | 15 +++++++++++++ .../LiveTv/LiveTvManager.cs | 12 +++++------ .../Session/SessionManager.cs | 25 ++++++++-------------- .../Sorting/DatePlayedComparer.cs | 2 +- .../Sorting/PlayCountComparer.cs | 2 +- .../Sync/SyncManager.cs | 2 +- .../TV/TVSeriesManager.cs | 4 ++-- MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 2 +- 19 files changed, 70 insertions(+), 65 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 065f882687..bfbb3a6d75 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -247,7 +247,7 @@ namespace MediaBrowser.Api.Movies var recentlyPlayedMovies = allMoviesForCategories .Select(i => { - var userdata = _userDataRepository.GetUserData(user.Id, i.GetUserDataKey()); + var userdata = _userDataRepository.GetUserData(user, i); return new Tuple(i, userdata.Played, userdata.LastPlayedDate ?? DateTime.MinValue); }) .Where(i => i.Item2) @@ -260,7 +260,7 @@ namespace MediaBrowser.Api.Movies .Select(i => { var score = 0; - var userData = _userDataRepository.GetUserData(user.Id, i.GetUserDataKey()); + var userData = _userDataRepository.GetUserData(user, i); if (userData.IsFavorite) { diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index 6ae2b08322..b3164ce3f7 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -274,7 +274,7 @@ namespace MediaBrowser.Api.UserLibrary { items = items.Where(i => { - var userdata = UserDataRepository.GetUserData(user.Id, i.GetUserDataKey()); + var userdata = UserDataRepository.GetUserData(user, i); return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value; }); @@ -284,7 +284,7 @@ namespace MediaBrowser.Api.UserLibrary { items = items.Where(i => { - var userdata = UserDataRepository.GetUserData(user.Id, i.GetUserDataKey()); + var userdata = UserDataRepository.GetUserData(user, i); return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value; }); @@ -294,7 +294,7 @@ namespace MediaBrowser.Api.UserLibrary { items = items.Where(i => { - var userdata = UserDataRepository.GetUserData(user.Id, i.GetUserDataKey()); + var userdata = UserDataRepository.GetUserData(user, i); var likes = userdata.Likes ?? false; var favorite = userdata.IsFavorite; @@ -307,7 +307,7 @@ namespace MediaBrowser.Api.UserLibrary { items = items.Where(i => { - var userdata = UserDataRepository.GetUserData(user.Id, i.GetUserDataKey()); + var userdata = UserDataRepository.GetUserData(user, i); return userdata != null && userdata.IsFavorite; }); diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index c2c481cb6f..8cc5cab358 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -519,10 +519,8 @@ namespace MediaBrowser.Api.UserLibrary var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _libraryManager.GetItemById(itemId); - var key = item.GetUserDataKey(); - // Get the user data for this item - var data = _userDataRepository.GetUserData(user.Id, key); + var data = _userDataRepository.GetUserData(user, item); // Set favorite status data.IsFavorite = isFavorite; @@ -567,10 +565,8 @@ namespace MediaBrowser.Api.UserLibrary var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _libraryManager.GetItemById(itemId); - var key = item.GetUserDataKey(); - // Get the user data for this item - var data = _userDataRepository.GetUserData(user.Id, key); + var data = _userDataRepository.GetUserData(user, item); data.Likes = likes; diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 9171c2a716..4828426fdc 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1617,9 +1617,7 @@ namespace MediaBrowser.Controller.Entities throw new ArgumentNullException(); } - var key = GetUserDataKey(); - - var data = UserDataManager.GetUserData(user.Id, key); + var data = UserDataManager.GetUserData(user, this); if (datePlayed.HasValue) { @@ -1654,9 +1652,7 @@ namespace MediaBrowser.Controller.Entities throw new ArgumentNullException(); } - var key = GetUserDataKey(); - - var data = UserDataManager.GetUserData(user.Id, key); + var data = UserDataManager.GetUserData(user, this); //I think it is okay to do this here. // if this is only called when a user is manually forcing something to un-played @@ -1987,14 +1983,14 @@ namespace MediaBrowser.Controller.Entities public virtual bool IsPlayed(User user) { - var userdata = UserDataManager.GetUserData(user.Id, GetUserDataKey()); + var userdata = UserDataManager.GetUserData(user, this); return userdata != null && userdata.Played; } public bool IsFavoriteOrLiked(User user) { - var userdata = UserDataManager.GetUserData(user.Id, GetUserDataKey()); + var userdata = UserDataManager.GetUserData(user, this); return userdata != null && (userdata.IsFavorite || (userdata.Likes ?? false)); } @@ -2006,7 +2002,7 @@ namespace MediaBrowser.Controller.Entities throw new ArgumentNullException("user"); } - var userdata = UserDataManager.GetUserData(user.Id, GetUserDataKey()); + var userdata = UserDataManager.GetUserData(user, this); return userdata == null || !userdata.Played; } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index f4cdc8fa1b..41f0c02bdc 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1635,7 +1635,7 @@ namespace MediaBrowser.Controller.Entities var isUnplayed = true; - var itemUserData = UserDataManager.GetUserData(user.Id, child.GetUserDataKey()); + var itemUserData = UserDataManager.GetUserData(user, child); // Incrememt totalPercentPlayed if (itemUserData != null) diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index db669ca37d..5a0e0b614b 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -348,7 +348,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => !i.IsFolder) .OfType(); - var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite); + var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite); return GetResult(artists, parent, query); } @@ -1218,7 +1218,7 @@ namespace MediaBrowser.Controller.Entities if (query.IsLiked.HasValue) { - userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + userData = userData ?? userDataManager.GetUserData(user, item); if (!userData.Likes.HasValue || userData.Likes != query.IsLiked.Value) { @@ -1228,7 +1228,7 @@ namespace MediaBrowser.Controller.Entities if (query.IsFavoriteOrLiked.HasValue) { - userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + userData = userData ?? userDataManager.GetUserData(user, item); var isFavoriteOrLiked = userData.IsFavorite || (userData.Likes ?? false); if (isFavoriteOrLiked != query.IsFavoriteOrLiked.Value) @@ -1239,7 +1239,7 @@ namespace MediaBrowser.Controller.Entities if (query.IsFavorite.HasValue) { - userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + userData = userData ?? userDataManager.GetUserData(user, item); if (userData.IsFavorite != query.IsFavorite.Value) { @@ -1249,7 +1249,7 @@ namespace MediaBrowser.Controller.Entities if (query.IsResumable.HasValue) { - userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + userData = userData ?? userDataManager.GetUserData(user, item); var isResumable = userData.PlaybackPositionTicks > 0; if (isResumable != query.IsResumable.Value) diff --git a/MediaBrowser.Controller/Library/IUserDataManager.cs b/MediaBrowser.Controller/Library/IUserDataManager.cs index 56ac14e9df..4ff0f6439f 100644 --- a/MediaBrowser.Controller/Library/IUserDataManager.cs +++ b/MediaBrowser.Controller/Library/IUserDataManager.cs @@ -45,6 +45,11 @@ namespace MediaBrowser.Controller.Library /// Task{UserItemData}. UserItemData GetUserData(Guid userId, string key); + UserItemData GetUserData(IHasUserData user, IHasUserData item); + + UserItemData GetUserData(string userId, IHasUserData item); + UserItemData GetUserData(Guid userId, IHasUserData item); + /// /// Gets the user data dto. /// diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 34fb2a6df7..bc9fa1d7e7 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -111,7 +111,7 @@ namespace MediaBrowser.Dlna.ContentDirectory var newbookmark = int.Parse(sparams["PosSecond"], _usCulture); - var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + var userdata = _userDataManager.GetUserData(user, item); userdata.PlaybackPositionTicks = TimeSpan.FromSeconds(newbookmark).Ticks; diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index c9956c68a5..6a9842cb2e 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Server.Implementations.Channels if (query.IsFavorite.HasValue) { var val = query.IsFavorite.Value; - channels = channels.Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite == val) + channels = channels.Where(i => _userDataManager.GetUserData(user, i).IsFavorite == val) .ToList(); } @@ -1437,7 +1437,7 @@ namespace MediaBrowser.Server.Implementations.Channels case ItemFilter.IsFavoriteOrLikes: return items.Where(item => { - var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + var userdata = _userDataManager.GetUserData(user, item); if (userdata == null) { @@ -1453,7 +1453,7 @@ namespace MediaBrowser.Server.Implementations.Channels case ItemFilter.Likes: return items.Where(item => { - var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + var userdata = _userDataManager.GetUserData(user, item); return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value; }); @@ -1461,7 +1461,7 @@ namespace MediaBrowser.Server.Implementations.Channels case ItemFilter.Dislikes: return items.Where(item => { - var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + var userdata = _userDataManager.GetUserData(user, item); return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value; }); @@ -1469,7 +1469,7 @@ namespace MediaBrowser.Server.Implementations.Channels case ItemFilter.IsFavorite: return items.Where(item => { - var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + var userdata = _userDataManager.GetUserData(user, item); return userdata != null && userdata.IsFavorite; }); @@ -1477,7 +1477,7 @@ namespace MediaBrowser.Server.Implementations.Channels case ItemFilter.IsResumable: return items.Where(item => { - var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + var userdata = _userDataManager.GetUserData(user, item); return userdata != null && userdata.PlaybackPositionTicks > 0; }); diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 7adde5c273..b19f5727c8 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -487,7 +487,7 @@ namespace MediaBrowser.Server.Implementations.Dto { if (item.IsFolder) { - var userData = _userDataRepository.GetUserData(user.Id, item.GetUserDataKey()); + var userData = _userDataRepository.GetUserData(user, item); // Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice // TODO: Improve in future @@ -1686,7 +1686,7 @@ namespace MediaBrowser.Server.Implementations.Dto dateLastMediaAdded = new[] { dateLastMediaAdded.Value, child.DateCreated }.Max(); } - var userdata = _userDataRepository.GetUserData(user.Id, child.GetUserDataKey()); + var userdata = _userDataRepository.GetUserData(user, child); recursiveItemCount++; diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 092b797ce7..a47fcdf4f8 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -267,7 +267,7 @@ namespace MediaBrowser.Server.Implementations.Library private void SetUserProperties(IHasUserData item, MediaSourceInfo source, User user) { - var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user, item); var allowRememberingSelection = item == null || item.EnableRememberingTrackSelections; diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs index ae737d2446..c16beed8cc 100644 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs @@ -172,6 +172,21 @@ namespace MediaBrowser.Server.Implementations.Library return userId + key; } + public UserItemData GetUserData(IHasUserData user, IHasUserData item) + { + return GetUserData(user.Id, item.GetUserDataKey()); + } + + public UserItemData GetUserData(string userId, IHasUserData item) + { + return GetUserData(userId, item.GetUserDataKey()); + } + + public UserItemData GetUserData(Guid userId, IHasUserData item) + { + return GetUserData(userId, item.GetUserDataKey()); + } + public UserItemDataDto GetUserDataDto(IHasUserData item, User user) { var userData = GetUserData(user.Id, item.GetUserDataKey()); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index ab2b59d482..eec8328f89 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -164,7 +164,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var val = query.IsFavorite.Value; channels = channels - .Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite == val); + .Where(i => _userDataManager.GetUserData(user, i).IsFavorite == val); } if (query.IsLiked.HasValue) @@ -174,7 +174,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv channels = channels .Where(i => { - var likes = _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).Likes; + var likes = _userDataManager.GetUserData(user, i).Likes; return likes.HasValue && likes.Value == val; }); @@ -187,7 +187,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv channels = channels .Where(i => { - var likes = _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).Likes; + var likes = _userDataManager.GetUserData(user, i).Likes; return likes.HasValue && likes.Value != val; }); @@ -200,7 +200,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { if (enableFavoriteSorting) { - var userData = _userDataManager.GetUserData(user.Id, i.GetUserDataKey()); + var userData = _userDataManager.GetUserData(user, i); if (userData.IsFavorite) { @@ -1005,7 +1005,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var channel = GetInternalChannel(program.ChannelId); - var channelUserdata = _userDataManager.GetUserData(userId, channel.GetUserDataKey()); + var channelUserdata = _userDataManager.GetUserData(userId, channel); if (channelUserdata.Likes ?? false) { @@ -1036,7 +1036,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (genres.TryGetValue(i, out genre)) { - var genreUserdata = _userDataManager.GetUserData(userId, genre.GetUserDataKey()); + var genreUserdata = _userDataManager.GetUserData(userId, genre); if (genreUserdata.Likes ?? false) { diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 88f11c3685..014e8babf9 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -601,11 +601,9 @@ namespace MediaBrowser.Server.Implementations.Session if (libraryItem != null) { - var key = libraryItem.GetUserDataKey(); - foreach (var user in users) { - await OnPlaybackStart(user.Id, key, libraryItem).ConfigureAwait(false); + await OnPlaybackStart(user.Id, libraryItem).ConfigureAwait(false); } } @@ -632,12 +630,11 @@ namespace MediaBrowser.Server.Implementations.Session /// Called when [playback start]. /// /// The user identifier. - /// The user data key. /// The item. /// Task. - private async Task OnPlaybackStart(Guid userId, string userDataKey, IHasUserData item) + private async Task OnPlaybackStart(Guid userId, IHasUserData item) { - var data = _userDataRepository.GetUserData(userId, userDataKey); + var data = _userDataRepository.GetUserData(userId, item); data.PlayCount++; data.LastPlayedDate = DateTime.UtcNow; @@ -676,11 +673,9 @@ namespace MediaBrowser.Server.Implementations.Session if (libraryItem != null) { - var key = libraryItem.GetUserDataKey(); - foreach (var user in users) { - await OnPlaybackProgress(user, key, libraryItem, info).ConfigureAwait(false); + await OnPlaybackProgress(user, libraryItem, info).ConfigureAwait(false); } } @@ -714,9 +709,9 @@ namespace MediaBrowser.Server.Implementations.Session StartIdleCheckTimer(); } - private async Task OnPlaybackProgress(User user, string userDataKey, BaseItem item, PlaybackProgressInfo info) + private async Task OnPlaybackProgress(User user, BaseItem item, PlaybackProgressInfo info) { - var data = _userDataRepository.GetUserData(user.Id, userDataKey); + var data = _userDataRepository.GetUserData(user.Id, item); var positionTicks = info.PositionTicks; @@ -811,11 +806,9 @@ namespace MediaBrowser.Server.Implementations.Session if (libraryItem != null) { - var key = libraryItem.GetUserDataKey(); - foreach (var user in users) { - playedToCompletion = await OnPlaybackStopped(user.Id, key, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false); + playedToCompletion = await OnPlaybackStopped(user.Id, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false); } } @@ -848,13 +841,13 @@ namespace MediaBrowser.Server.Implementations.Session await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false); } - private async Task OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks, bool playbackFailed) + private async Task OnPlaybackStopped(Guid userId, BaseItem item, long? positionTicks, bool playbackFailed) { bool playedToCompletion = false; if (!playbackFailed) { - var data = _userDataRepository.GetUserData(userId, userDataKey); + var data = _userDataRepository.GetUserData(userId, item); if (positionTicks.HasValue) { diff --git a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs index c881591beb..3edf23020a 100644 --- a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs @@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Sorting /// DateTime. private DateTime GetDate(BaseItem x) { - var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey()); + var userdata = UserDataRepository.GetUserData(User, x); if (userdata != null && userdata.LastPlayedDate.HasValue) { diff --git a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs index 1bc5261b44..8b14efffcf 100644 --- a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Sorting /// DateTime. private int GetValue(BaseItem x) { - var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey()); + var userdata = UserDataRepository.GetUserData(User, x); return userdata == null ? 0 : userdata.PlayCount; } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index fe1a7fb28f..38edc30240 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -687,7 +687,7 @@ namespace MediaBrowser.Server.Implementations.Sync private Task ReportOfflinePlayedItem(UserAction action) { var item = _libraryManager.GetItemById(action.ItemId); - var userData = _userDataManager.GetUserData(new Guid(action.UserId), item.GetUserDataKey()); + var userData = _userDataManager.GetUserData(action.UserId, item); userData.LastPlayedDate = action.Date; _userDataManager.UpdatePlayState(item, userData, action.PositionTicks); diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 3e43ebe9b8..dc880d84b5 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -85,7 +85,7 @@ namespace MediaBrowser.Server.Implementations.TV { var episode = i.Item1; - var seriesUserData = _userDataManager.GetUserData(user.Id, episode.Series.GetUserDataKey()); + var seriesUserData = _userDataManager.GetUserData(user, episode.Series); if (seriesUserData.IsFavorite) { @@ -128,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.TV // Go back starting with the most recent episodes foreach (var episode in allEpisodes) { - var userData = _userDataManager.GetUserData(user.Id, episode.GetUserDataKey()); + var userData = _userDataManager.GetUserData(user, episode); if (userData.Played) { diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index 6d15d168d1..d2e09d4ebf 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -936,7 +936,7 @@ namespace MediaBrowser.XbmcMetadata.Savers return; } - var userdata = userDataRepo.GetUserData(user.Id, item.GetUserDataKey()); + var userdata = userDataRepo.GetUserData(user, item); writer.WriteElementString("isuserfavorite", userdata.IsFavorite.ToString().ToLower()); -- cgit v1.2.3 From a4d1c9e6e48f63121cc51abda61ed46d7f6a72cf Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 1 May 2016 17:48:37 -0400 Subject: update sqlite --- .../Notifications/INotificationsRepository.cs | 6 - .../Persistence/IDisplayPreferencesRepository.cs | 6 - .../Persistence/IItemRepository.cs | 6 - .../Persistence/IUserDataRepository.cs | 6 - .../Providers/IProviderRepository.cs | 6 - .../Activity/ActivityRepository.cs | 4 +- .../MediaBrowser.Server.Implementations.csproj | 6 +- .../Notifications/SqliteNotificationsRepository.cs | 4 +- .../Persistence/DataExtensions.cs | 182 +++++++++++++++++ .../Persistence/IDbConnector.cs | 10 + .../SqliteDisplayPreferencesRepository.cs | 4 +- .../Persistence/SqliteExtensions.cs | 218 --------------------- .../SqliteFileOrganizationRepository.cs | 4 +- .../Persistence/SqliteProviderInfoRepository.cs | 4 +- .../Persistence/SqliteUserDataRepository.cs | 4 +- .../Persistence/SqliteUserRepository.cs | 6 +- .../Security/AuthenticationRepository.cs | 4 +- .../Social/SharingRepository.cs | 4 +- .../Sync/SyncRepository.cs | 4 +- .../MediaBrowser.Server.Mono.csproj | 5 + MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 11 +- MediaBrowser.Server.Mono/Native/NativeApp.cs | 7 +- .../Native/SqliteExtensions.cs | 62 ++++++ MediaBrowser.Server.Mono/Program.cs | 2 +- .../ApplicationHost.cs | 55 ++---- MediaBrowser.Server.Startup.Common/INativeApp.cs | 3 + .../MediaBrowser.ServerApplication.csproj | 25 +-- .../Native/SqliteExtensions.cs | 62 ++++++ .../Native/WindowsApp.cs | 6 + MediaBrowser.ServerApplication/packages.config | 2 +- 30 files changed, 401 insertions(+), 327 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs create mode 100644 MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs delete mode 100644 MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs create mode 100644 MediaBrowser.Server.Mono/Native/SqliteExtensions.cs create mode 100644 MediaBrowser.ServerApplication/Native/SqliteExtensions.cs (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Controller/Notifications/INotificationsRepository.cs b/MediaBrowser.Controller/Notifications/INotificationsRepository.cs index 6ad4a5377e..cd587a5099 100644 --- a/MediaBrowser.Controller/Notifications/INotificationsRepository.cs +++ b/MediaBrowser.Controller/Notifications/INotificationsRepository.cs @@ -19,12 +19,6 @@ namespace MediaBrowser.Controller.Notifications /// Occurs when [notifications marked read]. /// event EventHandler NotificationsMarkedRead; - - /// - /// Opens the connection to the repository - /// - /// Task. - Task Initialize(); /// /// Gets the notifications. diff --git a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs index 17de730cb8..abf96994f1 100644 --- a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs +++ b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs @@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Persistence /// public interface IDisplayPreferencesRepository : IRepository { - /// - /// Opens the connection to the repository - /// - /// Task. - Task Initialize(); - /// /// Saves display preferences for an item /// diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 15df1f6492..7bcc36958a 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -13,12 +13,6 @@ namespace MediaBrowser.Controller.Persistence /// public interface IItemRepository : IRepository { - /// - /// Opens the connection to the repository - /// - /// Task. - Task Initialize(); - /// /// Saves an item /// diff --git a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs index 2a904be0d9..2e165f4163 100644 --- a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs +++ b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs @@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Persistence /// public interface IUserDataRepository : IRepository { - /// - /// Opens the connection to the repository - /// - /// Task. - Task Initialize(); - /// /// Saves the user data. /// diff --git a/MediaBrowser.Controller/Providers/IProviderRepository.cs b/MediaBrowser.Controller/Providers/IProviderRepository.cs index 1f77d0ca1c..891275d775 100644 --- a/MediaBrowser.Controller/Providers/IProviderRepository.cs +++ b/MediaBrowser.Controller/Providers/IProviderRepository.cs @@ -21,11 +21,5 @@ namespace MediaBrowser.Controller.Providers /// The cancellation token. /// Task. Task SaveMetadataStatus(MetadataStatus status, CancellationToken cancellationToken); - - /// - /// Initializes this instance. - /// - /// Task. - Task Initialize(); } } diff --git a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs index 85ab761823..b0e05a5bc8 100644 --- a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs +++ b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs @@ -27,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Activity _appPaths = appPaths; } - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "activitylog.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 43f5d741b4..aff3a5e160 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -78,9 +78,6 @@ - - ..\ThirdParty\System.Data.SQLite.ManagedOnly\1.0.94.0\System.Data.SQLite.dll - @@ -261,6 +258,8 @@ + + @@ -275,7 +274,6 @@ - diff --git a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index 7302431e17..cecf03ddfe 100644 --- a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs +++ b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -32,11 +32,11 @@ namespace MediaBrowser.Server.Implementations.Notifications _appPaths = appPaths; } - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "notifications.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs new file mode 100644 index 0000000000..103b75f840 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs @@ -0,0 +1,182 @@ +using System.Text; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; +using System; +using System.Data; +using System.IO; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + static class DataExtensions + { + /// + /// Determines whether the specified conn is open. + /// + /// The conn. + /// true if the specified conn is open; otherwise, false. + public static bool IsOpen(this IDbConnection conn) + { + return conn.State == ConnectionState.Open; + } + + public static IDataParameter GetParameter(this IDbCommand cmd, int index) + { + return (IDataParameter)cmd.Parameters[index]; + } + + public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name, DbType type) + { + var param = cmd.CreateParameter(); + + param.ParameterName = name; + param.DbType = type; + + paramCollection.Add(param); + + return param; + } + + public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name) + { + var param = cmd.CreateParameter(); + + param.ParameterName = name; + + paramCollection.Add(param); + + return param; + } + + + /// + /// Gets a stream from a DataReader at a given ordinal + /// + /// The reader. + /// The ordinal. + /// Stream. + /// reader + public static Stream GetMemoryStream(this IDataReader reader, int ordinal) + { + if (reader == null) + { + throw new ArgumentNullException("reader"); + } + + var memoryStream = new MemoryStream(); + var num = 0L; + var array = new byte[4096]; + long bytes; + do + { + bytes = reader.GetBytes(ordinal, num, array, 0, array.Length); + memoryStream.Write(array, 0, (int)bytes); + num += bytes; + } + while (bytes > 0L); + memoryStream.Position = 0; + return memoryStream; + } + + /// + /// Runs the queries. + /// + /// The connection. + /// The queries. + /// The logger. + /// true if XXXX, false otherwise + /// queries + public static void RunQueries(this IDbConnection connection, string[] queries, ILogger logger) + { + if (queries == null) + { + throw new ArgumentNullException("queries"); + } + + using (var tran = connection.BeginTransaction()) + { + try + { + using (var cmd = connection.CreateCommand()) + { + foreach (var query in queries) + { + cmd.Transaction = tran; + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + } + } + + tran.Commit(); + } + catch (Exception e) + { + logger.ErrorException("Error running queries", e); + tran.Rollback(); + throw; + } + } + } + + public static void Attach(IDbConnection db, string path, string alias) + { + using (var cmd = db.CreateCommand()) + { + cmd.CommandText = string.Format("attach '{0}' as {1};", path, alias); + cmd.ExecuteNonQuery(); + } + } + + /// + /// Serializes to bytes. + /// + /// The json. + /// The obj. + /// System.Byte[][]. + /// obj + public static byte[] SerializeToBytes(this IJsonSerializer json, object obj) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + using (var stream = new MemoryStream()) + { + json.SerializeToStream(obj, stream); + return stream.ToArray(); + } + } + + public static void AddColumn(this IDbConnection connection, ILogger logger, string table, string columnName, string type) + { + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "PRAGMA table_info(" + table + ")"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + if (!reader.IsDBNull(1)) + { + var name = reader.GetString(1); + + if (string.Equals(name, columnName, StringComparison.OrdinalIgnoreCase)) + { + return; + } + } + } + } + } + + var builder = new StringBuilder(); + + builder.AppendLine("alter table " + table); + builder.AppendLine("add column " + columnName + " " + type); + + connection.RunQueries(new[] { builder.ToString() }, logger); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs new file mode 100644 index 0000000000..cac9fe9835 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs @@ -0,0 +1,10 @@ +using System.Data; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + public interface IDbConnector + { + Task Connect(string dbPath); + } +} diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs index 45e0304c1c..6077cfdba4 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs @@ -52,11 +52,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs deleted file mode 100644 index 4fb1e07dd7..0000000000 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs +++ /dev/null @@ -1,218 +0,0 @@ -using System.Text; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; -using System; -using System.Data; -using System.Data.SQLite; -using System.IO; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Persistence -{ - /// - /// Class SQLiteExtensions - /// - static class SqliteExtensions - { - /// - /// Determines whether the specified conn is open. - /// - /// The conn. - /// true if the specified conn is open; otherwise, false. - public static bool IsOpen(this IDbConnection conn) - { - return conn.State == ConnectionState.Open; - } - - public static IDataParameter GetParameter(this IDbCommand cmd, int index) - { - return (IDataParameter)cmd.Parameters[index]; - } - - public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name, DbType type) - { - var param = cmd.CreateParameter(); - - param.ParameterName = name; - param.DbType = type; - - paramCollection.Add(param); - - return param; - } - - public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name) - { - var param = cmd.CreateParameter(); - - param.ParameterName = name; - - paramCollection.Add(param); - - return param; - } - - - /// - /// Gets a stream from a DataReader at a given ordinal - /// - /// The reader. - /// The ordinal. - /// Stream. - /// reader - public static Stream GetMemoryStream(this IDataReader reader, int ordinal) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - var memoryStream = new MemoryStream(); - var num = 0L; - var array = new byte[4096]; - long bytes; - do - { - bytes = reader.GetBytes(ordinal, num, array, 0, array.Length); - memoryStream.Write(array, 0, (int)bytes); - num += bytes; - } - while (bytes > 0L); - memoryStream.Position = 0; - return memoryStream; - } - - /// - /// Runs the queries. - /// - /// The connection. - /// The queries. - /// The logger. - /// true if XXXX, false otherwise - /// queries - public static void RunQueries(this IDbConnection connection, string[] queries, ILogger logger) - { - if (queries == null) - { - throw new ArgumentNullException("queries"); - } - - using (var tran = connection.BeginTransaction()) - { - try - { - using (var cmd = connection.CreateCommand()) - { - foreach (var query in queries) - { - cmd.Transaction = tran; - cmd.CommandText = query; - cmd.ExecuteNonQuery(); - } - } - - tran.Commit(); - } - catch (Exception e) - { - logger.ErrorException("Error running queries", e); - tran.Rollback(); - throw; - } - } - } - - /// - /// Connects to db. - /// - /// The db path. - /// The logger. - /// Task{IDbConnection}. - /// dbPath - public static async Task ConnectToDb(string dbPath, ILogger logger) - { - if (string.IsNullOrEmpty(dbPath)) - { - throw new ArgumentNullException("dbPath"); - } - - logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); - - var connectionstr = new SQLiteConnectionStringBuilder - { - PageSize = 4096, - CacheSize = 2000, - SyncMode = SynchronizationModes.Full, - DataSource = dbPath, - JournalMode = SQLiteJournalModeEnum.Wal - }; - - var connection = new SQLiteConnection(connectionstr.ConnectionString); - - await connection.OpenAsync().ConfigureAwait(false); - - return connection; - } - - public static void Attach(IDbConnection db, string path, string alias) - { - using (var cmd = db.CreateCommand()) - { - cmd.CommandText = string.Format("attach '{0}' as {1};", path, alias); - cmd.ExecuteNonQuery(); - } - } - - /// - /// Serializes to bytes. - /// - /// The json. - /// The obj. - /// System.Byte[][]. - /// obj - public static byte[] SerializeToBytes(this IJsonSerializer json, object obj) - { - if (obj == null) - { - throw new ArgumentNullException("obj"); - } - - using (var stream = new MemoryStream()) - { - json.SerializeToStream(obj, stream); - return stream.ToArray(); - } - } - - public static void AddColumn(this IDbConnection connection, ILogger logger, string table, string columnName, string type) - { - using (var cmd = connection.CreateCommand()) - { - cmd.CommandText = "PRAGMA table_info(" + table + ")"; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) - { - if (!reader.IsDBNull(1)) - { - var name = reader.GetString(1); - - if (string.Equals(name, columnName, StringComparison.OrdinalIgnoreCase)) - { - return; - } - } - } - } - } - - var builder = new StringBuilder(); - - builder.AppendLine("alter table " + table); - builder.AppendLine("add column " + columnName + " " + type); - - connection.RunQueries(new[] { builder.ToString() }, logger); - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs index 2d5aad04df..037776997e 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs @@ -35,11 +35,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "fileorganization.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs index dbceda727b..40d5c9586e 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs @@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "refreshinfo.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index 63c41c71fe..33a2b11877 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -37,11 +37,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs index 9bd7e47f39..f7ca39a548 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs @@ -43,12 +43,12 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "users.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); - + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); + string[] queries = { "create table if not exists users (guid GUID primary key, data BLOB)", diff --git a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs index b932f0cac4..e8d9814ecb 100644 --- a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs +++ b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs @@ -27,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Security _appPaths = appPaths; } - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "authentication.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs index d6d7f021a3..317743eb1b 100644 --- a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs +++ b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs @@ -26,11 +26,11 @@ namespace MediaBrowser.Server.Implementations.Social /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "shares.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 965c081ebd..6d31663b97 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.Sync _appPaths = appPaths; } - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "sync14.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index 48d2df7cef..b71877e17a 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -76,12 +76,17 @@ ..\ThirdParty\MediaBrowser.IsoMounting.Linux\MediaBrowser.IsoMounting.Linux.dll + + + ..\ThirdParty\System.Data.SQLite.ManagedOnly\1.0.94.0\System.Data.SQLite.dll + Properties\SharedVersion.cs + diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index fbfef9a34d..a012a19a3d 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Reflection; using System.Text.RegularExpressions; using MediaBrowser.Controller.Power; +using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Startup.Common.FFMpeg; using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem; @@ -17,9 +18,12 @@ namespace MediaBrowser.Server.Mono.Native public abstract class BaseMonoApp : INativeApp { protected StartupOptions StartupOptions { get; private set; } - protected BaseMonoApp(StartupOptions startupOptions) + protected ILogger Logger { get; private set; } + + protected BaseMonoApp(StartupOptions startupOptions, ILogger logger) { StartupOptions = startupOptions; + Logger = logger; } /// @@ -227,6 +231,11 @@ namespace MediaBrowser.Server.Mono.Native throw new NotImplementedException(); } + public IDbConnector GetDbConnector() + { + return new DbConnector(Logger); + } + public static FFMpegInstallInfo GetInfo(NativeEnvironment environment) { var info = new FFMpegInstallInfo(); diff --git a/MediaBrowser.Server.Mono/Native/NativeApp.cs b/MediaBrowser.Server.Mono/Native/NativeApp.cs index c73a964970..c0874a1d82 100644 --- a/MediaBrowser.Server.Mono/Native/NativeApp.cs +++ b/MediaBrowser.Server.Mono/Native/NativeApp.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Server.Startup.Common; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Startup.Common; namespace MediaBrowser.Server.Mono.Native { @@ -7,8 +8,8 @@ namespace MediaBrowser.Server.Mono.Native /// internal class NativeApp : BaseMonoApp { - public NativeApp(StartupOptions startupOptions) - : base(startupOptions) + public NativeApp(StartupOptions startupOptions, ILogger logger) + : base(startupOptions, logger) { } diff --git a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs new file mode 100644 index 0000000000..385a7d0c58 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs @@ -0,0 +1,62 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.Server.Mono.Native +{ + /// + /// Class SQLiteExtensions + /// + static class SqliteExtensions + { + /// + /// Connects to db. + /// + /// The db path. + /// The logger. + /// Task{IDbConnection}. + /// dbPath + public static async Task ConnectToDb(string dbPath, ILogger logger) + { + if (string.IsNullOrEmpty(dbPath)) + { + throw new ArgumentNullException("dbPath"); + } + + logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); + + var connectionstr = new SQLiteConnectionStringBuilder + { + PageSize = 4096, + CacheSize = 2000, + SyncMode = SynchronizationModes.Full, + DataSource = dbPath, + JournalMode = SQLiteJournalModeEnum.Wal + }; + + var connection = new SQLiteConnection(connectionstr.ConnectionString); + + await connection.OpenAsync().ConfigureAwait(false); + + return connection; + } + } + + public class DbConnector : IDbConnector + { + private readonly ILogger _logger; + + public DbConnector(ILogger logger) + { + _logger = logger; + } + + public Task Connect(string dbPath) + { + return SqliteExtensions.ConnectToDb(dbPath, _logger); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index 2a06094493..32de452421 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -79,7 +79,7 @@ namespace MediaBrowser.Server.Mono var fileSystem = new ManagedFileSystem(new PatternsLogger(logManager.GetLogger("FileSystem")), false, false); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); - var nativeApp = new NativeApp(options); + var nativeApp = new NativeApp(options, logManager.GetLogger("App")); _appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "emby.mono.zip", nativeApp); diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index fd6dee0f6e..2d56a15753 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -410,13 +410,16 @@ namespace MediaBrowser.Server.Startup.Common UserRepository = await GetUserRepository().ConfigureAwait(false); RegisterSingleInstance(UserRepository); - DisplayPreferencesRepository = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths); + var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths); + DisplayPreferencesRepository = displayPreferencesRepo; RegisterSingleInstance(DisplayPreferencesRepository); - ItemRepository = new SqliteItemRepository(ApplicationPaths, JsonSerializer, LogManager); + var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager); + ItemRepository = itemRepo; RegisterSingleInstance(ItemRepository); - ProviderRepository = new SqliteProviderInfoRepository(LogManager, ApplicationPaths); + var providerRepo = new SqliteProviderInfoRepository(LogManager, ApplicationPaths); + ProviderRepository = providerRepo; RegisterSingleInstance(ProviderRepository); FileOrganizationRepository = await GetFileOrganizationRepository().ConfigureAwait(false); @@ -541,7 +544,7 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(NativeApp.GetPowerManagement()); var sharingRepo = new SharingRepository(LogManager, ApplicationPaths); - await sharingRepo.Initialize().ConfigureAwait(false); + await sharingRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); RegisterSingleInstance(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); RegisterSingleInstance(new SsdpHandler(LogManager.GetLogger("SsdpHandler"), ServerConfigurationManager, this)); @@ -557,9 +560,11 @@ namespace MediaBrowser.Server.Startup.Common SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager); RegisterSingleInstance(SubtitleEncoder); - - await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false); - await ConfigureItemRepositories().ConfigureAwait(false); + + await displayPreferencesRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await itemRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await providerRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; await ConfigureUserDataRepositories().ConfigureAwait(false); await ConfigureNotificationsRepository().ConfigureAwait(false); progress.Report(100); @@ -658,7 +663,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -677,7 +682,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -686,7 +691,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -695,7 +700,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -704,7 +709,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -717,35 +722,13 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); NotificationsRepository = repo; RegisterSingleInstance(NotificationsRepository); } - /// - /// Configures the repositories. - /// - /// Task. - private async Task ConfigureDisplayPreferencesRepositories() - { - await DisplayPreferencesRepository.Initialize().ConfigureAwait(false); - } - - /// - /// Configures the item repositories. - /// - /// Task. - private async Task ConfigureItemRepositories() - { - await ItemRepository.Initialize().ConfigureAwait(false); - - await ProviderRepository.Initialize().ConfigureAwait(false); - - ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; - } - /// /// Configures the user data repositories. /// @@ -754,7 +737,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); ((UserDataManager)UserDataManager).Repository = repo; } diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index c0758b47f5..c13d3624e3 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging; using System.Collections.Generic; using System.Reflection; using MediaBrowser.Controller.Power; +using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Startup.Common.FFMpeg; namespace MediaBrowser.Server.Startup.Common @@ -104,5 +105,7 @@ namespace MediaBrowser.Server.Startup.Common FFMpegInstallInfo GetFfmpegInstallInfo(); void LaunchUrl(string url); + + IDbConnector GetDbConnector(); } } diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 291e63dac7..f544a149d8 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -13,6 +13,8 @@ 512 ..\ + + AnyCPU @@ -81,9 +83,9 @@ - - False - ..\packages\System.Data.SQLite.Core.1.0.94.0\lib\net45\System.Data.SQLite.dll + + ..\packages\System.Data.SQLite.Core.1.0.101.0\lib\net46\System.Data.SQLite.dll + True @@ -112,6 +114,7 @@ + @@ -156,14 +159,6 @@ - - x64\SQLite.Interop.dll - PreserveNewest - - - x86\SQLite.Interop.dll - PreserveNewest - MediaBrowser.InstallUtil.dll PreserveNewest @@ -1116,6 +1111,13 @@ + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + - \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs new file mode 100644 index 0000000000..1cde2ea139 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs @@ -0,0 +1,62 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class SQLiteExtensions + /// + static class SqliteExtensions + { + /// + /// Connects to db. + /// + /// The db path. + /// The logger. + /// Task{IDbConnection}. + /// dbPath + public static async Task ConnectToDb(string dbPath, ILogger logger) + { + if (string.IsNullOrEmpty(dbPath)) + { + throw new ArgumentNullException("dbPath"); + } + + logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); + + var connectionstr = new SQLiteConnectionStringBuilder + { + PageSize = 4096, + CacheSize = 2000, + SyncMode = SynchronizationModes.Full, + DataSource = dbPath, + JournalMode = SQLiteJournalModeEnum.Wal + }; + + var connection = new SQLiteConnection(connectionstr.ConnectionString); + + await connection.OpenAsync().ConfigureAwait(false); + + return connection; + } + } + + public class DbConnector : IDbConnector + { + private readonly ILogger _logger; + + public DbConnector(ILogger logger) + { + _logger = logger; + } + + public Task Connect(string dbPath) + { + return SqliteExtensions.ConnectToDb(dbPath, _logger); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 10cd59436d..808c7558ec 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -10,6 +10,7 @@ using System.Reflection; using System.Windows.Forms; using CommonIO; using MediaBrowser.Controller.Power; +using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Startup.Common.FFMpeg; using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem; @@ -191,6 +192,11 @@ namespace MediaBrowser.ServerApplication.Native } } + public IDbConnector GetDbConnector() + { + return new DbConnector(_logger); + } + /// /// Processes the exited. /// diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 1c86a02ae6..2d4baae256 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file -- cgit v1.2.3 From 6adc668bed55948b89ee6adcc379cce7253da82c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 7 May 2016 13:47:41 -0400 Subject: update icons --- .../Entities/Audio/MusicArtist.cs | 14 ++++++++++ .../Entities/Audio/MusicGenre.cs | 8 ++++++ MediaBrowser.Controller/Entities/GameGenre.cs | 8 ++++++ MediaBrowser.Controller/Entities/Genre.cs | 8 ++++++ MediaBrowser.Controller/Entities/IItemByName.cs | 2 ++ .../Entities/InternalItemsQuery.cs | 1 + MediaBrowser.Controller/Entities/Person.cs | 7 +++++ MediaBrowser.Controller/Entities/PhotoAlbum.cs | 9 ------- MediaBrowser.Controller/Entities/Studio.cs | 7 +++++ MediaBrowser.Controller/Entities/TV/Series.cs | 16 +++--------- MediaBrowser.Controller/Entities/Year.cs | 16 ++++++++++++ MediaBrowser.Controller/Playlists/Playlist.cs | 11 ++++---- .../Library/MusicManager.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 6 +++++ .../Photos/BaseDynamicImageProvider.cs | 15 +++++++++++ .../Session/SessionManager.cs | 25 ++++++++++-------- .../Sync/SyncJobProcessor.cs | 30 +++++++++------------- 17 files changed, 129 insertions(+), 56 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 2cca632179..2637e729c1 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -40,6 +40,20 @@ namespace MediaBrowser.Controller.Entities.Audio return !IsAccessedByName; } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + var itemByNameFilter = GetItemFilter(); + + if (query.User != null) + { + return query.User.RootFolder + .GetRecursiveChildren(query.User, i => !i.IsFolder && itemByNameFilter(i)); + } + + return LibraryManager.RootFolder + .GetRecursiveChildren(i => !i.IsFolder && itemByNameFilter(i)); + } + protected override IEnumerable ActualChildren { get diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 4d041264c0..05870176e8 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -79,5 +79,13 @@ namespace MediaBrowser.Controller.Entities.Audio return false; } } + + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.ExcludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name }; + + return LibraryManager.GetItemList(query); + } } } diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 71028d4cf7..7c1e88cb1a 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -62,6 +62,14 @@ namespace MediaBrowser.Controller.Entities return i => i is Game && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.IncludeItemTypes = new[] { typeof(Game).Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index fa890ad9eb..c87d4daaf9 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -66,6 +66,14 @@ namespace MediaBrowser.Controller.Entities return i => !(i is Game) && !(i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.ExcludeItemTypes = new[] { typeof(Game).Name, typeof(MusicVideo).Name, typeof(Audio.Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index e6667290c1..7747e738cb 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -20,6 +20,8 @@ namespace MediaBrowser.Controller.Entities /// /// Func<BaseItem, System.Boolean>. Func GetItemFilter(); + + IEnumerable GetTaggedItems(InternalItemsQuery query); } public interface IHasDualAccess : IItemByName diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 2615f351ad..385ee81e9d 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -134,6 +134,7 @@ namespace MediaBrowser.Controller.Entities public string[] AlbumNames { get; set; } public string[] ArtistNames { get; set; } + public string AncestorWithPresentationUniqueKey { get; set; } public bool GroupByPresentationUniqueKey { get; set; } diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 89581e967d..2b099e3d5f 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -31,6 +31,13 @@ namespace MediaBrowser.Controller.Entities return GetItemLookupInfo(); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Person = Name; + + return LibraryManager.GetItemList(query); + } + /// /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs index c8ab67a698..b0ddcfb8c6 100644 --- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs +++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs @@ -7,15 +7,6 @@ namespace MediaBrowser.Controller.Entities { public class PhotoAlbum : Folder { - [IgnoreDataMember] - public override bool SupportsLocalMetadata - { - get - { - return false; - } - } - [IgnoreDataMember] public override bool AlwaysScanInternalMetadataPath { diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 7ceefbc6e7..48ca7bbccc 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -65,6 +65,13 @@ namespace MediaBrowser.Controller.Entities return i => i.Studios.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Studios = new[] { Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index abca6a6431..a70bac6db4 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MoreLinq; namespace MediaBrowser.Controller.Entities.TV { @@ -180,7 +181,7 @@ namespace MediaBrowser.Controller.Entities.TV else { items = query.Recursive - ? GetRecursiveChildren(user, filter) + ? GetSeasons(user).Cast().Concat(GetEpisodes(user)).Where(filter) : GetSeasons(user).Where(filter); } @@ -211,7 +212,7 @@ namespace MediaBrowser.Controller.Entities.TV } else { - seasons = base.GetChildren(user, true).OfType(); + seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType(); } if (!includeMissingSeasons && !includeVirtualUnaired) @@ -250,17 +251,8 @@ namespace MediaBrowser.Controller.Entities.TV // Specials could appear twice based on above - once in season 0, once in the aired season // This depends on settings for that series // When this happens, remove the duplicate from season 0 - var returnList = new List(); - foreach (var episode in allEpisodes) - { - if (!returnList.Contains(episode)) - { - returnList.Insert(0, episode); - } - } - - return returnList; + return allEpisodes.DistinctBy(i => i.Id).Reverse(); } public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken) diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index f27ce79dd3..db896f1fc7 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -70,6 +70,22 @@ namespace MediaBrowser.Controller.Entities return inputItems.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + int year; + + var usCulture = new CultureInfo("en-US"); + + if (!int.TryParse(Name, NumberStyles.Integer, usCulture, out year)) + { + return new List(); + } + + query.Years = new[] { year }; + + return LibraryManager.GetItemList(query); + } + public int? GetYearValue() { int i; diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 750dea3618..cd0c5dc1c7 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -99,11 +99,12 @@ namespace MediaBrowser.Controller.Playlists var musicGenre = item as MusicGenre; if (musicGenre != null) { - Func filter = i => i is Audio && i.Genres.Contains(musicGenre.Name, StringComparer.OrdinalIgnoreCase); - - var items = user == null - ? LibraryManager.RootFolder.GetRecursiveChildren(filter) - : user.RootFolder.GetRecursiveChildren(user, filter); + var items = LibraryManager.GetItemList(new InternalItemsQuery(user) + { + Recursive = true, + IncludeItemTypes = new[] { typeof(Audio).Name }, + Genres = new[] { musicGenre.Name } + }); return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending); } diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index aad7c112b7..c82c4cdf7b 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable public interface IHasUserData : IHasId { - /// - /// Gets the user data key. - /// - /// System.String. - string GetUserDataKey(); - List GetUserDataKeys(); /// diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs index 5e0baa1f67..1eda79f022 100644 --- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs +++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs @@ -125,11 +125,6 @@ namespace MediaBrowser.Dlna.Ssdp args.EndPoint = endPoint; args.LocalEndPoint = new IPEndPoint(localIp, 0); - if (_ssdpHandler.IgnoreMessage(args, true)) - { - return; - } - _ssdpHandler.LogMessageReceived(args, true); TryCreateDevice(args); diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs index 0fabbf54aa..f637160be9 100644 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -199,22 +200,22 @@ namespace MediaBrowser.Server.Implementations.Library public UserItemData GetUserData(IHasUserData user, IHasUserData item) { - return GetUserData(user.Id, item.GetUserDataKey()); + return GetUserData(user.Id, item.GetUserDataKeys().First()); } public UserItemData GetUserData(string userId, IHasUserData item) { - return GetUserData(userId, item.GetUserDataKey()); + return GetUserData(userId, item.GetUserDataKeys().First()); } public UserItemData GetUserData(Guid userId, IHasUserData item) { - return GetUserData(userId, item.GetUserDataKey()); + return GetUserData(userId, item.GetUserDataKeys().First()); } public UserItemDataDto GetUserDataDto(IHasUserData item, User user) { - var userData = GetUserData(user.Id, item.GetUserDataKey()); + var userData = GetUserData(user.Id, item.GetUserDataKeys().First()); var dto = GetUserItemDataDto(userData); item.FillUserDataDtoValues(dto, userData, user); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 379e2f0560..bbba06870e 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -345,7 +345,8 @@ namespace MediaBrowser.Server.Implementations.Sync if (!folder.IsPreSorted) { - items = items.OrderBy(i => i.SortName).ToArray(); + items = _libraryManager.Sort(items, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending) + .ToArray(); } return items; diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 271b02d9a7..f5abcf336e 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -158,7 +158,7 @@ namespace MediaBrowser.ServerApplication.Native info.FFMpegFilename = "ffmpeg.exe"; info.FFProbeFilename = "ffprobe.exe"; - info.Version = "20160508"; + info.Version = "20160410"; info.ArchiveType = "7z"; info.IsEmbedded = false; info.DownloadUrls = GetDownloadUrls(); @@ -214,14 +214,14 @@ namespace MediaBrowser.ServerApplication.Native case Architecture.X86_X64: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win64.7z", - "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160508-git-caee88d-win64-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win64.7z", + "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160409-git-0c90b2e-win64-static.7z" }; case Architecture.X86: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win32.7z", - "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160508-git-caee88d-win32-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win32.7z", + "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160409-git-0c90b2e-win32-static.7z" }; } return new string[] { }; -- cgit v1.2.3 From c21a971b98c99a006642dd762422edcf876e8aa6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 15 May 2016 13:24:59 -0400 Subject: update sync db indexes --- MediaBrowser.Server.Implementations/Sync/SyncRepository.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 6d31663b97..739d1ab6e6 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -49,9 +49,11 @@ namespace MediaBrowser.Server.Implementations.Sync "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Profile TEXT, Quality TEXT, Bitrate INT, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", + "create index if not exists idx_SyncJobs1 on SyncJobs(TargetId)", "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT, ItemDateModifiedTicks BIGINT)", - "create index if not exists idx_SyncJobItems on SyncJobs(Id)", + "create index if not exists idx_SyncJobItems1 on SyncJobItems(Id)", + "create index if not exists idx_SyncJobItems2 on SyncJobItems(TargetId)", //pragmas "pragma temp_store = memory", -- cgit v1.2.3 From e5655d32f122b4840057aac30bba24d2a94c36fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 27 May 2016 13:17:57 -0400 Subject: fix timestamps in hls subtitles --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 6 +++++- MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs | 8 +------- MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs | 6 ++++-- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index c2183ad7b9..1382527e2d 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -98,6 +98,9 @@ namespace MediaBrowser.Api.Subtitles [ApiMember(Name = "EndPositionTicks", Description = "EndPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public long? EndPositionTicks { get; set; } + + [ApiMember(Name = "CopyTimestamps", Description = "CopyTimestamps", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool CopyTimestamps { get; set; } } [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/subtitles.m3u8", "GET", Summary = "Gets an HLS subtitle playlist.")] @@ -175,7 +178,7 @@ namespace MediaBrowser.Api.Subtitles var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks); - var url = string.Format("stream.vtt?StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}", + var url = string.Format("stream.vtt?CopyTimestamps=true,StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}", positionTicks.ToString(CultureInfo.InvariantCulture), endPositionTicks.ToString(CultureInfo.InvariantCulture), accessToken); @@ -222,6 +225,7 @@ namespace MediaBrowser.Api.Subtitles request.Format, request.StartPositionTicks, request.EndPositionTicks, + request.CopyTimestamps, CancellationToken.None).ConfigureAwait(false); } diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs index e538b84d8f..44489cbf58 100644 --- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs @@ -10,13 +10,6 @@ namespace MediaBrowser.Controller.MediaEncoding /// /// Gets the subtitles. /// - /// The item identifier. - /// The media source identifier. - /// Index of the subtitle stream. - /// The output format. - /// The start time ticks. - /// The end time ticks. - /// The cancellation token. /// Task{Stream}. Task GetSubtitles(string itemId, string mediaSourceId, @@ -24,6 +17,7 @@ namespace MediaBrowser.Controller.MediaEncoding string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken); /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 8c33cc7c0b..25adbcdb0c 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -58,6 +58,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken) { var ms = new MemoryStream(); @@ -68,7 +69,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles var trackInfo = reader.Parse(stream, cancellationToken); - FilterEvents(trackInfo, startTimeTicks, endTimeTicks, false); + FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps); var writer = GetWriter(outputFormat); @@ -116,6 +117,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken) { var subtitle = await GetSubtitleStream(itemId, mediaSourceId, subtitleStreamIndex, cancellationToken) @@ -130,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles using (var stream = subtitle.Item1) { - return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, cancellationToken).ConfigureAwait(false); + return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, preserveOriginalTimestamps, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index bbba06870e..398dcc86bb 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -748,7 +748,7 @@ namespace MediaBrowser.Server.Implementations.Sync _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, cancellationToken).ConfigureAwait(false)) + using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, false, cancellationToken).ConfigureAwait(false)) { using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { -- cgit v1.2.3 From cba6c99d548ba8735de3ffdbc2f6c710a00f096b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 May 2016 14:42:18 -0400 Subject: add null check to sync process --- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 398dcc86bb..886308d43c 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -483,6 +483,11 @@ namespace MediaBrowser.Server.Implementations.Sync private async Task ProcessJobItem(SyncJobItem jobItem, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { + if (jobItem == null) + { + throw new ArgumentNullException("jobItem"); + } + var item = _libraryManager.GetItemById(jobItem.ItemId); if (item == null) { -- cgit v1.2.3 From 4c7f292ba884c16b9e95eb319f3664469189d22c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 11 Jun 2016 11:55:05 -0400 Subject: use individual connections --- .../Notifications/SqliteNotificationsRepository.cs | 443 +++++------ .../Persistence/BaseSqliteRepository.cs | 16 +- .../Persistence/IDbConnector.cs | 2 +- .../SqliteDisplayPreferencesRepository.cs | 256 +++--- .../Persistence/SqliteExtensions.cs | 20 +- .../SqliteFileOrganizationRepository.cs | 4 +- .../Persistence/SqliteItemRepository.cs | 6 +- .../Persistence/SqliteUserDataRepository.cs | 4 +- .../Persistence/SqliteUserRepository.cs | 201 +++-- .../Security/AuthenticationRepository.cs | 325 ++++---- .../Social/SharingRepository.cs | 171 ++-- .../Sync/SyncRepository.cs | 865 ++++++++++----------- 12 files changed, 1114 insertions(+), 1199 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index 10e8c5699e..6c3bc3050e 100644 --- a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs +++ b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -15,30 +15,20 @@ namespace MediaBrowser.Server.Implementations.Notifications { public class SqliteNotificationsRepository : BaseSqliteRepository, INotificationsRepository { - private IDbConnection _connection; - private readonly IServerApplicationPaths _appPaths; + public SqliteNotificationsRepository(ILogManager logManager, IServerApplicationPaths appPaths, IDbConnector dbConnector) : base(logManager, dbConnector) + { + DbFilePath = Path.Combine(appPaths.DataPath, "notifications.db"); + } public event EventHandler NotificationAdded; public event EventHandler NotificationsMarkedRead; public event EventHandler NotificationUpdated; - private IDbCommand _replaceNotificationCommand; - private IDbCommand _markReadCommand; - private IDbCommand _markAllReadCommand; - - public SqliteNotificationsRepository(ILogManager logManager, IServerApplicationPaths appPaths) - : base(logManager) + public async Task Initialize() { - _appPaths = appPaths; - } - - public async Task Initialize(IDbConnector dbConnector) - { - var dbFile = Path.Combine(_appPaths.DataPath, "notifications.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + string[] queries = { "create table if not exists Notifications (Id GUID NOT NULL, UserId GUID NOT NULL, Date DATETIME NOT NULL, Name TEXT NOT NULL, Description TEXT, Url TEXT, Level TEXT NOT NULL, IsRead BOOLEAN NOT NULL, Category TEXT NOT NULL, RelatedId TEXT, PRIMARY KEY (Id, UserId))", "create index if not exists idx_Notifications1 on Notifications(Id)", @@ -50,39 +40,8 @@ namespace MediaBrowser.Server.Implementations.Notifications "pragma shrink_memory" }; - _connection.RunQueries(queries, Logger); - - PrepareStatements(); - } - - private void PrepareStatements() - { - _replaceNotificationCommand = _connection.CreateCommand(); - _replaceNotificationCommand.CommandText = "replace into Notifications (Id, UserId, Date, Name, Description, Url, Level, IsRead, Category, RelatedId) values (@Id, @UserId, @Date, @Name, @Description, @Url, @Level, @IsRead, @Category, @RelatedId)"; - - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Id"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@UserId"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Date"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Name"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Description"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Url"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Level"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Category"); - _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@RelatedId"); - - _markReadCommand = _connection.CreateCommand(); - _markReadCommand.CommandText = "update Notifications set IsRead=@IsRead where Id=@Id and UserId=@UserId"; - - _markReadCommand.Parameters.Add(_replaceNotificationCommand, "@UserId"); - _markReadCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead"); - _markReadCommand.Parameters.Add(_replaceNotificationCommand, "@Id"); - - _markAllReadCommand = _connection.CreateCommand(); - _markAllReadCommand.CommandText = "update Notifications set IsRead=@IsRead where UserId=@UserId"; - - _markAllReadCommand.Parameters.Add(_replaceNotificationCommand, "@UserId"); - _markAllReadCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead"); + connection.RunQueries(queries, Logger); + } } /// @@ -94,49 +53,52 @@ namespace MediaBrowser.Server.Implementations.Notifications { var result = new NotificationResult(); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - var clauses = new List(); - - if (query.IsRead.HasValue) + using (var cmd = connection.CreateCommand()) { - clauses.Add("IsRead=@IsRead"); - cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = query.IsRead.Value; - } + var clauses = new List(); - clauses.Add("UserId=@UserId"); - cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(query.UserId); + if (query.IsRead.HasValue) + { + clauses.Add("IsRead=@IsRead"); + cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = query.IsRead.Value; + } - var whereClause = " where " + string.Join(" And ", clauses.ToArray()); + clauses.Add("UserId=@UserId"); + cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(query.UserId); - cmd.CommandText = string.Format("select count(Id) from Notifications{0};select Id,UserId,Date,Name,Description,Url,Level,IsRead,Category,RelatedId from Notifications{0} order by IsRead asc, Date desc", whereClause); + var whereClause = " where " + string.Join(" And ", clauses.ToArray()); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - if (reader.Read()) - { - result.TotalRecordCount = reader.GetInt32(0); - } + cmd.CommandText = string.Format("select count(Id) from Notifications{0};select Id,UserId,Date,Name,Description,Url,Level,IsRead,Category,RelatedId from Notifications{0} order by IsRead asc, Date desc", whereClause); - if (reader.NextResult()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - var notifications = GetNotifications(reader); - - if (query.StartIndex.HasValue) + if (reader.Read()) { - notifications = notifications.Skip(query.StartIndex.Value); + result.TotalRecordCount = reader.GetInt32(0); } - if (query.Limit.HasValue) + if (reader.NextResult()) { - notifications = notifications.Take(query.Limit.Value); - } + var notifications = GetNotifications(reader); - result.Notifications = notifications.ToArray(); + if (query.StartIndex.HasValue) + { + notifications = notifications.Skip(query.StartIndex.Value); + } + + if (query.Limit.HasValue) + { + notifications = notifications.Take(query.Limit.Value); + } + + result.Notifications = notifications.ToArray(); + } } - } - return result; + return result; + } } } @@ -144,31 +106,34 @@ namespace MediaBrowser.Server.Implementations.Notifications { var result = new NotificationsSummary(); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select Level from Notifications where UserId=@UserId and IsRead=@IsRead"; - - cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(userId); - cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = false; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) + using (var cmd = connection.CreateCommand()) { - var levels = new List(); + cmd.CommandText = "select Level from Notifications where UserId=@UserId and IsRead=@IsRead"; - while (reader.Read()) + cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(userId); + cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = false; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - levels.Add(GetLevel(reader, 0)); - } + var levels = new List(); - result.UnreadCount = levels.Count; + while (reader.Read()) + { + levels.Add(GetLevel(reader, 0)); + } - if (levels.Count > 0) - { - result.MaxUnreadNotificationLevel = levels.Max(); + result.UnreadCount = levels.Count; + + if (levels.Count > 0) + { + result.MaxUnreadNotificationLevel = levels.Max(); + } } - } - return result; + return result; + } } } @@ -179,10 +144,14 @@ namespace MediaBrowser.Server.Implementations.Notifications /// IEnumerable{Notification}. private IEnumerable GetNotifications(IDataReader reader) { + var list = new List(); + while (reader.Read()) { - yield return GetNotification(reader); + list.Add(GetNotification(reader)); } + + return list; } private Notification GetNotification(IDataReader reader) @@ -273,59 +242,74 @@ namespace MediaBrowser.Server.Implementations.Notifications cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); + using (var replaceNotificationCommand = connection.CreateCommand()) + { + replaceNotificationCommand.CommandText = "replace into Notifications (Id, UserId, Date, Name, Description, Url, Level, IsRead, Category, RelatedId) values (@Id, @UserId, @Date, @Name, @Description, @Url, @Level, @IsRead, @Category, @RelatedId)"; + + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Id"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@UserId"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Date"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Name"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Description"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Url"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Level"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@IsRead"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Category"); + replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@RelatedId"); + + IDbTransaction transaction = null; + + try + { + transaction = connection.BeginTransaction(); - _replaceNotificationCommand.GetParameter(0).Value = new Guid(notification.Id); - _replaceNotificationCommand.GetParameter(1).Value = new Guid(notification.UserId); - _replaceNotificationCommand.GetParameter(2).Value = notification.Date.ToUniversalTime(); - _replaceNotificationCommand.GetParameter(3).Value = notification.Name; - _replaceNotificationCommand.GetParameter(4).Value = notification.Description; - _replaceNotificationCommand.GetParameter(5).Value = notification.Url; - _replaceNotificationCommand.GetParameter(6).Value = notification.Level.ToString(); - _replaceNotificationCommand.GetParameter(7).Value = notification.IsRead; - _replaceNotificationCommand.GetParameter(8).Value = string.Empty; - _replaceNotificationCommand.GetParameter(9).Value = string.Empty; + replaceNotificationCommand.GetParameter(0).Value = new Guid(notification.Id); + replaceNotificationCommand.GetParameter(1).Value = new Guid(notification.UserId); + replaceNotificationCommand.GetParameter(2).Value = notification.Date.ToUniversalTime(); + replaceNotificationCommand.GetParameter(3).Value = notification.Name; + replaceNotificationCommand.GetParameter(4).Value = notification.Description; + replaceNotificationCommand.GetParameter(5).Value = notification.Url; + replaceNotificationCommand.GetParameter(6).Value = notification.Level.ToString(); + replaceNotificationCommand.GetParameter(7).Value = notification.IsRead; + replaceNotificationCommand.GetParameter(8).Value = string.Empty; + replaceNotificationCommand.GetParameter(9).Value = string.Empty; - _replaceNotificationCommand.Transaction = transaction; + replaceNotificationCommand.Transaction = transaction; - _replaceNotificationCommand.ExecuteNonQuery(); + replaceNotificationCommand.ExecuteNonQuery(); - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save notification:", e); + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save notification:", e); - if (transaction != null) - { - transaction.Rollback(); - } + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } } - - WriteLock.Release(); } } @@ -366,51 +350,58 @@ namespace MediaBrowser.Server.Implementations.Notifications { cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + using (var markAllReadCommand = connection.CreateCommand()) + { + markAllReadCommand.CommandText = "update Notifications set IsRead=@IsRead where UserId=@UserId"; - IDbTransaction transaction = null; + markAllReadCommand.Parameters.Add(markAllReadCommand, "@UserId"); + markAllReadCommand.Parameters.Add(markAllReadCommand, "@IsRead"); - try - { - cancellationToken.ThrowIfCancellationRequested(); + IDbTransaction transaction = null; - transaction = _connection.BeginTransaction(); + try + { + cancellationToken.ThrowIfCancellationRequested(); - _markAllReadCommand.GetParameter(0).Value = new Guid(userId); - _markAllReadCommand.GetParameter(1).Value = isRead; + transaction = connection.BeginTransaction(); - _markAllReadCommand.ExecuteNonQuery(); + markAllReadCommand.GetParameter(0).Value = new Guid(userId); + markAllReadCommand.GetParameter(1).Value = isRead; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + markAllReadCommand.ExecuteNonQuery(); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save notification:", e); + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); - } + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save notification:", e); - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); - } + if (transaction != null) + { + transaction.Rollback(); + } - WriteLock.Release(); + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } + } } } @@ -418,72 +409,66 @@ namespace MediaBrowser.Server.Implementations.Notifications { cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - cancellationToken.ThrowIfCancellationRequested(); + using (var markReadCommand = connection.CreateCommand()) + { + markReadCommand.CommandText = "update Notifications set IsRead=@IsRead where Id=@Id and UserId=@UserId"; - transaction = _connection.BeginTransaction(); + markReadCommand.Parameters.Add(markReadCommand, "@UserId"); + markReadCommand.Parameters.Add(markReadCommand, "@IsRead"); + markReadCommand.Parameters.Add(markReadCommand, "@Id"); - _markReadCommand.GetParameter(0).Value = new Guid(userId); - _markReadCommand.GetParameter(1).Value = isRead; + IDbTransaction transaction = null; - foreach (var id in notificationIdList) - { - _markReadCommand.GetParameter(2).Value = id; + try + { + cancellationToken.ThrowIfCancellationRequested(); - _markReadCommand.Transaction = transaction; + transaction = connection.BeginTransaction(); - _markReadCommand.ExecuteNonQuery(); - } + markReadCommand.GetParameter(0).Value = new Guid(userId); + markReadCommand.GetParameter(1).Value = isRead; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + foreach (var id in notificationIdList) + { + markReadCommand.GetParameter(2).Value = id; - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save notification:", e); + markReadCommand.Transaction = transaction; - if (transaction != null) - { - transaction.Rollback(); - } + markReadCommand.ExecuteNonQuery(); + } - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); - } + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - WriteLock.Release(); - } - } + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save notification:", e); - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } + if (transaction != null) + { + transaction.Rollback(); + } - _connection.Dispose(); - _connection = null; + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } + } } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs b/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs index 3959078449..f9c892b76a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs @@ -9,13 +9,22 @@ namespace MediaBrowser.Server.Implementations.Persistence public abstract class BaseSqliteRepository : IDisposable { protected readonly SemaphoreSlim WriteLock = new SemaphoreSlim(1, 1); + protected readonly IDbConnector DbConnector; protected ILogger Logger; - protected BaseSqliteRepository(ILogManager logManager) + protected string DbFilePath { get; set; } + + protected BaseSqliteRepository(ILogManager logManager, IDbConnector dbConnector) { + DbConnector = dbConnector; Logger = logManager.GetLogger(GetType().Name); } + protected Task CreateConnection(bool isReadOnly = false) + { + return DbConnector.Connect(DbFilePath, false, true); + } + private bool _disposed; protected void CheckDisposed() { @@ -84,6 +93,9 @@ namespace MediaBrowser.Server.Implementations.Persistence } } - protected abstract void CloseConnection(); + protected virtual void CloseConnection() + { + + } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs index 2092f830a7..596cf8407a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs +++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs @@ -5,6 +5,6 @@ namespace MediaBrowser.Server.Implementations.Persistence { public interface IDbConnector { - Task Connect(string dbPath, int? cacheSize = null); + Task Connect(string dbPath, bool isReadOnly, bool enablePooling = false, int? cacheSize = null); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs index 6077cfdba4..1a6a88ebe2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs @@ -18,12 +18,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository { - private IDbConnection _connection; - - public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths) : base(logManager) + public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IDbConnector dbConnector) + : base(logManager, dbConnector) { _jsonSerializer = jsonSerializer; - _appPaths = appPaths; + DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db"); } /// @@ -43,22 +42,15 @@ namespace MediaBrowser.Server.Implementations.Persistence /// private readonly IJsonSerializer _jsonSerializer; - /// - /// The _app paths - /// - private readonly IApplicationPaths _appPaths; - /// /// Opens the connection to the database /// /// Task. - public async Task Initialize(IDbConnector dbConnector) + public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + string[] queries = { "create table if not exists userdisplaypreferences (id GUID, userId GUID, client text, data BLOB)", "create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)", @@ -69,7 +61,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "pragma shrink_memory" }; - _connection.RunQueries(queries, Logger); + connection.RunQueries(queries, Logger); + } } /// @@ -96,58 +89,57 @@ namespace MediaBrowser.Server.Implementations.Persistence var serialized = _jsonSerializer.SerializeToBytes(displayPreferences); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); + IDbTransaction transaction = null; - using (var cmd = _connection.CreateCommand()) + try { - cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)"; + transaction = connection.BeginTransaction(); + + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)"; - cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = new Guid(displayPreferences.Id); - cmd.Parameters.Add(cmd, "@2", DbType.Guid).Value = userId; - cmd.Parameters.Add(cmd, "@3", DbType.String).Value = client; - cmd.Parameters.Add(cmd, "@4", DbType.Binary).Value = serialized; + cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = new Guid(displayPreferences.Id); + cmd.Parameters.Add(cmd, "@2", DbType.Guid).Value = userId; + cmd.Parameters.Add(cmd, "@3", DbType.String).Value = client; + cmd.Parameters.Add(cmd, "@4", DbType.Binary).Value = serialized; - cmd.Transaction = transaction; + cmd.Transaction = transaction; - cmd.ExecuteNonQuery(); - } + cmd.ExecuteNonQuery(); + } - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + transaction.Commit(); + } + catch (OperationCanceledException) { - transaction.Rollback(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Failed to save display preferences:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save display preferences:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } @@ -168,64 +160,63 @@ namespace MediaBrowser.Server.Implementations.Persistence cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); + IDbTransaction transaction = null; - foreach (var displayPreference in displayPreferences) + try { + transaction = connection.BeginTransaction(); - var serialized = _jsonSerializer.SerializeToBytes(displayPreference); - - using (var cmd = _connection.CreateCommand()) + foreach (var displayPreference in displayPreferences) { - cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)"; - cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = new Guid(displayPreference.Id); - cmd.Parameters.Add(cmd, "@2", DbType.Guid).Value = userId; - cmd.Parameters.Add(cmd, "@3", DbType.String).Value = displayPreference.Client; - cmd.Parameters.Add(cmd, "@4", DbType.Binary).Value = serialized; + var serialized = _jsonSerializer.SerializeToBytes(displayPreference); - cmd.Transaction = transaction; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)"; - cmd.ExecuteNonQuery(); + cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = new Guid(displayPreference.Id); + cmd.Parameters.Add(cmd, "@2", DbType.Guid).Value = userId; + cmd.Parameters.Add(cmd, "@3", DbType.String).Value = displayPreference.Client; + cmd.Parameters.Add(cmd, "@4", DbType.Binary).Value = serialized; + + cmd.Transaction = transaction; + + cmd.ExecuteNonQuery(); + } } - } - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + transaction.Commit(); + } + catch (OperationCanceledException) { - transaction.Rollback(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Failed to save display preferences:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save display preferences:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } @@ -246,28 +237,33 @@ namespace MediaBrowser.Server.Implementations.Persistence var guidId = displayPreferencesId.GetMD5(); - var cmd = _connection.CreateCommand(); - cmd.CommandText = "select data from userdisplaypreferences where id = @id and userId=@userId and client=@client"; - - cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = guidId; - cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; - cmd.Parameters.Add(cmd, "@client", DbType.String).Value = client; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) + using (var connection = CreateConnection(true).Result) { - if (reader.Read()) + using (var cmd = connection.CreateCommand()) { - using (var stream = reader.GetMemoryStream(0)) + cmd.CommandText = "select data from userdisplaypreferences where id = @id and userId=@userId and client=@client"; + + cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = guidId; + cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; + cmd.Parameters.Add(cmd, "@client", DbType.String).Value = client; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) { - return _jsonSerializer.DeserializeFromStream(stream); + if (reader.Read()) + { + using (var stream = reader.GetMemoryStream(0)) + { + return _jsonSerializer.DeserializeFromStream(stream); + } + } } + + return new DisplayPreferences + { + Id = guidId.ToString("N") + }; } } - - return new DisplayPreferences - { - Id = guidId.ToString("N") - }; } /// @@ -278,36 +274,30 @@ namespace MediaBrowser.Server.Implementations.Persistence /// item public IEnumerable GetAllDisplayPreferences(Guid userId) { + var list = new List(); - var cmd = _connection.CreateCommand(); - cmd.CommandText = "select data from userdisplaypreferences where userId=@userId"; - - cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + using (var connection = CreateConnection(true).Result) { - while (reader.Read()) + using (var cmd = connection.CreateCommand()) { - using (var stream = reader.GetMemoryStream(0)) + cmd.CommandText = "select data from userdisplaypreferences where userId=@userId"; + + cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - yield return _jsonSerializer.DeserializeFromStream(stream); + while (reader.Read()) + { + using (var stream = reader.GetMemoryStream(0)) + { + list.Add(_jsonSerializer.DeserializeFromStream(stream)); + } + } } } } - } - - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } - _connection.Dispose(); - _connection = null; - } + return list; } public Task SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs index 2f3f34aa4c..cc9e3ebccf 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs @@ -19,11 +19,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// /// Connects to db. /// - /// The db path. - /// The logger. - /// Task{IDbConnection}. - /// dbPath - public static async Task ConnectToDb(string dbPath, int? cacheSize, ILogger logger) + public static async Task ConnectToDb(string dbPath, bool isReadOnly, bool enablePooling, int? cacheSize, ILogger logger) { if (string.IsNullOrEmpty(dbPath)) { @@ -38,7 +34,9 @@ namespace MediaBrowser.Server.Implementations.Persistence CacheSize = cacheSize ?? 2000, SyncMode = SynchronizationModes.Normal, DataSource = dbPath, - JournalMode = SQLiteJournalModeEnum.Wal + JournalMode = SQLiteJournalModeEnum.Wal, + Pooling = enablePooling, + ReadOnly = isReadOnly }; var connection = new SQLiteConnection(connectionstr.ConnectionString); @@ -47,15 +45,5 @@ namespace MediaBrowser.Server.Implementations.Persistence return connection; } - - public static void BindFunction(this SQLiteConnection connection, SQLiteFunction function) - { - var attributes = function.GetType().GetCustomAttributes(typeof(SQLiteFunctionAttribute), true).Cast().ToArray(); - if (attributes.Length == 0) - { - throw new InvalidOperationException("SQLiteFunction doesn't have SQLiteFunctionAttribute"); - } - connection.BindFunction(attributes[0], function); - } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs index 037776997e..8a4ba6460d 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs @@ -26,7 +26,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deleteResultCommand; private IDbCommand _deleteAllCommand; - public SqliteFileOrganizationRepository(ILogManager logManager, IServerApplicationPaths appPaths) : base(logManager) + public SqliteFileOrganizationRepository(ILogManager logManager, IServerApplicationPaths appPaths, IDbConnector connector) : base(logManager, connector) { _appPaths = appPaths; } @@ -39,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_appPaths.DataPath, "fileorganization.db"); - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile, false).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 071951018d..9bfdd879da 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -99,8 +99,8 @@ namespace MediaBrowser.Server.Implementations.Persistence /// /// Initializes a new instance of the class. /// - public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager) - : base(logManager) + public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager, IDbConnector connector) + : base(logManager, connector) { if (config == null) { @@ -127,7 +127,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_config.ApplicationPaths.DataPath, "library.db"); - _connection = await dbConnector.Connect(dbFile, 6000).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile, false, false, 6000).ConfigureAwait(false); var createMediaStreamsTableCommand = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index bfdb9e0c7a..d81f4ad37b 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbConnection _connection; private readonly IApplicationPaths _appPaths; - public SqliteUserDataRepository(ILogManager logManager, IApplicationPaths appPaths) : base(logManager) + public SqliteUserDataRepository(ILogManager logManager, IApplicationPaths appPaths, IDbConnector connector) : base(logManager, connector) { _appPaths = appPaths; } @@ -43,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db"); - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile, false).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs index f7ca39a548..4c07a60181 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs @@ -17,14 +17,13 @@ namespace MediaBrowser.Server.Implementations.Persistence /// public class SqliteUserRepository : BaseSqliteRepository, IUserRepository { - private IDbConnection _connection; - private readonly IServerApplicationPaths _appPaths; private readonly IJsonSerializer _jsonSerializer; - public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer) : base(logManager) + public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IDbConnector dbConnector) : base(logManager, dbConnector) { - _appPaths = appPaths; _jsonSerializer = jsonSerializer; + + DbFilePath = Path.Combine(appPaths.DataPath, "users.db"); } /// @@ -43,13 +42,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize(IDbConnector dbConnector) + public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "users.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + string[] queries = { "create table if not exists users (guid GUID primary key, data BLOB)", "create index if not exists idx_users on users(guid)", @@ -61,7 +58,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "pragma shrink_memory" }; - _connection.RunQueries(queries, Logger); + connection.RunQueries(queries, Logger); + } } /// @@ -84,55 +82,54 @@ namespace MediaBrowser.Server.Implementations.Persistence cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); + IDbTransaction transaction = null; - using (var cmd = _connection.CreateCommand()) + try { - cmd.CommandText = "replace into users (guid, data) values (@1, @2)"; - cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = user.Id; - cmd.Parameters.Add(cmd, "@2", DbType.Binary).Value = serialized; + transaction = connection.BeginTransaction(); - cmd.Transaction = transaction; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "replace into users (guid, data) values (@1, @2)"; + cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = user.Id; + cmd.Parameters.Add(cmd, "@2", DbType.Binary).Value = serialized; - cmd.ExecuteNonQuery(); - } + cmd.Transaction = transaction; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + cmd.ExecuteNonQuery(); + } + + transaction.Commit(); + } + catch (OperationCanceledException) { - transaction.Rollback(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Failed to save user:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save user:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } @@ -142,25 +139,32 @@ namespace MediaBrowser.Server.Implementations.Persistence /// IEnumerable{User}. public IEnumerable RetrieveAllUsers() { - using (var cmd = _connection.CreateCommand()) - { - cmd.CommandText = "select guid,data from users"; + var list = new List(); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + using (var connection = CreateConnection(true).Result) + { + using (var cmd = connection.CreateCommand()) { - while (reader.Read()) - { - var id = reader.GetGuid(0); + cmd.CommandText = "select guid,data from users"; - using (var stream = reader.GetMemoryStream(1)) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) { - var user = _jsonSerializer.DeserializeFromStream(stream); - user.Id = id; - yield return user; + var id = reader.GetGuid(0); + + using (var stream = reader.GetMemoryStream(1)) + { + var user = _jsonSerializer.DeserializeFromStream(stream); + user.Id = id; + list.Add(user); + } } } } } + + return list; } /// @@ -179,69 +183,54 @@ namespace MediaBrowser.Server.Implementations.Persistence cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); + IDbTransaction transaction = null; - using (var cmd = _connection.CreateCommand()) + try { - cmd.CommandText = "delete from users where guid=@guid"; - - cmd.Parameters.Add(cmd, "@guid", DbType.Guid).Value = user.Id; + transaction = connection.BeginTransaction(); - cmd.Transaction = transaction; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "delete from users where guid=@guid"; - cmd.ExecuteNonQuery(); - } + cmd.Parameters.Add(cmd, "@guid", DbType.Guid).Value = user.Id; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + cmd.Transaction = transaction; - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to delete user:", e); + cmd.ExecuteNonQuery(); + } - if (transaction != null) - { - transaction.Rollback(); + transaction.Commit(); } - - throw; - } - finally - { - if (transaction != null) + catch (OperationCanceledException) { - transaction.Dispose(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Failed to delete user:", e); - WriteLock.Release(); - } - } + if (transaction != null) + { + transaction.Rollback(); + } - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) + throw; + } + finally { - _connection.Close(); + if (transaction != null) + { + transaction.Dispose(); + } } - - _connection.Dispose(); - _connection = null; } } } diff --git a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs index e8d9814ecb..3013510de1 100644 --- a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs +++ b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs @@ -15,25 +15,21 @@ namespace MediaBrowser.Server.Implementations.Security { public class AuthenticationRepository : BaseSqliteRepository, IAuthenticationRepository { - private IDbConnection _connection; private readonly IServerApplicationPaths _appPaths; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private IDbCommand _saveInfoCommand; - - public AuthenticationRepository(ILogManager logManager, IServerApplicationPaths appPaths) - : base(logManager) + public AuthenticationRepository(ILogManager logManager, IServerApplicationPaths appPaths, IDbConnector connector) + : base(logManager, connector) { _appPaths = appPaths; + DbFilePath = Path.Combine(appPaths.DataPath, "authentication.db"); } - public async Task Initialize(IDbConnector dbConnector) + public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "authentication.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + string[] queries = { "create table if not exists AccessTokens (Id GUID PRIMARY KEY, AccessToken TEXT NOT NULL, DeviceId TEXT, AppName TEXT, AppVersion TEXT, DeviceName TEXT, UserId TEXT, IsActive BIT, DateCreated DATETIME NOT NULL, DateRevoked DATETIME)", "create index if not exists idx_AccessTokens on AccessTokens(Id)", @@ -44,28 +40,10 @@ namespace MediaBrowser.Server.Implementations.Security "pragma shrink_memory" }; - _connection.RunQueries(queries, Logger); - - _connection.AddColumn(Logger, "AccessTokens", "AppVersion", "TEXT"); + connection.RunQueries(queries, Logger); - PrepareStatements(); - } - - private void PrepareStatements() - { - _saveInfoCommand = _connection.CreateCommand(); - _saveInfoCommand.CommandText = "replace into AccessTokens (Id, AccessToken, DeviceId, AppName, AppVersion, DeviceName, UserId, IsActive, DateCreated, DateRevoked) values (@Id, @AccessToken, @DeviceId, @AppName, @AppVersion, @DeviceName, @UserId, @IsActive, @DateCreated, @DateRevoked)"; - - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@Id"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@AccessToken"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@DeviceId"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@AppName"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@AppVersion"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@DeviceName"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@UserId"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@IsActive"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@DateCreated"); - _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@DateRevoked"); + connection.AddColumn(Logger, "AccessTokens", "AppVersion", "TEXT"); + } } public Task Create(AuthenticationInfo info, CancellationToken cancellationToken) @@ -84,61 +62,76 @@ namespace MediaBrowser.Server.Implementations.Security cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); + using (var saveInfoCommand = connection.CreateCommand()) + { + saveInfoCommand.CommandText = "replace into AccessTokens (Id, AccessToken, DeviceId, AppName, AppVersion, DeviceName, UserId, IsActive, DateCreated, DateRevoked) values (@Id, @AccessToken, @DeviceId, @AppName, @AppVersion, @DeviceName, @UserId, @IsActive, @DateCreated, @DateRevoked)"; + + saveInfoCommand.Parameters.Add(saveInfoCommand, "@Id"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@AccessToken"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@DeviceId"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@AppName"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@AppVersion"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@DeviceName"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@UserId"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@IsActive"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@DateCreated"); + saveInfoCommand.Parameters.Add(saveInfoCommand, "@DateRevoked"); + + IDbTransaction transaction = null; + + try + { + transaction = connection.BeginTransaction(); - var index = 0; + var index = 0; - _saveInfoCommand.GetParameter(index++).Value = new Guid(info.Id); - _saveInfoCommand.GetParameter(index++).Value = info.AccessToken; - _saveInfoCommand.GetParameter(index++).Value = info.DeviceId; - _saveInfoCommand.GetParameter(index++).Value = info.AppName; - _saveInfoCommand.GetParameter(index++).Value = info.AppVersion; - _saveInfoCommand.GetParameter(index++).Value = info.DeviceName; - _saveInfoCommand.GetParameter(index++).Value = info.UserId; - _saveInfoCommand.GetParameter(index++).Value = info.IsActive; - _saveInfoCommand.GetParameter(index++).Value = info.DateCreated; - _saveInfoCommand.GetParameter(index++).Value = info.DateRevoked; + saveInfoCommand.GetParameter(index++).Value = new Guid(info.Id); + saveInfoCommand.GetParameter(index++).Value = info.AccessToken; + saveInfoCommand.GetParameter(index++).Value = info.DeviceId; + saveInfoCommand.GetParameter(index++).Value = info.AppName; + saveInfoCommand.GetParameter(index++).Value = info.AppVersion; + saveInfoCommand.GetParameter(index++).Value = info.DeviceName; + saveInfoCommand.GetParameter(index++).Value = info.UserId; + saveInfoCommand.GetParameter(index++).Value = info.IsActive; + saveInfoCommand.GetParameter(index++).Value = info.DateCreated; + saveInfoCommand.GetParameter(index++).Value = info.DateRevoked; - _saveInfoCommand.Transaction = transaction; + saveInfoCommand.Transaction = transaction; - _saveInfoCommand.ExecuteNonQuery(); + saveInfoCommand.ExecuteNonQuery(); - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save record:", e); + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save record:", e); - if (transaction != null) - { - transaction.Rollback(); - } + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } } - - WriteLock.Release(); } } @@ -151,101 +144,104 @@ namespace MediaBrowser.Server.Implementations.Security throw new ArgumentNullException("query"); } - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = BaseSelectText; - - var whereClauses = new List(); - - var startIndex = query.StartIndex ?? 0; - - if (!string.IsNullOrWhiteSpace(query.AccessToken)) + using (var cmd = connection.CreateCommand()) { - whereClauses.Add("AccessToken=@AccessToken"); - cmd.Parameters.Add(cmd, "@AccessToken", DbType.String).Value = query.AccessToken; - } + cmd.CommandText = BaseSelectText; - if (!string.IsNullOrWhiteSpace(query.UserId)) - { - whereClauses.Add("UserId=@UserId"); - cmd.Parameters.Add(cmd, "@UserId", DbType.String).Value = query.UserId; - } + var whereClauses = new List(); - if (!string.IsNullOrWhiteSpace(query.DeviceId)) - { - whereClauses.Add("DeviceId=@DeviceId"); - cmd.Parameters.Add(cmd, "@DeviceId", DbType.String).Value = query.DeviceId; - } + var startIndex = query.StartIndex ?? 0; - if (query.IsActive.HasValue) - { - whereClauses.Add("IsActive=@IsActive"); - cmd.Parameters.Add(cmd, "@IsActive", DbType.Boolean).Value = query.IsActive.Value; - } + if (!string.IsNullOrWhiteSpace(query.AccessToken)) + { + whereClauses.Add("AccessToken=@AccessToken"); + cmd.Parameters.Add(cmd, "@AccessToken", DbType.String).Value = query.AccessToken; + } - if (query.HasUser.HasValue) - { - if (query.HasUser.Value) + if (!string.IsNullOrWhiteSpace(query.UserId)) { - whereClauses.Add("UserId not null"); + whereClauses.Add("UserId=@UserId"); + cmd.Parameters.Add(cmd, "@UserId", DbType.String).Value = query.UserId; } - else + + if (!string.IsNullOrWhiteSpace(query.DeviceId)) { - whereClauses.Add("UserId is null"); + whereClauses.Add("DeviceId=@DeviceId"); + cmd.Parameters.Add(cmd, "@DeviceId", DbType.String).Value = query.DeviceId; } - } - var whereTextWithoutPaging = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + if (query.IsActive.HasValue) + { + whereClauses.Add("IsActive=@IsActive"); + cmd.Parameters.Add(cmd, "@IsActive", DbType.Boolean).Value = query.IsActive.Value; + } - if (startIndex > 0) - { - var pagingWhereText = whereClauses.Count == 0 ? + if (query.HasUser.HasValue) + { + if (query.HasUser.Value) + { + whereClauses.Add("UserId not null"); + } + else + { + whereClauses.Add("UserId is null"); + } + } + + var whereTextWithoutPaging = whereClauses.Count == 0 ? string.Empty : " where " + string.Join(" AND ", whereClauses.ToArray()); - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM AccessTokens {0} ORDER BY DateCreated LIMIT {1})", - pagingWhereText, - startIndex.ToString(_usCulture))); - } + if (startIndex > 0) + { + var pagingWhereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); + + whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM AccessTokens {0} ORDER BY DateCreated LIMIT {1})", + pagingWhereText, + startIndex.ToString(_usCulture))); + } - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += whereText; + cmd.CommandText += whereText; - cmd.CommandText += " ORDER BY DateCreated"; + cmd.CommandText += " ORDER BY DateCreated"; - if (query.Limit.HasValue) - { - cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture); - } + if (query.Limit.HasValue) + { + cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture); + } - cmd.CommandText += "; select count (Id) from AccessTokens" + whereTextWithoutPaging; + cmd.CommandText += "; select count (Id) from AccessTokens" + whereTextWithoutPaging; - var list = new List(); - var count = 0; + var list = new List(); + var count = 0; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - list.Add(Get(reader)); + while (reader.Read()) + { + list.Add(Get(reader)); + } + + if (reader.NextResult() && reader.Read()) + { + count = reader.GetInt32(0); + } } - if (reader.NextResult() && reader.Read()) + return new QueryResult() { - count = reader.GetInt32(0); - } + Items = list.ToArray(), + TotalRecordCount = count + }; } - - return new QueryResult() - { - Items = list.ToArray(), - TotalRecordCount = count - }; } } @@ -256,24 +252,27 @@ namespace MediaBrowser.Server.Implementations.Security throw new ArgumentNullException("id"); } - var guid = new Guid(id); - - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = BaseSelectText + " where Id=@Id"; - - cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid; + var guid = new Guid(id); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) + using (var cmd = connection.CreateCommand()) { - if (reader.Read()) + cmd.CommandText = BaseSelectText + " where Id=@Id"; + + cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) { - return Get(reader); + if (reader.Read()) + { + return Get(reader); + } } } - } - return null; + return null; + } } private AuthenticationInfo Get(IDataReader reader) @@ -319,19 +318,5 @@ namespace MediaBrowser.Server.Implementations.Security return info; } - - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } - - _connection.Dispose(); - _connection = null; - } - } } } diff --git a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs index 317743eb1b..8a895037e7 100644 --- a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs +++ b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs @@ -12,27 +12,21 @@ namespace MediaBrowser.Server.Implementations.Social { public class SharingRepository : BaseSqliteRepository { - private IDbConnection _connection; - private IDbCommand _saveShareCommand; - private readonly IApplicationPaths _appPaths; - - public SharingRepository(ILogManager logManager, IApplicationPaths appPaths) - : base(logManager) + public SharingRepository(ILogManager logManager, IApplicationPaths appPaths, IDbConnector dbConnector) + : base(logManager, dbConnector) { - _appPaths = appPaths; + DbFilePath = Path.Combine(appPaths.DataPath, "shares.db"); } /// /// Opens the connection to the database /// /// Task. - public async Task Initialize(IDbConnector dbConnector) + public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "shares.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + string[] queries = { "create table if not exists Shares (Id GUID, ItemId TEXT, UserId TEXT, ExpirationDate DateTime, PRIMARY KEY (Id))", "create index if not exists idx_Shares on Shares(Id)", @@ -43,23 +37,8 @@ namespace MediaBrowser.Server.Implementations.Social "pragma shrink_memory" }; - _connection.RunQueries(queries, Logger); - - PrepareStatements(); - } - - /// - /// Prepares the statements. - /// - private void PrepareStatements() - { - _saveShareCommand = _connection.CreateCommand(); - _saveShareCommand.CommandText = "replace into Shares (Id, ItemId, UserId, ExpirationDate) values (@Id, @ItemId, @UserId, @ExpirationDate)"; - - _saveShareCommand.Parameters.Add(_saveShareCommand, "@Id"); - _saveShareCommand.Parameters.Add(_saveShareCommand, "@ItemId"); - _saveShareCommand.Parameters.Add(_saveShareCommand, "@UserId"); - _saveShareCommand.Parameters.Add(_saveShareCommand, "@ExpirationDate"); + connection.RunQueries(queries, Logger); + } } public async Task CreateShare(SocialShareInfo info) @@ -77,53 +56,62 @@ namespace MediaBrowser.Server.Implementations.Social cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); - - _saveShareCommand.GetParameter(0).Value = new Guid(info.Id); - _saveShareCommand.GetParameter(1).Value = info.ItemId; - _saveShareCommand.GetParameter(2).Value = info.UserId; - _saveShareCommand.GetParameter(3).Value = info.ExpirationDate; - - _saveShareCommand.Transaction = transaction; - - _saveShareCommand.ExecuteNonQuery(); - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + using (var saveShareCommand = connection.CreateCommand()) { - transaction.Rollback(); + saveShareCommand.CommandText = "replace into Shares (Id, ItemId, UserId, ExpirationDate) values (@Id, @ItemId, @UserId, @ExpirationDate)"; + + saveShareCommand.Parameters.Add(saveShareCommand, "@Id"); + saveShareCommand.Parameters.Add(saveShareCommand, "@ItemId"); + saveShareCommand.Parameters.Add(saveShareCommand, "@UserId"); + saveShareCommand.Parameters.Add(saveShareCommand, "@ExpirationDate"); + + IDbTransaction transaction = null; + + try + { + transaction = connection.BeginTransaction(); + + saveShareCommand.GetParameter(0).Value = new Guid(info.Id); + saveShareCommand.GetParameter(1).Value = info.ItemId; + saveShareCommand.GetParameter(2).Value = info.UserId; + saveShareCommand.GetParameter(3).Value = info.ExpirationDate; + + saveShareCommand.Transaction = transaction; + + saveShareCommand.ExecuteNonQuery(); + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save share:", e); + + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } } - - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save share:", e); - - if (transaction != null) - { - transaction.Rollback(); - } - - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); - } - - WriteLock.Release(); } } @@ -134,20 +122,23 @@ namespace MediaBrowser.Server.Implementations.Social throw new ArgumentNullException("id"); } - var cmd = _connection.CreateCommand(); - cmd.CommandText = "select Id, ItemId, UserId, ExpirationDate from Shares where id = @id"; + using (var connection = CreateConnection(true).Result) + { + var cmd = connection.CreateCommand(); + cmd.CommandText = "select Id, ItemId, UserId, ExpirationDate from Shares where id = @id"; - cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = new Guid(id); + cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = new Guid(id); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) - { - if (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) { - return GetSocialShareInfo(reader); + if (reader.Read()) + { + return GetSocialShareInfo(reader); + } } - } - return null; + return null; + } } private SocialShareInfo GetSocialShareInfo(IDataReader reader) @@ -164,21 +155,7 @@ namespace MediaBrowser.Server.Implementations.Social public async Task DeleteShare(string id) { - - } - - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } - _connection.Dispose(); - _connection = null; - } } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 739d1ab6e6..5b623cf2ad 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -18,34 +18,22 @@ namespace MediaBrowser.Server.Implementations.Sync { public class SyncRepository : BaseSqliteRepository, ISyncRepository { - private IDbConnection _connection; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private IDbCommand _insertJobCommand; - private IDbCommand _updateJobCommand; - private IDbCommand _deleteJobCommand; - - private IDbCommand _deleteJobItemsCommand; - private IDbCommand _insertJobItemCommand; - private IDbCommand _updateJobItemCommand; - private readonly IJsonSerializer _json; - private readonly IServerApplicationPaths _appPaths; - public SyncRepository(ILogManager logManager, IJsonSerializer json, IServerApplicationPaths appPaths) - : base(logManager) + public SyncRepository(ILogManager logManager, IJsonSerializer json, IServerApplicationPaths appPaths, IDbConnector connector) + : base(logManager, connector) { _json = json; - _appPaths = appPaths; + DbFilePath = Path.Combine(appPaths.DataPath, "sync14.db"); } - public async Task Initialize(IDbConnector dbConnector) + public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "sync14.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + string[] queries = { "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Profile TEXT, Quality TEXT, Bitrate INT, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", @@ -61,114 +49,12 @@ namespace MediaBrowser.Server.Implementations.Sync "pragma shrink_memory" }; - _connection.RunQueries(queries, Logger); - - _connection.AddColumn(Logger, "SyncJobs", "Profile", "TEXT"); - _connection.AddColumn(Logger, "SyncJobs", "Bitrate", "INT"); - _connection.AddColumn(Logger, "SyncJobItems", "ItemDateModifiedTicks", "BIGINT"); + connection.RunQueries(queries, Logger); - PrepareStatements(); - } - - private void PrepareStatements() - { - // _deleteJobCommand - _deleteJobCommand = _connection.CreateCommand(); - _deleteJobCommand.CommandText = "delete from SyncJobs where Id=@Id"; - _deleteJobCommand.Parameters.Add(_deleteJobCommand, "@Id"); - - // _deleteJobItemsCommand - _deleteJobItemsCommand = _connection.CreateCommand(); - _deleteJobItemsCommand.CommandText = "delete from SyncJobItems where JobId=@JobId"; - _deleteJobItemsCommand.Parameters.Add(_deleteJobItemsCommand, "@JobId"); - - // _insertJobCommand - _insertJobCommand = _connection.CreateCommand(); - _insertJobCommand.CommandText = "insert into SyncJobs (Id, TargetId, Name, Profile, Quality, Bitrate, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Profile, @Quality, @Bitrate, @Status, @Progress, @UserId, @ItemIds, @Category, @ParentId, @UnwatchedOnly, @ItemLimit, @SyncNewContent, @DateCreated, @DateLastModified, @ItemCount)"; - - _insertJobCommand.Parameters.Add(_insertJobCommand, "@Id"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@TargetId"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@Name"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@Profile"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@Quality"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@Bitrate"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@Status"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@Progress"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@UserId"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@ItemIds"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@Category"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@ParentId"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@UnwatchedOnly"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@ItemLimit"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@SyncNewContent"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@DateCreated"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@DateLastModified"); - _insertJobCommand.Parameters.Add(_insertJobCommand, "@ItemCount"); - - // _updateJobCommand - _updateJobCommand = _connection.CreateCommand(); - _updateJobCommand.CommandText = "update SyncJobs set TargetId=@TargetId,Name=@Name,Profile=@Profile,Quality=@Quality,Bitrate=@Bitrate,Status=@Status,Progress=@Progress,UserId=@UserId,ItemIds=@ItemIds,Category=@Category,ParentId=@ParentId,UnwatchedOnly=@UnwatchedOnly,ItemLimit=@ItemLimit,SyncNewContent=@SyncNewContent,DateCreated=@DateCreated,DateLastModified=@DateLastModified,ItemCount=@ItemCount where Id=@Id"; - - _updateJobCommand.Parameters.Add(_updateJobCommand, "@Id"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@TargetId"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@Name"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@Profile"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@Quality"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@Bitrate"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@Status"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@Progress"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@UserId"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@ItemIds"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@Category"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@ParentId"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@UnwatchedOnly"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@ItemLimit"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@SyncNewContent"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@DateCreated"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@DateLastModified"); - _updateJobCommand.Parameters.Add(_updateJobCommand, "@ItemCount"); - - // _insertJobItemCommand - _insertJobItemCommand = _connection.CreateCommand(); - _insertJobItemCommand.CommandText = "insert into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex, ItemDateModifiedTicks) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex, @ItemDateModifiedTicks)"; - - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@Id"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemId"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemName"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@MediaSourceId"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@JobId"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@TemporaryPath"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@OutputPath"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@Status"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@TargetId"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@DateCreated"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@Progress"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@AdditionalFiles"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@MediaSource"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@IsMarkedForRemoval"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@JobItemIndex"); - _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemDateModifiedTicks"); - - // _updateJobItemCommand - _updateJobItemCommand = _connection.CreateCommand(); - _updateJobItemCommand.CommandText = "update SyncJobItems set ItemId=@ItemId,ItemName=@ItemName,MediaSourceId=@MediaSourceId,JobId=@JobId,TemporaryPath=@TemporaryPath,OutputPath=@OutputPath,Status=@Status,TargetId=@TargetId,DateCreated=@DateCreated,Progress=@Progress,AdditionalFiles=@AdditionalFiles,MediaSource=@MediaSource,IsMarkedForRemoval=@IsMarkedForRemoval,JobItemIndex=@JobItemIndex,ItemDateModifiedTicks=@ItemDateModifiedTicks where Id=@Id"; - - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@Id"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemId"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemName"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@MediaSourceId"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@JobId"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@TemporaryPath"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@OutputPath"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@Status"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@TargetId"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@DateCreated"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@Progress"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@AdditionalFiles"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@MediaSource"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@IsMarkedForRemoval"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@JobItemIndex"); - _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemDateModifiedTicks"); + connection.AddColumn(Logger, "SyncJobs", "Profile", "TEXT"); + connection.AddColumn(Logger, "SyncJobs", "Bitrate", "INT"); + connection.AddColumn(Logger, "SyncJobItems", "ItemDateModifiedTicks", "BIGINT"); + } } private const string BaseJobSelectText = "select Id, TargetId, Name, Profile, Quality, Bitrate, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; @@ -182,7 +68,7 @@ namespace MediaBrowser.Server.Implementations.Sync } CheckDisposed(); - + var guid = new Guid(id); if (guid == Guid.Empty) @@ -190,22 +76,25 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentNullException("id"); } - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = BaseJobSelectText + " where Id=@Id"; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = BaseJobSelectText + " where Id=@Id"; - cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid; + cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) - { - if (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) { - return GetJob(reader); + if (reader.Read()) + { + return GetJob(reader); + } } } - } - return null; + return null; + } } private SyncJob GetJob(IDataReader reader) @@ -283,15 +172,15 @@ namespace MediaBrowser.Server.Implementations.Sync public Task Create(SyncJob job) { - return InsertOrUpdate(job, _insertJobCommand); + return InsertOrUpdate(job, true); } public Task Update(SyncJob job) { - return InsertOrUpdate(job, _updateJobCommand); + return InsertOrUpdate(job, false); } - private async Task InsertOrUpdate(SyncJob job, IDbCommand cmd) + private async Task InsertOrUpdate(SyncJob job, bool insert) { if (job == null) { @@ -299,70 +188,119 @@ namespace MediaBrowser.Server.Implementations.Sync } CheckDisposed(); - - await WriteLock.WaitAsync().ConfigureAwait(false); - - IDbTransaction transaction = null; - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); - - var index = 0; - - cmd.GetParameter(index++).Value = new Guid(job.Id); - cmd.GetParameter(index++).Value = job.TargetId; - cmd.GetParameter(index++).Value = job.Name; - cmd.GetParameter(index++).Value = job.Profile; - cmd.GetParameter(index++).Value = job.Quality; - cmd.GetParameter(index++).Value = job.Bitrate; - cmd.GetParameter(index++).Value = job.Status.ToString(); - cmd.GetParameter(index++).Value = job.Progress; - cmd.GetParameter(index++).Value = job.UserId; - cmd.GetParameter(index++).Value = string.Join(",", job.RequestedItemIds.ToArray()); - cmd.GetParameter(index++).Value = job.Category; - cmd.GetParameter(index++).Value = job.ParentId; - cmd.GetParameter(index++).Value = job.UnwatchedOnly; - cmd.GetParameter(index++).Value = job.ItemLimit; - cmd.GetParameter(index++).Value = job.SyncNewContent; - cmd.GetParameter(index++).Value = job.DateCreated; - cmd.GetParameter(index++).Value = job.DateLastModified; - cmd.GetParameter(index++).Value = job.ItemCount; - - cmd.Transaction = transaction; + using (var cmd = connection.CreateCommand()) + { + if (insert) + { + cmd.CommandText = "insert into SyncJobs (Id, TargetId, Name, Profile, Quality, Bitrate, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Profile, @Quality, @Bitrate, @Status, @Progress, @UserId, @ItemIds, @Category, @ParentId, @UnwatchedOnly, @ItemLimit, @SyncNewContent, @DateCreated, @DateLastModified, @ItemCount)"; + + cmd.Parameters.Add(cmd, "@Id"); + cmd.Parameters.Add(cmd, "@TargetId"); + cmd.Parameters.Add(cmd, "@Name"); + cmd.Parameters.Add(cmd, "@Profile"); + cmd.Parameters.Add(cmd, "@Quality"); + cmd.Parameters.Add(cmd, "@Bitrate"); + cmd.Parameters.Add(cmd, "@Status"); + cmd.Parameters.Add(cmd, "@Progress"); + cmd.Parameters.Add(cmd, "@UserId"); + cmd.Parameters.Add(cmd, "@ItemIds"); + cmd.Parameters.Add(cmd, "@Category"); + cmd.Parameters.Add(cmd, "@ParentId"); + cmd.Parameters.Add(cmd, "@UnwatchedOnly"); + cmd.Parameters.Add(cmd, "@ItemLimit"); + cmd.Parameters.Add(cmd, "@SyncNewContent"); + cmd.Parameters.Add(cmd, "@DateCreated"); + cmd.Parameters.Add(cmd, "@DateLastModified"); + cmd.Parameters.Add(cmd, "@ItemCount"); + } + else + { + cmd.CommandText = "update SyncJobs set TargetId=@TargetId,Name=@Name,Profile=@Profile,Quality=@Quality,Bitrate=@Bitrate,Status=@Status,Progress=@Progress,UserId=@UserId,ItemIds=@ItemIds,Category=@Category,ParentId=@ParentId,UnwatchedOnly=@UnwatchedOnly,ItemLimit=@ItemLimit,SyncNewContent=@SyncNewContent,DateCreated=@DateCreated,DateLastModified=@DateLastModified,ItemCount=@ItemCount where Id=@Id"; + + cmd.Parameters.Add(cmd, "@Id"); + cmd.Parameters.Add(cmd, "@TargetId"); + cmd.Parameters.Add(cmd, "@Name"); + cmd.Parameters.Add(cmd, "@Profile"); + cmd.Parameters.Add(cmd, "@Quality"); + cmd.Parameters.Add(cmd, "@Bitrate"); + cmd.Parameters.Add(cmd, "@Status"); + cmd.Parameters.Add(cmd, "@Progress"); + cmd.Parameters.Add(cmd, "@UserId"); + cmd.Parameters.Add(cmd, "@ItemIds"); + cmd.Parameters.Add(cmd, "@Category"); + cmd.Parameters.Add(cmd, "@ParentId"); + cmd.Parameters.Add(cmd, "@UnwatchedOnly"); + cmd.Parameters.Add(cmd, "@ItemLimit"); + cmd.Parameters.Add(cmd, "@SyncNewContent"); + cmd.Parameters.Add(cmd, "@DateCreated"); + cmd.Parameters.Add(cmd, "@DateLastModified"); + cmd.Parameters.Add(cmd, "@ItemCount"); + } - cmd.ExecuteNonQuery(); + IDbTransaction transaction = null; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + try + { + transaction = connection.BeginTransaction(); + + var index = 0; + + cmd.GetParameter(index++).Value = new Guid(job.Id); + cmd.GetParameter(index++).Value = job.TargetId; + cmd.GetParameter(index++).Value = job.Name; + cmd.GetParameter(index++).Value = job.Profile; + cmd.GetParameter(index++).Value = job.Quality; + cmd.GetParameter(index++).Value = job.Bitrate; + cmd.GetParameter(index++).Value = job.Status.ToString(); + cmd.GetParameter(index++).Value = job.Progress; + cmd.GetParameter(index++).Value = job.UserId; + cmd.GetParameter(index++).Value = string.Join(",", job.RequestedItemIds.ToArray()); + cmd.GetParameter(index++).Value = job.Category; + cmd.GetParameter(index++).Value = job.ParentId; + cmd.GetParameter(index++).Value = job.UnwatchedOnly; + cmd.GetParameter(index++).Value = job.ItemLimit; + cmd.GetParameter(index++).Value = job.SyncNewContent; + cmd.GetParameter(index++).Value = job.DateCreated; + cmd.GetParameter(index++).Value = job.DateLastModified; + cmd.GetParameter(index++).Value = job.ItemCount; + + cmd.Transaction = transaction; + + cmd.ExecuteNonQuery(); + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save record:", e); + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save record:", e); - if (transaction != null) - { - transaction.Rollback(); - } + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } } - - WriteLock.Release(); } } @@ -374,56 +312,66 @@ namespace MediaBrowser.Server.Implementations.Sync } CheckDisposed(); - - await WriteLock.WaitAsync().ConfigureAwait(false); - IDbTransaction transaction = null; - - try - { - transaction = _connection.BeginTransaction(); - - var index = 0; - - _deleteJobCommand.GetParameter(index++).Value = new Guid(id); - _deleteJobCommand.Transaction = transaction; - _deleteJobCommand.ExecuteNonQuery(); - - index = 0; - _deleteJobItemsCommand.GetParameter(index++).Value = id; - _deleteJobItemsCommand.Transaction = transaction; - _deleteJobItemsCommand.ExecuteNonQuery(); - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } - - throw; - } - catch (Exception e) + using (var connection = await CreateConnection().ConfigureAwait(false)) { - Logger.ErrorException("Failed to save record:", e); - - if (transaction != null) + using (var deleteJobCommand = connection.CreateCommand()) { - transaction.Rollback(); - } - - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); + using (var deleteJobItemsCommand = connection.CreateCommand()) + { + IDbTransaction transaction = null; + + try + { + // _deleteJobCommand + deleteJobCommand.CommandText = "delete from SyncJobs where Id=@Id"; + deleteJobCommand.Parameters.Add(deleteJobCommand, "@Id"); + + transaction = connection.BeginTransaction(); + + deleteJobCommand.GetParameter(0).Value = new Guid(id); + deleteJobCommand.Transaction = transaction; + deleteJobCommand.ExecuteNonQuery(); + + // _deleteJobItemsCommand + deleteJobItemsCommand.CommandText = "delete from SyncJobItems where JobId=@JobId"; + deleteJobItemsCommand.Parameters.Add(deleteJobItemsCommand, "@JobId"); + + deleteJobItemsCommand.GetParameter(0).Value = id; + deleteJobItemsCommand.Transaction = transaction; + deleteJobItemsCommand.ExecuteNonQuery(); + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save record:", e); + + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } + } } - - WriteLock.Release(); } } @@ -435,83 +383,86 @@ namespace MediaBrowser.Server.Implementations.Sync } CheckDisposed(); - - using (var cmd = _connection.CreateCommand()) + + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = BaseJobSelectText; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = BaseJobSelectText; - var whereClauses = new List(); + var whereClauses = new List(); - if (query.Statuses.Length > 0) - { - var statuses = string.Join(",", query.Statuses.Select(i => "'" + i.ToString() + "'").ToArray()); + if (query.Statuses.Length > 0) + { + var statuses = string.Join(",", query.Statuses.Select(i => "'" + i.ToString() + "'").ToArray()); - whereClauses.Add(string.Format("Status in ({0})", statuses)); - } - if (!string.IsNullOrWhiteSpace(query.TargetId)) - { - whereClauses.Add("TargetId=@TargetId"); - cmd.Parameters.Add(cmd, "@TargetId", DbType.String).Value = query.TargetId; - } - if (!string.IsNullOrWhiteSpace(query.UserId)) - { - whereClauses.Add("UserId=@UserId"); - cmd.Parameters.Add(cmd, "@UserId", DbType.String).Value = query.UserId; - } - if (query.SyncNewContent.HasValue) - { - whereClauses.Add("SyncNewContent=@SyncNewContent"); - cmd.Parameters.Add(cmd, "@SyncNewContent", DbType.Boolean).Value = query.SyncNewContent.Value; - } + whereClauses.Add(string.Format("Status in ({0})", statuses)); + } + if (!string.IsNullOrWhiteSpace(query.TargetId)) + { + whereClauses.Add("TargetId=@TargetId"); + cmd.Parameters.Add(cmd, "@TargetId", DbType.String).Value = query.TargetId; + } + if (!string.IsNullOrWhiteSpace(query.UserId)) + { + whereClauses.Add("UserId=@UserId"); + cmd.Parameters.Add(cmd, "@UserId", DbType.String).Value = query.UserId; + } + if (query.SyncNewContent.HasValue) + { + whereClauses.Add("SyncNewContent=@SyncNewContent"); + cmd.Parameters.Add(cmd, "@SyncNewContent", DbType.Boolean).Value = query.SyncNewContent.Value; + } - cmd.CommandText += " mainTable"; + cmd.CommandText += " mainTable"; - var whereTextWithoutPaging = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereTextWithoutPaging = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - var startIndex = query.StartIndex ?? 0; - if (startIndex > 0) - { - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobs ORDER BY (Select Max(DateLastModified) from SyncJobs where TargetId=mainTable.TargetId) DESC, DateLastModified DESC LIMIT {0})", - startIndex.ToString(_usCulture))); - } + var startIndex = query.StartIndex ?? 0; + if (startIndex > 0) + { + whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobs ORDER BY (Select Max(DateLastModified) from SyncJobs where TargetId=mainTable.TargetId) DESC, DateLastModified DESC LIMIT {0})", + startIndex.ToString(_usCulture))); + } - if (whereClauses.Count > 0) - { - cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); - } + if (whereClauses.Count > 0) + { + cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); + } - cmd.CommandText += " ORDER BY (Select Max(DateLastModified) from SyncJobs where TargetId=mainTable.TargetId) DESC, DateLastModified DESC"; + cmd.CommandText += " ORDER BY (Select Max(DateLastModified) from SyncJobs where TargetId=mainTable.TargetId) DESC, DateLastModified DESC"; - if (query.Limit.HasValue) - { - cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture); - } + if (query.Limit.HasValue) + { + cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture); + } - cmd.CommandText += "; select count (Id) from SyncJobs" + whereTextWithoutPaging; + cmd.CommandText += "; select count (Id) from SyncJobs" + whereTextWithoutPaging; - var list = new List(); - var count = 0; + var list = new List(); + var count = 0; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - list.Add(GetJob(reader)); + while (reader.Read()) + { + list.Add(GetJob(reader)); + } + + if (reader.NextResult() && reader.Read()) + { + count = reader.GetInt32(0); + } } - if (reader.NextResult() && reader.Read()) + return new QueryResult() { - count = reader.GetInt32(0); - } + Items = list.ToArray(), + TotalRecordCount = count + }; } - - return new QueryResult() - { - Items = list.ToArray(), - TotalRecordCount = count - }; } } @@ -523,25 +474,28 @@ namespace MediaBrowser.Server.Implementations.Sync } CheckDisposed(); - + var guid = new Guid(id); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = BaseJobItemSelectText + " where Id=@Id"; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = BaseJobItemSelectText + " where Id=@Id"; - cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid; + cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) - { - if (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) { - return GetJobItem(reader); + if (reader.Read()) + { + return GetJobItem(reader); + } } } - } - return null; + return null; + } } private QueryResult GetJobItemReader(SyncJobItemQuery query, string baseSelectText, Func itemFactory) @@ -551,81 +505,84 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentNullException("query"); } - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = baseSelectText; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = baseSelectText; - var whereClauses = new List(); + var whereClauses = new List(); - if (!string.IsNullOrWhiteSpace(query.JobId)) - { - whereClauses.Add("JobId=@JobId"); - cmd.Parameters.Add(cmd, "@JobId", DbType.String).Value = query.JobId; - } - if (!string.IsNullOrWhiteSpace(query.ItemId)) - { - whereClauses.Add("ItemId=@ItemId"); - cmd.Parameters.Add(cmd, "@ItemId", DbType.String).Value = query.ItemId; - } - if (!string.IsNullOrWhiteSpace(query.TargetId)) - { - whereClauses.Add("TargetId=@TargetId"); - cmd.Parameters.Add(cmd, "@TargetId", DbType.String).Value = query.TargetId; - } + if (!string.IsNullOrWhiteSpace(query.JobId)) + { + whereClauses.Add("JobId=@JobId"); + cmd.Parameters.Add(cmd, "@JobId", DbType.String).Value = query.JobId; + } + if (!string.IsNullOrWhiteSpace(query.ItemId)) + { + whereClauses.Add("ItemId=@ItemId"); + cmd.Parameters.Add(cmd, "@ItemId", DbType.String).Value = query.ItemId; + } + if (!string.IsNullOrWhiteSpace(query.TargetId)) + { + whereClauses.Add("TargetId=@TargetId"); + cmd.Parameters.Add(cmd, "@TargetId", DbType.String).Value = query.TargetId; + } - if (query.Statuses.Length > 0) - { - var statuses = string.Join(",", query.Statuses.Select(i => "'" + i.ToString() + "'").ToArray()); + if (query.Statuses.Length > 0) + { + var statuses = string.Join(",", query.Statuses.Select(i => "'" + i.ToString() + "'").ToArray()); - whereClauses.Add(string.Format("Status in ({0})", statuses)); - } + whereClauses.Add(string.Format("Status in ({0})", statuses)); + } - var whereTextWithoutPaging = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereTextWithoutPaging = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - var startIndex = query.StartIndex ?? 0; - if (startIndex > 0) - { - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobItems ORDER BY JobItemIndex, DateCreated LIMIT {0})", - startIndex.ToString(_usCulture))); - } + var startIndex = query.StartIndex ?? 0; + if (startIndex > 0) + { + whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobItems ORDER BY JobItemIndex, DateCreated LIMIT {0})", + startIndex.ToString(_usCulture))); + } - if (whereClauses.Count > 0) - { - cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); - } + if (whereClauses.Count > 0) + { + cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); + } - cmd.CommandText += " ORDER BY JobItemIndex, DateCreated"; + cmd.CommandText += " ORDER BY JobItemIndex, DateCreated"; - if (query.Limit.HasValue) - { - cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture); - } + if (query.Limit.HasValue) + { + cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture); + } - cmd.CommandText += "; select count (Id) from SyncJobItems" + whereTextWithoutPaging; + cmd.CommandText += "; select count (Id) from SyncJobItems" + whereTextWithoutPaging; - var list = new List(); - var count = 0; + var list = new List(); + var count = 0; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - list.Add(itemFactory(reader)); + while (reader.Read()) + { + list.Add(itemFactory(reader)); + } + + if (reader.NextResult() && reader.Read()) + { + count = reader.GetInt32(0); + } } - if (reader.NextResult() && reader.Read()) + return new QueryResult() { - count = reader.GetInt32(0); - } + Items = list.ToArray(), + TotalRecordCount = count + }; } - - return new QueryResult() - { - Items = list.ToArray(), - TotalRecordCount = count - }; } } @@ -641,15 +598,15 @@ namespace MediaBrowser.Server.Implementations.Sync public Task Create(SyncJobItem jobItem) { - return InsertOrUpdate(jobItem, _insertJobItemCommand); + return InsertOrUpdate(jobItem, true); } public Task Update(SyncJobItem jobItem) { - return InsertOrUpdate(jobItem, _updateJobItemCommand); + return InsertOrUpdate(jobItem, false); } - private async Task InsertOrUpdate(SyncJobItem jobItem, IDbCommand cmd) + private async Task InsertOrUpdate(SyncJobItem jobItem, bool insert) { if (jobItem == null) { @@ -657,68 +614,114 @@ namespace MediaBrowser.Server.Implementations.Sync } CheckDisposed(); - - await WriteLock.WaitAsync().ConfigureAwait(false); - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); - - var index = 0; - - cmd.GetParameter(index++).Value = new Guid(jobItem.Id); - cmd.GetParameter(index++).Value = jobItem.ItemId; - cmd.GetParameter(index++).Value = jobItem.ItemName; - cmd.GetParameter(index++).Value = jobItem.MediaSourceId; - cmd.GetParameter(index++).Value = jobItem.JobId; - cmd.GetParameter(index++).Value = jobItem.TemporaryPath; - cmd.GetParameter(index++).Value = jobItem.OutputPath; - cmd.GetParameter(index++).Value = jobItem.Status.ToString(); - cmd.GetParameter(index++).Value = jobItem.TargetId; - cmd.GetParameter(index++).Value = jobItem.DateCreated; - cmd.GetParameter(index++).Value = jobItem.Progress; - cmd.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles); - cmd.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); - cmd.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; - cmd.GetParameter(index++).Value = jobItem.JobItemIndex; - cmd.GetParameter(index++).Value = jobItem.ItemDateModifiedTicks; - - cmd.Transaction = transaction; + using (var cmd = connection.CreateCommand()) + { + if (insert) + { + cmd.CommandText = "insert into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex, ItemDateModifiedTicks) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex, @ItemDateModifiedTicks)"; + + cmd.Parameters.Add(cmd, "@Id"); + cmd.Parameters.Add(cmd, "@ItemId"); + cmd.Parameters.Add(cmd, "@ItemName"); + cmd.Parameters.Add(cmd, "@MediaSourceId"); + cmd.Parameters.Add(cmd, "@JobId"); + cmd.Parameters.Add(cmd, "@TemporaryPath"); + cmd.Parameters.Add(cmd, "@OutputPath"); + cmd.Parameters.Add(cmd, "@Status"); + cmd.Parameters.Add(cmd, "@TargetId"); + cmd.Parameters.Add(cmd, "@DateCreated"); + cmd.Parameters.Add(cmd, "@Progress"); + cmd.Parameters.Add(cmd, "@AdditionalFiles"); + cmd.Parameters.Add(cmd, "@MediaSource"); + cmd.Parameters.Add(cmd, "@IsMarkedForRemoval"); + cmd.Parameters.Add(cmd, "@JobItemIndex"); + cmd.Parameters.Add(cmd, "@ItemDateModifiedTicks"); + } + else + { + // cmd + cmd.CommandText = "update SyncJobItems set ItemId=@ItemId,ItemName=@ItemName,MediaSourceId=@MediaSourceId,JobId=@JobId,TemporaryPath=@TemporaryPath,OutputPath=@OutputPath,Status=@Status,TargetId=@TargetId,DateCreated=@DateCreated,Progress=@Progress,AdditionalFiles=@AdditionalFiles,MediaSource=@MediaSource,IsMarkedForRemoval=@IsMarkedForRemoval,JobItemIndex=@JobItemIndex,ItemDateModifiedTicks=@ItemDateModifiedTicks where Id=@Id"; + + cmd.Parameters.Add(cmd, "@Id"); + cmd.Parameters.Add(cmd, "@ItemId"); + cmd.Parameters.Add(cmd, "@ItemName"); + cmd.Parameters.Add(cmd, "@MediaSourceId"); + cmd.Parameters.Add(cmd, "@JobId"); + cmd.Parameters.Add(cmd, "@TemporaryPath"); + cmd.Parameters.Add(cmd, "@OutputPath"); + cmd.Parameters.Add(cmd, "@Status"); + cmd.Parameters.Add(cmd, "@TargetId"); + cmd.Parameters.Add(cmd, "@DateCreated"); + cmd.Parameters.Add(cmd, "@Progress"); + cmd.Parameters.Add(cmd, "@AdditionalFiles"); + cmd.Parameters.Add(cmd, "@MediaSource"); + cmd.Parameters.Add(cmd, "@IsMarkedForRemoval"); + cmd.Parameters.Add(cmd, "@JobItemIndex"); + cmd.Parameters.Add(cmd, "@ItemDateModifiedTicks"); + } - cmd.ExecuteNonQuery(); + IDbTransaction transaction = null; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + try + { + transaction = connection.BeginTransaction(); + + var index = 0; + + cmd.GetParameter(index++).Value = new Guid(jobItem.Id); + cmd.GetParameter(index++).Value = jobItem.ItemId; + cmd.GetParameter(index++).Value = jobItem.ItemName; + cmd.GetParameter(index++).Value = jobItem.MediaSourceId; + cmd.GetParameter(index++).Value = jobItem.JobId; + cmd.GetParameter(index++).Value = jobItem.TemporaryPath; + cmd.GetParameter(index++).Value = jobItem.OutputPath; + cmd.GetParameter(index++).Value = jobItem.Status.ToString(); + cmd.GetParameter(index++).Value = jobItem.TargetId; + cmd.GetParameter(index++).Value = jobItem.DateCreated; + cmd.GetParameter(index++).Value = jobItem.Progress; + cmd.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles); + cmd.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); + cmd.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; + cmd.GetParameter(index++).Value = jobItem.JobItemIndex; + cmd.GetParameter(index++).Value = jobItem.ItemDateModifiedTicks; + + cmd.Transaction = transaction; + + cmd.ExecuteNonQuery(); + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save record:", e); + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save record:", e); - if (transaction != null) - { - transaction.Rollback(); - } + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } } - - WriteLock.Release(); } } @@ -809,19 +812,5 @@ namespace MediaBrowser.Server.Implementations.Sync return item; } - - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } - - _connection.Dispose(); - _connection = null; - } - } } } -- cgit v1.2.3 From da6e94396fb417077010d3a2e5f3282bf06234c3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 11 Jun 2016 16:12:01 -0400 Subject: update connection pooling --- .../Chapters/IChapterManager.cs | 2 +- .../Persistence/IItemRepository.cs | 4 +- MediaBrowser.Providers/Chapters/ChapterManager.cs | 2 +- .../Activity/ActivityRepository.cs | 7 +- .../Library/LibraryManager.cs | 10 +- .../LiveTv/LiveTvManager.cs | 2 +- .../Notifications/SqliteNotificationsRepository.cs | 7 +- .../Persistence/BaseSqliteRepository.cs | 12 +- .../SqliteDisplayPreferencesRepository.cs | 7 +- .../Persistence/SqliteExtensions.cs | 13 +- .../SqliteFileOrganizationRepository.cs | 7 +- .../Persistence/SqliteItemRepository.cs | 2855 ++++++++++---------- .../Persistence/SqliteUserDataRepository.cs | 7 +- .../Persistence/SqliteUserRepository.cs | 3 - .../Security/AuthenticationRepository.cs | 7 +- .../Social/SharingRepository.cs | 3 - .../Sync/SyncRepository.cs | 3 - 17 files changed, 1533 insertions(+), 1418 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/MediaBrowser.Controller/Chapters/IChapterManager.cs b/MediaBrowser.Controller/Chapters/IChapterManager.cs index 676ef9c561..27e06fb8dd 100644 --- a/MediaBrowser.Controller/Chapters/IChapterManager.cs +++ b/MediaBrowser.Controller/Chapters/IChapterManager.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Chapters /// The chapters. /// The cancellation token. /// Task. - Task SaveChapters(string itemId, IEnumerable chapters, CancellationToken cancellationToken); + Task SaveChapters(string itemId, List chapters, CancellationToken cancellationToken); /// /// Searches the specified video. diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 7bcc36958a..80a6e4042f 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -81,7 +81,7 @@ namespace MediaBrowser.Controller.Persistence /// The chapters. /// The cancellation token. /// Task. - Task SaveChapters(Guid id, IEnumerable chapters, CancellationToken cancellationToken); + Task SaveChapters(Guid id, List chapters, CancellationToken cancellationToken); /// /// Gets the media streams. @@ -97,7 +97,7 @@ namespace MediaBrowser.Controller.Persistence /// The streams. /// The cancellation token. /// Task. - Task SaveMediaStreams(Guid id, IEnumerable streams, CancellationToken cancellationToken); + Task SaveMediaStreams(Guid id, List streams, CancellationToken cancellationToken); /// /// Gets the item ids. diff --git a/MediaBrowser.Providers/Chapters/ChapterManager.cs b/MediaBrowser.Providers/Chapters/ChapterManager.cs index 6e2cd77eb3..88811c850d 100644 --- a/MediaBrowser.Providers/Chapters/ChapterManager.cs +++ b/MediaBrowser.Providers/Chapters/ChapterManager.cs @@ -259,7 +259,7 @@ namespace MediaBrowser.Providers.Chapters return _itemRepo.GetChapters(new Guid(itemId)); } - public Task SaveChapters(string itemId, IEnumerable chapters, CancellationToken cancellationToken) + public Task SaveChapters(string itemId, List chapters, CancellationToken cancellationToken) { return _itemRepo.SaveChapters(new Guid(itemId), chapters, cancellationToken); } diff --git a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs index d6ae381e9d..c992def39d 100644 --- a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs +++ b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs @@ -30,12 +30,7 @@ namespace MediaBrowser.Server.Implementations.Activity string[] queries = { "create table if not exists ActivityLogEntries (Id GUID PRIMARY KEY, Name TEXT, Overview TEXT, ShortOverview TEXT, Type TEXT, ItemId TEXT, UserId TEXT, DateCreated DATETIME, LogSeverity TEXT)", - "create index if not exists idx_ActivityLogEntries on ActivityLogEntries(Id)", - - //pragmas - "pragma temp_store = memory", - - "pragma shrink_memory" + "create index if not exists idx_ActivityLogEntries on ActivityLogEntries(Id)" }; connection.RunQueries(queries, Logger); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 503fb1aa74..2483ec93e8 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1309,7 +1309,15 @@ namespace MediaBrowser.Server.Implementations.Library AddUserToQuery(query, query.User); } - return ItemRepository.GetItems(query); + if (query.EnableTotalRecordCount) + { + return ItemRepository.GetItems(query); + } + + return new QueryResult + { + Items = ItemRepository.GetItemList(query).ToArray() + }; } public List GetItemIds(InternalItemsQuery query) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index d7491d2de1..171ed824e8 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -952,7 +952,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (query.Limit.HasValue) { - internalQuery.Limit = Math.Max(query.Limit.Value * 5, 300); + internalQuery.Limit = Math.Max(query.Limit.Value * 5, 200); } if (query.HasAired.HasValue) diff --git a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index 6c3bc3050e..be8c6d48d6 100644 --- a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs +++ b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -32,12 +32,7 @@ namespace MediaBrowser.Server.Implementations.Notifications "create table if not exists Notifications (Id GUID NOT NULL, UserId GUID NOT NULL, Date DATETIME NOT NULL, Name TEXT NOT NULL, Description TEXT, Url TEXT, Level TEXT NOT NULL, IsRead BOOLEAN NOT NULL, Category TEXT NOT NULL, RelatedId TEXT, PRIMARY KEY (Id, UserId))", "create index if not exists idx_Notifications1 on Notifications(Id)", - "create index if not exists idx_Notifications2 on Notifications(UserId)", - - //pragmas - "pragma temp_store = memory", - - "pragma shrink_memory" + "create index if not exists idx_Notifications2 on Notifications(UserId)" }; connection.RunQueries(queries, Logger); diff --git a/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs b/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs index de0c245bdb..c6e7952294 100644 --- a/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs @@ -20,9 +20,17 @@ namespace MediaBrowser.Server.Implementations.Persistence Logger = logManager.GetLogger(GetType().Name); } - protected Task CreateConnection(bool isReadOnly = false) + protected virtual async Task CreateConnection(bool isReadOnly = false) { - return DbConnector.Connect(DbFilePath, false, true); + var connection = await DbConnector.Connect(DbFilePath, false, true).ConfigureAwait(false); + + connection.RunQueries(new [] + { + "pragma temp_store = memory" + + }, Logger); + + return connection; } private bool _disposed; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs index 1a6a88ebe2..40970dbe4d 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs @@ -53,12 +53,7 @@ namespace MediaBrowser.Server.Implementations.Persistence string[] queries = { "create table if not exists userdisplaypreferences (id GUID, userId GUID, client text, data BLOB)", - "create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)", - - //pragmas - "pragma temp_store = memory", - - "pragma shrink_memory" + "create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)" }; connection.RunQueries(queries, Logger); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs index cc9e3ebccf..0a76381e12 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs @@ -26,8 +26,6 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("dbPath"); } - logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); - var connectionstr = new SQLiteConnectionStringBuilder { PageSize = 4096, @@ -39,7 +37,16 @@ namespace MediaBrowser.Server.Implementations.Persistence ReadOnly = isReadOnly }; - var connection = new SQLiteConnection(connectionstr.ConnectionString); + var connectionString = connectionstr.ConnectionString; + + if (enablePooling) + { + connectionString += ";Max Pool Size=100"; + } + + //logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, connectionString); + + var connection = new SQLiteConnection(connectionString); await connection.OpenAsync().ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs index 8a4ba6460d..d7e8afdd4c 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs @@ -44,12 +44,7 @@ namespace MediaBrowser.Server.Implementations.Persistence string[] queries = { "create table if not exists FileOrganizerResults (ResultId GUID PRIMARY KEY, OriginalPath TEXT, TargetPath TEXT, FileLength INT, OrganizationDate datetime, Status TEXT, OrganizationType TEXT, StatusMessage TEXT, ExtractedName TEXT, ExtractedYear int null, ExtractedSeasonNumber int null, ExtractedEpisodeNumber int null, ExtractedEndingEpisodeNumber, DuplicatePaths TEXT int null)", - "create index if not exists idx_FileOrganizerResults on FileOrganizerResults(ResultId)", - - //pragmas - "pragma temp_store = memory", - - "pragma shrink_memory" + "create index if not exists idx_FileOrganizerResults on FileOrganizerResults(ResultId)" }; _connection.RunQueries(queries, Logger); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 9bfdd879da..0eb56a1fc4 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -31,8 +31,6 @@ namespace MediaBrowser.Server.Implementations.Persistence /// public class SqliteItemRepository : BaseSqliteRepository, IItemRepository { - private IDbConnection _connection; - private readonly TypeMapper _typeMapper = new TypeMapper(); /// @@ -58,42 +56,8 @@ namespace MediaBrowser.Server.Implementations.Persistence /// private readonly IServerConfigurationManager _config; - /// - /// The _save item command - /// - private IDbCommand _saveItemCommand; - private readonly string _criticReviewsPath; - private IDbCommand _deleteItemCommand; - - private IDbCommand _deletePeopleCommand; - private IDbCommand _savePersonCommand; - - private IDbCommand _deleteChaptersCommand; - private IDbCommand _saveChapterCommand; - - private IDbCommand _deleteStreamsCommand; - private IDbCommand _saveStreamCommand; - - private IDbCommand _deleteAncestorsCommand; - private IDbCommand _saveAncestorCommand; - - private IDbCommand _deleteUserDataKeysCommand; - private IDbCommand _saveUserDataKeysCommand; - - private IDbCommand _deleteItemValuesCommand; - private IDbCommand _saveItemValuesCommand; - - private IDbCommand _deleteProviderIdsCommand; - private IDbCommand _saveProviderIdsCommand; - - private IDbCommand _deleteImagesCommand; - private IDbCommand _saveImagesCommand; - - private IDbCommand _updateInheritedRatingCommand; - private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 89; /// @@ -115,6 +79,22 @@ namespace MediaBrowser.Server.Implementations.Persistence _jsonSerializer = jsonSerializer; _criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews"); + DbFilePath = Path.Combine(_config.ApplicationPaths.DataPath, "library.db"); + } + + protected override async Task CreateConnection(bool isReadOnly = false) + { + var connection = await DbConnector.Connect(DbFilePath, false, true, 20000).ConfigureAwait(false); + + //AttachUserDataDb(connection); + + //connection.RunQueries(new [] + //{ + // "pragma locking_mode=EXCLUSIVE" + + //}, Logger); + + return connection; } private const string ChaptersTableName = "Chapters2"; @@ -125,14 +105,12 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Task. public async Task Initialize(IDbConnector dbConnector) { - var dbFile = Path.Combine(_config.ApplicationPaths.DataPath, "library.db"); - - _connection = await dbConnector.Connect(dbFile, false, false, 6000).ConfigureAwait(false); - - var createMediaStreamsTableCommand - = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + var createMediaStreamsTableCommand + = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; - string[] queries = { + string[] queries = { "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID, Path TEXT)", "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", @@ -165,113 +143,113 @@ namespace MediaBrowser.Server.Implementations.Persistence createMediaStreamsTableCommand, "create index if not exists idx_mediastreams1 on mediastreams(ItemId)", - - //pragmas - "pragma temp_store = memory", - - "pragma shrink_memory" + }; - _connection.RunQueries(queries, Logger); - - _connection.AddColumn(Logger, "AncestorIds", "AncestorIdText", "Text"); - - _connection.AddColumn(Logger, "TypedBaseItems", "Path", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "StartDate", "DATETIME"); - _connection.AddColumn(Logger, "TypedBaseItems", "EndDate", "DATETIME"); - _connection.AddColumn(Logger, "TypedBaseItems", "ChannelId", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsMovie", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsSports", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsKids", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "CommunityRating", "Float"); - _connection.AddColumn(Logger, "TypedBaseItems", "CustomRating", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "IndexNumber", "INT"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsLocked", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "Name", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "OfficialRating", "Text"); - - _connection.AddColumn(Logger, "TypedBaseItems", "MediaType", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "Overview", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "ParentIndexNumber", "INT"); - _connection.AddColumn(Logger, "TypedBaseItems", "PremiereDate", "DATETIME"); - _connection.AddColumn(Logger, "TypedBaseItems", "ProductionYear", "INT"); - _connection.AddColumn(Logger, "TypedBaseItems", "ParentId", "GUID"); - _connection.AddColumn(Logger, "TypedBaseItems", "Genres", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "ParentalRatingValue", "INT"); - _connection.AddColumn(Logger, "TypedBaseItems", "SchemaVersion", "INT"); - _connection.AddColumn(Logger, "TypedBaseItems", "SortName", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "RunTimeTicks", "BIGINT"); - - _connection.AddColumn(Logger, "TypedBaseItems", "OfficialRatingDescription", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "HomePageUrl", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "VoteCount", "INT"); - _connection.AddColumn(Logger, "TypedBaseItems", "DisplayMediaType", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "DateCreated", "DATETIME"); - _connection.AddColumn(Logger, "TypedBaseItems", "DateModified", "DATETIME"); - - _connection.AddColumn(Logger, "TypedBaseItems", "ForcedSortName", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsOffline", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "LocationType", "Text"); - - _connection.AddColumn(Logger, "TypedBaseItems", "IsSeries", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsLive", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsNews", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsPremiere", "BIT"); - - _connection.AddColumn(Logger, "TypedBaseItems", "EpisodeTitle", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsRepeat", "BIT"); - - _connection.AddColumn(Logger, "TypedBaseItems", "PreferredMetadataLanguage", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "PreferredMetadataCountryCode", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsHD", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "ExternalEtag", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "DateLastRefreshed", "DATETIME"); - - _connection.AddColumn(Logger, "TypedBaseItems", "DateLastSaved", "DATETIME"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsInMixedFolder", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "LockedFields", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "Studios", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "Audio", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "ExternalServiceId", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "Tags", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsFolder", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "InheritedParentalRatingValue", "INT"); - _connection.AddColumn(Logger, "TypedBaseItems", "UnratedType", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "TopParentId", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsItemByName", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "SourceType", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "TrailerTypes", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "CriticRating", "Float"); - _connection.AddColumn(Logger, "TypedBaseItems", "CriticRatingSummary", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME"); - _connection.AddColumn(Logger, "TypedBaseItems", "InheritedTags", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "CleanName", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "PresentationUniqueKey", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "SlugName", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "OriginalTitle", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "PrimaryVersionId", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "DateLastMediaAdded", "DATETIME"); - _connection.AddColumn(Logger, "TypedBaseItems", "Album", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "IsVirtualItem", "BIT"); - _connection.AddColumn(Logger, "TypedBaseItems", "SeriesName", "Text"); - - _connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT"); - - string[] postQueries = - { + connection.RunQueries(queries, Logger); + + connection.AddColumn(Logger, "AncestorIds", "AncestorIdText", "Text"); + + connection.AddColumn(Logger, "TypedBaseItems", "Path", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "StartDate", "DATETIME"); + connection.AddColumn(Logger, "TypedBaseItems", "EndDate", "DATETIME"); + connection.AddColumn(Logger, "TypedBaseItems", "ChannelId", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "IsMovie", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "IsSports", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "IsKids", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "CommunityRating", "Float"); + connection.AddColumn(Logger, "TypedBaseItems", "CustomRating", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "IndexNumber", "INT"); + connection.AddColumn(Logger, "TypedBaseItems", "IsLocked", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "Name", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "OfficialRating", "Text"); + + connection.AddColumn(Logger, "TypedBaseItems", "MediaType", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "Overview", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "ParentIndexNumber", "INT"); + connection.AddColumn(Logger, "TypedBaseItems", "PremiereDate", "DATETIME"); + connection.AddColumn(Logger, "TypedBaseItems", "ProductionYear", "INT"); + connection.AddColumn(Logger, "TypedBaseItems", "ParentId", "GUID"); + connection.AddColumn(Logger, "TypedBaseItems", "Genres", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "ParentalRatingValue", "INT"); + connection.AddColumn(Logger, "TypedBaseItems", "SchemaVersion", "INT"); + connection.AddColumn(Logger, "TypedBaseItems", "SortName", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "RunTimeTicks", "BIGINT"); + + connection.AddColumn(Logger, "TypedBaseItems", "OfficialRatingDescription", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "HomePageUrl", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "VoteCount", "INT"); + connection.AddColumn(Logger, "TypedBaseItems", "DisplayMediaType", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "DateCreated", "DATETIME"); + connection.AddColumn(Logger, "TypedBaseItems", "DateModified", "DATETIME"); + + connection.AddColumn(Logger, "TypedBaseItems", "ForcedSortName", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "IsOffline", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "LocationType", "Text"); + + connection.AddColumn(Logger, "TypedBaseItems", "IsSeries", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "IsLive", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "IsNews", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "IsPremiere", "BIT"); + + connection.AddColumn(Logger, "TypedBaseItems", "EpisodeTitle", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "IsRepeat", "BIT"); + + connection.AddColumn(Logger, "TypedBaseItems", "PreferredMetadataLanguage", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "PreferredMetadataCountryCode", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "IsHD", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "ExternalEtag", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "DateLastRefreshed", "DATETIME"); + + connection.AddColumn(Logger, "TypedBaseItems", "DateLastSaved", "DATETIME"); + connection.AddColumn(Logger, "TypedBaseItems", "IsInMixedFolder", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "LockedFields", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "Studios", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "Audio", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "ExternalServiceId", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "Tags", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "IsFolder", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "InheritedParentalRatingValue", "INT"); + connection.AddColumn(Logger, "TypedBaseItems", "UnratedType", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "TopParentId", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "IsItemByName", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "SourceType", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "TrailerTypes", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "CriticRating", "Float"); + connection.AddColumn(Logger, "TypedBaseItems", "CriticRatingSummary", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME"); + connection.AddColumn(Logger, "TypedBaseItems", "InheritedTags", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "CleanName", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "PresentationUniqueKey", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "SlugName", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "OriginalTitle", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "PrimaryVersionId", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "DateLastMediaAdded", "DATETIME"); + connection.AddColumn(Logger, "TypedBaseItems", "Album", "Text"); + connection.AddColumn(Logger, "TypedBaseItems", "IsVirtualItem", "BIT"); + connection.AddColumn(Logger, "TypedBaseItems", "SeriesName", "Text"); + + connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT"); + + string[] postQueries = + { "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)", "create index if not exists idx_Type on TypedBaseItems(Type)", "create index if not exists idx_TopParentId on TypedBaseItems(TopParentId)", "create index if not exists idx_TypeTopParentId on TypedBaseItems(Type,TopParentId)" - }; + }; - _connection.RunQueries(postQueries, Logger); + connection.RunQueries(postQueries, Logger); - PrepareStatements(); + new MediaStreamColumns(connection, Logger).AddColumns(); - new MediaStreamColumns(_connection, Logger).AddColumns(); + //AttachUserDataDb(connection); + } + } - DataExtensions.Attach(_connection, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), "UserDataDb"); + private void AttachUserDataDb(IDbConnection connection) + { + DataExtensions.Attach(connection, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), "UserDataDb" + Guid.NewGuid().ToString("N")); } private readonly string[] _retriveItemColumns = @@ -373,220 +351,6 @@ namespace MediaBrowser.Server.Implementations.Persistence "CodecTimeBase" }; - /// - /// Prepares the statements. - /// - private void PrepareStatements() - { - var saveColumns = new List - { - "guid", - "type", - "data", - "Path", - "StartDate", - "EndDate", - "ChannelId", - "IsKids", - "IsMovie", - "IsSports", - "IsSeries", - "IsLive", - "IsNews", - "IsPremiere", - "EpisodeTitle", - "IsRepeat", - "CommunityRating", - "CustomRating", - "IndexNumber", - "IsLocked", - "Name", - "OfficialRating", - "MediaType", - "Overview", - "ParentIndexNumber", - "PremiereDate", - "ProductionYear", - "ParentId", - "Genres", - "ParentalRatingValue", - "InheritedParentalRatingValue", - "SchemaVersion", - "SortName", - "RunTimeTicks", - "OfficialRatingDescription", - "HomePageUrl", - "VoteCount", - "DisplayMediaType", - "DateCreated", - "DateModified", - "ForcedSortName", - "IsOffline", - "LocationType", - "PreferredMetadataLanguage", - "PreferredMetadataCountryCode", - "IsHD", - "ExternalEtag", - "DateLastRefreshed", - "DateLastSaved", - "IsInMixedFolder", - "LockedFields", - "Studios", - "Audio", - "ExternalServiceId", - "Tags", - "IsFolder", - "UnratedType", - "TopParentId", - "IsItemByName", - "SourceType", - "TrailerTypes", - "CriticRating", - "CriticRatingSummary", - "DateModifiedDuringLastRefresh", - "InheritedTags", - "CleanName", - "PresentationUniqueKey", - "SlugName", - "OriginalTitle", - "PrimaryVersionId", - "DateLastMediaAdded", - "Album", - "IsVirtualItem", - "SeriesName" - }; - _saveItemCommand = _connection.CreateCommand(); - _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; - - for (var i = 1; i <= saveColumns.Count; i++) - { - if (i > 1) - { - _saveItemCommand.CommandText += ","; - } - _saveItemCommand.CommandText += "@" + i.ToString(CultureInfo.InvariantCulture); - - _saveItemCommand.Parameters.Add(_saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); - } - _saveItemCommand.CommandText += ")"; - - _deleteItemCommand = _connection.CreateCommand(); - _deleteItemCommand.CommandText = "delete from TypedBaseItems where guid=@Id"; - _deleteItemCommand.Parameters.Add(_deleteItemCommand, "@Id"); - - // People - _deletePeopleCommand = _connection.CreateCommand(); - _deletePeopleCommand.CommandText = "delete from People where ItemId=@Id"; - _deletePeopleCommand.Parameters.Add(_deletePeopleCommand, "@Id"); - - _savePersonCommand = _connection.CreateCommand(); - _savePersonCommand.CommandText = "insert into People (ItemId, Name, Role, PersonType, SortOrder, ListOrder) values (@ItemId, @Name, @Role, @PersonType, @SortOrder, @ListOrder)"; - _savePersonCommand.Parameters.Add(_savePersonCommand, "@ItemId"); - _savePersonCommand.Parameters.Add(_savePersonCommand, "@Name"); - _savePersonCommand.Parameters.Add(_savePersonCommand, "@Role"); - _savePersonCommand.Parameters.Add(_savePersonCommand, "@PersonType"); - _savePersonCommand.Parameters.Add(_savePersonCommand, "@SortOrder"); - _savePersonCommand.Parameters.Add(_savePersonCommand, "@ListOrder"); - - // Ancestors - _deleteAncestorsCommand = _connection.CreateCommand(); - _deleteAncestorsCommand.CommandText = "delete from AncestorIds where ItemId=@Id"; - _deleteAncestorsCommand.Parameters.Add(_deleteAncestorsCommand, "@Id"); - - _saveAncestorCommand = _connection.CreateCommand(); - _saveAncestorCommand.CommandText = "insert into AncestorIds (ItemId, AncestorId, AncestorIdText) values (@ItemId, @AncestorId, @AncestorIdText)"; - _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@ItemId"); - _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@AncestorId"); - _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@AncestorIdText"); - - // Chapters - _deleteChaptersCommand = _connection.CreateCommand(); - _deleteChaptersCommand.CommandText = "delete from " + ChaptersTableName + " where ItemId=@ItemId"; - _deleteChaptersCommand.Parameters.Add(_deleteChaptersCommand, "@ItemId"); - - _saveChapterCommand = _connection.CreateCommand(); - _saveChapterCommand.CommandText = "replace into " + ChaptersTableName + " (ItemId, ChapterIndex, StartPositionTicks, Name, ImagePath) values (@ItemId, @ChapterIndex, @StartPositionTicks, @Name, @ImagePath)"; - - _saveChapterCommand.Parameters.Add(_saveChapterCommand, "@ItemId"); - _saveChapterCommand.Parameters.Add(_saveChapterCommand, "@ChapterIndex"); - _saveChapterCommand.Parameters.Add(_saveChapterCommand, "@StartPositionTicks"); - _saveChapterCommand.Parameters.Add(_saveChapterCommand, "@Name"); - _saveChapterCommand.Parameters.Add(_saveChapterCommand, "@ImagePath"); - - // MediaStreams - _deleteStreamsCommand = _connection.CreateCommand(); - _deleteStreamsCommand.CommandText = "delete from mediastreams where ItemId=@ItemId"; - _deleteStreamsCommand.Parameters.Add(_deleteStreamsCommand, "@ItemId"); - - _saveStreamCommand = _connection.CreateCommand(); - - _saveStreamCommand.CommandText = string.Format("replace into mediastreams ({0}) values ({1})", - string.Join(",", _mediaStreamSaveColumns), - string.Join(",", _mediaStreamSaveColumns.Select(i => "@" + i).ToArray())); - - foreach (var col in _mediaStreamSaveColumns) - { - _saveStreamCommand.Parameters.Add(_saveStreamCommand, "@" + col); - } - - _updateInheritedRatingCommand = _connection.CreateCommand(); - _updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid"; - _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@Guid"); - _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@InheritedParentalRatingValue"); - - _updateInheritedTagsCommand = _connection.CreateCommand(); - _updateInheritedTagsCommand.CommandText = "Update TypedBaseItems set InheritedTags=@InheritedTags where Guid=@Guid"; - _updateInheritedTagsCommand.Parameters.Add(_updateInheritedTagsCommand, "@Guid"); - _updateInheritedTagsCommand.Parameters.Add(_updateInheritedTagsCommand, "@InheritedTags"); - - // user data - _deleteUserDataKeysCommand = _connection.CreateCommand(); - _deleteUserDataKeysCommand.CommandText = "delete from UserDataKeys where ItemId=@Id"; - _deleteUserDataKeysCommand.Parameters.Add(_deleteUserDataKeysCommand, "@Id"); - - _saveUserDataKeysCommand = _connection.CreateCommand(); - _saveUserDataKeysCommand.CommandText = "insert into UserDataKeys (ItemId, UserDataKey, Priority) values (@ItemId, @UserDataKey, @Priority)"; - _saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@ItemId"); - _saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@UserDataKey"); - _saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@Priority"); - - // item values - _deleteItemValuesCommand = _connection.CreateCommand(); - _deleteItemValuesCommand.CommandText = "delete from ItemValues where ItemId=@Id"; - _deleteItemValuesCommand.Parameters.Add(_deleteItemValuesCommand, "@Id"); - - _saveItemValuesCommand = _connection.CreateCommand(); - _saveItemValuesCommand.CommandText = "insert into ItemValues (ItemId, Type, Value) values (@ItemId, @Type, @Value)"; - _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@ItemId"); - _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@Type"); - _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@Value"); - - // provider ids - _deleteProviderIdsCommand = _connection.CreateCommand(); - _deleteProviderIdsCommand.CommandText = "delete from ProviderIds where ItemId=@Id"; - _deleteProviderIdsCommand.Parameters.Add(_deleteProviderIdsCommand, "@Id"); - - _saveProviderIdsCommand = _connection.CreateCommand(); - _saveProviderIdsCommand.CommandText = "insert into ProviderIds (ItemId, Name, Value) values (@ItemId, @Name, @Value)"; - _saveProviderIdsCommand.Parameters.Add(_saveProviderIdsCommand, "@ItemId"); - _saveProviderIdsCommand.Parameters.Add(_saveProviderIdsCommand, "@Name"); - _saveProviderIdsCommand.Parameters.Add(_saveProviderIdsCommand, "@Value"); - - // images - _deleteImagesCommand = _connection.CreateCommand(); - _deleteImagesCommand.CommandText = "delete from Images where ItemId=@Id"; - _deleteImagesCommand.Parameters.Add(_deleteImagesCommand, "@Id"); - - _saveImagesCommand = _connection.CreateCommand(); - _saveImagesCommand.CommandText = "insert into Images (ItemId, ImageType, Path, DateModified, IsPlaceHolder, SortOrder) values (@ItemId, @ImageType, @Path, @DateModified, @IsPlaceHolder, @SortOrder)"; - _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@ItemId"); - _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@ImageType"); - _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@Path"); - _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@DateModified"); - _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@IsPlaceHolder"); - _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@SortOrder"); - } - /// /// Save a standard item in the repo /// @@ -626,314 +390,408 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); + IDbTransaction transaction = null; - foreach (var item in items) + try { - cancellationToken.ThrowIfCancellationRequested(); - - var index = 0; - - _saveItemCommand.GetParameter(index++).Value = item.Id; - _saveItemCommand.GetParameter(index++).Value = item.GetType().FullName; - _saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item); - - _saveItemCommand.GetParameter(index++).Value = item.Path; - - var hasStartDate = item as IHasStartDate; - if (hasStartDate != null) - { - _saveItemCommand.GetParameter(index++).Value = hasStartDate.StartDate; - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - } - - _saveItemCommand.GetParameter(index++).Value = item.EndDate; - _saveItemCommand.GetParameter(index++).Value = item.ChannelId; - - var hasProgramAttributes = item as IHasProgramAttributes; - if (hasProgramAttributes != null) - { - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsKids; - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsMovie; - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsSports; - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsSeries; - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsLive; - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsNews; - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsPremiere; - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.EpisodeTitle; - _saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsRepeat; - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - _saveItemCommand.GetParameter(index++).Value = null; - _saveItemCommand.GetParameter(index++).Value = null; - _saveItemCommand.GetParameter(index++).Value = null; - _saveItemCommand.GetParameter(index++).Value = null; - _saveItemCommand.GetParameter(index++).Value = null; - _saveItemCommand.GetParameter(index++).Value = null; - _saveItemCommand.GetParameter(index++).Value = null; - _saveItemCommand.GetParameter(index++).Value = null; - } - - _saveItemCommand.GetParameter(index++).Value = item.CommunityRating; - _saveItemCommand.GetParameter(index++).Value = item.CustomRating; - - _saveItemCommand.GetParameter(index++).Value = item.IndexNumber; - _saveItemCommand.GetParameter(index++).Value = item.IsLocked; - - _saveItemCommand.GetParameter(index++).Value = item.Name; - _saveItemCommand.GetParameter(index++).Value = item.OfficialRating; - - _saveItemCommand.GetParameter(index++).Value = item.MediaType; - _saveItemCommand.GetParameter(index++).Value = item.Overview; - _saveItemCommand.GetParameter(index++).Value = item.ParentIndexNumber; - _saveItemCommand.GetParameter(index++).Value = item.PremiereDate; - _saveItemCommand.GetParameter(index++).Value = item.ProductionYear; - - if (item.ParentId == Guid.Empty) - { - _saveItemCommand.GetParameter(index++).Value = null; - } - else - { - _saveItemCommand.GetParameter(index++).Value = item.ParentId; - } - - _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray()); - _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue() ?? 0; - _saveItemCommand.GetParameter(index++).Value = item.GetInheritedParentalRatingValue() ?? 0; - - _saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion; - _saveItemCommand.GetParameter(index++).Value = item.SortName; - _saveItemCommand.GetParameter(index++).Value = item.RunTimeTicks; - - _saveItemCommand.GetParameter(index++).Value = item.OfficialRatingDescription; - _saveItemCommand.GetParameter(index++).Value = item.HomePageUrl; - _saveItemCommand.GetParameter(index++).Value = item.VoteCount; - _saveItemCommand.GetParameter(index++).Value = item.DisplayMediaType; - _saveItemCommand.GetParameter(index++).Value = item.DateCreated; - _saveItemCommand.GetParameter(index++).Value = item.DateModified; - - _saveItemCommand.GetParameter(index++).Value = item.ForcedSortName; - _saveItemCommand.GetParameter(index++).Value = item.IsOffline; - _saveItemCommand.GetParameter(index++).Value = item.LocationType.ToString(); - - _saveItemCommand.GetParameter(index++).Value = item.PreferredMetadataLanguage; - _saveItemCommand.GetParameter(index++).Value = item.PreferredMetadataCountryCode; - _saveItemCommand.GetParameter(index++).Value = item.IsHD; - _saveItemCommand.GetParameter(index++).Value = item.ExternalEtag; - - if (item.DateLastRefreshed == default(DateTime)) - { - _saveItemCommand.GetParameter(index++).Value = null; - } - else - { - _saveItemCommand.GetParameter(index++).Value = item.DateLastRefreshed; - } - - if (item.DateLastSaved == default(DateTime)) - { - _saveItemCommand.GetParameter(index++).Value = null; - } - else - { - _saveItemCommand.GetParameter(index++).Value = item.DateLastSaved; - } - - _saveItemCommand.GetParameter(index++).Value = item.IsInMixedFolder; - _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()); - _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Studios.ToArray()); - - if (item.Audio.HasValue) - { - _saveItemCommand.GetParameter(index++).Value = item.Audio.Value.ToString(); - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - } - - _saveItemCommand.GetParameter(index++).Value = item.ServiceName; - - if (item.Tags.Count > 0) - { - _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray()); - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - } - - _saveItemCommand.GetParameter(index++).Value = item.IsFolder; - - _saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString(); - - var topParent = item.GetTopParent(); - if (topParent != null) - { - //Logger.Debug("Item {0} has top parent {1}", item.Id, topParent.Id); - _saveItemCommand.GetParameter(index++).Value = topParent.Id.ToString("N"); - } - else - { - //Logger.Debug("Item {0} has null top parent", item.Id); - _saveItemCommand.GetParameter(index++).Value = null; - } - - var isByName = false; - var byName = item as IItemByName; - if (byName != null) - { - var dualAccess = item as IHasDualAccess; - isByName = dualAccess == null || dualAccess.IsAccessedByName; - } - _saveItemCommand.GetParameter(index++).Value = isByName; - - _saveItemCommand.GetParameter(index++).Value = item.SourceType.ToString(); - - var trailer = item as Trailer; - if (trailer != null && trailer.TrailerTypes.Count > 0) - { - _saveItemCommand.GetParameter(index++).Value = string.Join("|", trailer.TrailerTypes.Select(i => i.ToString()).ToArray()); - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - } + transaction = connection.BeginTransaction(); - _saveItemCommand.GetParameter(index++).Value = item.CriticRating; - _saveItemCommand.GetParameter(index++).Value = item.CriticRatingSummary; - - if (!item.DateModifiedDuringLastRefresh.HasValue || item.DateModifiedDuringLastRefresh.Value == default(DateTime)) - { - _saveItemCommand.GetParameter(index++).Value = null; - } - else - { - _saveItemCommand.GetParameter(index++).Value = item.DateModifiedDuringLastRefresh.Value; - } - - var inheritedTags = item.GetInheritedTags(); - if (inheritedTags.Count > 0) - { - _saveItemCommand.GetParameter(index++).Value = string.Join("|", inheritedTags.ToArray()); - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - } - - if (string.IsNullOrWhiteSpace(item.Name)) - { - _saveItemCommand.GetParameter(index++).Value = null; - } - else + using (var saveItemCommand = connection.CreateCommand()) { - _saveItemCommand.GetParameter(index++).Value = item.Name.RemoveDiacritics(); - } - - _saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey; - _saveItemCommand.GetParameter(index++).Value = item.SlugName; - _saveItemCommand.GetParameter(index++).Value = item.OriginalTitle; - - var video = item as Video; - if (video != null) - { - _saveItemCommand.GetParameter(index++).Value = video.PrimaryVersionId; - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - } - - var folder = item as Folder; - if (folder != null && folder.DateLastMediaAdded.HasValue) - { - _saveItemCommand.GetParameter(index++).Value = folder.DateLastMediaAdded.Value; - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - } - - _saveItemCommand.GetParameter(index++).Value = item.Album; + var saveColumns = new List + { + "guid", + "type", + "data", + "Path", + "StartDate", + "EndDate", + "ChannelId", + "IsKids", + "IsMovie", + "IsSports", + "IsSeries", + "IsLive", + "IsNews", + "IsPremiere", + "EpisodeTitle", + "IsRepeat", + "CommunityRating", + "CustomRating", + "IndexNumber", + "IsLocked", + "Name", + "OfficialRating", + "MediaType", + "Overview", + "ParentIndexNumber", + "PremiereDate", + "ProductionYear", + "ParentId", + "Genres", + "ParentalRatingValue", + "InheritedParentalRatingValue", + "SchemaVersion", + "SortName", + "RunTimeTicks", + "OfficialRatingDescription", + "HomePageUrl", + "VoteCount", + "DisplayMediaType", + "DateCreated", + "DateModified", + "ForcedSortName", + "IsOffline", + "LocationType", + "PreferredMetadataLanguage", + "PreferredMetadataCountryCode", + "IsHD", + "ExternalEtag", + "DateLastRefreshed", + "DateLastSaved", + "IsInMixedFolder", + "LockedFields", + "Studios", + "Audio", + "ExternalServiceId", + "Tags", + "IsFolder", + "UnratedType", + "TopParentId", + "IsItemByName", + "SourceType", + "TrailerTypes", + "CriticRating", + "CriticRatingSummary", + "DateModifiedDuringLastRefresh", + "InheritedTags", + "CleanName", + "PresentationUniqueKey", + "SlugName", + "OriginalTitle", + "PrimaryVersionId", + "DateLastMediaAdded", + "Album", + "IsVirtualItem", + "SeriesName" + }; + + saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; + + for (var i = 1; i <= saveColumns.Count; i++) + { + if (i > 1) + { + saveItemCommand.CommandText += ","; + } + saveItemCommand.CommandText += "@" + i.ToString(CultureInfo.InvariantCulture); - var season = item as Season; - if (season != null && season.IsVirtualItem.HasValue) - { - _saveItemCommand.GetParameter(index++).Value = season.IsVirtualItem.Value; - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; - } + saveItemCommand.Parameters.Add(saveItemCommand, "@" + i.ToString(CultureInfo.InvariantCulture)); + } + saveItemCommand.CommandText += ")"; - var hasSeries = item as IHasSeries; - if (hasSeries != null) - { - _saveItemCommand.GetParameter(index++).Value = hasSeries.SeriesName; - } - else - { - _saveItemCommand.GetParameter(index++).Value = null; + foreach (var item in items) + { + cancellationToken.ThrowIfCancellationRequested(); + + var index = 0; + + saveItemCommand.GetParameter(index++).Value = item.Id; + saveItemCommand.GetParameter(index++).Value = item.GetType().FullName; + saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item); + + saveItemCommand.GetParameter(index++).Value = item.Path; + + var hasStartDate = item as IHasStartDate; + if (hasStartDate != null) + { + saveItemCommand.GetParameter(index++).Value = hasStartDate.StartDate; + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + saveItemCommand.GetParameter(index++).Value = item.EndDate; + saveItemCommand.GetParameter(index++).Value = item.ChannelId; + + var hasProgramAttributes = item as IHasProgramAttributes; + if (hasProgramAttributes != null) + { + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsKids; + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsMovie; + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsSports; + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsSeries; + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsLive; + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsNews; + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsPremiere; + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.EpisodeTitle; + saveItemCommand.GetParameter(index++).Value = hasProgramAttributes.IsRepeat; + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + saveItemCommand.GetParameter(index++).Value = null; + saveItemCommand.GetParameter(index++).Value = null; + saveItemCommand.GetParameter(index++).Value = null; + saveItemCommand.GetParameter(index++).Value = null; + saveItemCommand.GetParameter(index++).Value = null; + saveItemCommand.GetParameter(index++).Value = null; + saveItemCommand.GetParameter(index++).Value = null; + saveItemCommand.GetParameter(index++).Value = null; + } + + saveItemCommand.GetParameter(index++).Value = item.CommunityRating; + saveItemCommand.GetParameter(index++).Value = item.CustomRating; + + saveItemCommand.GetParameter(index++).Value = item.IndexNumber; + saveItemCommand.GetParameter(index++).Value = item.IsLocked; + + saveItemCommand.GetParameter(index++).Value = item.Name; + saveItemCommand.GetParameter(index++).Value = item.OfficialRating; + + saveItemCommand.GetParameter(index++).Value = item.MediaType; + saveItemCommand.GetParameter(index++).Value = item.Overview; + saveItemCommand.GetParameter(index++).Value = item.ParentIndexNumber; + saveItemCommand.GetParameter(index++).Value = item.PremiereDate; + saveItemCommand.GetParameter(index++).Value = item.ProductionYear; + + if (item.ParentId == Guid.Empty) + { + saveItemCommand.GetParameter(index++).Value = null; + } + else + { + saveItemCommand.GetParameter(index++).Value = item.ParentId; + } + + saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray()); + saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue() ?? 0; + saveItemCommand.GetParameter(index++).Value = item.GetInheritedParentalRatingValue() ?? 0; + + saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion; + saveItemCommand.GetParameter(index++).Value = item.SortName; + saveItemCommand.GetParameter(index++).Value = item.RunTimeTicks; + + saveItemCommand.GetParameter(index++).Value = item.OfficialRatingDescription; + saveItemCommand.GetParameter(index++).Value = item.HomePageUrl; + saveItemCommand.GetParameter(index++).Value = item.VoteCount; + saveItemCommand.GetParameter(index++).Value = item.DisplayMediaType; + saveItemCommand.GetParameter(index++).Value = item.DateCreated; + saveItemCommand.GetParameter(index++).Value = item.DateModified; + + saveItemCommand.GetParameter(index++).Value = item.ForcedSortName; + saveItemCommand.GetParameter(index++).Value = item.IsOffline; + saveItemCommand.GetParameter(index++).Value = item.LocationType.ToString(); + + saveItemCommand.GetParameter(index++).Value = item.PreferredMetadataLanguage; + saveItemCommand.GetParameter(index++).Value = item.PreferredMetadataCountryCode; + saveItemCommand.GetParameter(index++).Value = item.IsHD; + saveItemCommand.GetParameter(index++).Value = item.ExternalEtag; + + if (item.DateLastRefreshed == default(DateTime)) + { + saveItemCommand.GetParameter(index++).Value = null; + } + else + { + saveItemCommand.GetParameter(index++).Value = item.DateLastRefreshed; + } + + if (item.DateLastSaved == default(DateTime)) + { + saveItemCommand.GetParameter(index++).Value = null; + } + else + { + saveItemCommand.GetParameter(index++).Value = item.DateLastSaved; + } + + saveItemCommand.GetParameter(index++).Value = item.IsInMixedFolder; + saveItemCommand.GetParameter(index++).Value = string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()); + saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Studios.ToArray()); + + if (item.Audio.HasValue) + { + saveItemCommand.GetParameter(index++).Value = item.Audio.Value.ToString(); + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + saveItemCommand.GetParameter(index++).Value = item.ServiceName; + + if (item.Tags.Count > 0) + { + saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray()); + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + saveItemCommand.GetParameter(index++).Value = item.IsFolder; + + saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString(); + + var topParent = item.GetTopParent(); + if (topParent != null) + { + //Logger.Debug("Item {0} has top parent {1}", item.Id, topParent.Id); + saveItemCommand.GetParameter(index++).Value = topParent.Id.ToString("N"); + } + else + { + //Logger.Debug("Item {0} has null top parent", item.Id); + saveItemCommand.GetParameter(index++).Value = null; + } + + var isByName = false; + var byName = item as IItemByName; + if (byName != null) + { + var dualAccess = item as IHasDualAccess; + isByName = dualAccess == null || dualAccess.IsAccessedByName; + } + saveItemCommand.GetParameter(index++).Value = isByName; + + saveItemCommand.GetParameter(index++).Value = item.SourceType.ToString(); + + var trailer = item as Trailer; + if (trailer != null && trailer.TrailerTypes.Count > 0) + { + saveItemCommand.GetParameter(index++).Value = string.Join("|", trailer.TrailerTypes.Select(i => i.ToString()).ToArray()); + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + saveItemCommand.GetParameter(index++).Value = item.CriticRating; + saveItemCommand.GetParameter(index++).Value = item.CriticRatingSummary; + + if (!item.DateModifiedDuringLastRefresh.HasValue || item.DateModifiedDuringLastRefresh.Value == default(DateTime)) + { + saveItemCommand.GetParameter(index++).Value = null; + } + else + { + saveItemCommand.GetParameter(index++).Value = item.DateModifiedDuringLastRefresh.Value; + } + + var inheritedTags = item.GetInheritedTags(); + if (inheritedTags.Count > 0) + { + saveItemCommand.GetParameter(index++).Value = string.Join("|", inheritedTags.ToArray()); + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + if (string.IsNullOrWhiteSpace(item.Name)) + { + saveItemCommand.GetParameter(index++).Value = null; + } + else + { + saveItemCommand.GetParameter(index++).Value = item.Name.RemoveDiacritics(); + } + + saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey; + saveItemCommand.GetParameter(index++).Value = item.SlugName; + saveItemCommand.GetParameter(index++).Value = item.OriginalTitle; + + var video = item as Video; + if (video != null) + { + saveItemCommand.GetParameter(index++).Value = video.PrimaryVersionId; + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + var folder = item as Folder; + if (folder != null && folder.DateLastMediaAdded.HasValue) + { + saveItemCommand.GetParameter(index++).Value = folder.DateLastMediaAdded.Value; + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + saveItemCommand.GetParameter(index++).Value = item.Album; + + var season = item as Season; + if (season != null && season.IsVirtualItem.HasValue) + { + saveItemCommand.GetParameter(index++).Value = season.IsVirtualItem.Value; + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + var hasSeries = item as IHasSeries; + if (hasSeries != null) + { + saveItemCommand.GetParameter(index++).Value = hasSeries.SeriesName; + } + else + { + saveItemCommand.GetParameter(index++).Value = null; + } + + saveItemCommand.Transaction = transaction; + + saveItemCommand.ExecuteNonQuery(); + + if (item.SupportsAncestors) + { + UpdateAncestors(item.Id, item.GetAncestorIds().Distinct().ToList(), connection, transaction); + } + + UpdateUserDataKeys(item.Id, item.GetUserDataKeys().Distinct(StringComparer.OrdinalIgnoreCase).ToList(), connection, transaction); + UpdateImages(item.Id, item.ImageInfos, connection, transaction); + UpdateProviderIds(item.Id, item.ProviderIds, connection, transaction); + UpdateItemValues(item.Id, GetItemValues(item), connection, transaction); + } } - _saveItemCommand.Transaction = transaction; - - _saveItemCommand.ExecuteNonQuery(); - - if (item.SupportsAncestors) + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) { - UpdateAncestors(item.Id, item.GetAncestorIds().Distinct().ToList(), transaction); + transaction.Rollback(); } - UpdateUserDataKeys(item.Id, item.GetUserDataKeys().Distinct(StringComparer.OrdinalIgnoreCase).ToList(), transaction); - UpdateImages(item.Id, item.ImageInfos, transaction); - UpdateProviderIds(item.Id, item.ProviderIds, transaction); - UpdateItemValues(item.Id, GetItemValues(item), transaction); + throw; } - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + catch (Exception e) { - transaction.Rollback(); - } + Logger.ErrorException("Failed to save items:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save items:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } @@ -953,19 +811,22 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems where guid = @guid"; - cmd.Parameters.Add(cmd, "@guid", DbType.Guid).Value = id; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) + using (var cmd = connection.CreateCommand()) { - if (reader.Read()) + cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems where guid = @guid"; + cmd.Parameters.Add(cmd, "@guid", DbType.Guid).Value = id; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) { - return GetItem(reader); + if (reader.Read()) + { + return GetItem(reader); + } } + return null; } - return null; } } @@ -1371,22 +1232,25 @@ namespace MediaBrowser.Server.Implementations.Persistence } var list = new List(); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select StartPositionTicks,Name,ImagePath from " + ChaptersTableName + " where ItemId = @ItemId order by ChapterIndex asc"; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select StartPositionTicks,Name,ImagePath from " + ChaptersTableName + " where ItemId = @ItemId order by ChapterIndex asc"; - cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = id; + cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = id; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - list.Add(GetChapter(reader)); + while (reader.Read()) + { + list.Add(GetChapter(reader)); + } } } - } - return list; + return list; + } } /// @@ -1404,21 +1268,24 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("id"); } - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select StartPositionTicks,Name,ImagePath from " + ChaptersTableName + " where ItemId = @ItemId and ChapterIndex=@ChapterIndex"; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select StartPositionTicks,Name,ImagePath from " + ChaptersTableName + " where ItemId = @ItemId and ChapterIndex=@ChapterIndex"; - cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = id; - cmd.Parameters.Add(cmd, "@ChapterIndex", DbType.Int32).Value = index; + cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = id; + cmd.Parameters.Add(cmd, "@ChapterIndex", DbType.Int32).Value = index; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) - { - if (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) { - return GetChapter(reader); + if (reader.Read()) + { + return GetChapter(reader); + } } + return null; } - return null; } } @@ -1447,6 +1314,21 @@ namespace MediaBrowser.Server.Implementations.Persistence return chapter; } + private void DeleteChapters(IDbConnection connection, IDbTransaction transaction, Guid id) + { + using (var deleteChaptersCommand = connection.CreateCommand()) + { + deleteChaptersCommand.CommandText = "delete from " + ChaptersTableName + " where ItemId=@ItemId"; + deleteChaptersCommand.Parameters.Add(deleteChaptersCommand, "@ItemId"); + + deleteChaptersCommand.GetParameter(0).Value = id; + + deleteChaptersCommand.Transaction = transaction; + + deleteChaptersCommand.ExecuteNonQuery(); + } + } + /// /// Saves the chapters. /// @@ -1461,7 +1343,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// or /// cancellationToken /// - public async Task SaveChapters(Guid id, IEnumerable chapters, CancellationToken cancellationToken) + public async Task SaveChapters(Guid id, List chapters, CancellationToken cancellationToken) { CheckDisposed(); @@ -1477,90 +1359,89 @@ namespace MediaBrowser.Server.Implementations.Persistence cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); - - // First delete chapters - _deleteChaptersCommand.GetParameter(0).Value = id; + IDbTransaction transaction = null; - _deleteChaptersCommand.Transaction = transaction; - - _deleteChaptersCommand.ExecuteNonQuery(); - - var index = 0; - - foreach (var chapter in chapters) + try { - cancellationToken.ThrowIfCancellationRequested(); + transaction = connection.BeginTransaction(); - _saveChapterCommand.GetParameter(0).Value = id; - _saveChapterCommand.GetParameter(1).Value = index; - _saveChapterCommand.GetParameter(2).Value = chapter.StartPositionTicks; - _saveChapterCommand.GetParameter(3).Value = chapter.Name; - _saveChapterCommand.GetParameter(4).Value = chapter.ImagePath; + // First delete chapters + DeleteChapters(connection, transaction, id); - _saveChapterCommand.Transaction = transaction; + var index = 0; - _saveChapterCommand.ExecuteNonQuery(); + if (chapters.Count > 0) + { + using (var saveChapterCommand = connection.CreateCommand()) + { + saveChapterCommand.CommandText = "replace into " + ChaptersTableName + " (ItemId, ChapterIndex, StartPositionTicks, Name, ImagePath) values (@ItemId, @ChapterIndex, @StartPositionTicks, @Name, @ImagePath)"; + saveChapterCommand.Parameters.Add(saveChapterCommand, "@ItemId"); + saveChapterCommand.Parameters.Add(saveChapterCommand, "@ChapterIndex"); + saveChapterCommand.Parameters.Add(saveChapterCommand, "@StartPositionTicks"); + saveChapterCommand.Parameters.Add(saveChapterCommand, "@Name"); + saveChapterCommand.Parameters.Add(saveChapterCommand, "@ImagePath"); + + if (chapters.Count > 1) + { + saveChapterCommand.Prepare(); + } + + foreach (var chapter in chapters) + { + cancellationToken.ThrowIfCancellationRequested(); + + saveChapterCommand.GetParameter(0).Value = id; + saveChapterCommand.GetParameter(1).Value = index; + saveChapterCommand.GetParameter(2).Value = chapter.StartPositionTicks; + saveChapterCommand.GetParameter(3).Value = chapter.Name; + saveChapterCommand.GetParameter(4).Value = chapter.ImagePath; + + saveChapterCommand.Transaction = transaction; + + saveChapterCommand.ExecuteNonQuery(); + + index++; + } + } + } - index++; + transaction.Commit(); } - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + catch (OperationCanceledException) { - transaction.Rollback(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Failed to save chapters:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save chapters:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } - protected override void CloseConnection() + private bool EnableJoinUserData(InternalItemsQuery query) { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } - - _connection.Dispose(); - _connection = null; - } - } - - private bool EnableJoinUserData(InternalItemsQuery query) - { - if (query.User == null) + if (query.User == null) { return false; } @@ -1628,13 +1509,13 @@ namespace MediaBrowser.Server.Implementations.Persistence if (EnableJoinUserData(query)) { - list.Add("UserDataDb.UserData.UserId"); - list.Add("UserDataDb.UserData.lastPlayedDate"); - list.Add("UserDataDb.UserData.playbackPositionTicks"); - list.Add("UserDataDb.UserData.playcount"); - list.Add("UserDataDb.UserData.isFavorite"); - list.Add("UserDataDb.UserData.played"); - list.Add("UserDataDb.UserData.rating"); + list.Add("UserData.UserId"); + list.Add("UserData.lastPlayedDate"); + list.Add("UserData.playbackPositionTicks"); + list.Add("UserData.playcount"); + list.Add("UserData.isFavorite"); + list.Add("UserData.played"); + list.Add("UserData.rating"); } if (query.SimilarTo != null) @@ -1688,7 +1569,7 @@ namespace MediaBrowser.Server.Implementations.Persistence return string.Empty; } - return " left join UserDataDb.UserData on (select UserDataKey from UserDataKeys where ItemId=Guid order by Priority LIMIT 1)=UserDataDb.UserData.Key"; + return " left join UserData on (select UserDataKey from UserDataKeys where ItemId=Guid order by Priority LIMIT 1)=UserData.Key"; } public IEnumerable GetItemList(InternalItemsQuery query) @@ -1702,53 +1583,61 @@ namespace MediaBrowser.Server.Implementations.Persistence var now = DateTime.UtcNow; - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems"; - cmd.CommandText += GetJoinUserDataText(query); - if (EnableJoinUserData(query)) { - cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id; + AttachUserDataDb(connection); } - var whereClauses = GetWhereClauses(query, cmd); + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems"; + cmd.CommandText += GetJoinUserDataText(query); - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + if (EnableJoinUserData(query)) + { + cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id; + } - cmd.CommandText += whereText; + var whereClauses = GetWhereClauses(query, cmd); - if (EnableGroupByPresentationUniqueKey(query)) - { - cmd.CommandText += " Group by PresentationUniqueKey"; - } + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += GetOrderByText(query); + cmd.CommandText += whereText; - if (query.Limit.HasValue || query.StartIndex.HasValue) - { - var limit = query.Limit ?? int.MaxValue; + if (EnableGroupByPresentationUniqueKey(query)) + { + cmd.CommandText += " Group by PresentationUniqueKey"; + } - cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); + cmd.CommandText += GetOrderByText(query); - if (query.StartIndex.HasValue) + if (query.Limit.HasValue || query.StartIndex.HasValue) { - cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); - } - } + var limit = query.Limit ?? int.MaxValue; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - LogQueryTime("GetItemList", cmd, now); + cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); - while (reader.Read()) + if (query.StartIndex.HasValue) + { + cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + } + } + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - var item = GetItem(reader); - if (item != null) + LogQueryTime("GetItemList", cmd, now); + + while (reader.Read()) { - yield return item; + var item = GetItem(reader); + if (item != null) + { + yield return item; + } } } } @@ -1792,86 +1681,94 @@ namespace MediaBrowser.Server.Implementations.Persistence var now = DateTime.UtcNow; - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems"; - cmd.CommandText += GetJoinUserDataText(query); - if (EnableJoinUserData(query)) { - cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id; + AttachUserDataDb(connection); } - var whereClauses = GetWhereClauses(query, cmd); + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems"; + cmd.CommandText += GetJoinUserDataText(query); + + if (EnableJoinUserData(query)) + { + cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id; + } - var whereTextWithoutPaging = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereClauses = GetWhereClauses(query, cmd); - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereTextWithoutPaging = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += whereText; + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - if (EnableGroupByPresentationUniqueKey(query)) - { - cmd.CommandText += " Group by PresentationUniqueKey"; - } + cmd.CommandText += whereText; + + if (EnableGroupByPresentationUniqueKey(query)) + { + cmd.CommandText += " Group by PresentationUniqueKey"; + } - cmd.CommandText += GetOrderByText(query); + cmd.CommandText += GetOrderByText(query); - if (query.Limit.HasValue || query.StartIndex.HasValue) - { - var limit = query.Limit ?? int.MaxValue; + if (query.Limit.HasValue || query.StartIndex.HasValue) + { + var limit = query.Limit ?? int.MaxValue; + + cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); - cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); + if (query.StartIndex.HasValue) + { + cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + } + } - if (query.StartIndex.HasValue) + if (EnableGroupByPresentationUniqueKey(query)) { - cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems"; + } + else + { + cmd.CommandText += "; select count (guid) from TypedBaseItems"; } - } - if (EnableGroupByPresentationUniqueKey(query)) - { - cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems"; - } - else - { - cmd.CommandText += "; select count (guid) from TypedBaseItems"; - } + cmd.CommandText += GetJoinUserDataText(query); + cmd.CommandText += whereTextWithoutPaging; - cmd.CommandText += GetJoinUserDataText(query); - cmd.CommandText += whereTextWithoutPaging; + var list = new List(); + var count = 0; - var list = new List(); - var count = 0; + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) + { + LogQueryTime("GetItems", cmd, now); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - LogQueryTime("GetItems", cmd, now); + while (reader.Read()) + { + var item = GetItem(reader); + if (item != null) + { + list.Add(item); + } + } - while (reader.Read()) - { - var item = GetItem(reader); - if (item != null) + if (reader.NextResult() && reader.Read()) { - list.Add(item); + count = reader.GetInt32(0); } } - if (reader.NextResult() && reader.Read()) + return new QueryResult() { - count = reader.GetInt32(0); - } + Items = list.ToArray(), + TotalRecordCount = count + }; } - - return new QueryResult() - { - Items = list.ToArray(), - TotalRecordCount = count - }; } } @@ -1989,56 +1886,64 @@ namespace MediaBrowser.Server.Implementations.Persistence var now = DateTime.UtcNow; - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems"; - cmd.CommandText += GetJoinUserDataText(query); - if (EnableJoinUserData(query)) { - cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id; + AttachUserDataDb(connection); } - var whereClauses = GetWhereClauses(query, cmd); + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems"; + cmd.CommandText += GetJoinUserDataText(query); - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + if (EnableJoinUserData(query)) + { + cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id; + } - cmd.CommandText += whereText; + var whereClauses = GetWhereClauses(query, cmd); - if (EnableGroupByPresentationUniqueKey(query)) - { - cmd.CommandText += " Group by PresentationUniqueKey"; - } + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += GetOrderByText(query); + cmd.CommandText += whereText; - if (query.Limit.HasValue || query.StartIndex.HasValue) - { - var limit = query.Limit ?? int.MaxValue; + if (EnableGroupByPresentationUniqueKey(query)) + { + cmd.CommandText += " Group by PresentationUniqueKey"; + } - cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); + cmd.CommandText += GetOrderByText(query); - if (query.StartIndex.HasValue) + if (query.Limit.HasValue || query.StartIndex.HasValue) { - cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); - } - } + var limit = query.Limit ?? int.MaxValue; - var list = new List(); + cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - LogQueryTime("GetItemIdsList", cmd, now); + if (query.StartIndex.HasValue) + { + cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + } + } + + var list = new List(); - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - list.Add(reader.GetGuid(0)); + LogQueryTime("GetItemIdsList", cmd, now); + + while (reader.Read()) + { + list.Add(reader.GetGuid(0)); + } } - } - return list; + return list; + } } } @@ -2051,73 +1956,76 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select guid,path from TypedBaseItems"; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select guid,path from TypedBaseItems"; - var whereClauses = GetWhereClauses(query, cmd); + var whereClauses = GetWhereClauses(query, cmd); - var whereTextWithoutPaging = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereTextWithoutPaging = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += whereText; + cmd.CommandText += whereText; - if (EnableGroupByPresentationUniqueKey(query)) - { - cmd.CommandText += " Group by PresentationUniqueKey"; - } + if (EnableGroupByPresentationUniqueKey(query)) + { + cmd.CommandText += " Group by PresentationUniqueKey"; + } - cmd.CommandText += GetOrderByText(query); + cmd.CommandText += GetOrderByText(query); - if (query.Limit.HasValue || query.StartIndex.HasValue) - { - var limit = query.Limit ?? int.MaxValue; + if (query.Limit.HasValue || query.StartIndex.HasValue) + { + var limit = query.Limit ?? int.MaxValue; - cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); + cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); - if (query.StartIndex.HasValue) - { - cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + if (query.StartIndex.HasValue) + { + cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + } } - } - cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging; + cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging; - var list = new List>(); - var count = 0; + var list = new List>(); + var count = 0; - Logger.Debug(cmd.CommandText); + Logger.Debug(cmd.CommandText); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - var id = reader.GetGuid(0); - string path = null; + while (reader.Read()) + { + var id = reader.GetGuid(0); + string path = null; + + if (!reader.IsDBNull(1)) + { + path = reader.GetString(1); + } + list.Add(new Tuple(id, path)); + } - if (!reader.IsDBNull(1)) + if (reader.NextResult() && reader.Read()) { - path = reader.GetString(1); + count = reader.GetInt32(0); } - list.Add(new Tuple(id, path)); } - if (reader.NextResult() && reader.Read()) + return new QueryResult>() { - count = reader.GetInt32(0); - } + Items = list.ToArray(), + TotalRecordCount = count + }; } - - return new QueryResult>() - { - Items = list.ToArray(), - TotalRecordCount = count - }; } } @@ -2132,78 +2040,86 @@ namespace MediaBrowser.Server.Implementations.Persistence var now = DateTime.UtcNow; - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems"; - - var whereClauses = GetWhereClauses(query, cmd); - cmd.CommandText += GetJoinUserDataText(query); - if (EnableJoinUserData(query)) { - cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id; + AttachUserDataDb(connection); } - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); - - cmd.CommandText += whereText; - - if (EnableGroupByPresentationUniqueKey(query)) + using (var cmd = connection.CreateCommand()) { - cmd.CommandText += " Group by PresentationUniqueKey"; - } + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems"; - cmd.CommandText += GetOrderByText(query); + var whereClauses = GetWhereClauses(query, cmd); + cmd.CommandText += GetJoinUserDataText(query); - if (query.Limit.HasValue || query.StartIndex.HasValue) - { - var limit = query.Limit ?? int.MaxValue; + if (EnableJoinUserData(query)) + { + cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = query.User.Id; + } + + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); + cmd.CommandText += whereText; - if (query.StartIndex.HasValue) + if (EnableGroupByPresentationUniqueKey(query)) { - cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + cmd.CommandText += " Group by PresentationUniqueKey"; } - } - if (EnableGroupByPresentationUniqueKey(query)) - { - cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems"; - } - else - { - cmd.CommandText += "; select count (guid) from TypedBaseItems"; - } + cmd.CommandText += GetOrderByText(query); - cmd.CommandText += GetJoinUserDataText(query); - cmd.CommandText += whereText; + if (query.Limit.HasValue || query.StartIndex.HasValue) + { + var limit = query.Limit ?? int.MaxValue; - var list = new List(); - var count = 0; + cmd.CommandText += " LIMIT " + limit.ToString(CultureInfo.InvariantCulture); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - LogQueryTime("GetItemIds", cmd, now); + if (query.StartIndex.HasValue) + { + cmd.CommandText += " OFFSET " + query.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + } + } - while (reader.Read()) + if (EnableGroupByPresentationUniqueKey(query)) + { + cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems"; + } + else { - list.Add(reader.GetGuid(0)); + cmd.CommandText += "; select count (guid) from TypedBaseItems"; } - if (reader.NextResult() && reader.Read()) + cmd.CommandText += GetJoinUserDataText(query); + cmd.CommandText += whereText; + + var list = new List(); + var count = 0; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - count = reader.GetInt32(0); + LogQueryTime("GetItemIds", cmd, now); + + while (reader.Read()) + { + list.Add(reader.GetGuid(0)); + } + + if (reader.NextResult() && reader.Read()) + { + count = reader.GetInt32(0); + } } - } - return new QueryResult() - { - Items = list.ToArray(), - TotalRecordCount = count - }; + return new QueryResult() + { + Items = list.ToArray(), + TotalRecordCount = count + }; + } } } @@ -2987,77 +2903,88 @@ namespace MediaBrowser.Server.Implementations.Persistence private async Task UpdateInheritedTags(CancellationToken cancellationToken) { - var newValues = new List>(); - - using (var cmd = _connection.CreateCommand()) + using (var connection = await CreateConnection().ConfigureAwait(false)) { - cmd.CommandText = "select Guid,InheritedTags,(select group_concat(Tags, '|') from TypedBaseItems where (guid=outer.guid) OR (guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid))) as NewInheritedTags from typedbaseitems as Outer where NewInheritedTags <> InheritedTags"; + var newValues = new List>(); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + using (var cmd = connection.CreateCommand()) { - while (reader.Read()) + cmd.CommandText = "select Guid,InheritedTags,(select group_concat(Tags, '|') from TypedBaseItems where (guid=outer.guid) OR (guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid))) as NewInheritedTags from typedbaseitems as Outer where NewInheritedTags <> InheritedTags"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - var id = reader.GetGuid(0); - string value = reader.IsDBNull(2) ? null : reader.GetString(2); + while (reader.Read()) + { + var id = reader.GetGuid(0); + string value = reader.IsDBNull(2) ? null : reader.GetString(2); - newValues.Add(new Tuple(id, value)); + newValues.Add(new Tuple(id, value)); + } } } - } - Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count); - if (newValues.Count == 0) - { - return; - } + Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count); + if (newValues.Count == 0) + { + return; + } - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); + IDbTransaction transaction = null; - IDbTransaction transaction = null; + try + { + transaction = connection.BeginTransaction(); - try - { - transaction = _connection.BeginTransaction(); + using (var updateInheritedTagsCommand = connection.CreateCommand()) + { + updateInheritedTagsCommand.CommandText = "Update TypedBaseItems set InheritedTags=@InheritedTags where Guid=@Guid"; + updateInheritedTagsCommand.Parameters.Add(updateInheritedTagsCommand, "@Guid"); + updateInheritedTagsCommand.Parameters.Add(updateInheritedTagsCommand, "@InheritedTags"); - foreach (var item in newValues) - { - _updateInheritedTagsCommand.GetParameter(0).Value = item.Item1; - _updateInheritedTagsCommand.GetParameter(1).Value = item.Item2; + if (newValues.Count > 1) + { + updateInheritedTagsCommand.Prepare(); + } - _updateInheritedTagsCommand.Transaction = transaction; - _updateInheritedTagsCommand.ExecuteNonQuery(); - } + foreach (var item in newValues) + { + updateInheritedTagsCommand.GetParameter(0).Value = item.Item1; + updateInheritedTagsCommand.GetParameter(1).Value = item.Item2; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + updateInheritedTagsCommand.Transaction = transaction; + updateInheritedTagsCommand.ExecuteNonQuery(); + } + } + + transaction.Commit(); + } + catch (OperationCanceledException) { - transaction.Rollback(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Error running query:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Error running query:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } @@ -3065,75 +2992,82 @@ namespace MediaBrowser.Server.Implementations.Persistence { var newValues = new List>(); - using (var cmd = _connection.CreateCommand()) + using (var connection = await CreateConnection().ConfigureAwait(false)) { - cmd.CommandText = "select Guid,InheritedParentalRatingValue,(select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems where guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid)))) as NewInheritedParentalRatingValue from typedbaseitems as Outer where InheritedParentalRatingValue <> NewInheritedParentalRatingValue"; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + using (var cmd = connection.CreateCommand()) { - while (reader.Read()) + cmd.CommandText = "select Guid,InheritedParentalRatingValue,(select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems where guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid)))) as NewInheritedParentalRatingValue from typedbaseitems as Outer where InheritedParentalRatingValue <> NewInheritedParentalRatingValue"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - var id = reader.GetGuid(0); - var newValue = reader.GetInt32(2); + while (reader.Read()) + { + var id = reader.GetGuid(0); + var newValue = reader.GetInt32(2); - newValues.Add(new Tuple(id, newValue)); + newValues.Add(new Tuple(id, newValue)); + } } } - } - Logger.Debug("UpdateInheritedParentalRatings - {0} rows", newValues.Count); - if (newValues.Count == 0) - { - return; - } + Logger.Debug("UpdateInheritedParentalRatings - {0} rows", newValues.Count); + if (newValues.Count == 0) + { + return; + } - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); + using (var updateInheritedRatingCommand = connection.CreateCommand()) + { + updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid"; + updateInheritedRatingCommand.Parameters.Add(updateInheritedRatingCommand, "@Guid"); + updateInheritedRatingCommand.Parameters.Add(updateInheritedRatingCommand, "@InheritedParentalRatingValue"); + updateInheritedRatingCommand.Prepare(); - IDbTransaction transaction = null; + IDbTransaction transaction = null; - try - { - transaction = _connection.BeginTransaction(); + try + { + transaction = connection.BeginTransaction(); - foreach (var item in newValues) - { - _updateInheritedRatingCommand.GetParameter(0).Value = item.Item1; - _updateInheritedRatingCommand.GetParameter(1).Value = item.Item2; + foreach (var item in newValues) + { + updateInheritedRatingCommand.GetParameter(0).Value = item.Item1; + updateInheritedRatingCommand.GetParameter(1).Value = item.Item2; - _updateInheritedRatingCommand.Transaction = transaction; - _updateInheritedRatingCommand.ExecuteNonQuery(); - } + updateInheritedRatingCommand.Transaction = transaction; + updateInheritedRatingCommand.ExecuteNonQuery(); + } - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - catch (Exception e) - { - Logger.ErrorException("Error running query:", e); + throw; + } + catch (Exception e) + { + Logger.ErrorException("Error running query:", e); - if (transaction != null) - { - transaction.Rollback(); - } + if (transaction != null) + { + transaction.Rollback(); + } - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } } - - WriteLock.Release(); } } @@ -3176,89 +3110,73 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); + IDbTransaction transaction = null; - // Delete people - _deletePeopleCommand.GetParameter(0).Value = id; - _deletePeopleCommand.Transaction = transaction; - _deletePeopleCommand.ExecuteNonQuery(); + try + { + transaction = connection.BeginTransaction(); - // Delete chapters - _deleteChaptersCommand.GetParameter(0).Value = id; - _deleteChaptersCommand.Transaction = transaction; - _deleteChaptersCommand.ExecuteNonQuery(); + // Delete people + DeletePeople(connection, transaction, id); + DeleteChapters(connection, transaction, id); + DeleteMediaStreams(connection, transaction, id); - // Delete media streams - _deleteStreamsCommand.GetParameter(0).Value = id; - _deleteStreamsCommand.Transaction = transaction; - _deleteStreamsCommand.ExecuteNonQuery(); + // Delete ancestors + DeleteAncestors(connection, transaction, id); - // Delete ancestors - _deleteAncestorsCommand.GetParameter(0).Value = id; - _deleteAncestorsCommand.Transaction = transaction; - _deleteAncestorsCommand.ExecuteNonQuery(); + // Delete user data keys + DeleteUserDataKeys(connection, transaction, id); - // Delete user data keys - _deleteUserDataKeysCommand.GetParameter(0).Value = id; - _deleteUserDataKeysCommand.Transaction = transaction; - _deleteUserDataKeysCommand.ExecuteNonQuery(); + // Delete item values + DeleteItemValues(connection, transaction, id); - // Delete item values - _deleteItemValuesCommand.GetParameter(0).Value = id; - _deleteItemValuesCommand.Transaction = transaction; - _deleteItemValuesCommand.ExecuteNonQuery(); + // Delete provider ids + DeleteProviderIds(connection, transaction, id); - // Delete provider ids - _deleteProviderIdsCommand.GetParameter(0).Value = id; - _deleteProviderIdsCommand.Transaction = transaction; - _deleteProviderIdsCommand.ExecuteNonQuery(); + DeleteImages(connection, transaction, id); - // Delete images - _deleteImagesCommand.GetParameter(0).Value = id; - _deleteImagesCommand.Transaction = transaction; - _deleteImagesCommand.ExecuteNonQuery(); + // Delete the item + using (var deleteItemCommand = connection.CreateCommand()) + { + deleteItemCommand.CommandText = "delete from TypedBaseItems where guid=@Id"; + deleteItemCommand.Parameters.Add(deleteItemCommand, "@Id"); - // Delete the item - _deleteItemCommand.GetParameter(0).Value = id; - _deleteItemCommand.Transaction = transaction; - _deleteItemCommand.ExecuteNonQuery(); + deleteItemCommand.GetParameter(0).Value = id; + deleteItemCommand.Transaction = transaction; + deleteItemCommand.ExecuteNonQuery(); + } - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + transaction.Commit(); + } + catch (OperationCanceledException) { - transaction.Rollback(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Failed to save children:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save children:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } @@ -3271,30 +3189,33 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select Distinct Name from People"; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select Distinct Name from People"; - var whereClauses = GetPeopleWhereClauses(query, cmd); + var whereClauses = GetPeopleWhereClauses(query, cmd); - if (whereClauses.Count > 0) - { - cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); - } + if (whereClauses.Count > 0) + { + cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); + } - cmd.CommandText += " order by ListOrder"; + cmd.CommandText += " order by ListOrder"; - var list = new List(); + var list = new List(); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - list.Add(reader.GetString(0)); + while (reader.Read()) + { + list.Add(reader.GetString(0)); + } } - } - return list; + return list; + } } } @@ -3307,30 +3228,33 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = "select ItemId, Name, Role, PersonType, SortOrder from People"; + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "select ItemId, Name, Role, PersonType, SortOrder from People"; - var whereClauses = GetPeopleWhereClauses(query, cmd); + var whereClauses = GetPeopleWhereClauses(query, cmd); - if (whereClauses.Count > 0) - { - cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); - } + if (whereClauses.Count > 0) + { + cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray()); + } - cmd.CommandText += " order by ListOrder"; + cmd.CommandText += " order by ListOrder"; - var list = new List(); + var list = new List(); - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - list.Add(GetPerson(reader)); + while (reader.Read()) + { + list.Add(GetPerson(reader)); + } } - } - return list; + return list; + } } } @@ -3384,7 +3308,21 @@ namespace MediaBrowser.Server.Implementations.Persistence return whereClauses; } - private void UpdateAncestors(Guid itemId, List ancestorIds, IDbTransaction transaction) + private void DeleteAncestors(IDbConnection connection, IDbTransaction transaction, Guid id) + { + using (var deleteAncestorsCommand = connection.CreateCommand()) + { + deleteAncestorsCommand.CommandText = "delete from AncestorIds where ItemId=@Id"; + deleteAncestorsCommand.Parameters.Add(deleteAncestorsCommand, "@Id"); + + deleteAncestorsCommand.GetParameter(0).Value = id; + deleteAncestorsCommand.Transaction = transaction; + + deleteAncestorsCommand.ExecuteNonQuery(); + } + } + + private void UpdateAncestors(Guid itemId, List ancestorIds, IDbConnection connection, IDbTransaction transaction) { if (itemId == Guid.Empty) { @@ -3399,20 +3337,33 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); // First delete - _deleteAncestorsCommand.GetParameter(0).Value = itemId; - _deleteAncestorsCommand.Transaction = transaction; + DeleteAncestors(connection, transaction, itemId); - _deleteAncestorsCommand.ExecuteNonQuery(); - - foreach (var ancestorId in ancestorIds) + if (ancestorIds.Count > 0) { - _saveAncestorCommand.GetParameter(0).Value = itemId; - _saveAncestorCommand.GetParameter(1).Value = ancestorId; - _saveAncestorCommand.GetParameter(2).Value = ancestorId.ToString("N"); + using (var saveAncestorCommand = connection.CreateCommand()) + { + saveAncestorCommand.CommandText = "insert into AncestorIds (ItemId, AncestorId, AncestorIdText) values (@ItemId, @AncestorId, @AncestorIdText)"; + saveAncestorCommand.Parameters.Add(saveAncestorCommand, "@ItemId"); + saveAncestorCommand.Parameters.Add(saveAncestorCommand, "@AncestorId"); + saveAncestorCommand.Parameters.Add(saveAncestorCommand, "@AncestorIdText"); + + if (ancestorIds.Count > 1) + { + saveAncestorCommand.Prepare(); + } + + foreach (var ancestorId in ancestorIds) + { + saveAncestorCommand.GetParameter(0).Value = itemId; + saveAncestorCommand.GetParameter(1).Value = ancestorId; + saveAncestorCommand.GetParameter(2).Value = ancestorId.ToString("N"); - _saveAncestorCommand.Transaction = transaction; + saveAncestorCommand.Transaction = transaction; - _saveAncestorCommand.ExecuteNonQuery(); + saveAncestorCommand.ExecuteNonQuery(); + } + } } } @@ -3440,7 +3391,20 @@ namespace MediaBrowser.Server.Implementations.Persistence return list; } - private void UpdateImages(Guid itemId, List images, IDbTransaction transaction) + private void DeleteImages(IDbConnection connection, IDbTransaction transaction, Guid id) + { + using (var deleteImagesCommand = connection.CreateCommand()) + { + deleteImagesCommand.CommandText = "delete from Images where ItemId=@Id"; + deleteImagesCommand.Parameters.Add(deleteImagesCommand, "@Id"); + + deleteImagesCommand.GetParameter(0).Value = id; + deleteImagesCommand.Transaction = transaction; + deleteImagesCommand.ExecuteNonQuery(); + } + } + + private void UpdateImages(Guid itemId, List images, IDbConnection connection, IDbTransaction transaction) { if (itemId == Guid.Empty) { @@ -3455,38 +3419,70 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); // First delete - _deleteImagesCommand.GetParameter(0).Value = itemId; - _deleteImagesCommand.Transaction = transaction; - - _deleteImagesCommand.ExecuteNonQuery(); + DeleteImages(connection, transaction, itemId); - var index = 0; - foreach (var image in images) + if (images.Count > 0) { - _saveImagesCommand.GetParameter(0).Value = itemId; - _saveImagesCommand.GetParameter(1).Value = image.Type; - _saveImagesCommand.GetParameter(2).Value = image.Path; - - if (image.DateModified == default(DateTime)) - { - _saveImagesCommand.GetParameter(3).Value = null; - } - else + using (var saveImagesCommand = connection.CreateCommand()) { - _saveImagesCommand.GetParameter(3).Value = image.DateModified; + var index = 0; + + saveImagesCommand.CommandText = "insert into Images (ItemId, ImageType, Path, DateModified, IsPlaceHolder, SortOrder) values (@ItemId, @ImageType, @Path, @DateModified, @IsPlaceHolder, @SortOrder)"; + saveImagesCommand.Parameters.Add(saveImagesCommand, "@ItemId"); + saveImagesCommand.Parameters.Add(saveImagesCommand, "@ImageType"); + saveImagesCommand.Parameters.Add(saveImagesCommand, "@Path"); + saveImagesCommand.Parameters.Add(saveImagesCommand, "@DateModified"); + saveImagesCommand.Parameters.Add(saveImagesCommand, "@IsPlaceHolder"); + saveImagesCommand.Parameters.Add(saveImagesCommand, "@SortOrder"); + + if (images.Count > 1) + { + saveImagesCommand.Prepare(); + } + + foreach (var image in images) + { + saveImagesCommand.GetParameter(0).Value = itemId; + saveImagesCommand.GetParameter(1).Value = image.Type; + saveImagesCommand.GetParameter(2).Value = image.Path; + + if (image.DateModified == default(DateTime)) + { + saveImagesCommand.GetParameter(3).Value = null; + } + else + { + saveImagesCommand.GetParameter(3).Value = image.DateModified; + } + + saveImagesCommand.GetParameter(4).Value = image.IsPlaceholder; + saveImagesCommand.GetParameter(5).Value = index; + + saveImagesCommand.Transaction = transaction; + + saveImagesCommand.ExecuteNonQuery(); + index++; + } } + } + } - _saveImagesCommand.GetParameter(4).Value = image.IsPlaceholder; - _saveImagesCommand.GetParameter(5).Value = index; + private void DeleteProviderIds(IDbConnection connection, IDbTransaction transaction, Guid itemId) + { + using (var deleteProviderIdsCommand = connection.CreateCommand()) + { + // provider ids + deleteProviderIdsCommand.CommandText = "delete from ProviderIds where ItemId=@Id"; + deleteProviderIdsCommand.Parameters.Add(deleteProviderIdsCommand, "@Id"); - _saveImagesCommand.Transaction = transaction; + deleteProviderIdsCommand.GetParameter(0).Value = itemId; + deleteProviderIdsCommand.Transaction = transaction; - _saveImagesCommand.ExecuteNonQuery(); - index++; + deleteProviderIdsCommand.ExecuteNonQuery(); } } - private void UpdateProviderIds(Guid itemId, Dictionary values, IDbTransaction transaction) + private void UpdateProviderIds(Guid itemId, Dictionary values, IDbConnection connection, IDbTransaction transaction) { if (itemId == Guid.Empty) { @@ -3501,23 +3497,51 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); // First delete - _deleteProviderIdsCommand.GetParameter(0).Value = itemId; - _deleteProviderIdsCommand.Transaction = transaction; + DeleteProviderIds(connection, transaction, itemId); + + if (values.Count > 0) + { + using (var saveProviderIdsCommand = connection.CreateCommand()) + { + saveProviderIdsCommand.CommandText = "insert into ProviderIds (ItemId, Name, Value) values (@ItemId, @Name, @Value)"; + saveProviderIdsCommand.Parameters.Add(saveProviderIdsCommand, "@ItemId"); + saveProviderIdsCommand.Parameters.Add(saveProviderIdsCommand, "@Name"); + saveProviderIdsCommand.Parameters.Add(saveProviderIdsCommand, "@Value"); + + if (values.Count > 1) + { + saveProviderIdsCommand.Prepare(); + } + + foreach (var pair in values) + { + saveProviderIdsCommand.GetParameter(0).Value = itemId; + saveProviderIdsCommand.GetParameter(1).Value = pair.Key; + saveProviderIdsCommand.GetParameter(2).Value = pair.Value; + saveProviderIdsCommand.Transaction = transaction; - _deleteProviderIdsCommand.ExecuteNonQuery(); + saveProviderIdsCommand.ExecuteNonQuery(); + } + } + } + } - foreach (var pair in values) + private void DeleteItemValues(IDbConnection connection, IDbTransaction transaction, Guid itemId) + { + using (var deleteItemValuesCommand = connection.CreateCommand()) { - _saveProviderIdsCommand.GetParameter(0).Value = itemId; - _saveProviderIdsCommand.GetParameter(1).Value = pair.Key; - _saveProviderIdsCommand.GetParameter(2).Value = pair.Value; - _saveProviderIdsCommand.Transaction = transaction; + deleteItemValuesCommand.CommandText = "delete from ItemValues where ItemId=@Id"; + deleteItemValuesCommand.Parameters.Add(deleteItemValuesCommand, "@Id"); + + // First delete + deleteItemValuesCommand.GetParameter(0).Value = itemId; + deleteItemValuesCommand.Transaction = transaction; - _saveProviderIdsCommand.ExecuteNonQuery(); + deleteItemValuesCommand.ExecuteNonQuery(); } } - private void UpdateItemValues(Guid itemId, List> values, IDbTransaction transaction) + private void UpdateItemValues(Guid itemId, List> values, IDbConnection connection, IDbTransaction transaction) { if (itemId == Guid.Empty) { @@ -3532,23 +3556,51 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); // First delete - _deleteItemValuesCommand.GetParameter(0).Value = itemId; - _deleteItemValuesCommand.Transaction = transaction; + DeleteItemValues(connection, transaction, itemId); + + if (values.Count > 0) + { + using (var saveItemValuesCommand = connection.CreateCommand()) + { + saveItemValuesCommand.CommandText = "insert into ItemValues (ItemId, Type, Value) values (@ItemId, @Type, @Value)"; + saveItemValuesCommand.Parameters.Add(saveItemValuesCommand, "@ItemId"); + saveItemValuesCommand.Parameters.Add(saveItemValuesCommand, "@Type"); + saveItemValuesCommand.Parameters.Add(saveItemValuesCommand, "@Value"); + + if (values.Count > 1) + { + saveItemValuesCommand.Prepare(); + } + + foreach (var pair in values) + { + saveItemValuesCommand.GetParameter(0).Value = itemId; + saveItemValuesCommand.GetParameter(1).Value = pair.Item1; + saveItemValuesCommand.GetParameter(2).Value = pair.Item2; + saveItemValuesCommand.Transaction = transaction; - _deleteItemValuesCommand.ExecuteNonQuery(); + saveItemValuesCommand.ExecuteNonQuery(); + } + } + } + } - foreach (var pair in values) + private void DeleteUserDataKeys(IDbConnection connection, IDbTransaction transaction, Guid itemId) + { + using (var deleteUserDataKeysCommand = connection.CreateCommand()) { - _saveItemValuesCommand.GetParameter(0).Value = itemId; - _saveItemValuesCommand.GetParameter(1).Value = pair.Item1; - _saveItemValuesCommand.GetParameter(2).Value = pair.Item2; - _saveItemValuesCommand.Transaction = transaction; + // user data + deleteUserDataKeysCommand.CommandText = "delete from UserDataKeys where ItemId=@Id"; + deleteUserDataKeysCommand.Parameters.Add(deleteUserDataKeysCommand, "@Id"); + + deleteUserDataKeysCommand.GetParameter(0).Value = itemId; + deleteUserDataKeysCommand.Transaction = transaction; - _saveItemValuesCommand.ExecuteNonQuery(); + deleteUserDataKeysCommand.ExecuteNonQuery(); } } - private void UpdateUserDataKeys(Guid itemId, List keys, IDbTransaction transaction) + private void UpdateUserDataKeys(Guid itemId, List keys, IDbConnection connection, IDbTransaction transaction) { if (itemId == Guid.Empty) { @@ -3563,21 +3615,50 @@ namespace MediaBrowser.Server.Implementations.Persistence CheckDisposed(); // First delete - _deleteUserDataKeysCommand.GetParameter(0).Value = itemId; - _deleteUserDataKeysCommand.Transaction = transaction; + DeleteUserDataKeys(connection, transaction, itemId); - _deleteUserDataKeysCommand.ExecuteNonQuery(); var index = 0; - foreach (var key in keys) + if (keys.Count > 0) + { + using (var saveUserDataKeysCommand = connection.CreateCommand()) + { + saveUserDataKeysCommand.CommandText = "insert into UserDataKeys (ItemId, UserDataKey, Priority) values (@ItemId, @UserDataKey, @Priority)"; + saveUserDataKeysCommand.Parameters.Add(saveUserDataKeysCommand, "@ItemId"); + saveUserDataKeysCommand.Parameters.Add(saveUserDataKeysCommand, "@UserDataKey"); + saveUserDataKeysCommand.Parameters.Add(saveUserDataKeysCommand, "@Priority"); + + if (keys.Count > 1) + { + saveUserDataKeysCommand.Prepare(); + } + + foreach (var key in keys) + { + saveUserDataKeysCommand.GetParameter(0).Value = itemId; + saveUserDataKeysCommand.GetParameter(1).Value = key; + saveUserDataKeysCommand.GetParameter(2).Value = index; + index++; + saveUserDataKeysCommand.Transaction = transaction; + + saveUserDataKeysCommand.ExecuteNonQuery(); + } + } + } + } + + private void DeletePeople(IDbConnection connection, IDbTransaction transaction, Guid id) + { + using (var deletePeopleCommand = connection.CreateCommand()) { - _saveUserDataKeysCommand.GetParameter(0).Value = itemId; - _saveUserDataKeysCommand.GetParameter(1).Value = key; - _saveUserDataKeysCommand.GetParameter(2).Value = index; - index++; - _saveUserDataKeysCommand.Transaction = transaction; + deletePeopleCommand.CommandText = "delete from People where ItemId=@Id"; + deletePeopleCommand.Parameters.Add(deletePeopleCommand, "@Id"); - _saveUserDataKeysCommand.ExecuteNonQuery(); + + deletePeopleCommand.GetParameter(0).Value = id; + deletePeopleCommand.Transaction = transaction; + + deletePeopleCommand.ExecuteNonQuery(); } } @@ -3597,69 +3678,85 @@ namespace MediaBrowser.Server.Implementations.Persistence var cancellationToken = CancellationToken.None; - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); - - // First delete - _deletePeopleCommand.GetParameter(0).Value = itemId; - _deletePeopleCommand.Transaction = transaction; + IDbTransaction transaction = null; - _deletePeopleCommand.ExecuteNonQuery(); + try + { + transaction = connection.BeginTransaction(); - var listIndex = 0; + // First delete + DeletePeople(connection, transaction, itemId); - foreach (var person in people) - { - cancellationToken.ThrowIfCancellationRequested(); + var listIndex = 0; - _savePersonCommand.GetParameter(0).Value = itemId; - _savePersonCommand.GetParameter(1).Value = person.Name; - _savePersonCommand.GetParameter(2).Value = person.Role; - _savePersonCommand.GetParameter(3).Value = person.Type; - _savePersonCommand.GetParameter(4).Value = person.SortOrder; - _savePersonCommand.GetParameter(5).Value = listIndex; + if (people.Count > 0) + { + using (var savePersonCommand = connection.CreateCommand()) + { + savePersonCommand.CommandText = "insert into People (ItemId, Name, Role, PersonType, SortOrder, ListOrder) values (@ItemId, @Name, @Role, @PersonType, @SortOrder, @ListOrder)"; + savePersonCommand.Parameters.Add(savePersonCommand, "@ItemId"); + savePersonCommand.Parameters.Add(savePersonCommand, "@Name"); + savePersonCommand.Parameters.Add(savePersonCommand, "@Role"); + savePersonCommand.Parameters.Add(savePersonCommand, "@PersonType"); + savePersonCommand.Parameters.Add(savePersonCommand, "@SortOrder"); + savePersonCommand.Parameters.Add(savePersonCommand, "@ListOrder"); + + if (people.Count > 1) + { + savePersonCommand.Prepare(); + } + + foreach (var person in people) + { + cancellationToken.ThrowIfCancellationRequested(); + + savePersonCommand.GetParameter(0).Value = itemId; + savePersonCommand.GetParameter(1).Value = person.Name; + savePersonCommand.GetParameter(2).Value = person.Role; + savePersonCommand.GetParameter(3).Value = person.Type; + savePersonCommand.GetParameter(4).Value = person.SortOrder; + savePersonCommand.GetParameter(5).Value = listIndex; + + savePersonCommand.Transaction = transaction; + + savePersonCommand.ExecuteNonQuery(); + listIndex++; + } + } + } - _savePersonCommand.Transaction = transaction; + transaction.Commit(); - _savePersonCommand.ExecuteNonQuery(); - listIndex++; } - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + catch (OperationCanceledException) { - transaction.Rollback(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Failed to save people:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save people:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } @@ -3699,42 +3796,61 @@ namespace MediaBrowser.Server.Implementations.Persistence var list = new List(); - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - var cmdText = "select " + string.Join(",", _mediaStreamSaveColumns) + " from mediastreams where"; + using (var cmd = connection.CreateCommand()) + { + var cmdText = "select " + string.Join(",", _mediaStreamSaveColumns) + " from mediastreams where"; - cmdText += " ItemId=@ItemId"; - cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = query.ItemId; + cmdText += " ItemId=@ItemId"; + cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = query.ItemId; - if (query.Type.HasValue) - { - cmdText += " AND StreamType=@StreamType"; - cmd.Parameters.Add(cmd, "@StreamType", DbType.String).Value = query.Type.Value.ToString(); - } + if (query.Type.HasValue) + { + cmdText += " AND StreamType=@StreamType"; + cmd.Parameters.Add(cmd, "@StreamType", DbType.String).Value = query.Type.Value.ToString(); + } - if (query.Index.HasValue) - { - cmdText += " AND StreamIndex=@StreamIndex"; - cmd.Parameters.Add(cmd, "@StreamIndex", DbType.Int32).Value = query.Index.Value; - } + if (query.Index.HasValue) + { + cmdText += " AND StreamIndex=@StreamIndex"; + cmd.Parameters.Add(cmd, "@StreamIndex", DbType.Int32).Value = query.Index.Value; + } - cmdText += " order by StreamIndex ASC"; + cmdText += " order by StreamIndex ASC"; - cmd.CommandText = cmdText; + cmd.CommandText = cmdText; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) { - list.Add(GetMediaStream(reader)); + while (reader.Read()) + { + list.Add(GetMediaStream(reader)); + } } } + + return list; } + } - return list; + private void DeleteMediaStreams(IDbConnection connection, IDbTransaction transaction, Guid id) + { + using (var deleteStreamsCommand = connection.CreateCommand()) + { + // MediaStreams + deleteStreamsCommand.CommandText = "delete from mediastreams where ItemId=@ItemId"; + deleteStreamsCommand.Parameters.Add(deleteStreamsCommand, "@ItemId"); + + deleteStreamsCommand.GetParameter(0).Value = id; + + deleteStreamsCommand.Transaction = transaction; + + deleteStreamsCommand.ExecuteNonQuery(); + } } - public async Task SaveMediaStreams(Guid id, IEnumerable streams, CancellationToken cancellationToken) + public async Task SaveMediaStreams(Guid id, List streams, CancellationToken cancellationToken) { CheckDisposed(); @@ -3750,100 +3866,115 @@ namespace MediaBrowser.Server.Implementations.Persistence cancellationToken.ThrowIfCancellationRequested(); - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try + using (var connection = await CreateConnection().ConfigureAwait(false)) { - transaction = _connection.BeginTransaction(); - - // First delete chapters - _deleteStreamsCommand.GetParameter(0).Value = id; - - _deleteStreamsCommand.Transaction = transaction; + IDbTransaction transaction = null; - _deleteStreamsCommand.ExecuteNonQuery(); - - foreach (var stream in streams) + try { - cancellationToken.ThrowIfCancellationRequested(); - - var index = 0; - - _saveStreamCommand.GetParameter(index++).Value = id; - _saveStreamCommand.GetParameter(index++).Value = stream.Index; - _saveStreamCommand.GetParameter(index++).Value = stream.Type.ToString(); - _saveStreamCommand.GetParameter(index++).Value = stream.Codec; - _saveStreamCommand.GetParameter(index++).Value = stream.Language; - _saveStreamCommand.GetParameter(index++).Value = stream.ChannelLayout; - _saveStreamCommand.GetParameter(index++).Value = stream.Profile; - _saveStreamCommand.GetParameter(index++).Value = stream.AspectRatio; - _saveStreamCommand.GetParameter(index++).Value = stream.Path; - - _saveStreamCommand.GetParameter(index++).Value = stream.IsInterlaced; - - _saveStreamCommand.GetParameter(index++).Value = stream.BitRate; - _saveStreamCommand.GetParameter(index++).Value = stream.Channels; - _saveStreamCommand.GetParameter(index++).Value = stream.SampleRate; + transaction = connection.BeginTransaction(); - _saveStreamCommand.GetParameter(index++).Value = stream.IsDefault; - _saveStreamCommand.GetParameter(index++).Value = stream.IsForced; - _saveStreamCommand.GetParameter(index++).Value = stream.IsExternal; + // First delete + DeleteMediaStreams(connection, transaction, id); - _saveStreamCommand.GetParameter(index++).Value = stream.Width; - _saveStreamCommand.GetParameter(index++).Value = stream.Height; - _saveStreamCommand.GetParameter(index++).Value = stream.AverageFrameRate; - _saveStreamCommand.GetParameter(index++).Value = stream.RealFrameRate; - _saveStreamCommand.GetParameter(index++).Value = stream.Level; - _saveStreamCommand.GetParameter(index++).Value = stream.PixelFormat; - _saveStreamCommand.GetParameter(index++).Value = stream.BitDepth; - _saveStreamCommand.GetParameter(index++).Value = stream.IsAnamorphic; - _saveStreamCommand.GetParameter(index++).Value = stream.RefFrames; - - _saveStreamCommand.GetParameter(index++).Value = stream.CodecTag; - _saveStreamCommand.GetParameter(index++).Value = stream.Comment; - _saveStreamCommand.GetParameter(index++).Value = stream.NalLengthSize; - _saveStreamCommand.GetParameter(index++).Value = stream.IsAVC; - _saveStreamCommand.GetParameter(index++).Value = stream.Title; - - _saveStreamCommand.GetParameter(index++).Value = stream.TimeBase; - _saveStreamCommand.GetParameter(index++).Value = stream.CodecTimeBase; + if (streams.Count > 0) + { + using (var saveStreamCommand = connection.CreateCommand()) + { + saveStreamCommand.CommandText = string.Format("replace into mediastreams ({0}) values ({1})", + string.Join(",", _mediaStreamSaveColumns), + string.Join(",", _mediaStreamSaveColumns.Select(i => "@" + i).ToArray())); + + foreach (var col in _mediaStreamSaveColumns) + { + saveStreamCommand.Parameters.Add(saveStreamCommand, "@" + col); + } + + if (streams.Count > 1) + { + saveStreamCommand.Prepare(); + } + + foreach (var stream in streams) + { + cancellationToken.ThrowIfCancellationRequested(); + + var index = 0; + + saveStreamCommand.GetParameter(index++).Value = id; + saveStreamCommand.GetParameter(index++).Value = stream.Index; + saveStreamCommand.GetParameter(index++).Value = stream.Type.ToString(); + saveStreamCommand.GetParameter(index++).Value = stream.Codec; + saveStreamCommand.GetParameter(index++).Value = stream.Language; + saveStreamCommand.GetParameter(index++).Value = stream.ChannelLayout; + saveStreamCommand.GetParameter(index++).Value = stream.Profile; + saveStreamCommand.GetParameter(index++).Value = stream.AspectRatio; + saveStreamCommand.GetParameter(index++).Value = stream.Path; + + saveStreamCommand.GetParameter(index++).Value = stream.IsInterlaced; + + saveStreamCommand.GetParameter(index++).Value = stream.BitRate; + saveStreamCommand.GetParameter(index++).Value = stream.Channels; + saveStreamCommand.GetParameter(index++).Value = stream.SampleRate; + + saveStreamCommand.GetParameter(index++).Value = stream.IsDefault; + saveStreamCommand.GetParameter(index++).Value = stream.IsForced; + saveStreamCommand.GetParameter(index++).Value = stream.IsExternal; + + saveStreamCommand.GetParameter(index++).Value = stream.Width; + saveStreamCommand.GetParameter(index++).Value = stream.Height; + saveStreamCommand.GetParameter(index++).Value = stream.AverageFrameRate; + saveStreamCommand.GetParameter(index++).Value = stream.RealFrameRate; + saveStreamCommand.GetParameter(index++).Value = stream.Level; + saveStreamCommand.GetParameter(index++).Value = stream.PixelFormat; + saveStreamCommand.GetParameter(index++).Value = stream.BitDepth; + saveStreamCommand.GetParameter(index++).Value = stream.IsAnamorphic; + saveStreamCommand.GetParameter(index++).Value = stream.RefFrames; + + saveStreamCommand.GetParameter(index++).Value = stream.CodecTag; + saveStreamCommand.GetParameter(index++).Value = stream.Comment; + saveStreamCommand.GetParameter(index++).Value = stream.NalLengthSize; + saveStreamCommand.GetParameter(index++).Value = stream.IsAVC; + saveStreamCommand.GetParameter(index++).Value = stream.Title; + + saveStreamCommand.GetParameter(index++).Value = stream.TimeBase; + saveStreamCommand.GetParameter(index++).Value = stream.CodecTimeBase; + + saveStreamCommand.Transaction = transaction; + saveStreamCommand.ExecuteNonQuery(); + } + } + } - _saveStreamCommand.Transaction = transaction; - _saveStreamCommand.ExecuteNonQuery(); + transaction.Commit(); } - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) + catch (OperationCanceledException) { - transaction.Rollback(); + if (transaction != null) + { + transaction.Rollback(); + } + + throw; } + catch (Exception e) + { + Logger.ErrorException("Failed to save media streams:", e); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save media streams:", e); + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); + throw; } - - throw; - } - finally - { - if (transaction != null) + finally { - transaction.Dispose(); + if (transaction != null) + { + transaction.Dispose(); + } } - - WriteLock.Release(); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index 0ce27fa5a2..da0f584d53 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -45,12 +45,7 @@ namespace MediaBrowser.Server.Implementations.Persistence "create table if not exists userdata (key nvarchar, userId GUID, rating float null, played bit, playCount int, isFavorite bit, playbackPositionTicks bigint, lastPlayedDate datetime null)", "create index if not exists idx_userdata on userdata(key)", - "create unique index if not exists userdataindex on userdata (key, userId)", - - //pragmas - "pragma temp_store = memory", - - "pragma shrink_memory" + "create unique index if not exists userdataindex on userdata (key, userId)" }; connection.RunQueries(queries, Logger); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs index 4c07a60181..25ab60ca50 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs @@ -52,9 +52,6 @@ namespace MediaBrowser.Server.Implementations.Persistence "create index if not exists idx_users on users(guid)", "create table if not exists schema_version (table_name primary key, version)", - //pragmas - "pragma temp_store = memory", - "pragma shrink_memory" }; diff --git a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs index 3013510de1..74a552dccc 100644 --- a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs +++ b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs @@ -32,12 +32,7 @@ namespace MediaBrowser.Server.Implementations.Security string[] queries = { "create table if not exists AccessTokens (Id GUID PRIMARY KEY, AccessToken TEXT NOT NULL, DeviceId TEXT, AppName TEXT, AppVersion TEXT, DeviceName TEXT, UserId TEXT, IsActive BIT, DateCreated DATETIME NOT NULL, DateRevoked DATETIME)", - "create index if not exists idx_AccessTokens on AccessTokens(Id)", - - //pragmas - "pragma temp_store = memory", - - "pragma shrink_memory" + "create index if not exists idx_AccessTokens on AccessTokens(Id)" }; connection.RunQueries(queries, Logger); diff --git a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs index 8a895037e7..c4243c1a76 100644 --- a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs +++ b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs @@ -31,9 +31,6 @@ namespace MediaBrowser.Server.Implementations.Social "create table if not exists Shares (Id GUID, ItemId TEXT, UserId TEXT, ExpirationDate DateTime, PRIMARY KEY (Id))", "create index if not exists idx_Shares on Shares(Id)", - //pragmas - "pragma temp_store = memory", - "pragma shrink_memory" }; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 5b623cf2ad..a1ed66a995 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -43,9 +43,6 @@ namespace MediaBrowser.Server.Implementations.Sync "create index if not exists idx_SyncJobItems1 on SyncJobItems(Id)", "create index if not exists idx_SyncJobItems2 on SyncJobItems(TargetId)", - //pragmas - "pragma temp_store = memory", - "pragma shrink_memory" }; -- cgit v1.2.3 From 759f5a856064450acdb4c26839d6d890afb99a17 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 19 Jun 2016 02:18:29 -0400 Subject: update task results --- Emby.Drawing/ImageMagick/ImageMagickEncoder.cs | 11 --- MediaBrowser.Api/BaseApiService.cs | 2 +- MediaBrowser.Api/GamesService.cs | 9 +- MediaBrowser.Api/Images/ImageService.cs | 10 +-- MediaBrowser.Api/Images/RemoteImageService.cs | 10 +-- MediaBrowser.Api/ItemLookupService.cs | 36 ++++---- MediaBrowser.Api/Library/LibraryService.cs | 6 +- MediaBrowser.Api/LiveTv/LiveTvService.cs | 2 +- MediaBrowser.Api/Movies/MoviesService.cs | 18 ++-- MediaBrowser.Api/Music/AlbumsService.cs | 13 +-- MediaBrowser.Api/Music/InstantMixService.cs | 21 ++--- MediaBrowser.Api/PackageReviewService.cs | 12 +-- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 4 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 2 +- MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs | 9 +- .../Playback/Progressive/AudioService.cs | 5 +- .../Progressive/BaseProgressiveStreamingService.cs | 28 ++++--- .../Playback/Progressive/VideoService.cs | 5 +- MediaBrowser.Api/PlaylistService.cs | 4 +- MediaBrowser.Api/SimilarItemsHelper.cs | 12 +-- MediaBrowser.Api/Subtitles/SubtitleService.cs | 10 +-- MediaBrowser.Api/Sync/SyncService.cs | 14 ++-- MediaBrowser.Api/System/SystemService.cs | 2 +- MediaBrowser.Api/TvShowsService.cs | 25 +++--- MediaBrowser.Api/UserLibrary/ItemsService.cs | 2 +- MediaBrowser.Api/UserLibrary/PlaystateService.cs | 6 +- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 12 +-- MediaBrowser.Controller/Dto/IDtoService.cs | 3 +- MediaBrowser.Controller/Entities/BaseItem.cs | 4 +- MediaBrowser.Controller/Entities/Folder.cs | 24 ++++-- MediaBrowser.Controller/Entities/IHasUserData.cs | 3 +- MediaBrowser.Controller/IServerApplicationHost.cs | 5 +- .../Library/IUserDataManager.cs | 4 +- MediaBrowser.Controller/Net/IHttpResultFactory.cs | 8 +- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 4 +- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 13 +-- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 35 ++++---- MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs | 4 +- MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs | 7 +- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 29 +++---- MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs | 11 ++- .../Channels/ChannelManager.cs | 8 +- .../Connect/ConnectManager.cs | 14 ++-- .../Dto/DtoService.cs | 95 ++++++++++------------ .../EntryPoints/AutomaticRestartEntryPoint.cs | 28 ++++--- .../EntryPoints/UserDataChangeNotifier.cs | 2 +- .../HttpServer/HttpResultFactory.cs | 10 +-- .../HttpServer/SwaggerService.cs | 2 +- .../Library/LibraryManager.cs | 2 +- .../Library/UserDataManager.cs | 13 ++- .../Library/UserManager.cs | 2 +- .../LiveTv/LiveTvManager.cs | 6 +- .../LiveTv/LiveTvMediaSourceProvider.cs | 2 +- .../Session/SessionManager.cs | 29 ++++--- .../Sync/SyncJobProcessor.cs | 32 ++++++-- .../Udp/UdpServer.cs | 12 +-- .../ApplicationHost.cs | 49 +++++------ MediaBrowser.WebDashboard/Api/DashboardService.cs | 9 +- 58 files changed, 404 insertions(+), 355 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync') diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index 180f797e34..3dbe7239dd 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -111,7 +111,6 @@ namespace Emby.Drawing.ImageMagick wand.CurrentImage.TrimImage(10); wand.SaveImage(outputPath); } - SaveDelay(); } public ImageSize GetImageSize(string path) @@ -189,7 +188,6 @@ namespace Emby.Drawing.ImageMagick } } } - SaveDelay(); } private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options) @@ -294,15 +292,6 @@ namespace Emby.Drawing.ImageMagick { new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height); } - - SaveDelay(); - } - - private void SaveDelay() - { - // For some reason the images are not always getting released right away - //var task = Task.Delay(300); - //Task.WaitAll(task); } public string Name diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 44d459a01e..44a367be09 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -115,7 +115,7 @@ namespace MediaBrowser.Api /// System.Object. protected object ToStaticFileResult(string path) { - return ResultFactory.GetStaticFileResult(Request, path); + return ResultFactory.GetStaticFileResult(Request, path).Result; } protected DtoOptions GetDtoOptions(object request) diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index cb77e62adf..4758b01869 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Threading.Tasks; using MediaBrowser.Model.Querying; namespace MediaBrowser.Api @@ -186,14 +187,14 @@ namespace MediaBrowser.Api /// /// The request. /// System.Object. - public object Get(GetSimilarGames request) + public async Task Get(GetSimilarGames request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } - private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + private async Task> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; @@ -216,7 +217,7 @@ namespace MediaBrowser.Api var result = new QueryResult { - Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), + Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(), TotalRecordCount = itemsResult.Count }; diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index e5fe5bd684..a511f8c728 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -514,7 +514,7 @@ namespace MediaBrowser.Api.Images /// if set to true [is head request]. /// System.Object. /// - public object GetImage(ImageRequest request, IHasImages item, bool isHeadRequest) + public Task GetImage(ImageRequest request, IHasImages item, bool isHeadRequest) { if (request.PercentPlayed.HasValue) { @@ -594,8 +594,7 @@ namespace MediaBrowser.Api.Images supportedImageEnhancers, cacheDuration, responseHeaders, - isHeadRequest) - .Result; + isHeadRequest); } private async Task GetImageResult(IHasImages item, @@ -632,7 +631,7 @@ namespace MediaBrowser.Api.Images headers["Vary"] = "Accept"; - return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions + return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions { CacheDuration = cacheDuration, ResponseHeaders = headers, @@ -643,7 +642,8 @@ namespace MediaBrowser.Api.Images // Sometimes imagemagick keeps a hold on the file briefly even after it's done writing to it. // I'd rather do this than add a delay after saving the file FileShare = FileShare.ReadWrite - }); + + }).ConfigureAwait(false); } private List GetOutputFormats(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List enhancers) diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index 02d1cdbe2d..b21e544951 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -238,9 +238,9 @@ namespace MediaBrowser.Api.Images } if (_fileSystem.FileExists(contentPath)) - { - return ToStaticFileResult(contentPath); - } + { + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); + } } catch (DirectoryNotFoundException) { @@ -259,9 +259,9 @@ namespace MediaBrowser.Api.Images contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); } - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } - + /// /// Downloads the image. /// diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index 41bfd9da28..30cde48835 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -132,58 +132,58 @@ namespace MediaBrowser.Api return ToOptimizedResult(infos); } - public object Post(GetMovieRemoteSearchResults request) + public async Task Post(GetMovieRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetSeriesRemoteSearchResults request) + public async Task Post(GetSeriesRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetGameRemoteSearchResults request) + public async Task Post(GetGameRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetBoxSetRemoteSearchResults request) + public async Task Post(GetBoxSetRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetPersonRemoteSearchResults request) + public async Task Post(GetPersonRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetMusicAlbumRemoteSearchResults request) + public async Task Post(GetMusicAlbumRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetMusicArtistRemoteSearchResults request) + public async Task Post(GetMusicArtistRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Get(GetRemoteSearchImage request) + public async Task Get(GetRemoteSearchImage request) { - var result = GetRemoteImage(request).Result; + var result = GetRemoteImage(request).ConfigureAwait(false); return result; } @@ -241,7 +241,7 @@ namespace MediaBrowser.Api if (_fileSystem.FileExists(contentPath)) { - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } } catch (DirectoryNotFoundException) @@ -261,7 +261,7 @@ namespace MediaBrowser.Api contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); } - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } /// diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index f9b3def975..4cd6a66efb 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -493,7 +493,7 @@ namespace MediaBrowser.Api.Library } } - public object Get(GetDownload request) + public Task Get(GetDownload request) { var item = _libraryManager.GetItemById(request.Id); var auth = _authContext.GetAuthorizationInfo(Request); @@ -552,7 +552,7 @@ namespace MediaBrowser.Api.Library } } - public object Get(GetFile request) + public Task Get(GetFile request) { var item = _libraryManager.GetItemById(request.Id); var locationType = item.LocationType; @@ -565,7 +565,7 @@ namespace MediaBrowser.Api.Library throw new ArgumentException("This command cannot be used for directories."); } - return ToStaticFileResult(item.Path); + return ResultFactory.GetStaticFileResult(Request, item.Path); } /// diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 41c0c39eae..48f7cd62e7 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -785,7 +785,7 @@ namespace MediaBrowser.Api.LiveTv var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId); - var returnArray = _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ToArray(); + var returnArray = (await _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ConfigureAwait(false)).ToArray(); var result = new QueryResult { diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index ff18d440c1..a2a935b12a 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -111,16 +111,16 @@ namespace MediaBrowser.Api.Movies /// /// The request. /// System.Object. - public object Get(GetSimilarMovies request) + public async Task Get(GetSimilarMovies request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } - public object Get(GetSimilarTrailers request) + public async Task Get(GetSimilarTrailers request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -138,7 +138,7 @@ namespace MediaBrowser.Api.Movies return ToOptimizedResult(result); } - private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + private async Task> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; @@ -163,7 +163,7 @@ namespace MediaBrowser.Api.Movies var result = new QueryResult { - Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), + Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(), TotalRecordCount = itemsResult.Count }; @@ -296,7 +296,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = name, CategoryId = name.GetMD5().ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray() }; } } @@ -330,7 +330,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = name, CategoryId = name.GetMD5().ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray() }; } } @@ -361,7 +361,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = item.Name, CategoryId = item.Id.ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).Result.ToArray() }; } } diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index e774c30776..2d7e909bf6 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -8,6 +8,7 @@ using ServiceStack; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Api.Music { @@ -49,18 +50,18 @@ namespace MediaBrowser.Api.Music _dtoService = dtoService; } - public object Get(GetSimilarArtists request) + public async Task Get(GetSimilarArtists request) { var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, + var result = await SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, _itemRepo, _libraryManager, _userDataRepository, _dtoService, Logger, request, new[] { typeof(MusicArtist) }, - SimilarItemsHelper.GetSimiliarityScore); + SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -70,18 +71,18 @@ namespace MediaBrowser.Api.Music /// /// The request. /// System.Object. - public object Get(GetSimilarAlbums request) + public async Task Get(GetSimilarAlbums request) { var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, + var result = await SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, _itemRepo, _libraryManager, _userDataRepository, _dtoService, Logger, request, new[] { typeof(MusicAlbum) }, - GetAlbumSimilarityScore); + GetAlbumSimilarityScore).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs index d2a4aa60cc..19265408bf 100644 --- a/MediaBrowser.Api/Music/InstantMixService.cs +++ b/MediaBrowser.Api/Music/InstantMixService.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying; using ServiceStack; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Api.Music { @@ -76,7 +77,7 @@ namespace MediaBrowser.Api.Music _libraryManager = libraryManager; } - public object Get(GetInstantMixFromItem request) + public Task Get(GetInstantMixFromItem request) { var item = _libraryManager.GetItemById(request.Id); @@ -87,7 +88,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromArtistId request) + public Task Get(GetInstantMixFromArtistId request) { var item = _libraryManager.GetItemById(request.Id); @@ -98,7 +99,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromMusicGenreId request) + public Task Get(GetInstantMixFromMusicGenreId request) { var item = _libraryManager.GetItemById(request.Id); @@ -109,7 +110,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromSong request) + public Task Get(GetInstantMixFromSong request) { var item = _libraryManager.GetItemById(request.Id); @@ -120,7 +121,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromAlbum request) + public Task Get(GetInstantMixFromAlbum request) { var album = _libraryManager.GetItemById(request.Id); @@ -131,7 +132,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromPlaylist request) + public Task Get(GetInstantMixFromPlaylist request) { var playlist = (Playlist)_libraryManager.GetItemById(request.Id); @@ -142,7 +143,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromMusicGenre request) + public Task Get(GetInstantMixFromMusicGenre request) { var user = _userManager.GetUserById(request.UserId); @@ -151,7 +152,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromArtist request) + public Task Get(GetInstantMixFromArtist request) { var user = _userManager.GetUserById(request.UserId); var artist = _libraryManager.GetArtist(request.Name); @@ -161,7 +162,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - private object GetResult(IEnumerable