Changeset 1945

Show
Ignore:
Timestamp:
29-06-11 10:10:48 (3 years ago)
Author:
robert@…
Message:

- Updated the import algorithm in the simpleWizard, so it won't be too slow with > 200 samples
- Changed the warning added in r1944 so the user knows why the import will be slow

Location:
trunk/grails-app
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/studycapturing/SimpleWizardController.groovy

    r1944 r1945  
    4545                                flow.study = getStudyFromRequest( params ) 
    4646                                if (!flow.study) retrievalError() 
    47  
     47                                 
     48                                // Save number of samples in flow 
     49                                flow.numExistingSamples = 0 
     50                                if( flow.study.id ) { 
     51                                        flow.numExistingSamples = Sample.countByParent( flow.study ); 
     52                                } 
     53                                 
    4854                                // Search for studies 
    4955                                flow.studies = Study.giveWritableStudies( authenticationService.getLoggedInUser(), 100 ) 
     
    823829        // loop through all entities to validate them and add them to failedcells if an error occurs 
    824830        def numInvalidEntities = 0; 
    825         def errors = []; 
     831        def entityErrors = []; 
    826832 
    827833        // Add all samples 
    828834        table.each { record -> 
    829835            record.each { entity -> 
     836                                 
    830837                if( entity ) { 
    831838                    // Determine entity class and add a parent. Add the entity to the study 
     
    838845                    switch( entity.class ) { 
    839846                        case Sample:                                                    // instantiate a sample 
    840                                                         def newSample = new Sample( 
    841                                                                         parentSubject   : subject, 
    842                                                                         parentEvent             : samplingEvent, 
    843                                                                         parentEventGroup: eventGroup, 
    844                                                                         name                    : sampleName, 
    845                                                                         template                : (samplingEvent.sampleTemplate) ? samplingEvent.sampleTemplate : '' 
    846                                                                 ) 
    847  
    848                                                         flow.study.addToSamples(newSample) 
    849847                            if( !study.samples?.find( equalClosure ) ) { 
    850848                                study.addToSamples( entity ); 
    851849                            } 
    852  
     850                                                         
    853851                            // If an eventgroup is created, add it to the study 
    854852                            // The eventgroup must have a unique name, but the user shouldn't be bothered with it 
     
    863861                                } 
    864862                            } 
    865  
     863                                                         
    866864                            break; 
    867865                        case Subject: 
    868                             if( !study.samples?.find( equalClosure ) ) { 
    869  
     866                                                        if( !study.subjects?.find( equalClosure ) ) { 
     867         
    870868                                if( preferredIdentifier ) { 
    871869                                    // Subjects without a name should just be called 'subject' 
     
    884882 
    885883                                study.addToSubjects( entity ); 
    886  
    887                             } 
     884                            }  
    888885 
    889886                            break; 
     
    905902                            break; 
    906903                    } 
    907  
     904                                         
    908905                    if (!entity.validate()) { 
    909906                        numInvalidEntities++; 
     
    916913                        if( currentErrors ) { 
    917914                            currentErrors.each { 
    918                                 errors += "(" + entityName + ") " + it.value; 
     915                                entityErrors += "(" + entityName + ") " + it.value; 
    919916                            } 
    920917                        } 
     
    925922 
    926923                flow.imported.numInvalidEntities = numInvalidEntities + failedcells?.size(); 
    927                 flow.imported.errors = errors; 
     924                flow.imported.errors = entityErrors; 
    928925 
    929926                return true 
     
    941938        def handleMissingFields( study, params, flow ) { 
    942939                def numInvalidEntities = 0; 
    943                 def errors = []; 
     940                def entityErrors = []; 
    944941 
    945942                // Check which fields failed previously 
     
    989986                                        if( currentErrors ) { 
    990987                                                currentErrors.each { 
    991                                                         errors += "(" + entityName + ") " + it.value; 
     988                                                        entityErrors += "(" + entityName + ") " + it.value; 
    992989                                                } 
    993990                                        } 
     
    1002999                flow.imported.failedCells = newFailedCells 
    10031000                flow.imported.numInvalidEntities = numInvalidEntities; 
    1004                 flow.imported.errors = errors; 
     1001                flow.imported.errors = entityErrors; 
    10051002 
    10061003                return numInvalidEntities == 0 
  • trunk/grails-app/domain/dbnp/studycapturing/Sample.groovy

    r1922 r1945  
    142142           Sample s = (Sample) o; 
    143143            
    144            return this.id == s.id 
     144           return this.is(s) || this.id == s.id 
    145145   } 
    146146         
  • trunk/grails-app/services/dbnp/importer/ImporterService.groovy

    r1684 r1945  
    2222class ImporterService { 
    2323        def authenticationService 
     24        def sessionFactory 
    2425 
    2526        static transactional = false 
     
    258259                if( !mcmap ) 
    259260                        return; 
     261                         
     262                def hibernateSession = sessionFactory.getCurrentSession()  
    260263 
    261264                // Check whether the rows should be imported in one or more entities 
     
    269272                def sheet = wb.getSheetAt(sheetindex) 
    270273                def table = [] 
     274                def samples = [] 
    271275                def failedcells = [] // list of cells that have failed to import 
    272276                 
     
    287291                        if( row && !rowIsEmpty( row ) ) { 
    288292                                // Create an entity record based on a row read from Excel and store the cells which failed to be mapped 
    289                                 def (record, failed) = importOrUpdateRecord( templates, entities, row, mcmap, parent, table, existingEntities[i] ); 
    290          
     293                                def (record, failed) = importOrUpdateRecord( templates, entities, row, mcmap, parent, samples, existingEntities[i] ); 
     294 
    291295                                // Setup the relationships between the imported entities 
    292296                                relateEntities( record ); 
    293          
     297 
    294298                                // Add record with entities and its values to the table 
    295299                                table.add(record) 
    296          
     300 
    297301                                // If failed cells have been found, add them to the failed cells list 
    298302                                if (failed?.importcells?.size() > 0) failedcells.add(failed) 
     303                                 
     304                                // Add a sample to the list of samples if possible 
     305                                def sample = record.find { it instanceof dbnp.studycapturing.Sample } 
     306                                if( sample && !samples.contains( sample ) ) 
     307                                        samples << sample 
    299308                        } 
    300309                } 
     
    357366         * @param       mcmap           Hashmap of mappingcolumns, with the first entry in the hashmap containing information about the first column, etc. 
    358367         * @param       parent          Study to import all data into. Is used for determining which sample/event/subject/assay to update 
    359          * @param       importedRows    Rows that have been imported before this row. These rows might contain the same entities as are 
    360          *                                                      imported in this row. These entities should be used again, to avoid importing duplicates. 
     368         * @param       importedSamples Samples that have been imported before this row. These entities should be used again if possible,  
     369         *                                                      to avoid importing duplicates. 
    361370         * @return      List            List with two entries: 
    362371         *                      0                       List with ImportRecords, one for each row in the excelsheet 
     
    364373         *                                              (because the value in the excelsheet can't be entered into the template field) 
    365374         */ 
    366         def importOrUpdateRecord(def templates, def entities, Row excelRow, mcmap, Study parent = null, List importedRows, Map existingEntities ) { 
     375        def importOrUpdateRecord(def templates, def entities, Row excelRow, mcmap, Study parent = null, List importedSamples, Map existingEntities ) { 
    367376                DataFormatter df = new DataFormatter(); 
    368377                def record = [] // list of entities and the read values 
    369378                def failed = new ImportRecord() // map with entity identifier and failed mappingcolumn 
    370379 
     380                def currentTime = System.currentTimeMillis(); 
     381                 
    371382                // Check whether this record mentions a sample that has been imported before. In that case, 
    372383                // we update that record, in order to prevent importing the same sample multiple times 
    373384                def importedEntities = []; 
    374                 if( importedRows ) 
    375                         importedEntities = importedRows.flatten().findAll { it.class == dbnp.studycapturing.Sample }.unique(); 
     385                if( importedSamples ) 
     386                        importedEntities = importedSamples 
    376387 
    377388                def importedSample = findEntityInImportedEntities( dbnp.studycapturing.Sample, excelRow, mcmap, importedEntities, df ) 
  • trunk/grails-app/views/simpleWizard/simpleWizard/columns.gsp

    r1944 r1945  
    3333                                Please match the columns from the excel file with the fields in the database. 
    3434                        </span>  
    35                         <g:if test="${excel.numDataRows > 200}"> 
     35                        <g:if test="${excel.numDataRows > 300}"> 
    3636                                <span class="info"> 
    37                                         <span class="error" style="background-position: 0 50%;">Too many samples in excel file</span>  
    38                                         Your uploaded excel file contains more than 200 samples. This wizard might become very slow when importing that many samples.<br /> 
    39                                         The best you can do is to save your study (go back to the first page of the wizard and click save), and use the <i>Import</i> -&gt;  
    40                                         <i>A part or a study design</i> menu option. 
     37                                        <span class="error" style="background-position: 0 50%;">Many samples in excel file</span>  
     38                                        Your uploaded excel file contains more than 300 samples. This wizard might become less responsive when importing that many samples, but 
     39                                        will still be working properly.<br /> 
     40                                        Please be patient when importing the data and saving your study. 
    4141                                </span>  
    4242                        </g:if> 
  • trunk/grails-app/views/simpleWizard/simpleWizard/study.gsp

    r1686 r1945  
    3434                        filled out, the more valuable the system will be. 
    3535                </span> 
     36                 
     37                <g:if test="${numExistingSamples > 300}"> 
     38                        <span class="info"> 
     39                                <span class="error" style="background-position: 0 50%;">Many samples in study</span>  
     40                                Your study contains more than 300 samples. This wizard might become less responsive when editing that many samples, but will still function properly.<br /> 
     41                                Please be patient when editing samples and saving your study. 
     42                        </span>  
     43                </g:if> 
     44                 
    3645                 
    3746                <g:if test="${flash.validationErrors}">