Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/nad-au/autoinc

Multi-provider distributed unique Id generator
https://github.com/nad-au/autoinc

neo4j

Last synced: about 4 hours ago
JSON representation

Multi-provider distributed unique Id generator

Awesome Lists containing this project

README

        

# AutoInc
Multi-provider distributed unique Id generator for .NET. Its purpose is to generate sequence numbers for common business use-cases. For example: Product, Invoice or Registration numbers.

## AutoInc.Neo4j

AutoInc.Neo4j is a [Neo4j](https://neo4j.com/) provider, allowing for unique Ids to be generated by the Neo4j graph database.

### Getting Started

Using Nuget package manager to install the [AutoInc.Neo4j](https://www.nuget.org/packages/AutoInc.Neo4j/) package to your .NET project, or type the following from the package manager console.

```
Install-Package AutoInc.Neo4j
```

We'll need to connect to the Neo4j database. See [Neo4j.Driver](https://github.com/neo4j/neo4j-dotnet-driver) documentation for detailed connection instructions.

``` csharp
var driver = GraphDatabase.Driver("neo4j://localhost:7687");
```

AutoInc.Neo4j maintains sequence numbers inside dedicated nodes. One node is created for each sequence number (scope). By default, AutoInc.Neo4j uses the `UniqueId` label. This can be changed by setting the static `Neo4jOptions.LabelName` property.

``` csharp
Neo4jOptions.LabelName = "MySequenceNumber";
```

### Initialising constraints

Before creating sequence numbers, we should create unique constraints on our sequence nodes to avoid duplicates. Due to the differences between Neo4j Community and Neo4j Enterprise, we need to perform an extra step if the latter is used.

``` csharp
Neo4jOptions.UseNeo4jEnterprise = true; // Only if Neo4j Enterprise is used

await driver.InitialiseUniqueIdsAsync();
```

### Generating sequence numbers

A sequence number is generated by calling the `NextUniqueIdAsync` method and specifying the scope name.

``` csharp
var invoiceNumber = await driver.NextUniqueIdAsync("invoice");
```

### Updating the next sequence number

Sometimes it is useful to set the next (or start) number for a sequence range. We can do this by calling the `UpdateUniqueIdAsync` method and specifying the scope name. When calling this method, it effectively sets the *last* sequence number. What this means is that when calling `NextUniqueIdAsync` it will return the *last* sequence number + 1.

``` csharp
await driver.UpdateUniqueIdAsync("invoice", 10);

Console.WriteLine(await driver.NextUniqueIdAsync("invoice"));
// Prints 11
```

### Extension methods

AutoInc.Neo4j provides extension methods for `NextUniqueIdAsync` and `UpdateUniqueIdAsync` which hang off `IDriver`, `IAsyncSession` and `IAsyncTransaction` interfaces which all work the same way.

### Transactions

Ideally, we would combine the sequence number generation along with the query which consumes the sequence number (the create query). To do this we wrap both operations inside a transaction. The advantage here is that if the transaction is rolled-back, the sequence number is also reset, so the number is not wasted.

``` csharp
var session = driver.AsyncSession();

await session.WriteTransactionAsync(async tx =>
{
var id = await tx.NextUniqueIdAsync("invoice");

var parameters = new { id };
var query = "CREATE (invoice:Invoice {Id: $id})";
await tx.RunAsync(query, parameters);
});

await session.CloseAsync();
```

### Non-async methods

[Neo4j.Driver](https://github.com/neo4j/neo4j-dotnet-driver) supports non-async operations through its [Neo4j.Driver.Simple](https://www.nuget.org/packages/Neo4j.Driver.Simple/) package. This package exposes alternative interfaces `ISession` and `ITransaction`. AutoInc.Neo4j provides `UpdateUniqueId` and `NextUniqueId` extension methods which hang off these interfaces. These are identical to the async versions.

``` csharp
driver.UpdateUniqueId("invoice", 20);

Console.WriteLine(driver.NextUniqueId("invoice"));
// Prints 21
```