Implemented UniqueConstraints Bundle #457

Closed
wants to merge 1 commit into
from

Projects

None yet

3 participants

@felipeleusin

This is a simple bundle that allows the developer to flag properties their model to act like Unique Constraints. A simple document is created for each constraint and is enforced with triggers.

@ravendb
ravendb commented Feb 9, 2012

Can you send us a CLA?

On Wed, Feb 8, 2012 at 12:44 PM, Felipe Leusin <
reply@reply.github.com

wrote:

This is a simple bundle that allows the developer to flag properties their
model to act like Unique Constraints. A simple document is created for each
constraint and is enforced with triggers.

You can merge this Pull Request by running:

git pull https://github.com/felipeleusin/ravendb master

Or you can view, comment on it, or merge it online at:

#457

-- Commit Summary --

  • implemented unique constraints bundle

-- File Changes --

M Bundles/Raven.Bundles.Tests/Raven.Bundles.Tests.csproj (12)
A Bundles/Raven.Bundles.Tests/UniqueConstraints/CreateTests.cs (90)
A Bundles/Raven.Bundles.Tests/UniqueConstraints/DeleteTests.cs (50)
A Bundles/Raven.Bundles.Tests/UniqueConstraints/UniqueConstraintsTest.cs
(39)
A Bundles/Raven.Bundles.Tests/UniqueConstraints/UpdateTests.cs (30)
A Bundles/Raven.Bundles.UniqueConstraints/Constants.cs (11)
A Bundles/Raven.Bundles.UniqueConstraints/Properties/AssemblyInfo.cs (36)
A
Bundles/Raven.Bundles.UniqueConstraints/Raven.Bundles.UniqueConstraints.csproj
(66)
A
Bundles/Raven.Bundles.UniqueConstraints/UniqueConstraintsDeleteTrigger.cs
(40)
A Bundles/Raven.Bundles.UniqueConstraints/UniqueConstraintsPutTrigger.cs
(133)
M Bundles/Raven.Bundles.sln (24)
A Bundles/Raven.Client.UniqueConstraints/Properties/AssemblyInfo.cs (20)
A
Bundles/Raven.Client.UniqueConstraints/Raven.Client.UniqueConstraints.csproj
(68)
A Bundles/Raven.Client.UniqueConstraints/UniqueConstraintAttribte.cs (8)
A Bundles/Raven.Client.UniqueConstraints/UniqueConstraintsStoreListener.cs
(43)

-- Patch Links --

https://github.com/ravendb/ravendb/pull/457.patch
https://github.com/ravendb/ravendb/pull/457.diff


Reply to this email directly or view it on GitHub:
#457

@felipeleusin

Sure. Will send tomorrow.

@ayende
Member
ayende commented Feb 25, 2012

Thanks for this, I pulled this in. Can you provide documentation for this?

@ayende ayende closed this Feb 25, 2012
@felipeleusin

I'll send one tomorrow.

@felipeleusin

I'll write one tomorrow and send you.

On Sat, Feb 25, 2012 at 5:23 PM, Ayende Rahien <
reply@reply.github.com

wrote:

Thanks for this, I pulled this in. Can you provide documentation for this?


Reply to this email directly or view it on GitHub:
#457 (comment)

@ayende
Member
ayende commented Feb 27, 2012

Thanks

On Mon, Feb 27, 2012 at 12:31 AM, Felipe Leusin <
reply@reply.github.com

wrote:

I'll write one tomorrow and send you.

On Sat, Feb 25, 2012 at 5:23 PM, Ayende Rahien <
reply@reply.github.com

wrote:

Thanks for this, I pulled this in. Can you provide documentation for
this?


Reply to this email directly or view it on GitHub:
#457 (comment)


Reply to this email directly or view it on GitHub:
#457 (comment)

@felipeleusin

UniqueConstraints Bundle

Premise

This bundle aims to allow the user to implement unique constraints in the objects (usefull for properties like email or social security number).

How it works

The bundle works both in the server (using a PutTrigger and a DeleteTrigger) and in the client (using a DocumentStoreListener).

When a document is stored in the database it generates "dummy" documents with the fields as "UniqueConstraints/" + entityName + "/" + propertyName + "/" + propertyValue. This way you don't require indexes (which would need to be stale to check for uniqueness).

UniqueConstraintsStoreListener

The listener works by using reflection when the document is stored on the database and generating metadata regarding it's unique constraints. The reflection result is cached in a ConcurrentDictionary to help with performance.

UniqueConstraintsPutTrigger

The put trigger acts whenever it finds a document being inserted with constraints metadata it checks for existing documents in for the constraints and if any existing document is found it returns a VetoResult.Deny informing the confliction fields. This would need to be checked on the client-side using a try block for the OperationVetoedException.

If a document is being updated the trigger updates the generated constraint document.

UniqueConstraintsDeleteTrigger

The delete trigger acts whener it find a document being delete with constraints metadata and deletes the referenced constraint documents.

Caveats

  • This was developed to be used with strings or ValueTypes. I'm unsure how it would behave with another property with the UniqueConstraint attribute.
  • If, in the same transaction you're updating documents and "switching" constraints (as in inserting a document with a property that was already beign used but in the same transaction deleting the "old" document) it may not work as expected.

Credits

Thanks to Ayende and it's team for RavenDB.
Matt Warren for help with some tests and some fixes.

Felipe Leusin (@whymclovin)

@ravendb
ravendb commented Feb 27, 2012

Thanks, we will push this to our website shortly

On Mon, Feb 27, 2012 at 4:17 PM, Felipe Leusin <
reply@reply.github.com

wrote:

UniqueConstraints Bundle

Premise

This bundle aims to allow the user to implement unique constraints in the
objects (usefull for properties like email or social security number).

How it works

The bundle works both in the server (using a PutTrigger and a
DeleteTrigger) and in the client (using a DocumentStoreListener).

When a document is stored in the database it generates "dummy" documents
with the fields as "UniqueConstraints/" + entityName + "/" + propertyName +
"/" + propertyValue. This way you don't require indexes (which would need
to be stale to check for uniqueness).

UniqueConstraintsStoreListener

The listener works by using reflection when the document is stored on the
database and generating metadata regarding it's unique constraints. The
reflection result is cached in a ConcurrentDictionary to help with
performance.

UniqueConstraintsPutTrigger

The put trigger acts whenever it finds a document being inserted with
constraints metadata it checks for existing documents in for the
constraints and if any existing document is found it returns a
VetoResult.Deny informing the confliction fields. This would need to be
checked on the client-side using a try block for the
OperationVetoedException.

If a document is being updated the trigger updates the generated
constraint document.

UniqueConstraintsDeleteTrigger

The delete trigger acts whener it find a document being delete with
constraints metadata and deletes the referenced constraint documents.

Caveats

  • This was developed to be used with strings or ValueTypes. I'm unsure how
    it would behave with another property with the UniqueConstraint attribute.
  • If, in the same transaction you're updating documents and "switching"
    constraints (as in inserting a document with a property that was already
    beign used but in the same transaction deleting the "old" document) it
    may not work as expected.

Credits

Thanks to Ayende and it's team for RavenDB.
Matt Warren for help with some tests and some fixes.

Felipe Leusin (@whymclovin)


Reply to this email directly or view it on GitHub:
#457 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment