[Biojava-dev] DeleteStyle in BioSQL using mysql
S. Foote
foote at nrcbsa.bio.nrc.ca
Fri Sep 12 07:53:10 EDT 2003
Hi Len,
The on delete cascade allows you to delete a row from a table and any other rows in other tables that
are referenced to that row.
Hence, "delete from location using location, seqfeature where
location.seqfeature_id=seqfeature_seqfeature_id
and seqfeature.bioentry_id=?" means:
delete rows from location by finding the relevant rows using the seqfeature table id which is
referenced in the location table having the given bioentry_id
Thus, it automatically determines the list of seqfeature ids for the given bioentry_id that need
deleting and in turn finds all the locations that relate to those features.
So, with mysql < 4.0.0, you will need to find each seqfeature_id and remove it individually.
Luckily, this had popped up before and someone had submitted a hack that does just this. You could
probably find it in the list archives somewhere, but I just found a copy. I'll put it below.
Cheers,
Simon
private void _removeSequence(String id)
throws BioException, IllegalIDException, ChangeVetoException
{
Sequence seq = (Sequence) sequencesByName.get(id);
if (seq != null) {
seq = null; // Don't want to be holding the reference ourselves!
try {
Thread.sleep(100L);
System.gc();
} catch (Exception ex) {
ex.printStackTrace();
}
seq = (Sequence) sequencesByName.get(id);
if (seq != null) {
throw new BioException("There are still references to sequence with ID "
+ id + " from this database.");
}
}
Connection conn = null;
try {
conn = pool.takeConnection();
conn.setAutoCommit(false);
int bioentry_id = -1;
int biosequence_id = -1;
ArrayList featureIdList = null;
PreparedStatement get_sequence =
conn.prepareStatement("select bioentry.bioentry_id,
biosequence.biosequence_id " +
"from bioentry, biosequence " +
"where bioentry.accession = ? and " +
" biosequence.bioentry_id = bioentry.bioentry_id");
get_sequence.setString(1, id);
ResultSet rs = get_sequence.executeQuery();
boolean exists;
if ((exists = rs.next())) {
bioentry_id = rs.getInt(1);
biosequence_id = rs.getInt(2);
}
System.out.println("Simon: " + bioentry_id);
get_sequence.close();
if ( bioentry_id != -1) {
// Now get all the seqfeature_ids
PreparedStatement getFeatureId =
conn.prepareStatement("select seqfeature_id from seqfeature
where bioentry_id = ?");
getFeatureId.setInt(1, bioentry_id);
ResultSet rs1 = getFeatureId.executeQuery();
while ( rs1.next() ) {
if ( featureIdList == null ) featureIdList = new ArrayList();
Integer anInt = new Integer(rs1.getInt(1));
featureIdList.add(anInt);
}
getFeatureId.close();
PreparedStatement delete_taxa =
conn.prepareStatement("delete from bioentry_taxa where
bioentry_id = ?");
delete_taxa.setInt(1, bioentry_id);
delete_taxa.executeUpdate();
delete_taxa.close();
PreparedStatement delete_reference =
conn.prepareStatement("delete from bioentry_reference where
bioentry_id = ?");
delete_reference.setInt(1, bioentry_id);
delete_reference.executeUpdate();
delete_reference.close();
PreparedStatement delete_comment =
conn.prepareStatement("delete from comment where bioentry_id =
?");
// REMOVED -- Oracle does not like the name "Comment" for a
// table, so re-name this table to Biocomment
PreparedStatement delete_comment =
conn.prepareStatement("delete from comment where bioentry_id =
?");
delete_comment.setInt(1, bioentry_id);
delete_comment.executeUpdate();
delete_comment.close();
PreparedStatement delete_qv =
conn.prepareStatement("delete from bioentry_qualifier_value
where bioentry_id = ?");
delete_qv.setInt(1, bioentry_id);
delete_qv.executeUpdate();
delete_qv.close();
if ( featureIdList != null ) {
Iterator iter = featureIdList.iterator();
while ( iter.hasNext() ) {
Integer anInt = (Integer) iter.next();
int sf_id = anInt.intValue();
PreparedStatement delete_locs =
conn.prepareStatement("delete from
seqfeature_location where seqfeature_id = ? ");
delete_locs.setInt(1, sf_id);
delete_locs.executeUpdate();
delete_locs.close();
PreparedStatement delete_fqv =
conn.prepareStatement("delete from
seqfeature_qualifier_value where seqfeature_id = ?");
delete_fqv.setInt(1, sf_id);
delete_fqv.executeUpdate();
delete_fqv.close();
PreparedStatement delete_rel =
conn.prepareStatement("delete from
seqfeature_relationship where parent_seqfeature_id = ? ");
delete_rel.setInt(1, sf_id);
delete_rel.executeUpdate();
delete_rel.close();
}
}
PreparedStatement delete_features =
conn.prepareStatement("delete from seqfeature " +
" where bioentry_id = ?");
delete_features.setInt(1, bioentry_id);
delete_features.executeUpdate();
delete_features.close();
if ( biosequence_id != -1 ) {
PreparedStatement delete_biosequence =
conn.prepareStatement("delete from biosequence where
biosequence_id = ?");
delete_biosequence.setInt(1, biosequence_id);
delete_biosequence.executeUpdate();
delete_biosequence.close();
}
PreparedStatement delete_entry =
conn.prepareStatement("delete from bioentry where bioentry_id =
?");
delete_entry.setInt(1, bioentry_id);
delete_entry.executeUpdate();
delete_entry.close();
}
// } CHECK THIS -- WHY COMMENTED OUT ???
// get_sequence.close();
conn.commit();
pool.putConnection(conn);
if (!exists) {
throw new IllegalIDException("Sequence " + id + " didn't exist");
}
} catch (SQLException ex) {
System.err.println( ex.toString());
boolean rolledback = false;
if (conn != null) {
try {
conn.rollback();
rolledback = true;
} catch (SQLException ex2) {}
}
throw new BioException(ex, "Error removing from BioSQL tables"
+ (rolledback ? " (rolled back successfully)" : ""));
}
}
According to Len Trigg:
> Simon Foote wrote:
> > The "using" syntax is valid as it pertains to cascading deletes.
> > The deletes function correctly with MySQL version 4.0.14 using InnoDb
> > tables in my test cases.
>
> I put in the version checking, and both mysql and hsqldb fail on the
> deletion statement with (hsqldb):
>
> Caused by: java.sql.SQLException: Column not found: SEQFEATURE_ID in
> statement [delete from location where location.seqfeature_id =
> seqfeature.seqfeature_id and seqfeature.bioentry_id = 19]
>
> or (mysql 3.23.56):
>
> Caused by: java.sql.SQLException: General error, message from server:
> "Unknown table 'seqfeature' in where clause"
>
>
> Does this mean that the DELETE_GENERIC implementation is going to have
> to lookup the relevant seqfeature_id's and remove each location
> separately? My SQL knowledge is pretty basic, so I'm learning as I go
> along... (A quick two line explanation of what the "on delete cascade"
> stuff means also wouldn't go astray :-)).
>
>
> Cheers,
> Len.
>
More information about the biojava-dev
mailing list