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

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

@ -66,6 +66,9 @@ namespace NzbDrone.Common.Test.InstrumentationTests
[TestCase("Hardlinking episode file: /Users/mySecret/Downloads to /media/abc.mkv")] [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 '/home/mySecret/Downloads/abs.mkv' to '/media/abc.mkv' failed.")]
[TestCase("Hardlink '/Users/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 // Announce URLs (passkeys) Magnet & Tracker
[TestCase(@"magnet_uri"":""magnet:?xt=urn:btih:9pr04sgkillroyimaveql2tyu8xyui&dn=&tr=https%3a%2f%2fxxx.yyy%2f9pr04sg601233210imaveql2tyu8xyui%2fannounce""}")] [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); var cleansedMessage = CleanseLogMessage.Cleanse(message);
cleansedMessage.Should().NotContain("mySecret"); cleansedMessage.Should().NotContain("mySecret");
cleansedMessage.Should().NotContain("123%@%_@!#^#@");
cleansedMessage.Should().NotContain("01233210"); 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(@"Some message (from 32.2.3.5 user agent)")]
[TestCase(@"Auth-Invalidated ip 32.2.3.5")] [TestCase(@"Auth-Invalidated ip 32.2.3.5")]
[TestCase(@"Auth-Success ip 32.2.3.5")] [TestCase(@"Auth-Success ip 32.2.3.5")]

@ -4,11 +4,13 @@ using DryIoc.Microsoft.DependencyInjection;
using FluentAssertions; using FluentAssertions;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Composition.Extensions; using NzbDrone.Common.Composition.Extensions;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Extensions; using NzbDrone.Core.Datastore.Extensions;
using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
@ -29,7 +31,8 @@ namespace NzbDrone.Common.Test
.AddDummyDatabase() .AddDummyDatabase()
.AddStartupContext(new StartupContext("first", "second")); .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(); 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 (@"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 (@"/fetch/[a-z0-9]{32}/(?<secret>[a-z0-9]{32})", RegexOptions.Compiled),
new (@"getnzb.*?(?<=\?|&)(r)=(?<secret>[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), 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 // 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"), 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() public void SingleOrDefault_should_return_null_on_empty_db()
{ {
Mocker.Resolve<IDatabase>() Mocker.Resolve<IDatabase>()
.OpenConnection().Query<Series>("SELECT * FROM Series") .OpenConnection().Query<Series>("SELECT * FROM \"Series\"")
.SingleOrDefault() .SingleOrDefault()
.Should() .Should()
.BeNull(); .BeNull();
@ -27,6 +27,20 @@ namespace NzbDrone.Core.Test.Datastore
Mocker.Resolve<IDatabase>().Vacuum(); 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] [Test]
public void get_version() public void get_version()
{ {

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
@ -15,6 +16,17 @@ namespace NzbDrone.Core.Test.Datastore
[TestFixture] [TestFixture]
public class DatabaseRelationshipFixture : DbTest 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] [Test]
public void one_to_one() public void one_to_one()
{ {

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

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

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentAssertions; 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().HaveCount(2);
history.Should().NotContain(c => c.Data.ContainsKey("downloadClientId")); 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().HaveCount(2);
history.Should().NotContain(c => c.Data.ContainsKey("downloadClientId")); 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().NotContainKey("downloadClientId");
history.Data.Should().Contain(new KeyValuePair<string, string>("indexer", "test")); history.Data.Should().Contain(new KeyValuePair<string, string>("indexer", "test"));

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

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration; using NzbDrone.Core.Datastore.Migration;
@ -17,25 +17,25 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new c.Insert.IntoTable("Profiles").Row(new
{ {
Name = "Profile1", Name = "Profile1",
CutOff = 0, Cutoff = 0,
Items = "[]", Items = "[]",
Language = 1 Language = 1
}); });
c.Insert.IntoTable("Series").Row(new c.Insert.IntoTable("Series").Row(new
{ {
Tvdbid = 1, TvdbId = 1,
TvRageId = 1, TvRageId = 1,
Title = "Title1", Title = "Title1",
CleanTitle = "CleanTitle1", CleanTitle = "CleanTitle1",
Status = 1, Status = 1,
Images = "", Images = "",
Path = "c:\\test", Path = "c:\\test",
Monitored = 1, Monitored = true,
SeasonFolder = 1, SeasonFolder = true,
Runtime = 0, Runtime = 0,
SeriesType = 0, SeriesType = 0,
UseSceneNumbering = 0, UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00", LastInfoSync = "2000-01-01 00:00:00",
ProfileId = 1 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); tags.Should().HaveCount(1);
} }
@ -58,25 +58,25 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new c.Insert.IntoTable("Profiles").Row(new
{ {
Name = "Profile1", Name = "Profile1",
CutOff = 0, Cutoff = 0,
Items = "[]", Items = "[]",
Language = 1 Language = 1
}); });
c.Insert.IntoTable("Series").Row(new c.Insert.IntoTable("Series").Row(new
{ {
Tvdbid = 1, TvdbId = 1,
TvRageId = 1, TvRageId = 1,
Title = "Title1", Title = "Title1",
CleanTitle = "CleanTitle1", CleanTitle = "CleanTitle1",
Status = 1, Status = 1,
Images = "", Images = "",
Path = "c:\\test", Path = "c:\\test",
Monitored = 1, Monitored = true,
SeasonFolder = 1, SeasonFolder = true,
Runtime = 0, Runtime = 0,
SeriesType = 0, SeriesType = 0,
UseSceneNumbering = 0, UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00", LastInfoSync = "2000-01-01 00:00:00",
Tags = "[]", Tags = "[]",
ProfileId = 1 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); 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); 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] [Test]
@ -134,25 +134,25 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new c.Insert.IntoTable("Profiles").Row(new
{ {
Name = "Profile1", Name = "Profile1",
CutOff = 0, Cutoff = 0,
Items = "[]", Items = "[]",
Language = 1 Language = 1
}); });
c.Insert.IntoTable("Series").Row(new c.Insert.IntoTable("Series").Row(new
{ {
Tvdbid = 1, TvdbId = 1,
TvRageId = 1, TvRageId = 1,
Title = "Title1", Title = "Title1",
CleanTitle = "CleanTitle1", CleanTitle = "CleanTitle1",
Status = 1, Status = 1,
Images = "", Images = "",
Path = "c:\\test", Path = "c:\\test",
Monitored = 1, Monitored = true,
SeasonFolder = 1, SeasonFolder = true,
Runtime = 0, Runtime = 0,
SeriesType = 0, SeriesType = 0,
UseSceneNumbering = 0, UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00", LastInfoSync = "2000-01-01 00:00:00",
Tags = "[2]", Tags = "[2]",
ProfileId = 1 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); series.Tags.First().Should().Be(1);
} }
@ -181,25 +181,25 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Profiles").Row(new c.Insert.IntoTable("Profiles").Row(new
{ {
Name = "Profile1", Name = "Profile1",
CutOff = 0, Cutoff = 0,
Items = "[]", Items = "[]",
Language = 1 Language = 1
}); });
c.Insert.IntoTable("Series").Row(new c.Insert.IntoTable("Series").Row(new
{ {
Tvdbid = 1, TvdbId = 1,
TvRageId = 1, TvRageId = 1,
Title = "Title1", Title = "Title1",
CleanTitle = "CleanTitle1", CleanTitle = "CleanTitle1",
Status = 1, Status = 1,
Images = "", Images = "",
Path = "c:\\test", Path = "c:\\test",
Monitored = 1, Monitored = true,
SeasonFolder = 1, SeasonFolder = true,
Runtime = 0, Runtime = 0,
SeriesType = 0, SeriesType = 0,
UseSceneNumbering = 0, UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00", LastInfoSync = "2000-01-01 00:00:00",
Tags = "[2]", Tags = "[2]",
ProfileId = 1 ProfileId = 1
@ -207,18 +207,18 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("Series").Row(new c.Insert.IntoTable("Series").Row(new
{ {
Tvdbid = 2, TvdbId = 2,
TvRageId = 2, TvRageId = 2,
Title = "Title2", Title = "Title2",
CleanTitle = "CleanTitle2", CleanTitle = "CleanTitle2",
Status = 1, Status = 1,
Images = "", Images = "",
Path = "c:\\test", Path = "c:\\test",
Monitored = 1, Monitored = true,
SeasonFolder = 1, SeasonFolder = true,
Runtime = 0, Runtime = 0,
SeriesType = 0, SeriesType = 0,
UseSceneNumbering = 0, UseSceneNumbering = false,
LastInfoSync = "2000-01-01 00:00:00", LastInfoSync = "2000-01-01 00:00:00",
Tags = "[]", Tags = "[]",
ProfileId = 1 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(); series.Tags.Should().BeEmpty();
} }
} }

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
@ -17,7 +17,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
c.Insert.IntoTable("DownloadClients").Row(new c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Sab", Name = "Sab",
Implementation = "Sabnzbd", Implementation = "Sabnzbd",
Settings = new 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.Should().HaveCount(1);
downloadClients.First().Settings.ToObject<SabnzbdSettings81>().TvCategory.Should().Be("abc"); 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 c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Trans", Name = "Trans",
Implementation = "Transmission", Implementation = "Transmission",
Settings = new 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.Should().HaveCount(1);
downloadClients.First().Settings.ToObject<TransmissionSettings81>().TvCategory.Should().Be(".abc"); 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 c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Trans", Name = "Trans",
Implementation = "Transmission", Implementation = "Transmission",
Settings = new 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.Should().HaveCount(1);
downloadClients.First().Settings.ToObject<TransmissionSettings81>().TvCategory.Should().Be(""); downloadClients.First().Settings.ToObject<TransmissionSettings81>().TvCategory.Should().Be("");

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

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
@ -17,7 +17,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
c.Insert.IntoTable("DownloadClients").Row(new c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Deluge", Name = "Deluge",
Implementation = "Deluge", Implementation = "Deluge",
Settings = new DelugeSettings85 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.Should().HaveCount(1);
items.First().Settings.ToObject<DelugeSettings85>().UrlBase.Should().Be("/my/"); 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 c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Trans", Name = "Trans",
Implementation = "Transmission", Implementation = "Transmission",
Settings = new TransmissionSettings81 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.Should().HaveCount(1);
items.First().Settings.ToObject<TransmissionSettings81>().UrlBase.Should().Be("/transmission/"); 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 c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Trans", Name = "Trans",
Implementation = "Transmission", Implementation = "Transmission",
Settings = new TransmissionSettings81 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.Should().HaveCount(1);
items.First().Settings.ToObject<TransmissionSettings81>().UrlBase.Should().Be("/my/url/transmission/"); items.First().Settings.ToObject<TransmissionSettings81>().UrlBase.Should().Be("/my/url/transmission/");

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Serializer; 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); 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); 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.Should().HaveCount(1);
items.First().Settings.ToObject<PushBulletSettings86>().DeviceIds.First().Should().Be(deviceId); items.First().Settings.ToObject<PushBulletSettings86>().DeviceIds.First().Should().Be(deviceId);

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Serializer; 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.Should().HaveCount(1);
items.First().Settings.ToObject<PushBulletSettings88>().ChannelTags.Should().HaveCount(2); items.First().Settings.ToObject<PushBulletSettings88>().ChannelTags.Should().HaveCount(2);

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Serializer; 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.Should().HaveCount(1);
items.First().Settings.ToObject<KickassTorrentsSettings90>().BaseUrl.Should().Be("https://kat.cr"); 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.Should().HaveCount(1);
items.First().Settings.ToObject<KickassTorrentsSettings90>().BaseUrl.Should().Be("kickass.so"); items.First().Settings.ToObject<KickassTorrentsSettings90>().BaseUrl.Should().Be("kickass.so");

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration; 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.Should().HaveCount(2);
items.First().Extension.Should().Be(".jpg"); 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; var items = profiles.First().Items;
items.Should().HaveCount(4); items.Should().HaveCount(4);

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Datastore.Migration; 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.Should().HaveCount(1);
items.First().Extension.Should().Be(".jpg"); items.First().Extension.Should().Be(".jpg");

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Serializer; 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.Should().HaveCount(1);
items.First().Settings.ToObject<BroadcastheNetSettings106>().BaseUrl.Should().Contain("api.broadcasthe.net"); 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.Should().HaveCount(1);
items.First().Settings.ToObject<BroadcastheNetSettings106>().BaseUrl.Should().Be("http://api.btnapps.net"); 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(); 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.Should().HaveCount(1);
items.First()["Extension"].Should().Be(".srt"); 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.Should().HaveCount(1);
items.First()["Extension"].Should().Be(".nfo-orig"); items.First()["Extension"].Should().Be(".nfo-orig");

@ -13,7 +13,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
var db = WithMigrationTestDb(); 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(); 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(); 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"); items.Should().Be("True");
} }
} }

@ -13,7 +13,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
var db = WithMigrationTestDb(); 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(); 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"); 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"); 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"); 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"); 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(""); 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"); 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(); 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"); 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"); 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; var items = profiles.First().Items;
items.Should().HaveCount(6); 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; var items = profiles.First().Items;
items.Should().HaveCount(6); 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; var items = profiles.First().Items;
items.Should().HaveCount(6); 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; var items = profiles.First().Items;
items[1].Items.First().Quality.Should().Be((int)Quality.WEBRip480p); 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.Should().HaveCount(1);
items.First().Settings.ToObject<NewznabSettings121>().BaseUrl.Should().Be(baseUrl.Replace("animetosho", "feed.animetosho")); 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; var items = profiles.First().Items;
items.Should().HaveCount(4); 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; var items = profiles.First().Items;
items.Should().HaveCount(4); items.Should().HaveCount(4);

@ -16,11 +16,11 @@ namespace NzbDrone.Core.Test.Datastore.Migration
var dbBefore = WithTestDb(new MigrationContext(MigrationType, 110)); var dbBefore = WithTestDb(new MigrationContext(MigrationType, 110));
// Ensure 111 isn't applied // 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 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); result.Should().Be(0);
} }

@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
c.Insert.IntoTable("DownloadClients").Row(new c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Deluge", Name = "Deluge",
Implementation = "Deluge", Implementation = "Deluge",
Settings = new DelugeSettings85 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.Should().HaveCount(1);
items.First().Priority.Should().Be(1); items.First().Priority.Should().Be(1);
@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
c.Insert.IntoTable("DownloadClients").Row(new c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Deluge", Name = "Deluge",
Implementation = "Deluge", Implementation = "Deluge",
Settings = new DelugeSettings85 Settings = new DelugeSettings85
@ -56,7 +56,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
ConfigContract = "DelugeSettings" ConfigContract = "DelugeSettings"
}).Row(new }).Row(new
{ {
Enable = 1, Enable = true,
Name = "Deluge2", Name = "Deluge2",
Implementation = "Deluge", Implementation = "Deluge",
Settings = new DelugeSettings85 Settings = new DelugeSettings85
@ -68,7 +68,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
ConfigContract = "DelugeSettings" ConfigContract = "DelugeSettings"
}).Row(new }).Row(new
{ {
Enable = 1, Enable = true,
Name = "sab", Name = "sab",
Implementation = "Sabnzbd", Implementation = "Sabnzbd",
Settings = new SabnzbdSettings81 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.Should().HaveCount(3);
items[0].Priority.Should().Be(1); items[0].Priority.Should().Be(1);
@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
c.Insert.IntoTable("DownloadClients").Row(new c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 0, Enable = false,
Name = "Deluge", Name = "Deluge",
Implementation = "Deluge", Implementation = "Deluge",
Settings = new DelugeSettings85 Settings = new DelugeSettings85
@ -107,7 +107,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
ConfigContract = "DelugeSettings" ConfigContract = "DelugeSettings"
}).Row(new }).Row(new
{ {
Enable = 0, Enable = false,
Name = "Deluge2", Name = "Deluge2",
Implementation = "Deluge", Implementation = "Deluge",
Settings = new DelugeSettings85 Settings = new DelugeSettings85
@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
ConfigContract = "DelugeSettings" ConfigContract = "DelugeSettings"
}).Row(new }).Row(new
{ {
Enable = 0, Enable = false,
Name = "sab", Name = "sab",
Implementation = "Sabnzbd", Implementation = "Sabnzbd",
Settings = new SabnzbdSettings81 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.Should().HaveCount(3);
items[0].Priority.Should().Be(1); items[0].Priority.Should().Be(1);

@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
AddEpisodeFile(c, 1); 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); 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.Should().HaveCount(1);
items.First().Implementation.Should().Be("Email"); items.First().Implementation.Should().Be("Email");

@ -19,7 +19,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
c.Insert.IntoTable("DownloadClients").Row(new c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Deluge", Name = "Deluge",
Implementation = "Deluge", Implementation = "Deluge",
Priority = 1, 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.Should().HaveCount(1);
items.First().RemoveCompletedDownloads.Should().BeFalse(); items.First().RemoveCompletedDownloads.Should().BeFalse();
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
c.Insert.IntoTable("DownloadClients").Row(new c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "Deluge", Name = "Deluge",
Implementation = "Deluge", Implementation = "Deluge",
Priority = 1, 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.Should().HaveCount(1);
items.First().RemoveCompletedDownloads.Should().BeTrue(); items.First().RemoveCompletedDownloads.Should().BeTrue();
@ -81,7 +81,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
{ {
c.Insert.IntoTable("DownloadClients").Row(new c.Insert.IntoTable("DownloadClients").Row(new
{ {
Enable = 1, Enable = true,
Name = "RTorrent", Name = "RTorrent",
Implementation = "RTorrent", Implementation = "RTorrent",
Priority = 1, 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.Should().HaveCount(1);
items.First().RemoveCompletedDownloads.Should().BeFalse(); items.First().RemoveCompletedDownloads.Should().BeFalse();

@ -74,13 +74,13 @@ namespace NzbDrone.Core.Test.Datastore.Migration
""isPossibleSceneSeasonSpecial"": false ""isPossibleSceneSeasonSpecial"": false
}", }",
Release = "{}", 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.Quality.Quality.Should().Be(Quality.HDTV720p.Id);
pending.Language.Should().Be(Language.English.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.Should().HaveCount(1);
customFormats.First().Name.Should().Be("Profile_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); 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.Should().HaveCount(1);
customFormats.First().Name.Should().Be("Profile_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.Should().HaveCount(1);
releaseProfiles.First().Name.Should().Be("Profile"); 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); 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.Should().HaveCount(1);
customFormats.First().Name.Should().Be("Unnamed_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.Should().HaveCount(2);
customFormats.First().Name.Should().Be("Unnamed_1"); 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.Should().HaveCount(6);
customFormats.First().Name.Should().Be("Some - Profile_1_0"); 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.Should().HaveCount(2);
customFormats.First().Name.Should().Be("Profile_1_0"); 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.Should().HaveCount(1);
customFormats.First().FormatItems.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.Should().HaveCount(1);
customFormats.First().FormatItems.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 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}", 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}", DailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title} {Preferred.Words } {Quality Full}",
AnimeEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {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.Should().HaveCount(1);
customFormats.First().StandardEpisodeFormat.Should().Be("{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Custom Formats } {Quality Full}"); 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.Should().HaveCount(1);
customFormats.First().Specifications.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.Should().HaveCount(1);
customFormats.First().Specifications.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.Should().HaveCount(1);
metadataFiles.First().RelativePath.Should().NotContain("metadata"); 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 // 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.Should().HaveCount(2);
exclusions.First().TvdbId.Should().Be(1); exclusions.First().TvdbId.Should().Be(1);

@ -11,9 +11,9 @@ using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.Datastore namespace NzbDrone.Core.Test.Datastore
{ {
[TestFixture] [TestFixture]
public class WhereBuilderFixture : CoreTest public class WhereBuilderPostgresFixture : CoreTest
{ {
private WhereBuilder _subject; private WhereBuilderPostgres _subject;
[OneTimeSetUp] [OneTimeSetUp]
public void MapTables() public void MapTables()
@ -22,9 +22,9 @@ namespace NzbDrone.Core.Test.Datastore
Mocker.Resolve<DbFactory>(); 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] [Test]
@ -71,7 +71,7 @@ namespace NzbDrone.Core.Test.Datastore
public void where_throws_without_concrete_condition_if_requiresConcreteCondition() public void where_throws_without_concrete_condition_if_requiresConcreteCondition()
{ {
Expression<Func<Series, Series, bool>> filter = (x, y) => x.Id == y.Id; 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()); Assert.Throws<InvalidOperationException>(() => _subject.ToString());
} }
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Test.Datastore
public void where_allows_abstract_condition_if_not_requiresConcreteCondition() public void where_allows_abstract_condition_if_not_requiresConcreteCondition()
{ {
Expression<Func<Series, Series, bool>> filter = (x, y) => x.Id == y.Id; 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\")"); _subject.ToString().Should().Be($"(\"Series\".\"Id\" = \"Series\".\"Id\")");
} }
@ -115,7 +115,7 @@ namespace NzbDrone.Core.Test.Datastore
var test = "small"; var test = "small";
_subject = Where(x => x.CleanTitle.Contains(test)); _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); _subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
} }
@ -125,7 +125,7 @@ namespace NzbDrone.Core.Test.Datastore
var test = "small"; var test = "small";
_subject = Where(x => test.Contains(x.CleanTitle)); _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); _subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
} }
@ -135,7 +135,7 @@ namespace NzbDrone.Core.Test.Datastore
var test = "small"; var test = "small";
_subject = Where(x => x.CleanTitle.StartsWith(test)); _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); _subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
} }
@ -145,7 +145,7 @@ namespace NzbDrone.Core.Test.Datastore
var test = "small"; var test = "small";
_subject = Where(x => x.CleanTitle.EndsWith(test)); _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); _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 }; var list = new List<int> { 1, 2, 3 };
_subject = Where(x => list.Contains(x.Id)); _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(); _subject.Parameters.ParameterNames.Should().BeEmpty();
} }
@ -166,7 +166,7 @@ namespace NzbDrone.Core.Test.Datastore
var list = new List<int> { 1, 2, 3 }; var list = new List<int> { 1, 2, 3 };
_subject = Where(x => x.CleanTitle == "test" && list.Contains(x.Id)); _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] [Test]
@ -176,7 +176,7 @@ namespace NzbDrone.Core.Test.Datastore
_subject = Where(x => list.Contains(x.CleanTitle)); _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] [Test]
@ -193,7 +193,7 @@ namespace NzbDrone.Core.Test.Datastore
var allowed = new List<SeriesStatusType> { SeriesStatusType.Upcoming, SeriesStatusType.Continuing }; var allowed = new List<SeriesStatusType> { SeriesStatusType.Upcoming, SeriesStatusType.Continuing };
_subject = Where(x => allowed.Contains(x.Status)); _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] [Test]
@ -202,7 +202,7 @@ namespace NzbDrone.Core.Test.Datastore
var allowed = new SeriesStatusType[] { SeriesStatusType.Upcoming, SeriesStatusType.Continuing }; var allowed = new SeriesStatusType[] { SeriesStatusType.Upcoming, SeriesStatusType.Continuing };
_subject = Where(x => allowed.Contains(x.Status)); _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.Collections.Generic;
using System.Data.SQLite; using System.Data.SQLite;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Npgsql;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Test.Common.Datastore;
namespace NzbDrone.Core.Test.Framework namespace NzbDrone.Core.Test.Framework
{ {
@ -49,6 +53,7 @@ namespace NzbDrone.Core.Test.Framework
public abstract class DbTest : CoreTest public abstract class DbTest : CoreTest
{ {
private ITestDatabase _db; private ITestDatabase _db;
private DatabaseType _databaseType;
protected virtual MigrationType MigrationType => MigrationType.Main; protected virtual MigrationType MigrationType => MigrationType.Main;
@ -101,17 +106,39 @@ namespace NzbDrone.Core.Test.Framework
private IDatabase CreateDatabase(MigrationContext migrationContext) private IDatabase CreateDatabase(MigrationContext migrationContext)
{ {
if (_databaseType == DatabaseType.PostgreSQL)
{
CreatePostgresDb();
}
var factory = Mocker.Resolve<DbFactory>(); var factory = Mocker.Resolve<DbFactory>();
// If a special migration test or log migration then create new // 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 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 // Otherwise try to use a cached migrated db
var cachedDb = GetCachedDatabase(migrationContext.MigrationType); var cachedDb = SqliteDatabase.GetCachedDb(migrationContext.MigrationType);
var testDb = GetTestDb(migrationContext.MigrationType); var testDb = GetTestSqliteDb(migrationContext.MigrationType);
if (File.Exists(cachedDb)) if (File.Exists(cachedDb))
{ {
TestLogger.Info($"Using cached initial database {cachedDb}"); TestLogger.Info($"Using cached initial database {cachedDb}");
@ -131,12 +158,7 @@ namespace NzbDrone.Core.Test.Framework
} }
} }
private string GetCachedDatabase(MigrationType type) private string GetTestSqliteDb(MigrationType type)
{
return Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_{type}.db");
}
private string GetTestDb(MigrationType type)
{ {
return type == MigrationType.Main ? TestFolderInfo.GetDatabase() : TestFolderInfo.GetLogDatabase(); return type == MigrationType.Main ? TestFolderInfo.GetDatabase() : TestFolderInfo.GetLogDatabase();
} }
@ -151,6 +173,13 @@ namespace NzbDrone.Core.Test.Framework
WithTempAsAppPath(); WithTempAsAppPath();
SetupLogging(); 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<IConnectionStringFactory>(Mocker.Resolve<ConnectionStringFactory>());
Mocker.SetConstant<IMigrationController>(Mocker.Resolve<MigrationController>()); 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) // Make sure there are no lingering connections. (When this happens it means we haven't disposed something properly)
GC.Collect(); GC.Collect();
GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers();
SQLiteConnection.ClearAllPools(); SQLiteConnection.ClearAllPools();
NpgsqlConnection.ClearAllPools();
if (TestFolderInfo != null) if (TestFolderInfo != null)
{ {
DeleteTempFolder(TestFolderInfo.AppDataFolder); DeleteTempFolder(TestFolderInfo.AppDataFolder);
} }
if (_databaseType == DatabaseType.PostgreSQL)
{
DropPostgresDb();
}
} }
} }
} }

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

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

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

