# Changes between Version 3 and Version 4 of TracReports

Ignore:
Timestamp:
Apr 18, 2013 10:02:31 AM (9 years ago)
Comment:

--

### Legend:

Unmodified
 v3 ''Creating a custom report requires a comfortable knowledge of SQL.'' '''Note that you need to set up [TracPermissions#Reports permissions] in order to see the buttons for adding or editing reports.''' A report is basically a single named SQL query, executed and presented by }}} --- == Advanced Reports: Dynamic Variables == }}} Dynamic variables can also be used in the report title and description (since 1.1.1). === !Special/Constant Variables === }}} ---- specialized SQL statements to control the output of the Trac report engine. == Special Columns == === Special Columns === To format reports, TracReports looks for 'magic' column names in the query result. These 'magic' names are processed and affect the layout and style of the }}} * '''__style__''' — A custom CSS style expression to use for the current row. * '''__style__''' — A custom CSS style expression to use on the  element of the current row. * '''__class__''' — Zero or more space-separated CSS class names to be set on the  element of the current row. These classes are added to the class name derived from __color__ and the odd / even indicator. '''Example:''' ''List active tickets, grouped by milestone, group header linked to milestone page, colored by priority'' If you have tickets in the database ''before'' you declare the extra fields in trac.ini, there will be no associated data in the ticket_custom table. To get around this, use SQL's "LEFT OUTER JOIN" clauses. See [trac:TracIniReportCustomFieldSample TracIniReportCustomFieldSample] for some examples. '''Note that you need to set up permissions in order to see the buttons for adding or editing reports.''' === A note about SQL rewriting #rewriting Beyond the relatively trivial replacement of dynamic variables, the SQL query is also altered in order to support two features of the reports: 1. [#sort-order changing the sort order] 2. pagination support (limitation of the number of result rows displayed on each page) In order to support the first feature, the sort column is inserted in the ORDER BY clause in the first position or in the second position if a __group__ column is specified (an ORDER BY clause is created if needed). In order to support pagination, a LIMIT ... OFFSET ... clause is appended. The query might be too complex for the automatic rewrite to work correctly, resulting in an erroneous query. In this case you still have the possibility to control exactly how the rewrite is done by manually inserting the following tokens: - @SORT_COLUMN@, the place where the name of the selected sort column will be inserted, - @LIMIT_OFFSET@, the place where the pagination support clause will be added Note that if you write them after an SQL comment, --, you'll effectively disable rewriting if this is what you want! Let's take an example, consider the following SQL query: {{{ -- ## 4: Assigned, Active Tickets by Owner ## -- -- -- List assigned tickets, group by ticket owner, sorted by priority. -- SELECT p.value AS __color__, owner AS __group__, id AS ticket, summary, component, milestone, t.type AS type, severity, time AS created, changetime AS _changetime, description AS _description, reporter AS _reporter FROM ticket t,enum p WHERE status = 'assigned' AND p.name=t.priority AND p.type='priority' ORDER BY __group__, p.value, severity, time }}} The automatic rewrite will be the following (4 rows per page, page 2, sorted by component): {{{ SELECT p.value AS __color__, owner AS __group__, id AS ticket, summary, component, milestone, t.type AS type, severity, time AS created, changetime AS _changetime, description AS _description, reporter AS _reporter FROM ticket t,enum p WHERE status = 'assigned' AND p.name=t.priority AND p.type='priority' ORDER BY __group__ ASC, component ASC,  __group__, p.value, severity, time LIMIT 4 OFFSET 4 }}} The equivalent SQL query with the rewrite tokens would have been: {{{ SELECT p.value AS __color__, owner AS __group__, id AS ticket, summary, component, milestone, t.type AS type, severity, time AS created, changetime AS _changetime, description AS _description, reporter AS _reporter FROM ticket t,enum p WHERE status = 'assigned' AND p.name=t.priority AND p.type='priority' ORDER BY __group__, @SORT_COLUMN@, p.value, severity, time @LIMIT_OFFSET@ }}} If you want to always sort first by priority and only then by the user selected sort column, simply use the following ORDER BY clause: {{{ ORDER BY __group__, p.value, @SORT_COLUMN@, severity, time }}} ----