Skip to content

Instantly share code, notes, and snippets.

@Romiko
Created September 27, 2011 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Romiko/1243853 to your computer and use it in GitHub Desktop.
Save Romiko/1243853 to your computer and use it in GitHub Desktop.
public virtual NodeReference<TNode> Create<TNode>(
TNode node,
IEnumerable<IRelationshipAllowingParticipantNode<TNode>> relationships,
IEnumerable<IndexEntry> indexEntries)
where TNode : class
{
if (node == null)
throw new ArgumentNullException("node");
relationships = relationships ?? Enumerable.Empty<IRelationshipAllowingParticipantNode<TNode>>();
indexEntries = indexEntries ?? Enumerable.Empty<IndexEntry>();
var validationContext = new ValidationContext(node, null, null);
Validator.ValidateObject(node, validationContext);
var calculatedRelationships = relationships
.Cast<Relationship>()
.Select(r => new
{
CalculatedDirection = Relationship.DetermineRelationshipDirection(typeof (TNode), r),
Relationship = r
})
.ToArray();
CheckRoot();
var batchSteps = new List<BatchStep>();
var createNodeStep = batchSteps.Add(Method.POST, "/node", node);
foreach (var relationship in calculatedRelationships)
{
var participants = new[]
{
string.Format("{{{0}}}", createNodeStep.Id),
string.Format("/node/{0}", relationship.Relationship.OtherNode.Id)
};
string sourceNode, targetNode;
switch (relationship.CalculatedDirection)
{
case RelationshipDirection.Outgoing:
sourceNode = participants[0];
targetNode = participants[1];
break;
case RelationshipDirection.Incoming:
sourceNode = participants[1];
targetNode = participants[0];
break;
default:
throw new NotSupportedException(string.Format(
"The specified relationship direction is not supported: {0}",
relationship.CalculatedDirection));
}
var relationshipTemplate = new RelationshipTemplate
{
To = targetNode,
Data = relationship.Relationship.Data,
Type = relationship.Relationship.RelationshipTypeKey
};
batchSteps.Add(Method.POST, sourceNode + "/relationships", relationshipTemplate);
}
var indexAddresses = indexEntries
.SelectMany(i => i
.KeyValues
.Select(k => BuildIndexAddress(i.Name, k.Key, k.Value)))
.Where(a => !string.IsNullOrEmpty(a));
foreach (var indexAddress in indexAddresses)
{
batchSteps.Add(Method.POST, indexAddress, "{0}");
}
var batchResponse = ExecuteBatch(batchSteps);
var createResponse = batchResponse[createNodeStep];
var nodeId = int.Parse(GetLastPathSegment(createResponse.Location));
var nodeReference = new NodeReference<TNode>(nodeId, this);
return nodeReference;
}
BatchResponse ExecuteBatch(List<BatchStep> batchSteps)
{
var request = new RestRequest(RootApiResponse.Batch, Method.POST)
{
RequestFormat = DataFormat.Json,
JsonSerializer = new CustomJsonSerializer { NullHandling = JsonSerializerNullValueHandling }
};
request.AddBody(batchSteps);
var response = CreateClient().Execute<BatchResponse>(request);
ValidateExpectedResponseCodes(response, HttpStatusCode.OK);
return response.Data;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment