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

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