From 92cf390fb0d8cb23d56128591e15f496210fcc7e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 21 Nov 2016 15:22:43 -0500 Subject: [PATCH] update user data db --- Emby.Server.Core/ApplicationHost.cs | 2 +- .../Data/BaseSqliteRepository.cs | 20 ++--- .../Data/SqliteItemRepository.cs | 45 ++++------- .../Data/SqliteUserDataRepository.cs | 81 ++++++++++++++----- 4 files changed, 85 insertions(+), 63 deletions(-) diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs index d481380805..7e5d6e31c7 100644 --- a/Emby.Server.Core/ApplicationHost.cs +++ b/Emby.Server.Core/ApplicationHost.cs @@ -694,7 +694,7 @@ namespace Emby.Server.Core displayPreferencesRepo.Initialize(); - var userDataRepo = new SqliteUserDataRepository(LogManager.GetLogger("SqliteUserDataRepository"), ApplicationPaths); + var userDataRepo = new SqliteUserDataRepository(LogManager.GetLogger("SqliteUserDataRepository"), ApplicationPaths, FileSystemManager); ((UserDataManager)UserDataManager).Repository = userDataRepo; itemRepo.Initialize(userDataRepo); diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs index d4226ec256..5c60a6f86f 100644 --- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs +++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs @@ -42,7 +42,7 @@ namespace Emby.Server.Implementations.Data private string _defaultWal; - protected SQLiteDatabaseConnection CreateConnection(bool isReadOnly = false, Action onConnect = null) + protected SQLiteDatabaseConnection CreateConnection(bool isReadOnly = false) { if (!_versionLogged) { @@ -88,9 +88,8 @@ namespace Emby.Server.Implementations.Data var queries = new List { - "PRAGMA default_temp_store=memory", - "pragma temp_store = memory", - "PRAGMA journal_mode=WAL" + "PRAGMA temp_store = memory", + //"PRAGMA journal_mode=WAL" //"PRAGMA cache size=-10000" }; @@ -108,18 +107,19 @@ namespace Emby.Server.Implementations.Data //Logger.Info("synchronous: " + db.Query("PRAGMA synchronous").SelectScalarString().First()); //Logger.Info("temp_store: " + db.Query("PRAGMA temp_store").SelectScalarString().First()); - //if (!string.Equals(_defaultWal, "wal", StringComparison.OrdinalIgnoreCase) || onConnect != null) + if (!string.Equals(_defaultWal, "wal", StringComparison.OrdinalIgnoreCase)) { + queries.Add("PRAGMA journal_mode=WAL"); + using (WriteLock.Write()) { db.ExecuteAll(string.Join(";", queries.ToArray())); - - if (onConnect != null) - { - onConnect(db); - } } } + else + { + db.ExecuteAll(string.Join(";", queries.ToArray())); + } return db; } diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index bc1eca06a9..5c24c9ac4b 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -357,23 +357,6 @@ namespace Emby.Server.Implementations.Data //await Vacuum(_connection).ConfigureAwait(false); } - - private SQLiteDatabaseConnection CreateConnection(bool readOnly, bool attachUserdata) - { - Action onConnect = null; - - if (attachUserdata) - { - onConnect = - c => SqliteExtensions.Attach(c, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), - "UserDataDb"); - } - - var conn = CreateConnection(readOnly, onConnect); - - return conn; - } - private readonly string[] _retriveItemColumns = { "type", @@ -2265,13 +2248,13 @@ namespace Emby.Server.Implementations.Data 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) @@ -2336,7 +2319,7 @@ namespace Emby.Server.Implementations.Data return string.Empty; } - return " left join UserDataDb.UserData on UserDataKey=UserDataDb.UserData.Key And (UserId=@UserId)"; + return " left join UserData on UserDataKey=UserData.Key And (UserId=@UserId)"; } private string GetGroupBy(InternalItemsQuery query) @@ -2412,7 +2395,7 @@ namespace Emby.Server.Implementations.Data } } - using (var connection = CreateConnection(true, EnableJoinUserData(query))) + using (var connection = CreateConnection(true)) { using (WriteLock.Read()) { @@ -2581,7 +2564,7 @@ namespace Emby.Server.Implementations.Data } } - using (var connection = CreateConnection(true, EnableJoinUserData(query))) + using (var connection = CreateConnection(true)) { using (WriteLock.Read()) { @@ -2811,7 +2794,7 @@ namespace Emby.Server.Implementations.Data var list = new List(); - using (var connection = CreateConnection(true, EnableJoinUserData(query))) + using (var connection = CreateConnection(true)) { using (WriteLock.Read()) { @@ -2882,7 +2865,7 @@ namespace Emby.Server.Implementations.Data var list = new List>(); - using (var connection = CreateConnection(true, EnableJoinUserData(query))) + using (var connection = CreateConnection(true)) { using (WriteLock.Read()) { @@ -2972,7 +2955,7 @@ namespace Emby.Server.Implementations.Data var list = new List(); - using (var connection = CreateConnection(true, EnableJoinUserData(query))) + using (var connection = CreateConnection(true)) { using (WriteLock.Read()) { @@ -4880,7 +4863,7 @@ namespace Emby.Server.Implementations.Data var list = new List>(); var count = 0; - using (var connection = CreateConnection(true, EnableJoinUserData(query))) + using (var connection = CreateConnection(true)) { using (WriteLock.Read()) { diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs index feeb212f16..4c1b8fcd95 100644 --- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using SQLitePCL.pretty; @@ -14,10 +15,15 @@ namespace Emby.Server.Implementations.Data { public class SqliteUserDataRepository : BaseSqliteRepository, IUserDataRepository { - public SqliteUserDataRepository(ILogger logger, IApplicationPaths appPaths) + private readonly string _importFile; + private readonly IFileSystem _fileSystem; + + public SqliteUserDataRepository(ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem) : base(logger) { - DbFilePath = Path.Combine(appPaths.DataPath, "userdata_v2.db"); + _fileSystem = fileSystem; + DbFilePath = Path.Combine(appPaths.DataPath, "library.db"); + _importFile = Path.Combine(appPaths.DataPath, "userdata_v2.db"); } /// @@ -43,31 +49,23 @@ namespace Emby.Server.Implementations.Data using (var connection = CreateConnection()) { - connection.ExecuteAll(string.Join(";", new[] - { - "PRAGMA page_size=4096", - "pragma default_temp_store = memory", - "pragma temp_store = memory" - })); - string[] queries = { - "PRAGMA locking_mode=NORMAL", + "pragma temp_store = memory", - "create table if not exists UserDataDb.userdata (key nvarchar, userId GUID, rating float null, played bit, playCount int, isFavorite bit, playbackPositionTicks bigint, lastPlayedDate datetime null)", + "create table if not exists userdata (key nvarchar, userId GUID, rating float null, played bit, playCount int, isFavorite bit, playbackPositionTicks bigint, lastPlayedDate datetime null)", - "drop index if exists UserDataDb.idx_userdata", - "drop index if exists UserDataDb.idx_userdata1", - "drop index if exists UserDataDb.idx_userdata2", - "drop index if exists UserDataDb.userdataindex1", + "create table if not exists DataSettings (IsUserDataImported bit)", - "create unique index if not exists UserDataDb.userdataindex on userdata (key, userId)", - "create index if not exists UserDataDb.userdataindex2 on userdata (key, userId, played)", - "create index if not exists UserDataDb.userdataindex3 on userdata (key, userId, playbackPositionTicks)", - "create index if not exists UserDataDb.userdataindex4 on userdata (key, userId, isFavorite)", + "drop index if exists idx_userdata", + "drop index if exists idx_userdata1", + "drop index if exists idx_userdata2", + "drop index if exists userdataindex1", - //pragmas - "pragma temp_store = memory", + "create unique index if not exists userdataindex on userdata (key, userId)", + "create index if not exists userdataindex2 on userdata (key, userId, played)", + "create index if not exists userdataindex3 on userdata (key, userId, playbackPositionTicks)", + "create index if not exists userdataindex4 on userdata (key, userId, isFavorite)", "pragma shrink_memory" }; @@ -81,7 +79,48 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "userdata", "AudioStreamIndex", "int", existingColumnNames); AddColumn(db, "userdata", "SubtitleStreamIndex", "int", existingColumnNames); }); + + ImportUserDataIfNeeded(connection); + } + } + + private void ImportUserDataIfNeeded(IDatabaseConnection connection) + { + if (!_fileSystem.FileExists(_importFile)) + { + return; + } + + var fileToImport = _importFile; + var isImported = connection.Query("select IsUserDataImported from DataSettings").SelectScalarBool().FirstOrDefault(); + + if (isImported) + { + return; } + + ImportUserData(connection, fileToImport); + + connection.RunInTransaction(db => + { + using (var statement = db.PrepareStatement("replace into DataSettings (IsUserDataImported) values (@IsUserDataImported)")) + { + statement.TryBind("@IsUserDataImported", true); + statement.MoveNext(); + } + }); + } + + private void ImportUserData(IDatabaseConnection connection, string file) + { + SqliteExtensions.Attach(connection, file, "UserDataBackup"); + + var columns = "key, userId, rating, played, playCount, isFavorite, playbackPositionTicks, lastPlayedDate, AudioStreamIndex, SubtitleStreamIndex"; + + connection.RunInTransaction(db => + { + db.Execute("REPLACE INTO userdata(" + columns + ") SELECT " + columns + " FROM UserDataBackup.userdata;"); + }); } ///