New: Postgres Database Support

Co-Authored-By: Qstick <376117+Qstick@users.noreply.github.com>
pull/5913/head
Robin Dadswell 2 years ago committed by Qstick
parent 69ddd99eb8
commit a13011aa49

@ -22,6 +22,8 @@ class About extends Component {
isNetCore,
isDocker,
runtimeVersion,
databaseVersion,
databaseType,
appData,
startupPath,
mode,
@ -69,6 +71,11 @@ class About extends Component {
/>
}
<DescriptionListItem
title={translate('Database')}
data={`${titleCase(databaseType)} ${databaseVersion}`}
/>
<DescriptionListItem
title={translate('AppDataDirectory')}
data={appData}
@ -108,6 +115,8 @@ About.propTypes = {
isNetCore: PropTypes.bool.isRequired,
runtimeVersion: PropTypes.string.isRequired,
isDocker: PropTypes.bool.isRequired,
databaseType: PropTypes.string.isRequired,
databaseVersion: PropTypes.string.isRequired,
appData: PropTypes.string.isRequired,
startupPath: PropTypes.string.isRequired,
mode: PropTypes.string.isRequired,

@ -8,5 +8,6 @@
<add key="SQLite" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/SQLite/nuget/v3/index.json" />
<add key="coverlet-nightly" value="https://pkgs.dev.azure.com/Servarr/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json" />
<add key="FFMpegCore" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/FFMpegCore/nuget/v3/index.json" />
<add key="FluentMigrator" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/FluentMigrator/nuget/v3/index.json" />
</packageSources>
</configuration>

@ -43,7 +43,7 @@ namespace NzbDrone.Automation.Test
driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080);
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger());
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), null);
_runner.KillAll();
_runner.Start(true);

@ -66,6 +66,9 @@ namespace NzbDrone.Common.Test.InstrumentationTests
[TestCase("Hardlinking episode file: /Users/mySecret/Downloads to /media/abc.mkv")]
[TestCase("Hardlink '/home/mySecret/Downloads/abs.mkv' to '/media/abc.mkv' failed.")]
[TestCase("Hardlink '/Users/mySecret/Downloads/abs.mkv' to '/media/abc.mkv' failed.")]
[TestCase("/sonarr/signalr/messages/negotiate?access_token=1234530f422f4aacb6b301233210aaaa&negotiateVersion=1")]
[TestCase(@"[Info] MigrationController: *** Migrating Database=sonarr-main;Host=postgres14;Username=mySecret;Password=mySecret;Port=5432;Enlist=False ***")]
[TestCase(@"[Info] MigrationController: *** Migrating Database=sonarr-main;Host=postgres14;Username=mySecret;Password=mySecret;Port=5432;token=mySecret;Enlist=False&username=mySecret;mypassword=mySecret;mypass=shouldkeep1;test_token=mySecret;password=123%@%_@!#^#@;use_password=mySecret;get_token=shouldkeep2;usetoken=shouldkeep3;passwrd=mySecret;")]
// Announce URLs (passkeys) Magnet & Tracker
[TestCase(@"magnet_uri"":""magnet:?xt=urn:btih:9pr04sgkillroyimaveql2tyu8xyui&dn=&tr=https%3a%2f%2fxxx.yyy%2f9pr04sg601233210imaveql2tyu8xyui%2fannounce""}")]
@ -90,9 +93,24 @@ namespace NzbDrone.Common.Test.InstrumentationTests
var cleansedMessage = CleanseLogMessage.Cleanse(message);
cleansedMessage.Should().NotContain("mySecret");
cleansedMessage.Should().NotContain("123%@%_@!#^#@");
cleansedMessage.Should().NotContain("01233210");
}
[TestCase(@"[Info] MigrationController: *** Migrating Database=sonarr-main;Host=postgres14;Username=mySecret;Password=mySecret;Port=5432;token=mySecret;Enlist=False&username=mySecret;mypassword=mySecret;mypass=shouldkeep1;test_token=mySecret;password=123%@%_@!#^#@;use_password=mySecret;get_token=shouldkeep2;usetoken=shouldkeep3;passwrd=mySecret;")]
public void should_keep_message(string message)
{
var cleansedMessage = CleanseLogMessage.Cleanse(message);
cleansedMessage.Should().NotContain("mySecret");
cleansedMessage.Should().NotContain("123%@%_@!#^#@");
cleansedMessage.Should().NotContain("01233210");
cleansedMessage.Should().Contain("shouldkeep1");
cleansedMessage.Should().Contain("shouldkeep2");
cleansedMessage.Should().Contain("shouldkeep3");
}
[TestCase(@"Some message (from 32.2.3.5 user agent)")]
[TestCase(@"Auth-Invalidated ip 32.2.3.5")]
[TestCase(@"Auth-Success ip 32.2.3.5")]

@ -4,11 +4,13 @@ using DryIoc.Microsoft.DependencyInjection;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Composition.Extensions;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Extensions;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Events;
@ -29,7 +31,8 @@ namespace NzbDrone.Common.Test
.AddDummyDatabase()
.AddStartupContext(new StartupContext("first", "second"));
container.RegisterInstance<IHostLifetime>(new Mock<IHostLifetime>().Object);
container.RegisterInstance(new Mock<IHostLifetime>().Object);
container.RegisterInstance(new Mock<IOptions<PostgresOptions>>().Object);
var serviceProvider = container.GetServiceProvider();

@ -17,6 +17,7 @@ namespace NzbDrone.Common.Instrumentation
new (@"iptorrents\.com/[/a-z0-9?&;]*?(?:[?&;](u|tp)=(?<secret>[^&=;]+?))+(?= |;|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"/fetch/[a-z0-9]{32}/(?<secret>[a-z0-9]{32})", RegexOptions.Compiled),
new (@"getnzb.*?(?<=\?|&)(r)=(?<secret>[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new (@"\b(\w*)?(_?(?<!use|get_)token|username|passwo?rd)=(?<secret>[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Trackers Announce Keys; Designed for Qbit Json; should work for all in theory
new (@"announce(\.php)?(/|%2f|%3fpasskey%3d)(?<secret>[a-z0-9]{16,})|(?<secret>[a-z0-9]{16,})(/|%2f)announce"),

@ -15,7 +15,7 @@ namespace NzbDrone.Core.Test.Datastore
public void SingleOrDefault_should_return_null_on_empty_db()
{
Mocker.Resolve<IDatabase>()
.OpenConnection().Query<Series>("SELECT * FROM Series")
.OpenConnection().Query<Series>("SELECT * FROM \"Series\"")
.SingleOrDefault()
.Should()
.BeNull();
@ -27,6 +27,20 @@ namespace NzbDrone.Core.Test.Datastore
Mocker.Resolve<IDatabase>().Vacuum();
}
[Test]
public void postgres_should_not_contain_timestamp_without_timezone_columns()
{
if (Db.DatabaseType != DatabaseType.PostgreSQL)
{
return;
}
Mocker.Resolve<IDatabase>()
.OpenConnection().Query("SELECT table_name, column_name, data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = 'public' AND data_type = 'timestamp without time zone'")
.Should()
.BeNullOrEmpty();
}
[Test]
public void get_version()
{

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
@ -15,6 +16,17 @@ namespace NzbDrone.Core.Test.Datastore
[TestFixture]
public class DatabaseRelationshipFixture : DbTest
{
[SetUp]
public void Setup()
{
AssertionOptions.AssertEquivalencyUsing(options =>
{
options.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation.ToUniversalTime(), TimeSpan.FromMilliseconds(20))).WhenTypeIs<DateTime>();
options.Using<DateTime?>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation.Value.ToUniversalTime(), TimeSpan.FromMilliseconds(20))).WhenTypeIs<DateTime?>();
return options;
});
}
[Test]
public void one_to_one()
{

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration;
@ -26,12 +26,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
GrabDelay = 2,
Name = "TwoHours",
Cutoff = "{}",
Cutoff = 0,
Items = "[]"
});
});
var allProfiles = db.Query<DelayProfile70>("SELECT * FROM DelayProfiles");
var allProfiles = db.Query<DelayProfile70>("SELECT * FROM \"DelayProfiles\"");
allProfiles.Should().HaveCount(3);
allProfiles.Should().OnlyContain(c => c.PreferredProtocol == 1);
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var tags = db.Query<Tag69>("SELECT * FROM Tags");
var tags = db.Query<Tag69>("SELECT * FROM \"Tags\"");
tags.Should().HaveCount(1);
tags.First().Label.Should().Be("delay-60");
@ -83,17 +83,17 @@ namespace NzbDrone.Core.Test.Datastore.Migration
Status = 0,
Images = "[]",
Path = @"C:\Test\Series",
Monitored = 1,
SeasonFolder = 1,
RunTime = 0,
Monitored = true,
SeasonFolder = true,
Runtime = 0,
SeriesType = 0,
UseSceneNumbering = 0,
UseSceneNumbering = false,
Tags = "[1]"
});
});
var tag = db.Query<Tag69>("SELECT Id, Label FROM Tags").Single();
var series = db.Query<Series69>("SELECT Tags FROM Series");
var tag = db.Query<Tag69>("SELECT \"Id\", \"Label\" FROM \"Tags\"").Single();
var series = db.Query<Series69>("SELECT \"Tags\" FROM \"Series\"");
series.Should().HaveCount(1);

