JIRADEV-DatabaseSchema-180614-1519-1192.pdf

22
1. a. b. 2. Database Schema On this page: About the JIRA database schema Entity Engine and working with the JIRA database Relationships between tables About the JIRA database schema The PDF below shows the database schema for . JIRA 6.1 EAP 3 (m03) The database schema is also described in / in the JIRA WEB-INF/classes/entitydefs entitymodel.xml web application. The file has an XML definition of all JIRA's database tables, table columns entitymodel.xml and their data type. Some of the relationships between tables also appear in the file. Generating JIRA database schema information To generate schema information for the JIRA database, e.g. the PDF above, follow the instructions below. You can generate schema information in pdf, txt and formats. Note, if you want to generate the schema in PDF dot format, you need to have installed. Graphviz Download the attached plugin: For JIRA 5: jira-schema-diagram-generator-plugin-1.0.jar For JIRA 6: jira-schema-diagram-generator-plugin-1.0.1.jar

Transcript of JIRADEV-DatabaseSchema-180614-1519-1192.pdf

Page 1: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

1. a. b.

2.

Database SchemaOn this page:

About the JIRA database schemaEntity Engine and working with the JIRA databaseRelationships between tables

About the JIRA database schemaThe PDF below shows the database schema for .JIRA 6.1 EAP 3 (m03)

 

The database schema is also described in / in the JIRAWEB-INF/classes/entitydefs entitymodel.xmlweb application. The file has an XML definition of all JIRA's database tables, table columnsentitymodel.xmland their data type. Some of the relationships between tables also appear in the file.

Generating JIRA database schema information

To generate schema information for the JIRA database, e.g. the PDF above, follow the instructions below. Youcan generate schema information in pdf, txt and formats. Note, if you want to generate the schema in PDFdotformat, you need to have installed.Graphviz

Download the attached plugin: For JIRA 5:  jira-schema-diagram-generator-plugin-1.0.jarFor JIRA 6: jira-schema-diagram-generator-plugin-1.0.1.jar

Page 2: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

2

2. 3.

a.

b. c. d. e.

Install the plugin in your JIRA instance by following the instructions on .Managing JIRA's Plugins

Go to the JIRA administration console and navigate to System > Troubleshooting and Support >Generate Schema Diagram

: start typing Keyboard shortcut g + g + generateEnter the tables/columns to omit from the generated schema information, if desired.If you want to generate a pdf, enter the path to the Graphviz executable.Click .Generate SchemaThe 'Database Schema' page will be displayed with links to the schema file in txt, dot and pdfformat.

Entity Engine and working with the JIRA databaseJIRA uses Entity Engine module of the suite to communicate with the database. You can learn more aboutOfBizthe Entity Engine by reading its online .documentation

If you are using JIRA's API you will notice that a lot of code deals with objects. The GenericValue GenericVa is an OfBiz entity engine object. Each GenericValue object represents a record in the database.lue

To get a value of a field from a GenericValue you will need to use the relevant getter method for the field's type.For example:

GenericValue project = ...String name = project.getString("name");Long id = project.getLong("id");

The list of valid fields for each entity can be obtained by looking the entity's definition in the WEB-INF/classes file. For the above example, one needs to look at the "Project" entity./entitydefs/entitymodel.xml

Notes about working with the JIRA database:

Direct database queries are not recommended in JIRA. Instead, we recommend addingPlease Note:or modifying data via , or . Check out the JIRA's REST APIs JIRA RPC Services (deprecated) Jelly Tags C

and for existing remote scripting tools. If you absolutely must modifyommand Line Interface Python CLIdata in your database via direct database queries, always your data before performing anyback upmodification to the database.Try adding for a great way to watch JIRA database queries in action.SQL LoggingHelp contribute to our examples at . These are SQL examples that can beExample SQL queries for JIRArun against the JIRA schema.

Relationships between tablesSome of the relationships between JIRA's tables in the database are documented below:

Issue FieldsSimple fieldsUser detailsComponents and versionsIssue linksCustom fieldsCustom field configuration optionsCustom field configuration default valueCustom field configuration schemesCustom field configuration scopesChange HistoryWork logsUsers and GroupsIssue status and workflow

Page 3: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

3

Issue Fields

This page shows how to examine each of a JIRA issue's fields via SQL. We will use as a sampleJRA-3166issue in our queries.

Simple fields

Most fields in JIRA are kept in the table:jiraissue

