Skip to content

Commit 3c7ffa8

Browse files
adds example application
1 parent 856a0c3 commit 3c7ffa8

7 files changed

Lines changed: 256 additions & 9 deletions

File tree

Config.SqlStreamStore.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Config.SqlStreamStore", "sr
99
EndProject
1010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Config.SqlStreamStore.Tests", "src\Config.SqlStreamStore.Tests\Config.SqlStreamStore.Tests.csproj", "{E5C986D9-5100-4A8E-8617-12AE0FAE064C}"
1111
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Config.SqlstreamStore.Example", "src\Config.SqlstreamStore.Example\Config.SqlstreamStore.Example.csproj", "{4470477D-A3F1-4653-AB90-0772C720C257}"
13+
EndProject
1214
Global
1315
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1416
Debug|Any CPU = Debug|Any CPU
@@ -46,9 +48,22 @@ Global
4648
{E5C986D9-5100-4A8E-8617-12AE0FAE064C}.Release|x64.Build.0 = Release|Any CPU
4749
{E5C986D9-5100-4A8E-8617-12AE0FAE064C}.Release|x86.ActiveCfg = Release|Any CPU
4850
{E5C986D9-5100-4A8E-8617-12AE0FAE064C}.Release|x86.Build.0 = Release|Any CPU
51+
{4470477D-A3F1-4653-AB90-0772C720C257}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
52+
{4470477D-A3F1-4653-AB90-0772C720C257}.Debug|Any CPU.Build.0 = Debug|Any CPU
53+
{4470477D-A3F1-4653-AB90-0772C720C257}.Debug|x64.ActiveCfg = Debug|Any CPU
54+
{4470477D-A3F1-4653-AB90-0772C720C257}.Debug|x64.Build.0 = Debug|Any CPU
55+
{4470477D-A3F1-4653-AB90-0772C720C257}.Debug|x86.ActiveCfg = Debug|Any CPU
56+
{4470477D-A3F1-4653-AB90-0772C720C257}.Debug|x86.Build.0 = Debug|Any CPU
57+
{4470477D-A3F1-4653-AB90-0772C720C257}.Release|Any CPU.ActiveCfg = Release|Any CPU
58+
{4470477D-A3F1-4653-AB90-0772C720C257}.Release|Any CPU.Build.0 = Release|Any CPU
59+
{4470477D-A3F1-4653-AB90-0772C720C257}.Release|x64.ActiveCfg = Release|Any CPU
60+
{4470477D-A3F1-4653-AB90-0772C720C257}.Release|x64.Build.0 = Release|Any CPU
61+
{4470477D-A3F1-4653-AB90-0772C720C257}.Release|x86.ActiveCfg = Release|Any CPU
62+
{4470477D-A3F1-4653-AB90-0772C720C257}.Release|x86.Build.0 = Release|Any CPU
4963
EndGlobalSection
5064
GlobalSection(NestedProjects) = preSolution
5165
{178F5A5D-9027-44BB-BA32-70ED75996275} = {7317961C-320E-4B68-A79B-39E066908D2D}
5266
{E5C986D9-5100-4A8E-8617-12AE0FAE064C} = {7317961C-320E-4B68-A79B-39E066908D2D}
67+
{4470477D-A3F1-4653-AB90-0772C720C257} = {7317961C-320E-4B68-A79B-39E066908D2D}
5368
EndGlobalSection
5469
EndGlobal

