parent
bd53092f0c
commit
9b21408a03
@ -0,0 +1,206 @@
|
|||||||
|
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.Movies;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Datastore
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class WhereBuilderPostgresFixture : CoreTest
|
||||||
|
{
|
||||||
|
private WhereBuilderPostgres _subject;
|
||||||
|
|
||||||
|
[OneTimeSetUp]
|
||||||
|
public void MapTables()
|
||||||
|
{
|
||||||
|
// Generate table mapping
|
||||||
|
Mocker.Resolve<DbFactory>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private WhereBuilderPostgres Where(Expression<Func<Movie, bool>> filter)
|
||||||
|
{
|
||||||
|
return new WhereBuilderPostgres(filter, true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_equal_const()
|
||||||
|
{
|
||||||
|
_subject = Where(x => x.Id == 10);
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
|
||||||
|
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_equal_variable()
|
||||||
|
{
|
||||||
|
var id = 10;
|
||||||
|
_subject = Where(x => x.Id == id);
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
|
||||||
|
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_equal_property()
|
||||||
|
{
|
||||||
|
var movie = new Movie { Id = 10 };
|
||||||
|
_subject = Where(x => x.Id == movie.Id);
|
||||||
|
|
||||||
|
_subject.Parameters.ParameterNames.Should().HaveCount(1);
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
|
||||||
|
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(movie.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_equal_joined_property()
|
||||||
|
{
|
||||||
|
_subject = Where(x => x.Profile.Id == 1);
|
||||||
|
|
||||||
|
_subject.Parameters.ParameterNames.Should().HaveCount(1);
|
||||||
|
_subject.ToString().Should().Be($"(\"Profiles\".\"Id\" = @Clause1_P1)");
|
||||||
|
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_throws_without_concrete_condition_if_requiresConcreteCondition()
|
||||||
|
{
|
||||||
|
Expression<Func<Movie, Movie, bool>> filter = (x, y) => x.Id == y.Id;
|
||||||
|
_subject = new WhereBuilderPostgres(filter, true, 0);
|
||||||
|
Assert.Throws<InvalidOperationException>(() => _subject.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_allows_abstract_condition_if_not_requiresConcreteCondition()
|
||||||
|
{
|
||||||
|
Expression<Func<Movie, Movie, bool>> filter = (x, y) => x.Id == y.Id;
|
||||||
|
_subject = new WhereBuilderPostgres(filter, false, 0);
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = \"Movies\".\"Id\")");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_string_is_null()
|
||||||
|
{
|
||||||
|
_subject = Where(x => x.CleanTitle == null);
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_string_is_null_value()
|
||||||
|
{
|
||||||
|
string cleanTitle = null;
|
||||||
|
_subject = Where(x => x.CleanTitle == cleanTitle);
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_equal_null_property()
|
||||||
|
{
|
||||||
|
var movie = new Movie { CleanTitle = null };
|
||||||
|
_subject = Where(x => x.CleanTitle == movie.CleanTitle);
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_column_contains_string()
|
||||||
|
{
|
||||||
|
var test = "small";
|
||||||
|
_subject = Where(x => x.CleanTitle.Contains(test));
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE '%' || @Clause1_P1 || '%')");
|
||||||
|
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_string_contains_column()
|
||||||
|
{
|
||||||
|
var test = "small";
|
||||||
|
_subject = Where(x => test.Contains(x.CleanTitle));
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(@Clause1_P1 ILIKE '%' || \"Movies\".\"CleanTitle\" || '%')");
|
||||||
|
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_column_starts_with_string()
|
||||||
|
{
|
||||||
|
var test = "small";
|
||||||
|
_subject = Where(x => x.CleanTitle.StartsWith(test));
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE @Clause1_P1 || '%')");
|
||||||
|
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_column_ends_with_string()
|
||||||
|
{
|
||||||
|
var test = "small";
|
||||||
|
_subject = Where(x => x.CleanTitle.EndsWith(test));
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" ILIKE '%' || @Clause1_P1)");
|
||||||
|
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_in_list()
|
||||||
|
{
|
||||||
|
var list = new List<int> { 1, 2, 3 };
|
||||||
|
_subject = Where(x => list.Contains(x.Id));
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = ANY (('{{1, 2, 3}}')))");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_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($"((\"Movies\".\"CleanTitle\" = @Clause1_P1) AND (\"Movies\".\"Id\" = ANY (('{{1, 2, 3}}'))))");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void postgres_where_in_string_list()
|
||||||
|
{
|
||||||
|
var list = new List<string> { "first", "second", "third" };
|
||||||
|
|
||||||
|
_subject = Where(x => list.Contains(x.CleanTitle));
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" = ANY (@Clause1_P1))");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void enum_as_int()
|
||||||
|
{
|
||||||
|
_subject = Where(x => x.Status == MovieStatusType.Announced);
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = @Clause1_P1)");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void enum_in_list()
|
||||||
|
{
|
||||||
|
var allowed = new List<MovieStatusType> { MovieStatusType.Announced, MovieStatusType.InCinemas };
|
||||||
|
_subject = Where(x => allowed.Contains(x.Status));
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = ANY (@Clause1_P1))");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void enum_in_array()
|
||||||
|
{
|
||||||
|
var allowed = new MovieStatusType[] { MovieStatusType.Announced, MovieStatusType.InCinemas };
|
||||||
|
_subject = Where(x => allowed.Contains(x.Status));
|
||||||
|
|
||||||
|
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = ANY (@Clause1_P1))");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using Npgsql;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Test.Common.Datastore
|
||||||
|
{
|
||||||
|
public static class PostgresDatabase
|
||||||
|
{
|
||||||
|
public static PostgresOptions GetTestOptions()
|
||||||
|
{
|
||||||
|
var options = PostgresOptions.GetOptions();
|
||||||
|
|
||||||
|
var uid = TestBase.GetUID();
|
||||||
|
options.MainDb = uid + "_main";
|
||||||
|
options.LogDb = uid + "_log";
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Create(PostgresOptions options, MigrationType migrationType)
|
||||||
|
{
|
||||||
|
var db = GetDatabaseName(options, migrationType);
|
||||||
|
var connectionString = GetConnectionString(options);
|
||||||
|
using var conn = new NpgsqlConnection(connectionString);
|
||||||
|
conn.Open();
|
||||||
|
|
||||||
|
using var cmd = conn.CreateCommand();
|
||||||
|
cmd.CommandText = $"CREATE DATABASE \"{db}\" WITH OWNER = {options.User} ENCODING = 'UTF8' CONNECTION LIMIT = -1;";
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Drop(PostgresOptions options, MigrationType migrationType)
|
||||||
|
{
|
||||||
|
var db = GetDatabaseName(options, migrationType);
|
||||||
|
var connectionString = GetConnectionString(options);
|
||||||
|
using var conn = new NpgsqlConnection(connectionString);
|
||||||
|
conn.Open();
|
||||||
|
|
||||||
|
using var cmd = conn.CreateCommand();
|
||||||
|
cmd.CommandText = $"DROP DATABASE \"{db}\" WITH (FORCE);";
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetConnectionString(PostgresOptions options)
|
||||||
|
{
|
||||||
|
var builder = new NpgsqlConnectionStringBuilder()
|
||||||
|
{
|
||||||
|
Host = options.Host,
|
||||||
|
Port = options.Port,
|
||||||
|
Username = options.User,
|
||||||
|
Password = options.Password,
|
||||||
|
Enlist = false
|
||||||
|
};
|
||||||
|
|
||||||
|
return builder.ConnectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetDatabaseName(PostgresOptions options, MigrationType migrationType)
|
||||||
|
{
|
||||||
|
return migrationType switch
|
||||||
|
{
|
||||||
|
MigrationType.Main => options.MainDb,
|
||||||
|
MigrationType.Log => options.LogDb,
|
||||||
|
_ => throw new NotImplementedException("Unknown migration type")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
using System.IO;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Test.Common.Datastore
|
||||||
|
{
|
||||||
|
public static class SqliteDatabase
|
||||||
|
{
|
||||||
|
public static string GetCachedDb(MigrationType type)
|
||||||
|
{
|
||||||
|
return Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_{type}.db");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RunSettings>
|
||||||
|
<RunConfiguration>
|
||||||
|
<EnvironmentVariables>
|
||||||
|
<Radarr__Postgres__Host>192.168.100.5</Radarr__Postgres__Host>
|
||||||
|
<Radarr__Postgres__Port>5432</Radarr__Postgres__Port>
|
||||||
|
<Radarr__Postgres__User>abc</Radarr__Postgres__User>
|
||||||
|
<Radarr__Postgres__Password>abc</Radarr__Postgres__Password>
|
||||||
|
</EnvironmentVariables>
|
||||||
|
</RunConfiguration>
|
||||||
|
</RunSettings>
|
Loading…
Reference in new issue