Skip to content

Commit

Permalink
Delay-load message details
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Jul 6, 2024
1 parent fc041ab commit f1d5519
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 50 deletions.
34 changes: 23 additions & 11 deletions MarkMpn.Sql4Cds.Engine/MessageCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ public interface IMessageCache
public class MessageCache : IMessageCache
{
private readonly IOrganizationService _org;
private readonly Dictionary<string, Message> _cache;
private readonly Dictionary<string, bool> _entityMessages;
private readonly IAttributeMetadataCache _metadata;
private Dictionary<string, Message> _cache;
private Dictionary<string, bool> _entityMessages;

/// <summary>
/// Loads a list of messages from a specific instance
Expand All @@ -55,6 +56,14 @@ public class MessageCache : IMessageCache
public MessageCache(IOrganizationService org, IAttributeMetadataCache metadata)
{
_org = org;
_metadata = metadata;
}

private void Load()
{
if (_cache != null)
return;

_entityMessages = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);

// Load the requests and input parameters
Expand All @@ -68,7 +77,7 @@ public MessageCache(IOrganizationService org, IAttributeMetadataCache metadata)

var messageRequestFields = new Dictionary<string, List<MessageParameter>>();

foreach (var entity in RetrieveAll(org, requestQry, metadata))
foreach (var entity in RetrieveAll(requestQry))
{
var messageName = entity.GetAttributeValue<string>("name");

Expand Down Expand Up @@ -108,7 +117,7 @@ public MessageCache(IOrganizationService org, IAttributeMetadataCache metadata)

var messageResponseFields = new Dictionary<string, List<MessageParameter>>();

foreach (var entity in RetrieveAll(org, responseQry, metadata))
foreach (var entity in RetrieveAll(responseQry))
{
var messageName = (string)entity.GetAttributeValue<AliasedValue>("sdkmessagerequest.name").Value;

Expand Down Expand Up @@ -147,11 +156,11 @@ public MessageCache(IOrganizationService org, IAttributeMetadataCache metadata)
}, StringComparer.OrdinalIgnoreCase);
}

private IEnumerable<Entity> RetrieveAll(IOrganizationService org, QueryExpression qry, IAttributeMetadataCache metadata)
private IEnumerable<Entity> RetrieveAll(QueryExpression qry)
{
RemoveMissingAttributes(qry, metadata);
RemoveMissingAttributes(qry);

var results = org.RetrieveMultiple(qry);
var results = _org.RetrieveMultiple(qry);

foreach (var entity in results.Entities)
yield return entity;
Expand All @@ -168,21 +177,21 @@ private IEnumerable<Entity> RetrieveAll(IOrganizationService org, QueryExpressio
PagingCookie = results.PagingCookie
};

results = org.RetrieveMultiple(qry);
results = _org.RetrieveMultiple(qry);

foreach (var entity in results.Entities)
yield return entity;
}
}

private void RemoveMissingAttributes(QueryExpression qry, IAttributeMetadataCache metadata)
private void RemoveMissingAttributes(QueryExpression qry)
{
var logicalName = qry.EntityName;
var columnSet = qry.ColumnSet;
RemoveMissingAttributes(metadata[logicalName], columnSet);
RemoveMissingAttributes(_metadata[logicalName], columnSet);

foreach (var linkEntity in qry.LinkEntities)
RemoveMissingAttributes(linkEntity, metadata);
RemoveMissingAttributes(linkEntity, _metadata);
}

private void RemoveMissingAttributes(LinkEntity linkEntity, IAttributeMetadataCache metadata)
Expand Down Expand Up @@ -235,16 +244,19 @@ private Type GetType(string typeName)

public bool TryGetValue(string name, out Message message)
{
Load();
return _cache.TryGetValue(name, out message);
}

public IEnumerable<Message> GetAllMessages()
{
Load();
return _cache.Values;
}

