فهرست منبع

Revert "Merge pull request #452 from Bond-009/activitydb"

This reverts commit 48ad18d12baeeb42ec0ec7df9473330dcbc76754, reversing
changes made to fe197415cac19c0e4005c52761c5e7a37b8a4557.
Erwin de Haan 6 سال پیش
والد
کامیت
d1a0497f55

+ 46 - 47
Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs

@@ -2,7 +2,6 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
-using System.Threading.Tasks;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Plugins;
 using MediaBrowser.Common.Plugins;
 using MediaBrowser.Common.Updates;
 using MediaBrowser.Common.Updates;
@@ -93,18 +92,18 @@ namespace Emby.Server.Implementations.Activity
             _appHost.ApplicationUpdated += _appHost_ApplicationUpdated;
             _appHost.ApplicationUpdated += _appHost_ApplicationUpdated;
         }
         }
 
 
-        async void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e)
+        void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("CameraImageUploadedFrom"), e.Argument.Device.Name),
                 Name = string.Format(_localization.GetLocalizedString("CameraImageUploadedFrom"), e.Argument.Device.Name),
                 Type = NotificationType.CameraImageUploaded.ToString()
                 Type = NotificationType.CameraImageUploaded.ToString()
             });
             });
         }
         }
 
 
-        async void _userManager_UserLockedOut(object sender, GenericEventArgs<User> e)
+        void _userManager_UserLockedOut(object sender, GenericEventArgs<User> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("UserLockedOutWithName"), e.Argument.Name),
                 Name = string.Format(_localization.GetLocalizedString("UserLockedOutWithName"), e.Argument.Name),
                 Type = NotificationType.UserLockedOut.ToString(),
                 Type = NotificationType.UserLockedOut.ToString(),
@@ -112,9 +111,9 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _subManager_SubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e)
+        void _subManager_SubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"), e.Provider, Notifications.Notifications.GetItemName(e.Item)),
                 Name = string.Format(_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"), e.Provider, Notifications.Notifications.GetItemName(e.Item)),
                 Type = "SubtitleDownloadFailure",
                 Type = "SubtitleDownloadFailure",
@@ -123,7 +122,7 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e)
+        void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e)
         {
         {
             var item = e.MediaInfo;
             var item = e.MediaInfo;
 
 
@@ -146,7 +145,7 @@ namespace Emby.Server.Implementations.Activity
 
 
             var user = e.Users.First();
             var user = e.Users.First();
 
 
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
                 Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
                 Type = GetPlaybackStoppedNotificationType(item.MediaType),
                 Type = GetPlaybackStoppedNotificationType(item.MediaType),
@@ -154,7 +153,7 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e)
+        void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e)
         {
         {
             var item = e.MediaInfo;
             var item = e.MediaInfo;
 
 
@@ -177,7 +176,7 @@ namespace Emby.Server.Implementations.Activity
 
 
             var user = e.Users.First();
             var user = e.Users.First();
 
 
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
                 Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
                 Type = GetPlaybackNotificationType(item.MediaType),
                 Type = GetPlaybackNotificationType(item.MediaType),
@@ -238,7 +237,7 @@ namespace Emby.Server.Implementations.Activity
             return null;
             return null;
         }
         }
 
 
-        async void _sessionManager_SessionEnded(object sender, SessionEventArgs e)
+        void _sessionManager_SessionEnded(object sender, SessionEventArgs e)
         {
         {
             string name;
             string name;
             var session = e.SessionInfo;
             var session = e.SessionInfo;
@@ -255,7 +254,7 @@ namespace Emby.Server.Implementations.Activity
                 name = string.Format(_localization.GetLocalizedString("UserOfflineFromDevice"), session.UserName, session.DeviceName);
                 name = string.Format(_localization.GetLocalizedString("UserOfflineFromDevice"), session.UserName, session.DeviceName);
             }
             }
 
 
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = name,
                 Name = name,
                 Type = "SessionEnded",
                 Type = "SessionEnded",