@ -189,9 +189,12 @@ namespace NzbDrone.Core.Backup
private void BackupDatabase() 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() private void BackupConfigFile()

@ -40,7 +40,7 @@ namespace NzbDrone.Core.Blocklisting
Delete(x => seriesIds.Contains(x.SeriesId)); 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) => protected override IEnumerable<Blocklist> PagedQuery(SqlBuilder sql) => _database.QueryJoined<Blocklist, Series>(sql, (bl, movie) =>
{ {
bl.Series = movie; bl.Series = movie;

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

@ -67,7 +67,7 @@ namespace NzbDrone.Core.Datastore
_updateSql = GetUpdateSql(_properties); _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(); 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()) 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"; 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); SqlBuilderExtensions.LogQuery(_insertSql, model);
var multi = connection.QueryMultiple(_insertSql, model, transaction); 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); _keyProperty.SetValue(model, id);
return model; return model;
@ -293,7 +299,7 @@ namespace NzbDrone.Core.Datastore
{ {
using (var conn = _database.OpenConnection()) using (var conn = _database.OpenConnection())
{ {
conn.Execute($"DELETE FROM [{_table}]"); conn.Execute($"DELETE FROM \"{_table}\"");
} }
if (vacuum) if (vacuum)
@ -352,7 +358,7 @@ namespace NzbDrone.Core.Datastore
private string GetUpdateSql(List<PropertyInfo> propertiesToUpdate) private string GetUpdateSql(List<PropertyInfo> propertiesToUpdate)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendFormat("UPDATE {0} SET ", _table); sb.AppendFormat("UPDATE \"{0}\" SET ", _table);
for (var i = 0; i < propertiesToUpdate.Count; i++) for (var i = 0; i < propertiesToUpdate.Count; i++)
{ {
@ -420,9 +426,10 @@ namespace NzbDrone.Core.Datastore
pagingSpec.SortKey = $"{_table}.{_keyProperty.Name}"; pagingSpec.SortKey = $"{_table}.{_keyProperty.Name}";
} }
var sortKey = TableMapping.Mapper.GetSortKey(pagingSpec.SortKey);
var sortDirection = pagingSpec.SortDirection == SortDirection.Descending ? "DESC" : "ASC"; var sortDirection = pagingSpec.SortDirection == SortDirection.Descending ? "DESC" : "ASC";
var pagingOffset = (pagingSpec.Page - 1) * pagingSpec.PageSize; var pagingOffset = Math.Max(pagingSpec.Page - 1, 0) * pagingSpec.PageSize;
builder.OrderBy($"{pagingSpec.SortKey} {sortDirection} LIMIT {pagingSpec.PageSize} OFFSET {pagingOffset}"); builder.OrderBy($"\"{sortKey}\" {sortDirection} LIMIT {pagingSpec.PageSize} OFFSET {pagingOffset}");
return queryFunc(builder).ToList(); return queryFunc(builder).ToList();
} }

@ -1,27 +1,36 @@
using System; using System;
using System.Data.SQLite; using System.Data.SQLite;
using Npgsql;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Core.Datastore namespace NzbDrone.Core.Datastore
{ {
public interface IConnectionStringFactory public interface IConnectionStringFactory
{ {
string MainDbConnectionString { get; } DatabaseConnectionInfo MainDbConnection { get; }
string LogDbConnectionString { get; } DatabaseConnectionInfo LogDbConnection { get; }
string GetDatabasePath(string connectionString); string GetDatabasePath(string connectionString);
} }
public class ConnectionStringFactory : IConnectionStringFactory public class ConnectionStringFactory : IConnectionStringFactory
{ {
public ConnectionStringFactory(IAppFolderInfo appFolderInfo) private readonly IConfigFileProvider _configFileProvider;
public ConnectionStringFactory(IAppFolderInfo appFolderInfo, IConfigFileProvider configFileProvider)
{ {
MainDbConnectionString = GetConnectionString(appFolderInfo.GetDatabase()); _configFileProvider = configFileProvider;
LogDbConnectionString = GetConnectionString(appFolderInfo.GetLogDatabase());
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 DatabaseConnectionInfo MainDbConnection { get; private set; }
public string LogDbConnectionString { get; private set; } public DatabaseConnectionInfo LogDbConnection { get; private set; }
public string GetDatabasePath(string connectionString) public string GetDatabasePath(string connectionString)
{ {
@ -30,23 +39,39 @@ namespace NzbDrone.Core.Datastore
return connectionBuilder.DataSource; return connectionBuilder.DataSource;
} }
private static string GetConnectionString(string dbPath) private static DatabaseConnectionInfo GetConnectionString(string dbPath)
{ {
var connectionBuilder = new SQLiteConnectionStringBuilder(); var connectionBuilder = new SQLiteConnectionStringBuilder
{
connectionBuilder.DataSource = dbPath; DataSource = dbPath,
connectionBuilder.CacheSize = (int)-10000; CacheSize = (int)-10000,
connectionBuilder.DateTimeKind = DateTimeKind.Utc; DateTimeKind = DateTimeKind.Utc,
connectionBuilder.JournalMode = OsInfo.IsOsx ? SQLiteJournalModeEnum.Truncate : SQLiteJournalModeEnum.Wal; JournalMode = OsInfo.IsOsx ? SQLiteJournalModeEnum.Truncate : SQLiteJournalModeEnum.Wal,
connectionBuilder.Pooling = true; Pooling = true,
connectionBuilder.Version = 3; Version = 3
};
if (OsInfo.IsOsx) if (OsInfo.IsOsx)
{ {
connectionBuilder.Add("Full FSync", true); 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;
using System.Data.Common;
using System.Data.SQLite;
using System.Text.RegularExpressions;
using Dapper; using Dapper;
using NLog; using NLog;
using NzbDrone.Common.Instrumentation; using NzbDrone.Common.Instrumentation;
@ -11,6 +14,7 @@ namespace NzbDrone.Core.Datastore
IDbConnection OpenConnection(); IDbConnection OpenConnection();
Version Version { get; } Version Version { get; }
int Migration { get; } int Migration { get; }
DatabaseType DatabaseType { get; }
void Vacuum(); void Vacuum();
} }
@ -32,15 +36,25 @@ namespace NzbDrone.Core.Datastore
return _datamapperFactory(); return _datamapperFactory();
} }
public DatabaseType DatabaseType
{
get
{
using var db = _datamapperFactory();
return db is SQLiteConnection ? DatabaseType.SQLite : DatabaseType.PostgreSQL;
}
}
public Version Version public Version Version
{ {
get get
{ {
using (var db = _datamapperFactory()) using var db = _datamapperFactory();
{ var dbConnection = db as DbConnection;
var version = db.QueryFirstOrDefault<string>("SELECT sqlite_version()"); var version = Regex.Replace(dbConnection.ServerVersion, @"\(.*?\)", "");
return new Version(version);
} return new Version(version);
} }
} }
@ -50,7 +64,7 @@ namespace NzbDrone.Core.Datastore
{ {
using (var db = _datamapperFactory()) 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;
using System.Data.Common;
using System.Data.SQLite; using System.Data.SQLite;
using System.Net.Sockets;
using System.Threading;
using NLog; using NLog;
using Npgsql;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Exceptions; using NzbDrone.Common.Exceptions;
@ -57,22 +61,22 @@ namespace NzbDrone.Core.Datastore
public IDatabase Create(MigrationContext migrationContext) public IDatabase Create(MigrationContext migrationContext)
{ {
string connectionString; DatabaseConnectionInfo connectionInfo;
switch (migrationContext.MigrationType) switch (migrationContext.MigrationType)
{ {
case MigrationType.Main: case MigrationType.Main:
{ {
connectionString = _connectionStringFactory.MainDbConnectionString; connectionInfo = _connectionStringFactory.MainDbConnection;
CreateMain(connectionString, migrationContext); CreateMain(connectionInfo.ConnectionString, migrationContext);
break; break;
} }
case MigrationType.Log: case MigrationType.Log:
{ {
connectionString = _connectionStringFactory.LogDbConnectionString; connectionInfo = _connectionStringFactory.LogDbConnection;
CreateLog(connectionString, migrationContext); CreateLog(connectionInfo.ConnectionString, migrationContext);
break; break;
} }
@ -85,10 +89,19 @@ namespace NzbDrone.Core.Datastore
var db = new Database(migrationContext.MigrationType.ToString(), () => var db = new Database(migrationContext.MigrationType.ToString(), () =>
{ {
var conn = SQLiteFactory.Instance.CreateConnection(); DbConnection conn;
conn.ConnectionString = connectionString;
conn.Open(); if (connectionInfo.DatabaseType == DatabaseType.SQLite)
{
conn = SQLiteFactory.Instance.CreateConnection();
conn.ConnectionString = connectionInfo.ConnectionString;
}
else
{
conn = new NpgsqlConnection(connectionInfo.ConnectionString);
}
conn.Open();
return conn; 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); 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) catch (Exception e)
{ {
throw new SonarrStartupException(e, "Error creating main database"); 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) 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) 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) 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) 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); return builder.Where(wb.ToString(), wb.Parameters);
} }
public static SqlBuilder OrWhere<TModel>(this SqlBuilder builder, Expression<Func<TModel, bool>> filter) 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); return builder.OrWhere(wb.ToString(), wb.Parameters);
} }
public static SqlBuilder Join<TLeft, TRight>(this SqlBuilder builder, Expression<Func<TLeft, TRight, bool>> filter) 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)); 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) 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)); 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) public static SqlBuilder GroupBy<TModel>(this SqlBuilder builder, Expression<Func<TModel, object>> property)
{ {
var table = TableMapping.Mapper.TableNameMapping(typeof(TModel)); var table = TableMapping.Mapper.TableNameMapping(typeof(TModel));
var propName = property.GetMemberName().Name; 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) public static SqlBuilder.Template AddSelectTemplate(this SqlBuilder builder, Type type)
@ -138,6 +145,18 @@ namespace NzbDrone.Core.Datastore
return sb.ToString(); 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) private static Dictionary<string, object> ToDictionary(this DynamicParameters dynamicParams)
{ {
var argsDictionary = new Dictionary<string, object>(); var argsDictionary = new Dictionary<string, object>();
@ -150,11 +169,14 @@ namespace NzbDrone.Core.Datastore
} }
var templates = dynamicParams.GetType().GetField("templates", BindingFlags.NonPublic | BindingFlags.Instance); 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 public class LogDatabase : ILogDatabase
{ {
private readonly IDatabase _database; private readonly IDatabase _database;
private readonly DatabaseType _databaseType;
public LogDatabase(IDatabase database) public LogDatabase(IDatabase database)
{ {
_database = database; _database = database;
_databaseType = _database == null ? DatabaseType.SQLite : _database.DatabaseType;
} }
public IDbConnection OpenConnection() public IDbConnection OpenConnection()
@ -25,6 +27,8 @@ namespace NzbDrone.Core.Datastore
public int Migration => _database.Migration; public int Migration => _database.Migration;
public DatabaseType DatabaseType => _databaseType;
public void Vacuum() public void Vacuum()
{ {
_database.Vacuum(); _database.Vacuum();

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

@ -1,4 +1,4 @@
using FluentMigrator; using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -13,7 +13,7 @@ namespace NzbDrone.Core.Datastore.Migration
.AsBoolean() .AsBoolean()
.Nullable(); .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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -10,8 +10,8 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
Delete.Column("SeasonFolderFormat").FromTable("NamingConfig"); Delete.Column("SeasonFolderFormat").FromTable("NamingConfig");
Execute.Sql("UPDATE NamingConfig SET RenameEpisodes = 1 WHERE RenameEpisodes = -1"); IfDatabase("sqlite").Update.Table("NamingConfig").Set(new { RenameEpisodes = 1 }).Where(new { RenameEpisodes = -1 });
Execute.Sql("UPDATE NamingConfig SET RenameEpisodes = 0 WHERE RenameEpisodes = -2"); 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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -11,11 +11,11 @@ namespace NzbDrone.Core.Datastore.Migration
Alter.Table("Episodes").AddColumn("Monitored").AsBoolean().Nullable(); Alter.Table("Episodes").AddColumn("Monitored").AsBoolean().Nullable();
Alter.Table("Seasons").AddColumn("Monitored").AsBoolean().Nullable(); Alter.Table("Seasons").AddColumn("Monitored").AsBoolean().Nullable();
Execute.Sql("UPDATE Episodes SET Monitored = 1 WHERE Ignored = 0"); Update.Table("Episodes").Set(new { Monitored = true }).Where(new { Ignored = false });
Execute.Sql("UPDATE Episodes SET Monitored = 0 WHERE Ignored = 1"); Update.Table("Episodes").Set(new { Monitored = false }).Where(new { Ignored = true });
Execute.Sql("UPDATE Seasons SET Monitored = 1 WHERE Ignored = 0"); Update.Table("Seasons").Set(new { Monitored = true }).Where(new { Ignored = false });
Execute.Sql("UPDATE Seasons SET Monitored = 0 WHERE Ignored = 1"); 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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -10,7 +10,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
Alter.Table("Episodes").AddColumn("AirDateUtc").AsDateTime().Nullable(); 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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
protected override void MainDbUpgrade() 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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -9,7 +9,7 @@ namespace NzbDrone.Core.Datastore.Migration
protected override void MainDbUpgrade() protected override void MainDbUpgrade()
{ {
// we were storing new file name as scene name. // 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.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
@ -35,7 +35,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
var getDuplicates = conn.CreateCommand(); var getDuplicates = conn.CreateCommand();
getDuplicates.Transaction = tran; 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>>(); var result = new List<KeyValuePair<int, T>>();
@ -68,19 +68,19 @@ namespace NzbDrone.Core.Datastore.Migration
var deleteCmd = conn.CreateCommand(); var deleteCmd = conn.CreateCommand();
deleteCmd.Transaction = tran; 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.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.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.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.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(); deleteCmd.ExecuteNonQuery();
} }
@ -89,10 +89,10 @@ namespace NzbDrone.Core.Datastore.Migration
var deleteCmd = conn.CreateCommand(); var deleteCmd = conn.CreateCommand();
deleteCmd.Transaction = tran; 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.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(); deleteCmd.ExecuteNonQuery();
} }
} }

@ -22,7 +22,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var allSeriesCmd = conn.CreateCommand()) using (var allSeriesCmd = conn.CreateCommand())
{ {
allSeriesCmd.Transaction = tran; allSeriesCmd.Transaction = tran;
allSeriesCmd.CommandText = @"SELECT Id FROM Series"; allSeriesCmd.CommandText = "SELECT \"Id\" FROM \"Series\"";
using (var allSeriesReader = allSeriesCmd.ExecuteReader()) using (var allSeriesReader = allSeriesCmd.ExecuteReader())
{ {
while (allSeriesReader.Read()) while (allSeriesReader.Read())
@ -33,7 +33,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var seasonsCmd = conn.CreateCommand()) using (var seasonsCmd = conn.CreateCommand())
{ {
seasonsCmd.Transaction = tran; 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()) using (var seasonReader = seasonsCmd.ExecuteReader())
{ {
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) 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.Transaction = tran;
updateCmd.CommandText = text; updateCmd.CommandText = text;

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

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

@ -1,4 +1,5 @@
using FluentMigrator; using System;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +9,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
protected override void MainDbUpgrade() 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()) using (var selectCommand = conn.CreateCommand())
{ {
selectCommand.Transaction = tran; selectCommand.Transaction = tran;
selectCommand.CommandText = @"SELECT * FROM Notifications WHERE ConfigContract = 'PushoverSettings'"; selectCommand.CommandText = "SELECT * FROM \"Notifications\" WHERE \"ConfigContract\" = 'PushoverSettings'";
using (var reader = selectCommand.ExecuteReader()) using (var reader = selectCommand.ExecuteReader())
{ {
@ -41,9 +41,9 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
var text = string.Format("UPDATE Notifications " + var text = string.Format("UPDATE \"Notifications\" " +
"SET Settings = '{0}'" + "SET \"Settings\" = '{0}'" +
"WHERE Id = {1}", "WHERE \"Id\" = {1}",
settings.ToJson(), settings.ToJson(),
id); id);

@ -1,4 +1,4 @@
using FluentMigrator; using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -10,7 +10,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
Alter.Table("NamingConfig").AddColumn("SeriesFolderFormat").AsString().Nullable(); 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()) using (var qualityProfileCmd = conn.CreateCommand())
{ {
qualityProfileCmd.Transaction = tran; qualityProfileCmd.Transaction = tran;
qualityProfileCmd.CommandText = @"SELECT Id, Allowed FROM QualityProfiles"; qualityProfileCmd.CommandText = "SELECT \"Id\", \"Allowed\" FROM \"QualityProfiles\"";
using (var qualityProfileReader = qualityProfileCmd.ExecuteReader()) using (var qualityProfileReader = qualityProfileCmd.ExecuteReader())
{ {
while (qualityProfileReader.Read()) while (qualityProfileReader.Read())
@ -47,7 +47,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
updateCmd.Transaction = tran; updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE QualityProfiles SET Items = ? WHERE Id = ?"; updateCmd.CommandText = "UPDATE \"QualityProfiles\" SET \"Items\" = ? WHERE \"Id\" = ?";
var param = updateCmd.CreateParameter(); var param = updateCmd.CreateParameter();
qualityProfileItemConverter.SetValue(param, items); qualityProfileItemConverter.SetValue(param, items);
updateCmd.Parameters.Add(param); updateCmd.Parameters.Add(param);
@ -75,7 +75,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var qualityModelCmd = conn.CreateCommand()) using (var qualityModelCmd = conn.CreateCommand())
{ {
qualityModelCmd.Transaction = tran; qualityModelCmd.Transaction = tran;
qualityModelCmd.CommandText = @"SELECT Distinct Quality FROM " + tableName; qualityModelCmd.CommandText = $"SELECT Distinct \"Quality\" FROM \"{tableName}\"";
using (var qualityModelReader = qualityModelCmd.ExecuteReader()) using (var qualityModelReader = qualityModelCmd.ExecuteReader())
{ {
while (qualityModelReader.Read()) while (qualityModelReader.Read())
@ -96,7 +96,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
updateCmd.Transaction = tran; updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE " + tableName + " SET Quality = ? WHERE Quality = ?"; updateCmd.CommandText = "UPDATE \"" + tableName + "\" SET \"Quality\" = ? WHERE \"Quality\" = ?";
var param = updateCmd.CreateParameter(); var param = updateCmd.CreateParameter();
qualityModelConverter.SetValue(param, qualityNew); qualityModelConverter.SetValue(param, qualityNew);
updateCmd.Parameters.Add(param); updateCmd.Parameters.Add(param);

@ -33,7 +33,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var qualitySizeCmd = conn.CreateCommand()) using (var qualitySizeCmd = conn.CreateCommand())
{ {
qualitySizeCmd.Transaction = tran; qualitySizeCmd.Transaction = tran;
qualitySizeCmd.CommandText = @"SELECT QualityId, MinSize, MaxSize FROM QualitySizes"; qualitySizeCmd.CommandText = "SELECT \"QualityId\", \"MinSize\", \"MaxSize\" FROM \"QualitySizes\"";
using (var qualitySizeReader = qualitySizeCmd.ExecuteReader()) using (var qualitySizeReader = qualitySizeCmd.ExecuteReader())
{ {
while (qualitySizeReader.Read()) while (qualitySizeReader.Read())
@ -47,7 +47,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
updateCmd.Transaction = tran; 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(qualityId);
updateCmd.AddParameter(defaultConfig.Title); updateCmd.AddParameter(defaultConfig.Title);
updateCmd.AddParameter(defaultConfig.Weight); updateCmd.AddParameter(defaultConfig.Weight);

@ -1,4 +1,4 @@
using FluentMigrator; using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -10,7 +10,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
Alter.Table("Notifications").AddColumn("OnUpgrade").AsBoolean().Nullable(); 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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
protected override void MainDbUpgrade() 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()) using (var configCmd = conn.CreateCommand())
{ {
configCmd.Transaction = tran; configCmd.Transaction = tran;
configCmd.CommandText = @"SELECT * FROM Config"; configCmd.CommandText = "SELECT * FROM \"Config\"";
using (var configReader = configCmd.ExecuteReader()) using (var configReader = configCmd.ExecuteReader())
{ {
var keyIndex = configReader.GetOrdinal("Key"); var keyIndex = configReader.GetOrdinal("Key");
@ -121,7 +121,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
using (var updateCmd = conn.CreateCommand()) 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(name);
updateCmd.AddParameter(implementation); updateCmd.AddParameter(implementation);
updateCmd.AddParameter(settings); updateCmd.AddParameter(settings);
@ -138,7 +138,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
using (var updateCmd = conn.CreateCommand()) 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', " + "'nzbgettvcategory', 'nzbgetrecenttvpriority', 'nzbgetoldertvpriority', 'sabhost', 'sabport', " +
"'sabapikey', 'sabusername', 'sabpassword', 'sabtvcategory', 'sabrecenttvpriority', " + "'sabapikey', 'sabusername', 'sabpassword', 'sabtvcategory', 'sabrecenttvpriority', " +
"'saboldertvpriority', 'sabusessl', 'downloadclient', 'blackholefolder', 'pneumaticfolder')"; "'saboldertvpriority', 'sabusessl', 'downloadclient', 'blackholefolder', 'pneumaticfolder')";

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

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

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

@ -27,13 +27,13 @@ namespace NzbDrone.Core.Datastore.Migration
using (var cmd = conn.CreateCommand()) using (var cmd = conn.CreateCommand())
{ {
cmd.Transaction = tran; 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(); var result = cmd.ExecuteScalar();
if (result == null) 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(); cmd.ExecuteNonQuery();
} }
} }
@ -44,11 +44,11 @@ namespace NzbDrone.Core.Datastore.Migration
using (var downloadClientsCmd = conn.CreateCommand()) using (var downloadClientsCmd = conn.CreateCommand())
{ {
downloadClientsCmd.Transaction = tran; 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; var downloadedEpisodesFolder = downloadClientsCmd.ExecuteScalar() as string;
downloadClientsCmd.Transaction = tran; 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()) using (var downloadClientReader = downloadClientsCmd.ExecuteReader())
{ {
while (downloadClientReader.Read()) while (downloadClientReader.Read())
@ -71,7 +71,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
updateCmd.Transaction = tran; 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("UsenetBlackhole");
updateCmd.AddParameter(newSettings); updateCmd.AddParameter(newSettings);
updateCmd.AddParameter("UsenetBlackholeSettings"); updateCmd.AddParameter("UsenetBlackholeSettings");
@ -90,7 +90,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
updateCmd.Transaction = tran; 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(newSettings);
updateCmd.AddParameter("PneumaticSettings"); updateCmd.AddParameter("PneumaticSettings");
updateCmd.AddParameter(id); updateCmd.AddParameter(id);
@ -103,7 +103,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
updateCmd.Transaction = tran; updateCmd.Transaction = tran;
updateCmd.CommandText = "DELETE FROM DownloadClients WHERE Id = ?"; updateCmd.CommandText = "DELETE FROM \"DownloadClients\" WHERE \"Id\" = ?";
updateCmd.AddParameter(id); updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery(); updateCmd.ExecuteNonQuery();
@ -141,7 +141,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var historyCmd = conn.CreateCommand()) using (var historyCmd = conn.CreateCommand())
{ {
historyCmd.Transaction = tran; 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()) using (var historyRead = historyCmd.ExecuteReader())
{ {
while (historyRead.Read()) while (historyRead.Read())
@ -238,7 +238,7 @@ namespace NzbDrone.Core.Datastore.Migration
pair.Key.Data["downloadClientId"] = pair.Value.Data["downloadClientId"]; pair.Key.Data["downloadClientId"] = pair.Value.Data["downloadClientId"];
updateHistoryCmd.Transaction = tran; 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.Data.ToJson());
updateHistoryCmd.AddParameter(pair.Key.Id); updateHistoryCmd.AddParameter(pair.Key.Id);

@ -1,4 +1,4 @@
using FluentMigrator; using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -10,11 +10,11 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
// Support XEM names // Support XEM names
Alter.Table("SceneMappings").AddColumn("Type").AsString().Nullable(); 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) // Add AnimeEpisodeFormat (set to Standard Episode format for now)
Alter.Table("NamingConfig").AddColumn("AnimeEpisodeFormat").AsString().Nullable(); 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()) using (var getSeriesCmd = conn.CreateCommand())
{ {
getSeriesCmd.Transaction = tran; getSeriesCmd.Transaction = tran;
getSeriesCmd.CommandText = @"SELECT Id, Title FROM Series"; getSeriesCmd.CommandText = "SELECT \"Id\", \"Title\" FROM \"Series\"";
using (var seriesReader = getSeriesCmd.ExecuteReader()) using (var seriesReader = getSeriesCmd.ExecuteReader())
{ {
while (seriesReader.Read()) while (seriesReader.Read())
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
updateCmd.Transaction = tran; updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE Series SET SortTitle = ? WHERE Id = ?"; updateCmd.CommandText = "UPDATE \"Series\" SET \"SortTitle\" = ? WHERE \"Id\" = ?";
updateCmd.AddParameter(sortTitle); updateCmd.AddParameter(sortTitle);
updateCmd.AddParameter(id); updateCmd.AddParameter(id);

@ -1,4 +1,4 @@
using FluentMigrator; using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration 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("Language").AsInt32().Nullable();
Alter.Table("Profiles").AddColumn("GrabDelay").AsInt32().Nullable(); Alter.Table("Profiles").AddColumn("GrabDelay").AsInt32().Nullable();
Alter.Table("Profiles").AddColumn("GrabDelayMode").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 // Rename QualityProfileId in Series
Alter.Table("Series").AddColumn("ProfileId").AsInt32().Nullable(); Alter.Table("Series").AddColumn("ProfileId").AsInt32().Nullable();
Execute.Sql("UPDATE Series SET ProfileId = QualityProfileId"); Execute.Sql("UPDATE \"Series\" SET \"ProfileId\" = \"QualityProfileId\"");
// Add HeldReleases // Add HeldReleases
Create.TableForModel("PendingReleases") Create.TableForModel("PendingReleases")

@ -23,7 +23,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var getSeriesCmd = conn.CreateCommand()) using (var getSeriesCmd = conn.CreateCommand())
{ {
getSeriesCmd.Transaction = tran; getSeriesCmd.Transaction = tran;
getSeriesCmd.CommandText = @"SELECT Id, Path FROM Series"; getSeriesCmd.CommandText = "SELECT \"Id\", \"Path\" FROM \"Series\"";
using (var seriesReader = getSeriesCmd.ExecuteReader()) using (var seriesReader = getSeriesCmd.ExecuteReader())
{ {
while (seriesReader.Read()) while (seriesReader.Read())
@ -34,7 +34,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var updateCmd = conn.CreateCommand()) using (var updateCmd = conn.CreateCommand())
{ {
updateCmd.Transaction = tran; 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(seriesPath);
updateCmd.AddParameter(seriesId); updateCmd.AddParameter(seriesId);

@ -1,4 +1,4 @@
using FluentMigrator; using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -12,8 +12,8 @@ namespace NzbDrone.Core.Datastore.Migration
.AddColumn("EnableRss").AsBoolean().Nullable() .AddColumn("EnableRss").AsBoolean().Nullable()
.AddColumn("EnableSearch").AsBoolean().Nullable(); .AddColumn("EnableSearch").AsBoolean().Nullable();
Execute.Sql("UPDATE Indexers SET EnableRss = Enable, EnableSearch = Enable"); Execute.Sql("UPDATE \"Indexers\" SET \"EnableRss\" = \"Enable\", \"EnableSearch\" = \"Enable\"");
Execute.Sql("UPDATE Indexers SET EnableSearch = 0 WHERE Implementation = 'Wombles'"); 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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -8,15 +8,15 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
protected override void MainDbUpgrade() protected override void MainDbUpgrade()
{ {
Execute.Sql("UPDATE [EpisodeFiles] " + Execute.Sql("UPDATE \"EpisodeFiles\" " +
"SET ReleaseGroup = NULL , SceneName = NULL " + "SET \"ReleaseGroup\" = NULL , \"SceneName\" = NULL " +
"WHERE " + "WHERE " +
" ReleaseGroup IS NULL " + " \"ReleaseGroup\" IS NULL " +
" OR SceneName IS NULL " + " OR \"SceneName\" IS NULL " +
" OR ReleaseGroup =='DRONE' " + " OR \"ReleaseGroup\" = 'DRONE' " +
" OR LENGTH(SceneName) <10 " + " OR LENGTH(\"SceneName\") <10 " +
" OR LENGTH(ReleaseGroup) > 20 " + " OR LENGTH(\"ReleaseGroup\") > 20 " +
" OR SceneName NOT LIKE '%.%'"); " OR \"SceneName\" NOT LIKE '%.%'");
} }
} }
} }

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

@ -1,4 +1,5 @@
using FluentMigrator; using System;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -8,9 +9,9 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
protected override void MainDbUpgrade() protected override void MainDbUpgrade()
{ {
Execute.Sql("UPDATE Episodes SET AbsoluteEpisodeNumber = NULL WHERE AbsoluteEpisodeNumber = 0"); Update.Table("Episodes").Set(new { AbsoluteEpisodeNumber = DBNull.Value }).Where(new { AbsoluteEpisodeNumber = 0 });
Execute.Sql("UPDATE Episodes SET SceneAbsoluteEpisodeNumber = NULL WHERE SceneAbsoluteEpisodeNumber = 0"); Update.Table("Episodes").Set(new { SceneAbsoluteEpisodeNumber = DBNull.Value }).Where(new { SceneAbsoluteEpisodeNumber = 0 });
Execute.Sql("UPDATE Episodes SET SceneSeasonNumber = NULL, SceneEpisodeNumber = NULL WHERE SceneSeasonNumber = 0 AND SceneEpisodeNumber = 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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -17,8 +17,8 @@ namespace NzbDrone.Core.Datastore.Migration
Alter.Table("Notifications") Alter.Table("Notifications")
.AddColumn("Tags").AsString().Nullable(); .AddColumn("Tags").AsString().Nullable();
Execute.Sql("UPDATE Series SET Tags = '[]'"); Update.Table("Series").Set(new { Tags = "[]" }).AllRows();
Execute.Sql("UPDATE Notifications SET Tags = '[]'"); Update.Table("Notifications").Set(new { Tags = "[]" }).AllRows();
} }
} }
} }

@ -16,7 +16,7 @@ namespace NzbDrone.Core.Datastore.Migration
.WithColumn("Tags").AsString().NotNullable(); .WithColumn("Tags").AsString().NotNullable();
Execute.WithConnection(ConvertRestrictions); 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) private void ConvertRestrictions(IDbConnection conn, IDbTransaction tran)
@ -24,7 +24,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var getRestictionsCmd = conn.CreateCommand()) using (var getRestictionsCmd = conn.CreateCommand())
{ {
getRestictionsCmd.Transaction = tran; 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()) using (var configReader = getRestictionsCmd.ExecuteReader())
{ {
@ -36,7 +36,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var insertCmd = conn.CreateCommand()) using (var insertCmd = conn.CreateCommand())
{ {
insertCmd.Transaction = tran; insertCmd.Transaction = tran;
insertCmd.CommandText = "INSERT INTO Restrictions (Ignored, Tags) VALUES (?, '[]')"; insertCmd.CommandText = "INSERT INTO \"Restrictions\" (\"Ignored\", \"Tags\") VALUES (?, '[]')";
insertCmd.AddParameter(restrictions); insertCmd.AddParameter(restrictions);
insertCmd.ExecuteNonQuery(); insertCmd.ExecuteNonQuery();

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

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

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using Dapper;
using FluentMigrator; using FluentMigrator;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
@ -22,10 +23,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void MoveToColumn(IDbConnection conn, IDbTransaction tran) private void MoveToColumn(IDbConnection conn, IDbTransaction tran)
{ {
var updatedHistory = new List<object>();
using (var getHistory = conn.CreateCommand()) using (var getHistory = conn.CreateCommand())
{ {
getHistory.Transaction = tran; 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()) using (var historyReader = getHistory.ExecuteReader())
{ {
@ -34,30 +37,23 @@ namespace NzbDrone.Core.Datastore.Migration
var id = historyReader.GetInt32(0); var id = historyReader.GetInt32(0);
var data = historyReader.GetString(1); 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"]; var updateSql = $"UPDATE \"History\" SET \"DownloadId\" = @DownloadId, \"Data\" = @Data WHERE \"Id\" = @Id";
dic.Remove("downloadClientId"); conn.Execute(updateSql, updatedHistory, transaction: tran);
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();
}
} }
} }

@ -1,4 +1,4 @@
using FluentMigrator; using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
protected override void MainDbUpgrade() 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.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using Dapper;
using FluentMigrator; using FluentMigrator;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
@ -48,7 +49,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var tagCmd = conn.CreateCommand()) using (var tagCmd = conn.CreateCommand())
{ {
tagCmd.Transaction = tran; tagCmd.Transaction = tran;
tagCmd.CommandText = @"SELECT Id, Label FROM Tags"; tagCmd.CommandText = "SELECT \"Id\", \"Label\" FROM \"Tags\"";
using (var tagReader = tagCmd.ExecuteReader()) using (var tagReader = tagCmd.ExecuteReader())
{ {
@ -72,7 +73,7 @@ namespace NzbDrone.Core.Datastore.Migration
using (var tagCmd = conn.CreateCommand()) using (var tagCmd = conn.CreateCommand())
{ {
tagCmd.Transaction = tran; 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()) 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()) Tags = t.Tags.ToJson(),
{ Id = t.Id
updateCmd.Transaction = tran; });
updateCmd.CommandText = string.Format(@"UPDATE {0} SET Tags = ? WHERE Id = ?", table);
updateCmd.AddParameter(model.Tags.ToJson());
updateCmd.AddParameter(model.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) private void DeleteTags(IDbConnection conn, IDbTransaction tran, List<TagReplacement079> replacements)
{ {
var idsToRemove = replacements.Select(r => r.OldId).Distinct(); var idsToRemove = replacements.Select(r => r.OldId).Distinct();
using (var removeCmd = conn.CreateCommand()) if (idsToRemove.Any())
{ {
removeCmd.Transaction = tran; using (var removeCmd = conn.CreateCommand())
removeCmd.CommandText = string.Format("DELETE FROM Tags WHERE Id IN ({0})", string.Join(",", idsToRemove)); {
removeCmd.ExecuteNonQuery(); 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 System.Data;
using Dapper;
using FluentMigrator; using FluentMigrator;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
@ -18,10 +19,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran) private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
{ {
var updatedClients = new List<object>();
using (var cmd = conn.CreateCommand()) using (var cmd = conn.CreateCommand())
{ {
cmd.Transaction = tran; 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()) using (var reader = cmd.ExecuteReader())
{ {
@ -37,19 +40,18 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
settings["tvCategory"] = "." + tvCategory; settings["tvCategory"] = "." + tvCategory;
using (var updateCmd = conn.CreateCommand()) updatedClients.Add(new
{ {
updateCmd.Transaction = tran; Settings = settings.ToJson(),
updateCmd.CommandText = "UPDATE DownloadClients SET Settings = ? WHERE Id = ?"; Id = id
updateCmd.AddParameter(settings.ToJson()); });
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
} }
} }
} }
} }
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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
protected override void MainDbUpgrade() 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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration 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("MinSize").AsDouble().Nullable();
Alter.Table("QualityDefinitions").AlterColumn("MaxSize").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 System.Data;
using Dapper;
using FluentMigrator; using FluentMigrator;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
@ -17,10 +18,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran) private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
{ {
var updatedClients = new List<object>();
using (var cmd = conn.CreateCommand()) using (var cmd = conn.CreateCommand())
{ {
cmd.Transaction = tran; 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()) using (var reader = cmd.ExecuteReader())
{ {
@ -42,18 +45,17 @@ namespace NzbDrone.Core.Datastore.Migration
settings["urlBase"] = string.Format("/{0}/transmission/", urlBase.Trim('/')); settings["urlBase"] = string.Format("/{0}/transmission/", urlBase.Trim('/'));
} }
using (var updateCmd = conn.CreateCommand()) updatedClients.Add(new
{ {
updateCmd.Transaction = tran; Settings = settings.ToJson(),
updateCmd.CommandText = "UPDATE DownloadClients SET Settings = ? WHERE Id = ?"; Id = id
updateCmd.AddParameter(settings.ToJson()); });
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
} }
} }
} }
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.Collections.Generic;
using System.Data; using System.Data;
using Dapper;
using FluentMigrator; using FluentMigrator;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
@ -17,10 +18,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran) private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
{ {
var updatedClients = new List<object>();
using (var cmd = conn.CreateCommand()) using (var cmd = conn.CreateCommand())
{ {
cmd.Transaction = tran; 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()) using (var reader = cmd.ExecuteReader())
{ {
@ -37,19 +40,18 @@ namespace NzbDrone.Core.Datastore.Migration
settings.Add("deviceIds", new[] { deviceId }); settings.Add("deviceIds", new[] { deviceId });
settings.Remove("deviceId"); settings.Remove("deviceId");
using (var updateCmd = conn.CreateCommand()) updatedClients.Add(new
{ {
updateCmd.Transaction = tran; Settings = settings.ToJson(),
updateCmd.CommandText = "UPDATE Notifications SET Settings = ? WHERE Id = ?"; Id = id
updateCmd.AddParameter(settings.ToJson()); });
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
} }
} }
} }
} }
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; using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
protected override void MainDbUpgrade() 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.Collections.Generic;
using System.Data; using System.Data;
using Dapper;
using FluentMigrator; using FluentMigrator;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer; using NzbDrone.Common.Serializer;
@ -18,10 +19,12 @@ namespace NzbDrone.Core.Datastore.Migration
private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran) private void UpdateTransmissionSettings(IDbConnection conn, IDbTransaction tran)
{ {
var updatedClients = new List<object>();
using (var cmd = conn.CreateCommand()) using (var cmd = conn.CreateCommand())
{ {
cmd.Transaction = tran; 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()) 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; Settings = settings.ToJson(),
updateCmd.CommandText = "UPDATE Notifications SET Settings = ? WHERE Id = ?"; Id = id
updateCmd.AddParameter(settings.ToJson()); });
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
} }
} }
} }
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