Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for DefaultDatabaseConnectionString from env. variable, prefixed with "$ENV::" #1

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CK-Sqlite.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CK.Testing.SqliteDBSetup",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeCakeBuilder", "CodeCakeBuilder\CodeCakeBuilder.csproj", "{ACD6DB7B-FF50-41B5-B107-0A3AE23E66A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CK.Sqlite.Setup.Runtime.Tests", "Tests\CK.Sqlite.Setup.Runtime.Tests\CK.Sqlite.Setup.Runtime.Tests.csproj", "{D59E523A-0C4F-4FD6-946B-455B761228B7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -51,12 +53,17 @@ Global
{ACD6DB7B-FF50-41B5-B107-0A3AE23E66A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACD6DB7B-FF50-41B5-B107-0A3AE23E66A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACD6DB7B-FF50-41B5-B107-0A3AE23E66A5}.Release|Any CPU.Build.0 = Release|Any CPU
{D59E523A-0C4F-4FD6-946B-455B761228B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D59E523A-0C4F-4FD6-946B-455B761228B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D59E523A-0C4F-4FD6-946B-455B761228B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D59E523A-0C4F-4FD6-946B-455B761228B7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{87995CBF-EFC2-464E-8BD6-E2977E8FC496} = {E41EE025-81BA-44EC-899A-4B0E1D2190DB}
{D59E523A-0C4F-4FD6-946B-455B761228B7} = {E41EE025-81BA-44EC-899A-4B0E1D2190DB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {40F56495-1F4F-4279-9A6D-6098152768FD}
Expand Down
24 changes: 23 additions & 1 deletion CK.Sqlite.Setup.Runtime/Engine/SqliteSetupAspect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace CK.Sqlite.Setup
{
public class SqliteSetupAspect : IStObjEngineAspect, ISqliteSetupAspect, IDisposable
{
static readonly string EnvironmentConnectionStringPrefix = "$ENV::";

readonly SqliteSetupAspectConfiguration _config;
readonly ISetupableAspectConfiguration _setupConfiguration;
readonly SqliteManagerProvider _databases;
Expand Down Expand Up @@ -48,13 +50,33 @@ public SqliteSetupAspect( SqliteSetupAspectConfiguration config, IActivityMonito
_config = config;
_setupConfiguration = setupConfiguration.Service;
_databases = new SqliteManagerProvider( monitor );
_databases.Add( SqliteDatabase.DefaultDatabaseName, _config.DefaultDatabaseConnectionString );
string defaultDatabaseConnectionString = ParsePrefixedEnvironmentString( _config.DefaultDatabaseConnectionString );
_databases.Add( SqliteDatabase.DefaultDatabaseName, defaultDatabaseConnectionString );
foreach( var db in _config.Databases )
{
_databases.Add( db.LogicalDatabaseName, db.ConnectionString );
}
}

string ParsePrefixedEnvironmentString( string environmentString )
{
string parsedString = environmentString;
if(
// Allow "$ENV::*" but not "$ENV::"
(environmentString.Length > EnvironmentConnectionStringPrefix.Length + 1)
&& environmentString.StartsWith( EnvironmentConnectionStringPrefix )
)
{
string environmentVariableName = environmentString.Substring( EnvironmentConnectionStringPrefix.Length );
parsedString = Environment.GetEnvironmentVariable( environmentVariableName );
if( parsedString == null )
{
throw new InvalidOperationException( $"The environment variable \"{environmentVariableName}\" specified in \"{environmentString}\" was not set." );
}
}
return parsedString;
}

bool IStObjEngineAspect.Configure( IActivityMonitor monitor, IStObjEngineConfigureContext context )
{
_defaultDatabase = _databases.FindManagerByName( SqliteDatabase.DefaultDatabaseName );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ V text not null
";

internal static string MergeTemporaryTableScript = @"
insert or replace into CKCore_tItemVersionStore( FullName, ItemType, ItemVersion ) select F, V, T from TMP_T;";
insert or replace into CKCore_tItemVersionStore( FullName, ItemType, ItemVersion ) select F, T, V from TMP_T;";

internal static string CreateVersionTableScript = @"
create table if not exists CKCore_tItemVersionStore
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\Common\Shared.props" />
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="**\*.sql" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.SQLite" Version="2.1.0" />
<PackageReference Include="NUnit" Version="[2.6.4]" />
<PackageReference Include="NUnit.Runners.Net4" Version="2.6.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\CK.Sqlite.Setup.Model\CK.Sqlite.Setup.Model.csproj" />
<ProjectReference Include="..\..\CK.Sqlite.Setup.Runtime\CK.Sqlite.Setup.Runtime.csproj" />
<ProjectReference Include="..\..\CK.Testing.SqliteDBSetup\CK.Testing.SqliteDBSetup.csproj" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"profiles": {
"NUnit GUI": {
"commandName": "Executable",
"executablePath": "%USERPROFILE%\\.nuget\\packages\\nunit.runners.net4\\2.6.4\\tools\\nunit.exe",
"commandLineArgs": "CK.Sqlite.Setup.Runtime.Tests.dll"
}
}
}
59 changes: 59 additions & 0 deletions Tests/CK.Sqlite.Setup.Runtime.Tests/RuntimeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using CK.Core;
using CK.Setup;
using FluentAssertions;
using NUnit.Framework;
using System;
using System.Collections.Generic;

namespace CK.Sqlite.Setup.Runtime.Tests
{
public class RuntimeTests
{
[Test]
public void sqlite_aspect_should_read_connectionstring_from_env_var()
{
SqliteSetupAspectConfiguration config = new SqliteSetupAspectConfiguration()
{
DefaultDatabaseConnectionString = "$ENV::SqliteSetupAspect:DefaultDatabaseConnectionString",
};
Environment.SetEnvironmentVariable( "SqliteSetupAspect:DefaultDatabaseConnectionString", "Data Source=:memory:" );
ConfigureOnly<ISetupableAspectConfiguration> co = new ConfigureOnly<ISetupableAspectConfiguration>( new TestSetupableAspectConfiguration() );


SqliteSetupAspect aspect = new SqliteSetupAspect( config, new ActivityMonitor(), co );


aspect.SqliteDatabases.FindManagerByName( SqliteDatabase.DefaultDatabaseName ).Should().NotBeNull();
aspect.SqliteDatabases.FindManagerByConnectionString( "Data Source=:memory:" ).Should().NotBeNull();
}

[Test]
public void sqlite_aspect_should_fail_on_unknown_from_env_var()
{
SqliteSetupAspectConfiguration config = new SqliteSetupAspectConfiguration()
{
DefaultDatabaseConnectionString = "$ENV::SqliteSetupAspect:DefaultDatabaseConnectionString",
};
Environment.SetEnvironmentVariable( "SqliteSetupAspect:DefaultDatabaseConnectionString", null );
ConfigureOnly<ISetupableAspectConfiguration> co = new ConfigureOnly<ISetupableAspectConfiguration>( new TestSetupableAspectConfiguration() );


Action act = () =>
{
SqliteSetupAspect aspect = new SqliteSetupAspect( config, new ActivityMonitor(), co );
};


act.Should().Throw<InvalidOperationException>();
}
}

class TestSetupableAspectConfiguration : ISetupableAspectConfiguration
{
public SetupableAspectConfiguration ExternalConfiguration { get; set; }
public SetupAspectConfigurator Configurator { get; set; }
public IList<object> ExternalItems { get; set; }
public Action<IEnumerable<IDependentItem>> DependencySorterHookInput { get; set; }
public Action<IEnumerable<ISortedItem>> DependencySorterHookOutput { get; set; }
}
}