mysql> desc jiraissue;+----------------------+---------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+----------------------+---------------+------+-----+---------+-------+| ID | decimal(18,0) | NO | PRI | NULL | || pkey | varchar(255) | YES | UNI | NULL | || PROJECT | decimal(18,0) | YES | MUL | NULL | || REPORTER | varchar(255) | YES | | NULL | || ASSIGNEE | varchar(255) | YES | MUL | NULL | || issuetype | varchar(255) | YES | | NULL | || SUMMARY | varchar(255) | YES | | NULL | || DESCRIPTION | longtext | YES | | NULL | || ENVIRONMENT | longtext | YES | | NULL | || PRIORITY | varchar(255) | YES | | NULL | || RESOLUTION | varchar(255) | YES | | NULL | || issuestatus | varchar(255) | YES | | NULL | || CREATED | datetime | YES | | NULL | || UPDATED | datetime | YES | | NULL | || DUEDATE | datetime | YES | | NULL | || RESOLUTIONDATE | datetime | YES | | NULL | || VOTES | decimal(18,0) | YES | | NULL | || WATCHES | decimal(18,0) | YES | | NULL | || TIMEORIGINALESTIMATE | decimal(18,0) | YES | | NULL | || TIMEESTIMATE | decimal(18,0) | YES | | NULL | || TIMESPENT | decimal(18,0) | YES | | NULL | || WORKFLOW_ID | decimal(18,0) | YES | MUL | NULL | || SECURITY | decimal(18,0) | YES | | NULL | || FIXFOR | decimal(18,0) | YES | | NULL | || COMPONENT | decimal(18,0) | YES | | NULL | |+----------------------+---------------+------+-----+---------+-------+

They can be retrieved with a regular select:

mysql> select id, pkey, project, reporter, assignee, issuetype, summaryfrom jiraissue where pkey='JRA-3166';+-------+----------+---------+-----------+----------+-----------+---------------------------------+| id | pkey | project | reporter | assignee | issuetype |summary |+-------+----------+---------+-----------+----------+-----------+---------------------------------+| 16550 | JRA-3166 | 10240 | mvleeuwen | NULL | 2 |Database consistency check tool |+-------+----------+---------+-----------+----------+-----------+---------------------------------+

Page 4: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

4

User details

Say we wish to find out the email address and other details about our reporter, .mvleeuwen

select user_name, directory_id, display_name, email_addressfrom cwd_userwhere user_name = 'mvleeuwen';

Normally this should return a single row, however JIRA allows you to set up multiple user directories and it ispossible that two or more directories contain the same username.

For more information about User and Group Tables see the .Users and Groups section

Components and versions

Since each issue can have multiple components/versions, there is a join table between and jiraissue versi/ tables called :on component nodeassociation

Page 5: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

5

mysql> desc nodeassociation;+--------------------+---------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------------+---------------+------+-----+---------+-------+| SOURCE_NODE_ID | decimal(18,0) | NO | PRI | | || SOURCE_NODE_ENTITY | varchar(60) | NO | PRI | | || SINK_NODE_ID | decimal(18,0) | NO | PRI | | || SINK_NODE_ENTITY | varchar(60) | NO | PRI | | || ASSOCIATION_TYPE | varchar(60) | NO | PRI | | || SEQUENCE | decimal(9,0) | YES | | NULL | |+--------------------+---------------+------+-----+---------+-------+

mysql> select distinct SOURCE_NODE_ENTITY from nodeassociation;+--------------------+| SOURCE_NODE_ENTITY |+--------------------+| Issue || Project |+--------------------+

mysql> select distinct SINK_NODE_ENTITY from nodeassociation;+-----------------------+| SINK_NODE_ENTITY |+-----------------------+| IssueSecurityScheme || PermissionScheme || IssueTypeScreenScheme || NotificationScheme || ProjectCategory || FieldLayoutScheme || Component || Version |+-----------------------+

mysql> select distinct ASSOCIATION_TYPE from nodeassociation;+------------------+| ASSOCIATION_TYPE |+------------------+| IssueVersion || IssueFixVersion || IssueComponent || ProjectScheme || ProjectCategory |+------------------+

So to get fix-for versions of an issue, run:

Page 6: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

6

mysql> select * from projectversion where id in ( select SINK_NODE_ID from nodeassociation whereASSOCIATION_TYPE='IssueFixVersion' and SOURCE_NODE_ID=( select id from jiraissue where pkey='JRA-5351') );+-------+---------+-------+-------------+----------+----------+----------+------+-------------+| ID | PROJECT | vname | DESCRIPTION | SEQUENCE | RELEASED | ARCHIVED| URL | RELEASEDATE |+-------+---------+-------+-------------+----------+----------+----------+------+-------------+| 11614 | 10240 | 3.6 | NULL | 131 | NULL | NULL | NULL | NULL |+-------+---------+-------+-------------+----------+----------+----------+------+-------------+

Similarly with affects versions:

