Skip to content

Commit

Permalink
fix: #1378, use configured StoreOptions (#1379)
Browse files Browse the repository at this point in the history
* fix: #1378, use configured StoreOptions

* Add back the original ctor, so no breaking change

* Revert laziness

* Add tests for #1378 fix

* Reverted change to test connection string

* Updated obsolete DuplicatedField constructor to use new one

* Formatting
  • Loading branch information
cocowalla authored and mysticmind committed Nov 7, 2019
1 parent 790cb27 commit 23835e6
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 22 deletions.
4 changes: 2 additions & 2 deletions src/Marten.Testing/ConnectionSource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;

namespace Marten.Testing
{
Expand All @@ -19,4 +19,4 @@ public ConnectionSource() : base(ConnectionString)
{
}
}
}
}
8 changes: 4 additions & 4 deletions src/Marten.Testing/Schema/DocumentMappingTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand All @@ -15,7 +15,7 @@

namespace Marten.Testing.Schema
{
public class DocumentMappingTests : IntegratedFixture
public class DocumentMappingTests: IntegratedFixture
{
public class FieldId
{
Expand Down Expand Up @@ -92,7 +92,7 @@ public class Organization
public string OtherField { get; set; }
}

public class CustomIdGeneration : IIdGeneration
public class CustomIdGeneration: IIdGeneration
{
public IEnumerable<Type> KeyTypes { get; }

Expand Down Expand Up @@ -804,4 +804,4 @@ public void add_overwrite_function_if_optimistic_concurrency()
objects.OfType<OverwriteFunction>().Any().ShouldBeTrue();
}
}
}
}
49 changes: 41 additions & 8 deletions src/Marten.Testing/Schema/DuplicatedFieldTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Reflection;
using Baseline.Reflection;
using Marten.Schema;
using Marten.Services;
using Marten.Testing.Documents;
using NpgsqlTypes;
using Shouldly;
Expand All @@ -12,7 +13,7 @@ namespace Marten.Testing.Schema
{
public class DuplicatedFieldTests
{
private DuplicatedField theField = new DuplicatedField(EnumStorage.AsInteger, new MemberInfo[] { ReflectionHelper.GetProperty<User>(x => x.FirstName) });
private DuplicatedField theField = new DuplicatedField(new StoreOptions(), new MemberInfo[] { ReflectionHelper.GetProperty<User>(x => x.FirstName) });

[Fact]
public void default_role_is_search()
Expand Down Expand Up @@ -53,7 +54,10 @@ public void sql_locator_with_custom_column_name()
[Fact]
public void enum_field()
{
var field = DuplicatedField.For<Target>(EnumStorage.AsString, x => x.Color);
var storeOptions = new StoreOptions();
storeOptions.Serializer(new JsonNetSerializer { EnumStorage = EnumStorage.AsString });

var field = DuplicatedField.For<Target>(storeOptions, x => x.Color);
field.UpsertArgument.DbType.ShouldBe(NpgsqlDbType.Varchar);
field.UpsertArgument.PostgresType.ShouldBe("varchar");

Expand All @@ -67,7 +71,10 @@ public void enum_field()
[InlineData(EnumStorage.AsString, "color = data ->> 'Color'")]
public void storage_is_set_when_passed_in(EnumStorage storageMode, string expectedUpdateFragment)
{
var field = DuplicatedField.For<Target>(storageMode, x => x.Color);
var storeOptions = new StoreOptions();
storeOptions.Serializer(new JsonNetSerializer { EnumStorage = storageMode });

var field = DuplicatedField.For<Target>(storeOptions, x => x.Color);
field.UpdateSqlFragment().ShouldBe(expectedUpdateFragment);
}

Expand All @@ -77,13 +84,13 @@ public void storage_is_set_when_passed_in(EnumStorage storageMode, string expect
[InlineData("text", "string = data ->> 'String'")]
public void pg_type_is_used_for_string(string pgType, string expectedUpdateFragment)
{
var field = DuplicatedField.For<Target>(EnumStorage.AsInteger, x => x.String);
var field = DuplicatedField.For<Target>(new StoreOptions(), x => x.String);
field.PgType = pgType ?? field.PgType;

field.UpdateSqlFragment().ShouldBe(expectedUpdateFragment);
var expectedPgType = pgType ?? "varchar";
field.PgType.ShouldBe(expectedPgType);
field.UpsertArgument.PostgresType.ShouldBe(expectedPgType);
field.UpsertArgument.PostgresType.ShouldBe(expectedPgType);
field.DbType.ShouldBe(NpgsqlDbType.Text);
}

Expand All @@ -93,7 +100,7 @@ public void pg_type_is_used_for_string(string pgType, string expectedUpdateFragm
[InlineData("text", "user_id = CAST(data ->> 'UserId' as text)")]
public void pg_type_is_used_for_guid(string pgType, string expectedUpdateFragment)
{
var field = DuplicatedField.For<Target>(EnumStorage.AsInteger, x => x.UserId);
var field = DuplicatedField.For<Target>(new StoreOptions(), x => x.UserId);
field.PgType = pgType ?? field.PgType;

field.UpdateSqlFragment().ShouldBe(expectedUpdateFragment);
Expand All @@ -109,7 +116,7 @@ public void pg_type_is_used_for_guid(string pgType, string expectedUpdateFragmen
[InlineData("text[]", "tags_array = CAST(ARRAY(SELECT jsonb_array_elements_text(CAST(data ->> 'TagsArray' as jsonb))) as text[])")]
public void pg_type_is_used_for_string_array(string pgType, string expectedUpdateFragment)
{
var field = DuplicatedField.For<Target>(EnumStorage.AsInteger, x => x.TagsArray);
var field = DuplicatedField.For<Target>(new StoreOptions(), x => x.TagsArray);
field.PgType = pgType ?? field.PgType;

field.UpdateSqlFragment().ShouldBe(expectedUpdateFragment);
Expand All @@ -125,7 +132,7 @@ public void pg_type_is_used_for_string_array(string pgType, string expectedUpdat
[InlineData("text[]", "tags_list = CAST(ARRAY(SELECT jsonb_array_elements_text(CAST(data ->> 'TagsList' as jsonb))) as text[])")]
public void pg_type_is_used_for_string_list(string pgType, string expectedUpdateFragment)
{
var field = DuplicatedField.For<ListTarget>(EnumStorage.AsInteger, x => x.TagsList);
var field = DuplicatedField.For<ListTarget>(new StoreOptions(), x => x.TagsList);
field.PgType = pgType ?? field.PgType;

field.UpdateSqlFragment().ShouldBe(expectedUpdateFragment);
Expand All @@ -135,6 +142,32 @@ public void pg_type_is_used_for_string_list(string pgType, string expectedUpdate
field.DbType.ShouldBe(NpgsqlDbType.Array | NpgsqlDbType.Text);
}

[Theory]
[InlineData(null, "date = public.mt_immutable_timestamp(data ->> 'Date')")]
[InlineData("myergen", "date = myergen.mt_immutable_timestamp(data ->> 'Date')")]
public void store_options_schema_name_is_used_for_timestamp(string schemaName, string expectedUpdateFragment)
{
var storeOptions = schemaName != null
? new StoreOptions {DatabaseSchemaName = schemaName}
: new StoreOptions();

var field = DuplicatedField.For<Target>(storeOptions, x => x.Date);
field.UpdateSqlFragment().ShouldBe(expectedUpdateFragment);
}

[Theory]
[InlineData(null, "date_offset = public.mt_immutable_timestamptz(data ->> 'DateOffset')")]
[InlineData("myergen", "date_offset = myergen.mt_immutable_timestamptz(data ->> 'DateOffset')")]
public void store_options_schema_name_is_used_for_timestamptz(string schemaName, string expectedUpdateFragment)
{
var storeOptions = schemaName != null
? new StoreOptions {DatabaseSchemaName = schemaName}
: new StoreOptions();

var field = DuplicatedField.For<Target>(storeOptions, x => x.DateOffset);
field.UpdateSqlFragment().ShouldBe(expectedUpdateFragment);
}

private class ListTarget
{
public List<string> TagsList { get; set; }
Expand Down
4 changes: 2 additions & 2 deletions src/Marten/Schema/DocumentMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ private static string defaultDocumentAliasName(Type documentType)
public DuplicatedField DuplicateField(string memberName, string pgType = null, bool notNull = false)
{
var field = FieldFor(memberName);
var duplicate = new DuplicatedField(_storeOptions.DuplicatedFieldEnumStorage, field.Members, _storeOptions.DuplicatedFieldUseTimestampWithoutTimeZoneForDateTime, notNull);
var duplicate = new DuplicatedField(_storeOptions, field.Members, _storeOptions.DuplicatedFieldUseTimestampWithoutTimeZoneForDateTime, notNull);
if (pgType.IsNotEmpty())
{
duplicate.PgType = pgType;
Expand All @@ -626,7 +626,7 @@ public DuplicatedField DuplicateField(MemberInfo[] members, string pgType = null
{
var memberName = members.Select(x => x.Name).Join("");

var duplicatedField = new DuplicatedField(_storeOptions.DuplicatedFieldEnumStorage, members, _storeOptions.DuplicatedFieldUseTimestampWithoutTimeZoneForDateTime, notNull);
var duplicatedField = new DuplicatedField(_storeOptions, members, _storeOptions.DuplicatedFieldUseTimestampWithoutTimeZoneForDateTime, notNull);
if (pgType.IsNotEmpty())
{
duplicatedField.PgType = pgType;
Expand Down
28 changes: 22 additions & 6 deletions src/Marten/Schema/DuplicatedField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,26 @@ namespace Marten.Schema
public class DuplicatedField: Field, IField
{
private readonly Func<Expression, object> _parseObject = expression => expression.Value();
private readonly StoreOptions _storeOptions;
private readonly bool useTimestampWithoutTimeZoneForDateTime;
private string _columnName;

[Obsolete("Please use constructor with StoreOptions parameter. This one will be removed in v4.0")]
public DuplicatedField(EnumStorage enumStorage, MemberInfo[] memberPath, bool useTimestampWithoutTimeZoneForDateTime = true, bool notNull = false)
: base(enumStorage, memberPath, notNull)
: this(GetStoreOptions(enumStorage), memberPath, useTimestampWithoutTimeZoneForDateTime, notNull)
{
}

public DuplicatedField(StoreOptions storeOptions, MemberInfo[] memberPath, bool useTimestampWithoutTimeZoneForDateTime = true, bool notNull = false)
: base(storeOptions.DuplicatedFieldEnumStorage, memberPath, notNull)
{
ColumnName = MemberName.ToTableAlias();
_storeOptions = storeOptions;
this.useTimestampWithoutTimeZoneForDateTime = useTimestampWithoutTimeZoneForDateTime;

if (MemberType.IsEnum)
{
if (enumStorage == EnumStorage.AsString)
if (storeOptions.DuplicatedFieldEnumStorage == EnumStorage.AsString)
{
DbType = NpgsqlDbType.Varchar;
PgType = "varchar";
Expand Down Expand Up @@ -99,12 +107,12 @@ public string UpdateSqlFragment()
{
if ((DbType & NpgsqlDbType.Array) == NpgsqlDbType.Array && PgType != "jsonb")
{
var jsonField = new JsonLocatorField("data", new StoreOptions(), _enumStorage, Casing.Default, Members, "jsonb");
var jsonField = new JsonLocatorField("data", _storeOptions, _enumStorage, Casing.Default, Members, "jsonb");
return $"{ColumnName} = CAST(ARRAY(SELECT jsonb_array_elements_text({jsonField.SqlLocator})) as {PgType})";
}
else
{
var jsonField = new JsonLocatorField("data", new StoreOptions(), _enumStorage, Casing.Default, Members, PgType);
var jsonField = new JsonLocatorField("data", _storeOptions, _enumStorage, Casing.Default, Members, PgType);
return $"{ColumnName} = {jsonField.SqlLocator}";
}
}
Expand All @@ -126,7 +134,7 @@ public string LocatorFor(string rootTableAlias)

public string SqlLocator { get; set; }

public static DuplicatedField For<T>(EnumStorage enumStorage, Expression<Func<T, object>> expression, bool useTimestampWithoutTimeZoneForDateTime = true, string pgType = null)
public static DuplicatedField For<T>(StoreOptions storeOptions, Expression<Func<T, object>> expression, bool useTimestampWithoutTimeZoneForDateTime = true, string pgType = null)
{
var accessor = ReflectionHelper.GetAccessor(expression);

Expand All @@ -136,7 +144,7 @@ public static DuplicatedField For<T>(EnumStorage enumStorage, Expression<Func<T,
throw new NotSupportedException("Not yet supporting deep properties yet. Soon.");
}

var duplicate = new DuplicatedField(enumStorage, new MemberInfo[] { accessor.InnerProperty }, useTimestampWithoutTimeZoneForDateTime);
var duplicate = new DuplicatedField(storeOptions, new MemberInfo[] { accessor.InnerProperty }, useTimestampWithoutTimeZoneForDateTime);
if (pgType.IsNotEmpty())
{
duplicate.PgType = pgType;
Expand All @@ -149,5 +157,13 @@ public virtual TableColumn ToColumn()
{
return new TableColumn(ColumnName, PgType);
}

[Obsolete("This method will be removed in v4.0 - it's only being kept for backward compatibility.")]
private static StoreOptions GetStoreOptions(EnumStorage enumStorage)
{
var storeOptions = new StoreOptions();
storeOptions.UseDefaultSerialization(enumStorage);
return storeOptions;
}
}
}

0 comments on commit 23835e6

Please sign in to comment.