Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7695284
added PrimaryKeyHandlers
slewis74 Jun 11, 2021
fe08fb6
Rounding out the PrimaryKeyHandler support, including Load and Alloca…
slewis74 Jun 14, 2021
f68a526
Updated tests to include a sample of TinyType usage, on the Customer …
slewis74 Jun 14, 2021
22ccb0b
cleanup/split into separate files
slewis74 Jun 14, 2021
1106bc1
Adjustments to how the Id prefix can be set, as well as the Format
slewis74 Jun 14, 2021
e419ff1
renamed PrimaryKeyHandlerRegistry property to PrimaryKeyHandlers, for…
slewis74 Jun 14, 2021
1061a4c
Add ability to get the key prefix from the configuration, Octopus ser…
slewis74 Jun 14, 2021
72d171e
Including more of the methods that allow TKey when loading documents
slewis74 Jun 17, 2021
5b8ac76
cleanup
slewis74 Jun 17, 2021
077542d
Fixed IReadQueryExecutor interface to correctly express nullable refe…
slewis74 Jun 17, 2021
706f33b
rolling back the nullable reference type changes to ExecuteScalar
slewis74 Jun 18, 2021
a6266ab
don't use the term TinyType
slewis74 Jun 21, 2021
2427cb4
renamed GetPrimitiveValue and removed FormatKey from IPrimitivePrimar…
slewis74 Jun 21, 2021
82e4bd4
Refactored the DocumentMap and IdColumnMapping builders to be better …
slewis74 Jun 21, 2021
df2c99e
Failing test for custom prefix
pawelpabich Jun 21, 2021
fd30294
The usage of custom Prefix resulted in a wrong type of id handler bei…
pawelpabich Jun 21, 2021
15c83d8
Added an easier to use escape hatch for people that use custom prefix
pawelpabich Jun 21, 2021
162d66a
This was added by mistake
pawelpabich Jun 22, 2021
a9c48d8
Fixed the Delete/DeleteAsync methods on IWriteQueryExecutor, to clean…
slewis74 Jun 22, 2021
7401f6a
Actually load the data
pawelpabich Jun 22, 2021
0a19e30
Make the built in primary key handler types public, so they can be cr…
slewis74 Jun 22, 2021
9d35dea
Changed the StringPrimaryKeyHandler so it takes a string for the pref…
slewis74 Jun 22, 2021
788eb92
Fixed IdColumnMapping constructor, it wasn't setting MaxLength and Di…
slewis74 Jun 28, 2021
7b439e0
Octopus server testing showed up an issue with LoadMany's query prepa…
slewis74 Jun 30, 2021
459f6eb
Re-instated `.In` extension method for use on custom primary key types
slewis74 Jul 6, 2021
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
6 changes: 3 additions & 3 deletions source/Nevermore.IntegrationTests/Advanced/HooksFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ public void ShouldCallHooks()

using var transaction = Store.BeginTransaction();

var customer = new Customer {Id = "C131", FirstName = "Fred", LastName = "Freddy"};
var customer = new Customer {Id = "C131".ToCustomerId(), FirstName = "Fred", LastName = "Freddy"};
transaction.Insert(customer);
AssertLogged(log, "BeforeInsert", "AfterInsert");

customer = transaction.Load<Customer>("C131");
customer = transaction.Load<Customer, CustomerId>("C131".ToCustomerId());

transaction.Update(customer);
AssertLogged(log, "BeforeUpdate", "AfterUpdate");

transaction.Delete(customer);
transaction.Delete<Customer, CustomerId>(customer);
AssertLogged(log, "BeforeDelete", "AfterDelete");

transaction.Commit();
Expand Down
16 changes: 8 additions & 8 deletions source/Nevermore.IntegrationTests/Advanced/MappingFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class User

// Test accessibility
public string Prop1 { get; set; }
public string Prop2 { get; } = "Hello";
public string Prop2 { get; } = "Hello";
public string Prop3 { get; private set; }
public string Prop4 { get; protected set; }
public string Prop5 { get; private set; }
Expand All @@ -31,13 +31,13 @@ public void SetOtherProps(string prop3, string prop4, string prop5)
Prop5 = prop5;
}
}

enum Education { School, HighSchool, College }