mysql> select * from projectversion where id in ( select SINK_NODE_ID from nodeassociation whereASSOCIATION_TYPE='IssueVersion' and SOURCE_NODE_ID=( select id from jiraissue where pkey='JRA-5351') );+-------+---------+---------------------+-------------+----------+----------+----------+------+---------------------+| ID | PROJECT | vname | DESCRIPTION | SEQUENCE |RELEASED | ARCHIVED | URL | RELEASEDATE |+-------+---------+---------------------+-------------+----------+----------+----------+------+---------------------+| 10931 | 10240 | 3.0.3 Professional | NULL | 73 | true | NULL | NULL | 2004-11-19 00:00:00 || 10930 | 10240 | 3.0.3 Standard | NULL | 72 | true | NULL | NULL | 2004-11-19 00:00:00 || 10932 | 10240 | 3.0.3 Enterprise | NULL | 74 | true | NULL | NULL | 2004-11-19 00:00:00 |+-------+---------+---------------------+-------------+----------+----------+----------+------+---------------------+

and components:

Page 7: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

7

mysql> select * from component where id in ( select SINK_NODE_ID from nodeassociation whereASSOCIATION_TYPE='IssueComponent' and SOURCE_NODE_ID=( select id from jiraissue where pkey='JRA-5351') );+-------+---------+---------------+-------------+------+------+--------------+| ID | PROJECT | cname | description | URL | LEAD |ASSIGNEETYPE |+-------+---------+---------------+-------------+------+------+--------------+| 10126 | 10240 | Web interface | NULL | NULL | NULL | NULL |+-------+---------+---------------+-------------+------+------+--------------+

Issue links

JIRA issue links are stored in the table, which simply links the IDs of two issues together, andissuelinkrecords the link type:

mysql> desc issuelink;+-------------+---------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------------+---------------+------+-----+---------+-------+| ID | decimal(18,0) | NO | PRI | | || LINKTYPE | decimal(18,0) | YES | MUL | NULL | || SOURCE | decimal(18,0) | YES | MUL | NULL | || DESTINATION | decimal(18,0) | YES | MUL | NULL | || SEQUENCE | decimal(18,0) | YES | | NULL | |+-------------+---------------+------+-----+---------+-------+5 rows in set (0.00 sec)

For instance, to list all links between TP-1 and TP-2:

Page 8: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

8

mysql> select * from issuelink where SOURCE=(select id from jiraissue wherepkey='TP-1') and DESTINATION=(select id from jiraissue where pkey='TP-2');+-------+----------+--------+-------------+----------+| ID | LINKTYPE | SOURCE | DESTINATION | SEQUENCE |+-------+----------+--------+-------------+----------+| 10020 | 10000 | 10000 | 10010 | NULL |+-------+----------+--------+-------------+----------+1 row in set (0.00 sec)

Link types are defined in . This query prints all links in the system with their type:issuelinktype

mysql> select j1.pkey, issuelinktype.INWARD, j2.pkey from jiraissue j1, issuelink,issuelinktype, jiraissue j2 where j1.id=issuelink.SOURCE andj2.id=issuelink.DESTINATION and issuelinktype.id=issuelink.linktype;+-------+---------------------+-------+| pkey | INWARD | pkey |+-------+---------------------+-------+| TP-4 | jira_subtask_inward | TP-5 || TP-4 | jira_subtask_inward | TP-7 || TP-4 | jira_subtask_inward | TP-8 || TP-11 | jira_subtask_inward | TP-12 || TP-4 | jira_subtask_inward | TP-6 || TP-1 | is duplicated by | TP-2 |+-------+---------------------+-------+6 rows in set (0.00 sec)

Subtasks

As shown in the last query, JIRA records the issue-subtask relation as a link. The "subtask" link type is hidden inthe user interface (indicated by the 'pstyle' value below), but visible in the database:

mysql> select * from issuelinktype;+-------+-------------------+---------------------+----------------------+--------------+| ID | LINKNAME | INWARD | OUTWARD | pstyle |+-------+-------------------+---------------------+----------------------+--------------+| 10000 | Duplicate | is duplicated by | duplicates | NULL || 10001 | jira_subtask_link | jira_subtask_inward | jira_subtask_outward |jira_subtask |+-------+-------------------+---------------------+----------------------+--------------+2 rows in set (0.00 sec)

This means it is possible to convert an issue to a subtask, or vice-versa, by tweaking records.issuelink

Custom fields have their own set of tables. For details, see Custom fields

Custom fields

Custom fields defined in the system are stored in the table, and instances of custom fields arecustomfieldstored in :customfieldvalue

Page 9: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

9

