Merge remote-tracking branch 'upstream/master' into random

This commit is contained in:
Bond-009
2019-12-06 12:06:13 +01:00
339 changed files with 4276 additions and 4900 deletions

View File

@@ -110,8 +110,8 @@ namespace Emby.Server.Implementations.Data
using (var statement = connection.PrepareStatement("replace into userdisplaypreferences (id, userid, client, data) values (@id, @userId, @client, @data)"))
{
statement.TryBind("@id", displayPreferences.Id.ToGuidBlob());
statement.TryBind("@userId", userId.ToGuidBlob());
statement.TryBind("@id", new Guid(displayPreferences.Id).ToByteArray());
statement.TryBind("@userId", userId.ToByteArray());
statement.TryBind("@client", client);
statement.TryBind("@data", serialized);
@@ -170,8 +170,8 @@ namespace Emby.Server.Implementations.Data
{
using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where id = @id and userId=@userId and client=@client"))
{
statement.TryBind("@id", guidId.ToGuidBlob());
statement.TryBind("@userId", userId.ToGuidBlob());
statement.TryBind("@id", guidId.ToByteArray());
statement.TryBind("@userId", userId.ToByteArray());
statement.TryBind("@client", client);
foreach (var row in statement.ExecuteQuery())
@@ -200,7 +200,7 @@ namespace Emby.Server.Implementations.Data
using (var connection = GetConnection(true))
using (var statement = connection.PrepareStatement("select data from userdisplaypreferences where userId=@userId"))
{
statement.TryBind("@userId", userId.ToGuidBlob());
statement.TryBind("@userId", userId.ToByteArray());
foreach (var row in statement.ExecuteQuery())
{

View File

@@ -9,6 +9,47 @@ namespace Emby.Server.Implementations.Data
{
public static class SqliteExtensions
{
private const string DatetimeFormatUtc = "yyyy-MM-dd HH:mm:ss.FFFFFFFK";
private const string DatetimeFormatLocal = "yyyy-MM-dd HH:mm:ss.FFFFFFF";
/// <summary>
/// An array of ISO-8601 DateTime formats that we support parsing.
/// </summary>
private static readonly string[] _datetimeFormats = new string[]
{
"THHmmssK",
"THHmmK",
"HH:mm:ss.FFFFFFFK",
"HH:mm:ssK",
"HH:mmK",
DatetimeFormatUtc,
"yyyy-MM-dd HH:mm:ssK",
"yyyy-MM-dd HH:mmK",
"yyyy-MM-ddTHH:mm:ss.FFFFFFFK",
"yyyy-MM-ddTHH:mmK",
"yyyy-MM-ddTHH:mm:ssK",
"yyyyMMddHHmmssK",
"yyyyMMddHHmmK",
"yyyyMMddTHHmmssFFFFFFFK",
"THHmmss",
"THHmm",
"HH:mm:ss.FFFFFFF",
"HH:mm:ss",
"HH:mm",
DatetimeFormatLocal,
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd HH:mm",
"yyyy-MM-ddTHH:mm:ss.FFFFFFF",
"yyyy-MM-ddTHH:mm",
"yyyy-MM-ddTHH:mm:ss",
"yyyyMMddHHmmss",
"yyyyMMddHHmm",
"yyyyMMddTHHmmssFFFFFFF",
"yyyy-MM-dd",
"yyyyMMdd",
"yy-MM-dd"
};
public static void RunQueries(this SQLiteDatabaseConnection connection, string[] queries)
{
if (queries == null)
@@ -22,16 +63,6 @@ namespace Emby.Server.Implementations.Data
});
}
public static byte[] ToGuidBlob(this string str)
{
return ToGuidBlob(new Guid(str));
}
public static byte[] ToGuidBlob(this Guid guid)
{
return guid.ToByteArray();
}
public static Guid ReadGuidFromBlob(this IResultSetValue result)
{
return new Guid(result.ToBlob());
@@ -50,58 +81,16 @@ namespace Emby.Server.Implementations.Data
CultureInfo.InvariantCulture);
}
private static string GetDateTimeKindFormat(
DateTimeKind kind)
{
return (kind == DateTimeKind.Utc) ? _datetimeFormatUtc : _datetimeFormatLocal;
}
/// <summary>
/// An array of ISO-8601 DateTime formats that we support parsing.
/// </summary>
private static string[] _datetimeFormats = new string[] {
"THHmmssK",
"THHmmK",
"HH:mm:ss.FFFFFFFK",
"HH:mm:ssK",
"HH:mmK",
"yyyy-MM-dd HH:mm:ss.FFFFFFFK", /* NOTE: UTC default (5). */
"yyyy-MM-dd HH:mm:ssK",
"yyyy-MM-dd HH:mmK",
"yyyy-MM-ddTHH:mm:ss.FFFFFFFK",
"yyyy-MM-ddTHH:mmK",
"yyyy-MM-ddTHH:mm:ssK",
"yyyyMMddHHmmssK",
"yyyyMMddHHmmK",
"yyyyMMddTHHmmssFFFFFFFK",
"THHmmss",
"THHmm",
"HH:mm:ss.FFFFFFF",
"HH:mm:ss",
"HH:mm",
"yyyy-MM-dd HH:mm:ss.FFFFFFF", /* NOTE: Non-UTC default (19). */
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd HH:mm",
"yyyy-MM-ddTHH:mm:ss.FFFFFFF",
"yyyy-MM-ddTHH:mm",
"yyyy-MM-ddTHH:mm:ss",
"yyyyMMddHHmmss",
"yyyyMMddHHmm",
"yyyyMMddTHHmmssFFFFFFF",
"yyyy-MM-dd",
"yyyyMMdd",
"yy-MM-dd"
};
private static string _datetimeFormatUtc = _datetimeFormats[5];
private static string _datetimeFormatLocal = _datetimeFormats[19];
private static string GetDateTimeKindFormat(DateTimeKind kind)
=> (kind == DateTimeKind.Utc) ? DatetimeFormatUtc : DatetimeFormatLocal;
public static DateTime ReadDateTime(this IResultSetValue result)
{
var dateText = result.ToString();
return DateTime.ParseExact(
dateText, _datetimeFormats,
dateText,
_datetimeFormats,
DateTimeFormatInfo.InvariantInfo,
DateTimeStyles.None).ToUniversalTime();
}
@@ -139,7 +128,10 @@ namespace Emby.Server.Implementations.Data
public static void Attach(SQLiteDatabaseConnection db, string path, string alias)
{
var commandText = string.Format("attach @path as {0};", alias);
var commandText = string.Format(
CultureInfo.InvariantCulture,
"attach @path as {0};",
alias);
using (var statement = db.PrepareStatement(commandText))
{
@@ -186,10 +178,7 @@ namespace Emby.Server.Implementations.Data
private static void CheckName(string name)
{
#if DEBUG
//if (!name.IndexOf("@", StringComparison.OrdinalIgnoreCase) != 0)
{
throw new Exception("Invalid param name: " + name);
}
throw new ArgumentException("Invalid param name: " + name, nameof(name));
#endif
}
@@ -264,7 +253,7 @@ namespace Emby.Server.Implementations.Data
{
if (statement.BindParameters.TryGetValue(name, out IBindParameter bindParam))
{
bindParam.Bind(value.ToGuidBlob());
bindParam.Bind(value.ToByteArray());
}
else
{
@@ -392,8 +381,7 @@ namespace Emby.Server.Implementations.Data
}
}
public static IEnumerable<IReadOnlyList<IResultSetValue>> ExecuteQuery(
this IStatement This)
public static IEnumerable<IReadOnlyList<IResultSetValue>> ExecuteQuery(this IStatement This)
{
while (This.MoveNext())
{

View File

@@ -27,7 +27,6 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
using SQLitePCL.pretty;
@@ -548,7 +547,7 @@ namespace Emby.Server.Implementations.Data
{
using (var saveImagesStatement = base.PrepareStatement(db, "Update TypedBaseItems set Images=@Images where guid=@Id"))
{
saveImagesStatement.TryBind("@Id", item.Id.ToGuidBlob());
saveImagesStatement.TryBind("@Id", item.Id.ToByteArray());
saveImagesStatement.TryBind("@Images", SerializeImages(item));
saveImagesStatement.MoveNext();
@@ -658,12 +657,14 @@ namespace Emby.Server.Implementations.Data
private void SaveItem(BaseItem item, BaseItem topParent, string userDataKey, IStatement saveItemStatement)
{
saveItemStatement.TryBind("@guid", item.Id);
saveItemStatement.TryBind("@type", item.GetType().FullName);
Type type = item.GetType();
if (TypeRequiresDeserialization(item.GetType()))
saveItemStatement.TryBind("@guid", item.Id);
saveItemStatement.TryBind("@type", type.FullName);
if (TypeRequiresDeserialization(type))
{
saveItemStatement.TryBind("@data", JsonSerializer.SerializeToUtf8Bytes(item, _jsonOptions));
saveItemStatement.TryBind("@data", JsonSerializer.SerializeToUtf8Bytes(item, type, _jsonOptions));
}
else
{
@@ -1177,7 +1178,7 @@ namespace Emby.Server.Implementations.Data
{
if (id == Guid.Empty)
{
throw new ArgumentException(nameof(id), "Guid can't be empty");
throw new ArgumentException("Guid can't be empty", nameof(id));
}
CheckDisposed();
@@ -1988,7 +1989,7 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException(nameof(chapters));
}
var idBlob = id.ToGuidBlob();
var idBlob = id.ToByteArray();
using (var connection = GetConnection())
{
@@ -3760,7 +3761,7 @@ namespace Emby.Server.Implementations.Data
if (statement != null)
{
statement.TryBind(paramName, personId.ToGuidBlob());
statement.TryBind(paramName, personId.ToByteArray());
}
index++;
}
@@ -3971,7 +3972,7 @@ namespace Emby.Server.Implementations.Data
clauses.Add("(guid in (select itemid from itemvalues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type<=1))");
if (statement != null)
{
statement.TryBind(paramName, artistId.ToGuidBlob());
statement.TryBind(paramName, artistId.ToByteArray());
}
index++;
}
@@ -3990,7 +3991,7 @@ namespace Emby.Server.Implementations.Data
clauses.Add("(guid in (select itemid from itemvalues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type=1))");
if (statement != null)
{
statement.TryBind(paramName, artistId.ToGuidBlob());
statement.TryBind(paramName, artistId.ToByteArray());
}
index++;
}
@@ -4009,7 +4010,7 @@ namespace Emby.Server.Implementations.Data
clauses.Add("((select CleanName from TypedBaseItems where guid=" + paramName + ") in (select CleanValue from itemvalues where ItemId=Guid and Type=0) AND (select CleanName from TypedBaseItems where guid=" + paramName + ") not in (select CleanValue from itemvalues where ItemId=Guid and Type=1))");
if (statement != null)
{
statement.TryBind(paramName, artistId.ToGuidBlob());
statement.TryBind(paramName, artistId.ToByteArray());
}
index++;
}
@@ -4028,7 +4029,7 @@ namespace Emby.Server.Implementations.Data
clauses.Add("Album in (select Name from typedbaseitems where guid=" + paramName + ")");
if (statement != null)
{
statement.TryBind(paramName, albumId.ToGuidBlob());
statement.TryBind(paramName, albumId.ToByteArray());
}
index++;
}
@@ -4047,7 +4048,7 @@ namespace Emby.Server.Implementations.Data
clauses.Add("(guid not in (select itemid from itemvalues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type<=1))");
if (statement != null)
{
statement.TryBind(paramName, artistId.ToGuidBlob());
statement.TryBind(paramName, artistId.ToByteArray());
}
index++;
}
@@ -4066,7 +4067,7 @@ namespace Emby.Server.Implementations.Data
clauses.Add("(guid in (select itemid from itemvalues where CleanValue = (select CleanName from TypedBaseItems where guid=" + paramName + ") and Type=2))");
if (statement != null)
{
statement.TryBind(paramName, genreId.ToGuidBlob());
statement.TryBind(paramName, genreId.ToByteArray());
}
index++;
}
@@ -4137,7 +4138,7 @@ namespace Emby.Server.Implementations.Data
if (statement != null)
{
statement.TryBind(paramName, studioId.ToGuidBlob());
statement.TryBind(paramName, studioId.ToByteArray());
}
index++;
}
@@ -4913,7 +4914,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
connection.RunInTransaction(db =>
{
var idBlob = id.ToGuidBlob();
var idBlob = id.ToByteArray();
// Delete people
ExecuteWithSingleParam(db, "delete from People where ItemId=@Id", idBlob);
@@ -5032,7 +5033,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
whereClauses.Add("ItemId=@ItemId");
if (statement != null)
{
statement.TryBind("@ItemId", query.ItemId.ToGuidBlob());
statement.TryBind("@ItemId", query.ItemId.ToByteArray());
}
}
if (!query.AppearsInItemId.Equals(Guid.Empty))
@@ -5040,7 +5041,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
whereClauses.Add("Name in (Select Name from People where ItemId=@AppearsInItemId)");
if (statement != null)
{
statement.TryBind("@AppearsInItemId", query.AppearsInItemId.ToGuidBlob());
statement.TryBind("@AppearsInItemId", query.AppearsInItemId.ToByteArray());
}
}
var queryPersonTypes = query.PersonTypes.Where(IsValidPersonType).ToList();
@@ -5109,7 +5110,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
CheckDisposed();
var itemIdBlob = itemId.ToGuidBlob();
var itemIdBlob = itemId.ToByteArray();
// First delete
deleteAncestorsStatement.Reset();
@@ -5143,7 +5144,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
var ancestorId = ancestorIds[i];
statement.TryBind("@AncestorId" + index, ancestorId.ToGuidBlob());
statement.TryBind("@AncestorId" + index, ancestorId.ToByteArray());
statement.TryBind("@AncestorIdText" + index, ancestorId.ToString("N", CultureInfo.InvariantCulture));
}
@@ -5608,7 +5609,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
CheckDisposed();
var guidBlob = itemId.ToGuidBlob();
var guidBlob = itemId.ToByteArray();
// First delete
db.Execute("delete from ItemValues where ItemId=@Id", guidBlob);
@@ -5632,10 +5633,13 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
if (isSubsequentRow)
{
insertText.Append(",");
insertText.Append(',');
}
insertText.AppendFormat("(@ItemId, @Type{0}, @Value{0}, @CleanValue{0})", i.ToString(CultureInfo.InvariantCulture));
insertText.AppendFormat(
CultureInfo.InvariantCulture,
"(@ItemId, @Type{0}, @Value{0}, @CleanValue{0})",
i);
isSubsequentRow = true;
}
@@ -5688,7 +5692,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
connection.RunInTransaction(db =>
{
var itemIdBlob = itemId.ToGuidBlob();
var itemIdBlob = itemId.ToByteArray();
// First delete chapters
db.Execute("delete from People where ItemId=@ItemId", itemIdBlob);
@@ -5807,7 +5811,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
using (var statement = PrepareStatement(connection, cmdText))
{
statement.TryBind("@ItemId", query.ItemId.ToGuidBlob());
statement.TryBind("@ItemId", query.ItemId.ToByteArray());
if (query.Type.HasValue)
{
@@ -5849,7 +5853,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
connection.RunInTransaction(db =>
{
var itemIdBlob = id.ToGuidBlob();
var itemIdBlob = id.ToByteArray();
// First delete chapters
db.Execute("delete from mediastreams where ItemId=@ItemId", itemIdBlob);

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities;
@@ -15,23 +14,19 @@ namespace Emby.Server.Implementations.Data
public class SqliteUserDataRepository : BaseSqliteRepository, IUserDataRepository
{
public SqliteUserDataRepository(
ILoggerFactory loggerFactory,
ILogger<SqliteUserDataRepository> logger,
IApplicationPaths appPaths)
: base(loggerFactory.CreateLogger(nameof(SqliteUserDataRepository)))
: base(logger)
{
DbFilePath = Path.Combine(appPaths.DataPath, "library.db");
}
/// <summary>
/// Gets the name of the repository
/// </summary>
/// <value>The name.</value>
/// <inheritdoc />
public string Name => "SQLite";
/// <summary>
/// Opens the connection to the database
/// Opens the connection to the database.
/// </summary>
/// <returns>Task.</returns>
public void Initialize(IUserManager userManager, SemaphoreSlim dbLock, SQLiteDatabaseConnection dbConnection)
{
WriteLock.Dispose();
@@ -97,7 +92,7 @@ namespace Emby.Server.Implementations.Data
continue;
}
statement.TryBind("@UserId", user.Id.ToGuidBlob());
statement.TryBind("@UserId", user.Id.ToByteArray());
statement.TryBind("@InternalUserId", user.InternalId);
statement.MoveNext();

View File

@@ -116,7 +116,7 @@ namespace Emby.Server.Implementations.Data
{
using (var statement = db.PrepareStatement("insert into LocalUsersv2 (guid, data) values (@guid, @data)"))
{
statement.TryBind("@guid", user.Id.ToGuidBlob());
statement.TryBind("@guid", user.Id.ToByteArray());
statement.TryBind("@data", serialized);
statement.MoveNext();