Skip to content

Commit

Permalink
Added UseCaseSensitiveQualifiedNamesWhenApplyingChanges to advanced s…
Browse files Browse the repository at this point in the history
…tore options to enable case sensitive names handling

Bumped Weasel to 6.2.0
  • Loading branch information
oskardudycz committed Nov 3, 2023
1 parent 2242824 commit ee4df42
Show file tree
Hide file tree
Showing 46 changed files with 242 additions and 190 deletions.
2 changes: 1 addition & 1 deletion Analysis.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ExcludeAssets>none</ExcludeAssets>
<IncludeAssets>all</IncludeAssets>
</PackageReference>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.93">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.103">
<PrivateAssets>all</PrivateAssets>
<ExcludeAssets>none</ExcludeAssets>
<IncludeAssets>all</IncludeAssets>
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration/multitenancy.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ If you don't know the tenant upfront, you can create and apply changes dynamical
var tenant = await theStore.Tenancy.GetTenantAsync(tenantId);
await tenant.Database.ApplyAllConfiguredChangesToDatabaseAsync();
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L151-L154' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_manual_single_tenancy_apply_changes' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L151-L156' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_manual_single_tenancy_apply_changes' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

You can place this code somewhere in the tenant initialization code. For instance:
Expand Down
32 changes: 14 additions & 18 deletions docs/scenarios/using-sequence-for-unique-id.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class MatterId: FeatureSchemaBase
private readonly int _startFrom;
private readonly string _schema;

