Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate schema classes for duplicates #1502

Merged
merged 2 commits into from
Aug 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>` and `IList<T>`) 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))
- Added more comprehensive error messages when passing an invalid url scheme to `SyncConfiguration` or `User.LoginAsync`. ([#1501](https://github.com/realm/realm-dotnet/pull/1501))

### Bug fixes
Expand Down
12 changes: 11 additions & 1 deletion Realm/Realm/Schema/RealmSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,19 @@ IEnumerator IEnumerable.GetEnumerator()
internal static RealmSchema CreateSchemaForClasses(IEnumerable<Type> classes)
{
var builder = new Builder();
var classNames = new HashSet<string>();
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();
Expand Down
37 changes: 37 additions & 0 deletions Tests/Tests.Shared/ConfigurationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,42 @@ public void ReadOnlyRealmsArentWritable()
}, Throws.TypeOf<RealmInvalidTransactionException>());
}
}

[Test]
public void DuplicateClassNames_ThrowsException()
{
var config = new RealmConfiguration
{
ObjectClasses = new[]
{
typeof(Foo.DuplicateClass),
typeof(Bar.DuplicateClass)
}
};

var constraint = Throws.TypeOf<NotSupportedException>().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; }
}
}