@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration;
using NzbDrone.Core.Test.Framework;
@ -19,12 +21,19 @@ namespace NzbDrone.Core.Test.Datastore.Migration
Id = 0,
Name = "SDTV",
Cutoff = 1,
Items = "[ { \"quality\": 1, \"allowed\": true } ]",
Items = new List<object>
{
new
{
Quality = 1,
Allowed = true
}
}.ToJson(),
Language = 1
});
});
var profiles = db.Query<Profile71>("SELECT Items FROM Profiles LIMIT 1");
var profiles = db.Query<Profile71>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
var items = profiles.First().Items;
items.Should().HaveCount(2);

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var history = db.Query<History72>("SELECT DownloadId, Data FROM History");
var history = db.Query<History72>("SELECT \"DownloadId\", \"Data\" FROM \"History\"");
history.Should().HaveCount(2);
history.Should().NotContain(c => c.Data.ContainsKey("downloadClientId"));
@ -56,7 +56,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var history = db.Query<History72>("SELECT DownloadId, Data FROM History");
var history = db.Query<History72>("SELECT \"DownloadId\", \"Data\" FROM \"History\"");
history.Should().HaveCount(2);
history.Should().NotContain(c => c.Data.ContainsKey("downloadClientId"));
@ -77,7 +77,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var history = db.Query<History72>("SELECT DownloadId, Data FROM History").Single();
var history = db.Query<History72>("SELECT \"DownloadId\", \"Data\" FROM \"History\"").Single();
history.Data.Should().NotContainKey("downloadClientId");
history.Data.Should().Contain(new KeyValuePair<string, string>("indexer", "test"));

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration;
@ -14,8 +14,8 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
var db = WithMigrationTestDb();
db.Query("SELECT * FROM ScheduledTasks").Should().BeEmpty();
db.Query("SELECT * FROM Series").Should().BeEmpty();
db.Query("SELECT * FROM \"ScheduledTasks\"").Should().BeEmpty();
db.Query("SELECT * FROM \"Series\"").Should().BeEmpty();
}
[Test]
@ -38,7 +38,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var jobs = db.Query<ScheduledTasks75>("SELECT TypeName, LastExecution FROM ScheduledTasks");
var jobs = db.Query<ScheduledTasks75>("SELECT \"TypeName\", \"LastExecution\" FROM \"ScheduledTasks\"");
jobs.Single(c => c.TypeName == "NzbDrone.Core.Tv.Commands.RefreshSeriesCommand")
.LastExecution.Year.Should()
@ -57,49 +57,49 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new
{
Name = "Profile1",
CutOff = 0,
Cutoff = 0,
Items = "[]",
Language = 1
});
c.Insert.IntoTable("Series").Row(new
{
Tvdbid = 1,
TvdbId = 1,
TvRageId =1,
Title ="Title1",
CleanTitle ="CleanTitle1",
Status =1,
Images ="",
Path ="c:\\test",
Monitored =1,
SeasonFolder =1,
Runtime= 0,
SeriesType=0,
UseSceneNumbering =0,
Status = 1,
Images = "",
Path = "c:\\test",
Monitored = true,
SeasonFolder = true,
Runtime = 0,
SeriesType = 0,
UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00",
ProfileId = 1
});
c.Insert.IntoTable("Series").Row(new
{
Tvdbid = 2,
TvdbId = 2,
TvRageId = 2,
Title = "Title2",
CleanTitle = "CleanTitle2",
Status = 1,
Images = "",
Path = "c:\\test2",
Monitored = 1,
SeasonFolder = 1,
Monitored = true,
SeasonFolder = true,
Runtime = 0,
SeriesType = 0,
UseSceneNumbering = 0,
UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00",
ProfileId = 1
});
});
var series = db.Query<Series69>("SELECT LastInfoSync FROM Series");
var series = db.Query<Series69>("SELECT \"LastInfoSync\" FROM \"Series\"");
series.Should().OnlyContain(c => c.LastInfoSync.Value.Year == 2014);
}

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration;
@ -17,25 +17,25 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new
{
Name = "Profile1",
CutOff = 0,
Cutoff = 0,
Items = "[]",
Language = 1
});
c.Insert.IntoTable("Series").Row(new
{
Tvdbid = 1,
TvdbId = 1,
TvRageId = 1,
Title = "Title1",
CleanTitle = "CleanTitle1",
Status = 1,
Images = "",
Path = "c:\\test",
Monitored = 1,
SeasonFolder = 1,
Monitored = true,
SeasonFolder = true,
Runtime = 0,
SeriesType = 0,
UseSceneNumbering = 0,
UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00",
ProfileId = 1
});
@ -46,7 +46,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var tags = db.Query<Tag69>("SELECT * FROM Tags");
var tags = db.Query<Tag69>("SELECT * FROM \"Tags\"");
tags.Should().HaveCount(1);
}
@ -58,25 +58,25 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new
{
Name = "Profile1",
CutOff = 0,
Cutoff = 0,
Items = "[]",
Language = 1
});
c.Insert.IntoTable("Series").Row(new
{
Tvdbid = 1,
TvdbId = 1,
TvRageId = 1,
Title = "Title1",
CleanTitle = "CleanTitle1",
Status = 1,
Images = "",
Path = "c:\\test",
Monitored = 1,
SeasonFolder = 1,
Monitored = true,
SeasonFolder = true,
Runtime = 0,
SeriesType = 0,
UseSceneNumbering = 0,
UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00",
Tags = "[]",
ProfileId = 1
@ -88,7 +88,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var tags = db.Query<Tag69>("SELECT * FROM Tags");
var tags = db.Query<Tag69>("SELECT * FROM \"Tags\"");
tags.Should().HaveCount(1);
}
@ -108,7 +108,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var tags = db.Query<Tag69>("SELECT * FROM Tags");
var tags = db.Query<Tag69>("SELECT * FROM \"Tags\"");
tags.Should().HaveCount(1);
}
@ -123,7 +123,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
Assert.That(() => db.Query("INSERT INTO Tags (Label) VALUES ('test')"), Throws.Exception);
Assert.That(() => db.Query("INSERT INTO \"Tags\" (\"Label\") VALUES ('test')"), Throws.Exception);
}
[Test]
@ -134,25 +134,25 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new
{
Name = "Profile1",
CutOff = 0,
Cutoff = 0,
Items = "[]",
Language = 1
});
c.Insert.IntoTable("Series").Row(new
{
Tvdbid = 1,
TvdbId = 1,
TvRageId = 1,
Title = "Title1",
CleanTitle = "CleanTitle1",
Status = 1,
Images = "",
Path = "c:\\test",
Monitored = 1,
SeasonFolder = 1,
Monitored = true,
SeasonFolder = true,
Runtime = 0,
SeriesType = 0,
UseSceneNumbering = 0,
UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00",
Tags = "[2]",
ProfileId = 1
@ -169,7 +169,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var series = db.Query<Series69>("SELECT Tags FROM Series WHERE Id = 1").Single();
var series = db.Query<Series69>("SELECT \"Tags\" FROM \"Series\" WHERE \"Id\" = 1").Single();
series.Tags.First().Should().Be(1);
}
@ -181,25 +181,25 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new
{
Name = "Profile1",
CutOff = 0,
Cutoff = 0,
Items = "[]",
Language = 1
});
c.Insert.IntoTable("Series").Row(new
{
Tvdbid = 1,
TvdbId = 1,
TvRageId = 1,
Title = "Title1",
CleanTitle = "CleanTitle1",
Status = 1,
Images = "",
Path = "c:\\test",
Monitored = 1,
SeasonFolder = 1,
Monitored = true,
SeasonFolder = true,
Runtime = 0,
SeriesType = 0,
UseSceneNumbering = 0,
UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00",
Tags = "[2]",
ProfileId = 1
@ -207,18 +207,18 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Series").Row(new
{
Tvdbid = 2,
TvdbId = 2,
TvRageId = 2,
Title = "Title2",
CleanTitle = "CleanTitle2",
Status = 1,
Images = "",
Path = "c:\\test",
Monitored = 1,
SeasonFolder = 1,
Monitored = true,
SeasonFolder = true,
Runtime = 0,
SeriesType = 0,
UseSceneNumbering = 0,
UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00",
Tags = "[]",
ProfileId = 1
@ -235,7 +235,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var series = db.Query<Series69>("SELECT Tags FROM Series WHERE Id = 2").Single();
var series = db.Query<Series69>("SELECT \"Tags\" FROM \"Series\" WHERE \"Id\" = 2").Single();
series.Tags.Should().BeEmpty();
}
}

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Serializer;
@ -17,7 +17,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Sab",
Implementation = "Sabnzbd",
Settings = new
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var downloadClients = db.Query<DownloadClientDefinition81>("SELECT Settings FROM DownloadClients");
var downloadClients = db.Query<DownloadClientDefinition81>("SELECT \"Settings\" FROM \"DownloadClients\"");
downloadClients.Should().HaveCount(1);
downloadClients.First().Settings.ToObject<SabnzbdSettings81>().TvCategory.Should().Be("abc");
@ -42,7 +42,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Trans",
Implementation = "Transmission",
Settings = new
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var downloadClients = db.Query<DownloadClientDefinition81>("SELECT Settings FROM DownloadClients");
var downloadClients = db.Query<DownloadClientDefinition81>("SELECT \"Settings\" FROM \"DownloadClients\"");
downloadClients.Should().HaveCount(1);
downloadClients.First().Settings.ToObject<TransmissionSettings81>().TvCategory.Should().Be(".abc");
@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Trans",
Implementation = "Transmission",
Settings = new
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var downloadClients = db.Query<DownloadClientDefinition81>("SELECT Settings FROM DownloadClients");
var downloadClients = db.Query<DownloadClientDefinition81>("SELECT \"Settings\" FROM \"DownloadClients\"");
downloadClients.Should().HaveCount(1);
downloadClients.First().Settings.ToObject<TransmissionSettings81>().TvCategory.Should().Be("");

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration;
@ -14,7 +14,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
var db = WithMigrationTestDb();
var qualityDefinitions = db.Query<QualityDefinition84>("SELECT * FROM QualityDefinitions");
var qualityDefinitions = db.Query<QualityDefinition84>("SELECT * FROM \"QualityDefinitions\"");
qualityDefinitions.Should().BeEmpty();
}
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var qualityDefinitions = db.Query<QualityDefinition84>("SELECT * FROM QualityDefinitions");
var qualityDefinitions = db.Query<QualityDefinition84>("SELECT * FROM \"QualityDefinitions\"");
qualityDefinitions.Should().HaveCount(2);
qualityDefinitions.First(v => v.Quality == 10).MaxSize.Should().NotHaveValue();
@ -60,7 +60,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var qualityDefinitions = db.Query<QualityDefinition84>("SELECT * FROM QualityDefinitions");
var qualityDefinitions = db.Query<QualityDefinition84>("SELECT * FROM \"QualityDefinitions\"");
qualityDefinitions.Should().HaveCount(1);
qualityDefinitions.First(v => v.Quality == 1).MaxSize.Should().NotHaveValue();
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var qualityDefinitions = db.Query<QualityDefinition84>("SELECT * FROM QualityDefinitions");
var qualityDefinitions = db.Query<QualityDefinition84>("SELECT * FROM \"QualityDefinitions\"");
qualityDefinitions.Should().HaveCount(2);
qualityDefinitions.First(v => v.Quality == 1).MaxSize.Should().Be(100);

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Serializer;
@ -17,7 +17,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Deluge",
Implementation = "Deluge",
Settings = new DelugeSettings85
@ -30,7 +30,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition81>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition81>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<DelugeSettings85>().UrlBase.Should().Be("/my/");
@ -43,7 +43,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Trans",
Implementation = "Transmission",
Settings = new TransmissionSettings81
@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition81>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition81>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<TransmissionSettings81>().UrlBase.Should().Be("/transmission/");
@ -68,7 +68,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Trans",
Implementation = "Transmission",
Settings = new TransmissionSettings81
@ -81,7 +81,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition81>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition81>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<TransmissionSettings81>().UrlBase.Should().Be("/my/url/transmission/");

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Serializer;
@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<Notification86>("SELECT * FROM Notifications");
var items = db.Query<Notification86>("SELECT * FROM \"Notifications\"");
items.Should().HaveCount(1);
}
@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<Notification86>("SELECT * FROM Notifications");
var items = db.Query<Notification86>("SELECT * FROM \"Notifications\"");
items.Should().HaveCount(1);
}
@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<Notification86>("SELECT * FROM Notifications");
var items = db.Query<Notification86>("SELECT * FROM \"Notifications\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<PushBulletSettings86>().DeviceIds.First().Should().Be(deviceId);

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Serializer;
@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<Notification86>("SELECT * FROM Notifications");
var items = db.Query<Notification86>("SELECT * FROM \"Notifications\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<PushBulletSettings88>().ChannelTags.Should().HaveCount(2);

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Serializer;
@ -33,7 +33,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<IndexerDefinition90>("SELECT * FROM Indexers");
var items = db.Query<IndexerDefinition90>("SELECT * FROM \"Indexers\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<KickassTorrentsSettings90>().BaseUrl.Should().Be("https://kat.cr");
@ -56,7 +56,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<IndexerDefinition90>("SELECT * FROM Indexers");
var items = db.Query<IndexerDefinition90>("SELECT * FROM \"Indexers\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<KickassTorrentsSettings90>().BaseUrl.Should().Be("kickass.so");

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration;
@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<MetadataFile99>("SELECT * FROM MetadataFiles");
var items = db.Query<MetadataFile99>("SELECT * FROM \"MetadataFiles\"");
items.Should().HaveCount(2);
items.First().Extension.Should().Be(".jpg");

@ -24,7 +24,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var profiles = db.Query<Profile71>("SELECT Items FROM Profiles LIMIT 1");
var profiles = db.Query<Profile71>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
var items = profiles.First().Items;
items.Should().HaveCount(4);

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration;
@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<MetadataFile99>("SELECT * FROM MetadataFiles");
var items = db.Query<MetadataFile99>("SELECT * FROM \"MetadataFiles\"");
items.Should().HaveCount(1);
items.First().Extension.Should().Be(".jpg");

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common.Serializer;
@ -30,7 +30,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<IndexerDefinition90>("SELECT * FROM Indexers");
var items = db.Query<IndexerDefinition90>("SELECT * FROM \"Indexers\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<BroadcastheNetSettings106>().BaseUrl.Should().Contain("api.broadcasthe.net");
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<IndexerDefinition90>("SELECT * FROM Indexers");
var items = db.Query<IndexerDefinition90>("SELECT * FROM \"Indexers\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<BroadcastheNetSettings106>().BaseUrl.Should().Be("http://api.btnapps.net");

@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query("Select * from ExtraFiles");
var items = db.Query("Select * from \"ExtraFiles\"");
items.Should().BeEmpty();
}
@ -50,7 +50,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query("Select * from SubtitleFiles");
var items = db.Query("Select * from \"SubtitleFiles\"");
items.Should().HaveCount(1);
items.First()["Extension"].Should().Be(".srt");
@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query("Select * from ExtraFiles");
var items = db.Query("Select * from \"ExtraFiles\"");
items.Should().HaveCount(1);
items.First()["Extension"].Should().Be(".nfo-orig");

@ -13,7 +13,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
var db = WithMigrationTestDb();
var items = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var items = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
items.Should().BeNull();
}
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var items = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
items.Should().BeNull();
}
@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var items = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
items.Should().Be("True");
}
}

@ -13,7 +13,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
var db = WithMigrationTestDb();
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var itemEnabled = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
itemEnabled.Should().BeNull();
}
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var itemEnabled = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
itemEnabled.Should().Be("True");
}
@ -51,10 +51,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var itemEnabled = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
itemEnabled.Should().Be("False");
var itemExtensions = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'extrafileextensions'");
var itemExtensions = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'extrafileextensions'");
itemExtensions.Should().Be("srt");
}
@ -76,10 +76,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var itemEnabled = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
itemEnabled.Should().Be("True");
var itemExtensions = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'extrafileextensions'");
var itemExtensions = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'extrafileextensions'");
itemExtensions.Should().Be("");
}
@ -95,10 +95,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var itemEnabled = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
itemEnabled.Should().Be("False");
var itemExtensions = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'extrafileextensions'");
var itemExtensions = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'extrafileextensions'");
itemExtensions.Should().BeNull();
}
@ -120,10 +120,10 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
var itemEnabled = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'importextrafiles'");
itemEnabled.Should().Be("False");
var itemExtensions = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'extrafileextensions'");
var itemExtensions = db.QueryScalar<string>("SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'extrafileextensions'");
itemExtensions.Should().Be("sub");
}
}

@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var profiles = db.Query<Profile117>("SELECT Items FROM Profiles LIMIT 1");
var profiles = db.Query<Profile117>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
var items = profiles.First().Items;
items.Should().HaveCount(6);
@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var profiles = db.Query<Profile117>("SELECT Items FROM Profiles LIMIT 1");
var profiles = db.Query<Profile117>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
var items = profiles.First().Items;
items.Should().HaveCount(6);
@ -75,7 +75,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var profiles = db.Query<Profile117>("SELECT Items FROM Profiles LIMIT 1");
var profiles = db.Query<Profile117>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
var items = profiles.First().Items;
items.Should().HaveCount(6);
@ -98,7 +98,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var profiles = db.Query<Profile117>("SELECT Items FROM Profiles LIMIT 1");
var profiles = db.Query<Profile117>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
var items = profiles.First().Items;
items[1].Items.First().Quality.Should().Be((int)Quality.WEBRip480p);

@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<IndexerDefinition121>("SELECT * FROM Indexers");
var items = db.Query<IndexerDefinition121>("SELECT * FROM \"Indexers\"");
items.Should().HaveCount(1);
items.First().Settings.ToObject<NewznabSettings121>().BaseUrl.Should().Be(baseUrl.Replace("animetosho", "feed.animetosho"));

@ -23,7 +23,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var profiles = db.Query<Profile122>("SELECT Items FROM Profiles LIMIT 1");
var profiles = db.Query<Profile122>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
var items = profiles.First().Items;
items.Should().HaveCount(4);
@ -46,7 +46,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var profiles = db.Query<Profile122>("SELECT Items FROM Profiles LIMIT 1");
var profiles = db.Query<Profile122>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
var items = profiles.First().Items;
items.Should().HaveCount(4);

@ -16,11 +16,11 @@ namespace NzbDrone.Core.Test.Datastore.Migration
var dbBefore = WithTestDb(new MigrationContext(MigrationType, 110));
// Ensure 111 isn't applied
dbBefore.GetDirectDataMapper().Query("INSERT INTO VersionInfo (Version, AppliedOn, Description) VALUES (111, '2018-12-24T18:21:07', 'remove_bitmetv')");
dbBefore.GetDirectDataMapper().Query("INSERT INTO \"VersionInfo\" (\"Version\", \"AppliedOn\", \"Description\") VALUES (111, '2018-12-24T18:21:07', 'remove_bitmetv')");
var dbAfter = WithMigrationTestDb();
var result = dbAfter.QueryScalar<int>("SELECT COUNT(*) FROM VersionInfo WHERE Description = 'remove_bitmetv'");
var result = dbAfter.QueryScalar<int>("SELECT COUNT(*) FROM \"VersionInfo\" WHERE \"Description\" = 'remove_bitmetv'");
result.Should().Be(0);
}

@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Deluge",
Implementation = "Deluge",
Settings = new DelugeSettings85
@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(1);
items.First().Priority.Should().Be(1);
@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Deluge",
Implementation = "Deluge",
Settings = new DelugeSettings85
@ -56,7 +56,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
ConfigContract = "DelugeSettings"
}).Row(new
{
Enable = 1,
Enable = true,
Name = "Deluge2",
Implementation = "Deluge",
Settings = new DelugeSettings85
@ -68,7 +68,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
ConfigContract = "DelugeSettings"
}).Row(new
{
Enable = 1,
Enable = true,
Name = "sab",
Implementation = "Sabnzbd",
Settings = new SabnzbdSettings81
@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(3);
items[0].Priority.Should().Be(1);
@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 0,
Enable = false,
Name = "Deluge",
Implementation = "Deluge",
Settings = new DelugeSettings85
@ -107,7 +107,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
ConfigContract = "DelugeSettings"
}).Row(new
{
Enable = 0,
Enable = false,
Name = "Deluge2",
Implementation = "Deluge",
Settings = new DelugeSettings85
@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
ConfigContract = "DelugeSettings"
}).Row(new
{
Enable = 0,
Enable = false,
Name = "sab",
Implementation = "Sabnzbd",
Settings = new SabnzbdSettings81
@ -131,7 +131,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(3);
items[0].Priority.Should().Be(1);

@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
AddEpisodeFile(c, 1);
});
var items = db.Query<EpisodeFile148>("SELECT MediaInfo FROM EpisodeFiles");
var items = db.Query<EpisodeFile148>("SELECT \"MediaInfo\" FROM \"EpisodeFiles\"");
items.Should().HaveCount(1);

@ -37,7 +37,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<NotificationDefinition173>("SELECT * FROM Notifications");
var items = db.Query<NotificationDefinition173>("SELECT * FROM \"Notifications\"");
items.Should().HaveCount(1);
items.First().Implementation.Should().Be("Email");

