Skip to content
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
17 changes: 17 additions & 0 deletions ClickView.GoodStuff.sln
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{63D140
.github\workflows\release.yaml = .github\workflows\release.yaml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Snowflake", "Snowflake", "{4B8ED14E-7CFF-4123-B54D-3BEBAB817262}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClickView.GoodStuff.Repositories.Snowflake", "src\Repositories\Snowflake\src\ClickView.GoodStuff.Repositories.Snowflake.csproj", "{E55CD02D-A938-4FD0-8BB2-D77943976DD0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClickView.GoodStuff.Repositories.Snowflake.Tests", "src\Repositories\Snowflake\test\ClickView.GoodStuff.Repositories.Snowflake.Tests.csproj", "{609D602D-1DBA-4A16-B17A-1AB4CF8E8E94}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -156,6 +162,14 @@ Global
{292AD84D-B42C-4DB6-882A-509860B4754F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{292AD84D-B42C-4DB6-882A-509860B4754F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{292AD84D-B42C-4DB6-882A-509860B4754F}.Release|Any CPU.Build.0 = Release|Any CPU
{E55CD02D-A938-4FD0-8BB2-D77943976DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E55CD02D-A938-4FD0-8BB2-D77943976DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E55CD02D-A938-4FD0-8BB2-D77943976DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E55CD02D-A938-4FD0-8BB2-D77943976DD0}.Release|Any CPU.Build.0 = Release|Any CPU
{609D602D-1DBA-4A16-B17A-1AB4CF8E8E94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{609D602D-1DBA-4A16-B17A-1AB4CF8E8E94}.Debug|Any CPU.Build.0 = Debug|Any CPU
{609D602D-1DBA-4A16-B17A-1AB4CF8E8E94}.Release|Any CPU.ActiveCfg = Release|Any CPU
{609D602D-1DBA-4A16-B17A-1AB4CF8E8E94}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -188,6 +202,9 @@ Global
{FED685BF-255A-4ED1-80ED-B7596ABC337B} = {0578918C-A83D-4FB0-BFD8-50639DB46AF0}
{292AD84D-B42C-4DB6-882A-509860B4754F} = {046FE4C7-4E48-4CD5-BF39-3AF8110DA1C9}
{63D140DE-F2A6-4644-9A1A-ABA3F2314C0A} = {A9533DB9-A1E9-4376-806E-926176FD9B13}
{4B8ED14E-7CFF-4123-B54D-3BEBAB817262} = {17A5F05F-B3EB-4011-A58C-BB1BB7995692}
{E55CD02D-A938-4FD0-8BB2-D77943976DD0} = {4B8ED14E-7CFF-4123-B54D-3BEBAB817262}
{609D602D-1DBA-4A16-B17A-1AB4CF8E8E94} = {4B8ED14E-7CFF-4123-B54D-3BEBAB817262}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F935033F-FAFD-48D4-843C-C7C8A9AE6562}
Expand Down
123 changes: 123 additions & 0 deletions src/Repositories/Snowflake/src/BaseSnowflakeRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
namespace ClickView.GoodStuff.Repositories.Snowflake
{
using System.Collections.Generic;
using System.Threading.Tasks;
using Abstractions;
using Dapper;
using global::Snowflake.Data.Client;

public class BaseSnowflakeRepository : BaseRepository<SnowflakeDbConnection>
{
public BaseSnowflakeRepository(ISnowflakeConnectionFactory connectionFactory) : base(
connectionFactory)
{
}

/// <summary>
/// Executes a write command
/// </summary>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <returns></returns>
protected async Task<int> ExecuteAsync(string sql, object? param = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you add cancellation token on these too?

{
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
await using var conn = GetWriteConnection();
#else
using var conn = GetWriteConnection();
#endif

return await conn.ExecuteAsync(sql, param);
}

/// <summary>
/// Executes a write command which selects a single value
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <returns></returns>
protected async Task<T> ExecuteScalarAsync<T>(string sql, object? param = null)
{
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
await using var conn = GetWriteConnection();
#else
using var conn = GetWriteConnection();
#endif

return await conn.ExecuteScalarAsync<T>(sql, param);
}

/// <summary>
/// Executes a single value query
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <returns></returns>
protected async Task<T> QueryScalarValueAsync<T>(string sql, object? param = null)
{
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
await using var conn = GetReadConnection();
#else
using var conn = GetReadConnection();
#endif

return await conn.ExecuteScalarAsync<T>(sql, param);
}

/// <summary>
/// Executes a single row query
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <returns></returns>
protected async Task<T> QueryFirstOrDefaultAsync<T>(string sql, object? param = null)
{
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
await using var conn = GetReadConnection();
#else
using var conn = GetReadConnection();
#endif

return await conn.QueryFirstOrDefaultAsync<T>(sql, param);
}

/// <summary>
/// Executes a single row query and throws an exception if more than one record is found
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <returns></returns>
protected async Task<T> QuerySingleOrDefaultAsync<T>(string sql, object? param = null)
{
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
await using var conn = GetReadConnection();
#else
using var conn = GetReadConnection();
#endif

return await conn.QuerySingleOrDefaultAsync<T>(sql, param);
}

/// <summary>
/// Executes a multiple row query
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <returns></returns>
protected async Task<IEnumerable<T>> QueryAsync<T>(string sql, object? param = null)
{
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
await using var conn = GetReadConnection();
#else
using var conn = GetReadConnection();
#endif

return await conn.QueryAsync<T>(sql, param);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
<IsPackable>true</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you update Dapper? #95

<PackageReference Include="Snowflake.Data" Version="2.0.23" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Abstractions\src\ClickView.GoodStuff.Repositories.Abstractions.csproj" />
</ItemGroup>

</Project>
9 changes: 9 additions & 0 deletions src/Repositories/Snowflake/src/ISnowflakeConnectionFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace ClickView.GoodStuff.Repositories.Snowflake
{
using Abstractions.Factories;
using global::Snowflake.Data.Client;

public interface ISnowflakeConnectionFactory : IConnectionFactory<SnowflakeDbConnection>
{
}
}
44 changes: 44 additions & 0 deletions src/Repositories/Snowflake/src/SnowflakeConnectionFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
namespace ClickView.GoodStuff.Repositories.Snowflake
{
using System;
using Abstractions.Factories;
using global::Snowflake.Data.Client;

public class SnowflakeConnectionFactory : SnowflakeConnectionFactory<SnowflakeConnectionOptions>
{
public SnowflakeConnectionFactory(ConnectionFactoryOptions<SnowflakeConnectionOptions> options) : base(options)
{
}
}

public class SnowflakeConnectionFactory<TOptions>
: ConnectionFactory<SnowflakeDbConnection, TOptions>, ISnowflakeConnectionFactory
where TOptions : SnowflakeConnectionOptions
{
public SnowflakeConnectionFactory(ConnectionFactoryOptions<TOptions> options) : base(options)
{
}

public override SnowflakeDbConnection GetReadConnection()
{
if (string.IsNullOrEmpty(ReadConnectionString))
throw new InvalidOperationException("Read is not allowed. No read connection options defined");

var connection = new SnowflakeDbConnection { ConnectionString = ReadConnectionString };
connection.Open();

return connection;
}

public override SnowflakeDbConnection GetWriteConnection()
{
if (string.IsNullOrEmpty(WriteConnectionString))
throw new InvalidOperationException("Write is not allowed. No write connection options defined");

var connection = new SnowflakeDbConnection { ConnectionString = WriteConnectionString };
connection.Open();

return connection;
}
}
}
62 changes: 62 additions & 0 deletions src/Repositories/Snowflake/src/SnowflakeConnectionOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace ClickView.GoodStuff.Repositories.Snowflake
{
using Abstractions;

public class SnowflakeConnectionOptions : RepositoryConnectionOptions
{
/// <summary>
/// The full account name which might include additional segments that identify the region and
/// cloud platform where your account is hosted
/// </summary>
public string? Account
{
set => SetParameter("account", value);
get => GetParameter("account");
}

/// <summary>
/// The name of the warehouse to use
/// </summary>
public string? Warehouse
{
set => SetParameter("warehouse", value);
get => GetParameter("warehouse");
}

/// <summary>
/// The database to use
/// </summary>
public string? Database
{
set => SetParameter("db", value);
get => GetParameter("db");
}

/// <summary>
/// The schema to use
/// </summary>
public string? Schema
{
set => SetParameter("schema", value);
get => GetParameter("schema");
}

/// <summary>
/// The Snowflake user to use
/// </summary>
public string? User
{
set => SetParameter("user", value);
get => GetParameter("user");
}

/// <summary>
/// The password for the Snowflake user
/// </summary>
public string? Password
{
set => SetParameter("password", value);
get => GetParameter("password");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\ClickView.GoodStuff.Repositories.Snowflake.csproj" />
</ItemGroup>

</Project>
Loading