reduce library queries

This commit is contained in:
Luke Pulverenti 2016-11-21 03:54:53 -05:00
parent 1dc080df8b
commit f275d7f3d2
32 changed files with 230 additions and 176 deletions

View File

@ -105,5 +105,10 @@ namespace Emby.Common.Implementations.EnvironmentInfo
{ {
return null; return null;
} }
public string StackTrace
{
get { return Environment.StackTrace; }
}
} }
} }

View File

@ -551,7 +551,7 @@ namespace Emby.Server.Core
DisplayPreferencesRepository = displayPreferencesRepo; DisplayPreferencesRepository = displayPreferencesRepo;
RegisterSingleInstance(DisplayPreferencesRepository); RegisterSingleInstance(DisplayPreferencesRepository);
var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager); var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager.GetLogger("SqliteItemRepository"), MemoryStreamFactory, assemblyInfo, FileSystemManager, EnvironmentInfo);
ItemRepository = itemRepo; ItemRepository = itemRepo;
RegisterSingleInstance(ItemRepository); RegisterSingleInstance(ItemRepository);

View File

@ -29,10 +29,9 @@ namespace Emby.Server.Implementations.Activity
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {

View File

@ -40,6 +40,8 @@ namespace Emby.Server.Implementations.Data
private static bool _versionLogged; private static bool _versionLogged;
private string _defaultWal;
protected SQLiteDatabaseConnection CreateConnection(bool isReadOnly = false, Action<SQLiteDatabaseConnection> onConnect = null) protected SQLiteDatabaseConnection CreateConnection(bool isReadOnly = false, Action<SQLiteDatabaseConnection> onConnect = null)
{ {
if (!_versionLogged) if (!_versionLogged)
@ -51,6 +53,15 @@ namespace Emby.Server.Implementations.Data
ConnectionFlags connectionFlags; ConnectionFlags connectionFlags;
if (isReadOnly)
{
//Logger.Info("Opening read connection");
}
else
{
//Logger.Info("Opening write connection");
}
isReadOnly = false; isReadOnly = false;
if (isReadOnly) if (isReadOnly)
@ -70,12 +81,16 @@ namespace Emby.Server.Implementations.Data
var db = SQLite3.Open(DbFilePath, connectionFlags, null); var db = SQLite3.Open(DbFilePath, connectionFlags, null);
if (string.IsNullOrWhiteSpace(_defaultWal))
{
_defaultWal = db.Query("PRAGMA journal_mode").SelectScalarString().First();
}
var queries = new List<string> var queries = new List<string>
{ {
"PRAGMA default_temp_store=memory",
"pragma temp_store = memory", "pragma temp_store = memory",
"PRAGMA page_size=4096", "PRAGMA journal_mode=WAL"
"PRAGMA journal_mode=WAL",
"pragma synchronous=Normal",
//"PRAGMA cache size=-10000" //"PRAGMA cache size=-10000"
}; };
@ -90,13 +105,19 @@ namespace Emby.Server.Implementations.Data
//// db.Execute(query); //// db.Execute(query);
////} ////}
using (WriteLock.Write()) //Logger.Info("synchronous: " + db.Query("PRAGMA synchronous").SelectScalarString().First());
{ //Logger.Info("temp_store: " + db.Query("PRAGMA temp_store").SelectScalarString().First());
db.ExecuteAll(string.Join(";", queries.ToArray()));
if (onConnect != null) //if (!string.Equals(_defaultWal, "wal", StringComparison.OrdinalIgnoreCase) || onConnect != null)
{
using (WriteLock.Write())
{ {
onConnect(db); db.ExecuteAll(string.Join(";", queries.ToArray()));
if (onConnect != null)
{
onConnect(db);
}
} }
} }

View File

@ -56,10 +56,9 @@ namespace Emby.Server.Implementations.Data
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {

View File

@ -33,10 +33,9 @@ namespace Emby.Server.Implementations.Data
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {

View File

@ -29,6 +29,7 @@ using MediaBrowser.Server.Implementations.Devices;
using MediaBrowser.Server.Implementations.Playlists; using MediaBrowser.Server.Implementations.Playlists;
using MediaBrowser.Model.Reflection; using MediaBrowser.Model.Reflection;
using SQLitePCL.pretty; using SQLitePCL.pretty;
using MediaBrowser.Model.System;
namespace Emby.Server.Implementations.Data namespace Emby.Server.Implementations.Data
{ {
@ -66,14 +67,14 @@ namespace Emby.Server.Implementations.Data
private readonly string _criticReviewsPath; private readonly string _criticReviewsPath;
public const int LatestSchemaVersion = 109;
private readonly IMemoryStreamFactory _memoryStreamProvider; private readonly IMemoryStreamFactory _memoryStreamProvider;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly IEnvironmentInfo _environmentInfo;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
/// </summary> /// </summary>
public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, IAssemblyInfo assemblyInfo, IFileSystem fileSystem) public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamFactory memoryStreamProvider, IAssemblyInfo assemblyInfo, IFileSystem fileSystem, IEnvironmentInfo environmentInfo)
: base(logger) : base(logger)
{ {
if (config == null) if (config == null)
@ -89,6 +90,7 @@ namespace Emby.Server.Implementations.Data
_jsonSerializer = jsonSerializer; _jsonSerializer = jsonSerializer;
_memoryStreamProvider = memoryStreamProvider; _memoryStreamProvider = memoryStreamProvider;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_environmentInfo = environmentInfo;
_typeMapper = new TypeMapper(assemblyInfo); _typeMapper = new TypeMapper(assemblyInfo);
_criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews"); _criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews");
@ -129,10 +131,9 @@ namespace Emby.Server.Implementations.Data
_connection.ExecuteAll(string.Join(";", new[] _connection.ExecuteAll(string.Join(";", new[]
{ {
"pragma default_temp_store = memory", "PRAGMA page_size=4096",
"pragma default_synchronous=Normal", "PRAGMA default_temp_store=memory",
"pragma temp_store = memory", "PRAGMA temp_store=memory"
"pragma synchronous=Normal",
})); }));
var createMediaStreamsTableCommand var createMediaStreamsTableCommand
@ -193,7 +194,6 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "ProductionYear", "INT", existingColumnNames); AddColumn(db, "TypedBaseItems", "ProductionYear", "INT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ParentId", "GUID", existingColumnNames); AddColumn(db, "TypedBaseItems", "ParentId", "GUID", existingColumnNames);
AddColumn(db, "TypedBaseItems", "Genres", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "Genres", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SchemaVersion", "INT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SortName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "SortName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "RunTimeTicks", "BIGINT", existingColumnNames); AddColumn(db, "TypedBaseItems", "RunTimeTicks", "BIGINT", existingColumnNames);
@ -205,7 +205,6 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ForcedSortName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "ForcedSortName", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsOffline", "BIT", existingColumnNames);
AddColumn(db, "TypedBaseItems", "LocationType", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "LocationType", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "IsSeries", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsSeries", "BIT", existingColumnNames);
@ -381,7 +380,6 @@ namespace Emby.Server.Implementations.Data
"data", "data",
"StartDate", "StartDate",
"EndDate", "EndDate",
"IsOffline",
"ChannelId", "ChannelId",
"IsMovie", "IsMovie",
"IsSports", "IsSports",
@ -529,7 +527,6 @@ namespace Emby.Server.Implementations.Data
"ParentId", "ParentId",
"Genres", "Genres",
"InheritedParentalRatingValue", "InheritedParentalRatingValue",
"SchemaVersion",
"SortName", "SortName",
"RunTimeTicks", "RunTimeTicks",
"OfficialRatingDescription", "OfficialRatingDescription",
@ -539,7 +536,6 @@ namespace Emby.Server.Implementations.Data
"DateCreated", "DateCreated",
"DateModified", "DateModified",
"ForcedSortName", "ForcedSortName",
"IsOffline",
"LocationType", "LocationType",
"PreferredMetadataLanguage", "PreferredMetadataLanguage",
"PreferredMetadataCountryCode", "PreferredMetadataCountryCode",
@ -790,7 +786,6 @@ namespace Emby.Server.Implementations.Data
} }
saveItemStatement.TryBind("@InheritedParentalRatingValue", item.GetInheritedParentalRatingValue() ?? 0); saveItemStatement.TryBind("@InheritedParentalRatingValue", item.GetInheritedParentalRatingValue() ?? 0);
saveItemStatement.TryBind("@SchemaVersion", LatestSchemaVersion);
saveItemStatement.TryBind("@SortName", item.SortName); saveItemStatement.TryBind("@SortName", item.SortName);
saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks); saveItemStatement.TryBind("@RunTimeTicks", item.RunTimeTicks);
@ -803,7 +798,6 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@DateModified", item.DateModified); saveItemStatement.TryBind("@DateModified", item.DateModified);
saveItemStatement.TryBind("@ForcedSortName", item.ForcedSortName); saveItemStatement.TryBind("@ForcedSortName", item.ForcedSortName);
saveItemStatement.TryBind("@IsOffline", item.IsOffline);
saveItemStatement.TryBind("@LocationType", item.LocationType.ToString()); saveItemStatement.TryBind("@LocationType", item.LocationType.ToString());
saveItemStatement.TryBind("@PreferredMetadataLanguage", item.PreferredMetadataLanguage); saveItemStatement.TryBind("@PreferredMetadataLanguage", item.PreferredMetadataLanguage);
@ -1182,7 +1176,7 @@ namespace Emby.Server.Implementations.Data
} }
CheckDisposed(); CheckDisposed();
//Logger.Info("Retrieving item {0}", id.ToString("N"));
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
using (WriteLock.Read()) using (WriteLock.Read())
@ -1369,64 +1363,72 @@ namespace Emby.Server.Implementations.Data
if (!reader.IsDBNull(4)) if (!reader.IsDBNull(4))
{ {
item.IsOffline = reader.GetBoolean(4); item.ChannelId = reader.GetString(4);
} }
if (!reader.IsDBNull(5)) var index = 5;
{
item.ChannelId = reader.GetString(5);
}
var hasProgramAttributes = item as IHasProgramAttributes; var hasProgramAttributes = item as IHasProgramAttributes;
if (hasProgramAttributes != null) if (hasProgramAttributes != null)
{ {
if (!reader.IsDBNull(6)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.IsMovie = reader.GetBoolean(6); hasProgramAttributes.IsMovie = reader.GetBoolean(index);
} }
index++;
if (!reader.IsDBNull(7)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.IsSports = reader.GetBoolean(7); hasProgramAttributes.IsSports = reader.GetBoolean(index);
} }
index++;
if (!reader.IsDBNull(8)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.IsKids = reader.GetBoolean(8); hasProgramAttributes.IsKids = reader.GetBoolean(index);
} }
index++;
if (!reader.IsDBNull(9)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.IsSeries = reader.GetBoolean(9); hasProgramAttributes.IsSeries = reader.GetBoolean(index);
} }
index++;
if (!reader.IsDBNull(10)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.IsLive = reader.GetBoolean(10); hasProgramAttributes.IsLive = reader.GetBoolean(index);
} }
index++;
if (!reader.IsDBNull(11)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.IsNews = reader.GetBoolean(11); hasProgramAttributes.IsNews = reader.GetBoolean(index);
} }
index++;
if (!reader.IsDBNull(12)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.IsPremiere = reader.GetBoolean(12); hasProgramAttributes.IsPremiere = reader.GetBoolean(index);
} }
index++;
if (!reader.IsDBNull(13)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.EpisodeTitle = reader.GetString(13); hasProgramAttributes.EpisodeTitle = reader.GetString(index);
} }
index++;
if (!reader.IsDBNull(14)) if (!reader.IsDBNull(index))
{ {
hasProgramAttributes.IsRepeat = reader.GetBoolean(14); hasProgramAttributes.IsRepeat = reader.GetBoolean(index);
} }
index++;
}
else
{
index += 9;
} }
var index = 15;
if (!reader.IsDBNull(index)) if (!reader.IsDBNull(index))
{ {
@ -2368,6 +2370,8 @@ namespace Emby.Server.Implementations.Data
CheckDisposed(); CheckDisposed();
//Logger.Info("GetItemList: " + _environmentInfo.StackTrace);
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
var list = new List<BaseItem>(); var list = new List<BaseItem>();
@ -2533,6 +2537,7 @@ namespace Emby.Server.Implementations.Data
TotalRecordCount = returnList.Count TotalRecordCount = returnList.Count
}; };
} }
//Logger.Info("GetItems: " + _environmentInfo.StackTrace);
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
@ -2770,6 +2775,7 @@ namespace Emby.Server.Implementations.Data
} }
CheckDisposed(); CheckDisposed();
//Logger.Info("GetItemIdsList: " + _environmentInfo.StackTrace);
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
@ -2928,6 +2934,7 @@ namespace Emby.Server.Implementations.Data
TotalRecordCount = returnList.Count TotalRecordCount = returnList.Count
}; };
} }
//Logger.Info("GetItemIds: " + _environmentInfo.StackTrace);
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
@ -3053,14 +3060,6 @@ namespace Emby.Server.Implementations.Data
statement.TryBind("@IsLocked", query.IsLocked); statement.TryBind("@IsLocked", query.IsLocked);
} }
} }
if (query.IsOffline.HasValue)
{
whereClauses.Add("IsOffline=@IsOffline");
if (statement != null)
{
statement.TryBind("@IsOffline", query.IsOffline);
}
}
var exclusiveProgramAttribtues = !(query.IsMovie ?? true) || var exclusiveProgramAttribtues = !(query.IsMovie ?? true) ||
!(query.IsSports ?? true) || !(query.IsSports ?? true) ||
@ -4721,7 +4720,7 @@ namespace Emby.Server.Implementations.Data
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
using (WriteLock.Write()) using (WriteLock.Read())
{ {
foreach (var row in connection.Query(commandText)) foreach (var row in connection.Query(commandText))
{ {
@ -4750,6 +4749,7 @@ namespace Emby.Server.Implementations.Data
} }
CheckDisposed(); CheckDisposed();
//Logger.Info("GetItemValues: " + _environmentInfo.StackTrace);
var now = DateTime.UtcNow; var now = DateTime.UtcNow;

View File

@ -45,10 +45,9 @@ namespace Emby.Server.Implementations.Data
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {

View File

@ -52,10 +52,9 @@ namespace Emby.Server.Implementations.Data
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {

View File

@ -482,7 +482,7 @@ namespace Emby.Server.Implementations.Dto
{ {
if (dtoOptions.EnableUserData) if (dtoOptions.EnableUserData)
{ {
dto.UserData = _userDataRepository.GetUserDataDto(item, user).Result; dto.UserData = await _userDataRepository.GetUserDataDto(item, user).ConfigureAwait(false);
} }
} }
@ -1450,11 +1450,19 @@ namespace Emby.Server.Implementations.Dto
private void AddInheritedImages(BaseItemDto dto, BaseItem item, DtoOptions options, BaseItem owner) private void AddInheritedImages(BaseItemDto dto, BaseItem item, DtoOptions options, BaseItem owner)
{ {
if (!item.SupportsInheritedParentImages)
{
return;
}
var logoLimit = options.GetImageLimit(ImageType.Logo); var logoLimit = options.GetImageLimit(ImageType.Logo);
var artLimit = options.GetImageLimit(ImageType.Art); var artLimit = options.GetImageLimit(ImageType.Art);
var thumbLimit = options.GetImageLimit(ImageType.Thumb); var thumbLimit = options.GetImageLimit(ImageType.Thumb);
var backdropLimit = options.GetImageLimit(ImageType.Backdrop); var backdropLimit = options.GetImageLimit(ImageType.Backdrop);
// For now. Emby apps are not using this
artLimit = 0;
if (logoLimit == 0 && artLimit == 0 && thumbLimit == 0 && backdropLimit == 0) if (logoLimit == 0 && artLimit == 0 && thumbLimit == 0 && backdropLimit == 0)
{ {
return; return;
@ -1515,6 +1523,12 @@ namespace Emby.Server.Implementations.Dto
} }
isFirst = false; isFirst = false;
if (!parent.SupportsInheritedParentImages)
{
break;
}
parent = parent.GetParent(); parent = parent.GetParent();
} }
} }

View File

@ -339,11 +339,6 @@ namespace Emby.Server.Implementations.Library
{ {
throw new ArgumentNullException("item"); throw new ArgumentNullException("item");
} }
RegisterItem(item.Id, item);
}
private void RegisterItem(Guid id, BaseItem item)
{
if (item is IItemByName) if (item is IItemByName)
{ {
if (!(item is MusicArtist)) if (!(item is MusicArtist))
@ -354,13 +349,13 @@ namespace Emby.Server.Implementations.Library
if (item.IsFolder) if (item.IsFolder)
{ {
if (!(item is ICollectionFolder) && !(item is UserView) && !(item is Channel) && !(item is AggregateFolder)) //if (!(item is ICollectionFolder) && !(item is UserView) && !(item is Channel) && !(item is AggregateFolder))
{ //{
if (item.SourceType != SourceType.Library) // if (item.SourceType != SourceType.Library)
{ // {
return; // return;
} // }
} //}
} }
else else
{ {
@ -370,7 +365,7 @@ namespace Emby.Server.Implementations.Library
} }
} }
LibraryItemsCache.AddOrUpdate(id, item, delegate { return item; }); LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
} }
public async Task DeleteItem(BaseItem item, DeleteOptions options) public async Task DeleteItem(BaseItem item, DeleteOptions options)
@ -1273,10 +1268,8 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.GetItemList(query); return ItemRepository.GetItemList(query);
} }
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, IEnumerable<string> parentIds) public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
{ {
var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList();
SetTopParentIdsOrAncestors(query, parents); SetTopParentIdsOrAncestors(query, parents);
if (query.AncestorIds.Length == 0 && query.TopParentIds.Length == 0) if (query.AncestorIds.Length == 0 && query.TopParentIds.Length == 0)
@ -1536,7 +1529,7 @@ namespace Emby.Server.Implementations.Library
} }
// Handle grouping // Handle grouping
if (user != null && !string.IsNullOrWhiteSpace(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType)) if (user != null && !string.IsNullOrWhiteSpace(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType) && user.Configuration.GroupedFolders.Length > 0)
{ {
return user.RootFolder return user.RootFolder
.GetChildren(user, true) .GetChildren(user, true)

View File

@ -245,20 +245,26 @@ namespace Emby.Server.Implementations.Library
var includeItemTypes = request.IncludeItemTypes; var includeItemTypes = request.IncludeItemTypes;
var limit = request.Limit ?? 10; var limit = request.Limit ?? 10;
var parentIds = string.IsNullOrEmpty(parentId) var parents = new List<BaseItem>();
? new string[] { }
: new[] { parentId };
if (parentIds.Length == 0) if (!string.IsNullOrWhiteSpace(parentId))
{ {
parentIds = user.RootFolder.GetChildren(user, true) var parent = _libraryManager.GetItemById(parentId) as Folder;
.OfType<Folder>() if (parent != null)
.Select(i => i.Id.ToString("N")) {
.Where(i => !user.Configuration.LatestItemsExcludes.Contains(i)) parents.Add(parent);
.ToArray(); }
} }
if (parentIds.Length == 0) if (parents.Count == 0)
{
parents = user.RootFolder.GetChildren(user, true)
.Where(i => i is Folder)
.Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N")))
.ToList();
}
if (parents.Count == 0)
{ {
return new List<BaseItem>(); return new List<BaseItem>();
} }
@ -283,10 +289,10 @@ namespace Emby.Server.Implementations.Library
ExcludeItemTypes = excludeItemTypes, ExcludeItemTypes = excludeItemTypes,
ExcludeLocationTypes = new[] { LocationType.Virtual }, ExcludeLocationTypes = new[] { LocationType.Virtual },
Limit = limit * 5, Limit = limit * 5,
SourceTypes = parentIds.Length == 0 ? new[] { SourceType.Library } : new SourceType[] { }, SourceTypes = parents.Count == 0 ? new[] { SourceType.Library } : new SourceType[] { },
IsPlayed = request.IsPlayed IsPlayed = request.IsPlayed
}, parentIds); }, parents);
} }
} }
} }

