Skip to content
This repository has been archived by the owner on Dec 3, 2024. It is now read-only.

feat: Created solution and added implementation #1

Merged
merged 3 commits into from
Apr 2, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ jobs:
dotnet-logging: ${{ inputs.dotnet-logging }}
dotnet-version: |
7.x
solution: ###SOLUTION###
solution: ./SequentialGuid.sln
secrets: inherit
23 changes: 9 additions & 14 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
<Project>

<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>

<ItemGroup>
<GlobalPackageReference Include="CSharpier.MSBuild" Version="0.26.3" />
<GlobalPackageReference Include="CSharpier.MSBuild" Version="0.27.3" />
<GlobalPackageReference Include="GitVersion.MsBuild" Version="5.12.0" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" />
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.8.14" />
<GlobalPackageReference Include="SonarAnalyzer.CSharp" Version="9.16.0.82469" Condition=" '$(BuildingInsideVisualStudio)' == 'true' " />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.9.28" />
<GlobalPackageReference Include="SonarAnalyzer.CSharp" Version="9.23.0.88079" Condition=" '$(BuildingInsideVisualStudio)' == 'true' " />
</ItemGroup>

<ItemGroup>
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="NetEvolve.Extensions.XUnit" Version="2.0.36" />
<PackageVersion Include="Verify.Xunit" Version="22.5.0" />
<PackageVersion Include="xunit" Version="2.6.2" />
<PackageVersion Include="xunit.core" Version="2.6.2" />
<PackageVersion Include="xunit.runner.console" Version="2.6.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.4" />
<PackageVersion Include="xunit" Version="2.7.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.7" />
</ItemGroup>

</Project>
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
# template-dotnet
.NET template for repositories
# NetEvolve.SequentialGuid