mysql> desc customfieldvalue;+-------------+---------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------------+---------------+------+-----+---------+-------+| ID | decimal(18,0) | NO | PRI | | || ISSUE | decimal(18,0) | YES | MUL | NULL | || CUSTOMFIELD | decimal(18,0) | YES | | NULL | || PARENTKEY | varchar(255) | YES | | NULL | || STRINGVALUE | varchar(255) | YES | | NULL | || NUMBERVALUE | decimal(18,6) | YES | | NULL | || TEXTVALUE | longtext | YES | | NULL | || DATEVALUE | datetime | YES | | NULL | || VALUETYPE | varchar(255) | YES | | NULL | |+-------------+---------------+------+-----+---------+-------+

We can print all custom field values for an issue with:

mysql> select * from customfieldvalue where issue=(select id fromjiraissue where pkey='JRA-5448');+-------+-------+-------------+-----------+-------------+-------------+-----------+---------------------+-----------+| ID | ISSUE | CUSTOMFIELD | PARENTKEY | STRINGVALUE | NUMBERVALUE |TEXTVALUE | DATEVALUE | VALUETYPE |+-------+-------+-------------+-----------+-------------+-------------+-----------+---------------------+-----------+| 23276 | 22160 | 10190 | NULL | NULL | NULL |NULL | 2004-12-07 17:25:58 | NULL |+-------+-------+-------------+-----------+-------------+-------------+-----------+---------------------+-----------+

and we can see what type of custom field this (10190) is with:

mysql> select * from customfield where id=10190;+-------+------------------------------------------------+--------------------------------------------------------+-----------------+-------------+--------------+-----------+---------+-----------+| ID | CUSTOMFIELDTYPEKEY |CUSTOMFIELDSEARCHERKEY | cfname | DESCRIPTION | defaultvalue | FIELDTYPE | PROJECT | ISSUETYPE |+-------+------------------------------------------------+--------------------------------------------------------+-----------------+-------------+--------------+-----------+---------+-----------+| 10190 | com.atlassian.jira.ext.charting:resolutiondate |com.atlassian.jira.ext.charting:resolutiondatesearcher | Resolution Date| NULL | NULL | NULL | NULL | NULL |+-------+------------------------------------------------+--------------------------------------------------------+-----------------+-------------+--------------+-----------+---------+-----------+

