From 7e706db22ac2f22953be478af5d99d897fc2787d Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Fri, 4 Aug 2017 15:59:36 +0300 Subject: [PATCH] Validate schema classes for duplicates --- CHANGELOG.md | 1 + Realm/Realm/Schema/RealmSchema.cs | 12 +++++++- Tests/Tests.Shared/ConfigurationTests.cs | 37 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a38de11245..9bb2e337c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Exposed `Realm.WriteCopy` API to copy a Realm file and optionally encrypt it with a different key. ([#1464](https://github.com/realm/realm-dotnet/pull/1464)) - The runtime representations of all Realm collections (`IQueryable` and `IList`) now implement the `IList` interface that is needed for data-binding to `ListView` in UWP applications. ([#1469](https://github.com/realm/realm-dotnet/pull/1469)) - Exposed `User.RetrieveInfoForUserAsync` API to allow admin users to lookup other users' identities in the Realm Object Server. This can be used, for example, to find a user by knowing their Facebook id. ([#1486](https://github.com/realm/realm-dotnet/pull/1486)) +- Added a check to verify there are no duplicate object names when creating the schema. ([#1502](https://github.com/realm/realm-dotnet/pull/1502)) ### Bug fixes - Fix an exception being thrown when comparing non-constant character value in a query. ([#1471](https://github.com/realm/realm-dotnet/pull/1471)) diff --git a/Realm/Realm/Schema/RealmSchema.cs b/Realm/Realm/Schema/RealmSchema.cs index 5fea5af2d3..4aec13a4fb 100644 --- a/Realm/Realm/Schema/RealmSchema.cs +++ b/Realm/Realm/Schema/RealmSchema.cs @@ -102,9 +102,19 @@ IEnumerator IEnumerable.GetEnumerator() internal static RealmSchema CreateSchemaForClasses(IEnumerable classes) { var builder = new Builder(); + var classNames = new HashSet(); foreach (var @class in classes) { - builder.Add(ObjectSchema.FromType(@class)); + var objectSchema = ObjectSchema.FromType(@class); + if (!classNames.Add(objectSchema.Name)) + { + var duplicateType = builder.Single(s => s.Name == objectSchema.Name).Type; + var errorMessage = "The names (without namespace) of objects persisted in Realm must be unique." + + $"The duplicate types are {@class.FullName} and {duplicateType.FullName}. Either rename one" + + " of them or explicitly specify ObjectClasses on your RealmConfiguration."; + throw new NotSupportedException(errorMessage); + } + builder.Add(objectSchema); } return builder.Build(); diff --git a/Tests/Tests.Shared/ConfigurationTests.cs b/Tests/Tests.Shared/ConfigurationTests.cs index e4415ca65a..78014cdf43 100644 --- a/Tests/Tests.Shared/ConfigurationTests.cs +++ b/Tests/Tests.Shared/ConfigurationTests.cs @@ -261,5 +261,42 @@ public void ReadOnlyRealmsArentWritable() }, Throws.TypeOf()); } } + + [Test] + public void DuplicateClassNames_ThrowsException() + { + var config = new RealmConfiguration + { + ObjectClasses = new[] + { + typeof(Foo.DuplicateClass), + typeof(Bar.DuplicateClass) + } + }; + + var constraint = Throws.TypeOf().And + .Message.Contains("Foo.DuplicateClass").And + .Message.Contains("Bar.DuplicateClass"); + + Assert.That(() => Realm.GetInstance(config), constraint); + } + } +} + +namespace Foo +{ + [Explicit] + public class DuplicateClass : RealmObject + { + public int IntValue { get; set; } + } +} + +namespace Bar +{ + [Explicit] + public class DuplicateClass : RealmObject + { + public string StringValue { get; set; } } } \ No newline at end of file