@ -19,7 +19,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Deluge",
Implementation = "Deluge",
Priority = 1,
@ -33,7 +33,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(1);
items.First().RemoveCompletedDownloads.Should().BeFalse();
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "Deluge",
Implementation = "Deluge",
Priority = 1,
@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(1);
items.First().RemoveCompletedDownloads.Should().BeTrue();
@ -81,7 +81,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("DownloadClients").Row(new
{
Enable = 1,
Enable = true,
Name = "RTorrent",
Implementation = "RTorrent",
Priority = 1,
@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM DownloadClients");
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM \"DownloadClients\"");
items.Should().HaveCount(1);
items.First().RemoveCompletedDownloads.Should().BeFalse();

@ -74,13 +74,13 @@ namespace NzbDrone.Core.Test.Datastore.Migration
""isPossibleSceneSeasonSpecial"": false
}",
Release = "{}",
Reason = PendingReleaseReason.Delay
Reason = (int)PendingReleaseReason.Delay
});
});
var json = db.Query<string>("SELECT ParsedEpisodeInfo FROM PendingReleases").First();
var json = db.Query<string>("SELECT \"ParsedEpisodeInfo\" FROM \"PendingReleases\"").First();
var pending = db.Query<ParsedEpisodeInfo162>("SELECT ParsedEpisodeInfo FROM PendingReleases").First();
var pending = db.Query<ParsedEpisodeInfo162>("SELECT \"ParsedEpisodeInfo\" FROM \"PendingReleases\"").First();
pending.Quality.Quality.Should().Be(Quality.HDTV720p.Id);
pending.Language.Should().Be(Language.English.Id);
}

@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(1);
customFormats.First().Name.Should().Be("Profile_1");
@ -69,7 +69,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(0);
}
@ -99,7 +99,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(1);
customFormats.First().Name.Should().Be("Profile_1");
@ -136,7 +136,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var releaseProfiles = db.Query<ReleaseProfile171>("SELECT Id, Name FROM ReleaseProfiles");
var releaseProfiles = db.Query<ReleaseProfile171>("SELECT \"Id\", \"Name\" FROM \"ReleaseProfiles\"");
releaseProfiles.Should().HaveCount(1);
releaseProfiles.First().Name.Should().Be("Profile");
@ -167,7 +167,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var releaseProfiles = db.Query<ReleaseProfile171>("SELECT Id, Name FROM ReleaseProfiles");
var releaseProfiles = db.Query<ReleaseProfile171>("SELECT \"Id\", \"Name\" FROM \"ReleaseProfiles\"");
releaseProfiles.Should().HaveCount(0);
}
@ -196,7 +196,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(1);
customFormats.First().Name.Should().Be("Unnamed_1");
@ -246,7 +246,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(2);
customFormats.First().Name.Should().Be("Unnamed_1");
@ -333,7 +333,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(6);
customFormats.First().Name.Should().Be("Some - Profile_1_0");
@ -372,7 +372,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(2);
customFormats.First().Name.Should().Be("Profile_1_0");
@ -413,7 +413,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<QualityProfile171>("SELECT Id, Name, FormatItems FROM QualityProfiles");
var customFormats = db.Query<QualityProfile171>("SELECT \"Id\", \"Name\", \"FormatItems\" FROM \"QualityProfiles\"");
customFormats.Should().HaveCount(1);
customFormats.First().FormatItems.Should().HaveCount(1);
@ -452,7 +452,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<QualityProfile171>("SELECT Id, Name, FormatItems FROM QualityProfiles");
var customFormats = db.Query<QualityProfile171>("SELECT \"Id\", \"Name\", \"FormatItems\" FROM \"QualityProfiles\"");
customFormats.Should().HaveCount(1);
customFormats.First().FormatItems.Should().HaveCount(1);
@ -466,14 +466,14 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{
c.Insert.IntoTable("NamingConfig").Row(new
{
MultiEpisodeStyle = false,
MultiEpisodeStyle = 0,
StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Preferred Words } {Quality Full}",
DailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title} {Preferred.Words } {Quality Full}",
AnimeEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Preferred_Words} {Quality Full}",
});
});
var customFormats = db.Query<NamingConfig171>("SELECT StandardEpisodeFormat, DailyEpisodeFormat, AnimeEpisodeFormat FROM NamingConfig");
var customFormats = db.Query<NamingConfig171>("SELECT \"StandardEpisodeFormat\", \"DailyEpisodeFormat\", \"AnimeEpisodeFormat\" FROM \"NamingConfig\"");
customFormats.Should().HaveCount(1);
customFormats.First().StandardEpisodeFormat.Should().Be("{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Custom Formats } {Quality Full}");
@ -506,7 +506,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(1);
customFormats.First().Specifications.Should().HaveCount(1);
@ -538,7 +538,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var customFormats = db.Query<CustomFormat171>("SELECT Id, Name, IncludeCustomFormatWhenRenaming, Specifications FROM CustomFormats");
var customFormats = db.Query<CustomFormat171>("SELECT \"Id\", \"Name\", \"IncludeCustomFormatWhenRenaming\", \"Specifications\" FROM \"CustomFormats\"");
customFormats.Should().HaveCount(1);
customFormats.First().Specifications.Should().HaveCount(1);

@ -43,7 +43,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
});
var metadataFiles = db.Query<MetadataFile184>("SELECT * FROM MetadataFiles");
var metadataFiles = db.Query<MetadataFile184>("SELECT * FROM \"MetadataFiles\"");
metadataFiles.Should().HaveCount(1);
metadataFiles.First().RelativePath.Should().NotContain("metadata");

@ -23,9 +23,9 @@ namespace NzbDrone.Core.Test.Datastore.Migration
});
// Should be able to insert as int after migration
db.Execute("INSERT INTO ImportListExclusions (TvdbId, Title) VALUES (2, 'Some Other Series')");
db.Execute("INSERT INTO \"ImportListExclusions\" (\"TvdbId\", \"Title\") VALUES (2, 'Some Other Series')");
var exclusions = db.Query<ImportListExclusions192>("SELECT * FROM ImportListExclusions");
var exclusions = db.Query<ImportListExclusions192>("SELECT * FROM \"ImportListExclusions\"");
exclusions.Should().HaveCount(2);
exclusions.First().TvdbId.Should().Be(1);

@ -11,9 +11,9 @@ using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.Datastore
{
[TestFixture]
public class WhereBuilderFixture : CoreTest
public class WhereBuilderPostgresFixture : CoreTest
{
private WhereBuilder _subject;
private WhereBuilderPostgres _subject;
[OneTimeSetUp]
public void MapTables()
@ -22,9 +22,9 @@ namespace NzbDrone.Core.Test.Datastore
Mocker.Resolve<DbFactory>();
}
private WhereBuilder Where(Expression<Func<Series, bool>> filter)
private WhereBuilderPostgres Where(Expression<Func<Series, bool>> filter)
{
return new WhereBuilder(filter, true, 0);
return new WhereBuilderPostgres(filter, true, 0);
}
[Test]
@ -71,7 +71,7 @@ namespace NzbDrone.Core.Test.Datastore
public void where_throws_without_concrete_condition_if_requiresConcreteCondition()
{
Expression<Func<Series, Series, bool>> filter = (x, y) => x.Id == y.Id;
_subject = new WhereBuilder(filter, true, 0);
_subject = new WhereBuilderPostgres(filter, true, 0);
Assert.Throws<InvalidOperationException>(() => _subject.ToString());
}
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Test.Datastore
public void where_allows_abstract_condition_if_not_requiresConcreteCondition()
{
Expression<Func<Series, Series, bool>> filter = (x, y) => x.Id == y.Id;
_subject = new WhereBuilder(filter, false, 0);
_subject = new WhereBuilderPostgres(filter, false, 0);
_subject.ToString().Should().Be($"(\"Series\".\"Id\" = \"Series\".\"Id\")");
}
@ -115,7 +115,7 @@ namespace NzbDrone.Core.Test.Datastore
var test = "small";
_subject = Where(x => x.CleanTitle.Contains(test));
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" LIKE '%' || @Clause1_P1 || '%')");
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" ILIKE '%' || @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@ -125,7 +125,7 @@ namespace NzbDrone.Core.Test.Datastore
var test = "small";
_subject = Where(x => test.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(@Clause1_P1 LIKE '%' || \"Series\".\"CleanTitle\" || '%')");
_subject.ToString().Should().Be($"(@Clause1_P1 ILIKE '%' || \"Series\".\"CleanTitle\" || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@ -135,7 +135,7 @@ namespace NzbDrone.Core.Test.Datastore
var test = "small";
_subject = Where(x => x.CleanTitle.StartsWith(test));
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" LIKE @Clause1_P1 || '%')");
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" ILIKE @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@ -145,7 +145,7 @@ namespace NzbDrone.Core.Test.Datastore
var test = "small";
_subject = Where(x => x.CleanTitle.EndsWith(test));
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" LIKE '%' || @Clause1_P1)");
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" ILIKE '%' || @Clause1_P1)");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
@ -155,7 +155,7 @@ namespace NzbDrone.Core.Test.Datastore
var list = new List<int> { 1, 2, 3 };
_subject = Where(x => list.Contains(x.Id));
_subject.ToString().Should().Be($"(\"Series\".\"Id\" IN (1, 2, 3))");
_subject.ToString().Should().Be($"(\"Series\".\"Id\" = ANY (('{{1, 2, 3}}')))");
_subject.Parameters.ParameterNames.Should().BeEmpty();
}
@ -166,7 +166,7 @@ namespace NzbDrone.Core.Test.Datastore
var list = new List<int> { 1, 2, 3 };
_subject = Where(x => x.CleanTitle == "test" && list.Contains(x.Id));
_subject.ToString().Should().Be($"((\"Series\".\"CleanTitle\" = @Clause1_P1) AND (\"Series\".\"Id\" IN (1, 2, 3)))");
_subject.ToString().Should().Be($"((\"Series\".\"CleanTitle\" = @Clause1_P1) AND (\"Series\".\"Id\" = ANY (('{{1, 2, 3}}'))))");
}
[Test]
@ -176,7 +176,7 @@ namespace NzbDrone.Core.Test.Datastore
_subject = Where(x => list.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" IN @Clause1_P1)");
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" = ANY (@Clause1_P1))");
}
[Test]
@ -193,7 +193,7 @@ namespace NzbDrone.Core.Test.Datastore
var allowed = new List<SeriesStatusType> { SeriesStatusType.Upcoming, SeriesStatusType.Continuing };
_subject = Where(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Series\".\"Status\" IN @Clause1_P1)");
_subject.ToString().Should().Be($"(\"Series\".\"Status\" = ANY (@Clause1_P1))");
}
[Test]
@ -202,7 +202,7 @@ namespace NzbDrone.Core.Test.Datastore
var allowed = new SeriesStatusType[] { SeriesStatusType.Upcoming, SeriesStatusType.Continuing };
_subject = Where(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Series\".\"Status\" IN @Clause1_P1)");
_subject.ToString().Should().Be($"(\"Series\".\"Status\" = ANY (@Clause1_P1))");
}
}
}

@ -0,0 +1,198 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.Datastore
{
[TestFixture]
public class WhereBuilderSqliteFixture : CoreTest
{
private WhereBuilderSqlite _subject;
[OneTimeSetUp]
public void MapTables()
{
// Generate table mapping
Mocker.Resolve<DbFactory>();
}
private WhereBuilderSqlite Where(Expression<Func<Series, bool>> filter)
{
return new WhereBuilderSqlite(filter, true, 0);
}
[Test]
public void where_equal_const()
{
_subject = Where(x => x.Id == 10);
_subject.ToString().Should().Be($"(\"Series\".\"Id\" = @Clause1_P1)");
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(10);
}
[Test]
public void where_equal_variable()
{
var id = 10;
_subject = Where(x => x.Id == id);
_subject.ToString().Should().Be($"(\"Series\".\"Id\" = @Clause1_P1)");
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(id);
}
[Test]
public void where_equal_property()
{
var author = new Series { Id = 10 };
_subject = Where(x => x.Id == author.Id);
_subject.Parameters.ParameterNames.Should().HaveCount(1);
_subject.ToString().Should().Be($"(\"Series\".\"Id\" = @Clause1_P1)");
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(author.Id);
}
[Test]
public void where_equal_lazy_property()
{
_subject = Where(x => x.QualityProfile.Value.Id == 1);
_subject.Parameters.ParameterNames.Should().HaveCount(1);
_subject.ToString().Should().Be($"(\"QualityProfiles\".\"Id\" = @Clause1_P1)");
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(1);
}
[Test]
public void where_throws_without_concrete_condition_if_requiresConcreteCondition()
{
Expression<Func<Series, Series, bool>> filter = (x, y) => x.Id == y.Id;
_subject = new WhereBuilderSqlite(filter, true, 0);
Assert.Throws<InvalidOperationException>(() => _subject.ToString());
}
[Test]
public void where_allows_abstract_condition_if_not_requiresConcreteCondition()
{
Expression<Func<Series, Series, bool>> filter = (x, y) => x.Id == y.Id;
_subject = new WhereBuilderSqlite(filter, false, 0);
_subject.ToString().Should().Be($"(\"Series\".\"Id\" = \"Series\".\"Id\")");
}
[Test]
public void where_string_is_null()
{
_subject = Where(x => x.CleanTitle == null);
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" IS NULL)");
}
[Test]
public void where_string_is_null_value()
{
string imdb = null;
_subject = Where(x => x.CleanTitle == imdb);
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" IS NULL)");
}
[Test]
public void where_equal_null_property()
{
var author = new Series { CleanTitle = null };
_subject = Where(x => x.CleanTitle == author.CleanTitle);
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" IS NULL)");
}
[Test]
public void where_column_contains_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.Contains(test));
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" LIKE '%' || @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
[Test]
public void where_string_contains_column()
{
var test = "small";
_subject = Where(x => test.Contains(x.CleanTitle));
_subject.ToString().Should().Be($"(@Clause1_P1 LIKE '%' || \"Series\".\"CleanTitle\" || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
[Test]
public void where_column_starts_with_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.StartsWith(test));
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" LIKE @Clause1_P1 || '%')");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
[Test]
public void where_column_ends_with_string()
{
var test = "small";
_subject = Where(x => x.CleanTitle.EndsWith(test));
_subject.ToString().Should().Be($"(\"Series\".\"CleanTitle\" LIKE '%' || @Clause1_P1)");
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
}
[Test]
public void where_in_list()
{
var list = new List<int> { 1, 2, 3 };
_subject = Where(x => list.Contains(x.Id));
_subject.ToString().Should().Be($"(\"Series\".\"Id\" IN (1, 2, 3))");
_subject.Parameters.ParameterNames.Should().BeEmpty();
}
[Test]
public void where_in_list_2()
{
var list = new List<int> { 1, 2, 3 };
_subject = Where(x => x.CleanTitle == "test" && list.Contains(x.Id));
_subject.ToString().Should().Be($"((\"Series\".\"CleanTitle\" = @Clause1_P1) AND (\"Series\".\"Id\" IN (1, 2, 3)))");
}
[Test]
public void enum_as_int()
{
_subject = Where(x => x.Status == SeriesStatusType.Continuing);
_subject.ToString().Should().Be($"(\"Series\".\"Status\" = @Clause1_P1)");
}
[Test]
public void enum_in_list()
{
var allowed = new List<SeriesStatusType> { SeriesStatusType.Continuing, SeriesStatusType.Ended };
_subject = Where(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Series\".\"Status\" IN @Clause1_P1)");
}
[Test]
public void enum_in_array()
{
var allowed = new SeriesStatusType[] { SeriesStatusType.Continuing, SeriesStatusType.Ended };
_subject = Where(x => allowed.Contains(x.Status));
_subject.ToString().Should().Be($"(\"Series\".\"Status\" IN @Clause1_P1)");
}
}
}

