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

Last change on this file since 7 was 7, checked in by robert@…, 8 years ago
  • Created tests for the synchronization and trash
  • Improved synchronizationservice and trash
  • Put authorization checks in several pages
File size: 11.2 KB
RevLine 
[4]1package nl.tno.metagenomics.integration
2
3import nl.tno.metagenomics.*
4
5class TrashService {
6
7        static transactional = true
8
9        /**
10         * Moves the valuable data from a study to trash and deletes the study
11         * @param               Study to move to trash
12         */
13        def moveToTrash( Study study ) {
14                log.trace "Moving study " + study + " to trash";
15                if( study.trashcan )
16                        return
[7]17
[4]18                saveDataInTrash( study );
[7]19               
20                def l = []
21                l += study.auth
22               
23                l.each { auth ->
24                        auth.user.removeFromAuth( auth );
25                        study.removeFromAuth( auth );
26                }
27               
[4]28                study.delete(flush:true);
29        }
[7]30
[4]31        /**
32         * Moves the valuable data from an assay to trash and deletes the assay
33         * @param               Assay to move to trash
34         */
35        def moveToTrash( Assay assay ) {
36                saveDataInTrash( assay );
[7]37
38                // Remove associations
39                def l = []
40                if( assay.runs ) {
41                        l += assay.runs
42                       
43                        l.each {
44                                if( it ) {
45                                        assay.removeFromRuns( it );
46                                        it.removeFromAssays( assay );
47                                }
48                        }
49                }
[4]50               
[7]51                l = []
52                l += assay.assaySamples
53               
54                l.each {
55                        it.sample.removeFromAssaySamples( it );
56                        assay.removeFromAssaySamples( it );
57                }
58
59                def study = assay.study
60                if( study ) {
61                        study.removeFromAssays( assay );
62                }
63               
64                /*
65                def assaySamples = assay.assaySamples.toList();
66                assaySamples.each {
67                        it.assay = null
68
69                        assay.removeFromAssaySamples( it );
70                        it.sample.removeFromAssaySamples( it );
71                        it.sample = null;
72                        it.delete( flush: true );
73                }
74
[4]75                assay.study.removeFromAssays( assay );
[7]76                assay.study.save();
77                //assay.study = null
78                //assay.delete(flush:true);
79                 */
[4]80        }
[7]81
[4]82        /**
83         * Moves the valuable data from a sample to trash and deletes the sample
84         * @param               Sample to move to trash
85         */
86        def moveToTrash( Sample sample ) {
87                saveDataInTrash( sample );
[7]88
89                // Remove associations
90                def l = []
91                l += sample.assaySamples
[4]92               
[7]93                l.each {
94                        it.assay.removeFromAssaySamples( it );
95                        sample.removeFromAssaySamples( it );
96                }
97               
98                def study = sample.study
[4]99                sample.study.removeFromSamples( sample );
[7]100                study.save();
[4]101        }
102
103        /**
[7]104        * Moves the valuable data from an assaySample to trash and deletes the assay
105        * @param                Assay to move to trash
106        */
107   def moveToTrash( AssaySample assaySample ) {
108           saveDataInTrash( assaySample );
109
110           // Remove associations
111           if( assaySample.run ) {
112                   assaySample.run.removeFromAssaySamples( assaySample );
113           }
114           
115           if( assaySample.assay ) {
116                   assaySample.assay.removeFromAssaySamples( assaySample );
117           }
118
119           if( assaySample.sample ) {
120                   assaySample.sample.removeFromAssaySamples( assaySample );
121           }
122           
123           def l = []
124           l += assaySample.sequenceData
125           
126           l.each {
127                   if( it ) {
128                                assaySample.removeFromSequenceData( it );
129                   }
130           }
131           
132   }
133       
134        /**
[4]135         * Saves data from the study in the trash can (if any data exists)
136         * @param study         Study to save data from
137         * @return
138         */
139        def saveDataInTrash( Study study ) {
[7]140                Study trashcan = this.giveTrashcan()
[4]141
142                if( !trashcan ) {
143                        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."
144                        return;
145                }
146
147                // Loop through all assays, and see if there are assay samples
148                // that have data
149                study.assays.each { assay ->
150                        saveDataInTrash( assay );
151                }
152        }
153
154        /**
155         * Saves data from the assay in the trash can (if any data exists)
156         * @param study         Assay to save data from
157         * @return
158         */
159        def saveDataInTrash( Assay assay ) {
[7]160                Study trashcan = this.giveTrashcan()
[4]161
162                if( !trashcan ) {
163                        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."
164                        return;
165                }
166
167                def assaySamples = assay.assaySamples.findAll { it.containsData() }
168
169                // For every assay sample that contains data, save that data in the trashcan
170                if( assaySamples.size() > 0 ) {
171                        // Create a dummy assay copy of the existing assay
172                        String newAssayToken = 'TrashAssay ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
173
174                        Assay dummyAssay = new Assay( assayToken: newAssayToken, name: assay.name, study: trashcan );
175                        trashcan.addToAssays( dummyAssay );
176                        dummyAssay.save()
177
178                        assaySamples.each { assaySample ->
179                                Sample sample = assaySample.sample
[7]180
[4]181                                // Create dummy sample
182                                String newSampleToken = 'TrashSample ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
183                                Sample dummySample = new Sample( sampleToken: newSampleToken, name: sample.name, study: trashcan );
184                                trashcan.addToSamples( dummySample );
185                                dummySample.save()
186
187                                // Create dummy assay sample
188                                AssaySample dummyAssaySample = new AssaySample( assay: dummyAssay, sample: dummySample );
189
190                                dummyAssay.addToAssaySamples( dummyAssaySample );
191                                dummySample.addToAssaySamples( dummyAssaySample );
192                                dummyAssaySample.save();
193
194                                // Move data from this assay sample to the trash version of it
195                                assaySample.moveValuableDataTo( dummyAssaySample );
196                                dummyAssaySample.save();
197                        }
198                }
199        }
200
201        /**
202         * Saves data from the sample in the trash can (if any data exists)
203         * @param study         Sample to save data from
204         * @return
205         */
206        def saveDataInTrash( Sample sample ) {
[7]207                Study trashcan = this.giveTrashcan()
[4]208
209                if( !trashcan ) {
210                        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."
211                        return;
212                }
213
214                def assaySamples = sample.assaySamples.findAll { it.containsData() }
215
216                // For every assay sample that contains data, save that data in the trashcan
217                if( assaySamples.size() > 0 ) {
218                        // Create dummy sample
219                        String newSampleToken = 'TrashSample ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
220                        Sample dummySample = new Sample( sampleToken: newSampleToken, name: sample.name, study: trashcan );
221                        trashcan.addToSamples( dummySample );
222                        dummySample.save()
223
224                        assaySamples.each { assaySample ->
225                                Assay assay = assaySample.assay;
226
227                                // Create a dummy assay copy of the existing assay
228                                String newAssayToken = 'TrashAssay ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
229
230                                Assay dummyAssay = new Assay( assayToken: newAssayToken, name: assay.name, study: trashcan );
231                                trashcan.addToAssays( dummyAssay );
232                                dummyAssay.save()
233
234                                // Create dummy assay sample
235                                AssaySample dummyAssaySample = new AssaySample( assay: dummyAssay, sample: dummySample );
236
237                                dummyAssay.addToAssaySamples( dummyAssaySample );
238                                dummySample.addToAssaySamples( dummyAssaySample );
239                                dummyAssaySample.save();
240
241                                // Move data from this assay sample to the trash version of it
242                                assaySample.moveValuableDataTo( dummyAssaySample );
243                                dummyAssaySample.save();
244                        }
245                }
246        }
247
[7]248       
[4]249        /**
[7]250        * Saves data from the assay-sample in the trash can (if any data exists)
251        * @param study          Sample to save data from
252        * @return
253        */
254   def saveDataInTrash( AssaySample assaySample ) {
255           Study trashcan = this.giveTrashcan()
256
257           if( !trashcan ) {
258                   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."
259                   return;
260           }
261
262           // For every assay sample that contains data, save that data in the trashcan
263           if( assaySample.containsData() ) {
264                   // Create dummy sample
265                   String newSampleToken = 'TrashSample ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
266                   Sample dummySample = new Sample( sampleToken: newSampleToken, name: assaySample.sample.name, study: trashcan );
267                   trashcan.addToSamples( dummySample );
268                   dummySample.save()
269
270                   Assay assay = assaySample.assay;
271
272                   // Create a dummy assay copy of the existing assay
273                   String newAssayToken = 'TrashAssay ' + new Date().format( 'yyyyMMddHHmmssSSS') + ( Math.random() * 10000 );
274
275                   Assay dummyAssay = new Assay( assayToken: newAssayToken, name: assay.name, study: trashcan );
276                   trashcan.addToAssays( dummyAssay );
277                   dummyAssay.save()
278
279                   // Create dummy assay sample
280                   AssaySample dummyAssaySample = new AssaySample( assay: dummyAssay, sample: dummySample );
281
282                   dummyAssay.addToAssaySamples( dummyAssaySample );
283                   dummySample.addToAssaySamples( dummyAssaySample );
284                   dummyAssaySample.save();
285
286                   // Move data from this assay sample to the trash version of it
287                   assaySample.moveValuableDataTo( dummyAssaySample );
288                   dummyAssaySample.save();
289           }
290   }
291
292        /**
293         * Retrieves the trashcan study from the database
294         */
295        def giveTrashcan = {
296                def study = Study.findByTrashcan( true );
297
298                if( !study )
299                        return null;
300                else
301                        return study
302        }
303       
304        /**
305         * Creates a new trashcan study. Should only be used by the bootstrap to create a trashcan
306         */
307        def createTrashcan = {
308                def study = new Study( name: "Trashcan", studyToken: "trash", trashcan: true )
309                study.save();
310        }
311
312        /**
[4]313         * Cleans up the trash by removing empty assays or samples. Empty means:
314         *      - an assay with samples
315         *  - a sample without sequences, tag sequence and oligo number
316         * 
317         *  Also removes samples in trash that are not referenced by an assaysample
318         */
319        def cleanTrash = {
320                def studies = Study.findAllByTrashcan( true );
[7]321
[4]322                studies.each { study ->
323                        def numAssays = study.assays?.size()
324                        def assayList = study.assays?.toList();
[7]325
[4]326                        def numSamples
327                        def sampleList
[7]328
[4]329                        // Loop backwards through the assays in order to facilitate removing assays
330                        for( def i = numAssays -1; i >= 0; i-- ) {
331                                // Loop through all samples and remove the ones that are empty
332                                if( assayList[ i ].assaySamples != null ) {
333                                        numSamples = assayList[ i ].assaySamples.size()
334                                        sampleList = assayList[ i ].assaySamples.toList();
[7]335
[4]336                                        for( def j = numSamples - 1; j >= 0; j-- ) {
337                                                def s = sampleList[ j ];
338                                                if( !s.tagSequence && !s.oligoNumber && s.numSequences() == 0 ) {
339                                                        assayList[ i ].removeFromAssaySamples( s );
340                                                        s.sample?.delete();
341                                                        s.delete();
342                                                }
343                                        }
344                                }
345
346                                // Now check if there are samples left. Otherwise, remove the assay
347                                if( assayList[i].assaySamples == null || assayList[i].assaySamples.size() == 0 ) {
348                                        study.removeFromAssays( assayList[ i ] );
349                                        assayList[i].delete();
[7]350                                }
[4]351                        }
[7]352
[4]353                        // Loop through samples and delete the ones not referenced by an assaysample
354                        /*
[7]355                         numSamples = study.samples?.size()
356                         sampleList = study.samples?.toList();
357                         for( def j = numSamples - 1; j >= 0; j-- ) {
358                         def s = sampleList[ j ];
359                         if( s.assaySamples == null || s.assaySamples.size() == 0 ) {
360                         study.removeFromSamples(s);
361                         s.delete(flush:true);
362                         }
363                         }
364                         */
[4]365                }
366        }
[7]367
[4]368        /**
369         * Restore an assay from trash and put the contents of the assay in another assay
370         * @param assay
371         * @param restoreTo
372         */
373        public void restoreAssay( Assay assay, Assay restoreTo ) {
374                // Loop through all assaysamples and restore the ones that have a matching name
375                assay.assaySamples.each { assaySample ->
376                        if( assaySample ) {
377                                // Find a sample with the same name
378                                def restoreSample = restoreTo.assaySamples.find { it.sample?.name == assaySample.sample?.name }
[7]379
[4]380                                if( restoreSample ) {
381                                        this.restoreSample( assaySample, restoreSample );
382                                }
383                        }
384                }
385        }
[7]386
[4]387        /**
388         * Restore a sample from trash and put the contents of the sample into another sample
389         * @param sample
390         * @param restoreTo
391         */
392        public void restoreSample( AssaySample sample, AssaySample restoreTo ) {
393                sample.moveValuableDataTo( restoreTo );
394                restoreTo.save();
395        }
396}
Note: See TracBrowser for help on using the repository browser.