src/Config.SqlStreamStore.Tests/ConfigRepositoryTests.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ namespace Config.SqlStreamStore.Tests
88
{
99

1010
// Optimistic concurrency checks
11-
// Can read settings from sql stream
12-
// Can write settings to a stream
1311
// Can roll back to a version
14-
//
12+
// wait until sql is available
13+
// configure stream name
1514

1615
public class ConfigRepositoryTests
1716
{

src/Config.SqlStreamStore/Config.SqlStreamStore.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,4 @@
1010
<PackageReference Include="sqlstreamstore" Version="1.1.3" />
1111
</ItemGroup>
1212

13-
<ItemGroup>
14-
</ItemGroup>
15-
1613
</Project>

src/Config.SqlStreamStore/StreamStoreConfigurationSource.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,39 @@
44

55
namespace Config.SqlStreamStore
66
{
7+
public static class ConfigurationBuilerExtensions
8+
{
9+
public static IConfigurationBuilder AddStreamStore(this IConfigurationBuilder builder,
10+
BuildStreamStoreFromConfig factory,
11+
bool subscribeToChanges = false)
12+
{
13+
builder.Add(new StreamStoreConfigurationSource(factory)
14+
{
15+
SubscribeToChanges = subscribeToChanges
16+
});
17+
return builder;
18+
}
19+
20+
public static IConfigurationBuilder AddStreamStore(this IConfigurationBuilder builder,
21+
string connectionStringKey,
22+
BuildStreamStoreFromConnectionString factory,
23+
bool subscribeToChanges = false)
24+
{
25+
builder.Add(new StreamStoreConfigurationSource(connectionStringKey, factory)
26+
{
27+
SubscribeToChanges = subscribeToChanges
28+
});
29+
return builder;
30+
}
31+
}
32+
33+
public delegate IStreamStore BuildStreamStoreFromConnectionString(string connectionString);
34+
public delegate IStreamStore BuildStreamStoreFromConfig(IConfigurationRoot configurationRoot);
35+
public delegate IConfigRepository BuildConfigRepository();
36+
737
public class StreamStoreConfigurationSource : IConfigurationSource
838
{
939

10-
public delegate IStreamStore BuildStreamStoreFromConnectionString(string connectionString);
11-
public delegate IStreamStore BuildStreamStoreFromConfig(IConfigurationRoot configurationRoot);
12-
public delegate IConfigRepository BuildConfigRepository();
1340
private readonly BuildStreamStoreFromConfig _buildStreamStoreFromConfig;
1441

1542
public bool SubscribeToChanges { get; set; }
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.1</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="microsoft.extensions.configuration.Ini" Version="2.1.1" />
10+
<PackageReference Include="sqlstreamstore.MsSql" Version="1.1.3" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\Config.SqlStreamStore\Config.SqlStreamStore.csproj" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<None Update="Settings.ini">
19+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
20+
</None>
21+
</ItemGroup>
22+
23+
</Project>
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
using System;
2+
using System.Data;
3+
using System.Data.SqlClient;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Config.SqlStreamStore;
7+
using Microsoft.Extensions.Configuration;
8+
using Microsoft.Extensions.Configuration.Ini;
9+
using Microsoft.Extensions.Logging;
10+
using Microsoft.Extensions.Primitives;
11+
using SqlStreamStore;
12+
13+
namespace Config.SqlstreamStore.Example
14+
{
15+
class Program
16+
{
17+
private static ILogger _logger;
18+
static void Main(string[] args)
19+
{
20+
21+
var cts = new CancellationTokenSource();
22+
23+
// We're first building configuraiton from the ini file
24+
// This contains the connection string
25+
var ini = new ConfigurationBuilder()
26+
.AddIniFile("Settings.ini")
27+
.Build();
28+
29+
// On a background thread, create the database and start initializing
30+
Task.Run(() => CreateDatabase(ini["ConnectionString"], cts.Token), cts.Token);
31+
32+
IStreamStore store = null;
33+
34+
var sssConfig = new ConfigurationBuilder()
35+
.AddStreamStore(
36+
subscribeToChanges: true,
37+
factory: config =>
38+
store = new MsSqlStreamStore(new MsSqlStreamStoreSettings(config["connectionString"]))
39+
)
40+
.AddConfiguration(ini)
41+
.Build();
42+
43+
ChangeToken.OnChange(sssConfig.GetReloadToken, () =>
44+
{
45+
Console.WriteLine("Settings changed:");
46+
PrintSettings(sssConfig);
47+
});
48+
49+
Console.WriteLine("Found settings at startup:");
50+
PrintSettings(sssConfig);
51+
52+
Console.ReadLine();
53+
cts.Cancel();
54+
store.Dispose();
55+
}
56+
57+
private static void PrintSettings(IConfigurationRoot sssConfig)
58+
{
59+
foreach (var setting in sssConfig.GetChildren())
60+
{
61+
Console.WriteLine(setting.Key + "=" + setting.Value);
62+
}
63+
Console.WriteLine();
64+
}
65+
66+
private static async Task CreateDatabase(string connectionString, CancellationToken ct)
67+
{
68+
try
69+
{
70+
await Task.Delay(1000);
71+
Console.WriteLine("Creating database schema");
72+
await Task.Delay(3000);
73+
74+
var mgr = new DatabaseManager(connectionString);
75+
mgr.EnsureDatabaseExists(10, 10);
76+
77+
var msSqlStreamStoreSettings = new MsSqlStreamStoreSettings(connectionString);
78+
79+
var store = new MsSqlStreamStore(msSqlStreamStoreSettings);
80+
if (!(await store.CheckSchema(ct)).IsMatch())
81+
{
82+
await store.CreateSchema(ct);
83+
}
84+
85+
var repo = new ConfigRepository(store);
86+
87+
while (!ct.IsCancellationRequested)
88+
{
89+
await Task.Delay(1000, ct);
90+
await repo.Modify(ct, ("setting1", DateTime.Now.ToLongTimeString()));
91+
}
92+
}
93+
94+
catch (Exception ex)
95+
{
96+
Console.WriteLine("error while creating database: " + ex.Message);
97+
throw;
98+
}
99+
}
100+
}
101+
102+
public class DatabaseManager
103+
{
104+
105+
public DatabaseManager(string connectionString)
106+
{
107+
_connectionStringBuilder = new SqlConnectionStringBuilder(connectionString);
108+
}
109+
110+
private readonly SqlConnectionStringBuilder _connectionStringBuilder;
111+
112+
private string DatabaseName
113+
{
114+
get
115+
{
116+
var databaseName = _connectionStringBuilder.InitialCatalog;
117+
return databaseName;
118+
}
119+
}
120+
public void DropDatabase()
121+
{
122+
123+
}
124+
125+
public void EnsureDatabaseExists(int size, int fileGrowth)
126+
{
127+
var masterConnectionString = GetMasterConnectionString();
128+
129+
using (var connection = new SqlConnection(masterConnectionString.ConnectionString))
130+
{
131+
connection.Open();
132+
133+
bool exists;
134+
var dbExists = $"SELECT count(*) FROM master.dbo.sysdatabases where name ='{DatabaseName}'";
135+
using (var command = new SqlCommand(dbExists, connection))
136+
{
137+
exists = (int)command.ExecuteScalar() > 0;
138+
}
139+
140+
if (exists)
141+
{
142+
Console.WriteLine($"Database instance {DatabaseName} already exists.");
143+
}
144+
else
145+
{
146+
string databasePath;
147+
using (var command = new SqlCommand(@"
148+
SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1)
149+
FROM master.sys.master_files
150+
WHERE database_id = 1 AND file_id = 1",
151+
connection))
152+
{
153+
databasePath = command.ExecuteScalar() as string;
154+
}
155+
156+
//_writeOutput($"Database instance {databaseName} does not exist. Creating...");
157+
var sql = $@"CREATE DATABASE [{DatabaseName}]
158+
ON PRIMARY (
159+
NAME = N'{DatabaseName}',
160+
FILENAME = N'{databasePath}{DatabaseName}.mdf',
161+
SIZE = {size}MB,
162+
FILEGROWTH = {fileGrowth}MB
163+
)
164+
LOG ON (
165+
NAME = N'{DatabaseName}_log',
166+
FILENAME = N'{databasePath}{DatabaseName}_log.ldf'
167+
)";
168+
169+
using (var command = new SqlCommand(sql, connection))
170+
{
171+
command.ExecuteNonQuery();
172+
}
173+
}
174+
}
175+
}
176+
177+
private SqlConnectionStringBuilder GetMasterConnectionString()
178+
{
179+
var masterConnectionString = new SqlConnectionStringBuilder(_connectionStringBuilder.ConnectionString);
180+
masterConnectionString.InitialCatalog = "master";
181+
return masterConnectionString;
182+
}
183+
184+
}
185+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ConnectionString = "server=(localdb)\mssqllocaldb;database=config"

0 commit comments

Comments
 (0)