@ -1,14 +1,18 @@
using System;
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Npgsql;
using NUnit.Framework;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Test.Common.Datastore;
namespace NzbDrone.Core.Test.Framework
{
@ -49,6 +53,7 @@ namespace NzbDrone.Core.Test.Framework
public abstract class DbTest : CoreTest
{
private ITestDatabase _db;
private DatabaseType _databaseType;
protected virtual MigrationType MigrationType => MigrationType.Main;
@ -101,17 +106,39 @@ namespace NzbDrone.Core.Test.Framework
private IDatabase CreateDatabase(MigrationContext migrationContext)
{
if (_databaseType == DatabaseType.PostgreSQL)
{
CreatePostgresDb();
}
var factory = Mocker.Resolve<DbFactory>();
// If a special migration test or log migration then create new
if (migrationContext.BeforeMigration != null)
if (migrationContext.BeforeMigration != null || _databaseType == DatabaseType.PostgreSQL)
{
return factory.Create(migrationContext);
}
return CreateSqliteDatabase(factory, migrationContext);
}
private void CreatePostgresDb()
{
var options = Mocker.Resolve<IOptions<PostgresOptions>>().Value;
PostgresDatabase.Create(options, MigrationType);
}
private void DropPostgresDb()
{
var options = Mocker.Resolve<IOptions<PostgresOptions>>().Value;
PostgresDatabase.Drop(options, MigrationType);
}
private IDatabase CreateSqliteDatabase(IDbFactory factory, MigrationContext migrationContext)
{
// Otherwise try to use a cached migrated db
var cachedDb = GetCachedDatabase(migrationContext.MigrationType);
var testDb = GetTestDb(migrationContext.MigrationType);
var cachedDb = SqliteDatabase.GetCachedDb(migrationContext.MigrationType);
var testDb = GetTestSqliteDb(migrationContext.MigrationType);
if (File.Exists(cachedDb))
{
TestLogger.Info($"Using cached initial database {cachedDb}");
@ -131,12 +158,7 @@ namespace NzbDrone.Core.Test.Framework
}
}
private string GetCachedDatabase(MigrationType type)
{
return Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_{type}.db");
}
private string GetTestDb(MigrationType type)
private string GetTestSqliteDb(MigrationType type)
{
return type == MigrationType.Main ? TestFolderInfo.GetDatabase() : TestFolderInfo.GetLogDatabase();
}
@ -151,6 +173,13 @@ namespace NzbDrone.Core.Test.Framework
WithTempAsAppPath();
SetupLogging();
// populate the possible postgres options
var postgresOptions = PostgresDatabase.GetTestOptions();
_databaseType = postgresOptions.Host.IsNotNullOrWhiteSpace() ? DatabaseType.PostgreSQL : DatabaseType.SQLite;
// Set up remaining container services
Mocker.SetConstant(Options.Create(postgresOptions));
Mocker.SetConstant<IConfigFileProvider>(Mocker.Resolve<ConfigFileProvider>());
Mocker.SetConstant<IConnectionStringFactory>(Mocker.Resolve<ConnectionStringFactory>());
Mocker.SetConstant<IMigrationController>(Mocker.Resolve<MigrationController>());
@ -170,12 +199,19 @@ namespace NzbDrone.Core.Test.Framework
// Make sure there are no lingering connections. (When this happens it means we haven't disposed something properly)
GC.Collect();
GC.WaitForPendingFinalizers();
SQLiteConnection.ClearAllPools();
NpgsqlConnection.ClearAllPools();
if (TestFolderInfo != null)
{
DeleteTempFolder(TestFolderInfo.AppDataFolder);
}
if (_databaseType == DatabaseType.PostgreSQL)
{
DropPostgresDb();
}
}
}
}

@ -1,5 +1,7 @@
using System.IO;
using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Test.Common.Datastore;
namespace NzbDrone.Core.Test
{
@ -10,13 +12,13 @@ namespace NzbDrone.Core.Test
[OneTimeTearDown]
public void ClearCachedDatabase()
{
var mainCache = Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_Main.db");
var mainCache = SqliteDatabase.GetCachedDb(MigrationType.Main);
if (File.Exists(mainCache))
{
File.Delete(mainCache);
}
var logCache = Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_Log.db");
var logCache = SqliteDatabase.GetCachedDb(MigrationType.Log);
if (File.Exists(logCache))
{
File.Delete(logCache);

@ -23,6 +23,7 @@ namespace NzbDrone.Core.Test.Framework
where T : ModelBase, new();
IDirectDataMapper GetDirectDataMapper();
IDbConnection OpenConnection();
DatabaseType DatabaseType { get; }
}
public class TestDatabase : ITestDatabase
@ -30,6 +31,8 @@ namespace NzbDrone.Core.Test.Framework
private readonly IDatabase _dbConnection;
private readonly IEventAggregator _eventAggregator;
public DatabaseType DatabaseType => _dbConnection.DatabaseType;
public TestDatabase(IDatabase dbConnection)
{
_eventAggregator = new Mock<IEventAggregator>().Object;

@ -78,7 +78,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
var stats = Subject.SeriesStatistics();
stats.Should().HaveCount(1);
stats.First().NextAiring.Should().Be(_episode.AirDateUtc);
stats.First().NextAiring.Should().BeCloseTo(_episode.AirDateUtc.Value, TimeSpan.FromMilliseconds(1000));
stats.First().PreviousAiring.Should().NotHaveValue();
}
@ -105,7 +105,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
stats.Should().HaveCount(1);
stats.First().NextAiring.Should().NotHaveValue();
stats.First().PreviousAiring.Should().Be(_episode.AirDateUtc);
stats.First().PreviousAiring.Should().BeCloseTo(_episode.AirDateUtc.Value, TimeSpan.FromMilliseconds(1000));
}
[Test]
@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.SeriesStatsTests
stats.Should().HaveCount(1);
stats.First().NextAiring.Should().NotHaveValue();
stats.First().PreviousAiring.Should().Be(_episode.AirDateUtc);
stats.First().PreviousAiring.Should().BeCloseTo(_episode.AirDateUtc.Value, TimeSpan.FromMilliseconds(1000));
}
[Test]

@ -189,9 +189,12 @@ namespace NzbDrone.Core.Backup
private void BackupDatabase()
{
_logger.ProgressDebug("Backing up database");
if (_maindDb.DatabaseType == DatabaseType.SQLite)
{
_logger.ProgressDebug("Backing up database");
_makeDatabaseBackup.BackupDatabase(_maindDb, _backupTempFolder);
_makeDatabaseBackup.BackupDatabase(_maindDb, _backupTempFolder);
}
}
private void BackupConfigFile()

@ -40,7 +40,7 @@ namespace NzbDrone.Core.Blocklisting
Delete(x => seriesIds.Contains(x.SeriesId));
}
protected override SqlBuilder PagedBuilder() => new SqlBuilder().Join<Blocklist, Series>((b, m) => b.SeriesId == m.Id);
protected override SqlBuilder PagedBuilder() => new SqlBuilder(_database.DatabaseType).Join<Blocklist, Series>((b, m) => b.SeriesId == m.Id);
protected override IEnumerable<Blocklist> PagedQuery(SqlBuilder sql) => _database.QueryJoined<Blocklist, Series>(sql, (bl, movie) =>
{
bl.Series = movie;

@ -5,12 +5,14 @@ using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Extensions.Options;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Authentication;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
@ -52,6 +54,12 @@ namespace NzbDrone.Core.Configuration
int SyslogPort { get; }
string SyslogLevel { get; }
string Theme { get; }
string PostgresHost { get; }
int PostgresPort { get; }
string PostgresUser { get; }
string PostgresPassword { get; }
string PostgresMainDb { get; }
string PostgresLogDb { get; }
}
public class ConfigFileProvider : IConfigFileProvider
@ -61,6 +69,7 @@ namespace NzbDrone.Core.Configuration
private readonly IEventAggregator _eventAggregator;
private readonly IDiskProvider _diskProvider;
private readonly ICached<string> _cache;
private readonly PostgresOptions _postgresOptions;
private readonly string _configFile;
private static readonly Regex HiddenCharacterRegex = new Regex("[^a-z0-9]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
@ -70,12 +79,14 @@ namespace NzbDrone.Core.Configuration
public ConfigFileProvider(IAppFolderInfo appFolderInfo,
ICacheManager cacheManager,
IEventAggregator eventAggregator,
IDiskProvider diskProvider)
IDiskProvider diskProvider,
IOptions<PostgresOptions> postgresOptions)
{
_cache = cacheManager.GetCache<string>(GetType());
_eventAggregator = eventAggregator;
_diskProvider = diskProvider;
_configFile = appFolderInfo.GetConfigPath();
_postgresOptions = postgresOptions.Value;
}
public Dictionary<string, object> GetConfigDictionary()
@ -191,6 +202,14 @@ namespace NzbDrone.Core.Configuration
public string ConsoleLogLevel => GetValue("ConsoleLogLevel", string.Empty, persist: false);
public string Theme => GetValue("Theme", "auto", persist: false);
public string PostgresHost => _postgresOptions?.Host ?? GetValue("PostgresHost", string.Empty, persist: false);
public string PostgresUser => _postgresOptions?.User ?? GetValue("PostgresUser", string.Empty, persist: false);
public string PostgresPassword => _postgresOptions?.Password ?? GetValue("PostgresPassword", string.Empty, persist: false);
public string PostgresMainDb => _postgresOptions?.MainDb ?? GetValue("PostgresMainDb", "sonarr-main", persist: false);
public string PostgresLogDb => _postgresOptions?.LogDb ?? GetValue("PostgresLogDb", "sonarr-log", persist: false);
public int PostgresPort => (_postgresOptions?.Port ?? 0) != 0 ? _postgresOptions.Port : GetValueInt("PostgresPort", 5432, persist: false);
public bool LogSql => GetValueBoolean("LogSql", false, persist: false);
public int LogRotate => GetValueInt("LogRotate", 50, persist: false);
public bool FilterSentryEvents => GetValueBoolean("FilterSentryEvents", true, persist: false);

@ -67,7 +67,7 @@ namespace NzbDrone.Core.Datastore
_updateSql = GetUpdateSql(_properties);
}
protected virtual SqlBuilder Builder() => new SqlBuilder();
protected virtual SqlBuilder Builder() => new SqlBuilder(_database.DatabaseType);
protected virtual List<TModel> Query(SqlBuilder builder) => _database.Query<TModel>(builder).ToList();
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Datastore
{
using (var conn = _database.OpenConnection())
{
return conn.ExecuteScalar<int>($"SELECT COUNT(*) FROM {_table}");
return conn.ExecuteScalar<int>($"SELECT COUNT(*) FROM \"{_table}\"");
}
}
@ -175,6 +175,11 @@ namespace NzbDrone.Core.Datastore
}
}
if (_database.DatabaseType == DatabaseType.PostgreSQL)
{
return $"INSERT INTO \"{_table}\" ({sbColumnList.ToString()}) VALUES ({sbParameterList.ToString()}) RETURNING \"Id\"";
}
return $"INSERT INTO {_table} ({sbColumnList.ToString()}) VALUES ({sbParameterList.ToString()}); SELECT last_insert_rowid() id";
}
@ -182,7 +187,8 @@ namespace NzbDrone.Core.Datastore
{
SqlBuilderExtensions.LogQuery(_insertSql, model);
var multi = connection.QueryMultiple(_insertSql, model, transaction);
var id = (int)multi.Read().First().id;
var multiRead = multi.Read();
var id = (int)(multiRead.First().id ?? multiRead.First().Id);
_keyProperty.SetValue(model, id);
return model;
@ -293,7 +299,7 @@ namespace NzbDrone.Core.Datastore
{
using (var conn = _database.OpenConnection())
{
conn.Execute($"DELETE FROM [{_table}]");
conn.Execute($"DELETE FROM \"{_table}\"");
}
if (vacuum)
@ -352,7 +358,7 @@ namespace NzbDrone.Core.Datastore
private string GetUpdateSql(List<PropertyInfo> propertiesToUpdate)
{
var sb = new StringBuilder();
sb.AppendFormat("UPDATE {0} SET ", _table);
sb.AppendFormat("UPDATE \"{0}\" SET ", _table);
for (var i = 0; i < propertiesToUpdate.Count; i++)
{
@ -420,9 +426,10 @@ namespace NzbDrone.Core.Datastore
pagingSpec.SortKey = $"{_table}.{_keyProperty.Name}";
}
var sortKey = TableMapping.Mapper.GetSortKey(pagingSpec.SortKey);
var sortDirection = pagingSpec.SortDirection == SortDirection.Descending ? "DESC" : "ASC";
var pagingOffset = (pagingSpec.Page - 1) * pagingSpec.PageSize;
builder.OrderBy($"{pagingSpec.SortKey} {sortDirection} LIMIT {pagingSpec.PageSize} OFFSET {pagingOffset}");
var pagingOffset = Math.Max(pagingSpec.Page - 1, 0) * pagingSpec.PageSize;
builder.OrderBy($"\"{sortKey}\" {sortDirection} LIMIT {pagingSpec.PageSize} OFFSET {pagingOffset}");
return queryFunc(builder).ToList();
}

@ -1,27 +1,36 @@
using System;
using System;
using System.Data.SQLite;
using Npgsql;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Core.Datastore
{
public interface IConnectionStringFactory
{
string MainDbConnectionString { get; }
string LogDbConnectionString { get; }
DatabaseConnectionInfo MainDbConnection { get; }
DatabaseConnectionInfo LogDbConnection { get; }
string GetDatabasePath(string connectionString);
}
public class ConnectionStringFactory : IConnectionStringFactory
{
public ConnectionStringFactory(IAppFolderInfo appFolderInfo)
private readonly IConfigFileProvider _configFileProvider;
public ConnectionStringFactory(IAppFolderInfo appFolderInfo, IConfigFileProvider configFileProvider)
{
MainDbConnectionString = GetConnectionString(appFolderInfo.GetDatabase());
LogDbConnectionString = GetConnectionString(appFolderInfo.GetLogDatabase());
_configFileProvider = configFileProvider;
MainDbConnection = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresMainDb) :
GetConnectionString(appFolderInfo.GetDatabase());
LogDbConnection = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresLogDb) :
GetConnectionString(appFolderInfo.GetLogDatabase());
}
public string MainDbConnectionString { get; private set; }
public string LogDbConnectionString { get; private set; }
public DatabaseConnectionInfo MainDbConnection { get; private set; }
public DatabaseConnectionInfo LogDbConnection { get; private set; }
public string GetDatabasePath(string connectionString)
{
@ -30,23 +39,39 @@ namespace NzbDrone.Core.Datastore
return connectionBuilder.DataSource;
}
private static string GetConnectionString(string dbPath)
private static DatabaseConnectionInfo GetConnectionString(string dbPath)
{
var connectionBuilder = new SQLiteConnectionStringBuilder();
connectionBuilder.DataSource = dbPath;
connectionBuilder.CacheSize = (int)-10000;
connectionBuilder.DateTimeKind = DateTimeKind.Utc;
connectionBuilder.JournalMode = OsInfo.IsOsx ? SQLiteJournalModeEnum.Truncate : SQLiteJournalModeEnum.Wal;
connectionBuilder.Pooling = true;
connectionBuilder.Version = 3;
var connectionBuilder = new SQLiteConnectionStringBuilder
{
DataSource = dbPath,
CacheSize = (int)-10000,
DateTimeKind = DateTimeKind.Utc,
JournalMode = OsInfo.IsOsx ? SQLiteJournalModeEnum.Truncate : SQLiteJournalModeEnum.Wal,
Pooling = true,
Version = 3
};
if (OsInfo.IsOsx)
{
connectionBuilder.Add("Full FSync", true);
}
return connectionBuilder.ConnectionString;
return new DatabaseConnectionInfo(DatabaseType.SQLite, connectionBuilder.ConnectionString);
}
private DatabaseConnectionInfo GetPostgresConnectionString(string dbName)
{
var connectionBuilder = new NpgsqlConnectionStringBuilder
{
Database = dbName,
Host = _configFileProvider.PostgresHost,
Username = _configFileProvider.PostgresUser,
Password = _configFileProvider.PostgresPassword,
Port = _configFileProvider.PostgresPort,
Enlist = false
};
return new DatabaseConnectionInfo(DatabaseType.PostgreSQL, connectionBuilder.ConnectionString);
}
}
}

