/*
* Copyright (c) 2006-2013 by Public Library of Science
*
* http://plos.org
* http://ambraproject.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ambraproject.service.migration;
import com.google.common.base.Preconditions;
import org.ambraproject.models.SavedSearchQuery;
import org.ambraproject.models.Version;
import org.ambraproject.util.TextUtils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
/**
* Hard-coded migration logic abstracted into the {@link Migration} interface, but otherwise untouched.
* <p/>
* The version numbering on these migrations comes from the legacy practice of tying schema version numbers to Ambra
* release numbers. Hence, all of these versions, and only these, are less than 1000.
* <p/>
* Do not add any new values to this enum.
*/
enum LegacyMigration implements Migration {
M280(282) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 280 starting");
final Long versionID = (Long) hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
//this should match the ambra version we will be going to deploy
v.setName("Ambra 2.82");
v.setVersion(282);
v.setUpdateInProcess(true);
session.save(v);
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_8_2_part1.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 280 complete");
}
},
M255(280) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 255 starting");
final Long versionID = (Long) hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
//this should match the ambra version we will be going to deploy
v.setName("Ambra 2.80");
v.setVersion(280);
v.setUpdateInProcess(true);
session.save(v);
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_8_0_part1.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 255 complete");
}
},
M250(255) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 250 starting");
final Long versionID = (Long) hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
//this should match the ambra version we will be going to deploy
v.setName("Ambra 2.55");
v.setVersion(255);
v.setUpdateInProcess(true);
session.save(v);
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_5_5_part1.sql");
return v.getID();
}
});
//Now we have to populate a hash used to identify unique searchParameters
List<SavedSearchQuery> queries = hibernateTemplate.loadAll(SavedSearchQuery.class);
for (SavedSearchQuery query : queries) {
String hash = TextUtils.createHash(query.getSearchParams());
query.setHash(hash);
hibernateTemplate.update(query);
}
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = (Version) session.load(Version.class, versionID);
//Now that hash is populated, add a null constraint, unique constraint and created index
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_5_5_part2.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 250 complete");
}
},
M249(250) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 249 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
//this should match the ambra version we will be going to deploy
v.setName("Ambra 2.50");
v.setVersion(250);
v.setUpdateInProcess(true);
session.save(v);
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_5_0.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 249 complete");
}
},
M248(249) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 248 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
//this should match the ambra version we will be going to deploy
v.setName("Ambra 2.49");
v.setVersion(249);
v.setUpdateInProcess(true);
session.save(v);
log.debug("Creating new table.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_4_9_part1.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 248 complete");
}
},
M246(247) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 246 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
//this should match the ambra version we will be going to deploy
v.setName("Ambra 2.48");
v.setVersion(248);
v.setUpdateInProcess(true);
session.save(v);
log.debug("Creating new table.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_4_8_part1.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 246 complete");
}
},
M245(246) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 245 starting");
hibernateTemplate.execute(new HibernateCallback<Void>() {
@Override
public Void doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
v.setName("Ambra 2.46");
v.setVersion(246);
v.setUpdateInProcess(true);
session.save(v);
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_4_6_part1.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 245 complete");
}
},
M240(243) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 240 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
v.setName("Ambra 2.43");
v.setVersion(243);
v.setUpdateInProcess(true);
session.save(v);
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_4_3_part1.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 240 complete");
}
},
M237(240) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 237 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
v.setName("Ambra 2.40");
v.setVersion(240);
v.setUpdateInProcess(true);
session.save(v);
log.debug("Creating new table.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_4_0_part1.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 237 complete");
}
},
M234(237) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 234 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
v.setName("Ambra 2.37");
v.setVersion(237);
v.setUpdateInProcess(true);
session.save(v);
log.debug("Creating new table.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_3_7_part1.sql");
log.debug("Table created, now generating data.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_3_7_part2.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 234 complete");
}
},
M232(234) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 232 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
v.setName("Ambra 2.34");
v.setVersion(234);
v.setUpdateInProcess(true);
session.save(v);
log.debug("Creating new tables.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_3_4_part1.sql");
log.debug("Tables created, now migrating data.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_3_4_part2.sql");
log.debug("Migrated data, now dropping tables");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_3_4_part3.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 232 complete");
}
},
M230(232) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 230 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
v.setName("Ambra 2.32");
v.setVersion(232);
v.setUpdateInProcess(true);
session.save(v);
log.debug("Creating new tables.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_3_2_part1.sql");
log.debug("Tables created, now migrating and cleaning up data.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_3_2_part2.sql");
log.debug("Migrated data, now dropping tables");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_3_2_part3.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 230 complete");
}
},
M222(223) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 222 starting");
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Version v = new Version();
v.setName("Ambra 2.30");
v.setVersion(230);
v.setUpdateInProcess(true);
session.save(v);
log.debug("Creating new tables.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_2_2_part1.sql");
log.debug("Tables created, now migrating data.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_2_2_part2.sql");
log.debug("Cleaning up data");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_2_2_part3.sql");
log.debug("Migrated data, now dropping tables");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_2_2_part4.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 222 complete");
}
},
M210(220) {
public void migrate(HibernateTemplate hibernateTemplate) {
log.info("Migration from 210 starting");
//First create version table and add one row
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {
log.debug("Creating new tables.");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_2_0_part1.sql");
Version v = new Version();
v.setName("Ambra 2.20");
v.setVersion(220);
v.setUpdateInProcess(true);
session.save(v);
log.debug("Tables created, now migrating data and removing old tables.");
//We execute step #2 in a slightly different way as this file has SQL delimited in a different fashion
//since it creates a trigger
String sqlScript = "";
try {
log.debug("migrate_ambra_2_2_0_part2.sql started");
sqlScript = BootstrapMigratorServiceImpl.getSQLScript("migrate_ambra_2_2_0_part2.sql");
log.debug("migrate_ambra_2_2_0_part2.sql completed");
} catch (IOException ex) {
throw new HibernateException(ex.getMessage(), ex);
}
session.createSQLQuery(sqlScript).executeUpdate();
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_2_0_part3.sql");
//step 4 also creates a trigger, so we need to execute it the same as with step 2
try {
log.debug("migrate_ambra_2_2_0_part4.sql started");
sqlScript = BootstrapMigratorServiceImpl.getSQLScript("migrate_ambra_2_2_0_part4.sql");
log.debug("migrate_ambra_2_2_0_part4.sql completed");
} catch (IOException ex) {
throw new HibernateException(ex.getMessage(), ex);
}
session.createSQLQuery(sqlScript).executeUpdate();
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_2_0_part5.sql");
BootstrapMigratorServiceImpl.execSQLScript(session, "migrate_ambra_2_2_0_part6.sql");
v.setUpdateInProcess(false);
session.update(v);
return null;
}
});
log.info("Migration from 210 complete");
}
};
private static final Logger log = LoggerFactory.getLogger(LegacyMigration.class);
static final int MIN_VERSION = 210;
private final int version;
private LegacyMigration(int version) {
Preconditions.checkArgument(version > MIN_VERSION, "Legacy versions don't go below " + MIN_VERSION);
Preconditions.checkArgument(version < SchemaMigration.THRESHOLD,
"Legacy versions must be less than " + SchemaMigration.THRESHOLD);
this.version = version;
}
@Override
public int getVersion() {
return version;
}
}