mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
parent
8255fb0b28
commit
857d661ff1
@ -9,6 +9,7 @@ public interface IConnectionStringFactory
|
|||||||
{
|
{
|
||||||
string MainDbConnectionString { get; }
|
string MainDbConnectionString { get; }
|
||||||
string LogDbConnectionString { get; }
|
string LogDbConnectionString { get; }
|
||||||
|
string GetDatabasePath(string connectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ConnectionStringFactory : IConnectionStringFactory
|
public class ConnectionStringFactory : IConnectionStringFactory
|
||||||
@ -22,6 +23,13 @@ public ConnectionStringFactory(IAppFolderInfo appFolderInfo)
|
|||||||
public string MainDbConnectionString { get; private set; }
|
public string MainDbConnectionString { get; private set; }
|
||||||
public string LogDbConnectionString { get; private set; }
|
public string LogDbConnectionString { get; private set; }
|
||||||
|
|
||||||
|
public string GetDatabasePath(string connectionString)
|
||||||
|
{
|
||||||
|
var connectionBuilder = new SQLiteConnectionStringBuilder(connectionString);
|
||||||
|
|
||||||
|
return connectionBuilder.DataSource;
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetConnectionString(string dbPath)
|
private static string GetConnectionString(string dbPath)
|
||||||
{
|
{
|
||||||
var connectionBuilder = new SQLiteConnectionStringBuilder();
|
var connectionBuilder = new SQLiteConnectionStringBuilder();
|
||||||
|
24
src/NzbDrone.Core/Datastore/CorruptDatabaseException.cs
Normal file
24
src/NzbDrone.Core/Datastore/CorruptDatabaseException.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using NzbDrone.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore
|
||||||
|
{
|
||||||
|
public class CorruptDatabaseException : NzbDroneException
|
||||||
|
{
|
||||||
|
public CorruptDatabaseException(string message, params object[] args) : base(message, args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public CorruptDatabaseException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public CorruptDatabaseException(string message, Exception innerException, params object[] args) : base(message, innerException, args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public CorruptDatabaseException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data.SQLite;
|
using System.Data.SQLite;
|
||||||
|
using System.IO;
|
||||||
using Marr.Data;
|
using Marr.Data;
|
||||||
using Marr.Data.Reflection;
|
using Marr.Data.Reflection;
|
||||||
|
using NLog;
|
||||||
using NzbDrone.Common.Composition;
|
using NzbDrone.Common.Composition;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Instrumentation;
|
||||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
using NzbDrone.Core.Instrumentation;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
|
||||||
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore
|
namespace NzbDrone.Core.Datastore
|
||||||
@ -18,8 +21,10 @@ public interface IDbFactory
|
|||||||
|
|
||||||
public class DbFactory : IDbFactory
|
public class DbFactory : IDbFactory
|
||||||
{
|
{
|
||||||
|
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(DbFactory));
|
||||||
private readonly IMigrationController _migrationController;
|
private readonly IMigrationController _migrationController;
|
||||||
private readonly IConnectionStringFactory _connectionStringFactory;
|
private readonly IConnectionStringFactory _connectionStringFactory;
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
|
||||||
static DbFactory()
|
static DbFactory()
|
||||||
{
|
{
|
||||||
@ -38,10 +43,13 @@ public static void RegisterDatabase(IContainer container)
|
|||||||
container.Register<ILogDatabase>(logDb);
|
container.Register<ILogDatabase>(logDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbFactory(IMigrationController migrationController, IConnectionStringFactory connectionStringFactory)
|
public DbFactory(IMigrationController migrationController,
|
||||||
|
IConnectionStringFactory connectionStringFactory,
|
||||||
|
IDiskProvider diskProvider)
|
||||||
{
|
{
|
||||||
_migrationController = migrationController;
|
_migrationController = migrationController;
|
||||||
_connectionStringFactory = connectionStringFactory;
|
_connectionStringFactory = connectionStringFactory;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDatabase Create(MigrationType migrationType = MigrationType.Main)
|
public IDatabase Create(MigrationType migrationType = MigrationType.Main)
|
||||||
@ -72,7 +80,43 @@ public IDatabase Create(MigrationContext migrationContext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
_migrationController.Migrate(connectionString, migrationContext);
|
_migrationController.Migrate(connectionString, migrationContext);
|
||||||
|
}
|
||||||
|
catch (SQLiteException ex)
|
||||||
|
{
|
||||||
|
var fileName = _connectionStringFactory.GetDatabasePath(connectionString);
|
||||||
|
|
||||||
|
if (migrationContext.MigrationType == MigrationType.Log)
|
||||||
|
{
|
||||||
|
Logger.Error(ex, "Logging database is corrupt, attempting to recreate it automatically");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_diskProvider.DeleteFile(fileName + "-shm");
|
||||||
|
_diskProvider.DeleteFile(fileName + "-wal");
|
||||||
|
_diskProvider.DeleteFile(fileName + "-journal");
|
||||||
|
_diskProvider.DeleteFile(fileName);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Logger.Error("Unable to recreate logging database automatically. It will need to be removed manually.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_migrationController.Migrate(connectionString, migrationContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (OsInfo.IsOsx)
|
||||||
|
{
|
||||||
|
throw new CorruptDatabaseException("Database file: {0} is corrupt, restore from backup if available. See: https://github.com/Sonarr/Sonarr/wiki/FAQ#i-use-sonarr-on-a-mac-and-it-suddenly-stopped-working-what-happened", ex, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new CorruptDatabaseException("Database file: {0} is corrupt, restore from backup if available. See: https://github.com/Sonarr/Sonarr/wiki/FAQ#i-am-getting-an-error-database-disk-image-is-malformed", ex, fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var db = new Database(migrationContext.MigrationType.ToString(), () =>
|
var db = new Database(migrationContext.MigrationType.ToString(), () =>
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System.Data.SQLite;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using FluentMigrator.Runner;
|
using FluentMigrator.Runner;
|
||||||
@ -37,6 +37,9 @@ public void Migrate(string connectionString, MigrationContext migrationContext)
|
|||||||
var options = new MigrationOptions { PreviewOnly = false, Timeout = 60 };
|
var options = new MigrationOptions { PreviewOnly = false, Timeout = 60 };
|
||||||
var factory = new NzbDroneSqliteProcessorFactory();
|
var factory = new NzbDroneSqliteProcessorFactory();
|
||||||
var processor = factory.Create(connectionString, _announcer, options);
|
var processor = factory.Create(connectionString, _announcer, options);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
var runner = new MigrationRunner(assembly, runnerContext, processor);
|
var runner = new MigrationRunner(assembly, runnerContext, processor);
|
||||||
|
|
||||||
if (migrationContext.DesiredVersion.HasValue)
|
if (migrationContext.DesiredVersion.HasValue)
|
||||||
@ -47,6 +50,14 @@ public void Migrate(string connectionString, MigrationContext migrationContext)
|
|||||||
{
|
{
|
||||||
runner.MigrateUp(true);
|
runner.MigrateUp(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (SQLiteException)
|
||||||
|
{
|
||||||
|
processor.Dispose();
|
||||||
|
SQLiteConnection.ClearAllPools();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|
||||||
|
@ -171,6 +171,7 @@
|
|||||||
<Compile Include="Datastore\Converters\ProviderSettingConverter.cs" />
|
<Compile Include="Datastore\Converters\ProviderSettingConverter.cs" />
|
||||||
<Compile Include="Datastore\Converters\QualityIntConverter.cs" />
|
<Compile Include="Datastore\Converters\QualityIntConverter.cs" />
|
||||||
<Compile Include="Datastore\Converters\UtcConverter.cs" />
|
<Compile Include="Datastore\Converters\UtcConverter.cs" />
|
||||||
|
<Compile Include="Datastore\CorruptDatabaseException.cs" />
|
||||||
<Compile Include="Datastore\Database.cs" />
|
<Compile Include="Datastore\Database.cs" />
|
||||||
<Compile Include="Datastore\DbFactory.cs" />
|
<Compile Include="Datastore\DbFactory.cs" />
|
||||||
<Compile Include="Datastore\Events\ModelEvent.cs" />
|
<Compile Include="Datastore\Events\ModelEvent.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user