mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-15 18:08:53 -07:00
move child definitions to db
This commit is contained in:
parent
6f15aeccd0
commit
6bc263052d
@ -407,6 +407,18 @@ namespace MediaBrowser.Common.Implementations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the export types.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns>IEnumerable{Type}.</returns>
|
||||||
|
public IEnumerable<Type> GetExportTypes<T>()
|
||||||
|
{
|
||||||
|
var currentType = typeof(T);
|
||||||
|
|
||||||
|
return AllConcreteTypes.AsParallel().Where(currentType.IsAssignableFrom);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the exports.
|
/// Gets the exports.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -415,9 +427,7 @@ namespace MediaBrowser.Common.Implementations
|
|||||||
/// <returns>IEnumerable{``0}.</returns>
|
/// <returns>IEnumerable{``0}.</returns>
|
||||||
public IEnumerable<T> GetExports<T>(bool manageLiftime = true)
|
public IEnumerable<T> GetExports<T>(bool manageLiftime = true)
|
||||||
{
|
{
|
||||||
var currentType = typeof(T);
|
var parts = GetExportTypes<T>().Select(CreateInstance).Cast<T>().ToArray();
|
||||||
|
|
||||||
var parts = AllConcreteTypes.AsParallel().Where(currentType.IsAssignableFrom).Select(CreateInstance).Cast<T>().ToArray();
|
|
||||||
|
|
||||||
if (manageLiftime)
|
if (manageLiftime)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +143,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
public static IServerConfigurationManager ConfigurationManager { get; set; }
|
public static IServerConfigurationManager ConfigurationManager { get; set; }
|
||||||
public static IProviderManager ProviderManager { get; set; }
|
public static IProviderManager ProviderManager { get; set; }
|
||||||
public static ILocalizationManager LocalizationManager { get; set; }
|
public static ILocalizationManager LocalizationManager { get; set; }
|
||||||
|
public static IItemRepository ItemRepository { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||||
|
22
MediaBrowser.Controller/Entities/ChildDefinition.cs
Normal file
22
MediaBrowser.Controller/Entities/ChildDefinition.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class ChildDefinition
|
||||||
|
/// </summary>
|
||||||
|
public class ChildDefinition
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the item id.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The item id.</value>
|
||||||
|
public Guid ItemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the type.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The type.</value>
|
||||||
|
public string Type { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -22,14 +22,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Folder : BaseItem
|
public class Folder : BaseItem
|
||||||
{
|
{
|
||||||
private static TypeMapper _typeMapper = new TypeMapper();
|
private static readonly TypeMapper _typeMapper = new TypeMapper();
|
||||||
|
|
||||||
public Folder()
|
|
||||||
{
|
|
||||||
ChildDefinitions = new ConcurrentDictionary<Guid, string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConcurrentDictionary<Guid, string> ChildDefinitions { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this instance is folder.
|
/// Gets a value indicating whether this instance is folder.
|
||||||
@ -118,14 +111,19 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
item.DateModified = DateTime.Now;
|
item.DateModified = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_children.TryAdd(item.Id, item) || !ChildDefinitions.TryAdd(item.Id, item.GetType().FullName))
|
if (!_children.TryAdd(item.Id, item))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Unable to add " + item.Name);
|
throw new InvalidOperationException("Unable to add " + item.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
await LibraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
await LibraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
await LibraryManager.UpdateItem(this, cancellationToken).ConfigureAwait(false);
|
await ItemRepository.SaveChildren(Id, _children.Values.ToList().Select(i => new ChildDefinition
|
||||||
|
{
|
||||||
|
ItemId = i.Id,
|
||||||
|
Type = i.GetType().FullName
|
||||||
|
|
||||||
|
}), cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -153,9 +151,8 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
public Task RemoveChild(BaseItem item, CancellationToken cancellationToken)
|
public Task RemoveChild(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
BaseItem removed;
|
BaseItem removed;
|
||||||
string removedType;
|
|
||||||
|
|
||||||
if (!_children.TryRemove(item.Id, out removed) || !ChildDefinitions.TryRemove(item.Id, out removedType))
|
if (!_children.TryRemove(item.Id, out removed))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Unable to remove " + item.Name);
|
throw new InvalidOperationException("Unable to remove " + item.Name);
|
||||||
}
|
}
|
||||||
@ -164,7 +161,12 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
|
|
||||||
LibraryManager.ReportItemRemoved(item);
|
LibraryManager.ReportItemRemoved(item);
|
||||||
|
|
||||||
return LibraryManager.UpdateItem(this, cancellationToken);
|
return ItemRepository.SaveChildren(Id, _children.Values.ToList().Select(i => new ChildDefinition
|
||||||
|
{
|
||||||
|
ItemId = i.Id,
|
||||||
|
Type = i.GetType().FullName
|
||||||
|
|
||||||
|
}), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Indexing
|
#region Indexing
|
||||||
@ -495,7 +497,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// Gets or sets the actual children.
|
/// Gets or sets the actual children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The actual children.</value>
|
/// <value>The actual children.</value>
|
||||||
protected virtual ConcurrentDictionary<Guid,BaseItem> ActualChildren
|
protected virtual ConcurrentDictionary<Guid, BaseItem> ActualChildren
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -558,10 +560,10 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// We want this sychronous.
|
/// We want this sychronous.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>ConcurrentBag{BaseItem}.</returns>
|
/// <returns>ConcurrentBag{BaseItem}.</returns>
|
||||||
protected virtual ConcurrentDictionary<Guid,BaseItem> LoadChildren()
|
protected virtual ConcurrentDictionary<Guid, BaseItem> LoadChildren()
|
||||||
{
|
{
|
||||||
//just load our children from the repo - the library will be validated and maintained in other processes
|
//just load our children from the repo - the library will be validated and maintained in other processes
|
||||||
return new ConcurrentDictionary<Guid,BaseItem>(GetCachedChildren().ToDictionary(i => i.Id));
|
return new ConcurrentDictionary<Guid, BaseItem>(GetCachedChildren().ToDictionary(i => i.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -709,9 +711,6 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string removedType;
|
|
||||||
ChildDefinitions.TryRemove(item.Id, out removedType);
|
|
||||||
|
|
||||||
LibraryManager.ReportItemRemoved(item);
|
LibraryManager.ReportItemRemoved(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -726,13 +725,16 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ChildDefinitions.TryAdd(item.Id, item.GetType().FullName);
|
|
||||||
|
|
||||||
Logger.Debug("** " + item.Name + " Added to library.");
|
Logger.Debug("** " + item.Name + " Added to library.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await LibraryManager.UpdateItem(this, CancellationToken.None).ConfigureAwait(false);
|
await ItemRepository.SaveChildren(Id, _children.Values.ToList().Select(i => new ChildDefinition
|
||||||
|
{
|
||||||
|
ItemId = i.Id,
|
||||||
|
Type = i.GetType().FullName
|
||||||
|
|
||||||
|
}), cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
//force the indexes to rebuild next time
|
//force the indexes to rebuild next time
|
||||||
IndexCache.Clear();
|
IndexCache.Clear();
|
||||||
@ -804,7 +806,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
{
|
{
|
||||||
lock (percentages)
|
lock (percentages)
|
||||||
{
|
{
|
||||||
percentages[child.Id] = p/100;
|
percentages[child.Id] = p / 100;
|
||||||
|
|
||||||
var percent = percentages.Values.Sum();
|
var percent = percentages.Values.Sum();
|
||||||
percent /= list.Count;
|
percent /= list.Count;
|
||||||
@ -862,7 +864,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||||
protected IEnumerable<BaseItem> GetCachedChildren()
|
protected IEnumerable<BaseItem> GetCachedChildren()
|
||||||
{
|
{
|
||||||
var items = ChildDefinitions.ToList().Select(RetrieveChild).Where(i => i != null).ToList();
|
var items = ItemRepository.GetChildren(Id).Select(RetrieveChild).Where(i => i != null).ToList();
|
||||||
|
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
@ -877,9 +879,9 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="child">The child.</param>
|
/// <param name="child">The child.</param>
|
||||||
/// <returns>BaseItem.</returns>
|
/// <returns>BaseItem.</returns>
|
||||||
private BaseItem RetrieveChild(KeyValuePair<Guid,string> child)
|
private BaseItem RetrieveChild(ChildDefinition child)
|
||||||
{
|
{
|
||||||
var type = child.Value;
|
var type = child.Type;
|
||||||
|
|
||||||
var itemType = _typeMapper.GetType(type);
|
var itemType = _typeMapper.GetType(type);
|
||||||
|
|
||||||
@ -889,7 +891,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = LibraryManager.RetrieveItem(child.Key, itemType);
|
var item = LibraryManager.RetrieveItem(child.ItemId, itemType);
|
||||||
|
|
||||||
return item is IByReferenceItem ? LibraryManager.GetOrAddByReferenceItem(item) : item;
|
return item is IByReferenceItem ? LibraryManager.GetOrAddByReferenceItem(item) : item;
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@
|
|||||||
<Compile Include="Dto\SessionInfoDtoBuilder.cs" />
|
<Compile Include="Dto\SessionInfoDtoBuilder.cs" />
|
||||||
<Compile Include="Entities\Audio\MusicAlbumDisc.cs" />
|
<Compile Include="Entities\Audio\MusicAlbumDisc.cs" />
|
||||||
<Compile Include="Entities\Audio\MusicGenre.cs" />
|
<Compile Include="Entities\Audio\MusicGenre.cs" />
|
||||||
|
<Compile Include="Entities\ChildDefinition.cs" />
|
||||||
<Compile Include="Entities\IByReferenceItem.cs" />
|
<Compile Include="Entities\IByReferenceItem.cs" />
|
||||||
<Compile Include="Entities\MusicVideo.cs" />
|
<Compile Include="Entities\MusicVideo.cs" />
|
||||||
<Compile Include="Library\ILibraryPostScanTask.cs" />
|
<Compile Include="Library\ILibraryPostScanTask.cs" />
|
||||||
|
@ -10,6 +10,12 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDisplayPreferencesRepository : IRepository
|
public interface IDisplayPreferencesRepository : IRepository
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the connection to the repository
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task Initialize();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves display preferences for an item
|
/// Saves display preferences for an item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -13,6 +13,12 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IItemRepository : IRepository
|
public interface IItemRepository : IRepository
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the connection to the repository
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task Initialize();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves an item
|
/// Saves an item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -75,6 +81,22 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task SaveChapters(Guid id, IEnumerable<ChapterInfo> chapters, CancellationToken cancellationToken);
|
Task SaveChapters(Guid id, IEnumerable<ChapterInfo> chapters, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the children.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parentId">The parent id.</param>
|
||||||
|
/// <returns>IEnumerable{ChildDefinition}.</returns>
|
||||||
|
IEnumerable<ChildDefinition> GetChildren(Guid parentId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the children.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parentId">The parent id.</param>
|
||||||
|
/// <param name="children">The children.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task SaveChildren(Guid parentId, IEnumerable<ChildDefinition> children, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,12 +8,6 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRepository : IDisposable
|
public interface IRepository : IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Opens the connection to the repository
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
Task Initialize();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the repository
|
/// Gets the name of the repository
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -10,6 +10,12 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IUserDataRepository : IRepository
|
public interface IUserDataRepository : IRepository
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the connection to the repository
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task Initialize();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the user data.
|
/// Saves the user data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -10,6 +10,12 @@ namespace MediaBrowser.Controller.Persistence
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IUserRepository : IRepository
|
public interface IUserRepository : IRepository
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the connection to the repository
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task Initialize();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes the user.
|
/// Deletes the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -64,6 +64,12 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\ServiceStack.Common.3.9.54\lib\net35\ServiceStack.Interfaces.dll</HintPath>
|
<HintPath>..\packages\ServiceStack.Common.3.9.54\lib\net35\ServiceStack.Interfaces.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="ServiceStack.OrmLite">
|
||||||
|
<HintPath>..\packages\ServiceStack.OrmLite.Sqlite32.3.9.54\lib\net40\ServiceStack.OrmLite.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="ServiceStack.OrmLite.SqliteNET">
|
||||||
|
<HintPath>..\packages\ServiceStack.OrmLite.Sqlite32.3.9.54\lib\net40\ServiceStack.OrmLite.SqliteNET.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="ServiceStack.OrmLite.SqlServer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="ServiceStack.OrmLite.SqlServer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.43\lib\ServiceStack.OrmLite.SqlServer.dll</HintPath>
|
<HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.43\lib\ServiceStack.OrmLite.SqlServer.dll</HintPath>
|
||||||
|
@ -27,16 +27,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||||||
private SQLiteCommand _saveChapterCommand;
|
private SQLiteCommand _saveChapterCommand;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
/// Initializes a new instance of the <see cref="SqliteItemRepository" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="appPaths">The app paths.</param>
|
/// <param name="appPaths">The app paths.</param>
|
||||||
/// <param name="jsonSerializer">The json serializer.</param>
|
|
||||||
/// <param name="logManager">The log manager.</param>
|
/// <param name="logManager">The log manager.</param>
|
||||||
/// <exception cref="System.ArgumentNullException">
|
/// <exception cref="System.ArgumentNullException">appPaths
|
||||||
/// appPaths
|
|
||||||
/// or
|
/// or
|
||||||
/// jsonSerializer
|
/// jsonSerializer</exception>
|
||||||
/// </exception>
|
|
||||||
public SqliteChapterRepository(IApplicationPaths appPaths, ILogManager logManager)
|
public SqliteChapterRepository(IApplicationPaths appPaths, ILogManager logManager)
|
||||||
{
|
{
|
||||||
if (appPaths == null)
|
if (appPaths == null)
|
||||||
|
@ -56,6 +56,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||||||
|
|
||||||
private SqliteChapterRepository _chapterRepository;
|
private SqliteChapterRepository _chapterRepository;
|
||||||
|
|
||||||
|
private SQLiteCommand _deleteChildrenCommand;
|
||||||
|
private SQLiteCommand _saveChildrenCommand;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -103,6 +106,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||||||
"create table if not exists baseitems (guid GUID primary key, data BLOB)",
|
"create table if not exists baseitems (guid GUID primary key, data BLOB)",
|
||||||
"create index if not exists idx_baseitems on baseitems(guid)",
|
"create index if not exists idx_baseitems on baseitems(guid)",
|
||||||
|
|
||||||
|
"create table if not exists ChildDefinitions (ParentId GUID, ItemId GUID, Type TEXT, PRIMARY KEY (ParentId, ItemId))",
|
||||||
|
"create index if not exists idx_baseitems on baseitems(ParentId,ItemId)",
|
||||||
|
|
||||||
//pragmas
|
//pragmas
|
||||||
"pragma temp_store = memory"
|
"pragma temp_store = memory"
|
||||||
};
|
};
|
||||||
@ -131,6 +137,22 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||||||
|
|
||||||
_saveItemCommand.Parameters.Add(new SQLiteParameter("@1"));
|
_saveItemCommand.Parameters.Add(new SQLiteParameter("@1"));
|
||||||
_saveItemCommand.Parameters.Add(new SQLiteParameter("@2"));
|
_saveItemCommand.Parameters.Add(new SQLiteParameter("@2"));
|
||||||
|
|
||||||
|
_deleteChildrenCommand = new SQLiteCommand
|
||||||
|
{
|
||||||
|
CommandText = "delete from ChildDefinitions where ParentId=@ParentId"
|
||||||
|
};
|
||||||
|
|
||||||
|
_deleteChildrenCommand.Parameters.Add(new SQLiteParameter("@ParentId"));
|
||||||
|
|
||||||
|
_saveChildrenCommand = new SQLiteCommand
|
||||||
|
{
|
||||||
|
CommandText = "replace into ChildDefinitions (ParentId, ItemId, Type) values (@ParentId, @ItemId, @Type)"
|
||||||
|
};
|
||||||
|
|
||||||
|
_saveChildrenCommand.Parameters.Add(new SQLiteParameter("@ParentId"));
|
||||||
|
_saveChildrenCommand.Parameters.Add(new SQLiteParameter("@ItemId"));
|
||||||
|
_saveChildrenCommand.Parameters.Add(new SQLiteParameter("@Type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -401,5 +423,110 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<ChildDefinition> GetChildren(Guid parentId)
|
||||||
|
{
|
||||||
|
if (parentId == Guid.Empty)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("parentId");
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var cmd = _connection.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = "select ItemId,Type from ChildDefinitions where ParentId = @ParentId";
|
||||||
|
|
||||||
|
cmd.Parameters.Add("@ParentId", DbType.Guid).Value = parentId;
|
||||||
|
|
||||||
|
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
yield return new ChildDefinition
|
||||||
|
{
|
||||||
|
ItemId = reader.GetGuid(0),
|
||||||
|
Type = reader.GetString(1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveChildren(Guid parentId, IEnumerable<ChildDefinition> children, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (parentId == Guid.Empty)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("parentId");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("children");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cancellationToken == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("cancellationToken");
|
||||||
|
}
|
||||||
|
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
SQLiteTransaction transaction = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transaction = _connection.BeginTransaction();
|
||||||
|
|
||||||
|
// First delete
|
||||||
|
_deleteChildrenCommand.Parameters[0].Value = parentId;
|
||||||
|
_deleteChildrenCommand.Transaction = transaction;
|
||||||
|
await _deleteChildrenCommand.ExecuteNonQueryAsync(cancellationToken);
|
||||||
|
|
||||||
|
foreach (var chapter in children)
|
||||||
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
_saveChildrenCommand.Parameters[0].Value = parentId;
|
||||||
|
_saveChildrenCommand.Parameters[1].Value = chapter.ItemId;
|
||||||
|
_saveChildrenCommand.Parameters[2].Value = chapter.Type;
|
||||||
|
|
||||||
|
_saveChildrenCommand.Transaction = transaction;
|
||||||
|
|
||||||
|
await _saveChildrenCommand.ExecuteNonQueryAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Failed to save children:", e);
|
||||||
|
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
transaction.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeLock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,6 +10,7 @@
|
|||||||
<package id="ServiceStack" version="3.9.54" targetFramework="net45" />
|
<package id="ServiceStack" version="3.9.54" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Api.Swagger" version="3.9.54" targetFramework="net45" />
|
<package id="ServiceStack.Api.Swagger" version="3.9.54" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Common" version="3.9.54" targetFramework="net45" />
|
<package id="ServiceStack.Common" version="3.9.54" targetFramework="net45" />
|
||||||
|
<package id="ServiceStack.OrmLite.Sqlite32" version="3.9.54" targetFramework="net45" />
|
||||||
<package id="ServiceStack.OrmLite.SqlServer" version="3.9.43" targetFramework="net45" />
|
<package id="ServiceStack.OrmLite.SqlServer" version="3.9.43" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Redis" version="3.9.43" targetFramework="net45" />
|
<package id="ServiceStack.Redis" version="3.9.43" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Text" version="3.9.54" targetFramework="net45" />
|
<package id="ServiceStack.Text" version="3.9.54" targetFramework="net45" />
|
||||||
|
@ -359,6 +359,7 @@ namespace MediaBrowser.ServerApplication
|
|||||||
BaseItem.LibraryManager = LibraryManager;
|
BaseItem.LibraryManager = LibraryManager;
|
||||||
BaseItem.ProviderManager = ProviderManager;
|
BaseItem.ProviderManager = ProviderManager;
|
||||||
BaseItem.LocalizationManager = LocalizationManager;
|
BaseItem.LocalizationManager = LocalizationManager;
|
||||||
|
BaseItem.ItemRepository = ItemRepository;
|
||||||
User.XmlSerializer = XmlSerializer;
|
User.XmlSerializer = XmlSerializer;
|
||||||
User.UserManager = UserManager;
|
User.UserManager = UserManager;
|
||||||
LocalizedStrings.ApplicationPaths = ApplicationPaths;
|
LocalizedStrings.ApplicationPaths = ApplicationPaths;
|
||||||
|
Loading…
Reference in New Issue
Block a user