Skip to content

Instantly share code, notes, and snippets.

@felipeleusin
Created April 1, 2011 21:24
Show Gist options
  • Save felipeleusin/898886 to your computer and use it in GitHub Desktop.
Save felipeleusin/898886 to your computer and use it in GitHub Desktop.
Delete Trigger to Ensure Unique Constraints
public static class EnsureHelper
{
private const string EnsureUniqueConstraint = "Ensure-Unique-Constraint";
public static IList<PropertyInfo> GetPropertiesFromMetadata(JObject metadata)
{
var clrType = metadata.Value<string>("Raven-Clr-Type");
if (clrType != null)
{
var type = Type.GetType(clrType);
return type != null
? type.GetProperties().Where(p => Attribute.IsDefined(p, typeof(EnsureUniqueAttribute), true)).ToList()
: null;
}
return null;
}
}
public class EnsureUniqueDeleteTrigger : AbstractDeleteTrigger
{
private const string EnsureUniqueConstraint = "Ensure-Unique-Constraint";
public override void OnDelete(string key, Raven.Http.TransactionInformation transactionInformation)
{
if (key.StartsWith("Raven"))
return;
var doc = Database.Get(key, transactionInformation);
if (doc == null)
return;
var metadata = doc.Metadata;
if (metadata.Value<bool>(EnsureUniqueConstraint))
return;
var pseudoKey = key.Substring(0, key.IndexOf("/"));
var deleteCommands = new List<DeleteCommandData>();
foreach (var propertyInfo in EnsureHelper.GetPropertiesFromMetadata(metadata))
{
var checkKey = pseudoKey + "/" + propertyInfo.Name.ToLowerInvariant() + "/" +
doc.ToJson().Value<string>(propertyInfo.Name);
deleteCommands.Add(new DeleteCommandData()
{
Etag = null, Key = checkKey, TransactionInformation = transactionInformation
});
}
Database.Batch(deleteCommands);
}
}
public class EnsureUniquePutTrigger : AbstractPutTrigger
{
private const string EnsureUniqueConstraint = "Ensure-Unique-Constraint";
public override VetoResult AllowPut(string key, JObject document, JObject metadata, Raven.Http.TransactionInformation transactionInformation)
{
if (key.StartsWith("Raven"))
{
return VetoResult.Allowed;
}
if (metadata.Value<bool>(EnsureUniqueConstraint))
{
return VetoResult.Allowed;
}
var pseudoKey = key.Substring(0, key.IndexOf("/"));
foreach (var propertyInfo in EnsureHelper.GetPropertiesFromMetadata(metadata))
{
var checkKey = pseudoKey + "/" + propertyInfo.Name.ToLowerInvariant() + "/" + document.Value<string>(propertyInfo.Name);
var checkDoc = Database.Get(checkKey, transactionInformation);
if (checkDoc != null)
{
var checkId = checkDoc.ToJson().Value<string>("Id");
if (checkId != key)
{
return VetoResult.Deny("Ensure unique constraint violated for field: " + propertyInfo.Name);
}
}
}
return VetoResult.Allowed;
}
public override void OnPut(string key, JObject document, JObject metadata, Raven.Http.TransactionInformation transactionInformation)
{
if (key.StartsWith("Raven"))
{
return;
}
if (metadata.Value<bool>(EnsureUniqueConstraint))
{
return;
}
var putCommands = new List<PutCommandData>();
var pseudoKey = key.Substring(0, key.IndexOf("/"));
foreach (var propertyInfo in EnsureHelper.GetPropertiesFromMetadata(metadata))
{
var checkId = propertyInfo.Name.ToLowerInvariant();
putCommands.Add(new PutCommandData()
{
Key = pseudoKey + "/" + checkId + "/" + document.Value<string>(propertyInfo.Name),
Etag = null,
Metadata = new JObject(new JProperty(EnsureUniqueConstraint, true)),
Document = new JObject(new JProperty("Id", key))
});
}
if (putCommands.Count > 0)
{
Database.Batch(putCommands);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment