commit
fd72bdab5c
|
@ -288,11 +288,9 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
// It's currently failing on live tv
|
|
||||||
if (state.RunTimeTicks.HasValue)
|
|
||||||
{
|
|
||||||
return "h264_qsv";
|
return "h264_qsv";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "libx264";
|
return "libx264";
|
||||||
|
@ -440,6 +438,8 @@ namespace MediaBrowser.Api.Playback
|
||||||
param += " -level " + state.VideoRequest.Level;
|
param += " -level " + state.VideoRequest.Level;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return param;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,11 +86,10 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
// See if we can save come cpu cycles by avoiding encoding
|
// See if we can save come cpu cycles by avoiding encoding
|
||||||
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
|
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return state.VideoStream != null && IsH264(state.VideoStream) ?
|
// if h264_mp4toannexb is ever added, do not use it for live tv
|
||||||
args + " -bsf:v h264_mp4toannexb" :
|
return args;
|
||||||
args;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
|
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
|
||||||
state.SegmentLength.ToString(UsCulture));
|
state.SegmentLength.ToString(UsCulture));
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId);
|
SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
SortMediaSources(result);
|
SortMediaSources(result, maxBitrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetDeviceSpecificData(BaseItem item,
|
private void SetDeviceSpecificData(BaseItem item,
|
||||||
|
@ -375,7 +375,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SortMediaSources(PlaybackInfoResponse result)
|
private void SortMediaSources(PlaybackInfoResponse result, int? maxBitrate)
|
||||||
{
|
{
|
||||||
var originalList = result.MediaSources.ToList();
|
var originalList = result.MediaSources.ToList();
|
||||||
|
|
||||||
|
@ -409,6 +409,23 @@ namespace MediaBrowser.Api.Playback
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}).ThenBy(i =>
|
||||||
|
{
|
||||||
|
if (maxBitrate.HasValue)
|
||||||
|
{
|
||||||
|
if (i.Bitrate.HasValue)
|
||||||
|
{
|
||||||
|
if (i.Bitrate.Value <= maxBitrate.Value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
}).ThenBy(originalList.IndexOf)
|
}).ThenBy(originalList.IndexOf)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1348,6 +1348,24 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return LocalizationManager.GetRatingLevel(rating);
|
return LocalizationManager.GetRatingLevel(rating);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<string> GetInheritedTags()
|
||||||
|
{
|
||||||
|
var list = new List<string>();
|
||||||
|
list.AddRange(Tags);
|
||||||
|
|
||||||
|
foreach (var parent in GetParents())
|
||||||
|
{
|
||||||
|
list.AddRange(parent.Tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var parent in LibraryManager.GetCollectionFolders(this))
|
||||||
|
{
|
||||||
|
list.AddRange(parent.Tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsVisibleViaTags(User user)
|
private bool IsVisibleViaTags(User user)
|
||||||
{
|
{
|
||||||
var hasTags = this as IHasTags;
|
var hasTags = this as IHasTags;
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public string[] IncludeItemTypes { get; set; }
|
public string[] IncludeItemTypes { get; set; }
|
||||||
public string[] ExcludeItemTypes { get; set; }
|
public string[] ExcludeItemTypes { get; set; }
|
||||||
public string[] ExcludeTags { get; set; }
|
public string[] ExcludeTags { get; set; }
|
||||||
|
public string[] ExcludeInheritedTags { get; set; }
|
||||||
public string[] Genres { get; set; }
|
public string[] Genres { get; set; }
|
||||||
|
|
||||||
public bool? IsMissing { get; set; }
|
public bool? IsMissing { get; set; }
|
||||||
|
@ -157,6 +158,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
AncestorIds = new string[] { };
|
AncestorIds = new string[] { };
|
||||||
TopParentIds = new string[] { };
|
TopParentIds = new string[] { };
|
||||||
ExcludeTags = new string[] { };
|
ExcludeTags = new string[] { };
|
||||||
|
ExcludeInheritedTags = new string[] { };
|
||||||
LocationTypes = new LocationType[] { };
|
LocationTypes = new LocationType[] { };
|
||||||
ExcludeLocationTypes = new LocationType[] { };
|
ExcludeLocationTypes = new LocationType[] { };
|
||||||
PresetViews = new string[] { };
|
PresetViews = new string[] { };
|
||||||
|
@ -181,7 +183,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
BlockUnratedItems = policy.BlockUnratedItems;
|
BlockUnratedItems = policy.BlockUnratedItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExcludeTags = policy.BlockedTags;
|
ExcludeInheritedTags = policy.BlockedTags;
|
||||||
|
|
||||||
User = user;
|
User = user;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
stream.DeviceProfileId = options.Profile.Id;
|
stream.DeviceProfileId = options.Profile.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetOptimalStream(streams);
|
return GetOptimalStream(streams, options.GetMaxBitrate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamInfo BuildVideoItem(VideoOptions options)
|
public StreamInfo BuildVideoItem(VideoOptions options)
|
||||||
|
@ -88,12 +88,12 @@ namespace MediaBrowser.Model.Dlna
|
||||||
stream.DeviceProfileId = options.Profile.Id;
|
stream.DeviceProfileId = options.Profile.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetOptimalStream(streams);
|
return GetOptimalStream(streams, options.GetMaxBitrate());
|
||||||
}
|
}
|
||||||
|
|
||||||
private StreamInfo GetOptimalStream(List<StreamInfo> streams)
|
private StreamInfo GetOptimalStream(List<StreamInfo> streams, int? maxBitrate)
|
||||||
{
|
{
|
||||||
streams = StreamInfoSorter.SortMediaSources(streams);
|
streams = StreamInfoSorter.SortMediaSources(streams, maxBitrate);
|
||||||
|
|
||||||
foreach (StreamInfo stream in streams)
|
foreach (StreamInfo stream in streams)
|
||||||
{
|
{
|
||||||
|
@ -424,7 +424,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
||||||
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
||||||
|
|
||||||
// TODO: We should probably preserve the full list and sent it tp the server that way
|
// TODO: We should probably preserve the full list and sent it to the server that way
|
||||||
string[] supportedAudioCodecs = transcodingProfile.AudioCodec.Split(',');
|
string[] supportedAudioCodecs = transcodingProfile.AudioCodec.Split(',');
|
||||||
string inputAudioCodec = audioStream == null ? null : audioStream.Codec;
|
string inputAudioCodec = audioStream == null ? null : audioStream.Codec;
|
||||||
foreach (string supportedAudioCodec in supportedAudioCodecs)
|
foreach (string supportedAudioCodec in supportedAudioCodecs)
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
public class StreamInfoSorter
|
public class StreamInfoSorter
|
||||||
{
|
{
|
||||||
public static List<StreamInfo> SortMediaSources(List<StreamInfo> streams)
|
public static List<StreamInfo> SortMediaSources(List<StreamInfo> streams, int? maxBitrate)
|
||||||
{
|
{
|
||||||
return streams.OrderBy(i =>
|
return streams.OrderBy(i =>
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,23 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}).ThenBy(i =>
|
||||||
|
{
|
||||||
|
if (maxBitrate.HasValue)
|
||||||
|
{
|
||||||
|
if (i.MediaSource.Bitrate.HasValue)
|
||||||
|
{
|
||||||
|
if (i.MediaSource.Bitrate.Value <= maxBitrate.Value)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,6 +246,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
string audioCodec = "ac3";
|
string audioCodec = "ac3";
|
||||||
|
|
||||||
int? videoBitrate = null;
|
int? videoBitrate = null;
|
||||||
|
int? audioBitrate = null;
|
||||||
|
|
||||||
if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -306,6 +307,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
audioCodec = channel.AudioCodec;
|
audioCodec = channel.AudioCodec;
|
||||||
|
|
||||||
videoBitrate = (channel.IsHD ?? true) ? 15000000 : 2000000;
|
videoBitrate = (channel.IsHD ?? true) ? 15000000 : 2000000;
|
||||||
|
audioBitrate = (channel.IsHD ?? true) ? 448000 : 192000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +348,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
// Set the index to -1 because we don't know the exact index of the audio stream within the container
|
// Set the index to -1 because we don't know the exact index of the audio stream within the container
|
||||||
Index = -1,
|
Index = -1,
|
||||||
Codec = audioCodec,
|
Codec = audioCodec,
|
||||||
BitRate = 192000
|
BitRate = audioBitrate
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RequiresOpening = false,
|
RequiresOpening = false,
|
||||||
|
|
|
@ -78,8 +78,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
private IDbCommand _saveAncestorCommand;
|
private IDbCommand _saveAncestorCommand;
|
||||||
|
|
||||||
private IDbCommand _updateInheritedRatingCommand;
|
private IDbCommand _updateInheritedRatingCommand;
|
||||||
|
private IDbCommand _updateInheritedTagsCommand;
|
||||||
|
|
||||||
private const int LatestSchemaVersion = 58;
|
private const int LatestSchemaVersion = 61;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
||||||
|
@ -135,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
|
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
|
||||||
"create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
|
"create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
|
||||||
"create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)",
|
"create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)",
|
||||||
|
|
||||||
"create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
|
"create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
|
||||||
"create index if not exists idxPeopleItemId on People(ItemId)",
|
"create index if not exists idxPeopleItemId on People(ItemId)",
|
||||||
"create index if not exists idxPeopleName on People(Name)",
|
"create index if not exists idxPeopleName on People(Name)",
|
||||||
|
@ -224,6 +225,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "CriticRating", "Float");
|
_connection.AddColumn(Logger, "TypedBaseItems", "CriticRating", "Float");
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "CriticRatingSummary", "Text");
|
_connection.AddColumn(Logger, "TypedBaseItems", "CriticRatingSummary", "Text");
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME");
|
_connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME");
|
||||||
|
_connection.AddColumn(Logger, "TypedBaseItems", "InheritedTags", "Text");
|
||||||
|
|
||||||
PrepareStatements();
|
PrepareStatements();
|
||||||
|
|
||||||
|
@ -402,7 +404,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
"guid",
|
"guid",
|
||||||
"type",
|
"type",
|
||||||
"data",
|
"data",
|
||||||
"Path",
|
"Path",
|
||||||
"StartDate",
|
"StartDate",
|
||||||
"EndDate",
|
"EndDate",
|
||||||
"ChannelId",
|
"ChannelId",
|
||||||
|
@ -462,7 +464,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
"TrailerTypes",
|
"TrailerTypes",
|
||||||
"CriticRating",
|
"CriticRating",
|
||||||
"CriticRatingSummary",
|
"CriticRatingSummary",
|
||||||
"DateModifiedDuringLastRefresh"
|
"DateModifiedDuringLastRefresh",
|
||||||
|
"InheritedTags"
|
||||||
};
|
};
|
||||||
_saveItemCommand = _connection.CreateCommand();
|
_saveItemCommand = _connection.CreateCommand();
|
||||||
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
|
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
|
||||||
|
@ -540,8 +543,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
|
|
||||||
_updateInheritedRatingCommand = _connection.CreateCommand();
|
_updateInheritedRatingCommand = _connection.CreateCommand();
|
||||||
_updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid";
|
_updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid";
|
||||||
_updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@InheritedParentalRatingValue");
|
|
||||||
_updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -715,7 +723,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
|
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.ServiceName;
|
_saveItemCommand.GetParameter(index++).Value = item.ServiceName;
|
||||||
|
|
||||||
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray());
|
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.IsFolder;
|
||||||
|
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString();
|
_saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString();
|
||||||
|
@ -765,6 +781,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.DateModifiedDuringLastRefresh.Value;
|
_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;
|
||||||
|
}
|
||||||
|
|
||||||
_saveItemCommand.Transaction = transaction;
|
_saveItemCommand.Transaction = transaction;
|
||||||
|
|
||||||
_saveItemCommand.ExecuteNonQuery();
|
_saveItemCommand.ExecuteNonQuery();
|
||||||
|
@ -2165,6 +2191,14 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
excludeTagIndex++;
|
excludeTagIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
excludeTagIndex = 0;
|
||||||
|
foreach (var excludeTag in query.ExcludeInheritedTags)
|
||||||
|
{
|
||||||
|
whereClauses.Add("InheritedTags not like @excludeInheritedTag" + excludeTagIndex);
|
||||||
|
cmd.Parameters.Add(cmd, "@excludeInheritedTag" + excludeTagIndex, DbType.String).Value = "%" + excludeTag + "%";
|
||||||
|
excludeTagIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
if (addPaging)
|
if (addPaging)
|
||||||
{
|
{
|
||||||
if (query.StartIndex.HasValue && query.StartIndex.Value > 0)
|
if (query.StartIndex.HasValue && query.StartIndex.Value > 0)
|
||||||
|
@ -2224,6 +2258,88 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
};
|
};
|
||||||
|
|
||||||
public async Task UpdateInheritedValues(CancellationToken cancellationToken)
|
public async Task UpdateInheritedValues(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await UpdateInheritedParentalRating(cancellationToken).ConfigureAwait(false);
|
||||||
|
await UpdateInheritedTags(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateInheritedTags(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var newValues = new List<Tuple<Guid, string>>();
|
||||||
|
|
||||||
|
using (var cmd = _connection.CreateCommand())
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
var id = reader.GetGuid(0);
|
||||||
|
string value = reader.IsDBNull(2) ? null : reader.GetString(2);
|
||||||
|
|
||||||
|
newValues.Add(new Tuple<Guid, string>(id, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count);
|
||||||
|
if (newValues.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
IDbTransaction transaction = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transaction = _connection.BeginTransaction();
|
||||||
|
|
||||||
|
foreach (var item in newValues)
|
||||||
|
{
|
||||||
|
_updateInheritedTagsCommand.GetParameter(0).Value = item.Item1;
|
||||||
|
_updateInheritedTagsCommand.GetParameter(1).Value = item.Item2;
|
||||||
|
|
||||||
|
_updateInheritedTagsCommand.Transaction = transaction;
|
||||||
|
_updateInheritedTagsCommand.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.ErrorException("Error running query:", e);
|
||||||
|
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteLock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateInheritedParentalRating(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var newValues = new List<Tuple<Guid, int>>();
|
var newValues = new List<Tuple<Guid, int>>();
|
||||||
|
|
||||||
|
@ -2243,6 +2359,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.Debug("UpdateInheritedParentalRatings - {0} rows", newValues.Count);
|
||||||
if (newValues.Count == 0)
|
if (newValues.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user