Skip to content

Commit

Permalink
another big refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
the-avid-engineer committed Jan 10, 2024
1 parent d7d65e5 commit 5f8d36d
Show file tree
Hide file tree
Showing 411 changed files with 12,051 additions and 9,654 deletions.
Binary file removed .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion src/.editorconfig → .editorconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
id = true
root = true

# C# files
[*.cs]
Expand Down
3 changes: 2 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<Project>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>12</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 4 additions & 0 deletions EntityDb.sln
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
global.json = global.json
ICON.png = ICON.png
LICENSE.txt = LICENSE.txt
README.md = README.md
SECURITY.md = SECURITY.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityDb.Json", "src\EntityDb.Json\EntityDb.Json.csproj", "{4936FFE0-98E5-43A2-89C9-0415A13CAA9B}"
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 - 2023 entitydb.io
Copyright (c) 2021 - 2024 entitydb.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
104 changes: 64 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,79 +29,103 @@ There are several core objects at the heart of this implementation. Encapsulatin
repositories.

1. Source Repository
- Agents
- Agent Signatures
- Deltas
- Tags
- Leases
- Aliases
2. Snapshot Repository
- Snapshots
3. Entity Repository
- Transaction Repository
- Optional: Snapshot Repository
4. Projection Repository
- Transaction Repository
- Optional: Snapshot Repository
2. State Repository
- States
3. Stream Repository
4. Entity Repository
5. Projection Repository

### Transactions
### Sources

A source represents an atomic operation on multiple entities. A source is committed atomically or not
at all. If some step in the source fails, the entire source should fail.
A source represents an atomic operation on one or more states.
If any message in the source cannot be committed, the entire source
cannot be committed.

### Agents
### Agent Signatures

An agent is an actor that can record sources. For example, if a source is initiated via an HTTP API, you
An agent is an actor that can record sources and interact with states. Whenever a source is committed,
the signature of the agent is recorded with it.

For example, if a source is initiated via an HTTP API, you
might use the `HttpContextAgent` - it's signature includes headers and connection information.

### Delta
### Deltas

A delta represents a change in state. Literally anything can be a delta.

A delta represents a change to a single entity. Going back to the bank account example,
Going back to the bank account example,
one delta could be `PerformDeposit` while another could be `PerformWithdrawl`. The things that you can do (commands),
as well as things that are done elsewhere (events), are delta.
as well as things that are done elsewhere (events), are deltas.

### Tags

A tag is a way to index entities by some piece of information. A tag can have a label and a value, both of which are
strings. Many accounts are typed, and you could represent this with a tag where `Label` is `Type` and `Value`
A tag is a way to index sources by some piece of information contained within. A tag can have a label and a value, both
of which are
strings.

Many accounts are typed, and you could represent this with a tag where `Label` is `Type` and `Value`
is `Savings` or `Checking`. You could then run a query to get the account id of all accounts where `Label` is `Type`
and `Value` is `Savings`. The number of savings accounts in the system would be the number of entity ids.
and `Value` is `Savings`. The number of savings accounts in the system would be the number of state ids.

### Leases

A lease is like a tag, except that it has a uniqueness constraint. Many banks have online portals, allowing bank members
A lease is like a tag, except that it has a uniqueness constraint. In addition to a label and value, leases also have
a scope.

