public QueryResponse QueryMap(IGlymaSession glymaSession, Guid domainId, Guid nodeId, int maxDepth, bool isFullDomainSearch, EdgeConditions edgeConditions, FilterConditions filterConditions, int objectIndex, bool isCompressed)
{
if (!isCompressed)
{
TransactionalMappingToolServiceCommonBase.SoftObjectLimit = 3000;
TransactionalMappingToolServiceCommonBase.HardObjectLimit = 4000;
}
else
{
TransactionalMappingToolServiceCommonBase.SoftObjectLimit = 5500;
TransactionalMappingToolServiceCommonBase.HardObjectLimit = 6500;
}
using (IDbConnectionAbstraction mapDbConnection = glymaSession.ConnectionFactory.CreateMapDbConnection())
{
SqlCommand queryMapCommand = new SqlCommand("QueryMap", mapDbConnection.Connection);
queryMapCommand.CommandType = CommandType.StoredProcedure;
queryMapCommand.Parameters.Add(new SqlParameter("@DomainId", domainId));
queryMapCommand.Parameters.Add(new SqlParameter("@NodeId", nodeId));
queryMapCommand.Parameters.Add(new SqlParameter("@Depth", maxDepth));
queryMapCommand.Parameters.Add(new SqlParameter("@FullDomain", isFullDomainSearch));
mapDbConnection.Open();
SqlDataReader queryMapResults = queryMapCommand.ExecuteReader();
QueryResponse queryResponse = new QueryResponse();
List<Node>[] orderedNodes = new List<Node>[maxDepth + 1];
do
{
while (queryMapResults.Read())
{
if (queryMapResults.GetSchemaTable().Select("ColumnName = 'Level'").Length > 0)
{
Node node = new Node();
node.LoadElement(queryMapResults);
List<Node> nodes;
if (orderedNodes[node.Depth] != null)
{
nodes = orderedNodes[node.Depth];
}
else
{
nodes = new List<Node>();
orderedNodes[node.Depth] = nodes;
}
nodes.Add(node);
queryResponse.AddNode(node);
}
else if (queryMapResults.GetSchemaTable().Select("ColumnName = 'MetadataId'").Length > 0)
{
Metadata metadata = new Metadata();
metadata.LoadElement(queryMapResults);
queryResponse.AddMetadata(metadata);
}
else if (queryMapResults.GetSchemaTable().Select("ColumnName = 'DescriptorUid'").Length > 0)
{
Descriptor descriptor = new Descriptor();
descriptor.LoadElement(queryMapResults);
queryResponse.AddDescriptor(descriptor);
}
else if (queryMapResults.GetSchemaTable().Select("ColumnName = 'RelationshipUid'").Length > 0)
{
Relationship relationship = new Relationship();
relationship.LoadElement(queryMapResults);
queryResponse.AddRelationship(relationship);
}
}
}
while (queryMapResults.NextResult());
mapDbConnection.Close();
try
{
mapDbConnection.Open();
AuditLogItem logItem = new AuditLogItem(mapDbConnection.Connection);
logItem.OperationName = "QueryMap";
//logItem.CallingUrl = callingUrl;
logItem.DomainUid = domainId;
logItem.NodeUid = nodeId;
logItem.RootMapUid = null;
logItem.MaxDepth = maxDepth;
logItem.ObjectIndex = objectIndex;
logItem.EdgeConditions = null;
logItem.FilterConditions = null;
logItem.SearchConditions = null;
logItem.PageNumber = null;
logItem.PageSize = null;
logItem.Commit();
mapDbConnection.Close();
}
catch
{
/// Don't do anything. This is here because audit logging is a very low importance task and we don't want it potentially killing the more important tasks at hand.
}
if (!queryResponse.Nodes.ContainsKey(nodeId))
{
queryResponse.ErrorId = 1;
queryResponse.ErrorMessage = "Provided node ID context doesn't exist";
return queryResponse;
}
queryResponse.AttachElements();
queryResponse.NodeContext = queryResponse.Nodes[nodeId];
if (maxDepth > 0 && edgeConditions != null && edgeConditions.EdgeCondition != null)
{
List<Guid> nodesToRemove = new List<Guid>();
List<Guid> relationshipsToRemove = new List<Guid>();
List<Guid> boundaryNodes = new List<Guid>();
List<Guid> boundaryRelationships = new List<Guid>();
for (int i = 1; i <= maxDepth; i++)
{
List<Node> nodes = orderedNodes[i];
foreach (Node node in nodes)
{
bool isBoundaryNode = false;
bool isBoundaryRelationship = false;
bool isNodeIncluded = true;
bool isRelationshipIncluded = true;
Relationship connectingRelationship = queryResponse.Relationships[node.ConnectingRelationship];
if (boundaryNodes.Contains(node.Origin))
{
isBoundaryNode = true;
isBoundaryRelationship = true;
isNodeIncluded = false;
isRelationshipIncluded = false;
}
else
{
EdgeResult relationshipEvalResult = edgeConditions.EdgeCondition.EvaluateCondition(connectingRelationship);
if (relationshipEvalResult.IsEdge.HasValue && relationshipEvalResult.IsEdge.Value)
{
// THis means the relationship was evaluated to be a boundary edge.
isBoundaryRelationship = true;
isRelationshipIncluded = relationshipEvalResult.IsIncluded;
}
EdgeResult nodeEvalResult = edgeConditions.EdgeCondition.EvaluateCondition(node);
if (nodeEvalResult.IsEdge.HasValue && nodeEvalResult.IsEdge.Value)
{
// This means the node was evaluated to be a boundary edge.
isBoundaryNode = true;
isNodeIncluded = nodeEvalResult.IsIncluded;
// The inclusion value for the node trumps the relationship value as the relationship is dependent on the node existing anyway.
isRelationshipIncluded = isNodeIncluded;
}
else if (isBoundaryRelationship)
{
// If the relationship was discovered to be a boundary then this node will be a boundary edge too.
isBoundaryNode = true;
isNodeIncluded = isRelationshipIncluded;
}
}
if (isBoundaryNode)
{
boundaryNodes.Add(node.NodeUid);
}
if (isBoundaryRelationship)
{
boundaryRelationships.Add(connectingRelationship.RelationshipUid);
}
if (!isNodeIncluded)
{
nodesToRemove.Add(node.NodeUid);
}
if (!isRelationshipIncluded)
{
relationshipsToRemove.Add(connectingRelationship.RelationshipUid);
}
}
}
foreach (Guid nodeIdToRemove in nodesToRemove)
{
queryResponse.Nodes.Remove(nodeIdToRemove);
}
foreach (Guid relationshipIdToRemove in relationshipsToRemove)
{
queryResponse.Relationships.Remove(relationshipIdToRemove);
}
}
int totalObjects = queryResponse.CountObjects();
queryResponse.Domain = new Domain();
queryResponse.Domain.DomainUid = domainId;
if (totalObjects > TransactionalMappingToolServiceCommonBase.HardObjectLimit || objectIndex > 0)
{
return queryResponse.GetPage(objectIndex);
}
return queryResponse;
}
}