@@ -264,11 +263,11 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _sessionManager_AuthenticationSucceeded(object sender, GenericEventArgs<AuthenticationResult> e)
+        void _sessionManager_AuthenticationSucceeded(object sender, GenericEventArgs<AuthenticationResult> e)
         {
         {
             var user = e.Argument.User;
             var user = e.Argument.User;
 
 
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("AuthenticationSucceededWithUserName"), user.Name),
                 Name = string.Format(_localization.GetLocalizedString("AuthenticationSucceededWithUserName"), user.Name),
                 Type = "AuthenticationSucceeded",
                 Type = "AuthenticationSucceeded",
@@ -277,9 +276,9 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _sessionManager_AuthenticationFailed(object sender, GenericEventArgs<AuthenticationRequest> e)
+        void _sessionManager_AuthenticationFailed(object sender, GenericEventArgs<AuthenticationRequest> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username),
                 Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username),
                 Type = "AuthenticationFailed",
                 Type = "AuthenticationFailed",
@@ -288,9 +287,9 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _appHost_ApplicationUpdated(object sender, GenericEventArgs<PackageVersionInfo> e)
+        void _appHost_ApplicationUpdated(object sender, GenericEventArgs<PackageVersionInfo> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("MessageApplicationUpdatedTo"), e.Argument.versionStr),
                 Name = string.Format(_localization.GetLocalizedString("MessageApplicationUpdatedTo"), e.Argument.versionStr),
                 Type = NotificationType.ApplicationUpdateInstalled.ToString(),
                 Type = NotificationType.ApplicationUpdateInstalled.ToString(),
@@ -298,27 +297,27 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
+        void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("MessageNamedServerConfigurationUpdatedWithValue"), e.Key),
                 Name = string.Format(_localization.GetLocalizedString("MessageNamedServerConfigurationUpdatedWithValue"), e.Key),
                 Type = "NamedConfigurationUpdated"
                 Type = "NamedConfigurationUpdated"
             });
             });
         }
         }
 
 
-        async void _config_ConfigurationUpdated(object sender, EventArgs e)
+        void _config_ConfigurationUpdated(object sender, EventArgs e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = _localization.GetLocalizedString("MessageServerConfigurationUpdated"),
                 Name = _localization.GetLocalizedString("MessageServerConfigurationUpdated"),
                 Type = "ServerConfigurationUpdated"
                 Type = "ServerConfigurationUpdated"
             });
             });
         }
         }
 
 
-        async void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e)
+        void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("UserPolicyUpdatedWithName"), e.Argument.Name),
                 Name = string.Format(_localization.GetLocalizedString("UserPolicyUpdatedWithName"), e.Argument.Name),
                 Type = "UserPolicyUpdated",
                 Type = "UserPolicyUpdated",
@@ -326,18 +325,18 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _userManager_UserDeleted(object sender, GenericEventArgs<User> e)
+        void _userManager_UserDeleted(object sender, GenericEventArgs<User> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("UserDeletedWithName"), e.Argument.Name),
                 Name = string.Format(_localization.GetLocalizedString("UserDeletedWithName"), e.Argument.Name),
                 Type = "UserDeleted"
                 Type = "UserDeleted"
             });
             });
         }
         }
 
 
-        async void _userManager_UserPasswordChanged(object sender, GenericEventArgs<User> e)
+        void _userManager_UserPasswordChanged(object sender, GenericEventArgs<User> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("UserPasswordChangedWithName"), e.Argument.Name),
                 Name = string.Format(_localization.GetLocalizedString("UserPasswordChangedWithName"), e.Argument.Name),
                 Type = "UserPasswordChanged",
                 Type = "UserPasswordChanged",
@@ -345,9 +344,9 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _userManager_UserCreated(object sender, GenericEventArgs<User> e)
+        void _userManager_UserCreated(object sender, GenericEventArgs<User> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("UserCreatedWithName"), e.Argument.Name),
                 Name = string.Format(_localization.GetLocalizedString("UserCreatedWithName"), e.Argument.Name),
                 Type = "UserCreated",
                 Type = "UserCreated",