Many banks have online portals, allowing bank members
to see their accounts on the internet. From the bank's perspective, all of the accounts should be tied to a member id,
probably a guid. But the member will not want to remember nor lookup this id - they will want to use a username. What
you can do in EntityDb is make a lease for members where the `Scope` is `Global`, the `Label`
is `Username`, and the `Value` is whatever username the member wants to use. If an attempt to commit a source is made
that would
violate the uniqueness constraint, it will be rejected. (This is obnoxious behavior for the user, though, so the bank
should check before attempting to commit to see if the username is available and give immediate feedback to choose a
that would violate the uniqueness constraint, the commit will fail. (However, this is bad UX, so the bank
should check that the username is available before attempting to commit and give immediate feedback to choose a
different username).

### Snapshots
### State

A snapshot is a stateful object at a given point in time. They always have an identifier and a version.
Together, the identifier and version called a pointer. You can request different versions of a given snapshot
by using different pointers!
A state is an object at a given point in time. Each state has a unique identifier, and across time each state
has a multiple versions. Together, the identifier and a single version are called a pointer, and you can refer to a
state
at a given point in time by using the associated pointer.

In the context of snapshots, the reserved version is reserved for pointing to the latest snapshot.
So if you want the latest version, you use a pointer with the exact id and the reserved version.
If you want a specific version, you can create pointer with the exact id and version you want.
The default version, `Version.Zero` is given special meaning in certain scenarios. When attempting to load a state, it
means
that the state does not exist. When attempting to modify a state, it means that the previous version of the state is
irrelevant.

The balance on your bank account is a snapshot. You can build that snapshot by summing all of the deposits and
withdrawls on your account. If you look at the bank statements, you will most likely see the snapshot of each bank
The balance on your bank account is a state. You can build that state by summing all of the deposits and
withdrawls on your account. If you look at the bank statements, you will most likely see the state of each bank
account for that statement, along with all of the deposits, withdrawls, and interest.

### Entities
### Stream Repository

A stream repository is specialized at producing sources when the order of messages
is out of the control of the application.

A great use case for a stream is to capture events coming from 3rd party, or even from
a different domain of your own suite of applications.

Sorry - I have not yet completed my thoughts of how to apply the banking metaphor here.

### Entity Repository

An entity repository is specialized at producing sources when the order of messages
is completely in the control of the application, and consuming sources to generate
a state that determines the validity of requests.

A great use case for an entity is to capture commands.

An entity is conceptually an aggregate id inside of a bounded context, and it extends the concept of a snapshot.
In the banking example, there are multiple entities. You have a membership at the bank. That's an entity. You probably
have a checking account. That's an entity. And you might even have a savings account. That is also an entity!

Which bounded contexts these entiies live in is up to the business.
### Projection Repository

### Projections
A projection repository does not produce sources, it only consumes them.

A projection is an aggregate, but notably _not_ the aggregate id, and it too extends the concept of a snapshot.
In the banking example, one example of a projection could be your entire account balance. It can be anything, though!
In the banking example, one example of a projection could be your entire balance across all accounts. It can be
anything, though!
You are not constrained in what data you want to use for your projection.
11 changes: 6 additions & 5 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

## Supported Versions

Version | Supported
|---|---|
\>= 8.0 | :white_check_mark:
< 8.0 | :x:
Version | Supported
|---------|--------------------|
\>= 8.0 | :white_check_mark:
< 8.0 | :x:

## Reporting a Vulnerability

Please report vulnerabilities [here](https://github.com/entitydb-io/EntityDb.NET/issues/new?assignees=&labels=&template=bug_report.md&title=[VULNERABILITY]%20)
Please report
vulnerabilities [here](https://github.com/entitydb-io/EntityDb.NET/issues/new?assignees=&labels=&template=bug_report.md&title=[VULNERABILITY]%20)
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "7.0.401",
"version": "8.0.100",
"allowPrerelease": false,
"rollForward": "disable"
}
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<Authors>Chris Philips</Authors>
<Company>entitydb.io</Company>
<Copyright>2021 - 2023 © entitydb.io</Copyright>
<Copyright>2021 - 2024 © entitydb.io</Copyright>
<RepositoryUrl>https://github.com/entitydb-io/entitydb</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<NeutralLanguage>en</NeutralLanguage>
Expand Down
18 changes: 0 additions & 18 deletions src/EntityDb.Abstractions/Entities/Deltas/IAddLeasesDelta.cs

This file was deleted.

18 changes: 0 additions & 18 deletions src/EntityDb.Abstractions/Entities/Deltas/IAddTagsDelta.cs

This file was deleted.

18 changes: 0 additions & 18 deletions src/EntityDb.Abstractions/Entities/Deltas/IDeleteLeasesDelta.cs

This file was deleted.

18 changes: 0 additions & 18 deletions src/EntityDb.Abstractions/Entities/Deltas/IDeleteTagsDelta.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/EntityDb.Abstractions/Entities/IEntity.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using EntityDb.Abstractions.Snapshots;
using EntityDb.Abstractions.States;

namespace EntityDb.Abstractions.Entities;

/// <summary>
/// Indicates the entity is compatible with several EntityDb.Common implementations.
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
public interface IEntity<TEntity> : ISnapshot<TEntity>
public interface IEntity<TEntity> : IState<TEntity>
{
/// <summary>
/// Returns <c>true</c> if <see cref="Reduce(object)" /> is not expected to throw an exception.
Expand Down
18 changes: 9 additions & 9 deletions src/EntityDb.Abstractions/Entities/IEntityRepositoryFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace EntityDb.Abstractions.Entities;

/// <summary>
/// Represents a type used to create instances of <see cref="IMultipleEntityRepository{TEntity}" />
/// and <see cref="ISingleEntityRepository{TEntity}"/>.
/// and <see cref="ISingleEntityRepository{TEntity}" />.
/// </summary>
/// <typeparam name="TEntity">The type of entity.</typeparam>
public interface IEntityRepositoryFactory<TEntity>
Expand All @@ -16,50 +16,50 @@ public interface IEntityRepositoryFactory<TEntity>
/// <param name="entityId">A id associated with a <typeparamref name="TEntity" />.</param>
/// <param name="agentSignatureOptionsName">The name of the agent signature options.</param>
/// <param name="sourceSessionOptionsName">The agent's use case for the source repository.</param>
/// <param name="snapshotSessionOptionsName">The agent's use case for the snapshot repository.</param>
/// <param name="stateSessionOptionsName">The agent's use case for the state repository.</param>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>A new instance of <see cref="ISingleEntityRepository{TEntity}" />.</returns>
Task<ISingleEntityRepository<TEntity>> CreateSingleForNew
(
Id entityId,
string agentSignatureOptionsName,
string sourceSessionOptionsName,
string? snapshotSessionOptionsName = null,
string? stateSessionOptionsName = null,
CancellationToken cancellationToken = default
);

/// <summary>
/// Create a new instance of <see cref="ISingleEntityRepository{TEntity}" />
/// for an existing entity.
/// </summary>
/// <param name="entityPointer">A pointer associated with a <typeparamref name="TEntity" />.</param>
/// <param name="agentSignatureOptionsName">The name of the agent signature options.</param>
/// <param name="sourceSessionOptionsName">The agent's use case for the source repository.</param>
/// <param name="snapshotSessionOptionsName">The agent's use case for the snapshot repository.</param>
/// <param name="stateSessionOptionsName">The agent's use case for the state repository.</param>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>A new instance of <see cref="ISingleEntityRepository{TEntity}" />.</returns>
Task<ISingleEntityRepository<TEntity>> CreateSingleForExisting
(
Pointer entityPointer,
string agentSignatureOptionsName,
string sourceSessionOptionsName,
string? snapshotSessionOptionsName = null,
string? stateSessionOptionsName = null,
CancellationToken cancellationToken = default
);

/// <summary>
/// Create a new instance of <see cref="IMultipleEntityRepository{TEntity}" />
/// </summary>
/// <param name="agentSignatureOptionsName">The name of the agent signature options.</param>
/// <param name="sourceSessionOptionsName">The agent's use case for the source repository.</param>
/// <param name="snapshotSessionOptionsName">The agent's use case for the snapshot repository.</param>
/// <param name="stateSessionOptionsName">The agent's use case for the state repository.</param>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>A new instance of <see cref="IMultipleEntityRepository{TEntity}" />.</returns>
Task<IMultipleEntityRepository<TEntity>> CreateMultiple
(
string agentSignatureOptionsName,
string sourceSessionOptionsName,
string? snapshotSessionOptionsName = null,
string? stateSessionOptionsName = null,
CancellationToken cancellationToken = default
);
}
Loading

0 comments on commit 5f8d36d

Please sign in to comment.