<commit_before>using System.Linq;
using System.Threading.Tasks;
using Baseline;
using Marten;
using Marten.Storage;
using Marten.Testing.Documents;
using Marten.Testing.Harness;
using Npgsql;
using Shouldly;
using Weasel.Core;
using Weasel.Core.Migrations;
using Weasel.Postgresql;
using Weasel.Postgresql.Tables;
using Xunit;

namespace CoreTests
{
    public class adding_custom_schema_objects : OneOffConfigurationsContext
    {
        [Fact]
        public void extension_feature_is_not_active_without_any_extended_objects()
        {
            theStore.Options.Storage.AllActiveFeatures(theStore.Storage.Database)
                .OfType<StorageFeatures>().Any().ShouldBeFalse();
        }

        [Fact]
        public void extension_feature_is_active_with_custom_extended_objects()
        {
            var table = new Table("names");
            table.AddColumn<string>("name").AsPrimaryKey();
            theStore.Options.Storage.ExtendedSchemaObjects.Add(table);

            var feature = theStore.Options.Storage.AllActiveFeatures(theStore.Storage.Database)
                .OfType<StorageFeatures>().Single().As<IFeatureSchema>();

            feature.Objects.Single().ShouldBeTheSameAs(table);
        }

        [Fact]
        public async Task build_a_table()
        {
            // The schema is dropped when this method is called, so existing
            // tables would be dropped first
            StoreOptions(opts =>
            {
                opts.RegisterDocumentType<Target>();

                var table = new Table("adding_custom_schema_objects.names");
                table.AddColumn<string>("name").AsPrimaryKey();

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

            await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();


            using var conn = new NpgsqlConnection(ConnectionSource.ConnectionString);
            await conn.OpenAsync();

            var tableNames = await conn.ExistingTables(schemas: new[] { "adding_custom_schema_objects" });
            tableNames.Any(x => x.Name == "names").ShouldBeTrue();
        }
    }
}<commit_msg>Added some additional unit tests to verify Function/Sequence/Extension on ExtendedSchemaObjects (#2299)<commit_after>using System.Linq;
using System.Threading.Tasks;
using Baseline;
using Marten;
using Marten.Storage;
using Marten.Testing.Documents;
using Marten.Testing.Harness;
using Npgsql;
using Shouldly;
using Weasel.Core;
using Weasel.Core.Migrations;
using Weasel.Postgresql;
using Weasel.Postgresql.Functions;
using Weasel.Postgresql.Tables;
using Xunit;

namespace CoreTests
{
    public class adding_custom_schema_objects : OneOffConfigurationsContext
    {
        [Fact]
        public void extension_feature_is_not_active_without_any_extended_objects()
        {
            theStore.Options.Storage.AllActiveFeatures(theStore.Storage.Database)
                .OfType<StorageFeatures>().Any().ShouldBeFalse();
        }

        [Fact]
        public void extension_feature_is_active_with_custom_extended_objects()
        {
            var table = new Table("names");
            table.AddColumn<string>("name").AsPrimaryKey();
            theStore.Options.Storage.ExtendedSchemaObjects.Add(table);

            var feature = theStore.Options.Storage.AllActiveFeatures(theStore.Storage.Database)
                .OfType<StorageFeatures>().Single().As<IFeatureSchema>();

            feature.Objects.Single().ShouldBeTheSameAs(table);
        }

        [Fact]
        public async Task build_a_table()
        {
            // The schema is dropped when this method is called, so existing
            // tables would be dropped first
            StoreOptions(opts =>
            {
                opts.RegisterDocumentType<Target>();

                var table = new Table("adding_custom_schema_objects.names");
                table.AddColumn<string>("name").AsPrimaryKey();

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

            await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();


            using var conn = new NpgsqlConnection(ConnectionSource.ConnectionString);
            await conn.OpenAsync();

            var tableNames = await conn.ExistingTables(schemas: new[] { "adding_custom_schema_objects" });
            tableNames.Any(x => x.Name == "names").ShouldBeTrue();
        }

        [Fact]
        public async Task enable_an_extension()
        {
            StoreOptions(opts =>
            {
                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.OpenSession();

            var result = await session.QueryAsync<bool>("select unaccent('Æ') = 'AE';");

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

        [Fact]
        public async Task create_a_function()
        {
            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"), @"
create or replace function iif(
    condition boolean,       -- if condition
    true_result anyelement,  -- then
    false_result anyelement  -- else
) returns anyelement as $f$
  select case when condition then true_result else false_result end
$f$  language sql immutable;
");

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

            await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();

            var session = theStore.OpenSession();

            var match = await session.QueryAsync<string>("select iif(1 = 1, 'value matches'::text, 'no match'::text);");
            var noMatch = await session.QueryAsync<string>("select iif(1 = 2, 'value matches'::text, 'no match'::text);");

            match.First().ShouldBe("value matches");
            noMatch.First().ShouldBe("no match");
        }

        [Fact]
        public async Task create_a_sequence()
        {
            StoreOptions(opts =>
            {
                opts.RegisterDocumentType<Target>();

                // Create a sequence to generate unique ids for documents
                var sequence = new Sequence("banana_seq");

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

            await theStore.Storage.ApplyAllConfiguredChangesToDatabaseAsync();

            var session = theStore.OpenSession();

            var value = await session.QueryAsync<int>("select nextval('banana_seq')");
            var valueAgain = await session.QueryAsync<int>("select nextval('banana_seq')");

            valueAgain.First().ShouldBe(value.First() + 1);
        }
    }
}
{'fraction_non_alphanumeric': 0.09943820224719101, 'fraction_numerical': 0.0012640449438202246, 'mean_word_length': 2.407177033492823, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1878592', 'n_tokens_mistral': 1876, 'n_tokens_neox': 1796, 'n_words': 382}