Skip to content

Commit

Permalink
Implement value comparer for hstore
Browse files Browse the repository at this point in the history
Closes #306
  • Loading branch information
roji committed Feb 27, 2018
1 parent 1765f8f commit 42e4544
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Net.NetworkInformation;
using System.Text;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using NpgsqlTypes;

namespace Microsoft.EntityFrameworkCore.Storage.Internal.Mapping
{
public class NpgsqlHstoreTypeMapping : NpgsqlTypeMapping
{
public NpgsqlHstoreTypeMapping() : base("hstore", typeof(Dictionary<string, string>), NpgsqlDbType.Hstore) {}
static readonly HstoreComparer ComparerInstance = new HstoreComparer();

public NpgsqlHstoreTypeMapping()
: base("hstore", typeof(Dictionary<string, string>), null, ComparerInstance, NpgsqlDbType.Hstore) {}

protected override string GenerateNonNullSqlLiteral(object value)
{
Expand All @@ -33,5 +40,26 @@ protected override string GenerateNonNullSqlLiteral(object value)
sb.Append('\'');
return sb.ToString();
}

class HstoreComparer : ValueComparer<Dictionary<string, string>>
{
public HstoreComparer() : base(
(a, b) => Compare(a,b),
source => Snapshot(source))
{}

static bool Compare(Dictionary<string, string> a, Dictionary<string, string> b)
{
if (a.Count != b.Count)
return false;
foreach (var kv in a)
if (!b.TryGetValue(kv.Key, out var bValue) || kv.Value != bValue)
return false;
return true;
}

static Dictionary<string, string> Snapshot(Dictionary<string, string> source)
=> new Dictionary<string, string>(source);
}
}
}
17 changes: 17 additions & 0 deletions test/EFCore.PG.Tests/Storage/NpgsqlTypeMappingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,23 @@ public void GenerateSqlLiteral_returns_hstore_literal()
{ "k2", "v2" }
}));

[Fact]
public void ValueComparer_hstore()
{
var source = new Dictionary<string, string>
{
{ "k1", "v1"},
{ "k2", "v2"}
};

var comparer = GetMapping("hstore").Comparer;
var snapshot = (Dictionary<string, string>)comparer.SnapshotFunc(source);
Assert.Equal(source, snapshot);
Assert.True(comparer.CompareFunc(source, snapshot));
snapshot.Remove("k1");
Assert.False(comparer.CompareFunc(source, snapshot));
}

[Fact]
public void GenerateSqlLiteral_returns_jsonb_literal()
=> Assert.Equal(@"JSONB '{""a"":1}'", GetMapping("jsonb").GenerateSqlLiteral(@"{""a"":1}"));
Expand Down

0 comments on commit 42e4544

Please sign in to comment.