@@ -355,9 +354,9 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _subManager_SubtitlesDownloaded(object sender, SubtitleDownloadEventArgs e)
+        void _subManager_SubtitlesDownloaded(object sender, SubtitleDownloadEventArgs e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("SubtitlesDownloadedForItem"), Notifications.Notifications.GetItemName(e.Item)),
                 Name = string.Format(_localization.GetLocalizedString("SubtitlesDownloadedForItem"), Notifications.Notifications.GetItemName(e.Item)),
                 Type = "SubtitlesDownloaded",
                 Type = "SubtitlesDownloaded",
@@ -366,7 +365,7 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _sessionManager_SessionStarted(object sender, SessionEventArgs e)
+        void _sessionManager_SessionStarted(object sender, SessionEventArgs e)
         {
         {
             string name;
             string name;
             var session = e.SessionInfo;
             var session = e.SessionInfo;
@@ -383,7 +382,7 @@ namespace Emby.Server.Implementations.Activity
                 name = string.Format(_localization.GetLocalizedString("UserOnlineFromDevice"), session.UserName, session.DeviceName);
                 name = string.Format(_localization.GetLocalizedString("UserOnlineFromDevice"), session.UserName, session.DeviceName);
             }
             }
 
 
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = name,
                 Name = name,
                 Type = "SessionStarted",
                 Type = "SessionStarted",
@@ -392,9 +391,9 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _installationManager_PluginUpdated(object sender, GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>> e)
+        void _installationManager_PluginUpdated(object sender, GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("PluginUpdatedWithName"), e.Argument.Item1.Name),
                 Name = string.Format(_localization.GetLocalizedString("PluginUpdatedWithName"), e.Argument.Item1.Name),
                 Type = NotificationType.PluginUpdateInstalled.ToString(),
                 Type = NotificationType.PluginUpdateInstalled.ToString(),
@@ -403,18 +402,18 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _installationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
+        void _installationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("PluginUninstalledWithName"), e.Argument.Name),
                 Name = string.Format(_localization.GetLocalizedString("PluginUninstalledWithName"), e.Argument.Name),
                 Type = NotificationType.PluginUninstalled.ToString()
                 Type = NotificationType.PluginUninstalled.ToString()
             });
             });
         }
         }
 
 
-        async void _installationManager_PluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> e)
+        void _installationManager_PluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> e)
         {
         {
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("PluginInstalledWithName"), e.Argument.name),
                 Name = string.Format(_localization.GetLocalizedString("PluginInstalledWithName"), e.Argument.name),
                 Type = NotificationType.PluginInstalled.ToString(),
                 Type = NotificationType.PluginInstalled.ToString(),
@@ -422,11 +421,11 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e)
+        void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e)
         {
         {
             var installationInfo = e.InstallationInfo;
             var installationInfo = e.InstallationInfo;
 
 
-            await CreateLogEntry(new ActivityLogEntry
+            CreateLogEntry(new ActivityLogEntry
             {
             {
                 Name = string.Format(_localization.GetLocalizedString("NameInstallFailed"), installationInfo.Name),
                 Name = string.Format(_localization.GetLocalizedString("NameInstallFailed"), installationInfo.Name),
                 Type = NotificationType.InstallationFailed.ToString(),
                 Type = NotificationType.InstallationFailed.ToString(),
@@ -435,7 +434,7 @@ namespace Emby.Server.Implementations.Activity
             });
             });
         }
         }
 
 
-        async void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e)
+        void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e)
         {
         {
             var result = e.Result;
             var result = e.Result;
             var task = e.Task;
             var task = e.Task;
@@ -462,7 +461,7 @@ namespace Emby.Server.Implementations.Activity
                     vals.Add(e.Result.LongErrorMessage);
                     vals.Add(e.Result.LongErrorMessage);
                 }
                 }
 
 
-                await CreateLogEntry(new ActivityLogEntry
+                CreateLogEntry(new ActivityLogEntry
                 {
                 {
                     Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
                     Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
                     Type = NotificationType.TaskFailed.ToString(),
                     Type = NotificationType.TaskFailed.ToString(),
@@ -473,11 +472,11 @@ namespace Emby.Server.Implementations.Activity
             }
             }
         }
         }
 
 