@ -1,5 +1,8 @@
using System;
using System;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.Text.RegularExpressions;
using Dapper;
using NLog;
using NzbDrone.Common.Instrumentation;
@ -11,6 +14,7 @@ namespace NzbDrone.Core.Datastore
IDbConnection OpenConnection();
Version Version { get; }
int Migration { get; }
DatabaseType DatabaseType { get; }
void Vacuum();
}
@ -32,15 +36,25 @@ namespace NzbDrone.Core.Datastore
return _datamapperFactory();
}
public DatabaseType DatabaseType
{
get
{
using var db = _datamapperFactory();
return db is SQLiteConnection ? DatabaseType.SQLite : DatabaseType.PostgreSQL;
}
}
public Version Version
{
get
{
using (var db = _datamapperFactory())
{
var version = db.QueryFirstOrDefault<string>("SELECT sqlite_version()");
return new Version(version);
}
using var db = _datamapperFactory();
var dbConnection = db as DbConnection;
var version = Regex.Replace(dbConnection.ServerVersion, @"\(.*?\)", "");
return new Version(version);
}
}
@ -50,7 +64,7 @@ namespace NzbDrone.Core.Datastore
{
using (var db = _datamapperFactory())
{
return db.QueryFirstOrDefault<int>("SELECT version from VersionInfo ORDER BY version DESC LIMIT 1");
return db.QueryFirstOrDefault<int>("SELECT \"Version\" from \"VersionInfo\" ORDER BY \"Version\" DESC LIMIT 1");
}
}
}
@ -73,4 +87,10 @@ namespace NzbDrone.Core.Datastore
}
}
}
public enum DatabaseType
{
SQLite,
PostgreSQL
}
}

@ -0,0 +1,14 @@
namespace NzbDrone.Core.Datastore
{
public class DatabaseConnectionInfo
{
public DatabaseConnectionInfo(DatabaseType databaseType, string connectionString)
{
DatabaseType = databaseType;
ConnectionString = connectionString;
}
public DatabaseType DatabaseType { get; internal set; }
public string ConnectionString { get; internal set; }
}
}

