aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Activity/ActivityRepository.cs
diff options
context:
space:
mode:
authorErwin de Haan <EraYaN@users.noreply.github.com>2019-01-25 21:33:58 +0100
committerBond-009 <bond.009@outlook.com>2019-01-25 23:32:06 +0100
commitd1a0497f55c7f41fe9f01bbed328967e381fd394 (patch)
treec67c1d3da5af32beac90e8480cf3f8827d042a39 /Emby.Server.Implementations/Activity/ActivityRepository.cs
parente0315b569591b71938829a8f35ac264399ef66bd (diff)
Revert "Merge pull request #452 from Bond-009/activitydb"
This reverts commit 48ad18d12baeeb42ec0ec7df9473330dcbc76754, reversing changes made to fe197415cac19c0e4005c52761c5e7a37b8a4557.
Diffstat (limited to 'Emby.Server.Implementations/Activity/ActivityRepository.cs')
-rw-r--r--Emby.Server.Implementations/Activity/ActivityRepository.cs305
1 files changed, 289 insertions, 16 deletions
diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs
index af0b20d92..aeed8b6f1 100644
--- a/Emby.Server.Implementations/Activity/ActivityRepository.cs
+++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs
@@ -1,37 +1,310 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
-using System.Threading.Tasks;
+using Emby.Server.Implementations.Data;
+using MediaBrowser.Controller;
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
{
- 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;
+ }
}
}