diff --git a/uk/ac/sanger/artemis/chado/ChadoDAO.java b/uk/ac/sanger/artemis/chado/ChadoDAO.java index 9fead21aa7378bcafd221877dfc4d05d9404c65f..c5d1e9666a36c0f1b1c9a1e2fbb97cebdcbd8763 100644 --- a/uk/ac/sanger/artemis/chado/ChadoDAO.java +++ b/uk/ac/sanger/artemis/chado/ChadoDAO.java @@ -242,6 +242,26 @@ public interface ChadoDAO */ public int deleteFeatureDbxref(final String schema, final ChadoTransaction tsn) throws SQLException; + + /** + * Insert a synonym for a feature. + * @param schema schema/organism name or null + * @param tsn the <code>ChadoTransaction</code> + * @return number of rows changed + * @throws SQLException + */ + public int insertFeatureAlias(final String schema, final ChadoTransaction tsn) + throws SQLException; + + /** + * Delete a synonym for a feature. + * @param schema schema/organism name or null + * @param tsn the <code>ChadoTransaction</code> + * @return number of rows changed + * @throws SQLException + */ + public int deleteFeatureAlias(final String schema, final ChadoTransaction tsn) + throws SQLException; /** * diff --git a/uk/ac/sanger/artemis/chado/ChadoTransaction.java b/uk/ac/sanger/artemis/chado/ChadoTransaction.java index 88ef2b125cc45419b05692936c86206c307eb47d..398e435bf583861b84336661d232e97a63a69f9a 100644 --- a/uk/ac/sanger/artemis/chado/ChadoTransaction.java +++ b/uk/ac/sanger/artemis/chado/ChadoTransaction.java @@ -57,6 +57,10 @@ public class ChadoTransaction public static final int INSERT_DBXREF = 7; public static final int DELETE_DBXREF = 8; + // SYNONYM TRANSACTIONS + public static final int INSERT_ALIAS = 9; + public static final int DELETE_ALIAS = 10; + /** properties store <i>e.g.</i> value=<quote>product=hypothetical protein</quote> */ private List properties; /** constraint store <i>e.g.</i> type_id=21078 */ @@ -150,13 +154,22 @@ public class ChadoTransaction final Timestamp lastmodified, final Object feature_obj) { - this.type = type; + this.type = type; this.dbxref = dbxref; - this.uniquename = uniquename; + this.uniquename = uniquename; this.lastmodified = lastmodified; - this.feature_obj = feature_obj; + this.feature_obj = feature_obj; } + public ChadoTransaction(final int type, + final String uniquename, + final Object feature_obj) + { + this.type = type; + this.uniquename = uniquename; + this.feature_obj = feature_obj; + } + /** * The <code>Dbxref</code> used in a transaction. * @return the feature dbxref diff --git a/uk/ac/sanger/artemis/chado/ChadoTransactionManager.java b/uk/ac/sanger/artemis/chado/ChadoTransactionManager.java index 28e29bde78fafec40c72a2918098626b86a38998..b9fe00025c4e58a984737ac34ba955233b5f3bc6 100644 --- a/uk/ac/sanger/artemis/chado/ChadoTransactionManager.java +++ b/uk/ac/sanger/artemis/chado/ChadoTransactionManager.java @@ -72,8 +72,15 @@ public class ChadoTransactionManager "Dbxref", "Ontology_term", "score", - "gff_source", // program or database - "gff_seqname" }; // seqID of coord system + "gff_source", // program or database + "gff_seqname" }; // seqID of coord system + + private String synonym_tags[] = + { "synonym", // the rest are PSU synonyms + "gene", + "primary_name", + "reserved_name", + "obsolete_name" }; /** @@ -265,7 +272,7 @@ public class ChadoTransactionManager final String name = this_qualifier.getName(); // ignore reserved tags - if(isReservedTag(name)) + if(isReservedTag(name) || isSynonymTag(name)) continue; final StringVector qualifier_values = this_qualifier.getValues(); @@ -303,6 +310,19 @@ public class ChadoTransactionManager return false; } + /** + * Determine if this is a GFF3 predefined tag. + * @param tag + * @return true if the tag is a GFF3 predefined tag + */ + private boolean isSynonymTag(final String tag) + { + for(int i=0; i<synonym_tags.length; i++) + if(tag.equals(synonym_tags[i])) + return true; + return false; + } + /** * Compare the old and new keys and qualifiers and find the qualifiers * that have changed or been added and UPDATE, INSERT or DELETE accordingly. @@ -348,11 +368,17 @@ public class ChadoTransactionManager { final Qualifier this_qualifier = (Qualifier)qualifiers_old.elementAt(qualifier_index); String name = this_qualifier.getName(); - if(isReservedTag(name)) - continue; if(!qualifiers_new.contains(name)) { + if(isReservedTag(name) || isSynonymTag(name)) + { + handleReservedTags(feature, uniquename, + null, + this_qualifier); + continue; + } + // get the cvterm_id for this featureprop/qualifier Long lcvterm_id = DatabaseDocument.getCvtermID(name); if(lcvterm_id == null) // chado doesn't recognise this @@ -408,7 +434,7 @@ public class ChadoTransactionManager continue; } - if(isReservedTag(name)) + if(isReservedTag(name) || isSynonymTag(name)) { handleReservedTags(feature, uniquename, this_qualifier, @@ -519,38 +545,69 @@ public class ChadoTransactionManager final Qualifier new_qualifier, final Qualifier old_qualifier) { - final StringVector new_qualifier_strings = - StreamQualifier.toStringVector(null, new_qualifier); + StringVector new_qualifier_strings = null; - final StringVector old_qualifier_strings = - StreamQualifier.toStringVector(null, old_qualifier); + if(new_qualifier != null) + new_qualifier_strings = StreamQualifier.toStringVector(null, new_qualifier); - ChadoTransaction tsn; + StringVector old_qualifier_strings; + + if(old_qualifier != null) + old_qualifier_strings = StreamQualifier.toStringVector(null, old_qualifier); + else + old_qualifier_strings = new StringVector(); + + final String qualifier_name; + + if(old_qualifier != null) + qualifier_name = old_qualifier.getName(); + else + qualifier_name = new_qualifier.getName(); + + ChadoTransaction tsn = null; // find tags that have been deleted for(int i = 0; i < old_qualifier_strings.size(); ++i) { String qualifier_string = (String)old_qualifier_strings.elementAt(i); - if(!new_qualifier_strings.contains(qualifier_string)) + if( new_qualifier_strings == null || + !new_qualifier_strings.contains(qualifier_string) ) { int index = qualifier_string.indexOf("="); qualifier_string = qualifier_string.substring(index+1); - index = qualifier_string.lastIndexOf(":"); - System.out.println(uniquename+" in handleReservedTags() DELETE db="+ - qualifier_string.substring(0,index)+" acc="+qualifier_string.substring(index+1)); - Dbxref old_dbxref = new Dbxref(); - old_dbxref.setName(qualifier_string.substring(0,index)); - old_dbxref.setAccession(qualifier_string.substring(index+1)); - - tsn = new ChadoTransaction(ChadoTransaction.DELETE_DBXREF, - uniquename, old_dbxref, - feature.getLastModified(), - feature); + if(qualifier_name.equals("Dbxref")) + { + index = qualifier_string.lastIndexOf(":"); + + System.out.println(uniquename+" in handleReservedTags() DELETE db="+ + qualifier_string.substring(0,index)+" acc="+qualifier_string.substring(index+1)); + + Dbxref old_dbxref = new Dbxref(); + old_dbxref.setName(qualifier_string.substring(0,index)); + old_dbxref.setAccession(qualifier_string.substring(index+1)); + + tsn = new ChadoTransaction(ChadoTransaction.DELETE_DBXREF, + uniquename, old_dbxref, + feature.getLastModified(), + feature); + } + else if(isSynonymTag(qualifier_name)) + { + System.out.println(uniquename+" in handleReservedTags() DELETE "+qualifier_name+" "+ + qualifier_string); + tsn = new ChadoTransaction(ChadoTransaction.DELETE_ALIAS, + uniquename, + feature); + tsn.setConstraint("synonym.name", "'"+qualifier_string+"'"); + } sql.add(tsn); } } + if(new_qualifier_strings == null) + return; + // find tags that have been inserted for(int i = 0; i < new_qualifier_strings.size(); ++i) { @@ -559,18 +616,33 @@ public class ChadoTransactionManager { int index = qualifier_string.indexOf("="); qualifier_string = qualifier_string.substring(index+1); - index = qualifier_string.lastIndexOf(":"); - System.out.println(uniquename+" in handleReservedTags() INSERT db="+ + if(qualifier_name.equals("Dbxref")) + { + index = qualifier_string.lastIndexOf(":"); + + System.out.println(uniquename+" in handleReservedTags() INSERT db="+ qualifier_string.substring(0,index)+" acc="+qualifier_string.substring(index+1)); - Dbxref new_dbxref = new Dbxref(); - new_dbxref.setName(qualifier_string.substring(0,index)); - new_dbxref.setAccession(qualifier_string.substring(index+1)); - - tsn = new ChadoTransaction(ChadoTransaction.INSERT_DBXREF, - uniquename, new_dbxref, - feature.getLastModified(), - feature); + Dbxref new_dbxref = new Dbxref(); + new_dbxref.setName(qualifier_string.substring(0,index)); + new_dbxref.setAccession(qualifier_string.substring(index+1)); + + tsn = new ChadoTransaction(ChadoTransaction.INSERT_DBXREF, + uniquename, new_dbxref, + feature.getLastModified(), + feature); + } + else if(isSynonymTag(qualifier_name)) + { + System.out.println(uniquename+" in handleReservedTags() INSERT "+qualifier_name+" "+ + qualifier_string); + tsn = new ChadoTransaction(ChadoTransaction.INSERT_ALIAS, + uniquename, + feature); + tsn.setConstraint("synonym.name", "'"+qualifier_string+"'"); + Long lcvterm_id = DatabaseDocument.getCvtermID(qualifier_name); + tsn.addProperty("type_id", lcvterm_id.toString()); + } sql.add(tsn); } } diff --git a/uk/ac/sanger/artemis/chado/IBatisDAO.java b/uk/ac/sanger/artemis/chado/IBatisDAO.java index 104d78be73841e331201069adb0e0f69bf69939c..34e7aeff3d726a37fcfeab9a8c4de7eb5766d444 100644 --- a/uk/ac/sanger/artemis/chado/IBatisDAO.java +++ b/uk/ac/sanger/artemis/chado/IBatisDAO.java @@ -509,6 +509,32 @@ public class IBatisDAO implements ChadoDAO return sqlMap.delete("deleteFeatureDbxref", dbxref); } + /** + * Insert a synonym for a feature. + * @param schema schema/organism name or null + * @param tsn the <code>ChadoTransaction</code> + * @return number of rows changed + * @throws SQLException + */ + public int insertFeatureAlias(final String schema, final ChadoTransaction tsn) + throws SQLException + { + return 0; + } + + /** + * Delete a synonym for a feature. + * @param schema schema/organism name or null + * @param tsn the <code>ChadoTransaction</code> + * @return number of rows changed + * @throws SQLException + */ + public int deleteFeatureAlias(final String schema, final ChadoTransaction tsn) + throws SQLException + { + return 0; + } + /** * Write the time a feature was last modified * @param schema schema/organism name or null diff --git a/uk/ac/sanger/artemis/chado/JdbcDAO.java b/uk/ac/sanger/artemis/chado/JdbcDAO.java index 421e9aef81249341048c97bac54b3a0826cde984..c954c225a013e4fc7c467c324256480adff15a0d 100644 --- a/uk/ac/sanger/artemis/chado/JdbcDAO.java +++ b/uk/ac/sanger/artemis/chado/JdbcDAO.java @@ -879,6 +879,102 @@ public class JdbcDAO return st.executeUpdate(sql); } + /** + * Insert a synonym for a feature. + * @param schema schema/organism name or null + * @param tsn the <code>ChadoTransaction</code> + * @return number of rows changed + * @throws SQLException + */ + public int insertFeatureAlias(final String schema, final ChadoTransaction tsn) + throws SQLException + { + final String uniquename = tsn.getUniqueName(); + String sql; + + List constraints = tsn.getConstraint(); + String sqlAliasId = "SELECT synonym_id FROM "+schema+".synonym WHERE "+ + constraints.get(0); + + appendToLogFile(sqlAliasId, sqlLog); + Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, + ResultSet.CONCUR_UPDATABLE); + ResultSet rs = st.executeQuery(sqlAliasId); + boolean exists = rs.next(); + + if(!exists) + { + // create a new synonym name + String synonym_name = (String)constraints.get(0); + int index = synonym_name.indexOf("="); + synonym_name = synonym_name.substring(index+1); + + String type_id = (String)tsn.getPropertiesValue().get(0); + + sql = "INSERT INTO "+schema+ + ".synonym (name, type_id, synonym_sgml) values ( "+ + synonym_name+","+type_id+","+synonym_name+")" ; + + st.executeUpdate(sql); + appendToLogFile(sql, sqlLog); + + rs = st.executeQuery(sqlAliasId); + rs.next(); + appendToLogFile(sqlAliasId, sqlLog); + } + + final int synonym_id = rs.getInt("synonym_id"); + sql = "INSERT INTO "+schema+ + ".feature_synonym ( synonym_id, feature_id, pub_id )"+ + " values ( "+synonym_id+" ,"+ + "(SELECT feature_id FROM "+schema+ + ".feature WHERE uniquename='"+uniquename+"'), "+ + " 1)"; + + appendToLogFile(sql, sqlLog); + return st.executeUpdate(sql); + } + + /** + * Delete a synonym for a feature. + * @param schema schema/organism name or null + * @param tsn the <code>ChadoTransaction</code> + * @return number of rows changed + * @throws SQLException + */ + public int deleteFeatureAlias(final String schema, final ChadoTransaction tsn) + throws SQLException + { + final String uniquename = tsn.getUniqueName(); + List constraints = tsn.getConstraint(); + String sql = "SELECT synonym_id FROM "+schema+".feature_synonym WHERE "+ + "synonym_id=(SELECT synonym_id FROM "+schema+".synonym WHERE "+ + constraints.get(0)+")"; + + appendToLogFile(sql, sqlLog); + Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + ResultSet rs = st.executeQuery(sql); + rs.last(); + int nrows = rs.getRow(); + final int synonym_id = rs.getInt("synonym_id"); + + // check this name is not used some where else, + // i.e. in more than one row + if(nrows>1) + { + sql = "DELETE FROM "+schema+".feature_synonym WHERE "+ + "synonym_id="+synonym_id+" AND "+ + "feature_id=(SELECT feature_id FROM "+schema+ + ".feature WHERE uniquename='"+uniquename+"')"; + } + else + sql = "DELETE FROM "+schema+".synonym WHERE synonym_id="+synonym_id; + + st = conn.createStatement(); + return st.executeUpdate(sql); + } + /** * Write the time a feature was last modified * @param schema schema/organism name or null diff --git a/uk/ac/sanger/artemis/util/DatabaseDocument.java b/uk/ac/sanger/artemis/util/DatabaseDocument.java index f9dead2febbfe087bf721302fc2294459d208b05..1cf337902fe485aeac2f6ab90077232115f2d1a0 100644 --- a/uk/ac/sanger/artemis/util/DatabaseDocument.java +++ b/uk/ac/sanger/artemis/util/DatabaseDocument.java @@ -386,8 +386,6 @@ public class DatabaseDocument extends Document String name = feat.getUniquename(); String typeName = getCvtermName(type_id); -// SimpleDateFormat date_format = new SimpleDateFormat("MM.dd.yyyy hh:mm:ss z"); -// String timelastmodified = date_format.format(feat.getTimelastmodified()); String timelastmodified = Long.toString(feat.getTimelastmodified().getTime()); String feature_id = Integer.toString(feat.getId()); @@ -466,6 +464,7 @@ public class DatabaseDocument extends Document } } + // append synonyms if(synonym != null && synonym.containsKey(new Integer(feature_id))) { @@ -479,9 +478,8 @@ public class DatabaseDocument extends Document this_buff.append(alias.getCvterm_name()+"="); this_buff.append(alias.getName()); - //this_buff.append((String)v_synonyms.get(j)); if(j<v_synonyms.size()-1) - this_buff.append(","); + this_buff.append(";"); } } @@ -778,6 +776,10 @@ public class DatabaseDocument extends Document dao.deleteFeatureDbxref(schema, tsn); else if(tsn.getType() == ChadoTransaction.INSERT_DBXREF) dao.insertFeatureDbxref(schema, tsn); + else if(tsn.getType() == ChadoTransaction.DELETE_ALIAS) + dao.deleteFeatureAlias(schema, tsn); + else if(tsn.getType() == ChadoTransaction.INSERT_ALIAS) + dao.insertFeatureAlias(schema, tsn); }