@ -1,6 +1,10 @@
using System;
using System.Data.Common;
using System.Data.SQLite;
using System.Net.Sockets;
using System.Threading;
using NLog;
using Npgsql;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Exceptions;
@ -57,22 +61,22 @@ namespace NzbDrone.Core.Datastore
public IDatabase Create(MigrationContext migrationContext)
{
string connectionString;
DatabaseConnectionInfo connectionInfo;
switch (migrationContext.MigrationType)
{
case MigrationType.Main:
{
connectionString = _connectionStringFactory.MainDbConnectionString;
CreateMain(connectionString, migrationContext);
connectionInfo = _connectionStringFactory.MainDbConnection;
CreateMain(connectionInfo.ConnectionString, migrationContext);
break;
}
case MigrationType.Log:
{
connectionString = _connectionStringFactory.LogDbConnectionString;
CreateLog(connectionString, migrationContext);
connectionInfo = _connectionStringFactory.LogDbConnection;
CreateLog(connectionInfo.ConnectionString, migrationContext);
break;
}
@ -85,10 +89,19 @@ namespace NzbDrone.Core.Datastore
var db = new Database(migrationContext.MigrationType.ToString(), () =>
{
var conn = SQLiteFactory.Instance.CreateConnection();
conn.ConnectionString = connectionString;
conn.Open();
DbConnection conn;
if (connectionInfo.DatabaseType == DatabaseType.SQLite)
{
conn = SQLiteFactory.Instance.CreateConnection();
conn.ConnectionString = connectionInfo.ConnectionString;
}
else
{
conn = new NpgsqlConnection(connectionInfo.ConnectionString);
}
conn.Open();
return conn;
});
@ -113,6 +126,39 @@ namespace NzbDrone.Core.Datastore
throw new CorruptDatabaseException("Database file: {0} is corrupt, restore from backup if available. See: https://wiki.servarr.com/sonarr/faq#i-am-getting-an-error-database-disk-image-is-malformed", e, fileName);
}
catch (NpgsqlException e)
{
if (e.InnerException is SocketException)
{
var retryCount = 3;
while (true)
{
Logger.Error(e, "Failure to connect to Postgres DB, {0} retries remaining", retryCount);
Thread.Sleep(5000);
try
{
_migrationController.Migrate(connectionString, migrationContext);
return;
}
catch (Exception ex)
{
if (--retryCount > 0)
{
continue;
}
throw new SonarrStartupException(ex, "Error creating main database");
}
}
}
else
{
throw new SonarrStartupException(e, "Error creating main database");
}
}
catch (Exception e)
{
throw new SonarrStartupException(e, "Error creating main database");

@ -20,12 +20,12 @@ namespace NzbDrone.Core.Datastore
public static SqlBuilder Select(this SqlBuilder builder, params Type[] types)
{
return builder.Select(types.Select(x => TableMapping.Mapper.TableNameMapping(x) + ".*").Join(", "));
return builder.Select(types.Select(x => $"\"{TableMapping.Mapper.TableNameMapping(x)}\".*").Join(", "));
}
public static SqlBuilder SelectDistinct(this SqlBuilder builder, params Type[] types)
{
return builder.Select("DISTINCT " + types.Select(x => TableMapping.Mapper.TableNameMapping(x) + ".*").Join(", "));
return builder.Select("DISTINCT " + types.Select(x => $"\"{TableMapping.Mapper.TableNameMapping(x)}\".*").Join(", "));
}
public static SqlBuilder SelectCount(this SqlBuilder builder)
@ -42,41 +42,48 @@ namespace NzbDrone.Core.Datastore
public static SqlBuilder Where<TModel>(this SqlBuilder builder, Expression<Func<TModel, bool>> filter)
{
var wb = new WhereBuilder(filter, true, builder.Sequence);
var wb = GetWhereBuilder(builder.DatabaseType, filter, true, builder.Sequence);
return builder.Where(wb.ToString(), wb.Parameters);
}
public static SqlBuilder WherePostgres<TModel>(this SqlBuilder builder, Expression<Func<TModel, bool>> filter)
{
var wb = new WhereBuilderPostgres(filter, true, builder.Sequence);
return builder.Where(wb.ToString(), wb.Parameters);
}
public static SqlBuilder OrWhere<TModel>(this SqlBuilder builder, Expression<Func<TModel, bool>> filter)
{
var wb = new WhereBuilder(filter, true, builder.Sequence);
var wb = GetWhereBuilder(builder.DatabaseType, filter, true, builder.Sequence);
return builder.OrWhere(wb.ToString(), wb.Parameters);
}
public static SqlBuilder Join<TLeft, TRight>(this SqlBuilder builder, Expression<Func<TLeft, TRight, bool>> filter)
{
var wb = new WhereBuilder(filter, false, builder.Sequence);
var wb = GetWhereBuilder(builder.DatabaseType, filter, false, builder.Sequence);
var rightTable = TableMapping.Mapper.TableNameMapping(typeof(TRight));
return builder.Join($"{rightTable} ON {wb.ToString()}");
return builder.Join($"\"{rightTable}\" ON {wb.ToString()}");
}
public static SqlBuilder LeftJoin<TLeft, TRight>(this SqlBuilder builder, Expression<Func<TLeft, TRight, bool>> filter)
{
var wb = new WhereBuilder(filter, false, builder.Sequence);
var wb = GetWhereBuilder(builder.DatabaseType, filter, false, builder.Sequence);
var rightTable = TableMapping.Mapper.TableNameMapping(typeof(TRight));
return builder.LeftJoin($"{rightTable} ON {wb.ToString()}");
return builder.LeftJoin($"\"{rightTable}\" ON {wb.ToString()}");
}
public static SqlBuilder GroupBy<TModel>(this SqlBuilder builder, Expression<Func<TModel, object>> property)
{
var table = TableMapping.Mapper.TableNameMapping(typeof(TModel));
var propName = property.GetMemberName().Name;
return builder.GroupBy($"{table}.{propName}");
return builder.GroupBy($"\"{table}\".\"{propName}\"");
}
public static SqlBuilder.Template AddSelectTemplate(this SqlBuilder builder, Type type)
@ -138,6 +145,18 @@ namespace NzbDrone.Core.Datastore
return sb.ToString();
}
private static WhereBuilder GetWhereBuilder(DatabaseType databaseType, Expression filter, bool requireConcrete, int seq)
{
if (databaseType == DatabaseType.PostgreSQL)
{
return new WhereBuilderPostgres(filter, requireConcrete, seq);
}
else
{
return new WhereBuilderSqlite(filter, requireConcrete, seq);
}
}
private static Dictionary<string, object> ToDictionary(this DynamicParameters dynamicParams)
{
var argsDictionary = new Dictionary<string, object>();
@ -150,11 +169,14 @@ namespace NzbDrone.Core.Datastore
}
var templates = dynamicParams.GetType().GetField("templates", BindingFlags.NonPublic | BindingFlags.Instance);
if (templates != null && templates.GetValue(dynamicParams) is List<object> list)
if (templates != null)
{
foreach (var objProps in list.Select(obj => obj.GetPropertyValuePairs().ToList()))
if (templates.GetValue(dynamicParams) is List<object> list)
{
objProps.ForEach(p => argsDictionary.Add(p.Key, p.Value));
foreach (var objProps in list.Select(obj => obj.GetPropertyValuePairs().ToList()))
{
objProps.ForEach(p => argsDictionary.Add(p.Key, p.Value));
}
}
}

@ -10,10 +10,12 @@ namespace NzbDrone.Core.Datastore
public class LogDatabase : ILogDatabase
{
private readonly IDatabase _database;
private readonly DatabaseType _databaseType;
public LogDatabase(IDatabase database)
{
_database = database;
_databaseType = _database == null ? DatabaseType.SQLite : _database.DatabaseType;
}
public IDbConnection OpenConnection()
@ -25,6 +27,8 @@ namespace NzbDrone.Core.Datastore
public int Migration => _database.Migration;
public DatabaseType DatabaseType => _databaseType;
public void Vacuum()
{
_database.Vacuum();

@ -10,10 +10,12 @@ namespace NzbDrone.Core.Datastore
public class MainDatabase : IMainDatabase
{
private readonly IDatabase _database;
private readonly DatabaseType _databaseType;
public MainDatabase(IDatabase database)
{
_database = database;
_databaseType = _database == null ? DatabaseType.SQLite : _database.DatabaseType;
}
public IDbConnection OpenConnection()
@ -25,6 +27,8 @@ namespace NzbDrone.Core.Datastore
public int Migration => _database.Migration;
public DatabaseType DatabaseType => _databaseType;
public void Vacuum()
{
_database.Vacuum();

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -13,7 +13,7 @@ namespace NzbDrone.Core.Datastore.Migration
.AsBoolean()
.Nullable();
Execute.Sql("UPDATE NamingConfig SET RenameEpisodes =~ UseSceneName");
Execute.Sql("UPDATE \"NamingConfig\" SET \"RenameEpisodes\" = NOT \"UseSceneName\"");
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -10,8 +10,8 @@ namespace NzbDrone.Core.Datastore.Migration
{
Delete.Column("SeasonFolderFormat").FromTable("NamingConfig");
Execute.Sql("UPDATE NamingConfig SET RenameEpisodes = 1 WHERE RenameEpisodes = -1");
Execute.Sql("UPDATE NamingConfig SET RenameEpisodes = 0 WHERE RenameEpisodes = -2");
IfDatabase("sqlite").Update.Table("NamingConfig").Set(new { RenameEpisodes = 1 }).Where(new { RenameEpisodes = -1 });
IfDatabase("sqlite").Update.Table("NamingConfig").Set(new { RenameEpisodes = 0 }).Where(new { RenameEpisodes = -2 });
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -11,11 +11,11 @@ namespace NzbDrone.Core.Datastore.Migration
Alter.Table("Episodes").AddColumn("Monitored").AsBoolean().Nullable();
Alter.Table("Seasons").AddColumn("Monitored").AsBoolean().Nullable();
Execute.Sql("UPDATE Episodes SET Monitored = 1 WHERE Ignored = 0");
Execute.Sql("UPDATE Episodes SET Monitored = 0 WHERE Ignored = 1");
Update.Table("Episodes").Set(new { Monitored = true }).Where(new { Ignored = false });
Update.Table("Episodes").Set(new { Monitored = false }).Where(new { Ignored = true });
Execute.Sql("UPDATE Seasons SET Monitored = 1 WHERE Ignored = 0");
Execute.Sql("UPDATE Seasons SET Monitored = 0 WHERE Ignored = 1");
Update.Table("Seasons").Set(new { Monitored = true }).Where(new { Ignored = false });
Update.Table("Seasons").Set(new { Monitored = false }).Where(new { Ignored = true });
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -10,7 +10,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
Alter.Table("Episodes").AddColumn("AirDateUtc").AsDateTime().Nullable();
Execute.Sql("UPDATE Episodes SET AirDateUtc = AirDate");
Execute.Sql("UPDATE \"Episodes\" SET \"AirDateUtc\" = \"AirDate\"");
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql(@"UPDATE HISTORY SET Data = replace( Data, '""Path""', '""ImportedPath""' ) WHERE EventType=3");
Execute.Sql("UPDATE \"History\" SET \"Data\" = replace( \"Data\", '\"Path\"', '\"ImportedPath\"' ) WHERE \"EventType\" = 3");
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -9,7 +9,7 @@ namespace NzbDrone.Core.Datastore.Migration
protected override void MainDbUpgrade()
{
// we were storing new file name as scene name.
Execute.Sql(@"UPDATE EpisodeFiles SET SceneName = NULL where SceneName != NULL");
Execute.Sql("UPDATE \"EpisodeFiles\" SET \"SceneName\" = NULL where \"SceneName\" != NULL");
}
}
}

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
@ -35,7 +35,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
var getDuplicates = conn.CreateCommand();
getDuplicates.Transaction = tran;
getDuplicates.CommandText = string.Format("select id, {0} from {1}", columnName, tableName);
getDuplicates.CommandText = string.Format("SELECT \"Id\", \"{0}\" from \"{1}\"", columnName, tableName);
var result = new List<KeyValuePair<int, T>>();
@ -68,19 +68,19 @@ namespace NzbDrone.Core.Datastore.Migration
var deleteCmd = conn.CreateCommand();
deleteCmd.Transaction = tran;
deleteCmd.CommandText = string.Format("DELETE FROM Series WHERE Id = {0}", seriesId.ToString());
deleteCmd.CommandText = string.Format("DELETE FROM \"Series\" WHERE \"Id\" = {0}", seriesId.ToString());
deleteCmd.ExecuteNonQuery();
deleteCmd.CommandText = string.Format("DELETE FROM Episodes WHERE SeriesId = {0}", seriesId.ToString());
deleteCmd.CommandText = string.Format("DELETE FROM \"Episodes\" WHERE \"SeriesId\" = {0}", seriesId.ToString());
deleteCmd.ExecuteNonQuery();
deleteCmd.CommandText = string.Format("DELETE FROM Seasons WHERE SeriesId = {0}", seriesId.ToString());
deleteCmd.CommandText = string.Format("DELETE FROM \"Seasons\" WHERE \"SeriesId\" = {0}", seriesId.ToString());
deleteCmd.ExecuteNonQuery();
deleteCmd.CommandText = string.Format("DELETE FROM History WHERE SeriesId = {0}", seriesId.ToString());
deleteCmd.CommandText = string.Format("DELETE FROM \"History\" WHERE \"SeriesId\" = {0}", seriesId.ToString());
deleteCmd.ExecuteNonQuery();
deleteCmd.CommandText = string.Format("DELETE FROM EpisodeFiles WHERE SeriesId = {0}", seriesId.ToString());
deleteCmd.CommandText = string.Format("DELETE FROM \"EpisodeFiles\" WHERE \"SeriesId\" = {0}", seriesId.ToString());
deleteCmd.ExecuteNonQuery();
}
@ -89,10 +89,10 @@ namespace NzbDrone.Core.Datastore.Migration
var deleteCmd = conn.CreateCommand();
deleteCmd.Transaction = tran;
deleteCmd.CommandText = string.Format("DELETE FROM Episodes WHERE Id = {0}", episodeId.ToString());
deleteCmd.CommandText = string.Format("DELETE FROM \"Episodes\" WHERE \"Id\" = {0}", episodeId.ToString());
deleteCmd.ExecuteNonQuery();
deleteCmd.CommandText = string.Format("DELETE FROM History WHERE EpisodeId = {0}", episodeId.ToString());
deleteCmd.CommandText = string.Format("DELETE FROM \"History\" WHERE \"EpisodeId\" = {0}", episodeId.ToString());
deleteCmd.ExecuteNonQuery();
}
}

@ -22,7 +22,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var allSeriesCmd = conn.CreateCommand())
{
allSeriesCmd.Transaction = tran;
allSeriesCmd.CommandText = @"SELECT Id FROM Series";
allSeriesCmd.CommandText = "SELECT \"Id\" FROM \"Series\"";
using (var allSeriesReader = allSeriesCmd.ExecuteReader())
{
while (allSeriesReader.Read())
@ -33,7 +33,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var seasonsCmd = conn.CreateCommand())
{
seasonsCmd.Transaction = tran;
seasonsCmd.CommandText = string.Format(@"SELECT SeasonNumber, Monitored FROM Seasons WHERE SeriesId = {0}", seriesId);
seasonsCmd.CommandText = $"SELECT \"SeasonNumber\", \"Monitored\" FROM \"Seasons\" WHERE \"SeriesId\" = {seriesId}";
using (var seasonReader = seasonsCmd.ExecuteReader())
{
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
var text = string.Format("UPDATE Series SET Seasons = '{0}' WHERE Id = {1}", seasons.ToJson(), seriesId);
var text = $"UPDATE \"Series\" SET \"Seasons\" = '{seasons.ToJson()}' WHERE \"Id\" = {seriesId}";
updateCmd.Transaction = tran;
updateCmd.CommandText = text;

@ -22,7 +22,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var namingConfigCmd = conn.CreateCommand())
{
namingConfigCmd.Transaction = tran;
namingConfigCmd.CommandText = @"SELECT * FROM NamingConfig LIMIT 1";
namingConfigCmd.CommandText = "SELECT * FROM \"NamingConfig\" LIMIT 1";
using (var namingConfigReader = namingConfigCmd.ExecuteReader())
{
var separatorIndex = namingConfigReader.GetOrdinal("Separator");
@ -98,9 +98,9 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
var text = string.Format("UPDATE NamingConfig " +
"SET StandardEpisodeFormat = '{0}', " +
"DailyEpisodeFormat = '{1}'",
var text = string.Format("UPDATE \"NamingConfig\" " +
"SET \"StandardEpisodeFormat\" = '{0}', " +
"\"DailyEpisodeFormat\" = '{1}'",
standardEpisodeFormat,
dailyEpisodeFormat);

@ -11,8 +11,8 @@ namespace NzbDrone.Core.Datastore.Migration
{
Alter.Table("NamingConfig").AddColumn("SeasonFolderFormat").AsString().Nullable();
Execute.WithConnection(ConvertConfig);
Execute.Sql("DELETE FROM Config WHERE [Key] = 'seasonfolderformat'");
Execute.Sql("DELETE FROM Config WHERE [Key] = 'useseasonfolder'");
Execute.Sql("DELETE FROM \"Config\" WHERE \"Key\" = 'seasonfolderformat'");
Execute.Sql("DELETE FROM \"Config\" WHERE \"Key\" = 'useseasonfolder'");
}
private void ConvertConfig(IDbConnection conn, IDbTransaction tran)
@ -20,7 +20,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var namingConfigCmd = conn.CreateCommand())
{
namingConfigCmd.Transaction = tran;
namingConfigCmd.CommandText = @"SELECT [Value] FROM Config WHERE [Key] = 'seasonfolderformat'";
namingConfigCmd.CommandText = "SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'seasonfolderformat'";
var seasonFormat = "Season {season}";
using (var namingConfigReader = namingConfigCmd.ExecuteReader())
@ -41,8 +41,8 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
var text = string.Format("UPDATE NamingConfig " +
"SET SeasonFolderFormat = '{0}'",
var text = string.Format("UPDATE \"NamingConfig\" " +
"SET \"SeasonFolderFormat\" = '{0}'",
seasonFormat);
updateCmd.Transaction = tran;

@ -1,4 +1,5 @@
using FluentMigrator;
using System;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +9,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("UPDATE EpisodeFiles SET ReleaseGroup = 'DRONE' WHERE ReleaseGroup IS NULL");
Update.Table("EpisodeFiles").Set(new { ReleaseGroup = "DRONE" }).Where(new { ReleaseGroup = DBNull.Value });
}
}
}

@ -20,7 +20,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var selectCommand = conn.CreateCommand())
{
selectCommand.Transaction = tran;
selectCommand.CommandText = @"SELECT * FROM Notifications WHERE ConfigContract = 'PushoverSettings'";
selectCommand.CommandText = "SELECT * FROM \"Notifications\" WHERE \"ConfigContract\" = 'PushoverSettings'";
using (var reader = selectCommand.ExecuteReader())
{
@ -41,9 +41,9 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
var text = string.Format("UPDATE Notifications " +
"SET Settings = '{0}'" +
"WHERE Id = {1}",
var text = string.Format("UPDATE \"Notifications\" " +
"SET \"Settings\" = '{0}'" +
"WHERE \"Id\" = {1}",
settings.ToJson(),
id);

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -10,7 +10,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
Alter.Table("NamingConfig").AddColumn("SeriesFolderFormat").AsString().Nullable();
Execute.Sql("UPDATE NamingConfig SET SeriesFolderFormat = '{Series Title}'");
Update.Table("NamingConfig").Set(new { SeriesFolderFormat = "{Series Title}" }).AllRows();
}
}
}

@ -32,7 +32,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var qualityProfileCmd = conn.CreateCommand())
{
qualityProfileCmd.Transaction = tran;
qualityProfileCmd.CommandText = @"SELECT Id, Allowed FROM QualityProfiles";
qualityProfileCmd.CommandText = "SELECT \"Id\", \"Allowed\" FROM \"QualityProfiles\"";
using (var qualityProfileReader = qualityProfileCmd.ExecuteReader())
{
while (qualityProfileReader.Read())
@ -47,7 +47,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE QualityProfiles SET Items = ? WHERE Id = ?";
updateCmd.CommandText = "UPDATE \"QualityProfiles\" SET \"Items\" = ? WHERE \"Id\" = ?";
var param = updateCmd.CreateParameter();
qualityProfileItemConverter.SetValue(param, items);
updateCmd.Parameters.Add(param);
@ -75,7 +75,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var qualityModelCmd = conn.CreateCommand())
{
qualityModelCmd.Transaction = tran;
qualityModelCmd.CommandText = @"SELECT Distinct Quality FROM " + tableName;
qualityModelCmd.CommandText = $"SELECT Distinct \"Quality\" FROM \"{tableName}\"";
using (var qualityModelReader = qualityModelCmd.ExecuteReader())
{
while (qualityModelReader.Read())
@ -96,7 +96,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE " + tableName + " SET Quality = ? WHERE Quality = ?";
updateCmd.CommandText = "UPDATE \"" + tableName + "\" SET \"Quality\" = ? WHERE \"Quality\" = ?";
var param = updateCmd.CreateParameter();
qualityModelConverter.SetValue(param, qualityNew);
updateCmd.Parameters.Add(param);

@ -33,7 +33,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var qualitySizeCmd = conn.CreateCommand())
{
qualitySizeCmd.Transaction = tran;
qualitySizeCmd.CommandText = @"SELECT QualityId, MinSize, MaxSize FROM QualitySizes";
qualitySizeCmd.CommandText = "SELECT \"QualityId\", \"MinSize\", \"MaxSize\" FROM \"QualitySizes\"";
using (var qualitySizeReader = qualitySizeCmd.ExecuteReader())
{
while (qualitySizeReader.Read())
@ -47,7 +47,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "INSERT INTO QualityDefinitions (Quality, Title, Weight, MinSize, MaxSize) VALUES (?, ?, ?, ?, ?)";
updateCmd.CommandText = "INSERT INTO \"QualityDefinitions\" (\"Quality\", \"Title\", \"Weight\", \"MinSize\", \"MaxSize\") VALUES (?, ?, ?, ?, ?)";
updateCmd.AddParameter(qualityId);
updateCmd.AddParameter(defaultConfig.Title);
updateCmd.AddParameter(defaultConfig.Weight);

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -10,7 +10,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
Alter.Table("Notifications").AddColumn("OnUpgrade").AsBoolean().Nullable();
Execute.Sql("UPDATE Notifications SET OnUpgrade = OnDownload");
Execute.Sql("UPDATE \"Notifications\" SET \"OnUpgrade\" = \"OnDownload\"");
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("UPDATE MetadataFiles SET Type = 4 WHERE Consumer = 'XbmcMetadata' AND SeasonNumber IS NOT NULL");
Execute.Sql("UPDATE \"MetadataFiles\" SET \"Type\" = 4 WHERE \"Consumer\" = 'XbmcMetadata' AND \"SeasonNumber\" IS NOT NULL");
}
}
}

@ -22,7 +22,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var configCmd = conn.CreateCommand())
{
configCmd.Transaction = tran;
configCmd.CommandText = @"SELECT * FROM Config";
configCmd.CommandText = "SELECT * FROM \"Config\"";
using (var configReader = configCmd.ExecuteReader())
{
var keyIndex = configReader.GetOrdinal("Key");
@ -121,7 +121,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
using (var updateCmd = conn.CreateCommand())
{
var text = string.Format("INSERT INTO DownloadClients (Enable, Name, Implementation, Settings, ConfigContract, Protocol) VALUES (1, ?, ?, ?, ?, ?)");
var text = string.Format("INSERT INTO \"DownloadClients\" (\"Enable\", \"Name\", \"Implementation\", \"Settings\", \"ConfigContract\", \"Protocol\") VALUES (1, ?, ?, ?, ?, ?)");
updateCmd.AddParameter(name);
updateCmd.AddParameter(implementation);
updateCmd.AddParameter(settings);
@ -138,7 +138,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
using (var updateCmd = conn.CreateCommand())
{
var text = "DELETE FROM Config WHERE [KEY] IN ('nzbgetusername', 'nzbgetpassword', 'nzbgethost', 'nzbgetport', " +
var text = "DELETE FROM \"Config\" WHERE [KEY] IN ('nzbgetusername', 'nzbgetpassword', 'nzbgethost', 'nzbgetport', " +
"'nzbgettvcategory', 'nzbgetrecenttvpriority', 'nzbgetoldertvpriority', 'sabhost', 'sabport', " +
"'sabapikey', 'sabusername', 'sabpassword', 'sabtvcategory', 'sabrecenttvpriority', " +
"'saboldertvpriority', 'sabusessl', 'downloadclient', 'blackholefolder', 'pneumaticfolder')";

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -9,19 +9,19 @@ namespace NzbDrone.Core.Datastore.Migration
protected override void MainDbUpgrade()
{
// Convert Episode Metadata to proper type
Execute.Sql("UPDATE MetadataFiles " +
"SET Type = 2 " +
"WHERE Consumer = 'XbmcMetadata' " +
"AND EpisodeFileId IS NOT NULL " +
"AND Type = 4 " +
"AND RelativePath LIKE '%.nfo'");
Execute.Sql("UPDATE \"MetadataFiles\" " +
"SET \"Type\" = 2 " +
"WHERE \"Consumer\" = 'XbmcMetadata' " +
"AND \"EpisodeFileId\" IS NOT NULL " +
"AND \"Type\" = 4 " +
"AND \"RelativePath\" LIKE '%.nfo'");
// Convert Episode Images to proper type
Execute.Sql("UPDATE MetadataFiles " +
"SET Type = 5 " +
"WHERE Consumer = 'XbmcMetadata' " +
"AND EpisodeFileId IS NOT NULL " +
"AND Type = 4");
Execute.Sql("UPDATE \"MetadataFiles\" " +
"SET \"Type\" = 5 " +
"WHERE \"Consumer\" = 'XbmcMetadata' " +
"AND \"EpisodeFileId\" IS NOT NULL " +
"AND \"Type\" = 4");
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,9 +8,9 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("UPDATE Indexers SET Settings = replace(Settings, '//nzb.su', '//api.nzb.su')" +
"WHERE Implementation = 'Newznab'" +
"AND Settings LIKE '%//nzb.su%'");
Execute.Sql("UPDATE \"Indexers\" SET \"Settings\" = replace(\"Settings\", '//nzb.su', '//api.nzb.su')" +
"WHERE \"Implementation\" = 'Newznab'" +
"AND \"Settings\" LIKE '%//nzb.su%'");
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,9 +8,9 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("UPDATE Indexers SET Settings = replace(Settings, '//dognzb.cr', '//api.dognzb.cr')" +
"WHERE Implementation = 'Newznab'" +
"AND Settings LIKE '%//dognzb.cr%'");
Execute.Sql("UPDATE \"Indexers\" SET \"Settings\" = replace(\"Settings\", '//dognzb.cr', '//api.dognzb.cr')" +
"WHERE \"Implementation\" = 'Newznab'" +
"AND \"Settings\" LIKE '%//dognzb.cr%'");
}
}
}

@ -27,13 +27,13 @@ namespace NzbDrone.Core.Datastore.Migration
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tran;
cmd.CommandText = @"SELECT Value FROM Config WHERE Key = 'downloadedepisodesfolder'";
cmd.CommandText = "SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'downloadedepisodesfolder'";
var result = cmd.ExecuteScalar();
if (result == null)
{
cmd.CommandText = @"INSERT INTO Config (Key, Value) VALUES ('enablecompleteddownloadhandling', 'True')";
cmd.CommandText = "INSERT INTO \"Config\" (\"Key\", \"Value\") VALUES ('enablecompleteddownloadhandling', 'True')";
cmd.ExecuteNonQuery();
}
}
@ -44,11 +44,11 @@ namespace NzbDrone.Core.Datastore.Migration
using (var downloadClientsCmd = conn.CreateCommand())
{
downloadClientsCmd.Transaction = tran;
downloadClientsCmd.CommandText = @"SELECT Value FROM Config WHERE Key = 'downloadedepisodesfolder'";
downloadClientsCmd.CommandText = "SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'downloadedepisodesfolder'";
var downloadedEpisodesFolder = downloadClientsCmd.ExecuteScalar() as string;
downloadClientsCmd.Transaction = tran;
downloadClientsCmd.CommandText = @"SELECT Id, Implementation, Settings, ConfigContract FROM DownloadClients WHERE ConfigContract = 'FolderSettings'";
downloadClientsCmd.CommandText = "SELECT \"Id\", \"Implementation\", \"Settings\", \"ConfigContract\" FROM \"DownloadClients\" WHERE \"ConfigContract\" = 'FolderSettings'";
using (var downloadClientReader = downloadClientsCmd.ExecuteReader())
{
while (downloadClientReader.Read())
@ -71,7 +71,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE DownloadClients SET Implementation = ?, Settings = ?, ConfigContract = ? WHERE Id = ?";
updateCmd.CommandText = "UPDATE \"DownloadClients\" SET \"Implementation\" = ?, \"Settings\" = ?, \"ConfigContract\" = ? WHERE \"Id\" = ?";
updateCmd.AddParameter("UsenetBlackhole");
updateCmd.AddParameter(newSettings);
updateCmd.AddParameter("UsenetBlackholeSettings");
@ -90,7 +90,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE DownloadClients SET Settings = ?, ConfigContract = ? WHERE Id = ?";
updateCmd.CommandText = "UPDATE \"DownloadClients\" SET \"Settings\" = ?, \"ConfigContract\" = ? WHERE \"Id\" = ?";
updateCmd.AddParameter(newSettings);
updateCmd.AddParameter("PneumaticSettings");
updateCmd.AddParameter(id);
@ -103,7 +103,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "DELETE FROM DownloadClients WHERE Id = ?";
updateCmd.CommandText = "DELETE FROM \"DownloadClients\" WHERE \"Id\" = ?";
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
@ -141,7 +141,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var historyCmd = conn.CreateCommand())
{
historyCmd.Transaction = tran;
historyCmd.CommandText = @"SELECT Id, EpisodeId, SeriesId, SourceTitle, Date, Data, EventType FROM History WHERE EventType NOT NULL";
historyCmd.CommandText = "SELECT \"Id\", \"EpisodeId\", \"SeriesId\", \"SourceTitle\", \"Date\", \"Data\", \"EventType\" FROM \"History\" WHERE \"EventType\" IS NOT NULL";
using (var historyRead = historyCmd.ExecuteReader())
{
while (historyRead.Read())
@ -238,7 +238,7 @@ namespace NzbDrone.Core.Datastore.Migration
pair.Key.Data["downloadClientId"] = pair.Value.Data["downloadClientId"];
updateHistoryCmd.Transaction = tran;
updateHistoryCmd.CommandText = "UPDATE History SET Data = ? WHERE Id = ?";
updateHistoryCmd.CommandText = "UPDATE \"History\" SET \"Data\" = ? WHERE \"Id\" = ?";
updateHistoryCmd.AddParameter(pair.Key.Data.ToJson());
updateHistoryCmd.AddParameter(pair.Key.Id);

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -10,11 +10,11 @@ namespace NzbDrone.Core.Datastore.Migration
{
// Support XEM names
Alter.Table("SceneMappings").AddColumn("Type").AsString().Nullable();
Execute.Sql("DELETE FROM SceneMappings");
Execute.Sql("DELETE FROM \"SceneMappings\"");
// Add AnimeEpisodeFormat (set to Standard Episode format for now)
Alter.Table("NamingConfig").AddColumn("AnimeEpisodeFormat").AsString().Nullable();
Execute.Sql("UPDATE NamingConfig SET AnimeEpisodeFormat = StandardEpisodeFormat");
Execute.Sql("UPDATE \"NamingConfig\" SET \"AnimeEpisodeFormat\" = \"StandardEpisodeFormat\"");
}
}
}

@ -19,7 +19,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var getSeriesCmd = conn.CreateCommand())
{
getSeriesCmd.Transaction = tran;
getSeriesCmd.CommandText = @"SELECT Id, Title FROM Series";
getSeriesCmd.CommandText = "SELECT \"Id\", \"Title\" FROM \"Series\"";
using (var seriesReader = getSeriesCmd.ExecuteReader())
{
while (seriesReader.Read())
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE Series SET SortTitle = ? WHERE Id = ?";
updateCmd.CommandText = "UPDATE \"Series\" SET \"SortTitle\" = ? WHERE \"Id\" = ?";
updateCmd.AddParameter(sortTitle);
updateCmd.AddParameter(id);

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -13,11 +13,11 @@ namespace NzbDrone.Core.Datastore.Migration
Alter.Table("Profiles").AddColumn("Language").AsInt32().Nullable();
Alter.Table("Profiles").AddColumn("GrabDelay").AsInt32().Nullable();
Alter.Table("Profiles").AddColumn("GrabDelayMode").AsInt32().Nullable();
Execute.Sql("UPDATE Profiles SET Language = 1, GrabDelay = 0, GrabDelayMode = 0");
Update.Table("Profiles").Set(new { Language = 1, GrabDelay = 0, GrabDelayMode = 0 }).AllRows();
// Rename QualityProfileId in Series
Alter.Table("Series").AddColumn("ProfileId").AsInt32().Nullable();
Execute.Sql("UPDATE Series SET ProfileId = QualityProfileId");
Execute.Sql("UPDATE \"Series\" SET \"ProfileId\" = \"QualityProfileId\"");
// Add HeldReleases
Create.TableForModel("PendingReleases")

@ -23,7 +23,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var getSeriesCmd = conn.CreateCommand())
{
getSeriesCmd.Transaction = tran;
getSeriesCmd.CommandText = @"SELECT Id, Path FROM Series";
getSeriesCmd.CommandText = "SELECT \"Id\", \"Path\" FROM \"Series\"";
using (var seriesReader = getSeriesCmd.ExecuteReader())
{
while (seriesReader.Read())
@ -34,7 +34,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE EpisodeFiles SET RelativePath = REPLACE(Path, ?, '') WHERE SeriesId = ?";
updateCmd.CommandText = "UPDATE \"EpisodeFiles\" SET \"RelativePath\" = REPLACE(\"Path\", ?, '') WHERE \"SeriesId\" = ?";
updateCmd.AddParameter(seriesPath);
updateCmd.AddParameter(seriesId);

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -12,8 +12,8 @@ namespace NzbDrone.Core.Datastore.Migration
.AddColumn("EnableRss").AsBoolean().Nullable()
.AddColumn("EnableSearch").AsBoolean().Nullable();
Execute.Sql("UPDATE Indexers SET EnableRss = Enable, EnableSearch = Enable");
Execute.Sql("UPDATE Indexers SET EnableSearch = 0 WHERE Implementation = 'Wombles'");
Execute.Sql("UPDATE \"Indexers\" SET \"EnableRss\" = \"Enable\", \"EnableSearch\" = \"Enable\"");
Update.Table("Indexers").Set(new { EnableSearch = false }).Where(new { Implementation = "Wombles" });
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,15 +8,15 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("UPDATE [EpisodeFiles] " +
"SET ReleaseGroup = NULL , SceneName = NULL " +
Execute.Sql("UPDATE \"EpisodeFiles\" " +
"SET \"ReleaseGroup\" = NULL , \"SceneName\" = NULL " +
"WHERE " +
" ReleaseGroup IS NULL " +
" OR SceneName IS NULL " +
" OR ReleaseGroup =='DRONE' " +
" OR LENGTH(SceneName) <10 " +
" OR LENGTH(ReleaseGroup) > 20 " +
" OR SceneName NOT LIKE '%.%'");
" \"ReleaseGroup\" IS NULL " +
" OR \"SceneName\" IS NULL " +
" OR \"ReleaseGroup\" = 'DRONE' " +
" OR LENGTH(\"SceneName\") <10 " +
" OR LENGTH(\"ReleaseGroup\") > 20 " +
" OR \"SceneName\" NOT LIKE '%.%'");
}
}
}

@ -29,7 +29,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var qualityModelCmd = conn.CreateCommand())
{
qualityModelCmd.Transaction = tran;
qualityModelCmd.CommandText = @"SELECT Distinct Quality FROM " + tableName;
qualityModelCmd.CommandText = $"SELECT Distinct \"Quality\" FROM \"{tableName}\"";
using (var qualityModelReader = qualityModelCmd.ExecuteReader())
{
@ -60,7 +60,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE " + tableName + " SET Quality = ? WHERE Quality = ?";
updateCmd.CommandText = "UPDATE \"" + tableName + "\" SET \"Quality\" = ? WHERE \"Quality\" = ?";
updateCmd.AddParameter(quality.Value);
updateCmd.AddParameter(quality.Key);

@ -1,4 +1,5 @@
using FluentMigrator;
using System;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,9 +9,9 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("UPDATE Episodes SET AbsoluteEpisodeNumber = NULL WHERE AbsoluteEpisodeNumber = 0");
Execute.Sql("UPDATE Episodes SET SceneAbsoluteEpisodeNumber = NULL WHERE SceneAbsoluteEpisodeNumber = 0");
Execute.Sql("UPDATE Episodes SET SceneSeasonNumber = NULL, SceneEpisodeNumber = NULL WHERE SceneSeasonNumber = 0 AND SceneEpisodeNumber = 0");
Update.Table("Episodes").Set(new { AbsoluteEpisodeNumber = DBNull.Value }).Where(new { AbsoluteEpisodeNumber = 0 });
Update.Table("Episodes").Set(new { SceneAbsoluteEpisodeNumber = DBNull.Value }).Where(new { SceneAbsoluteEpisodeNumber = 0 });
Update.Table("Episodes").Set(new { SceneSeasonNumber = DBNull.Value, SceneEpisodeNumber = DBNull.Value }).Where(new { SceneSeasonNumber = 0, SceneEpisodeNumber = 0 });
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -17,8 +17,8 @@ namespace NzbDrone.Core.Datastore.Migration
Alter.Table("Notifications")
.AddColumn("Tags").AsString().Nullable();
Execute.Sql("UPDATE Series SET Tags = '[]'");
Execute.Sql("UPDATE Notifications SET Tags = '[]'");
Update.Table("Series").Set(new { Tags = "[]" }).AllRows();
Update.Table("Notifications").Set(new { Tags = "[]" }).AllRows();
}
}
}