[![Nuget](https://img.shields.io/nuget/v/NetEvolve.SequentialGuid?logo=nuget)](https://www.nuget.org/packages/NetEvolve.SequentialGuid/)
[![Nuget](https://img.shields.io/nuget/dt/NetEvolve.SequentialGuid?logo=nuget)](https://www.nuget.org/packages/NetEvolve.SequentialGuid/)


A .NET library to generate sequential GUIDs, similar to SQL Server's `newsequentialid()`.
It's a drop-in replacement for `System.Guid.NewGuid()`, focusing on performance and low allocation.

> [!CAUTION]
> The downside is that it's not as unique as `System.Guid.NewGuid()` and crypotographically insecure.
> So be sure to understand the trade-offs before using it.

## Features
With the `SequentialGuidType` enum, you can choose between 3 different types of sequential GUIDs:
- `AsBinary`<br/>The sequential part is at the beginning of the GUID, similar to Oracle's `SYS_GUID()`.
- `AsString` (Default)<br/>The sequential part is at the beginning of the GUID.
- `AtEnd`<br/>The sequential part is at the end of the GUID, similar to SQL Server's `newsequentialid()`.

## Installation

```pwsh
dotnet add package NetEvolve.SequentialGuid
```

## Usage

```csharp
using NetEvolve.SequentialGuid;

Guid guid = SequentialGuidFactory.NewGuid(); // Default is SequentialGuidType.AsString
// or
Guid guid = SequentialGuidFactory.NewGuid(SequentialGuidType.AsBinary);
```
57 changes: 57 additions & 0 deletions SequentialGuid.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{554192CF-0D2E-42CE-9EC7-066A8FD73A4F}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.filenesting.json = .filenesting.json
.gitignore = .gitignore
.gitmodules = .gitmodules
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
Directory.Packages.props = Directory.Packages.props
Directory.Solution.props = Directory.Solution.props
GitVersion.yml = GitVersion.yml
LICENSE = LICENSE
new-project.ps1 = new-project.ps1
nuget.config = nuget.config
README.md = README.md
update-solution.ps1 = update-solution.ps1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{42F47CC9-30FA-44A2-91AC-3C55EB20D93E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0EAC5BD7-1E8D-4BA8-B0C9-19766031C329}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.SequentialGuid", "src\NetEvolve.SequentialGuid\NetEvolve.SequentialGuid.csproj", "{ADAE52D0-CA16-4E3F-814D-65625111ED5A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.SequentialGuid.Tests.Unit", "tests\NetEvolve.SequentialGuid.Tests.Unit\NetEvolve.SequentialGuid.Tests.Unit.csproj", "{433C0DEC-2E6F-4D22-9382-1BAA60BBBC0B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ADAE52D0-CA16-4E3F-814D-65625111ED5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ADAE52D0-CA16-4E3F-814D-65625111ED5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADAE52D0-CA16-4E3F-814D-65625111ED5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ADAE52D0-CA16-4E3F-814D-65625111ED5A}.Release|Any CPU.Build.0 = Release|Any CPU
{433C0DEC-2E6F-4D22-9382-1BAA60BBBC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{433C0DEC-2E6F-4D22-9382-1BAA60BBBC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{433C0DEC-2E6F-4D22-9382-1BAA60BBBC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{433C0DEC-2E6F-4D22-9382-1BAA60BBBC0B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{ADAE52D0-CA16-4E3F-814D-65625111ED5A} = {42F47CC9-30FA-44A2-91AC-3C55EB20D93E}
{433C0DEC-2E6F-4D22-9382-1BAA60BBBC0B} = {0EAC5BD7-1E8D-4BA8-B0C9-19766031C329}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4646205D-074A-48BC-9847-3262718F7FCD}
EndGlobalSection
EndGlobal
2 changes: 1 addition & 1 deletion new-project.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ New-Project `
-DisableTests $DisableTests `
-DisableUnitTests $DisableUnitTests `
-DisableIntegrationTests $DisableIntegrationTests `
-SolutionFile "###SOLUTION###" `
-SolutionFile "./SequentialGuid.sln" `
-OutputDirectory (Get-Location) `
-EnableProjectGrouping $EnableProjectGrouping `
-DisableArchitectureTests $DisableArchitectureTests
17 changes: 0 additions & 17 deletions new-solution.ps1

This file was deleted.

15 changes: 15 additions & 0 deletions src/NetEvolve.SequentialGuid/NetEvolve.SequentialGuid.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<PropertyGroup>
<Title>$(MSBuildProjectName)</Title>
<Description>Small project for the generation of sequential Guids.</Description>
<PackageProjectUrl>https://github.com/dailydevops/sequentialguid</PackageProjectUrl>
<RepositoryUrl>https://github.com/dailydevops/sequentialguid.git</RepositoryUrl>
<PackageTags>sequentialguid;guid;uuid</PackageTags>
</PropertyGroup>

</Project>
65 changes: 65 additions & 0 deletions src/NetEvolve.SequentialGuid/SequentialGuidFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
namespace NetEvolve.SequentialGuid;

using System;
using System.Diagnostics.CodeAnalysis;

/// <summary>
/// Factory class to create sequential <see cref="Guid"/>s.
/// </summary>
public static class SequentialGuidFactory
{
/// <summary>
/// Creates a new sequential <see cref="Guid"/> based on <paramref name="sequentialGuid"/>.
/// </summary>
/// <param name="sequentialGuid">Optional parameter. Defines the characteristics of the Sequential Guid.</param>
/// <returns>A sequential <see cref="Guid"/>.</returns>
public static Guid NewGuid(SequentialGuidType sequentialGuid = SequentialGuidType.AsString) =>
NewGuid(Random.Shared, DateTimeOffset.UtcNow, sequentialGuid);

/// <summary>
/// Creates a new sequential <see cref="Guid"/> based on <paramref name="sequentialGuid"/>.
/// </summary>
/// <param name="random"></param>
/// <param name="utcNow"></param>
/// <param name="sequentialGuid">Optional parameter. Defines the characteristics of the Sequential Guid.</param>
/// <returns>A sequential <see cref="Guid"/>.</returns>
[SuppressMessage("Security", "CA5394:Do not use insecure randomness")]
internal static Guid NewGuid(
[NotNull] Random random,
DateTimeOffset utcNow,
SequentialGuidType sequentialGuid = SequentialGuidType.AsString
)
{
ArgumentNullException.ThrowIfNull(random);

var timeStamp = utcNow.Ticks / 10000L;
var timeStampBytes = BitConverter.GetBytes(timeStamp).AsSpan();

if (BitConverter.IsLittleEndian)
{
timeStampBytes.Reverse();
}

Span<byte> guidBytes = stackalloc byte[16];

if (sequentialGuid == SequentialGuidType.AtEnd)
{
timeStampBytes[2..8].CopyTo(guidBytes[10..16]);
random.NextBytes(guidBytes[..9]);

return new Guid(guidBytes);
}

timeStampBytes[2..8].CopyTo(guidBytes[..6]);

if (sequentialGuid == SequentialGuidType.AsString && BitConverter.IsLittleEndian)
{
guidBytes[..4].Reverse();
guidBytes[4..6].Reverse();
}

random.NextBytes(guidBytes[7..]);

return new Guid(guidBytes);
}
}
33 changes: 33 additions & 0 deletions src/NetEvolve.SequentialGuid/SequentialGuidType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace NetEvolve.SequentialGuid;

using System;

/// <summary>
/// Describes the position of the sequential part of the <see cref="Guid"/>.
/// </summary>
public enum SequentialGuidType
{
/// <summary>
/// The sequential part is at the beginning of the <see cref="Guid"/>.
/// </summary>
/// <remarks>
/// Used by Oracle.
/// </remarks>
AsBinary = 1,

/// <summary>
/// The sequential part is at the beginning of the <see cref="Guid"/>.
/// </summary>
/// <remarks>
/// Used by MySql and PostgreSql.
/// </remarks>
AsString = 0,

/// <summary>
/// The sequential part is at the end of the <see cref="Guid"/>.
/// </summary>
/// <remarks>
/// Used by SqlServer.
/// </remarks>
AtEnd = 2,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.msbuild" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NetEvolve.Extensions.XUnit" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\NetEvolve.SequentialGuid\NetEvolve.SequentialGuid.csproj" />
</ItemGroup>

</Project>
Loading
Loading