Main Content

Create Custom Queries

With the CI/CD Automation for Simulink Check support package, you can define a development and verification process for your team by using a process model. You can use queries to find artifacts relevant to your tasks and processes. The support package contains several built-in queries that you can reconfigure and use to find artifacts in your project, but if you need to perform other actions or always want to use a reconfigured version of a built-in query, you can create and add custom queries to your process model.

To find artifacts in your project, you can use the built-in queries that ship with the support package or you can create your own custom queries. Use the built-in queries where possible. If your use case requires custom queries, use the following steps to create a custom query. Note that to reconfigure the functionality of a built-in task, your custom queries can inherit from a built-in query.

After you create a custom query, you can use that query as an input query for a task to modify or filter the task inputs.

Choose Superclass for Custom Query

There are two ways to define custom queries:

  • Inherit from a built-in query — Use this approach when there is a built-in query that is similar to the custom query that you want to create. When you inherit from a built-in query, like padv.builtin.query.FindArtifacts, your custom query inherits the functionality of that query, but then you can override the properties and methods of the class to fit your needs.

  • Inherit from padv.Query — Use this approach if your custom query needs to find artifacts in a way that is not similar to a built-in query. padv.Query is the base class of the built-in queries, so you must completely define the functionality of the query.

Define and Use Custom Query in Process

  1. Create a new MATLAB® class in your project.

    Tip

    Namespaces can help you organize the class definition files for your custom queries. In the root of your project, create a folder +processLibrary with a subfolder +query and save your class in that folder.

    To share your custom queries across multiple process models in different projects, consider creating a referenced project that contains your folders and class definition files. Your main projects can then use the referenced project as a shared process library.

  2. Use one of these approaches to define your custom query:

    • If you are inheriting from a built-in query, you can replace the contents of your class file with this example code:

      classdef MyCustomQuery<padv.builtin.query.FindArtifacts
          % query definition goes in this class
          % by default, this query finds all artifacts in the project
          methods
              function obj = MyCustomQuery(NameValueArgs)
                  arguments
                      NameValueArgs.Name = "MyCustomQuery";
                  end
              end
          end
      end
      This example query inherits from the built-in query padv.builtin.query.FindArtifacts, but you can change that line of code to inherit from another built-in query. Use the properties of the query to specify which sets of artifacts you want the query to return.

      Note

      If you want to override the run method for a built-in query, check which input arguments the run method for the built-in query accepts.

      For information, see Customize Your Process Model.

    • If you are inheriting from padv.Query, you can replace the contents of your class file with this example code:

      classdef MyCustomQuery < padv.Query
      
          methods
              function obj = MyCustomQuery(NameValueArgs)
                  obj@padv.Query("MyCustomQuery");
              end
      
              function artifacts = run(obj,~)
                  artifacts = padv.Artifact.empty;
                      % Core functionality of the query goes here
                  % artifacts = padv.Artifact(artifactType,...
                      % padv.util.ArtifactAddress(fullfile(fileparts));
                  
              end
          end
      end
      A query must have:

      • a unique name, specified using the Name property

      • a run function that returns either a padv.Artifact object or array of padv.Artifact objects. For more information, see padv.Artifact and Example Custom Queries.

  3. You can test your custom query in the MATLAB Command Window executing the run function. For example, for a query MyCustomQuery saved in the namespace processLibrary.query:

    run(processLibrary.query.MyCustomQuery)
    Note that your project needs to be open for the query to find artifacts.

  4. You can use your custom query in your process model. For example, you can control which artifacts a task iterates over by using your custom query as the iteration query for a task:

    function processmodel(pm)
        % Defines the project's processmodel
    
        arguments
            pm padv.ProcessModel
        end
    
        t = addTask(pm,"MyCustomTask",...
            IterationQuery = processLibrary.query.MyCustomQuery);
    
    end
    This example assumes that you saved your class file in the +query folder inside the +processLibrary folder.

  5. You can confirm which artifacts your task iterates over by opening Process Advisor. In the MATLAB Command Window, enter:

    processAdvisorWindow
    The artifacts that the task iterates over appear under the task name in the Tasks column.

    Task iterations under "MyCustomTask" in Tasks column

Example Custom Queries

Run Task on Data Dictionaries in Project

Suppose you want to find each of the data dictionaries in your project. There are no built-in queries that perform this functionality by default, but there is a built-in query padv.builtin.query.FindArtifacts that can find artifacts that meet certain search criteria. Effectively you can create your own version of the built-in query, but specialized to only find data dictionaries. You can create a class-based, custom query that inherits from padv.builtin.query.FindArtifacts and specifies the ArtifactType argument as a Simulink® data dictionary.

classdef FindSLDDs<padv.builtin.query.FindArtifacts
    %FindSLDDs This query is like FindArtifacts,
    % but only returns data dictionaries.
    methods
        function obj = FindSLDDs(NameValueArgs)
            arguments
                NameValueArgs.ArtifactType string = "sl_data_dictionary_file";
                NameValueArgs.Name = "FindSLDDs";
            end
            obj.ArtifactType = NameValueArgs.ArtifactType;
        end
    end
end

The example class FindSLDDs inherits its properties and run function from the built-in query padv.builtin.query.FindArtifacts, but specifies a unique Name and ArtifactType. The ArtifactType is specified as sl_data_dictionary_file because that is the artifact type associated with Simulink data dictionary files. For a list of valid artifact types, see padv.builtin.query.FindArtifacts.

You can have a task run once for each data dictionary in your project by using the custom query as the iteration query for the task.

function processmodel(pm)
    % Defines the project's processmodel

    arguments
        pm padv.ProcessModel
    end

    t = addTask(pm,"MyCustomTask",...
        IterationQuery = processLibrary.query.FindSLDDs);

end

Tasks column showing data dictionaries under "MyCustomTask"

Sort Artifacts in Specific Order

By default, queries sort artifacts alphabetically by the artifact address. If you want your query to sort artifacts in a different order, you can override the internal sortArtifacts method in a subclass that defines a custom sort behavior. For example:

classdef FindFileSorted < padv.builtin.query.FindArtifacts    
    methods
        function obj = FindFileSorted(options)
            arguments
                options.ArtifactType string
                options.IncludeLabel string
                options.ExcludeLabel string
                options.IncludePath string
                options.ExcludePath string
                options.InProject boolean
                options.FilterSubFileArtifacts boolean
            end
            fwdoptions = namedargs2cell(options);
            obj@padv.builtin.query.FindArtifacts(fwdoptions{:});
        end
    end
    methods(Access = protected)
        % Overload the default sort artifacts logic, in this case
        % Sorting artifacts based upon their string length rather than
        % Alphabetically
        function sortedArtifacts = sortArtifacts(~, artifacts)
            if isempty(artifacts)
                sortedArtifacts = artifacts;
                return;
            end
            namesToSort = arrayfun(@(art) art.ArtifactAddress.getFileAddress,artifacts);
            [~,idx] = sort(strlength(namesToSort));
            sortedArtifacts = artifacts(idx);
        end
    end
end

Note

If you override sortArtifacts, make sure that your implementation only changes the order of the artifacts, not the data type or structure. Do not use sortArtifacts to add or remove artifacts from the query results.

See Also

| | | |

Related Topics