-        private async Task CreateLogEntry(ActivityLogEntry entry)
+        private void CreateLogEntry(ActivityLogEntry entry)
         {
         {
             try
             try
             {
             {
-                await _activityManager.CreateAsync(entry);
+                _activityManager.Create(entry);
             }
             }
             catch
             catch
             {
             {

+ 12 - 26
Emby.Server.Implementations/Activity/ActivityManager.cs

@@ -1,10 +1,9 @@
 using System;
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
-using System.Threading.Tasks;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Model.Events;
 using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Querying;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 
 
 namespace Emby.Server.Implementations.Activity
 namespace Emby.Server.Implementations.Activity
@@ -27,38 +26,20 @@ namespace Emby.Server.Implementations.Activity
             _userManager = userManager;
             _userManager = userManager;
         }
         }
 
 
-        public async Task CreateAsync(ActivityLogEntry entry)
+        public void Create(ActivityLogEntry entry)
         {
         {
             entry.Date = DateTime.UtcNow;
             entry.Date = DateTime.UtcNow;
 
 
-            await _repo.CreateAsync(entry);
+            _repo.Create(entry);
 
 
             EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(entry));
             EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(entry));
         }
         }
 
 
-        public IEnumerable<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
+        public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
         {
         {
-            var result = _repo.GetActivityLogEntries();
+            var result = _repo.GetActivityLogEntries(minDate, hasUserId, startIndex, limit);
 
 
-            if (minDate.HasValue)
-            {
-                result = result.Where(x => x.Date >= minDate.Value);
-            }
-            if (hasUserId.HasValue)
-            {
-                result = result.Where(x => x.UserId != null && x.UserId != Guid.Empty);
-            }
-            if (startIndex.HasValue)
-            {
-                result = result.Where(x => x.Id >= startIndex.Value);
-            }
-            if (limit.HasValue)
-            {
-                result = result.Take(limit.Value);
-            }
-
-            // Add images for each user
-            foreach (var item in result)
+            foreach (var item in result.Items.Where(i => !i.UserId.Equals(Guid.Empty)))
             {
             {
                 var user = _userManager.GetUserById(item.UserId);
                 var user = _userManager.GetUserById(item.UserId);
 
 
@@ -69,7 +50,12 @@ namespace Emby.Server.Implementations.Activity
                 }
                 }
             }
             }
 
 
-            return result.AsEnumerable();
+            return result;
+        }
+
+        public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit)
+        {
+            return GetActivityLogEntries(minDate, null, startIndex, limit);
         }
         }
     }
     }
 }
 }

+ 289 - 16
Emby.Server.Implementations/Activity/ActivityRepository.cs

@@ -1,37 +1,310 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
-using System.Threading.Tasks;
+using Emby.Server.Implementations.Data;
+using MediaBrowser.Controller;
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Model.Activity;
-using Microsoft.EntityFrameworkCore;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Querying;
+using Microsoft.Extensions.Logging;
+using SQLitePCL.pretty;
 
 
 namespace Emby.Server.Implementations.Activity
 namespace Emby.Server.Implementations.Activity
 {
 {
-    public class ActivityRepository : DbContext, IActivityRepository
+    public class ActivityRepository : BaseSqliteRepository, IActivityRepository
     {
     {
-        protected string _dataDirPath;
+        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+        protected IFileSystem FileSystem { get; private set; }
 
 
-        public DbSet<ActivityLogEntry> ActivityLogs { get; set; }
+        public ActivityRepository(ILoggerFactory loggerFactory, IServerApplicationPaths appPaths, IFileSystem fileSystem)
+            : base(loggerFactory.CreateLogger(nameof(ActivityRepository)))
+        {
+            DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db");
+            FileSystem = fileSystem;
+        }
 
 
-        public ActivityRepository(string dataDirPath)
+        public void Initialize()
         {
         {
-            _dataDirPath = dataDirPath;
+            try
+            {
+                InitializeInternal();
+            }
+            catch (Exception ex)
+            {
+                Logger.LogError(ex, "Error loading database file. Will reset and retry.");
+
+                FileSystem.DeleteFile(DbFilePath);
+
+                InitializeInternal();
+            }
         }
         }
 
 
-        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+        private void InitializeInternal()
         {
         {
-            // Ensure the dir exists
-            Directory.CreateDirectory(_dataDirPath);
+            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);
+            }
+        }
 
 
-            optionsBuilder.UseSqlite($"Filename={Path.Combine(_dataDirPath, "activitylog.sqlite.db")}");
+        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");
+            }
         }
         }
 
 
