my ($dbh, $current_dbname, $previous_dbname, $dry_run) = @_;
my $error;
my $sth_seq_mapping = $dbh->prepare("INSERT INTO $current_dbname.seq_region_mapping VALUES(?,?,?)");
my $sth_update_old = $dbh->prepare("UPDATE $current_dbname.seq_region_mapping SET internal_seq_region_id = ? WHERE internal_seq_region_id = ?");
my $sth_remove_deprecated = $dbh->prepare("DELETE FROM $current_dbname.seq_region_mapping WHERE internal_seq_region_id = ?");
my $count_removed = 0;
my $count_updated = 0;
my $count_added = 0;
# If there has been no change in seq_region, no mapping needed
if ($cur_seq_region_checksum == $previous_seq_region_checksum) {
print STDERR "No change in seq_region for $current_dbname, no mapping needed\n";
return;
}
# There has been a seq_region change between releases, add the relation old_seq_region_id->new_seq_region_id
# Build a hash of currently used seq region ids to ensure we do not map to overlapping IDs
# i.e. a database has reused seq region IDs between releases
# Update the seq_region_mapping table with the old->new seq_region_id relation
foreach my $seq_region_name (keys %{$old_seq_region}){
my $current_name_hash = $current_seq_region->{$seq_region_name};
my $old_name_hash = $old_seq_region->{$seq_region_name};
# If the seq_region has disappeared, remove previous entries for that id
if (!defined $current_name_hash) {
$count_removed += $sth_remove_deprecated->execute($id) unless $dry_run;
next;
}
# while ( my ($length, $hash_length) = each %{$old_name_hash})
foreach my $length (keys %{$old_name_hash}){
my $current_length_hash = $current_name_hash->{$length};
my $old_length_hash = $old_name_hash->{$length};
# The seq_region might have a different length
if (!defined $current_length_hash) {
next;
}
foreach my $cs (keys %{$old_length_hash}) {
my $current_cs_hash = $current_length_hash->{$cs};
my $old_cs_hash = $old_length_hash->{$cs};
# The coord system might have changed
if (!defined $current_cs_hash) {
next;
}
foreach my $id (keys %{$old_cs_hash}) {
my $current_id = $current_cs_hash->{$id};
my $old_id = $old_cs_hash->{$id};
# If no change, no need to write out
if (!defined $current_id || $old_id == $current_id) {
next;
}
if(exists $current_seq_region_ids->{$old_id}) {
printf STDERR "Skipping the mapping for old id %d to current id %d as the old ID is in use in the DB. This means IDs have been reused. Do not reused seq_region_id primary keys\n", $old_id, $current_id;
$error = 1;
next;
}
# If there is a change, update any existing entries for this seq_region to the new id
# Then, add a new entry to map said id to the old release
$count_updated += $sth_update_old->execute($current_id,$old_id) unless $dry_run;
$count_added += $sth_seq_mapping->execute($old_id,$current_id, $mapping_set_id) unless $dry_run;
if($dry_run) {
$count_updated++;
$count_added++;
}
}
}
}
}
print STDERR "For $current_dbname, removed $count_removed, added $count_added, updated $count_updated seq_region_mapping entries\n\n" ;
if($error) {
die "Error detected when loading the mapping sets. Check STDERR for more information";
}
}