Skip to content
Merged
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
131 changes: 131 additions & 0 deletions .github/workflows/preview-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
name: Preview Release

on:
release:
types: [published]

permissions:
contents: write
id-token: write

jobs:
publish-preview:
if: github.event.release.prerelease == true && startsWith(github.event.release.tag_name, 'v1.5.4-preview.')
runs-on: ubuntu-latest
environment: nuget-preview

steps:
- name: Checkout release tag
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event.release.tag_name }}

- name: Set preview version
shell: bash
run: |
version="${{ github.event.release.tag_name }}"
version="${version#v}"
if [[ ! "$version" =~ ^1\.5\.4-preview\.[0-9]+$ ]]; then
echo "Unexpected preview version: $version" >&2
exit 1
fi
echo "PREVIEW_VERSION=$version" >> "$GITHUB_ENV"

- name: Setup .NET SDK
uses: actions/setup-dotnet@v5
with:
global-json-file: global.json

- name: Restore
run: dotnet restore DuckDB.NET.slnx /p:CI=false

- name: Build
run: >-
dotnet build DuckDB.NET.slnx
--configuration Release
--no-restore
/m:1
/p:BuildType=Full
/p:CI=false
/p:ForkPreview=true
/p:Version=${{ env.PREVIEW_VERSION }}
/p:PackageVersion=${{ env.PREVIEW_VERSION }}
/p:UseSharedCompilation=false

- name: Test
run: >-
dotnet test DuckDB.NET.Test/Test.csproj
--configuration Release
--no-build
--no-restore
--logger "console;verbosity=quiet"
/p:BuildType=Full
/p:CI=false
/p:ForkPreview=true
/p:DoesNotReturnAttribute=DoesNotReturnAttribute

- name: Pack preview packages
shell: bash
run: |
mkdir -p artifacts/preview
common_args=(
--configuration Release
--no-build
--no-restore
--output artifacts/preview
/m:1
/p:BuildType=Full
/p:CI=false
/p:ForkPreview=true
/p:PreviewPack=true
/p:Version="$PREVIEW_VERSION"
/p:PackageVersion="$PREVIEW_VERSION"
)
dotnet pack DuckDB.NET.Bindings/Bindings.csproj "${common_args[@]}"

dotnet restore DuckDB.NET.Data/Data.csproj \
--source artifacts/preview \
--source https://api.nuget.org/v3/index.json \
/p:BuildType=Full \
/p:CI=false \
/p:ForkPreview=true \
/p:PreviewPack=true \
/p:Version="$PREVIEW_VERSION" \
/p:PackageVersion="$PREVIEW_VERSION"

dotnet pack DuckDB.NET.Data/Data.csproj "${common_args[@]}"

- name: Validate and smoke-test packages
run: ./scripts/validate-preview-packages.sh artifacts/preview "$PREVIEW_VERSION"

- name: Generate checksums
working-directory: artifacts/preview
run: sha256sum *.nupkg > SHA256SUMS