-        public async Task CreateAsync(ActivityLogEntry entry)
+        private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
+
+        public void Create(ActivityLogEntry entry)
         {
         {
-            await ActivityLogs.AddAsync(entry);
-            await SaveChangesAsync();
+            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<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
+        {
+            using (WriteLock.Read())
+            using (var connection = CreateConnection(true))
+            {
+                var commandText = BaseActivitySelectText;
+                var whereClauses = new List<string>();
+
+                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<string>();
+                statementTexts.Add(commandText);
+                statementTexts.Add("select count (Id) from ActivityLog" + whereTextWithoutPaging);
+
+                return connection.RunInTransaction(db =>
+                {
+                    var list = new List<ActivityLogEntry>();
+                    var result = new QueryResult<ActivityLogEntry>();
+
+                    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);
+            }
         }
         }
 
 
-        public IQueryable<ActivityLogEntry> GetActivityLogEntries()
-            => ActivityLogs;
+        private static ActivityLogEntry GetEntry(IReadOnlyList<IResultSetValue> 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;
+        }
     }
     }
 }
 }

+ 7 - 7
Emby.Server.Implementations/ApplicationHost.cs

@@ -709,7 +709,7 @@ namespace Emby.Server.Implementations
             }
             }
         }
         }
 
 
-        public async Task InitAsync()
+        public void Init()
         {
         {
             HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
             HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
             HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
             HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
@@ -739,7 +739,7 @@ namespace Emby.Server.Implementations
 
 
             SetHttpLimit();
             SetHttpLimit();
 
 
-            await RegisterResourcesAsync();
+            RegisterResources();
 
 
             FindParts();
             FindParts();
         }
         }
@@ -754,7 +754,7 @@ namespace Emby.Server.Implementations
         /// <summary>
         /// <summary>
         /// Registers resources that classes will depend on
         /// Registers resources that classes will depend on
         /// </summary>
         /// </summary>
-        protected async Task RegisterResourcesAsync()
+        protected void RegisterResources()
         {
         {
             RegisterSingleInstance(ConfigurationManager);
             RegisterSingleInstance(ConfigurationManager);
             RegisterSingleInstance<IApplicationHost>(this);
             RegisterSingleInstance<IApplicationHost>(this);
@@ -931,7 +931,7 @@ namespace Emby.Server.Implementations
             EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
             EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
             RegisterSingleInstance(EncodingManager);
             RegisterSingleInstance(EncodingManager);
 
 
-            var activityLogRepo = await GetActivityLogRepositoryAsync();
+            var activityLogRepo = GetActivityLogRepository();
             RegisterSingleInstance(activityLogRepo);
             RegisterSingleInstance(activityLogRepo);
             RegisterSingleInstance<IActivityManager>(new ActivityManager(LoggerFactory, activityLogRepo, UserManager));
             RegisterSingleInstance<IActivityManager>(new ActivityManager(LoggerFactory, activityLogRepo, UserManager));
 
 
@@ -1146,11 +1146,11 @@ namespace Emby.Server.Implementations
             return repo;
             return repo;
         }
         }
 
 
-        private async Task<IActivityRepository> GetActivityLogRepositoryAsync()
+        private IActivityRepository GetActivityLogRepository()
         {
         {
-            var repo = new ActivityRepository(ServerConfigurationManager.ApplicationPaths.DataPath);
+            var repo = new ActivityRepository(LoggerFactory, ServerConfigurationManager.ApplicationPaths, FileSystemManager);
 
 
-            await repo.Database.EnsureCreatedAsync();
+            repo.Initialize();
 
 
             return repo;
             return repo;
         }
         }

+ 0 - 1
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -22,7 +22,6 @@
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.0" />
     <PackageReference Include="ServiceStack.Text.Core" Version="5.4.0" />
     <PackageReference Include="ServiceStack.Text.Core" Version="5.4.0" />
     <PackageReference Include="sharpcompress" Version="0.22.0" />
     <PackageReference Include="sharpcompress" Version="0.22.0" />
     <PackageReference Include="SimpleInjector" Version="4.4.2" />
     <PackageReference Include="SimpleInjector" Version="4.4.2" />

