source: trunk/grails-app/services/nl/tno/massSequencing/DataTablesService.groovy @ 69

Last change on this file since 69 was 69, checked in by robert@…, 8 years ago
  • Solved a bug in selecting rows in a paginated table
  • Removed debug printlns
File size: 4.6 KB
Line 
1package nl.tno.massSequencing
2
3class DataTablesService {
4
5        /**
6         * Retrieves data from the database for showing in a datatables table
7         *
8         * @param params                HTTP parameters for the request. Should contain the following parameters
9         *
10         *  int                 iDisplayStart           Display start point
11         *  int                 iDisplayLength          Number of records to display
12         *  int                 iSortCol_0                      Column being sorted on (you will need to decode this number for your database)
13         *  string              sSortDir_0                      Direction to be sorted - "desc" or "asc".
14         *  string              sEcho                           Information for DataTables to use for rendering
15         * 
16         * @param convertClosure        Closure to convert a row from the database into an output row.
17         * @param columns               List with the names of the columns to be retrieved. May contain aggregate functions. The columns should be in the same order as
18         *                                              layed out on the screen in order to search on the right column.
19         * @param groupColumns  List of the names of the columns to group on. Should not contain aggregate functions
20         * @param idColumn              Name of the ID column to be retrieved first.
21         * @param table                 Name of the table (including alias) to retrieve data from
22         * @param joins                 (optional) List of explicit joins to append to the query.
23         * @param queryParameters       (optional) List of query parameters, referred to with questionmarks or named parameters
24         * @see                                 http://www.datatables.net/usage/server-side
25         * @return                              Map with the following entries:
26
27         *   int                iTotalRecords                   Total records, before filtering (i.e. the total number of records in the database)
28         *   int                iTotalDisplayRecords    Total records, after filtering (i.e. the total number of records after filtering has been applied - not just the number of records being returned in this result set)
29         *   string     sEcho                                   An unaltered copy of sEcho sent from the client side. This parameter will change with each draw (it is basically a draw count) - so it is important that this is implemented. Note that it strongly recommended for security reasons that you 'cast' this parameter to an integer in order to prevent Cross Site Scripting (XSS) attacks.
30         *   string     sColumns                                Optional - this is a string of column names, comma separated (used in combination with sName) which will allow DataTables to reorder data on the client-side if required for display
31         *   array              aaData                                  The data in a 2D array
32         *
33         * Example:
34         *              retrieveData(
35         *                      [ "sEcho": 1, "iDisplayStart": 10, "iDisplayLength": 1 ],
36         *                      { [ it[ 1 ], it[ 2 ], it[ 3 ] ] }
37         *                      [ null, "s.name", "s.assay.name", "SUM(sequence.numSequences)" ], [ "s.name", "s.sample.name" ], "s.id", "Sample s"
38         *              );
39         *
40         * Returns
41         *              [ "iTotalRecords": 219, "iTotalDisplayRecords": 219, "sEcho": 1, "aaData": [ [ "sample 123", "assay 101", 20 ] ] ]
42         *
43         */
44        def retrieveData( def params, Class domainClass, Closure convertClosure, List<String> columns, List<String> groupColumns, String from, int total, def ids, Map orderByMapping = null, String where = "", def queryParameters = []) {
45
46                // Create SELECT statement
47                def selectHQL = "SELECT " + columns.join( ", " )
48               
49                // Create FROM statement
50                def fromHQL = "FROM " + from;
51
52                // Determine where clause
53                def whereHQL = "";
54                if( where ) {
55                        whereHQL = "WHERE " + where;
56                }
57               
58                // GROUP columns if needed
59                def groupHQL = "";
60                if( groupColumns ) {
61                        groupHQL = "GROUP BY " + groupColumns.join( ", " );
62                }
63               
64                // Order list correctly
65                def orderHQL = "";
66                if( params.int( 'iSortCol_0' ) ) {
67                        def orderColumnNum = params.int( 'iSortCol_0' );
68                        orderColumnNum = orderColumnNum >= columns.size() || orderColumnNum < 0 ? 0 : orderColumnNum
69
70                        // Search for the column number in the orderByMapping. If no mapping is given, the
71                        // numbers are taken 1-on-1
72                        def orderColumn;
73                        if( orderByMapping ) {
74                                orderColumn = orderByMapping[ orderColumnNum ] ?: orderColumnNum + 1;
75                        } else {
76                                orderColumn = orderColumnNum + 1;
77                        }
78                       
79                        def orderDirection = params.get( 'sSortDir_0' )
80       
81                        orderHQL = "ORDER BY " + orderColumn + " " + orderDirection
82                }
83               
84                // Determine which page to show
85                def num = params.int( 'iDisplayLength' )
86                num = ( num <= 0 ) ? 10 : num;
87               
88                def start = params.int( 'iDisplayStart' )
89                start = ( num <= 0 ) ? 0 : start;
90               
91                // Retrieve data itself
92                def retrieveHQL = [ selectHQL, fromHQL, whereHQL, groupHQL, orderHQL ].join( " " );
93               
94                def data = domainClass.executeQuery( retrieveHQL, queryParameters, [ max: num, offset: start ])
95               
96                def canWrite = true;
97               
98                def dataTablesStructure = [
99                        "sEcho": params.int( "sEcho" ),
100                        "iTotalRecords": total,
101                        "iTotalDisplayRecords": total,
102                        "aaData": data.collect( convertClosure ),
103                        "aIds": ids
104                ]
105
106               
107        }
108}
Note: See TracBrowser for help on using the repository browser.