Plugin importing SD file to database

User faea122c03

06-06-2008 15:58:25

Hi, everyone!





Now I'm writing plugin which adds SD file to IJC database. For this purpose I wrote the following code:





MDFileReader sdfi = new MDFileReader(filename2);


List ids = edp.queryForIds(DFTermExpression.ALL_DATA, SortDirective.EMPTY, getEnvironment());


Map<String,Object> valuesToUpdate = new HashMap<String,Object>();


List<DFField> fields = entity.getFields().getItems();











while(true){


Molecule str = sdfi.getMolecule();


if(str == null) break;


MarvinStructure dbstr = new MarvinStructure(str);


valuesToUpdate.put(structureFieldId, dbstr);


for(int i=0; i<fields.size(); i++){


String fldid = fields.get(i).getId();


if(fldid.compareTo(structureFieldId) == 0)


continue;


Object fvalue = str.getPropertyObject(fldid);


if(fvalue != null){


valuesToUpdate.put(fldid, dbstr);


}


}


edp.insert(valuesToUpdate, null, getEnvironment());


}





However, by execution this code I obtained the exception message that SD file is invalid because it is not produced by MDFileWriter. Question: Which class should I use for SD file reading in this case?

ChemAxon fa971619eb

06-06-2008 16:05:39

MolImporter is probably your best bet.


If you need a slightly lower level approach then you might find MRecordReader useful.





Tim

User faea122c03

07-06-2008 10:59:19

tdudgeon wrote:
MolImporter is probably your best bet.


If you need a slightly lower level approach then you might find MRecordReader useful.





Tim
Thanks! MolImporter throws no exception in my case. However, structures are not added to the database. For this purpose I use the following code:








while(true){


Molecule str = sdfi.read();


if(str == null) break;


MarvinStructure dbstr = new MarvinStructure(str);


valuesToUpdate.put(structureFieldId, dbstr);


for(int i=0; i<fields.size(); i++){


String fldid = fields.get(i).getId();


if(fldid.compareTo(structureFieldId) == 0)


continue;


Object fvalue = str.getPropertyObject(fldid);


if(fvalue != null){


valuesToUpdate.put(fldid, dbstr);


}


}


edp.insert(valuesToUpdate, null, getEnvironment());


}





What is wrong here? How should I fix the code?

ChemAxon e189db4705

09-06-2008 08:57:41

I tried to test your code, I had to modify it a little as I didn't know the context. Here is my method with the context:





Code:
            final DFEntityDataProvider edp = DIFUtilities.findEntityDataProvider(entity);


            final List<DFField> fields = entity.getFields().getItems();


            DFField structureField = null;


            for (DFField f: fields) {


                if (DIFUtilities.findCapability(f, DFFieldStructureCapability.class) != null) {


                    structureField = f;


                    fields.remove(f);


                    break;


                }


            }


            if (structureField == null) {


                return;


            }


            final String structureFieldId = structureField.getId();


            UIBackgroundRunnerRW runner = new UIBackgroundRunnerRW(edp.getLockable(), "insert", true) {


                public void phase1InRequestProcessor() {


                    BufferedReader reader = null;


                    try {


                        Map<String,Object> valuesToUpdate = new HashMap<String,Object>();


                       


                        reader = new BufferedReader(new FileReader("c:\\x.smiles"));


                        while (true) {


                            String molStr = reader.readLine();


                            if (molStr == null) {


                                break;


                            }


                            MarvinStructure dbstr = new MarvinStructure(molStr);


                            valuesToUpdate.put(structureFieldId, dbstr);


                            edp.insert(valuesToUpdate, null, getEnvironment());


                        }


                    }


                    catch (IOException exc) {


                        exc.printStackTrace();


                    }


                    finally {


                        try {


                            if (reader != null)


                               reader.close();


                        } catch (IOException ex) {


                            Exceptions.printStackTrace(ex);


                        }


                    }


                }


            };


            runner.start();


        }








This code works for me.


I changed a few things, but these should not have impact on the functionality:


- reading and creating Molecule a little different way (I use smiles)


- I do not modify any other fields (actually I tested it on new empty jchem entity)





I see two potential problems in your code:


1. could you verify you are filling only data which should be inserted? I don't see the context, so don't know if you are not inserting e.g. molWeight, id field,... those fields are filled automatically and should not be part of valuesToUpdate. You can check "field.getRequired() != DFField.Required.AUTO" before you are changing the value for it? Actually if your code performs this and silently just does nothing then it's wrong. Is it this case?





2. if you have gridview opened during importing the data, it's NOT refreshed. New data doesn't appear in table until you run next query or press "show all button". The reason for this is that result set should ideally re-run whole query after any row is added to database table, but this is not possible of course. There is a workaround that row can be also added to active result set.





Let me know if it helps


Petr