public bool IsMessageAvailable(string entityLogicalName, string messageName)
{
Load();
var key = entityLogicalName + ":" + messageName;

if (_entityMessages.TryGetValue(key, out var value))
Expand Down
90 changes: 51 additions & 39 deletions MarkMpn.Sql4Cds.XTB/ObjectExplorer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,59 +202,71 @@ private void AddConnectionChildNodes(ConnectionDetail con, CrmServiceClient svc,
SetIcon(sprocNode, "Folder");
treeView.SelectedNode = conNode;

foreach (var msg in _dataSources[con.ConnectionName].MessageCache.GetAllMessages().OrderBy(tvf => tvf.Name))
{
if (msg.IsValidAsTableValuedFunction())
{
var n = tvfNode.Nodes.Add(msg.Name);
n.Tag = msg;
n.ImageIndex = 25;
n.SelectedImageIndex = 25;
n.ContextMenuStrip = functionContextMenuStrip;
}

if (msg.IsValidAsStoredProcedure())
{
var n = sprocNode.Nodes.Add(msg.Name);
n.Tag = msg;
n.ImageIndex = 26;
n.SelectedImageIndex = 26;
n.ContextMenuStrip = procedureContextMenuStrip;
}
}

AddVirtualChildNodes(tvfNode, parent => LoadMessages(parent, msg => msg.IsValidAsTableValuedFunction(), 25, functionContextMenuStrip));
AddVirtualChildNodes(sprocNode, parent => LoadMessages(parent, msg => msg.IsValidAsStoredProcedure(), 26, procedureContextMenuStrip));

if (new Uri(con.OrganizationServiceUrl).Host.EndsWith(".dynamics.com") &&
new Version(con.OrganizationVersion) >= new Version("9.1.0.17437"))
{
var tsqlNode = conNode.Nodes.Add("TDS Endpoint");
SetIcon(tsqlNode, "Loading");

if (TDSEndpoint.IsEnabled(svc))
_ = Handle;
_ = Task.Run(() =>
{
if (!String.IsNullOrEmpty(svc.CurrentAccessToken))
{
tsqlNode.ImageIndex = 21;
tsqlNode.SelectedImageIndex = 21;
}
else
var enabled = TDSEndpoint.IsEnabled(svc);

Invoke((Action)(() =>
{
tsqlNode.Text += " (Unavailable - OAuth authentication required)";
tsqlNode.ImageIndex = 22;
tsqlNode.SelectedImageIndex = 22;
}
}
else
{
tsqlNode.Text += " (Disabled)";
tsqlNode.ImageIndex = 20;
tsqlNode.SelectedImageIndex = 20;
}
if (enabled)
{
if (!String.IsNullOrEmpty(svc.CurrentAccessToken))
{
tsqlNode.ImageIndex = 21;
tsqlNode.SelectedImageIndex = 21;
}
else
{
tsqlNode.Text += " (Unavailable - OAuth authentication required)";
tsqlNode.ImageIndex = 22;
tsqlNode.SelectedImageIndex = 22;
}
}
else
{
tsqlNode.Text += " (Disabled)";
tsqlNode.ImageIndex = 20;
tsqlNode.SelectedImageIndex = 20;
}
}));
});

tsqlNode.ContextMenuStrip = tsqlContextMenuStrip;
}

conNode.Expand();
}

private TreeNode[] LoadMessages(TreeNode parent, Func<MarkMpn.Sql4Cds.Engine.Message,bool> predicate, int imageIndex, ContextMenuStrip menu)
{
var connection = GetService(parent);
var dataSource = _dataSources[connection.ConnectionName];

return dataSource.MessageCache.GetAllMessages()
.Where(msg => predicate(msg))
.OrderBy(msg => msg.Name)
.Select(msg =>
{
var node = new TreeNode(msg.Name);
node.Tag = msg;
node.ImageIndex = 25;
node.SelectedImageIndex = 25;
node.ContextMenuStrip = functionContextMenuStrip;
return node;
})
.ToArray();
}

private TreeNode[] LoadAttributes(TreeNode parent)
{
var logicalName = parent.Parent.Text;
Expand Down

0 comments on commit f1d5519

Please sign in to comment.