Custom Fields
By default, the table and view schemas describe the column behavior of only system fields. To access custom fields for Issues, as well as system fields, you can set IncludeCustomFields in the connection string. You can also extend the schemas to configure access to custom fields. The following sections show how to surface different types of custom fields.
Accessing Custom Fields
Set the IncludeCustomFields property to True to expose access to all custom fields.
Please note that there is a performance overhead associated with exposing all custom field. If this represents an obstacle in realizing the desired use case, granular control of the exposed metadata is possible using custom schema files.
Extending Schemas
Custom schema improve driver performance by enabling connections to a subset of all available custom field metadata.
Table and view schemas are defined in .rsd configuration files with a simple format that makes them easy to customize. You can call CreateSchema to save a schema file; for example, with the IncludeCustomFields connection property set. Or, adapt the example Issues schema, which you can find at the end of this section.
To connect to custom schemas, set the Location property to the folder containing the schema files. The schemas included with the driver are located in the db subfolder of the installation folder.
Defining Custom Field Columns
Columns are defined in the api:info section of the schema file. You can use any of the existing column definitions as a template for creating custom field columns. All column definitions have at least a name and data type:
- name
- xs:type
Custom fields require the following additional parameters:
- other:urlname: This field must be specified to return the column in "SELECT MyCustomField" queries. This field has the format MyCustomFieldName_MyCustomFieldId. The Id of the custom field can be obtained by querying the Fields table.
- other:relativexpath: This field must be specified to return the column in "SELECT *" queries. This field is an XPath that maps to the column value in the JSON response from Jira. The XPaths are relative to a repeat element that separates the JSON response into rows.
See the following sections for examples of specifying the XPath to the value you want for different types of columns.
Adding Simple-Type Custom Field Columns
The following example is a column definition for a custom field with a simple data type.
<attr name="MyCustomField" xs:type="string" other:relativexpath="customfield_10002" other:urlname="customfield_10002" desc="My custom field." />
Adding Object-Type Custom Field Columns
Below is the JSON representation of an object-type custom field:
"customfield_10001" : { "name" : "New name", "description" : "desc" }
The following example models the fields of the object-type custom field as columns.
<attr name="MyCustomFieldName" xs:type="string" other:relativexpath="name" other:urlname="customfield_10001" desc="My custom field." />
<attr name="MyCustomFieldDesc" xs:type="string" other:relativexpath="description" other:urlname="customfield_10001" desc="My custom field." />
Adding Array-Type Custom Fields
To surface array-type custom fields, you will also need to pass several additional inputs to the processing operations of the driver, in addition to the relativexpath and urlname properties described in the Defining Custom Fields section. Use the api:set keyword to define the following variables.
- XPath: Set this to "/json/issues" for compatibility with future versions of the Jira API. The XPath value is relative to the RepeatElement and SubRepeatElement values, described below.
- SubRepeatElement: Set this to "/json/issues/fields/your-custom-field-name_your-custom-field-id". Query the Fields table to obtain the Id of a custom field.
- RepeatElement: Set this to a column that is in every custom field row.
- IsSearch: Set this to "true".
- JiraTableCode: Set this to the name of the custom field plus the Id of the custom field, which can be retrieved from the Fields table. Separate the custom field name and custom field Id with an underscore.
Below is an example of an array-type custom field in the raw JSON response of a query to the Issues table. You can use the logging facilities of the driver to obtain the JSON response: Set Logfile to a location that the driver can write to and set Verbosity to 3.
{ "expand": "schema,names", "startAt": 0, "maxResults": 50, "total": 43, "issues" : [{ "expand" : "operations,versionedRepresentations,editmeta,changelog,renderedFields", "id" : "10042", "self" : "https://cdatadev.atlassian.net/rest/api/2/issue/10042", "key" : "TEST-43", "fields" : { "customfield_1002" : [{ "description" : "MyCF", "id" : "10001", "created" : "2016-22-08", "author" : { "name" : "admin", "key" : "admin", } }, { "description" : "MyCF2", "id" : "10002", "created" : "2016-22-08", "author" : { "name" : "admin", "key" : "admin", } }, ... ] } ... ] }Below is an example schema that surfaces the nested values in the array-type custom field.
<api:script xmlns:api="vhttp://apiscript.com/ns?v1">
<api:info title="CustomFieldSample" description="Custom field example.">
<attr name="IssueId" xs:type="string" other:absolutexpath="/json/issues/id" desc="The Id of the issue." other:urlname="id" references="Issues.Id" />
<attr name="IssueKey" xs:type="string" other:absolutexpath="/json/issues/key" desc="The key of the issue." other:urlname="key" references="Issues.Key" />
<attr name="CfId" xs:type="string" other:relativexpath="id" desc="The Id of the custom field." />
<attr name="CfDescription" xs:type="string" other:relativexpath="description" desc="The description of the custom field." />
<attr name="CfCreatedDate" xs:type="datetime" other:relativexpath="created" desc="The date the custom field was created." />
<input name="JQL" description="JQL(Jira Query Language) allows you to build structured queries." />
<input name="Rows@Next" description="This is used to page through multiple pages of results and should not be set manually." />
</api:info>
<!--XPath should stay the same. Do not change this. -->
<api:set attr="XPath" value="/json/issues" />
<!--Subrepeat elment XPath. Set this based on the custom field structure. -->
<api:set attr="SubRepeatElement" value="/json/issues/fields/customfield_10020"/>
<!--Choose a column that is in every custom field row. -->
<api:set attr="RepeatElement" value="CfId" />
<!--Required. Do not change this. -->
<api:set attr="IsSearch" value="true" />
<!--Set this to the name of the custom field plus the Id, separated by an underscore. -->
<api:set attr="JiraTableCode" value="customfield_10020" />
<api:script method="GET">
<api:call op="jiraadoSelect" output="out">
<api:push item="out" />
</api:call>
</api:script>
</api:script>
Note that the table also includes columns outside the custom field. You can use the absolutexpath column property to add these. This optional field can be used to specify an absolute XPath not relative to the repeat element.
Complete Issues Schema
Below is an example schema for the Issues table.
<api:script xmlns:api="http://apiscript.com/ns?v1">
<api:info title="Issues" description="" other:isissues="true">
<attr name="Id" xs:type="int" key="true" readonly="true" description="The Id of the issue." other:urlname="id" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="id"/>
<attr name="Key" xs:type="string" columnsize="2000" readonly="true" description="The key of the issue." other:urlname="key" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="key"/>
<attr name="IssueTypeId" xs:type="string" columnsize="2000" readonly="false" description="The issue type Id." other:urlname="issuetype" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/issuetype/id"/>
<attr name="IssueTypeName" xs:type="string" columnsize="2000" readonly="true" description="The issue type name." other:urlname="issuetype" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/issuetype/name"/>
<attr name="ProjectId" xs:type="string" columnsize="2000" readonly="false" description="The project Id of the issue." other:urlname="project" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/project/id"/>
<attr name="ProjectName" xs:type="string" columnsize="2000" readonly="true" description="The project name of the issue." other:urlname="project" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/project/name"/>
<attr name="ProjectKey" xs:type="string" columnsize="2000" readonly="false" description="The project key of the issue." other:urlname="project" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/project/key"/>
<attr name="ResolutionId" xs:type="string" columnsize="2000" readonly="false" description="The resolution Id of the issue." other:urlname="resolution" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/resolution/id"/>
<attr name="ResolutionName" xs:type="string" columnsize="2000" readonly="false" description="The resolution name of the issue." other:urlname="resolution" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/resolution/name"/>
<attr name="ResolutionDescription" xs:type="string" columnsize="2000" readonly="true" description="The resolution description of the issue." other:urlname="resolution" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/resolution/description"/>
<attr name="ResolutionDate" xs:type="datetime" readonly="false" description="The resolution date of the issue." other:urlname="resolutiondate" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/resolutiondate"/>
<attr name="Workratio" xs:type="long" readonly="false" description="The work ratio of the issue." other:urlname="workratio" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/workratio"/>
<attr name="LastViewed" xs:type="datetime" readonly="true" description="The last time that the issue was viewed." other:urlname="lastViewed" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/lastViewed"/>
<attr name="WatchCount" xs:type="int" readonly="true" description="The number of watches of the issue." other:urlname="watches" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/watches/watchCount"/>
<attr name="IsWatching" xs:type="bool" readonly="false" description="Whether the currently authenticated user is watching the issue." other:urlname="watches" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/watches/isWatching"/>
<attr name="Created" xs:type="datetime" readonly="true" description="The creation date of the issue." other:urlname="created" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/created"/>
<attr name="PriorityId" xs:type="string" columnsize="2000" readonly="false" description="The priority Id of the issue." other:urlname="priority" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/priority/id"/>
<attr name="PriorityName" xs:type="string" columnsize="2000" readonly="true" description="The priority name of the issue." other:urlname="priority" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/priority/name"/>
<attr name="TimeSpentSeconds" xs:type="long" readonly="true" description="The time spent in seconds on the issue." other:urlname="timespent" other:aggregate="" other:supportedoperators="" other:fieldname="timetracking" other:insertfield="" other:relativexpath="fields/timetracking/timeSpentSeconds"/>
<attr name="TimeSpent" xs:type="string" columnsize="2000" readonly="true" description="The time spent on the issue." other:urlname="timespent" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="timetracking" other:insertfield="" other:relativexpath="fields/timetracking/timeSpent"/>
<attr name="TimeRemainingEstimateSeconds" xs:type="long" readonly="true" description="The time estimate in seconds of the issue." other:urlname="timeestimate" other:aggregate="" other:supportedoperators="" other:fieldname="timetracking" other:insertfield="" other:relativexpath="fields/timetracking/remainingEstimateSeconds"/>
<attr name="TimeRemainingEstimate" xs:type="string" columnsize="2000" readonly="false" description="The time estimate of the issue." other:urlname="timeestimate" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="timetracking" other:insertfield="" other:relativexpath="fields/timetracking/remainingEstimate"/>
<attr name="TimeOriginalEstimateSeconds" xs:type="long" readonly="true" description="The original time estimate in seconds of the issue." other:urlname="timeoriginalestimate" other:aggregate="" other:supportedoperators="" other:fieldname="timetracking" other:insertfield="" other:relativexpath="fields/timetracking/originalEstimateSeconds"/>
<attr name="TimeOriginalEstimate" xs:type="string" columnsize="2000" readonly="false" description="The original time estimate of the issue." other:urlname="timeoriginalestimate" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="timetracking" other:insertfield="" other:relativexpath="fields/timetracking/originalEstimate"/>
<attr name="AggregateTimeSpent" xs:type="long" readonly="true" description="The aggregate time spent of the issue." other:urlname="aggregatetimespent" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/aggregatetimespent"/>
<attr name="AggregateTimeOriginalEstimate" xs:type="long" readonly="true" description="The original aggregate time estimate of the issue." other:urlname="aggregatetimeoriginalestimate" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/aggregatetimeoriginalestimate"/>
<attr name="AggregateTimeEstimate" xs:type="long" readonly="true" description="The aggregate time estimate of the issue." other:urlname="aggregatetimeestimate" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/aggregatetimeestimate"/>
<attr name="AssigneeDisplayName" xs:type="string" columnsize="2000" readonly="true" description="Assignee display name." other:urlname="assignee" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/assignee/displayName"/>
<attr name="AssigneeKey" xs:type="string" columnsize="2000" readonly="false" description="The assignee key of the issue." other:urlname="assignee" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/assignee/key"/>
<attr name="AssigneeName" xs:type="string" columnsize="2000" readonly="true" description="The assignee name of the issue." other:urlname="assignee" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/assignee/name"/>
<attr name="AssigneeEmail" xs:type="string" columnsize="2000" readonly="true" description="The assignee email of the issue." other:urlname="assignee" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/assignee/emailAddress"/>
<attr name="Updated" xs:type="datetime" readonly="true" description="The updated date of the issue." other:urlname="updated" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/updated"/>
<attr name="StatusId" xs:type="string" columnsize="2000" readonly="false" description="The status Id of the issue." other:urlname="status" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/status/id"/>
<attr name="StatusName" xs:type="string" columnsize="2000" readonly="true" description="The status name of the issue." other:urlname="status" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/status/name"/>
<attr name="Description" xs:type="string" columnsize="2000" readonly="false" description="The description of the issue." other:urlname="description" other:aggregate="" other:supportedoperators="LIKE,NOT LIKE,IS,IS NOT" other:fieldname="" other:insertfield="" other:relativexpath="fields/description"/>
<attr name="Summary" xs:type="string" columnsize="2000" readonly="false" description="The summary of the issue." other:urlname="summary" other:aggregate="" other:supportedoperators="LIKE,NOT LIKE,IS,IS NOT" other:fieldname="" other:insertfield="" other:relativexpath="fields/summary"/>
<attr name="CreatorDisplayName" xs:type="string" columnsize="2000" readonly="true" description="Issue creator display name." other:urlname="creator" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/creator/displayName"/>
<attr name="CreatorName" xs:type="string" columnsize="2000" readonly="true" description="The creator name of the issue." other:urlname="creator" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/creator/name"/>
<attr name="CreatorKey" xs:type="string" columnsize="2000" readonly="true" description="The creator key of the issue." other:urlname="creator" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/creator/key"/>
<attr name="CreatorEmail" xs:type="string" columnsize="2000" readonly="true" description="The creator email of the issue." other:urlname="creator" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/creator/emailAddress"/>
<attr name="ReporterDisplayName" xs:type="string" columnsize="2000" readonly="true" description="Issue reporter display name." other:urlname="reporter" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/reporter/displayName"/>
<attr name="ReporterName" xs:type="string" columnsize="2000" readonly="true" description="The reporter name of the issue." other:urlname="reporter" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/reporter/name"/>
<attr name="ReporterKey" xs:type="string" columnsize="2000" readonly="true" description="The reporter key of the issue." other:urlname="reporter" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/reporter/key"/>
<attr name="ReporterEmail" xs:type="string" columnsize="2000" readonly="true" description="The reporter email of the issue." other:urlname="reporter" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/reporter/emailAddress"/>
<attr name="Environment" xs:type="string" columnsize="2000" readonly="true" description="Search for issues where the environment contains particular text." other:urlname="reporter" other:aggregate="" other:supportedoperators="LIKE,NOT LIKE,IS,IS NOT" other:fieldname="" other:insertfield="" other:relativexpath="fields/environment"/>
<attr name="SecurityLevel" xs:type="string" columnsize="2000" readonly="true" description="Search for issues with a particular security level." other:urlname="reporter" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/security/name"/>
<attr name="AggregateProgress" xs:type="long" readonly="true" description="The aggregate progress of the issue." other:urlname="aggregateprogress" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/aggregateprogress/progress"/>
<attr name="TotalProgress" xs:type="long" readonly="true" description="The aggregate total progress of the issue." other:urlname="aggregateprogress" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/aggregateprogress/total"/>
<attr name="Votes" xs:type="int" readonly="true" description="Votes of the issue." other:urlname="votes" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/votes/votes"/>
<attr name="HasVotes" xs:type="bool" readonly="true" description="The vote status of the issue." other:urlname="votes" other:aggregate="" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/votes/hasVoted"/>
<attr name="DueDate" xs:type="datetime" readonly="false" description="The due date of the issue." other:urlname="duedate" other:aggregate="" other:supportedoperators="=,!=,>,>=,<,<=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/duedate"/>
<attr name="Labels" xs:type="string" columnsize="2000" readonly="false" description="The labels of an issue" other:urlname="labels" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN" other:fieldname="" other:insertfield="" other:relativexpath="fields/labels"/>
<attr name="FixVersionsAggregate" xs:type="string" columnsize="2000" readonly="false" description="The fix versions of the issue" other:urlname="fixVersions" other:aggregate="/json/issues/fields/fixVersions" other:supportedoperators="" other:fieldname="" other:insertfield="fixVersions" other:relativexpath="fields/fixVersions"/>
<attr name="ComponentsAggregate" xs:type="string" columnsize="2000" readonly="false" description="Search for issues that belong to a particular component of a project. You can search by component name or component Id." other:urlname="components" other:aggregate="/json/issues/fields/components" other:supportedoperators="" other:fieldname="" other:insertfield="" other:relativexpath="fields/components"/>
<input name="JQL" xs:type="string" columnsize="2000" description="JQL (Jira Query Language) allows you to build structured queries." other:supportedoperators="IS,IS NOT" />
<input name="Attachments" xs:type="string" columnsize="2000" description="Search for issues that have or do not have attachments. This column can be queried with IS EMPTY or IS NOT EMPTY." other:supportedoperators="LIKE,NOT LIKE" />
<input name="Comment" xs:type="string" columnsize="2000" description="Search for issues that have a comment that contains particular text." other:urlname="" other:aggregate="" other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN"/>
<input name="Category" xs:type="string" columnsize="2000" description="Search for issues that belong to projects in a particular category." other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN"/>
<input name="SprintId" xs:type="integer" columnsize="2000" description="Search for issues that belongs to a specific sprint, by specifying the Id of the Sprint." other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN"/>
<input name="SprintName" xs:type="string" columnsize="2000" description="Search for issues that belongs to a specific sprint, by specifying the name of the Sprint." other:supportedoperators="=,!=,IS,IS NOT,IN,NOT IN"/>
<input name="Filter" xs:type="string" columnsize="2000" description="Search for issues of saved filters. This column can be queried with filter name or filter id." other:supportedoperators="=,!=,IN,NOT IN"/>
<input name="Rows@Next" desc="Identifier for the next page of results. Do not set this value manually." />
</api:info>
<api:script method="GET">
<api:call op="jiraadoSelect">
<api:push/>
</api:call>
</api:script>
<api:script method="POST">
<api:call op="jiraadoInsert">
<api:push/>
</api:call>
</api:script>
<api:script method="MERGE">
<api:call op="jiraadoUpdate">
<api:push/>
</api:call>
</api:script>
<api:script method="DELETE">
<api:call op="jiraadoDelete">
<api:push/>
</api:call>
</api:script>
</api:script>