root/trunk/src/groovy/dbnp/query/AssaySearch.groovy @ 1820

Revision 1820, 5.2 KB (checked in by robert@…, 3 years ago)

Adjusted querying process in order to improve speed with large amounts of data. The querying is now performed directly in HQL, instead of fetching all possible objects from the database and filtering them.

Line 
1/**
2 * AssaySearch Domain Class
3 *
4 * This class provides querying capabilities for searching for assays
5 *
6 * @author  Robert Horlings (robert@isdat.nl)
7 * @since       20110118
8 * @package     dbnp.query
9 *
10 * Revision information:
11 * $Rev: 1524 $
12 * $Author: robert@isdat.nl $
13 * $Date: 2011-02-15 15:05:23 +0100 (Tue, 15 Feb 2011) $
14 */
15package dbnp.query
16
17import groovy.lang.Closure;
18
19import java.util.Map;
20
21import dbnp.studycapturing.*
22import org.dbnp.gdt.*
23import org.apache.commons.logging.LogFactory;
24
25class AssaySearch extends Search {
26        private static final log = LogFactory.getLog(this);
27
28        public AssaySearch() {
29                super();
30
31                this.entity = "Assay";
32        }
33
34        /**
35         * Returns a closure for the given entitytype that determines the value for a criterion
36         * on the given object. The closure receives two parameters: the object and a criterion.
37         *
38         * For example:
39         *              For a study search, the object given is a study. How to determine the value for that study of
40         *              the criterion field of type sample? This is done by returning the field values for all
41         *              samples in the study
42         *                      { study, criterion -> return study.samples?.collect { criterion.getFieldValue( it ); } }
43         * @return
44         */
45        protected Closure valueCallback( String entity ) {
46                switch( entity ) {
47                        case "Study":
48                                return { assay, criterion -> return criterion.getFieldValue( assay.parent ) }
49                        case "Subject":
50                                return { assay, criterion -> return assay.samples?.parentSubject?.collect { criterion.getFieldValue( it ) } }
51                        case "Sample":
52                                return { assay, criterion -> return assay.samples?.collect { criterion.getFieldValue( it ) } }
53                        case "Event":
54                                return { assay, criterion ->
55                                        def values = []
56                                        assay.samples?.each { sample ->
57                                                if( sample && sample.parentEventGroup && sample.parentEventGroup.events && sample.parentEventGroup.events.size() > 0 ) {
58                                                        values << sample.parentEventGroup.events.collect { criterion.getFieldValue( it ) };
59                                                }
60                                        }
61                                        return values;
62                                }
63                        case "SamplingEvent":
64                                return { assay, criterion -> return assay.samples?.parentEvent?.collect { criterion.getFieldValue( it ) } }
65                        case "Assay":
66                                return { assay, criterion -> return criterion.getFieldValue( assay ) }
67                        default:
68                                return super.valueCallback( entity );
69                }
70        }
71
72       
73        /**
74         * Returns the HQL name for the element or collections to be searched in, for the given entity name
75         * For example: when searching for Subject.age > 50 with Study results, the system must search in all study.subjects for age > 50.
76         * But when searching for Sample results, the system must search in sample.parentSubject for age > 50
77         *
78         * @param entity        Name of the entity of the criterion
79         * @return                      HQL name for this element or collection of elements
80         */
81        protected String elementName( String entity ) {
82                switch( entity ) {
83                        case "Assay":                   return "assay"
84                        case "Sample":                  return "assay.samples"
85                        case "Study":                   return "assay.parent"
86                       
87                        case "Subject":                 return "assay.samples.parentSubject"                    // Will not be used, since entityClause() is overridden
88                        case "SamplingEvent":   return "assay.samples.parentEvent"                              // Will not be used, since entityClause() is overridden
89                        case "Event":                   return "assay.samples.parentEventGroup.events"  // Will not be used, since entityClause() is overridden
90                        default:                                return null;
91                }
92        }
93
94        /**
95         * Returns the a where clause for the given entity name
96         * For example: when searching for Subject.age > 50 with Study results, the system must search
97         *
98         *      WHERE EXISTS( FROM study.subjects subject WHERE subject IN (...)
99         *
100         * The returned string is fed to sprintf with 3 string parameters:
101         *              from (in this case 'study.subjects'
102         *              alias (in this case 'subject'
103         *              paramName (in this case '...')
104         *
105         * @param entity                Name of the entity of the criterion
106         * @return                      HQL where clause for this element or collection of elements
107         */
108        protected String entityClause( String entity ) {
109                switch( entity ) {
110                        case "Subject":
111                                return 'EXISTS( FROM assay.samples sample WHERE sample.parentSubject IN (:%3$s) )'
112                        case "SamplingEvent":
113                                return 'EXISTS( FROM assay.samples sample WHERE sample.parentEvent IN (:%3$s) )'
114                        case "Event":
115                                return 'EXISTS( FROM assay.samples sample WHERE EXISTS( FROM sample.parentEventGroup.events event WHERE event IN (:%3$s) ) )'
116                        default:
117                                return super.entityClause( entity );
118                }
119        }
120
121        /**
122         * Returns true iff the given entity is accessible by the user currently logged in
123         *
124         * @param entity                Study to determine accessibility for.
125         * @return                      True iff the user is allowed to access this study
126         */
127        protected boolean isAccessible( def entity ) {
128                return entity?.parent?.canRead( this.user );
129        }
130
131       
132        /**
133         * Returns the saved field data that could be shown on screen. This means, the data
134         * is filtered to show only data of the query results. Also, the study title and assay
135         * name are filtered out, in order to be able to show all data on the screen without
136         * checking further
137         *
138         * @return      Map with the entity id as a key, and a field-value map as value
139         */
140        public Map getShowableResultFields() {
141                Map showableFields = super.getShowableResultFields()
142                showableFields.each { sampleElement ->
143                        sampleElement.value = sampleElement.value.findAll { fieldElement ->
144                                fieldElement.key != "Study title" && fieldElement.key != "Assay name"
145                        }
146                }
147        }
148}
Note: See TracBrowser for help on using the browser.