@ -16,7 +16,7 @@ namespace NzbDrone.Core.Datastore.Migration
.WithColumn("Tags").AsString().NotNullable();
Execute.WithConnection(ConvertRestrictions);
Execute.Sql("DELETE FROM Config WHERE [Key] = 'releaserestrictions'");
Delete.FromTable("Config").Row(new { Key = "releaserestrictions" });
}
private void ConvertRestrictions(IDbConnection conn, IDbTransaction tran)
@ -24,7 +24,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var getRestictionsCmd = conn.CreateCommand())
{
getRestictionsCmd.Transaction = tran;
getRestictionsCmd.CommandText = @"SELECT [Value] FROM Config WHERE [Key] = 'releaserestrictions'";
getRestictionsCmd.CommandText = "SELECT \"Value\" FROM \"Config\" WHERE \"Key\" = 'releaserestrictions'";
using (var configReader = getRestictionsCmd.ExecuteReader())
{
@ -36,7 +36,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var insertCmd = conn.CreateCommand())
{
insertCmd.Transaction = tran;
insertCmd.CommandText = "INSERT INTO Restrictions (Ignored, Tags) VALUES (?, '[]')";
insertCmd.CommandText = "INSERT INTO \"Restrictions\" (\"Ignored\", \"Tags\") VALUES (?, '[]')";
insertCmd.AddParameter(restrictions);
insertCmd.ExecuteNonQuery();

@ -22,7 +22,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var namingConfigCmd = conn.CreateCommand())
{
namingConfigCmd.Transaction = tran;
namingConfigCmd.CommandText = @"SELECT StandardEpisodeFormat, DailyEpisodeFormat, AnimeEpisodeFormat FROM NamingConfig LIMIT 1";
namingConfigCmd.CommandText = "SELECT \"StandardEpisodeFormat\", \"DailyEpisodeFormat\", \"AnimeEpisodeFormat\" FROM \"NamingConfig\" LIMIT 1";
using (var configReader = namingConfigCmd.ExecuteReader())
{
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE NamingConfig SET StandardEpisodeFormat = ?, DailyEpisodeFormat = ?, AnimeEpisodeFormat = ?";
updateCmd.CommandText = "UPDATE \"NamingConfig\" SET \"StandardEpisodeFormat\" = ?, \"DailyEpisodeFormat\" = ?, \"AnimeEpisodeFormat\" = ?";
updateCmd.AddParameter(newStandard);
updateCmd.AddParameter(newDaily);
updateCmd.AddParameter(newAnime);

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Dapper;
using FluentMigrator;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework;
@ -24,8 +25,8 @@ namespace NzbDrone.Core.Datastore.Migration
Insert.IntoTable("DelayProfiles").Row(new
{
EnableUsenet = 1,
EnableTorrent = 1,
EnableUsenet = true,
EnableTorrent = true,
PreferredProtocol = 1,
UsenetDelay = 0,
TorrentDelay = 0,
@ -43,6 +44,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
var profiles = GetProfiles(conn, tran);
var order = 1;
var updateProfiles = new List<object>();
foreach (var profileClosure in profiles.DistinctBy(p => p.GrabDelay))
{
@ -56,16 +58,12 @@ namespace NzbDrone.Core.Datastore.Migration
var tagId = InsertTag(conn, tran, tag);
var tags = string.Format("[{0}]", tagId);
using (var insertDelayProfileCmd = conn.CreateCommand())
updateProfiles.Add(new
{
insertDelayProfileCmd.Transaction = tran;
insertDelayProfileCmd.CommandText = "INSERT INTO DelayProfiles (EnableUsenet, EnableTorrent, PreferredProtocol, TorrentDelay, UsenetDelay, [Order], Tags) VALUES (1, 1, 1, 0, ?, ?, ?)";
insertDelayProfileCmd.AddParameter(profile.GrabDelay);
insertDelayProfileCmd.AddParameter(order);
insertDelayProfileCmd.AddParameter(tags);
insertDelayProfileCmd.ExecuteNonQuery();
}
UsenetDelay = profile.GrabDelay,
Order = order,
Tags = tags
});
var matchingProfileIds = profiles.Where(p => p.GrabDelay == profile.GrabDelay)
.Select(p => p.Id);
@ -74,6 +72,9 @@ namespace NzbDrone.Core.Datastore.Migration
order++;
}
var insertDelayProfilesSql = $"INSERT INTO \"DelayProfiles\" (\"EnableUsenet\", \"EnableTorrent\", \"PreferredProtocol\", \"TorrentDelay\", \"UsenetDelay\", \"Order\", \"Tags\") VALUES (true, true, 1, 0, @UsenetDelay, @Order, @Tags)";
conn.Execute(insertDelayProfilesSql, updateProfiles, transaction: tran);
}
private List<Profile69> GetProfiles(IDbConnection conn, IDbTransaction tran)
@ -83,7 +84,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var getProfilesCmd = conn.CreateCommand())
{
getProfilesCmd.Transaction = tran;
getProfilesCmd.CommandText = @"SELECT Id, GrabDelay FROM Profiles";
getProfilesCmd.CommandText = "SELECT \"Id\", \"GrabDelay\" FROM \"Profiles\"";
using (var profileReader = getProfilesCmd.ExecuteReader())
{
@ -106,25 +107,28 @@ namespace NzbDrone.Core.Datastore.Migration
private int InsertTag(IDbConnection conn, IDbTransaction tran, string tagLabel)
{
using (var insertCmd = conn.CreateCommand())
var parameters = new
{
insertCmd.Transaction = tran;
insertCmd.CommandText = @"INSERT INTO Tags (Label) VALUES (?); SELECT last_insert_rowid()";
insertCmd.AddParameter(tagLabel);
TagLabel = tagLabel
};
var id = insertCmd.ExecuteScalar();
var insertTagSql = "INSERT INTO \"Tags\" (\"Label\") VALUES (@TagLabel)";
conn.Execute(insertTagSql, parameters, transaction: tran);
return Convert.ToInt32(id);
}
var selectTagSql = "SELECT \"Id\" FROM \"Tags\" WHERE \"Label\" = @TagLabel";
var id = conn.ExecuteScalar(selectTagSql, parameters, transaction: tran);
return Convert.ToInt32(id);
}
private void UpdateSeries(IDbConnection conn, IDbTransaction tran, IEnumerable<int> profileIds, int tagId)
{
var updatedSeries = new List<object>();
using (var getSeriesCmd = conn.CreateCommand())
{
getSeriesCmd.Transaction = tran;
getSeriesCmd.CommandText = "SELECT Id, Tags FROM Series WHERE ProfileId IN (?)";
getSeriesCmd.AddParameter(string.Join(",", profileIds));
getSeriesCmd.CommandText = $"SELECT \"Id\", \"Tags\" FROM \"Series\" WHERE \"ProfileId\" IN ({string.Join(",", profileIds)})";
using (var seriesReader = getSeriesCmd.ExecuteReader())
{
@ -136,18 +140,17 @@ namespace NzbDrone.Core.Datastore.Migration
var tags = Json.Deserialize<List<int>>(tagString);
tags.Add(tagId);
using (var updateSeriesCmd = conn.CreateCommand())
updatedSeries.Add(new
{
updateSeriesCmd.Transaction = tran;
updateSeriesCmd.CommandText = "UPDATE Series SET Tags = ? WHERE Id = ?";
updateSeriesCmd.AddParameter(tags.ToJson());
updateSeriesCmd.AddParameter(id);
updateSeriesCmd.ExecuteNonQuery();
}
Tags = tags.ToJson(),
Id = id
});
}
}
}
var updateSeriesSql = "UPDATE \"Series\" SET \"Tags\" = @Tags WHERE \"Id\" = @Id";
conn.Execute(updateSeriesSql, updatedSeries, transaction: tran);
}
}

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Dapper;
using FluentMigrator;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework;
@ -58,21 +59,17 @@ namespace NzbDrone.Core.Datastore.Migration
public void Commit()
{
foreach (var profile in _changedProfiles)
var profilesToUpdate = _changedProfiles.Select(p => new
{
using (var updateProfileCmd = _connection.CreateCommand())
{
updateProfileCmd.Transaction = _transaction;
updateProfileCmd.CommandText = "UPDATE Profiles SET Name = ?, Cutoff = ?, Items = ?, Language = ? WHERE Id = ?";
updateProfileCmd.AddParameter(profile.Name);
updateProfileCmd.AddParameter(profile.Cutoff);
updateProfileCmd.AddParameter(profile.Items.ToJson());
updateProfileCmd.AddParameter(profile.Language);
updateProfileCmd.AddParameter(profile.Id);
updateProfileCmd.ExecuteNonQuery();
}
}
Id = p.Id,
Name = p.Name,
Cutoff = p.Cutoff,
Language = p.Language,
Items = p.Items.ToJson()
});
var updateSql = $"UPDATE \"Profiles\" SET \"Name\" = @Name, \"Cutoff\" = @Cutoff, \"Language\" = @Language, \"Items\" = @Items WHERE \"Id\" = @Id";
_connection.Execute(updateSql, profilesToUpdate, transaction: _transaction);
_changedProfiles.Clear();
}
@ -169,7 +166,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var getProfilesCmd = _connection.CreateCommand())
{
getProfilesCmd.Transaction = _transaction;
getProfilesCmd.CommandText = @"SELECT Id, Name, Cutoff, Items, Language FROM Profiles";
getProfilesCmd.CommandText = "SELECT \"Id\", \"Name\", \"Cutoff\", \"Items\", \"Language\" FROM \"Profiles\"";
using (var profileReader = getProfilesCmd.ExecuteReader())
{

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data;
using Dapper;
using FluentMigrator;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework;
@ -22,10 +23,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void MoveToColumn(IDbConnection conn, IDbTransaction tran)
{
var updatedHistory = new List<object>();
using (var getHistory = conn.CreateCommand())
{
getHistory.Transaction = tran;
getHistory.CommandText = @"SELECT Id, Data FROM History WHERE Data LIKE '%downloadClientId%'";
getHistory.CommandText = "SELECT \"Id\", \"Data\" FROM \"History\" WHERE \"Data\" LIKE '%downloadClientId%'";
using (var historyReader = getHistory.ExecuteReader())
{
@ -34,30 +37,23 @@ namespace NzbDrone.Core.Datastore.Migration
var id = historyReader.GetInt32(0);
var data = historyReader.GetString(1);
UpdateHistory(tran, conn, id, data);
var dic = Json.Deserialize<Dictionary<string, string>>(data);
var downloadId = dic["downloadClientId"];
dic.Remove("downloadClientId");
updatedHistory.Add(new
{
Id = id,
Data = dic.ToJson(),
DownloadId = downloadId
});
}
}
}
}
private void UpdateHistory(IDbTransaction tran, IDbConnection conn, int id, string data)
{
var dic = Json.Deserialize<Dictionary<string, string>>(data);
var downloadId = dic["downloadClientId"];
dic.Remove("downloadClientId");
using (var updateHistoryCmd = conn.CreateCommand())
{
updateHistoryCmd.Transaction = tran;
updateHistoryCmd.CommandText = @"UPDATE History SET DownloadId = ?, Data = ? WHERE Id = ?";
updateHistoryCmd.AddParameter(downloadId);
updateHistoryCmd.AddParameter(dic.ToJson());
updateHistoryCmd.AddParameter(id);
updateHistoryCmd.ExecuteNonQuery();
}
var updateSql = $"UPDATE \"History\" SET \"DownloadId\" = @DownloadId, \"Data\" = @Data WHERE \"Id\" = @Id";
conn.Execute(updateSql, updatedHistory, transaction: tran);
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("UPDATE Indexers SET EnableRss = 0, EnableSearch = 0 WHERE Implementation = 'Eztv' AND Settings LIKE '%ezrss.it%'");
Execute.Sql("UPDATE \"Indexers\" SET \"EnableRss\" = false, \"EnableSearch\" = false WHERE \"Implementation\" = 'Eztv' AND \"Settings\" LIKE '%ezrss.it%'");
}
}
}

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Dapper;
using FluentMigrator;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework;
@ -48,7 +49,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var tagCmd = conn.CreateCommand())
{
tagCmd.Transaction = tran;
tagCmd.CommandText = @"SELECT Id, Label FROM Tags";
tagCmd.CommandText = "SELECT \"Id\", \"Label\" FROM \"Tags\"";
using (var tagReader = tagCmd.ExecuteReader())
{
@ -72,7 +73,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var tagCmd = conn.CreateCommand())
{
tagCmd.Transaction = tran;
tagCmd.CommandText = string.Format("SELECT Id, Tags FROM {0}", table);
tagCmd.CommandText = string.Format("SELECT \"Id\", \"Tags\" FROM \"{0}\"", table);
using (var tagReader = tagCmd.ExecuteReader())
{
@ -109,29 +110,28 @@ namespace NzbDrone.Core.Datastore.Migration
}
}
foreach (var model in toUpdate.DistinctBy(m => m.Id))
var updatedTags = toUpdate.DistinctBy(m => m.Id).Select(t => new
{
using (var updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = string.Format(@"UPDATE {0} SET Tags = ? WHERE Id = ?", table);
updateCmd.AddParameter(model.Tags.ToJson());
updateCmd.AddParameter(model.Id);
Tags = t.Tags.ToJson(),
Id = t.Id
});
updateCmd.ExecuteNonQuery();
}
}
var updateTagsSql = $"UPDATE \"{table}\" SET \"Tags\" = @Tags WHERE \"Id\" = @Id";
conn.Execute(updateTagsSql, updatedTags, transaction: tran);
}
private void DeleteTags(IDbConnection conn, IDbTransaction tran, List<TagReplacement079> replacements)
{
var idsToRemove = replacements.Select(r => r.OldId).Distinct();
using (var removeCmd = conn.CreateCommand())
if (idsToRemove.Any())
{
removeCmd.Transaction = tran;
removeCmd.CommandText = string.Format("DELETE FROM Tags WHERE Id IN ({0})", string.Join(",", idsToRemove));
removeCmd.ExecuteNonQuery();
using (var removeCmd = conn.CreateCommand())
{
removeCmd.Transaction = tran;
removeCmd.CommandText = $"DELETE FROM \"Tags\" WHERE \"Id\" IN ({string.Join(", ", idsToRemove)})";
removeCmd.ExecuteNonQuery();
}
}
}

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Data;
using Dapper;
using FluentMigrator;
using Newtonsoft.Json.Linq;
using NzbDrone.Common.Extensions;
@ -18,10 +19,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
{
var updatedClients = new List<object>();
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tran;
cmd.CommandText = "SELECT Id, Settings FROM DownloadClients WHERE Implementation = 'Transmission'";
cmd.CommandText = "SELECT \"Id\", \"Settings\" FROM \"DownloadClients\" WHERE \"Implementation\" = 'Transmission'";
using (var reader = cmd.ExecuteReader())
{
@ -37,19 +40,18 @@ namespace NzbDrone.Core.Datastore.Migration
{
settings["tvCategory"] = "." + tvCategory;
using (var updateCmd = conn.CreateCommand())
updatedClients.Add(new
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE DownloadClients SET Settings = ? WHERE Id = ?";
updateCmd.AddParameter(settings.ToJson());
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
Settings = settings.ToJson(),
Id = id
});
}
}
}
}
var updateClientsSql = "UPDATE \"DownloadClients\" SET \"Settings\" = @Settings WHERE \"Id\" = @Id";
conn.Execute(updateClientsSql, updatedClients, transaction: tran);
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("UPDATE Indexers SET ConfigContract = 'FanzubSettings' WHERE Implementation = 'Fanzub' AND ConfigContract = 'NullConfig'");
Update.Table("Indexers").Set(new { ConfigContract = "FanzubSettings" }).Where(new { Implementation = "Fanzub", ConfigContract = "NullConfig" });
}
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -11,7 +11,7 @@ namespace NzbDrone.Core.Datastore.Migration
Alter.Table("QualityDefinitions").AlterColumn("MinSize").AsDouble().Nullable();
Alter.Table("QualityDefinitions").AlterColumn("MaxSize").AsDouble().Nullable();
Execute.Sql("UPDATE QualityDefinitions SET MaxSize = NULL WHERE Quality = 10 OR MaxSize = 0");
Execute.Sql("UPDATE \"QualityDefinitions\" SET \"MaxSize\" = NULL WHERE \"Quality\" = 10 OR \"MaxSize\" = 0");
}
}

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Data;
using Dapper;
using FluentMigrator;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer;
@ -17,10 +18,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
{
var updatedClients = new List<object>();
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tran;
cmd.CommandText = "SELECT Id, Settings FROM DownloadClients WHERE Implementation = 'Transmission'";
cmd.CommandText = "SELECT \"Id\", \"Settings\" FROM \"DownloadClients\" WHERE \"Implementation\" = 'Transmission'";
using (var reader = cmd.ExecuteReader())
{
@ -42,18 +45,17 @@ namespace NzbDrone.Core.Datastore.Migration
settings["urlBase"] = string.Format("/{0}/transmission/", urlBase.Trim('/'));
}
using (var updateCmd = conn.CreateCommand())
updatedClients.Add(new
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE DownloadClients SET Settings = ? WHERE Id = ?";
updateCmd.AddParameter(settings.ToJson());
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
Settings = settings.ToJson(),
Id = id
});
}
}
}
var updateClientsSql = "UPDATE \"DownloadClients\" SET \"Settings\" = @Settings WHERE \"Id\" = @Id";
conn.Execute(updateClientsSql, updatedClients, transaction: tran);
}
}

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Data;
using Dapper;
using FluentMigrator;
using Newtonsoft.Json.Linq;
using NzbDrone.Common.Serializer;
@ -17,10 +18,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
{
var updatedClients = new List<object>();
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tran;
cmd.CommandText = "SELECT Id, Settings FROM Notifications WHERE Implementation = 'PushBullet'";
cmd.CommandText = "SELECT \"Id\", \"Settings\" FROM \"Notifications\" WHERE \"Implementation\" = 'PushBullet'";
using (var reader = cmd.ExecuteReader())
{
@ -37,19 +40,18 @@ namespace NzbDrone.Core.Datastore.Migration
settings.Add("deviceIds", new[] { deviceId });
settings.Remove("deviceId");
using (var updateCmd = conn.CreateCommand())
updatedClients.Add(new
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE Notifications SET Settings = ? WHERE Id = ?";
updateCmd.AddParameter(settings.ToJson());
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
Settings = settings.ToJson(),
Id = id
});
}
}
}
}
var updateClientsSql = "UPDATE \"Notifications\" SET \"Settings\" = @Settings WHERE \"Id\" = @Id";
conn.Execute(updateClientsSql, updatedClients, transaction: tran);
}
}

