From f6f0a8a481332f55a4af68ee776580cb506dd48c Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 6 Jan 2019 16:00:30 +0100 Subject: Use EF Core for Activity database --- .../Activity/ActivityRepository.cs | 305 ++------------------- 1 file changed, 16 insertions(+), 289 deletions(-) (limited to 'Emby.Server.Implementations/Activity/ActivityRepository.cs') diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index aeed8b6f1..34d6bc198 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -1,310 +1,37 @@ -using System; -using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; -using Emby.Server.Implementations.Data; -using MediaBrowser.Controller; +using System.Threading.Tasks; using MediaBrowser.Model.Activity; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Querying; -using Microsoft.Extensions.Logging; -using SQLitePCL.pretty; +using Microsoft.EntityFrameworkCore; namespace Emby.Server.Implementations.Activity { - public class ActivityRepository : BaseSqliteRepository, IActivityRepository + public class ActivityRepository : DbContext, IActivityRepository { - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - protected IFileSystem FileSystem { get; private set; } + protected string _dataDirPath; - public ActivityRepository(ILoggerFactory loggerFactory, IServerApplicationPaths appPaths, IFileSystem fileSystem) - : base(loggerFactory.CreateLogger(nameof(ActivityRepository))) - { - DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db"); - FileSystem = fileSystem; - } + public DbSet ActivityLogs { get; set; } - public void Initialize() + public ActivityRepository(string dataDirPath) { - try - { - InitializeInternal(); - } - catch (Exception ex) - { - Logger.LogError(ex, "Error loading database file. Will reset and retry."); - - FileSystem.DeleteFile(DbFilePath); - - InitializeInternal(); - } + _dataDirPath = dataDirPath; } - private void InitializeInternal() + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - using (var connection = CreateConnection()) - { - RunDefaultInitialization(connection); - - connection.RunQueries(new[] - { - "create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)", - "drop index if exists idx_ActivityLogEntries" - }); - - TryMigrate(connection); - } - } + // Ensure the dir exists + if (!Directory.Exists(_dataDirPath)) Directory.CreateDirectory(_dataDirPath); - private void TryMigrate(ManagedConnection connection) - { - try - { - if (TableExists(connection, "ActivityLogEntries")) - { - connection.RunQueries(new[] - { - "INSERT INTO ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) SELECT Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity FROM ActivityLogEntries", - "drop table if exists ActivityLogEntries" - }); - } - } - catch (Exception ex) - { - Logger.LogError(ex, "Error migrating activity log database"); - } + optionsBuilder.UseSqlite($"Filename={Path.Combine(_dataDirPath, "activitylog.sqlite.db")}"); } - private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog"; - - public void Create(ActivityLogEntry entry) + public async Task CreateAsync(ActivityLogEntry entry) { - if (entry == null) - { - throw new ArgumentNullException(nameof(entry)); - } - - using (WriteLock.Write()) - using (var connection = CreateConnection()) - { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)")) - { - statement.TryBind("@Name", entry.Name); - - statement.TryBind("@Overview", entry.Overview); - statement.TryBind("@ShortOverview", entry.ShortOverview); - statement.TryBind("@Type", entry.Type); - statement.TryBind("@ItemId", entry.ItemId); - - if (entry.UserId.Equals(Guid.Empty)) - { - statement.TryBindNull("@UserId"); - } - else - { - statement.TryBind("@UserId", entry.UserId.ToString("N")); - } - - statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); - statement.TryBind("@LogSeverity", entry.Severity.ToString()); - - statement.MoveNext(); - } - }, TransactionMode); - } - } - - public void Update(ActivityLogEntry entry) - { - if (entry == null) - { - throw new ArgumentNullException(nameof(entry)); - } - - using (WriteLock.Write()) - using (var connection = CreateConnection()) - { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id")) - { - statement.TryBind("@Id", entry.Id); - - statement.TryBind("@Name", entry.Name); - statement.TryBind("@Overview", entry.Overview); - statement.TryBind("@ShortOverview", entry.ShortOverview); - statement.TryBind("@Type", entry.Type); - statement.TryBind("@ItemId", entry.ItemId); - - if (entry.UserId.Equals(Guid.Empty)) - { - statement.TryBindNull("@UserId"); - } - else - { - statement.TryBind("@UserId", entry.UserId.ToString("N")); - } - - statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); - statement.TryBind("@LogSeverity", entry.Severity.ToString()); - - statement.MoveNext(); - } - }, TransactionMode); - } - } - - public QueryResult GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit) - { - using (WriteLock.Read()) - using (var connection = CreateConnection(true)) - { - var commandText = BaseActivitySelectText; - var whereClauses = new List(); - - if (minDate.HasValue) - { - whereClauses.Add("DateCreated>=@DateCreated"); - } - if (hasUserId.HasValue) - { - if (hasUserId.Value) - { - whereClauses.Add("UserId not null"); - } - else - { - whereClauses.Add("UserId is null"); - } - } - - var whereTextWithoutPaging = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); - - if (startIndex.HasValue && startIndex.Value > 0) - { - var pagingWhereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); - - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLog {0} ORDER BY DateCreated DESC LIMIT {1})", - pagingWhereText, - startIndex.Value.ToString(_usCulture))); - } - - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); - - commandText += whereText; - - commandText += " ORDER BY DateCreated DESC"; - - if (limit.HasValue) - { - commandText += " LIMIT " + limit.Value.ToString(_usCulture); - } - - var statementTexts = new List(); - statementTexts.Add(commandText); - statementTexts.Add("select count (Id) from ActivityLog" + whereTextWithoutPaging); - - return connection.RunInTransaction(db => - { - var list = new List(); - var result = new QueryResult(); - - var statements = PrepareAllSafe(db, statementTexts).ToList(); - - using (var statement = statements[0]) - { - if (minDate.HasValue) - { - statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue()); - } - - foreach (var row in statement.ExecuteQuery()) - { - list.Add(GetEntry(row)); - } - } - - using (var statement = statements[1]) - { - if (minDate.HasValue) - { - statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue()); - } - - result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First(); - } - - result.Items = list.ToArray(); - return result; - - }, ReadTransactionMode); - } + await ActivityLogs.AddAsync(entry); + await SaveChangesAsync(); } - private static ActivityLogEntry GetEntry(IReadOnlyList reader) - { - var index = 0; - - var info = new ActivityLogEntry - { - Id = reader[index].ToInt64() - }; - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.Name = reader[index].ToString(); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.Overview = reader[index].ToString(); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.ShortOverview = reader[index].ToString(); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.Type = reader[index].ToString(); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.ItemId = reader[index].ToString(); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.UserId = new Guid(reader[index].ToString()); - } - - index++; - info.Date = reader[index].ReadDateTime(); - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.Severity = (LogLevel)Enum.Parse(typeof(LogLevel), reader[index].ToString(), true); - } - - return info; - } + public IQueryable GetActivityLogEntries() + => ActivityLogs; } } -- cgit v1.2.3 From 8d9428ebdc463dcaa02cfa8daf91ab480f2ace6a Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 14 Jan 2019 18:28:29 +0100 Subject: Ensure DB exists --- .../Activity/ActivityRepository.cs | 5 ++++- Emby.Server.Implementations/ApplicationHost.cs | 16 ++++++++++------ Jellyfin.Server/Program.cs | 4 +--- MediaBrowser.Common/IApplicationHost.cs | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) (limited to 'Emby.Server.Implementations/Activity/ActivityRepository.cs') diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index 34d6bc198..fb5f8d6ef 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -20,7 +20,10 @@ namespace Emby.Server.Implementations.Activity protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // Ensure the dir exists - if (!Directory.Exists(_dataDirPath)) Directory.CreateDirectory(_dataDirPath); + if (!Directory.Exists(_dataDirPath)) + { + Directory.CreateDirectory(_dataDirPath); + } optionsBuilder.UseSqlite($"Filename={Path.Combine(_dataDirPath, "activitylog.sqlite.db")}"); } diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 6d0e251ce..3562074fe 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -709,7 +709,7 @@ namespace Emby.Server.Implementations } } - public void Init() + public async Task Init() { HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber; HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber; @@ -739,7 +739,7 @@ namespace Emby.Server.Implementations SetHttpLimit(); - RegisterResources(); + await RegisterResources(); FindParts(); } @@ -754,7 +754,7 @@ namespace Emby.Server.Implementations /// /// Registers resources that classes will depend on /// - protected void RegisterResources() + protected async Task RegisterResources() { RegisterSingleInstance(ConfigurationManager); RegisterSingleInstance(this); @@ -931,7 +931,7 @@ namespace Emby.Server.Implementations EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager); RegisterSingleInstance(EncodingManager); - var activityLogRepo = GetActivityLogRepository(); + var activityLogRepo = await GetActivityLogRepository(); RegisterSingleInstance(activityLogRepo); RegisterSingleInstance(new ActivityManager(LoggerFactory, activityLogRepo, UserManager)); @@ -1146,9 +1146,13 @@ namespace Emby.Server.Implementations return repo; } - private IActivityRepository GetActivityLogRepository() + private async Task GetActivityLogRepository() { - return new ActivityRepository(ServerConfigurationManager.ApplicationPaths.DataPath); + var repo = new ActivityRepository(ServerConfigurationManager.ApplicationPaths.DataPath); + + await repo.Database.EnsureCreatedAsync(); + + return repo; } /// diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 0510548b5..bdf8c4e94 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -99,7 +99,7 @@ namespace Jellyfin.Server new SystemEvents(), new NetworkManager(_loggerFactory, environmentInfo))) { - appHost.Init(); + await appHost.Init(); appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager); @@ -108,7 +108,6 @@ namespace Jellyfin.Server await appHost.RunStartupTasks(); // TODO: read input for a stop command - try { // Block main thread until shutdown @@ -167,7 +166,6 @@ namespace Jellyfin.Server { Directory.CreateDirectory(programDataPath); } - string configDir = Environment.GetEnvironmentVariable("JELLYFIN_CONFIG_DIR"); if (string.IsNullOrEmpty(configDir)) { diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs index 385127c54..f32eec6ce 100644 --- a/MediaBrowser.Common/IApplicationHost.cs +++ b/MediaBrowser.Common/IApplicationHost.cs @@ -131,7 +131,7 @@ namespace MediaBrowser.Common /// /// Inits this instance. /// - void Init(); + Task Init(); /// /// Creates the instance. -- cgit v1.2.3 From 3cd31cadf891fb4aad7ca8d8594bf27423724eb8 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 16 Jan 2019 15:32:51 +0100 Subject: No need to check if the dir exists --- Emby.Server.Implementations/Activity/ActivityRepository.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'Emby.Server.Implementations/Activity/ActivityRepository.cs') diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index fb5f8d6ef..af0b20d92 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -20,10 +20,7 @@ namespace Emby.Server.Implementations.Activity protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // Ensure the dir exists - if (!Directory.Exists(_dataDirPath)) - { - Directory.CreateDirectory(_dataDirPath); - } + Directory.CreateDirectory(_dataDirPath); optionsBuilder.UseSqlite($"Filename={Path.Combine(_dataDirPath, "activitylog.sqlite.db")}"); } -- cgit v1.2.3