public MatterId(StoreOptions options, int startFrom) : base(nameof(MatterId), options.Advanced.Migrator)
public MatterId(StoreOptions options, int startFrom): base(nameof(MatterId), options.Advanced.Migrator)
{
_startFrom = startFrom;
_schema = options.DatabaseSchemaName;
Expand All @@ -26,11 +26,12 @@ public class MatterId: FeatureSchemaBase
protected override IEnumerable<ISchemaObject> schemaObjects()
{
// We return a sequence that starts from the value provided in the ctor
yield return new Sequence(new DbObjectName(_schema, $"mt_{nameof(MatterId).ToLowerInvariant()}"), _startFrom);
yield return new Sequence(new PostgresqlObjectName(_schema, $"mt_{nameof(MatterId).ToLowerInvariant()}"),
_startFrom);
}
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L17-L36' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-setup' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L15-L37' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-setup' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

This sequence yielding customization will be plugged into Marten via the store configuration
Expand All @@ -40,7 +41,7 @@ This sequence yielding customization will be plugged into Marten via the store c
```cs
storeOptions.Storage.Add(new MatterId(storeOptions, 10000));
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L43-L45' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-storesetup-1' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L44-L48' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-storesetup-1' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

and then executed against the database (generating & executing the DDL statements that create the required database objects):
Expand All @@ -50,7 +51,7 @@ and then executed against the database (generating & executing the DDL statement
```cs
await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L48-L50' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-storesetup-2' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L51-L55' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-storesetup-2' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

We introduce a few types with `Guid` identifiers, whom we reference to our end users by numbers, encapsulated in the `Matter` field:
Expand All @@ -61,17 +62,20 @@ We introduce a few types with `Guid` identifiers, whom we reference to our end u
public class Contract
{
public Guid Id { get; set; }

public int Matter { get; set; }
// Other fields...
}

public class Inquiry
{
public Guid Id { get; set; }

public int Matter { get; set; }
// Other fields...
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L79-L92' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-setup-types' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L77-L95' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-setup-types' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Now, when creating and persisting such types, we first query the database for a new and unique running number. While we generate (or if wanted, let Marten generate) non-human-readable, system-internal identifiers for the created instances, we assign to them the newly generated and unique human-readable identifier:
Expand All @@ -85,24 +89,16 @@ await using var session = theStore.LightweightSession();
// Generate a new, unique identifier
var nextMatter = session.NextInSequence(matter);

var contract = new Contract
{
Id = Guid.NewGuid(),
Matter = nextMatter
};
var contract = new Contract { Id = Guid.NewGuid(), Matter = nextMatter };

var inquiry = new Inquiry
{
Id = Guid.NewGuid(),
Matter = nextMatter
};
var inquiry = new Inquiry { Id = Guid.NewGuid(), Matter = nextMatter };

session.Store(contract);
session.Store(inquiry);

await session.SaveChangesAsync();
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L52-L76' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-querymatter' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L57-L74' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-querymatter' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Lastly, we have an extension method (used above) as a shorthand for generating the SQL statement for a sequence value query:
Expand All @@ -119,5 +115,5 @@ public static class SessionExtensions
}
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L95-L104' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-setup-extensions' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/Examples/ScenarioUsingSequenceForUniqueId.cs#L98-L109' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_scenario-usingsequenceforuniqueid-setup-extensions' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->
16 changes: 8 additions & 8 deletions docs/schema/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@ Not to worry though, Marten comes with a base class that makes it a bit simpler
<!-- snippet: sample_creating-a-fake-schema-feature -->
<a id='snippet-sample_creating-a-fake-schema-feature'></a>
```cs
public class FakeStorage : FeatureSchemaBase
public class FakeStorage: FeatureSchemaBase
{
private readonly StoreOptions _options;

public FakeStorage(StoreOptions options) : base("fake", options.Advanced.Migrator)
public FakeStorage(StoreOptions options): base("fake", options.Advanced.Migrator)
{
_options = options;
}

protected override IEnumerable<ISchemaObject> schemaObjects()
{
var table = new Table(new DbObjectName(_options.DatabaseSchemaName, "mt_fake_table"));
var table = new Table(new PostgresqlObjectName(_options.DatabaseSchemaName, "mt_fake_table"));
table.AddColumn("name", "varchar");

yield return table;
}
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/DocumentDbTests/Configuration/ability_to_add_custom_storage_features.cs#L48-L67' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_creating-a-fake-schema-feature' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/DocumentDbTests/Configuration/ability_to_add_custom_storage_features.cs#L49-L69' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_creating-a-fake-schema-feature' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Now, to actually apply this feature to your Marten applications, use this syntax:
Expand All @@ -44,7 +44,7 @@ var store = DocumentStore.For(_ =>
_.Storage.Add(new FakeStorage(_));
});
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/DocumentDbTests/Configuration/ability_to_add_custom_storage_features.cs#L33-L44' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_adding-schema-feature' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/DocumentDbTests/Configuration/ability_to_add_custom_storage_features.cs#L32-L45' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_adding-schema-feature' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Do note that when you use the `Add<T>()` syntax, Marten will pass along the current `StoreOptions` to the constructor function if there is a constructor with that signature. Otherwise, it uses the no-arg constructor.
Expand Down Expand Up @@ -94,7 +94,7 @@ StoreOptions(opts =>
opts.RegisterDocumentType<Target>();

// Create a user defined function to act as a ternary operator similar to SQL Server
var function = new Function(new DbObjectName("public", "iif"), @"
var function = new Function(new PostgresqlObjectName("public", "iif"), @"
create or replace function iif(
condition boolean, -- if condition
true_result anyelement, -- then
Expand All @@ -109,7 +109,7 @@ $f$ language sql immutable;

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L190-L212' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_customschemafunction' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L192-L214' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_customschemafunction' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Sequence
Expand All @@ -131,7 +131,7 @@ StoreOptions(opts =>

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L226-L240' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_customschemasequence' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L228-L242' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_customschemasequence' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Extension
Expand Down
2 changes: 1 addition & 1 deletion src/CoreTests/CoreTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.5.3"/>
<PackageReference Include="xunit" Version="2.6.1"/>
<PackageReference Include="NSubstitute" Version="5.1.0"/>
<PackageReference Include="Shouldly" Version="4.2.1"/>
</ItemGroup>
Expand Down
4 changes: 3 additions & 1 deletion src/CoreTests/adding_custom_schema_objects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,10 @@ public async Task enable_an_extension_with_multitenancy_with_tenants_upfront_thr
});

#region sample_manual_single_tenancy_apply_changes

var tenant = await theStore.Tenancy.GetTenantAsync(tenantId);
await tenant.Database.ApplyAllConfiguredChangesToDatabaseAsync();

#endregion

await using var sessionNext = theStore.QuerySession(tenantId);
Expand Down Expand Up @@ -194,7 +196,7 @@ public async Task create_a_function()
opts.RegisterDocumentType<Target>();

// Create a user defined function to act as a ternary operator similar to SQL Server
var function = new Function(new DbObjectName("public", "iif"), @"
var function = new Function(new PostgresqlObjectName("public", "iif"), @"
create or replace function iif(
condition boolean, -- if condition
true_result anyelement, -- then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
using Marten.Testing.Harness;
using Weasel.Core;
using Weasel.Core.Migrations;
using Weasel.Postgresql;
using Weasel.Postgresql.Tables;
using Xunit;

namespace DocumentDbTests.Bugs;

public class Bug_2523_using_query_on_custom_storage_table : BugIntegrationContext
public class Bug_2523_using_query_on_custom_storage_table: BugIntegrationContext
{
[Fact]
public async Task WhenCustomTableIsUsedInABatchWithOtherDocumentResetAllShouldWork()
Expand All @@ -27,25 +28,26 @@ public async Task WhenCustomTableIsUsedInABatchWithOtherDocumentResetAllShouldWo

await using var session = store.LightweightSession();
session.QueueSqlCommand(CustomTableStorage.InsertSql, Guid.NewGuid().ToString());
session.Insert(new User{FirstName = "John", LastName = "Doe"});
session.Insert(new User { FirstName = "John", LastName = "Doe" });
await session.SaveChangesAsync();

await store.Advanced.ResetAllData();
}
}

public class CustomTableStorage : FeatureSchemaBase
public class CustomTableStorage: FeatureSchemaBase
{
private const string TableName = "mt_custom_table";
public const string InsertSql = $"insert into bugs.{TableName}(id) values(?)";

private readonly StoreOptions _options;

public CustomTableStorage(StoreOptions options) : base("custom_table", options.Advanced.Migrator) => _options = options;
public CustomTableStorage(StoreOptions options): base("custom_table", options.Advanced.Migrator) =>
_options = options;

protected override IEnumerable<ISchemaObject> schemaObjects()
{
var table = new Table(new DbObjectName("bugs", TableName));
var table = new Table(new PostgresqlObjectName("bugs", TableName));
table.AddColumn<string>("id").AsPrimaryKey();
yield return table;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,29 +98,29 @@ internal class spaceAfterTableNameSchema: testSchema
{
protected override IEnumerable<ISchemaObject> SchemaObjects()
{
var table = new Table(new DbObjectName(SchemaConstants.DefaultSchema,"test_space_after"));
var table = new Table(new PostgresqlObjectName(SchemaConstants.DefaultSchema, "test_space_after"));
table.AddColumn("space_after ", "int");
return new List<ISchemaObject> {table};
return new List<ISchemaObject> { table };
}
}

internal class spaceBeforeTableNameSchema: testSchema
{
protected override IEnumerable<ISchemaObject> SchemaObjects()
{
var table = new Table(new DbObjectName(SchemaConstants.DefaultSchema,"test_space_before"));
var table = new Table(new PostgresqlObjectName(SchemaConstants.DefaultSchema, "test_space_before"));
table.AddColumn(" space_before", "int");
return new List<ISchemaObject> {table};
return new List<ISchemaObject> { table };
}
}

internal class spaceInNameSchema: testSchema
{
protected override IEnumerable<ISchemaObject> SchemaObjects()
{
var table = new Table(new DbObjectName(SchemaConstants.DefaultSchema,"test_space_in"));
var table = new Table(new PostgresqlObjectName(SchemaConstants.DefaultSchema, "test_space_in"));
table.AddColumn("space inname", "int");
return new List<ISchemaObject> {table};
return new List<ISchemaObject> { table };
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ public class Bug_1338_Validate_Null_ForeignKeyDefinition_ReferenceDocumenType: B
[Fact]
public void StorageFeatures_AllActiveFeatures_Should_Not_Throw_With_ExternalForeignKeyDefinitions()
{
theStore.StorageFeatures.AllActiveFeatures(theStore.Tenancy.Default.Database).All(x => x != null).ShouldBeTrue();
theStore.StorageFeatures.AllActiveFeatures(theStore.Tenancy.Default.Database).All(x => x != null)
.ShouldBeTrue();
}

public async Task InitializeAsync()
{
var table = new Table(new DbObjectName(SchemaName, "external_table"));
var table = new Table(new PostgresqlObjectName(SchemaName, "external_table"));
table.AddColumn("id", "integer").AsPrimaryKey();

await using var dbConn = new NpgsqlConnection(ConnectionSource.ConnectionString);
Expand All @@ -40,7 +41,6 @@ public async Task InitializeAsync()
}, false);

await theStore.Advanced.Clean.DeleteDocumentsByTypeAsync(typeof(ClassWithExternalForeignKey));

}

public Task DisposeAsync()
Expand All @@ -60,10 +60,9 @@ public async Task UnitOfWork_GetTypeDependencies_Should_Not_Throw_With_ExternalF
// and finally, the function that we want to regression test"
// UnitOfWork.GetTypeDependencies(ClassWithExternalForeignKey)
await using var session = theStore.LightweightSession();
session.Insert(new ClassWithExternalForeignKey {Id = 1, ForeignId = 1});
session.Insert(new ClassWithExternalForeignKey { Id = 1, ForeignId = 1 });
await session.SaveChangesAsync();
}

}

public class ClassWithExternalForeignKey
Expand Down
Loading

0 comments on commit ee4df42

Please sign in to comment.