View File

@ -491,7 +491,7 @@ namespace Emby.Server.Implementations.LiveTv
var id = _tvDtoService.GetInternalChannelId(serviceName, channelInfo.Id); var id = _tvDtoService.GetInternalChannelId(serviceName, channelInfo.Id);
var item = _itemRepo.RetrieveItem(id) as LiveTvChannel; var item = _libraryManager.GetItemById(id) as LiveTvChannel;
if (item == null) if (item == null)
{ {

View File

@ -31,10 +31,9 @@ namespace Emby.Server.Implementations.Notifications
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {
@ -57,9 +56,9 @@ namespace Emby.Server.Implementations.Notifications
{ {
var result = new NotificationResult(); var result = new NotificationResult();
using (WriteLock.Read()) using (var connection = CreateConnection(true))
{ {
using (var connection = CreateConnection(true)) //using (WriteLock.Read())
{ {
var clauses = new List<string>(); var clauses = new List<string>();
var paramList = new List<object>(); var paramList = new List<object>();
@ -114,7 +113,7 @@ namespace Emby.Server.Implementations.Notifications
using (var connection = CreateConnection(true)) using (var connection = CreateConnection(true))
{ {
using (WriteLock.Read()) //using (WriteLock.Read())
{ {
using (var statement = connection.PrepareStatement("select Level from Notifications where UserId=@UserId and IsRead=@IsRead")) using (var statement = connection.PrepareStatement("select Level from Notifications where UserId=@UserId and IsRead=@IsRead"))
{ {

View File

@ -32,10 +32,9 @@ namespace Emby.Server.Implementations.Security
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {

View File

@ -29,10 +29,9 @@ namespace Emby.Server.Implementations.Social
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {

View File

@ -45,10 +45,9 @@ namespace Emby.Server.Implementations.Sync
{ {
connection.ExecuteAll(string.Join(";", new[] connection.ExecuteAll(string.Join(";", new[]
{ {
"PRAGMA page_size=4096",
"pragma default_temp_store = memory", "pragma default_temp_store = memory",
"pragma default_synchronous=Normal", "pragma temp_store = memory"
"pragma temp_store = memory",
"pragma synchronous=Normal",
})); }));
string[] queries = { string[] queries = {

View File

@ -72,7 +72,7 @@ namespace Emby.Server.Implementations.TV
return GetResult(episodes, null, request); return GetResult(episodes, null, request);
} }
public QueryResult<BaseItem> GetNextUp(NextUpQuery request, IEnumerable<Folder> parentsFolders) public QueryResult<BaseItem> GetNextUp(NextUpQuery request, List<Folder> parentsFolders)
{ {
var user = _userManager.GetUserById(request.UserId); var user = _userManager.GetUserById(request.UserId);
@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.TV
PresentationUniqueKey = presentationUniqueKey, PresentationUniqueKey = presentationUniqueKey,
Limit = limit Limit = limit
}, parentsFolders.Select(i => i.Id.ToString("N"))).Cast<Series>(); }, parentsFolders.Cast<BaseItem>().ToList()).Cast<Series>();
// Avoid implicitly captured closure // Avoid implicitly captured closure
var episodes = GetNextUpEpisodes(request, user, items); var episodes = GetNextUpEpisodes(request, user, items);

View File

@ -369,7 +369,7 @@ namespace MediaBrowser.Api.Library
if (item is Movie || (program != null && program.IsMovie) || item is Trailer) if (item is Movie || (program != null && program.IsMovie) || item is Trailer)
{ {
return new MoviesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _config, _authContext) return new MoviesService(_userManager, _libraryManager, _dtoService, _config, _authContext)
{ {
Request = Request, Request = Request,

View File

@ -78,16 +78,8 @@ namespace MediaBrowser.Api.Movies
/// </summary> /// </summary>
private readonly IUserManager _userManager; private readonly IUserManager _userManager;
/// <summary>
/// The _user data repository
/// </summary>
private readonly IUserDataManager _userDataRepository;
/// <summary>
/// The _library manager
/// </summary>
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IItemRepository _itemRepo;
private readonly IDtoService _dtoService; private readonly IDtoService _dtoService;
private readonly IServerConfigurationManager _config; private readonly IServerConfigurationManager _config;
private readonly IAuthorizationContext _authContext; private readonly IAuthorizationContext _authContext;
@ -95,17 +87,10 @@ namespace MediaBrowser.Api.Movies
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="MoviesService" /> class. /// Initializes a new instance of the <see cref="MoviesService" /> class.
/// </summary> /// </summary>
/// <param name="userManager">The user manager.</param> public MoviesService(IUserManager userManager, ILibraryManager libraryManager, IDtoService dtoService, IServerConfigurationManager config, IAuthorizationContext authContext)
/// <param name="userDataRepository">The user data repository.</param>
/// <param name="libraryManager">The library manager.</param>
/// <param name="itemRepo">The item repo.</param>
/// <param name="dtoService">The dto service.</param>
public MoviesService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IItemRepository itemRepo, IDtoService dtoService, IServerConfigurationManager config, IAuthorizationContext authContext)
{ {
_userManager = userManager; _userManager = userManager;
_userDataRepository = userDataRepository;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_itemRepo = itemRepo;
_dtoService = dtoService; _dtoService = dtoService;
_config = config; _config = config;
_authContext = authContext; _authContext = authContext;

View File

@ -61,6 +61,12 @@ namespace MediaBrowser.Controller.Entities.Audio
get { return true; } get { return true; }
} }
[IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
get { return true; }
}
[IgnoreDataMember] [IgnoreDataMember]
protected override bool SupportsOwnedItems protected override bool SupportsOwnedItems
{ {

View File

@ -1569,6 +1569,12 @@ namespace MediaBrowser.Controller.Entities
return IsVisibleStandaloneInternal(user, true); return IsVisibleStandaloneInternal(user, true);
} }
[IgnoreDataMember]
public virtual bool SupportsInheritedParentImages
{
get { return false; }
}
protected bool IsVisibleStandaloneInternal(User user, bool checkFolders) protected bool IsVisibleStandaloneInternal(User user, bool checkFolders)
{ {
if (!IsVisible(user)) if (!IsVisible(user))
@ -2329,17 +2335,25 @@ namespace MediaBrowser.Controller.Entities
{ {
get get
{ {
if (GetParent() is AggregateFolder || this is BasePluginFolder || this is Channel) if (this is BasePluginFolder || this is Channel)
{ {
return true; return true;
} }
var view = this as UserView; var view = this as UserView;
if (view != null && string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) if (view != null)
{ {
return true; if (string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (string.Equals(view.ViewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
{
return true;
}
} }
if (view != null && string.Equals(view.ViewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
if (GetParent() is AggregateFolder)
{ {
return true; return true;
} }

View File

@ -1383,6 +1383,15 @@ namespace MediaBrowser.Controller.Entities
{ {
return false; return false;
} }
var iItemByName = this as IItemByName;
if (iItemByName != null)
{
var hasDualAccess = this as IHasDualAccess;
if (hasDualAccess == null || hasDualAccess.IsAccessedByName)
{
return false;
}
}
return true; return true;
} }
@ -1395,17 +1404,6 @@ namespace MediaBrowser.Controller.Entities
return; return;
} }
var unplayedQueryResult = await GetItems(new InternalItemsQuery(user)
{
Recursive = true,
IsFolder = false,
IsVirtualItem = false,
EnableTotalRecordCount = true,
Limit = 0,
IsPlayed = false
}).ConfigureAwait(false);
var allItemsQueryResult = await GetItems(new InternalItemsQuery(user) var allItemsQueryResult = await GetItems(new InternalItemsQuery(user)
{ {
Recursive = true, Recursive = true,
@ -1415,17 +1413,28 @@ namespace MediaBrowser.Controller.Entities
Limit = 0 Limit = 0
}).ConfigureAwait(false); }).ConfigureAwait(false);
var recursiveItemCount = allItemsQueryResult.TotalRecordCount;
if (itemDto != null) if (itemDto != null)
{ {
itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount; itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount;
} }
var recursiveItemCount = allItemsQueryResult.TotalRecordCount; if (recursiveItemCount > 0 && SupportsPlayedStatus)
double unplayedCount = unplayedQueryResult.TotalRecordCount;
if (recursiveItemCount > 0)
{ {
var unplayedQueryResult = recursiveItemCount > 0 ? await GetItems(new InternalItemsQuery(user)
{
Recursive = true,
IsFolder = false,
IsVirtualItem = false,
EnableTotalRecordCount = true,
Limit = 0,
IsPlayed = false
}).ConfigureAwait(false) : new QueryResult<BaseItem>();
double unplayedCount = unplayedQueryResult.TotalRecordCount;
var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100; var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100;
dto.PlayedPercentage = 100 - unplayedPercentage; dto.PlayedPercentage = 100 - unplayedPercentage;
dto.Played = dto.PlayedPercentage.Value >= 100; dto.Played = dto.PlayedPercentage.Value >= 100;

View File

@ -124,7 +124,6 @@ namespace MediaBrowser.Controller.Entities
public int? MaxParentalRating { get; set; } public int? MaxParentalRating { get; set; }
public bool? HasDeadParentId { get; set; } public bool? HasDeadParentId { get; set; }
public bool? IsOffline { get; set; }
public bool? IsVirtualItem { get; set; } public bool? IsVirtualItem { get; set; }
public Guid? ParentId { get; set; } public Guid? ParentId { get; set; }

View File

@ -73,6 +73,12 @@ namespace MediaBrowser.Controller.Entities.TV
} }
} }
[IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
get { return true; }
}
[IgnoreDataMember] [IgnoreDataMember]
public int? AiredSeasonNumber public int? AiredSeasonNumber
{ {

View File

@ -39,6 +39,12 @@ namespace MediaBrowser.Controller.Entities.TV
} }
} }
[IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
get { return true; }
}
[IgnoreDataMember] [IgnoreDataMember]
public override Guid? DisplayParentId public override Guid? DisplayParentId
{ {

View File

@ -135,7 +135,6 @@ namespace MediaBrowser.Controller.Entities.TV
{ {
AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this),
IncludeItemTypes = new[] { typeof(Season).Name }, IncludeItemTypes = new[] { typeof(Season).Name },
SortBy = new[] { ItemSortBy.SortName },
IsVirtualItem = false, IsVirtualItem = false,
Limit = 0 Limit = 0
}); });

View File

@ -1812,7 +1812,7 @@ namespace MediaBrowser.Controller.Entities
.Where(i => user.IsFolderGrouped(i.Id) && UserView.IsEligibleForGrouping(i)); .Where(i => user.IsFolderGrouped(i.Id) && UserView.IsEligibleForGrouping(i));
} }
private IEnumerable<Folder> GetMediaFolders(User user, IEnumerable<string> viewTypes) private List<Folder> GetMediaFolders(User user, IEnumerable<string> viewTypes)
{ {
if (user == null) if (user == null)
{ {
@ -1822,7 +1822,7 @@ namespace MediaBrowser.Controller.Entities
var folder = i as ICollectionFolder; var folder = i as ICollectionFolder;
return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
}); }).ToList();
} }
return GetMediaFolders(user) return GetMediaFolders(user)
.Where(i => .Where(i =>
@ -1830,17 +1830,17 @@ namespace MediaBrowser.Controller.Entities
var folder = i as ICollectionFolder; var folder = i as ICollectionFolder;
return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
}); }).ToList();
} }
private IEnumerable<Folder> GetMediaFolders(Folder parent, User user, IEnumerable<string> viewTypes) private List<Folder> GetMediaFolders(Folder parent, User user, IEnumerable<string> viewTypes)
{ {
if (parent == null || parent is UserView) if (parent == null || parent is UserView)
{ {
return GetMediaFolders(user, viewTypes); return GetMediaFolders(user, viewTypes);
} }
return new[] { parent }; return new List<Folder> { parent };
} }
private IEnumerable<BaseItem> GetRecursiveChildren(Folder parent, User user, IEnumerable<string> viewTypes) private IEnumerable<BaseItem> GetRecursiveChildren(Folder parent, User user, IEnumerable<string> viewTypes)

View File

@ -538,10 +538,7 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// Gets the items. /// Gets the items.
/// </summary> /// </summary>
/// <param name="query">The query.</param> IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents);
/// <param name="parentIds">The parent ids.</param>
/// <returns>List&lt;BaseItem&gt;.</returns>
IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, IEnumerable<string> parentIds);
/// <summary> /// <summary>
/// Gets the items result. /// Gets the items result.

View File

@ -19,6 +19,6 @@ namespace MediaBrowser.Controller.TV
/// <param name="request">The request.</param> /// <param name="request">The request.</param>
/// <param name="parentsFolders">The parents folders.</param> /// <param name="parentsFolders">The parents folders.</param>
/// <returns>QueryResult&lt;BaseItem&gt;.</returns> /// <returns>QueryResult&lt;BaseItem&gt;.</returns>
QueryResult<BaseItem> GetNextUp(NextUpQuery request, IEnumerable<Folder> parentsFolders); QueryResult<BaseItem> GetNextUp(NextUpQuery request, List<Folder> parentsFolders);
} }
} }

View File

@ -14,6 +14,7 @@ namespace MediaBrowser.Model.System
Architecture SystemArchitecture { get; } Architecture SystemArchitecture { get; }
string GetEnvironmentVariable(string name); string GetEnvironmentVariable(string name);
string GetUserId(); string GetUserId();
string StackTrace { get; }
} }
public enum OperatingSystem public enum OperatingSystem

View File

@ -536,7 +536,7 @@ namespace MediaBrowser.Providers.Manager
refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport; refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport;
// Only one local provider allowed per item // Only one local provider allowed per item
if (item.IsLocked || IsFullLocalMetadata(localItem.Item)) if (item.IsLocked || localItem.Item.IsLocked || IsFullLocalMetadata(localItem.Item))
{ {
hasLocalMetadata = true; hasLocalMetadata = true;
} }
@ -573,14 +573,16 @@ namespace MediaBrowser.Providers.Manager
{ {
if (refreshResult.UpdateType > ItemUpdateType.None) if (refreshResult.UpdateType > ItemUpdateType.None)
{ {
// If no local metadata, take data from item itself if (hasLocalMetadata)
if (!hasLocalMetadata) {
MergeData(temp, metadata, item.LockedFields, true, true);
}
else
{ {
// TODO: If the new metadata from above has some blank data, this can cause old data to get filled into those empty fields // TODO: If the new metadata from above has some blank data, this can cause old data to get filled into those empty fields
MergeData(metadata, temp, new List<MetadataFields>(), false, true); MergeData(metadata, temp, new List<MetadataFields>(), false, false);
MergeData(temp, metadata, item.LockedFields, true, false);
} }
MergeData(temp, metadata, item.LockedFields, true, true);
} }
} }