source: trunk/grails-app/services/nl/tno/metagenomics/integration/TrashService.groovy @ 4

Last change on this file since 4 was 4, checked in by robert@…, 8 years ago

Implemented trash in order to prevent deletion of data

File size: 7.5 KB
Line 
1package nl.tno.metagenomics.integration
2
3import nl.tno.metagenomics.*
4
5
6class TrashService {
7
8        static transactional = true
9
10        /**
11         * Moves the valuable data from a study to trash and deletes the study
12         * @param               Study to move to trash
13         */
14        def moveToTrash( Study study ) {
15                log.trace "Moving study " + study + " to trash";
16                if( study.trashcan )
17                        return
18                       
19                saveDataInTrash( study );
20                study.delete(flush:true);
21        }
22       
23        /**
24         * Moves the valuable data from an assay to trash and deletes the assay
25         * @param               Assay to move to trash
26         */
27        def moveToTrash( Assay assay ) {
28                saveDataInTrash( assay );
29               
30                // Remove associations
31                assay.study.removeFromAssays( assay );
32                assay.delete(flush:true);
33        }
34       
35        /**
36         * Moves the valuable data from a sample to trash and deletes the sample
37         * @param               Sample to move to trash
38         */
39        def moveToTrash( Sample sample ) {
40                saveDataInTrash( sample );
41               
42                // Remove associations
43                sample.study.removeFromSamples( sample );
44                sample.delete(flush:true);
45        }
46
47        /**
48         * Saves data from the study in the trash can (if any data exists)
49         * @param study         Study to save data from
50         * @return
51         */
52        def saveDataInTrash( Study study ) {
53                Study trashcan = Study.findByTrashcan(true);
54
55                if( !trashcan ) {
56                        log.warn "No trashcan (study with trashcan property set to true) found in the database when deleting study " + study.name + ". Possibly valuable data is deleted forever."
57                        return;
58                }
59
60                // Loop through all assays, and see if there are assay samples
61                // that have data
62                study.assays.each { assay ->
63                        saveDataInTrash( assay );
64                }
65        }
66
67        /**
68         * Saves data from the assay in the trash can (if any data exists)
69         * @param study         Assay to save data from
70         * @return
71         */
72        def saveDataInTrash( Assay assay ) {
73                Study trashcan = Study.findByTrashcan(true);
74
75                if( !trashcan ) {
76                        log.warn "No trashcan (study with trashcan property set to true) found in the database when deleting assay " + assay.name + ". Possibly valuable data is deleted forever."
77                        return;
78                }
79
80                def assaySamples = assay.assaySamples.findAll { it.containsData() }
81
82                // For every assay sample that contains data, save that data in the trashcan
83                if( assaySamples.size() > 0 ) {
84                        // Create a dummy assay copy of the existing assay
85                        String newAssayToken = 'TrashAssay ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
86
87                        Assay dummyAssay = new Assay( assayToken: newAssayToken, name: assay.name, study: trashcan );
88                        trashcan.addToAssays( dummyAssay );
89                        dummyAssay.save()
90
91                        assaySamples.each { assaySample ->
92                                Sample sample = assaySample.sample
93                               
94                                // Create dummy sample
95                                String newSampleToken = 'TrashSample ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
96                                Sample dummySample = new Sample( sampleToken: newSampleToken, name: sample.name, study: trashcan );
97                                trashcan.addToSamples( dummySample );
98                                dummySample.save()
99
100                                // Create dummy assay sample
101                                AssaySample dummyAssaySample = new AssaySample( assay: dummyAssay, sample: dummySample );
102
103                                dummyAssay.addToAssaySamples( dummyAssaySample );
104                                dummySample.addToAssaySamples( dummyAssaySample );
105                                dummyAssaySample.save();
106
107                                // Move data from this assay sample to the trash version of it
108                                assaySample.moveValuableDataTo( dummyAssaySample );
109                                dummyAssaySample.save();
110                        }
111                }
112        }
113
114        /**
115         * Saves data from the sample in the trash can (if any data exists)
116         * @param study         Sample to save data from
117         * @return
118         */
119        def saveDataInTrash( Sample sample ) {
120                Study trashcan = Study.findByTrashcan(true);
121
122                if( !trashcan ) {
123                        log.warn "No trashcan (study with trashcan property set to true) found in the database when deleting sample " + sample.name + ". Possibly valuable data is deleted forever."
124                        return;
125                }
126
127                def assaySamples = sample.assaySamples.findAll { it.containsData() }
128
129                // For every assay sample that contains data, save that data in the trashcan
130                if( assaySamples.size() > 0 ) {
131                        // Create dummy sample
132                        String newSampleToken = 'TrashSample ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
133                        Sample dummySample = new Sample( sampleToken: newSampleToken, name: sample.name, study: trashcan );
134                        trashcan.addToSamples( dummySample );
135                        dummySample.save()
136
137                        assaySamples.each { assaySample ->
138                                Assay assay = assaySample.assay;
139
140                                // Create a dummy assay copy of the existing assay
141                                String newAssayToken = 'TrashAssay ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
142
143                                Assay dummyAssay = new Assay( assayToken: newAssayToken, name: assay.name, study: trashcan );
144                                trashcan.addToAssays( dummyAssay );
145                                dummyAssay.save()
146
147                                // Create dummy assay sample
148                                AssaySample dummyAssaySample = new AssaySample( assay: dummyAssay, sample: dummySample );
149
150                                dummyAssay.addToAssaySamples( dummyAssaySample );
151                                dummySample.addToAssaySamples( dummyAssaySample );
152                                dummyAssaySample.save();
153
154                                // Move data from this assay sample to the trash version of it
155                                assaySample.moveValuableDataTo( dummyAssaySample );
156                                dummyAssaySample.save();
157                        }
158                }
159        }
160
161        /**
162         * Cleans up the trash by removing empty assays or samples. Empty means:
163         *      - an assay with samples
164         *  - a sample without sequences, tag sequence and oligo number
165         * 
166         *  Also removes samples in trash that are not referenced by an assaysample
167         */
168        def cleanTrash = {
169                def studies = Study.findAllByTrashcan( true );
170               
171                studies.each { study ->
172                        def numAssays = study.assays?.size()
173                        def assayList = study.assays?.toList();
174                       
175                        def numSamples
176                        def sampleList
177                       
178                        // Loop backwards through the assays in order to facilitate removing assays
179                        for( def i = numAssays -1; i >= 0; i-- ) {
180                                // Loop through all samples and remove the ones that are empty
181                                if( assayList[ i ].assaySamples != null ) {
182                                        numSamples = assayList[ i ].assaySamples.size()
183                                        sampleList = assayList[ i ].assaySamples.toList();
184                                       
185                                        for( def j = numSamples - 1; j >= 0; j-- ) {
186                                                def s = sampleList[ j ];
187                                                if( !s.tagSequence && !s.oligoNumber && s.numSequences() == 0 ) {
188                                                        assayList[ i ].removeFromAssaySamples( s );
189                                                        s.sample?.delete();
190                                                        s.delete();
191                                                }
192                                        }
193                                }
194
195                                // Now check if there are samples left. Otherwise, remove the assay
196                                if( assayList[i].assaySamples == null || assayList[i].assaySamples.size() == 0 ) {
197                                        study.removeFromAssays( assayList[ i ] );
198                                        assayList[i].delete();
199                                } 
200                        }
201                       
202                        // Loop through samples and delete the ones not referenced by an assaysample
203                        /*
204                        numSamples = study.samples?.size()
205                        sampleList = study.samples?.toList();
206                       
207                        for( def j = numSamples - 1; j >= 0; j-- ) {
208                                def s = sampleList[ j ];
209                                if( s.assaySamples == null || s.assaySamples.size() == 0 ) {
210                                        study.removeFromSamples(s);
211                                        s.delete(flush:true);
212                                }
213                        }
214                        */
215                }
216        }
217       
218        /**
219         * Restore an assay from trash and put the contents of the assay in another assay
220         * @param assay
221         * @param restoreTo
222         */
223        public void restoreAssay( Assay assay, Assay restoreTo ) {
224                // Loop through all assaysamples and restore the ones that have a matching name
225                assay.assaySamples.each { assaySample ->
226                        if( assaySample ) {
227                                // Find a sample with the same name
228                                def restoreSample = restoreTo.assaySamples.find { it.sample?.name == assaySample.sample?.name }
229                               
230                                if( restoreSample ) {
231                                        this.restoreSample( assaySample, restoreSample );
232                                }
233                        }
234                }
235        }
236       
237        /**
238         * Restore a sample from trash and put the contents of the sample into another sample
239         * @param sample
240         * @param restoreTo
241         */
242        public void restoreSample( AssaySample sample, AssaySample restoreTo ) {
243                sample.moveValuableDataTo( restoreTo );
244                restoreTo.save();
245        }
246}
Note: See TracBrowser for help on using the repository browser.