+ 3 - 1
Jellyfin.Server/Program.cs

@@ -99,7 +99,7 @@ namespace Jellyfin.Server
                 new SystemEvents(),
                 new SystemEvents(),
                 new NetworkManager(_loggerFactory, environmentInfo)))
                 new NetworkManager(_loggerFactory, environmentInfo)))
             {
             {
-                await appHost.InitAsync();
+                appHost.Init();
 
 
                 appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);
                 appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);
 
 
@@ -108,6 +108,7 @@ namespace Jellyfin.Server
                 await appHost.RunStartupTasks();
                 await appHost.RunStartupTasks();
 
 
                 // TODO: read input for a stop command
                 // TODO: read input for a stop command
+
                 try
                 try
                 {
                 {
                     // Block main thread until shutdown
                     // Block main thread until shutdown
@@ -166,6 +167,7 @@ namespace Jellyfin.Server
             {
             {
                 Directory.CreateDirectory(programDataPath);
                 Directory.CreateDirectory(programDataPath);
             }
             }
+
             string configDir = Environment.GetEnvironmentVariable("JELLYFIN_CONFIG_DIR");
             string configDir = Environment.GetEnvironmentVariable("JELLYFIN_CONFIG_DIR");
             if (string.IsNullOrEmpty(configDir))
             if (string.IsNullOrEmpty(configDir))
             {
             {

+ 1 - 1
MediaBrowser.Api/Library/LibraryService.cs

@@ -839,7 +839,7 @@ namespace MediaBrowser.Api.Library
         {
         {
             try
             try
             {
             {
-                _activityManager.CreateAsync(new ActivityLogEntry
+                _activityManager.Create(new ActivityLogEntry
                 {
                 {
                     Name = string.Format(_localization.GetLocalizedString("UserDownloadingItemWithValues"), user.Name, item.Name),
                     Name = string.Format(_localization.GetLocalizedString("UserDownloadingItemWithValues"), user.Name, item.Name),
                     Type = "UserDownloadingContent",
                     Type = "UserDownloadingContent",

+ 1 - 1
MediaBrowser.Common/IApplicationHost.cs

@@ -131,7 +131,7 @@ namespace MediaBrowser.Common
         /// <summary>
         /// <summary>
         /// Inits this instance.
         /// Inits this instance.
         /// </summary>
         /// </summary>
-        Task InitAsync();
+        void Init();
 
 
         /// <summary>
         /// <summary>
         /// Creates the instance.
         /// Creates the instance.

+ 5 - 4
MediaBrowser.Model/Activity/IActivityManager.cs

@@ -1,7 +1,6 @@
 using System;
 using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
 using MediaBrowser.Model.Events;
 using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Querying;
 
 
 namespace MediaBrowser.Model.Activity
 namespace MediaBrowser.Model.Activity
 {
 {
@@ -9,8 +8,10 @@ namespace MediaBrowser.Model.Activity
     {
     {
         event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
         event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
 
 
-        Task CreateAsync(ActivityLogEntry entry);
+        void Create(ActivityLogEntry entry);
 
 
-        IEnumerable<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? x, int? y);
+        QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit);
+
+        QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? x, int? y);
     }
     }
 }
 }

+ 4 - 4
MediaBrowser.Model/Activity/IActivityRepository.cs

@@ -1,12 +1,12 @@
-using System.Linq;
-using System.Threading.Tasks;
+using System;
+using MediaBrowser.Model.Querying;
 
 
 namespace MediaBrowser.Model.Activity
 namespace MediaBrowser.Model.Activity
 {
 {
     public interface IActivityRepository
     public interface IActivityRepository
     {
     {
-        Task CreateAsync(ActivityLogEntry entry);
+        void Create(ActivityLogEntry entry);
 
 
-        IQueryable<ActivityLogEntry> GetActivityLogEntries();
+        QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? z, int? startIndex, int? limit);
     }
     }
 }
 }