- name: Upload workflow artifacts
uses: actions/upload-artifact@v7
with:
name: duckdb-net-${{ env.PREVIEW_VERSION }}
path: |
artifacts/preview/*.nupkg
artifacts/preview/SHA256SUMS
if-no-files-found: error

- name: Attach packages to GitHub prerelease
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload "${{ github.event.release.tag_name }}" artifacts/preview/* --clobber

- name: Authenticate to NuGet.org
uses: NuGet/login@v1
id: nuget-login
with:
user: skuirrels

- name: Publish preview packages to NuGet.org
run: >-
dotnet nuget push "artifacts/preview/*.nupkg"
--api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}"
--source https://api.nuget.org/v3/index.json
--skip-duplicate
20 changes: 19 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
<Company>Giorgi Dalakishvili</Company>
<Copyright>Copyright © 2020 - $(Year) Giorgi Dalakishvili</Copyright>

<ForkPackagePrefix Condition="'$(ForkPreview)' == 'true' AND '$(ForkPackagePrefix)' == ''">Skuirrels.</ForkPackagePrefix>
<Product>DuckDB.NET.$(MSBuildProjectName)</Product>
<PackageId>DuckDB.NET.$(MSBuildProjectName)</PackageId>
<PackageId>$(ForkPackagePrefix)DuckDB.NET.$(MSBuildProjectName)</PackageId>
<PackageTags>DuckDB;ADO.NET;Database;Olap;Embedded</PackageTags>
<PackageIcon>Logo.jpg</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageReadmeFile Condition="'$(ForkPreview)' == 'true'">README-PREVIEW.md</PackageReadmeFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>

<Deterministic>true</Deterministic>
Expand All @@ -38,6 +40,11 @@

</PropertyGroup>

<PropertyGroup Condition="'$(ForkPreview)' == 'true'">
<RepositoryUrl>https://github.com/skuirrels/DuckDB.NET</RepositoryUrl>
<PackageProjectUrl>https://github.com/skuirrels/DuckDB.NET</PackageProjectUrl>
</PropertyGroup>

<PropertyGroup>
<BuildType>ManagedOnly</BuildType>
<NoNativeText>This package does not include a copy of the native DuckDB library.</NoNativeText>
Expand All @@ -63,8 +70,19 @@
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
<None Include="..\README-PREVIEW.md" Condition="'$(ForkPreview)' == 'true'">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>

<Target Name="ValidateForkPreviewPackageMetadata" BeforeTargets="Pack" Condition="'$(ForkPreview)' == 'true'">
<Error Condition="$([System.String]::Copy('$(PackageId)').StartsWith('Skuirrels.')) != 'True'"
Text="Fork preview packages must use the Skuirrels package prefix." />
<Error Condition="$([System.String]::Copy('$(PackageVersion)').Contains('-preview.')) != 'True'"
Text="Fork preview package versions must contain the -preview. prerelease suffix." />
</Target>

<PropertyGroup Label="CI" Condition="'$(CI)' == ''">
<CI>false</CI>
<!-- GH, CircleCI, GitLab and BitBucket already use CI -->
Expand Down
67 changes: 67 additions & 0 deletions DuckDB.NET.Benchmarks/AppenderBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using BenchmarkDotNet.Attributes;
using DuckDB.NET.Data;

namespace DuckDB.NET.Benchmarks;

[MemoryDiagnoser]
public class AppenderBenchmark
{
private DuckDBConnection connection = null!;

[Params(1_000_000)]
public int RowCount { get; set; }

[GlobalSetup]
public void Setup()
{
connection = new DuckDBConnection("DataSource=:memory:");
connection.Open();
}

[GlobalCleanup]
public void Cleanup()
{
connection.Dispose();
}

[IterationSetup]
public void IterationSetup()
{
using var command = connection.CreateCommand();
command.CommandText = "DROP TABLE IF EXISTS bench; CREATE TABLE bench (a INTEGER, b BIGINT, c DOUBLE, d BOOLEAN);";
command.ExecuteNonQuery();
}

[Benchmark(Baseline = true)]
public void AppendRowsWithCreateRow()
{
using var appender = connection.CreateAppender("bench");

for (var i = 0; i < RowCount; i++)
{
appender.CreateRow()
.AppendValue(i)
.AppendValue((long)i)
.AppendValue((double)i)
.AppendValue(i % 2 == 0)
.EndRow();
}
}

[Benchmark]
public void AppendRowsWithAppendRow()
{
using var appender = connection.CreateAppender("bench");

for (var i = 0; i < RowCount; i++)
{
appender.AppendRow(i, static (row, value) =>
{
row.AppendValue(value)
.AppendValue((long)value)
.AppendValue((double)value)
.AppendValue(value % 2 == 0);
});
}
}
}
33 changes: 33 additions & 0 deletions DuckDB.NET.Benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net10.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Optimize>true</Optimize>
<BuildType>Full</BuildType>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\keyPair.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.15.4" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\DuckDB.NET.Data\Data.csproj" />
<ProjectReference Include="..\DuckDB.NET.Bindings\Bindings.csproj" Properties="BuildType=Full" />
</ItemGroup>

<!-- Copy the already-downloaded native DuckDB library into the benchmark output so it can be
loaded via runtimes/{rid}/native/. -->
<ItemGroup>
<None Include="..\DuckDB.NET.Bindings\obj\runtimes\**\*.dll;..\DuckDB.NET.Bindings\obj\runtimes\**\*.so;..\DuckDB.NET.Bindings\obj\runtimes\**\*.dylib;">
<Visible>false</Visible>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>runtimes\%(RecursiveDir)\%(FileName)%(Extension)</Link>
</None>
</ItemGroup>

</Project>
96 changes: 96 additions & 0 deletions DuckDB.NET.Benchmarks/MappedAppenderBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using BenchmarkDotNet.Attributes;
using DuckDB.NET.Data;
using DuckDB.NET.Data.Mapping;

namespace DuckDB.NET.Benchmarks;

[MemoryDiagnoser]
public class MappedAppenderBenchmark
{
private DuckDBConnection connection = null!;
private BenchRow[] rows = null!;
private IPropertyMapping<BenchRow>[] mappings = null!;

[Params(1_000_000)]
public int RowCount { get; set; }

public sealed class BenchRow
{
public int Id { get; init; }
public long Score { get; init; }
public double Value { get; init; }
public bool Active { get; init; }
}

public sealed class BenchRowMap : DuckDBAppenderMap<BenchRow>
{
public BenchRowMap()
{
Map(row => row.Id);
Map(row => row.Score);
Map(row => row.Value);
Map(row => row.Active);
}
}

[GlobalSetup]
public void Setup()
{
connection = new DuckDBConnection("DataSource=:memory:");
connection.Open();

rows = new BenchRow[RowCount];
for (var i = 0; i < RowCount; i++)
{
rows[i] = new BenchRow { Id = i, Score = i, Value = i, Active = i % 2 == 0 };
}

mappings = new BenchRowMap().PropertyMappings.ToArray();
}

[GlobalCleanup]
public void Cleanup()
{
connection.Dispose();
}

[IterationSetup]
public void IterationSetup()
{
using var command = connection.CreateCommand();
command.CommandText = "DROP TABLE IF EXISTS bench_mapped; CREATE TABLE bench_mapped (a INTEGER, b BIGINT, c DOUBLE, d BOOLEAN);";
command.ExecuteNonQuery();
}

// Mirrors the mapped appender loop before it adopted AppendRow.
[Benchmark(Baseline = true)]
public void AppendMappedRowsWithCreateRow()
{
using var appender = connection.CreateAppender("bench_mapped");

foreach (var record in rows)
{
AppendRecordWithCreateRow(appender, record);
}
}

[Benchmark]
public void AppendMappedRowsWithAppendRow()
{
using var appender = connection.CreateAppender<BenchRow, BenchRowMap>("bench_mapped");
appender.AppendRecords(rows);
}

private void AppendRecordWithCreateRow(DuckDBAppender appender, BenchRow record)
{
ArgumentNullException.ThrowIfNull(record);

var row = appender.CreateRow();
foreach (var mapping in mappings)
{
mapping.AppendToRow(row, record);
}

row.EndRow();
}
}
Loading
Loading