(ie. it's a "Resolution Date").

This query identifies a particular custom field value in a particular issue:

Page 10: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

10

mysql> select stringvalue from customfieldvalue wherecustomfield=(select id from customfield where cfname='Urgency') andissue=(select id from jiraissue where pkey='FOR-845');+-------------+| stringvalue |+-------------+| Low | +-------------+1 row in set (0.33 sec)

If the custom field has multiple values (multi-select or multi-user picker), each issue can have multiple customf rows:ieldvalue

mysql> select * from customfieldvalue where customfield=(select ID fromcustomfield where cfname='MultiUser');+-------+-------+-------------+-----------+-------------+-------------+-----------+-----------+-----------+| ID | ISSUE | CUSTOMFIELD | PARENTKEY | STRINGVALUE | NUMBERVALUE |TEXTVALUE | DATEVALUE | VALUETYPE |+-------+-------+-------------+-----------+-------------+-------------+-----------+-----------+-----------+| 10002 | 10060 | 10000 | NULL | bob | NULL |NULL | NULL | NULL | | 10003 | 10060 | 10000 | NULL | jeff | NULL |NULL | NULL | NULL | +-------+-------+-------------+-----------+-------------+-------------+-----------+-----------+-----------+2 rows in set (0.00 sec)

Here issue 10060 has two users, and in its MultiUser custom field.bob jeff

Custom field configuration options

The option sets (1, 2, 3 and A, B, C) are stored in the table:customfieldoption

mysql> select * from customfieldoption where customfieldconfig=10031;

ID CUSTOMFIELD

CUSTOMFIELDCONFIG

PARENTOPTIONID

SEQUENCE

customvalue

optiontype disabled

10000 10001 10031 NULL 0 1 NULL false

10001 10001 10031 NULL 1 2 NULL false

10002 10001 10031 NULL 2 3 NULL false

mysql> select * from customfieldoption where customfieldconfig=10032;

ID CUSTOMFIELD

CUSTOMFIELDCONFIG

PARENTOPTIONID

SEQUENCE

customvalue

optiontype disabled

10003 10001 10032 NULL 0 A NULL false

10004 10001 10032 NULL 1 B NULL false

Page 11: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

11

10005 10001 10032 NULL 2 C NULL false

Custom field configuration default value

The custom field default value is stored in the table. Since this table must store a valuegenericconfigurationfor any custom field type (cascading selects, multi-selects, etc) the value is encoded as XML.

If we were to set a default value of "2" for our "Default Configuration Scheme for SelectCF", it would be recordedas:

mysql> select * from genericconfiguration where ID=10031;

ID DATATYPE DATAKEY XMLVALUE

10031 DefaultValue 10030 <string>2</string>

Custom field configuration schemes

JIRA custom fields can have different default values and possible values for each project and/or issue type. Thisis set up by clicking 'Configure' in the custom field definition.

For instance, in this screenshot the "SelectCF" select-list field will have values 1, 2, 3 for all projects except bugsand improvements in "NewProj" and"Test Project", which will have values A, B and C:

Page 12: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

12

Custom field configuration scopes

In the database, these custom field configuration schemes are stored in the tablefieldconfigscheme

mysql> select * from fieldconfigscheme where id in (10031,10032);

ID configname DESCRIPTION FIELDID CUSTOMFIELD

10031 DefaultConfigurationScheme forSelectCF

Defaultconfigurationscheme generatedby JIRA

customfield_10001 NULL

10032 NewProj scheme   customfield_10001 NULL

The for each of these schemes is listed as records (one per project) in the projects in scope configurationcon table:text

mysql> select * from configurationcontext where fieldconfigscheme=10031;

ID PROJECTCATEGORY

PROJECT customfield FIELDCONFIGSCHEME

Page 13: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

13

10053 NULL NULL customfield_10001 10031

(Here showing that that the "Default Configuration Scheme for SelectCF" applies to all projects)

mysql> select * from configurationcontext where fieldconfigscheme=10032;

ID PROJECTCATEGORY

PROJECT customfield FIELDCONFIGSCHEME

10054 NULL 10000 customfield_10001 10032

10055 NULL 10010 customfield_10001 10032

(Here showing that "NewProj scheme" is restricted to projects with ids 10000 and 10010 ("Test Project" and"NewProj")).

Finally, the for each scheme is listed as records (one per issue type) in the issue types in scope fieldconfigsc table:hemeissuetype

mysql> select * from fieldconfigschemeissuetype where fieldconfigscheme = 10031;

ID ISSUETYPE FIELDCONFIGSCHEME FIELDCONFIGURATION

10051 NULL 10031 10031

(Here showing that "Default Configuration Scheme for SelectCF" is not limited to any issue types)

mysql> select * from fieldconfigschemeissuetype where fieldconfigscheme = 10032;

ID ISSUETYPE FIELDCONFIGSCHEME FIELDCONFIGURATION

10052 1 10032 10032

10053 4 10032 10032

(Here showing that "Newproj scheme" is limited to issue types with IDs 1 and 4).

Note that there should in and always be a record configurationcontext fieldconfigschemeissuetypefor each issue type configuration scheme. If the scheme isn't restricted to any projects or issue types, the proje

and columns of the respective tables should be .ct issuetype NULL

Notes:

JIRA has/had a bug where it didn't leave an entry when deleting an issue type ( ), so if you areJRA-10461making changes manually, don't make the same mistake. This bug was resolved in JIRA 3.11.

Change History

Change History Database Tables

JIRA stores the Change History records of each issue in the and tables.changegroup changeitem

Each change to the issue triggered by a user inserts one record into the table. Eachchangegroupchangegroup table record describes which issue it refers to, the time of the change and the user who hasperformed the change (null for a non-logged in user).

Page 14: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

14

mysql> select * from changegroup;+-------+---------+--------+---------------------+| ID | issueid | AUTHOR | CREATED |+-------+---------+--------+---------------------+| 10000 | 10000 | admin | 2005-06-09 15:16:39 || 10751 | 10000 | admin | 2005-06-10 00:00:00 |+-------+---------+--------+---------------------+

Each changegroup record refers to one or many records. Each record describes thechangeitem changeitemissue field that has been updated and its old and new values. The column records the id of theOLDVALUEchanged enity (e.g. status) while records the name fo the entity, so that if the entity is removed fromOLDSTRINGthe system the change history for an issue can still be displayed. The and columns areNEWVALUE NEWSTRINGsimilar in nature.

mysql> select * from changeitem;+-------+---------+-----------+------------+----------+-----------+----------+-----------+| ID | groupid | FIELDTYPE | FIELD | OLDVALUE | OLDSTRING | NEWVALUE |NEWSTRING |+-------+---------+-----------+------------+----------+-----------+----------+-----------+| 10000 | 10000 | jira | status | 1 | Open | 6 |Closed || 10001 | 10000 | jira | resolution | NULL | NULL | 1 |Fixed || 11404 | 10751 | jira | status | 1 | Open | 6 |Closed |+-------+---------+-----------+------------+----------+-----------+----------+-----------+

Inserting change history records

When writing tools that import data into JIRA, it is sometimes required to import change history. To do thisplease first insert a record into the table with a valid issue id:changegroup

insert into changegroup values (20000,10000,'admin','2005-06-12');

The issues are stored in the table:jiraissue

mysql> select id, pkey from jiraissue;+-------+-------+| id | pkey |+-------+-------+| 10000 | TST-1 |+-------+-------+

And then insert the required number of records referencing the inserted record:changeitem changegroup

Page 15: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

15

insert into changeitem values (11000, 20000,'jira','status','1','Open','6','Closed');

The SEQUENCE_VALUE_ITEM table

The SEQUENCE_VALUE_ITEM table is used to record, in a database independent way, the maximum ID usedin each of JIRA's database tables:

mysql> select * from SEQUENCE_VALUE_ITEM;+-----------------------------+--------+| SEQ_NAME | SEQ_ID |+-----------------------------+--------+| Action | 10310 | | ChangeGroup | 11050 | | ChangeItem | 11320 | | ColumnLayout | 10040 | | ColumnLayoutItem | 10120 | | Component | 10110 | | ConfigurationContext | 10170 | | SchemeIssueSecurities | 10040 | ...

Actually, Ofbiz allocates IDs in batches of 10, so the SEQ_ID is the next available ID rounded up to the nearest10. So you might have:

mysql> select max(ID) from jiraaction;+---------+| max(ID) |+---------+| 10303 | +---------+1 row in set (0.04 sec)

mysql> select * from SEQUENCE_VALUE_ITEM where SEQ_NAME='Action';+----------+--------+| SEQ_NAME | SEQ_ID |+----------+--------+| Action | 10310 | +----------+--------+1 row in set (0.01 sec)

Where 10310 is the nearest 10 above 10303.

The column refers to the database table name defined in SEQ_NAME WEB-INF/classes/entitydefs/entit (eg. "Action" is ).ymodel.xml jiraaction

Manually inserting records

The implication of this is that if you want to manually insert records into JIRA database tables, you must update. Set the relevant rows' SEQ_ID values to a value greater than the actualSEQUENCE_VALUE_ITEM yourself

maximum ID in the table. You will then need to restart JIRA to ensure all database caches are reset.

Retrieving Change History using JIRA's API

Page 16: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

16

The best way to retrieve change history entries is:

actionManager.getChangeHistory(getIssue(), authenticationContext.getUser());

You can declare dependency on JiraAuthenticationContext and ActionManager in the constructor of your pluginas described in .PicoContainer and JIRA

The getChangeHistory method returns objects on which you can call the getChangeItems()ChangeHistorymethod. This returns a List of GenericValue objects, each one representing an issue field update. To check thefield that was updated do:

String fieldName = changeItem.getString("field")

GenericValues are described in .Database Schema

Work logs

Work log entries are kept in the table. For instance, some worklogs in JIRA (from ):worklog JRA-10393

are stored in table as:worklog

id issueid

author grouplevel

rolelevel

worklogbody

created

updateauthor

updated

timeworked

startdate

83332 38315 mtokar     Implementedmethodtocalculatenumberofactiveusers +tests

2008-01-2219:44:04.867-06

mtokar 2008-01-2219:44:04.867-06

5400 2008-01-2219:43:00-06

83333 38315 [email protected]

    Implemented amethodtocheck iftheuserlimit ofthelicensehasbeenexceeded.

2008-01-2221:33:18.23-06

[email protected]

2008-01-2221:33:18.23-06

7200 2008-01-2221:31:00-06

83334 38315 [email protected]

    Addednewlicensetypes

2008-01-2223:49:27.794-06

[email protected]

2008-01-2223:51:06.029-06

7200 2008-01-2223:48:00-06

Page 17: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

17

83335 38315 [email protected]

    Integrate newlicensetypesinJIRA.

2008-01-2223:51:23.799-06

[email protected]

200

where:

issueid maps to .jiraissue idtimeworked is in seconds

Whenever a worklog entry is added, the and values arejiraissue.timespent jiraissue.timeestimateincremented and decremented respectively.

Users and Groups

Changed: JIRA 4.3 and higher uses "Embedded Crowd"as its user management framework.For the old user and group tables, see Databas

.e Schema v4.2

User and Group Tables

Users

Users are stored in the table:CWD_USER

COLUMN_NAME DATA_TYPE COMMENTS

ID NUMBER(18,0)  

DIRECTORY_ID NUMBER(18,0) Links to CWD_DIRECTORY

USER_NAME VARCHAR(255)  

LOWER_USER_NAME VARCHAR(255) used for case-insensitive search

ACTIVE NUMBER(9,0)  

CREATED_DATE DATE  

UPDATED_DATE DATE  

FIRST_NAME VARCHAR(255) Not used

LOWER_FIRST_NAME VARCHAR(255) Not used

LAST_NAME VARCHAR(255) Not used

LOWER_LAST_NAME VARCHAR(255) Not used

DISPLAY_NAME VARCHAR(255)  

LOWER_DISPLAY_NAME VARCHAR(255)  

EMAIL_ADDRESS VARCHAR(255)  

LOWER_EMAIL_ADDRESS VARCHAR(255)  

CREDENTIAL VARCHAR(255)  

See also which stores arbitrary "Attributes" against the User.CWD_USER_ATTRIBUTES

Page 18: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

18

Group Tables

The groups are stored in the table:CWD_GROUP

COLUMN_NAME DATA_TYPE COMMENTS

ID NUMBER(18,0)  

GROUP_NAME VARCHAR(255)  

LOWER_GROUP_NAME VARCHAR(255) used for case-insensitive search

ACTIVE NUMBER(9,0)  

LOCAL NUMBER(9,0)  

CREATED_DATE DATE  

UPDATED_DATE DATE  

DESCRIPTION VARCHAR(255)  

LOWER_DESCRIPTION VARCHAR(255)  

GROUP_TYPE VARCHAR(60)  

DIRECTORY_ID NUMBER(18,0) Links to CWD_DIRECTORY

See also which stores arbitrary "Attributes" against the Group.CWD_GROUP_ATTRIBUTES

Group Membership

The table records which users belong to which groups.CWD_MEMBERSHIPNote that it is also used to store parent/child relationships for nested groups.

COLUMN_NAME DATA_TYPE COMMENTS

ID NUMBER(18,0)  

PARENT_ID NUMBER(18,0) Parent Group

CHILD_ID NUMBER(18,0) User or nested Group ID

MEMBERSHIP_TYPE VARCHAR(60) Indicates a Group-Usermembership or Group-Groupmembership

GROUP_TYPE VARCHAR(60) not used

PARENT_NAME VARCHAR(255) Parent Group

LOWER_PARENT_NAME VARCHAR(255) used for case-insensitive search

CHILD_NAME VARCHAR(255) User or child Group

LOWER_CHILD_NAME VARCHAR(255) used for case-insensitive search

DIRECTORY_ID NUMBER(18,0) Note that this must match theDirectoryId for the Group and User

User Directories

JIRA can have multiple "User Directories".The main config is stored in CWD_DIRECTORY

COLUMN_NAME DATA_TYPE COMMENTS

ID NUMBER(18,0)  

Page 19: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

19

DIRECTORY_NAME VARCHAR(255)  

LOWER_DIRECTORY_NAME VARCHAR(255)  

CREATED_DATE DATE  

UPDATED_DATE DATE  

ACTIVE NUMBER(9,0)  

DESCRIPTION VARCHAR(255)  

IMPL_CLASS VARCHAR(255)  

LOWER_IMPL_CLASS VARCHAR(255)  

DIRECTORY_TYPE VARCHAR(60) Distinguishes Internal, LDAP,Crowd, etc

DIRECTORY_POSITION VARCHAR(18,0) Hierarchy of directories

Details and custom settings are stored in .CWD_DIRECTORY_ATTRIBUTEAvailable operations (permissions) are stored in .CWD_DIRECTORY_OPERATION

Shadowed Users

Consider a query like:

select user_name, directory_id, display_name, email_addressfrom cwd_userwhere user_name = 'fred'

Normally this should return a single row, however JIRA allows you to set up multiple user directories (eg multipleLDAP directories, or a single LDAP directory mixed with local users).It is possible that two or more directories contain the same username.Now the User Directories have a sort hierarchy, and JIRA will only recognise the user in the highest prioritydirectory.To find which user is in effect, you can change the query to:

select user_name, directory_id, display_name, email_address,dir.directory_position as positionfrom cwd_user usrjoin cwd_directory dir on dir.id = usr.directory_idwhere user_name = 'fred'order by dir.directory_position

The first user in the list is the actual one that JIRA will use.Any other users are considered as "shadowed" by the first and will be ignored by JIRA.

Watches and Votes

Watches and votes are recorded in the table:USERASSOCIATION

COLUMN_NAME DATA_TYPE COMMENTS

SOURCE_NAME VARCHAR(60) username

SINK_NODE_ID NUMBER(18,0)  

SINK_NODE_ENTITY VARCHAR(60)  

ASSOCIATION_TYPE VARCHAR(60)  

Page 20: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

20

SEQUENCE NUMBER(9,0)  

For example:

mysql> select * from userassociation;+---------------+--------------+------------------+------------------+----------+| SOURCE_NAME | SINK_NODE_ID | SINK_NODE_ENTITY | ASSOCIATION_TYPE | SEQUENCE |+---------------+--------------+------------------+------------------+----------+| asmith | 108433 | Issue | WatchIssue | NULL || droberts | 100915 | Issue | WatchIssue | NULL || dfernandez | 106387 | Issue | VoteIssue | NULL |...

For example, here user 'asmith' is watching issue with id 108433.

Issue status and workflow

This page describes the database tables involved in issue workflow. It will be useful for people who wish to insertissues into the database manually, or diagnose/fix corrupted databases.

JIRA issues have both:

a (Open, Closed, In Progress etc).statusa , which governs which transitions are availableworkflow step

Issue status

In the database, the (Open, Closed etc) is stored on the table:status jiraissue

Page 21: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

21

mysql> select issuestatus from jiraissue where pkey='TP-1';+-------------+| issuestatus |+-------------+| 1 |+-------------+1 row in set (0.00 sec)

mysql> select pname from issuestatus, jiraissue whereissuestatus.id=jiraissue.issuestatus and pkey='TP-1';+-------+| pname |+-------+| Open |+-------+1 row in set (0.00 sec)

Issue workflow step

Originally JIRA issues only had a status. Then in version 2.0, was added, so that transitions betweenworkflowstatuses could be customized. An issue's workflow step is stored in new tables, referenced from byjiraissuethe :workflow_id

mysql> select * from OS_WFENTRY where ID=(select workflow_id from jiraissue wherepkey='TP-1');+-------+------+-------------+-------+| ID | NAME | INITIALIZED | STATE |+-------+------+-------------+-------+| 10000 | jira | 0 | 1 |+-------+------+-------------+-------+1 row in set (0.02 sec)

The TP-1 issue's OS_WFENTRY row indicates that the issue uses the 'jira' (default, built-in) workflow.

mysql> select * from OS_CURRENTSTEP where ENTRY_ID=(select workflow_id fromjiraissue where pkey='TP-1');+-------+----------+---------+-----------+-------+---------------------+----------+-------------+--------+--------+| ID | ENTRY_ID | STEP_ID | ACTION_ID | OWNER | START_DATE | DUE_DATE |FINISH_DATE | STATUS | CALLER |+-------+----------+---------+-----------+-------+---------------------+----------+-------------+--------+--------+| 10000 | 10000 | 1 | 0 | | 2003-11-24 15:17:50 | || Open | |+-------+----------+---------+-----------+-------+---------------------+----------+-------------+--------+--------+1 row in set (0.13 sec)

The issue's OS_CURRENTSTEP row specifies the issue's . The only field really used is .current step STEP_IDThis references a step definition in the workflow:

<step id="1" name="Open">

The workflow definition for the built-in 'jira' workflow can be seen in atlassian-jira/WEB-INF/clas

Page 22: JIRADEV-DatabaseSchema-180614-1519-1192.pdf

22

How status and step relate

An issue's status and workflow step are kept in synch:

mysql> select issuestatus.pname status, issuestatus, OS_CURRENTSTEP.STEP_ID,OS_CURRENTSTEP.STATUS from issuestatus, jiraissue, OS_CURRENTSTEP where issuestatus.id=jiraissue.issuestatus andjiraissue.workflow_id=OS_CURRENTSTEP.ENTRY_ID;+-------------+-------------+---------+----------+| status | issuestatus | STEP_ID | STATUS |+-------------+-------------+---------+----------+| Open | 1 | 1 | Open || Open | 1 | 1 | Open || Open | 1 | 1 | Open || Open | 1 | 1 | Open || Open | 1 | 1 | Open || Open | 1 | 1 | Open |...| Open | 1 | 1 | Open || Open | 1 | 1 | Open || Open | 1 | 1 | Open || In Progress | 3 | 3 | Underway || Closed | 6 | 6 | Closed |+-------------+-------------+---------+----------+32 rows in set (0.00 sec)

mysql>

Status and step are kept in synch is with a (UpdateIssueStatusFunction), which updatesworkflow post-functionthe status whenever the step changes.

If the step gets out of synch with the status, then incorrect (or no) workflow operations appear on the issue page.Eg. if OS_CURRENTSTEP.STEP_ID was 6 ("Closed") when jiraissue.issuestatus was 1 ("Open"), then the issuewould have only one transition ("Reopen issue") which would break if anyone clicked on it.

Summary of issue status and workflow

For each row, there is a and row.jiraissue OS_CURRENTSTEP OS_WFENTRYOS_WFENTRY specifies the applicable workflow. specifies the step in that workflow.OS_CURRENTSTEPThe relations are:

jiraissue.WORKFLOW_ID == OS_WFENTRY.IDjiraissue.WORKFLOW_ID == OS_CURRENTSTEP.ENTRY_ID

 

 

 

ses/jira-workflow.xml