Skip to content

Commit

Permalink
Added tests showing options for single server tenancy and code genera…
Browse files Browse the repository at this point in the history
…tion upfront
  • Loading branch information
oskardudycz committed Jul 22, 2023
1 parent fd4b739 commit efddc68
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 11 deletions.
8 changes: 4 additions & 4 deletions docs/schema/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ StoreOptions(opts =>

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

## Function
Expand Down Expand Up @@ -100,7 +100,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#L121-L141' 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#L188-L210' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_customschemafunction' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

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

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L155-L167' 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#L224-L238' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_customschemasequence' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Extension
Expand All @@ -145,5 +145,5 @@ StoreOptions(opts =>

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L72-L85' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_customschemaextension' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/CoreTests/adding_custom_schema_objects.cs#L76-L91' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_customschemaextension' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Marten;
Expand Down Expand Up @@ -60,7 +59,7 @@ public async Task tenant_is_in_database(string tenantId, string databaseName, bo
theTenancy.WithTenants("tenant4", "tenant5")
.InDatabaseNamed("database2");

var databases = await theTenancy.BuildDatabases();
await theTenancy.BuildDatabases();

var database = await theTenancy.FindOrCreateDatabase(databaseName);
theTenancy.IsTenantStoredInCurrentDatabase(database, tenantId).ShouldBe(isContained);
Expand Down
90 changes: 85 additions & 5 deletions src/CoreTests/adding_custom_schema_objects.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using JasperFx.Core;
using JasperFx.Core.Reflection;
using Marten;
using Marten.Exceptions;
using Marten.Storage;
using Marten.Testing.Documents;
using Marten.Testing.Harness;
Expand All @@ -17,7 +18,7 @@

namespace CoreTests;

public class adding_custom_schema_objects : OneOffConfigurationsContext
public class adding_custom_schema_objects: OneOffConfigurationsContext
{
[Fact]
public void extension_feature_is_not_active_without_any_extended_objects()
Expand All @@ -44,7 +45,9 @@ public async Task build_a_table()
{
// The schema is dropped when this method is called, so existing
// tables would be dropped first

#region sample_CustomSchemaTable

StoreOptions(opts =>
{
opts.RegisterDocumentType<Target>();
Expand All @@ -56,6 +59,7 @@ public async Task build_a_table()
});

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();

#endregion


Expand All @@ -70,6 +74,7 @@ public async Task build_a_table()
public async Task enable_an_extension()
{
#region sample_CustomSchemaExtension

StoreOptions(opts =>
{
opts.RegisterDocumentType<Target>();
Expand All @@ -82,6 +87,7 @@ public async Task enable_an_extension()
});

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();

#endregion

var session = theStore.QuerySession();
Expand All @@ -92,8 +98,11 @@ public async Task enable_an_extension()
}

[Fact]
public async Task enable_an_extension_with_multitenancy()
public async Task enable_an_extension_with_multitenancy_no_tenants_upfront_does_not_register_extension()
{
const string tenantId = "unknownTenantSchemaObject";
await DropDatabaseIfExists(tenantId);

StoreOptions(opts =>
{
opts.MultiTenantedWithSingleServer(ConnectionSource.ConnectionString);
Expand All @@ -108,17 +117,76 @@ public async Task enable_an_extension_with_multitenancy()

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();

var session = theStore.QuerySession("tenant");
Func<Task> queryWithNonExistingDB = async () =>
{
await using var session = theStore.QuerySession(tenantId);
await session.QueryAsync<bool>("select unaccent('Æ') = 'AE';");
};
var martenException = await queryWithNonExistingDB.ShouldThrowAsync<MartenCommandException>();
martenException.InnerException.ShouldNotBeNull();
martenException.InnerException.As<PostgresException>().ShouldSatisfyAllConditions(
e => e.SqlState.ShouldBe(PostgresErrorCodes.UndefinedFunction),
e => e.MessageText.ShouldBe("function unaccent(unknown) does not exist")
);
}

[Fact]
public async Task enable_an_extension_with_multitenancy_with_tenants_upfront_through_manual_apply()
{
const string tenantId = "unknownTenantSchemaObjectManual";
await DropDatabaseIfExists(tenantId);

var result = await session.QueryAsync<bool>("select unaccent('Æ') = 'AE';");
StoreOptions(opts =>
{
opts.MultiTenantedWithSingleServer(ConnectionSource.ConnectionString);
opts.RegisterDocumentType<Target>();

// Unaccent is an extension ships with postgresql
// and removes accents (diacritic signs) from strings
var extension = new Extension("unaccent");

opts.Storage.ExtendedSchemaObjects.Add(extension);
});

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

await using var sessionNext = theStore.QuerySession(tenantId);
var result = await sessionNext.QueryAsync<bool>("select unaccent('Æ') = 'AE';");

result.First().ShouldBe(true);
}

[Fact]
public async Task enable_an_extension_with_multitenancy_with_tenants_upfront_through_config()
{
const string tenantId = "knownTenantSchemaObject";
await DropDatabaseIfExists(tenantId);

StoreOptions(opts =>
{
opts.MultiTenantedWithSingleServer(ConnectionSource.ConnectionString).WithTenants(tenantId);
opts.RegisterDocumentType<Target>();

// Unaccent is an extension ships with postgresql
// and removes accents (diacritic signs) from strings
var extension = new Extension("unaccent");

opts.Storage.ExtendedSchemaObjects.Add(extension);
});

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();

var session = theStore.QuerySession(tenantId);
var result = await session.QueryAsync<bool>("select unaccent('Æ') = 'AE';");
result.First().ShouldBe(true);
}

[Fact]
public async Task create_a_function()
{
#region sample_CustomSchemaFunction

StoreOptions(opts =>
{
opts.RegisterDocumentType<Target>();
Expand All @@ -138,6 +206,7 @@ create or replace function iif(
});

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();

#endregion

var session = theStore.QuerySession();
Expand All @@ -153,6 +222,7 @@ create or replace function iif(
public async Task create_a_sequence()
{
#region sample_CustomSchemaSequence

StoreOptions(opts =>
{
opts.RegisterDocumentType<Target>();
Expand All @@ -164,6 +234,7 @@ public async Task create_a_sequence()
});

await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();

#endregion

var session = theStore.QuerySession();
Expand All @@ -173,4 +244,13 @@ public async Task create_a_sequence()

valueAgain.First().ShouldBe(value.First() + 1);
}

private async Task DropDatabaseIfExists(string databaseName)
{
await using var conn = new NpgsqlConnection(ConnectionSource.ConnectionString);
await conn.OpenAsync();

await conn.KillIdleSessions(databaseName);
await conn.DropDatabase(databaseName);
}
}

0 comments on commit efddc68

Please sign in to comment.