source: trunk/src/groovy/dbnp/query/SampleSearch.groovy @ 1820

Last change on this file since 1820 was 1820, checked in by robert@…, 9 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.

  • Property svn:keywords set to Rev Author Date
File size: 4.9 KB
Line 
1/**
2 * SampleSearch Domain Class
3 *
4 * This class provides querying capabilities for searching for samples
5 *
6 * @author  Robert Horlings (robert@isdat.nl)
7 * @since       20110118
8 * @package     dbnp.query
9 *
10 * Revision information:
11 * $Rev: 1820 $
12 * $Author: robert@isdat.nl $
13 * $Date: 2011-05-06 15:41:49 +0000 (vr, 06 mei 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 SampleSearch extends Search {
26        private static final log = LogFactory.getLog(this);
27
28        public SampleSearch() {
29                super();
30
31                this.entity = "Sample";
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 { sample, criterion -> return criterion.getFieldValue( sample.parent ) }
49                        case "Subject":
50                                return { sample, criterion -> return criterion.getFieldValue( sample.parentSubject ); }
51                        case "Sample":
52                                return { sample, criterion -> return criterion.getFieldValue( sample ) }
53                        case "Event":
54                                return { sample, criterion ->
55                                        if( !sample || !sample.parentEventGroup || !sample.parentEventGroup.events || sample.parentEventGroup.events.size() == 0 )
56                                                return null
57
58                                        return sample.parentEventGroup.events?.collect { criterion.getFieldValue( it ) };
59                                }
60                        case "SamplingEvent":
61                                return { sample, criterion -> return criterion.getFieldValue( sample.parentEvent ); }
62                        case "Assay":
63                                return { sample, criterion ->
64                                        def sampleAssays = Assay.findByParent( sample.parent ).findAll { it.samples?.contains( sample ) };
65                                        if( sampleAssays && sampleAssays.size() > 0 )
66                                                return sampleAssays.collect { criterion.getFieldValue( it ) }
67                                        else
68                                                return null
69                                }
70                        default:
71                                return super.valueCallback( entity );
72                }
73        }
74
75        /**
76         * Returns the HQL name for the element or collections to be searched in, for the given entity name
77         * For example: when searching for Subject.age > 50 with Study results, the system must search in all study.subjects for age > 50.
78         * But when searching for Sample results, the system must search in sample.parentSubject for age > 50
79         *
80         * @param entity        Name of the entity of the criterion
81         * @return                      HQL name for this element or collection of elements
82         */
83        protected String elementName( String entity ) {
84                switch( entity ) {
85                        case "Sample":                  return "sample"
86                        case "Study":                   return "sample.parent"
87                        case "Subject":                 return "sample.parentSubject"
88                        case "SamplingEvent":   return "sample.parentEvent"
89                        case "Event":                   return "sample.parentEventGroup.events" 
90                        case "Assay":                   return "sample.assays"                  // Will not be used, since entityClause() is overridden
91                        default:                                return null;
92                }
93        }
94
95        /**
96         * Returns the a where clause for the given entity name
97         * For example: when searching for Subject.age > 50 with Study results, the system must search
98         *
99         *      WHERE EXISTS( FROM study.subjects subject WHERE subject IN (...)
100         *
101         * The returned string is fed to sprintf with 3 string parameters:
102         *              from (in this case 'study.subjects'
103         *              alias (in this case 'subject'
104         *              paramName (in this case '...')
105         *
106         * @param entity                Name of the entity of the criterion
107         * @return                      HQL where clause for this element or collection of elements
108         */
109        protected String entityClause( String entity ) {
110                switch( entity ) {
111                        case "Assay":
112                                return 'EXISTS( FROM Assay assay WHERE assay IN (:%3$s) AND EXISTS( FROM assay.samples assaySample WHERE assaySample = sample ) ) '
113                        default:
114                                return super.entityClause( entity );
115                }
116        }
117
118        /**
119         * Returns true iff the given entity is accessible by the user currently logged in
120         *
121         * @param entity                Study to determine accessibility for.
122         * @return                      True iff the user is allowed to access this study
123         */
124        protected boolean isAccessible( def entity ) {
125                return entity?.parent?.canRead( this.user );
126        }
127
128        /**
129         * Returns the saved field data that could be shown on screen. This means, the data
130         * is filtered to show only data of the query results. Also, the study title and sample
131         * name are filtered out, in order to be able to show all data on the screen without
132         * checking further
133         *
134         * @return      Map with the entity id as a key, and a field-value map as value
135         */
136        public Map getShowableResultFields() {
137                Map showableFields = super.getShowableResultFields()
138                showableFields.each { sampleElement ->
139                        sampleElement.value = sampleElement.value.findAll { fieldElement ->
140                                fieldElement.key != "Study title" && fieldElement.key != "Sample name"
141                        }
142                }
143        }
144}
Note: See TracBrowser for help on using the repository browser.