public override void OneTimeSetUp()
{
base.OneTimeSetUp();

NoMonkeyBusiness();
KeepDataBetweenTests();

Expand Down Expand Up @@ -86,7 +86,7 @@ public void ShouldFailIfReadOnlyNotMapped()
[Test, Order(2)]
public void ShouldWorkIfProp2IsSaveOnly()
{
var map = ((IDocumentMap)new UserMap()).Build();
var map = ((IDocumentMap)new UserMap()).Build(Configuration.PrimaryKeyHandlers);
// Pretend the user edited their document map to set it to SaveOnly
((IColumnMappingBuilder) map.Columns.Single(c => c.ColumnName == "Prop2")).SaveOnly();
Configuration.DocumentMaps.Register(map);
Expand All @@ -105,9 +105,9 @@ public void ShouldInsert()
Prop1 = "Prop1",
FirstName = "Fred"
};

user.SetOtherProps("Prop3", "Prop4", "Prop5");

transaction.Insert(user);
transaction.Update(user);
transaction.Commit();
Expand All @@ -117,7 +117,7 @@ public void ShouldInsert()
public void ShouldLoad()
{
using var transaction = Store.BeginTransaction();

var user = transaction.Load<User>("users-123");
user.Should().NotBeNull();
user.Age.Should().Be(18);
Expand All @@ -132,7 +132,7 @@ public void ShouldLoad()
public void ShouldDelete()
{
using var transaction = Store.BeginTransaction();

transaction.Delete<User>("users-123");
var user = transaction.Load<User>("users-123");
user.Should().BeNull();
Expand Down
23 changes: 10 additions & 13 deletions source/Nevermore.IntegrationTests/Advanced/NoJsonFixture.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System.Collections.Generic;
using System.Data;
using FluentAssertions;
using Microsoft.Data.SqlClient.Server;
using Nevermore.IntegrationTests.SetUp;
using Nevermore.Mapping;
using NUnit.Framework;
Expand All @@ -14,9 +11,9 @@ public override void OneTimeSetUp()
{
base.OneTimeSetUp();
NoMonkeyBusiness();

ExecuteSql("create table TestSchema.Car([Id] nvarchar(50), [Name] nvarchar(100))");

Store.Configuration.DocumentMaps.Register(new CarMap());
}

Expand All @@ -25,23 +22,23 @@ class Car
public string Id { get; set; }
public string Name { get; set; }
}
class CarMap : DocumentMap<Car>

class CarMap : DocumentMap<Car>
{
public CarMap()
{
Column(m => m.Name);

JsonStorageFormat = JsonStorageFormat.NoJson;
}
}

[Test]
public void ShouldMapWithoutJson()
{
using var transaction = Store.BeginTransaction();
transaction.Insert(new Car { Name = "Volvo" });

var car = transaction.Load<Car>("Cars-1");
car.Should().NotBeNull();
car.Name.Should().Be("Volvo");
Expand All @@ -54,9 +51,9 @@ public void ShouldMapWithoutJson()
car.Name.Should().Be("Bertie");

transaction.Query<Car>().Count().Should().Be(1);
transaction.Delete(car);

transaction.Delete<Car, string>(car);

transaction.Query<Car>().Count().Should().Be(0);

car = transaction.Load<Car>("Cars-1");
Expand Down
26 changes: 13 additions & 13 deletions source/Nevermore.IntegrationTests/KeyAllocatorFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void ShouldAllocateKeysInChunks()
var allocatorA = new KeyAllocator(Store, 10);
var allocatorB = new KeyAllocator(Store, 10);

// A gets 1-10
// A gets 1-10
AssertNext(allocatorA, "Todos", 1);
AssertNext(allocatorA, "Todos", 2);
AssertNext(allocatorA, "Todos", 3);
Expand Down Expand Up @@ -76,7 +76,7 @@ public void ShouldAllocateInParallel()
const int allocationCount = 20;
const int threadCount = 10;

var projectIds = new ConcurrentBag<string>();
var customerIds = new ConcurrentBag<CustomerId>();
var deploymentIds = new ConcurrentBag<string>();
var random = new Random(1);

Expand All @@ -90,21 +90,21 @@ public void ShouldAllocateInParallel()
var sequence = random.Next(3);
if (sequence == 0)
{
var id = transaction.AllocateId(typeof (Customer));
projectIds.Add(id);
var id = transaction.AllocateId<Customer, CustomerId>();
customerIds.Add(id);
transaction.Commit();
}
else if (sequence == 1)
{
// Abandon some transactions (just projects to make it easier)
var id = transaction.AllocateId(typeof(Customer));
var id = transaction.AllocateId<Customer, CustomerId>();
// Abandoned Ids are not returned to the pool
projectIds.Add(id);
customerIds.Add(id);
transaction.Dispose();
}
else if (sequence == 2)
{
var id = transaction.AllocateId(typeof(Order));
var id = transaction.AllocateId<Order, string>();
deploymentIds.Add(id);
transaction.Commit();
}
Expand All @@ -115,21 +115,21 @@ public void ShouldAllocateInParallel()
Task.WaitAll(tasks);
Func<string, int> removePrefix = x => int.Parse(x.Split('-')[1]);

var projectIdsAfter = projectIds.Select(removePrefix).OrderBy(x => x).ToArray();
var customerIdsAfter = customerIds.Select(x => removePrefix(x.Value)).OrderBy(x => x).ToArray();
var deploymentIdsAfter = deploymentIds.Select(removePrefix).OrderBy(x => x).ToArray();

projectIdsAfter.Distinct().Count().Should().Be(projectIdsAfter.Length);
customerIdsAfter.Distinct().Count().Should().Be(customerIdsAfter.Length);
deploymentIdsAfter.Distinct().Count().Should().Be(deploymentIdsAfter.Length);

// Check that there are no gaps in sequence

var firstProjectId = projectIdsAfter.First();
var lastProjectId = projectIdsAfter.Last();
var firstProjectId = customerIdsAfter.First();
var lastProjectId = customerIdsAfter.Last();

var expectedProjectIds = Enumerable.Range(firstProjectId, lastProjectId - firstProjectId + 1)
.ToList();

projectIdsAfter.Should().BeEquivalentTo(expectedProjectIds);
customerIdsAfter.Should().BeEquivalentTo(expectedProjectIds);
}

static void AssertNext(KeyAllocator allocator, string collection, int expected)
Expand Down
54 changes: 54 additions & 0 deletions source/Nevermore.IntegrationTests/Model/CustomIdType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#nullable enable
using System;
using System.Globalization;
using System.Reflection;

namespace Nevermore.IntegrationTests.Model
{
public class CustomIdType<T>
{
internal CustomIdType(T value)
{
Value = value;
}

public T Value { get; }

public override string? ToString()
{
return Value?.ToString();
}

public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return !(Value is null) && Value.Equals(((CustomIdType<T>) obj).Value);
}

public override int GetHashCode()
{
return (Value != null ? Value.GetHashCode() : 0);
}

public static CustomIdType<T>? Create(Type customType, T value)
{
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
var instance = Activator.CreateInstance(customType, bindingFlags, null, new object[] { value! }, CultureInfo.CurrentCulture);
return instance as CustomIdType<T>;
}

public static TCustomIdType? Create<TCustomIdType>(T value) where TCustomIdType : CustomIdType<T>
{
return (TCustomIdType?) Create(typeof(TCustomIdType), value);
}
}

public class StringCustomIdType : CustomIdType<string>
{
internal StringCustomIdType(string value) : base(value)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Nevermore.IntegrationTests.Model
{
class CustomPrefixIdKeyHandler : StringCustomIdTypeIdKeyHandler<CustomPrefixId>
{
public const string CustomPrefix = "CustomPrefix";

public CustomPrefixIdKeyHandler():base(CustomPrefix)
{
}
}
}
19 changes: 18 additions & 1 deletion source/Nevermore.IntegrationTests/Model/Customer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public Customer()
Roles = new ReferenceCollection();
}

public string Id { get; set; }
public CustomerId Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ReferenceCollection Roles { get; }
Expand All @@ -18,4 +18,21 @@ public Customer()
public string ApiKey { get; set; }
public string[] Passphrases { get; set; }
}

public class CustomerId : StringCustomIdType
{
internal CustomerId(string value) : base(value)
{
}
}

#nullable enable

public static class CustomerIdExtensionMethods
{
public static CustomerId? ToCustomerId(this string? value)
{
return string.IsNullOrWhiteSpace(value) ? null : new CustomerId(value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Nevermore.IntegrationTests.Model
{
public class DocumentWithCustomPrefix
{
public CustomPrefixId Id { get; set; }
public string Name { get; set; }
}

public class CustomPrefixId : StringCustomIdType
{
internal CustomPrefixId(string value) : base(value)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Nevermore.IntegrationTests.Model
{
public class DocumentWithCustomPrefixAndStringId
{
public string Id { get; set; }
public string Name { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Nevermore.Mapping;

namespace Nevermore.IntegrationTests.Model
{
public class DocumentWithCustomPrefixAndStringIdMap : DocumentMap<DocumentWithCustomPrefixAndStringId>
{
public const string CustomPrefix = "CustomPrefix";

public DocumentWithCustomPrefixAndStringIdMap()
{
Id().KeyHandler(new StringPrimaryKeyHandler(CustomPrefix));
Column(m => m.Name);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Nevermore.Mapping;

namespace Nevermore.IntegrationTests.Model
{
public class DocumentWithCustomPrefixMap : DocumentMap<DocumentWithCustomPrefix>
{
public DocumentWithCustomPrefixMap()
{
Id();
Column(m => m.Name);
}
}
}
Loading