@ -1,4 +1,4 @@
using FluentMigrator;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{
protected override void MainDbUpgrade()
{
Execute.Sql("DELETE FROM Indexers WHERE Implementation = 'Eztv'");
Delete.FromTable("Indexers").Row(new { Implementation = "Eztv" });
}
}
}

@ -1,6 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using System.Data;
using Dapper;
using FluentMigrator;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer;
@ -18,10 +19,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
{
var updatedClients = new List<object>();
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tran;
cmd.CommandText = "SELECT Id, Settings FROM Notifications WHERE Implementation = 'PushBullet'";
cmd.CommandText = "SELECT \"Id\", \"Settings\" FROM \"Notifications\" WHERE \"Implementation\" = 'PushBullet'";
using (var reader = cmd.ExecuteReader())
{
@ -55,18 +58,17 @@ namespace NzbDrone.Core.Datastore.Migration
}
}
using (var updateCmd = conn.CreateCommand())
updatedClients.Add(new
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE Notifications SET Settings = ? WHERE Id = ?";
updateCmd.AddParameter(settings.ToJson());
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
Settings = settings.ToJson(),
Id = id
});
}
}
}
var updateClientsSql = "UPDATE \"Notifications\" SET \"Settings\" = @Settings WHERE \"Id\" = @Id";
conn.Execute(updateClientsSql, updatedClients, transaction: tran);
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save