PLATFORMS SOLUTIONS BLOGS CONTACT

/sdk/handlerdecorators




Handler Decorators


You can create a handler with a decorator (the @ symbol) that allows you to obtain the name of a remote resource (such as a SalesForce table name) or a configuration setting that should be used instead of the default one.

Handler decorators allow you to call a handler and specifying an argument value directly as part of the table name. In this example we are calling the GetListItems (using the list tablename of the handler), and asking for the USStates SharePoint list:

SELECT * FROM SharePoint.list@USStates

Handler Decorators are most useful for SELECT, INSERT, DELETE and UPDATE operations. They are supported with LinkedServer calls as long as the columns returned are known at design time.


Uses

There are two primary scenarios in which decorators are useful:

  • Resource Names:
    In some cases, you may need to build an adapter for which the list of remote resources (or objects/tables) is not known at design time. For example it is not possible to known ahead of time the list of SharePoint lists that a customer has created when building the SharePoint adpater.

    Using the decorator in this way is not strictly necessary, since the name of the remote object could simply be passed in as an argument to the handler. Using the decorator simply makes it easier to call the handler:

    SELECT * FROM SharePoint.list@USStates

  • Dynamic Configurations:
    In some cases you may want your adapter to work with any number of configuration settings without having to use the _configUse command (which allows you to switch the current configuration setting). This makes it easy to use different settings without logging off and back on.

    SELECT * FROM CSV.data@config2

You can use a decorator the way you want; the above two use cases are the most commonly used so far, but you can leverage this mechanism in any way you deem useful.


Example: Resource Name

In this example the handler decorator is used to specify a remote SharePoint list name as part of the table name. The decorator is mapped to the listName argument of the handler, so that you do not have to specify it as part of a WHERE clause.

RegisterHandler("GetListItems,List@",
    HandlerOptions.Select | HandlerOptions.NoExec,
    "Get items from an existing SharePoint list (or view)",
    new[] { "SELECT * FROM SharePoint.list@mylist1" },
    GetListItems,
    new [] { "viewName|The name of the view to use.||@" } 
    );

The viewName argument is automatically set based to USStates in the above command; it is considered a required argument.

To specify a space within the name of the decorator, use the square brackets:

SELECT * FROM SharePoint.[list@US States List]



Here is a sample GetListItems method implementation that accesses the decorator:

private EventResult GetData(object sender, ExecEventArgs e)
{
    EventResult result = new EventResult(e);

    // Extract the decorator if found:
    // 
    // select * from SharePoint.list    
    // select * from SharePoint.[list@list1]
    // 

    string viewName = null;
    
    // get the decorator 
    // use TryGetArg for centralized code if you are not sure the handler has a given argument
    e.TryGetArg("viewName", out viewName, null);

    // is viewName null? if so, the viewName was not specified... throw an error    
    if (viewName == null)
    {
        result.ResultCode = 50000;
        result.ResultMsg = "The viewName argument is required";
    }
    else
    {
        // DO THE WORK HERE...
    }

    return result;
}


Example: Dynamic Configuration

In this example the handler decorator is used to specify a configuration setting other than the default one. This is useful for adapters that define a schema for a remote data set as part of its configuration settings.

RegisterHandler("GetData,Data@",
    HandlerOptions.Select,
    "Get data from a no-sql data source",
    new[] { 
        "SELECT * FROM MyAdapter.data",
        "SELECT * FROM MyAdapter.data@config1"
        },
    GetData,
    new [] { "definitionName|The name of the config setting to use.||@" } 
    );



You may also use the decorator to pass additional arguments separated by a column for example. For example this call contains both a configuration setting name (config1) and a sub-specifier (table1):

select * from adapter.[list@config1,table1]



A sample implementation code of the GetData method is presented below, with support for a sub-specifier.

private EventResult GetData(object sender, ExecEventArgs e)
{
    EventResult result = new EventResult(e);

    // Extract config name and sub-specifier if found
    // 
    // select * from adapter.list
    // select * from adapter.[list@config1]
    // select * from adapter.[list@config1,table1]
    // 

    string definitionName = null;
    string subSpecifier = null;

    // get the config name to load
    // use TryGetArg for centralized code if you are not sure the handler has a given argument
    e.TryGetArg("definitionName", out definitionName, e.Settings.ConfigName);

    string thisDefinition = definitionName;	// the config name provided, or the default config name

    // Is a specifier provided with a comma separator? 
    if (definitionName.Contains(','))
    {
      thisDefinition = definitionName.Split(',')[0]; // config1
      subSpecifier = definitionName.Split(',')[1];   // table1
    }

    // Load the specified settings (or the default setting if none provided)
    Config.SettingsCollection settings =
      (definitionName != null) ?
      e.AllSettings[thisDefinition] :
      e.Settings;


    // get a config setting called "url"
    string url = settings["url"].ToString();

    // DO THE WORK HERE...
    
    return result;
}







601 21st St Suite 300
Vero Beach, FL 32960
United States

(561) 921-8669
info@enzounified.com
terms of service
privacy policy

PLATFORM

ENZO SERVER
ENZO DATAZEN

SOLUTIONS

SOLUTIONS OVERVIEW
INTEGRATION
SaaS
CLOUD ANALYTICS

RESOURCES

DOWNLOAD
BLOGS & VIDEOS
IN THE NEWS
ENZO ADAPTERS
ONLINE DOCUMENTATION
TCO CALCULATOR

COMPANY

LEADERSHIP TEAM
PARTNERS


© 2023 - Enzo Unified