Skip to content

Commit

Permalink
Merge pull request #21 from nblumhardt/nugets
Browse files Browse the repository at this point in the history
C# API
  • Loading branch information
nblumhardt authored Jul 9, 2019
2 parents 905fbca + b17d87e commit d08d221
Show file tree
Hide file tree
Showing 10 changed files with 569 additions and 214 deletions.
11 changes: 9 additions & 2 deletions Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function Publish-Gzips($version)
{
$rids = @("ubuntu.14.04-x64", "ubuntu.16.04-x64", "rhel.7-x64", "osx.10.12-x64")
foreach ($rid in $rids) {
& dotnet publish src/Datalust.Piggy/Datalust.Piggy.csproj -c Release -f netcoreapp2.0 -r $rid /p:VersionPrefix=$version /p:ShowLinkerSizeComparison=true
& dotnet publish src/Datalust.Piggy/Datalust.Piggy.csproj -c Release -f netcoreapp2.0 -r $rid /p:VersionPrefix=$version
if($LASTEXITCODE -ne 0) { exit 4 }

# Make sure the archive contains a reasonable root filename
Expand All @@ -61,7 +61,7 @@ function Publish-Gzips($version)

function Publish-Msi($version)
{
& dotnet publish src/Datalust.Piggy/Datalust.Piggy.csproj -c Release -f netcoreapp2.0 -r win10-x64 /p:VersionPrefix=$version /p:ShowLinkerSizeComparison=true
& dotnet publish src/Datalust.Piggy/Datalust.Piggy.csproj -c Release -f netcoreapp2.0 -r win10-x64 /p:VersionPrefix=$version
if($LASTEXITCODE -ne 0) { exit 7 }

& msbuild ./setup/Datalust.Piggy.Setup/Datalust.Piggy.Setup.wixproj /t:Build /p:Configuration=Release /p:Platform=x64 /p:Version=$version /p:BuildProjectReferences=false
Expand All @@ -70,6 +70,12 @@ function Publish-Msi($version)
mv ./setup/Datalust.Piggy.Setup/bin/Release/piggy.msi ./artifacts/piggy-$version.msi
}

function Publish-Nupkgs($version)
{
& dotnet pack src/Datalust.Piggy/Datalust.Piggy.csproj -c Release -o $PSScriptRoot/artifacts /p:VersionPrefix=$version /p:OutputType=Library
if($LASTEXITCODE -ne 0) { exit 9 }
}

Push-Location $PSScriptRoot

$version = @{ $true = $env:APPVEYOR_BUILD_VERSION; $false = "99.99.99" }[$env:APPVEYOR_BUILD_VERSION -ne $NULL];
Expand All @@ -83,5 +89,6 @@ Execute-Tests
Create-ArtifactDir
Publish-Gzips($version)
Publish-Msi($version)
Publish-Nupkgs($version)

Pop-Location
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,15 @@ Available commands are:
Type `piggy help <command>` for detailed help
```

### C&sharp; API

For development and test automation purposes, the core script runner is also packaged as a C&sharp; API and published to NuGet as _Datalust.Piggy_.

```csharp
// dotnet add package Datalust.Piggy
var connectionString = // Npgsql connection string
using (var connection = DatabaseConnector.Connect(connectionString, createIfMissing: true)
{
UpdateSession.ApplyChangeScripts(connection, "./db", new Dictionary<string, string>());
}
```
9 changes: 8 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
version: 1.0.{build}
skip_tags: true
image: Visual Studio 2017
image: Visual Studio 2019
build_script:
- ps: ./Build.ps1
test: off
artifacts:
- path: artifacts/piggy-*.msi
- path: artifacts/piggy-*.tar.gz
- path: artifacts/Datalust.Piggy.*.nupkg
deploy:
- provider: NuGet
api_key:
secure: Xi+qouQ6+cOJ85PMOQKEGy+MC1EKyYJCoF2YfuE9Rcj6lvNtm08TIZllTJCqId+M
skip_symbols: true
on:
branch: master
- provider: GitHub
auth_token:
secure: Bo3ypKpKFxinjR9ShkNekNvkob2iklHJU+UlYyfHtcFFIAa58SV2TkEd0xWxz633
Expand Down
5 changes: 2 additions & 3 deletions piggy.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.12
# Visual Studio Version 16
VisualStudioVersion = 16.0.29020.237
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FC0A256C-CC1F-4ECE-AF09-707248D10DC1}"
EndProject
Expand All @@ -11,7 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sln", "sln", "{2EA56595-519
appveyor.yml = appveyor.yml
Build.ps1 = Build.ps1
LICENSE = LICENSE
nuget.config = nuget.config
README.md = README.md
EndProjectSection
EndProject
Expand Down
4 changes: 4 additions & 0 deletions piggy.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=cstr/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Datalust/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Postgre/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
610 changes: 447 additions & 163 deletions setup/Datalust.Piggy.Setup/Piggy.wxs

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions src/Datalust.Piggy/Cli/Commands/UpdateCommand.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using Datalust.Piggy.Cli.Features;
using Datalust.Piggy.Database;
using Datalust.Piggy.Update;
using Npgsql;
using Serilog;
Expand Down Expand Up @@ -35,9 +36,10 @@ protected override int Run()

try
{
UpdateSession.ApplyChangeScripts(
_databaseFeature.Host, _databaseFeature.Database, _usernamePasswordFeature.Username, _usernamePasswordFeature.Password,
_createIfMissing, _scriptRootFeature.ScriptRoot, _defineVariablesFeature.Variables);
using (var connection = DatabaseConnector.Connect(_databaseFeature.Host, _databaseFeature.Database, _usernamePasswordFeature.Username, _usernamePasswordFeature.Password, _createIfMissing))
{
UpdateSession.ApplyChangeScripts(connection, _scriptRootFeature.ScriptRoot, _defineVariablesFeature.Variables);
}

return 0;
}
Expand Down
57 changes: 44 additions & 13 deletions src/Datalust.Piggy/Database/DatabaseConnector.cs
Original file line number Diff line number Diff line change
@@ -1,42 +1,73 @@
using System;
using Npgsql;
using Npgsql.Logging;
using Serilog;

namespace Datalust.Piggy.Database
{
static class DatabaseConnector
/// <summary>
/// Assists with making a PostgreSQL database connection.
/// </summary>
public static class DatabaseConnector
{
static DatabaseConnector()
{
NpgsqlLogManager.Provider = new SerilogLoggingProvider();
}

/// <summary>
/// Connect to the specified database.
/// </summary>
/// <param name="host">The PostgreSQL host to connect to.</param>
/// <param name="database">The database to update.</param>
/// <param name="username">The username to authenticate with.</param>
/// <param name="password">The password to authenticate with.</param>
/// <param name="createIfMissing">If <c>true</c>, Piggy will attempt to create the database if it doesn't exist. The
/// database must already exist, otherwise.</param>
/// <returns>An open database connection.</returns>
public static NpgsqlConnection Connect(string host, string database, string username, string password, bool createIfMissing)
{
Log.Information("Connecting to database {Database} on {Host}", database, host);

var cstr = $"Host={host};Username={username};Password={password};Database={database}";
NpgsqlConnection conn = null;
try
{
conn = new NpgsqlConnection(cstr);
conn.Open();

Log.Information("Connected");

return conn;
return Connect($"Host={host};Username={username};Password={password};Database={database}");
}
catch (PostgresException px) when (px.SqlState == "3D000")
{
conn?.Dispose();

if (createIfMissing && TryCreate(host, database, username, password))
return Connect(host, database, username, password, false);

throw;
}
}

/// <summary>
/// Connect to the specified database.
/// </summary>
/// <param name="connectionString">A connection string identifying the database.</param>
/// <returns>An open database connection.</returns>
public static NpgsqlConnection Connect(string connectionString)
{
if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));

var conn = new NpgsqlConnection(connectionString);

Log.Information("Connecting to database {Database} on {Host}", conn.Database, conn.Host);

try
{
conn.Open();
}
catch
{
conn.Dispose();
throw;
}

Log.Information("Connected");

return conn;
}

static bool TryCreate(string host, string database, string username, string password)
{
Log.Information("Database does not exist; attempting to create it");
Expand Down
21 changes: 13 additions & 8 deletions src/Datalust.Piggy/Datalust.Piggy.csproj
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>A friendly PostgreSQL script runner in the spirit of DbUp.</Description>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
<AssemblyName>piggy</AssemblyName>
<ApplicationIcon>..\..\asset\Piggy-Icon-128px.ico</ApplicationIcon>
<RuntimeIdentifiers>win10-x64;ubuntu.14.04-x64;ubuntu.16.04-x64;rhel.7-x64;osx.10.12-x64</RuntimeIdentifiers>
<GenerateAssemblyInformationalVersionAttribute>True</GenerateAssemblyInformationalVersionAttribute>
<Authors>Datalust and Contributors</Authors>
<PackageId>Datalust.Piggy</PackageId>
<PackageTags>postgresql</PackageTags>
<PackageIconUrl>https://raw.githubusercontent.com/datalust/piggy/dev/asset/Piggy-Icon-128px.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/datalust/piggy</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
<TreatSpecificWarningsAsErrors />
</PropertyGroup>

<ItemGroup>
Expand All @@ -28,15 +34,14 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="dapper" Version="1.50.2" />
<PackageReference Include="npgsql" Version="3.2.4.1" />
<PackageReference Include="Serilog" Version="2.5.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.0.1" />
<PackageReference Include="Autofac" Version="4.0.0" />
<PackageReference Include="serilog.sinks.seq" Version="3.3.2" />
<PackageReference Include="dapper" Version="1.60.6" />
<PackageReference Include="npgsql" Version="4.0.7" />
<PackageReference Include="Serilog" Version="2.8.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Autofac" Version="4.9.2" />
<PackageReference Include="serilog.sinks.seq" Version="4.0.0" />
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
<PackageReference Include="System.Threading.ThreadPool" Version="4.3.0" />
<PackageReference Include="ILLink.Tasks" Version="0.1.4-preview-981901" />
</ItemGroup>

</Project>
46 changes: 25 additions & 21 deletions src/Datalust.Piggy/Update/UpdateSession.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using Datalust.Piggy.Database;
using Datalust.Piggy.Filesystem;
using Datalust.Piggy.History;
using Datalust.Piggy.Status;
Expand All @@ -11,32 +10,37 @@

namespace Datalust.Piggy.Update
{
static class UpdateSession
/// <summary>
/// Applies updates to a target database.
/// </summary>
public static class UpdateSession
{
public static void ApplyChangeScripts(string host, string database, string username, string password,
bool createIfMissing, string scriptRoot, IReadOnlyDictionary<string, string> variables)
/// <summary>
/// Apply change scripts from a folder hierarchy.
/// </summary>
/// <param name="connection">The database connection to use.</param>
/// <param name="scriptRoot">A root filesystem folder under which change scripts are stored.</param>
/// <param name="variables">A set of variables to replace within change scripts.</param>
public static void ApplyChangeScripts(NpgsqlConnection connection, string scriptRoot, IReadOnlyDictionary<string, string> variables)
{
using (var connection = DatabaseConnector.Connect(host, database, username, password, createIfMissing))
{
var scripts = DatabaseStatus.GetPendingScripts(connection, scriptRoot);

Log.Information("Found {Count} new script files to apply", scripts.Length);
var scripts = DatabaseStatus.GetPendingScripts(connection, scriptRoot);

if (scripts.Length != 0)
{
Log.Information("Ensuring the change log table exists");
using (var command = new NpgsqlCommand(AppliedChangeScriptLog.ChangesTableCreateScript, connection))
command.ExecuteNonQuery();
}
Log.Information("Found {Count} new script files to apply", scripts.Length);

foreach (var script in scripts)
{
Log.Information("Applying {FullPath} as {ScriptFile}", script.FullPath, script.RelativeName);
ApplyChangeScript(connection, script, variables);
}
if (scripts.Length != 0)
{
Log.Information("Ensuring the change log table exists");
using (var command = new NpgsqlCommand(AppliedChangeScriptLog.ChangesTableCreateScript, connection))
command.ExecuteNonQuery();
}

Log.Information("Done");
foreach (var script in scripts)
{
Log.Information("Applying {FullPath} as {ScriptFile}", script.FullPath, script.RelativeName);
ApplyChangeScript(connection, script, variables);
}

Log.Information("Done");
}

static void ApplyChangeScript(NpgsqlConnection connection, ChangeScriptFile script, IReadOnlyDictionary<string, string> variables)
Expand Down

0 comments on commit d08d221

Please sign in to comment.