.NET query extensions

To create a .NET query extension,

  1. Create a Class Library project in Visual Studio.
  2. Add a reference to SkySparc.Platform.Plugin.dll in your OmniFi installation directory.
  3. Add a class to the project and let it extend the abstract class SkySparc.Platform.Plugin.NET.ACustomQueryExtension.
  4. Implement the abstract methods om ACustomQueryExtension.

Constructor

public class MyDotNetQueryExtensions : ACustomQueryExtension
{
    public MyDotNetQueryExtensions(string System, string UserId, string Password)
            : base(System, UserId, Password)
    {
    }
}

The constructor is required, and accepts the system, user, and password. The user and password are credentials mapped in the OmniFi Administration application.

GetParametersImpl

Extensions that require some form of user input can define parameters. The return value is a List<Parameter>.

protected override List<Plugin_Parameter> GetParametersImpl()
{
    return (new List<Plugin_Parameter>
    {
        new Plugin_Parameter
        {
            Type = Plugin_DataType.INTEGER,
            Name = "count",
            Description = "Count",
            Mandatory = true,
            DefaultValue = new Plugin_Value(11),
            Comment = "Number of records to generate"
        }
    });            
}

Default value

You can provide a default value in the form of a typed Plugin_Value . The Plugin_Value class ensures type safety in communication between OmniFi and the extension by including data type information.

Parameter domains

Domains allow parameter input to be restricted to a certain subset of discrete values. For example, a yield curve gap set could be described as a set of discrete values [O/N | SPOT | 1W | 1M | 3M | 1Y …]. To provide the user with a convenient drop-down you can use the parameter domain feature. To provide a domain for a parameter, set the Domain property on the Plugin_Parameter to a List<Plugin_DomainItems>.

protected override List<Plugin_Parameter> GetParametersImpl()
{
    return (new List<Plugin_Parameter>
    {
        new Plugin_Parameter
        {
            Type = Plugin_DataType.INTEGER,
            Name = "count",
            Description = "Count",
            Mandatory = true,
            DefaultValue = new Plugin_Value(11),
            Comment = "Number of records to generate",
            Domain = new List<Plugin_DomainItem>
            {
                new Plugin_DomainItem
                {
                    DisplayMember = "First",
                    ValueMember = new Plugin_Value(1)
                },
                new Plugin_DomainItem
                {
                    DisplayMember = "Second",
                    ValueMember = new Plugin_Value(2)
                },
            }
        }
    });            
}

GetMetadataImpl

The query output is defined by the Plugin_MetadataCollection returned by GetMetadataImpl(). The metadata can define any number of entities.
To define an output column, simply add it to a Plugin_MetadataCollection. By default, the metadata is added to the main data set, however you can specify which data set to add the column to directly in the Add method:

protected override Plugin_MetadataCollection GetMetadataImpl(List<Plugin_Argument> Parameters)
{
    Plugin_MetadataCollection metadata = new Plugin_MetadataCollection();
    metadata.Add(
        new Plugin_Metadata
        {
            Type = Plugin_DataType.INTEGER,
            Name = "int",
            Description = "Integer"
        });
    metadata.Add(
        new Plugin_Metadata
        {
            Type = Plugin_DataType.STRING,
            Name = "str",
            Description = "String"
        });
    metadata.Add(
        new Plugin_Metadata
        {
            Type = Plugin_DataType.INTEGER,
            Name = "int",
            Description = "Integer"
        }, "SubEntity");
    metadata.Add(
        new Plugin_Metadata
        {
            Type = Plugin_DataType.STRING,
            Name = "str",
            Description = "String"
        }, "SubEntity");
    return (metadata);
}

📘

Note that the configured parameters are provided as arguments to the GetMetadataImpl method. It is recommended to avoid depending metadata on parameter input values where possible, as it makes parameterizing any queries in OmniFi Reporting much more difficult, but depending on the data source, it may be necessary.

ExecuteQueryImpl

Query execution is implemented by the ExecuteQueryImpl()? method. It accepts parameter and requested schema input, and returns a Plugin_QueryResult`.

protected override Plugin_QueryResult ExecuteQueryImpl(List<Plugin_Argument> Parameters, Plugin_ColumnSchema ColumnSchema)
{
  var paramLookup = Parameters.ToDictionary((x) => x.ParameterName);
  Plugin_Argument countValue;
  if (!paramLookup.TryGetValue("count", out countValue))
    throw new ApplicationException("Count parameter not provided");

  int count = countValue.IntegerValue ?? 10;
  Plugin_QueryResult result = new Plugin_QueryResult(
    new Plugin_Dataset(
      new Plugin_DataColumn("int", "Integer", Enumerable.Range(0, count)
                            .Select((x) => (int?)x).ToArray()),
      new Plugin_DataColumn("str", "String", Enumerable.Range(0, count)
                            .Select((x) => $"number {x}").ToArray())
    ),
    new Plugin_Dataset("SubEntity",
                       new Plugin_DataColumn("int", "Integer", Enumerable.Range(0, count)
                                             .Select((x) => (int?)x).ToArray()),
                       new Plugin_DataColumn("str", "String", Enumerable.Range(0, count)
                                             .Select((x) => $"number {x}").ToArray())
                      )
  );

  return (result);
}

Input parameters

Input parameters are provided as a list of Plugin_Argument. The ParameterName property of Plugin_Argument is unique, and can be used to create a dictionary:

var paramLookup = Parameters.ToDictionary((x) => x.ParameterName);

Schema

Return value