001 /** 002 * Copyright 2004-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.hr.time.util; 017 018 import java.sql.Connection; 019 import java.sql.ResultSet; 020 import java.sql.SQLException; 021 import java.sql.Statement; 022 import java.util.ArrayList; 023 import java.util.HashMap; 024 import java.util.List; 025 import java.util.Map; 026 027 import javax.sql.DataSource; 028 029 import junit.framework.Assert; 030 031 import org.apache.commons.lang.StringUtils; 032 import org.apache.log4j.Logger; 033 import org.enhydra.jdbc.pool.StandardXAPoolDataSource; 034 import org.kuali.hr.time.service.base.TkServiceLocator; 035 import org.kuali.rice.core.api.config.property.ConfigContext; 036 import org.kuali.rice.core.api.lifecycle.BaseLifecycle; 037 import org.springframework.jdbc.core.ConnectionCallback; 038 import org.springframework.jdbc.core.JdbcTemplate; 039 import org.springframework.jdbc.core.StatementCallback; 040 import org.springframework.transaction.PlatformTransactionManager; 041 import org.springframework.transaction.TransactionStatus; 042 import org.springframework.transaction.support.TransactionCallback; 043 import org.springframework.transaction.support.TransactionTemplate; 044 045 public class ClearDatabaseLifecycle extends BaseLifecycle { 046 047 protected static final Logger LOG = Logger.getLogger(ClearDatabaseLifecycle.class); 048 private List<String> alternativeTablesToClear = new ArrayList<String>(); 049 050 private static List<String> TABLES_TO_CLEAR = new ArrayList<String>(); 051 static { 052 TABLES_TO_CLEAR.add("HR_CALENDAR_T"); 053 TABLES_TO_CLEAR.add("HR_CALENDAR_ENTRIES_T"); 054 TABLES_TO_CLEAR.add("HR_DEPT_T"); 055 TABLES_TO_CLEAR.add("TK_ASSIGN_ACCT_T"); 056 TABLES_TO_CLEAR.add("TK_ASSIGNMENT_T"); 057 TABLES_TO_CLEAR.add("TK_CLOCK_LOCATION_RL_T"); 058 TABLES_TO_CLEAR.add("TK_CLOCK_LOG_T"); 059 TABLES_TO_CLEAR.add("TK_DAILY_OVERTIME_RL_T"); 060 TABLES_TO_CLEAR.add("HR_EARN_CODE_SECURITY_T"); 061 TABLES_TO_CLEAR.add("TK_DEPT_LUNCH_RL_T"); 062 TABLES_TO_CLEAR.add("HR_EARN_CODE_T"); 063 TABLES_TO_CLEAR.add("HR_EARN_CODE_GROUP_T"); 064 TABLES_TO_CLEAR.add("HR_EARN_CODE_GROUP_DEF_T"); 065 TABLES_TO_CLEAR.add("TK_GRACE_PERIOD_RL_T"); 066 TABLES_TO_CLEAR.add("TK_HOUR_DETAIL_HIST_T"); 067 TABLES_TO_CLEAR.add("TK_HOUR_DETAIL_T"); 068 TABLES_TO_CLEAR.add("HR_ROLES_T"); 069 TABLES_TO_CLEAR.add("HR_SAL_GROUP_T"); 070 TABLES_TO_CLEAR.add("TK_SHIFT_DIFFERENTIAL_RL_T"); 071 TABLES_TO_CLEAR.add("TK_SYSTEM_LUNCH_RL_T"); 072 TABLES_TO_CLEAR.add("TK_TASK_T"); 073 TABLES_TO_CLEAR.add("TK_TIME_BLOCK_HIST_T"); 074 TABLES_TO_CLEAR.add("TK_TIME_BLOCK_T"); 075 TABLES_TO_CLEAR.add("TK_TIME_COLLECTION_RL_T"); 076 TABLES_TO_CLEAR.add("TK_WEEKLY_OVERTIME_RL_T"); 077 TABLES_TO_CLEAR.add("TK_WORK_AREA_T"); 078 TABLES_TO_CLEAR.add("HR_JOB_T"); 079 TABLES_TO_CLEAR.add("HR_PAYTYPE_T"); 080 // TABLES_TO_CLEAR.add("HR_WORK_SCHEDULE_ENTRY_T"); 081 // TABLES_TO_CLEAR.add("HR_WORK_SCHEDULE_T"); 082 TABLES_TO_CLEAR.add("TK_DOCUMENT_HEADER_T"); 083 TABLES_TO_CLEAR.add("HR_POSITION_T"); 084 } 085 086 private static final Map<String,String> TABLE_TO_ID_MAP = new HashMap<String,String>(); 087 static{ 088 TABLE_TO_ID_MAP.put("TK_TIME_COLLECTION_RL_T", "TK_TIME_COLL_RULE_ID"); 089 TABLE_TO_ID_MAP.put("TK_SHIFT_DIFFERENTIAL_RL_T", "TK_SHIFT_DIFF_RL_ID"); 090 TABLE_TO_ID_MAP.put("TK_GRACE_PERIOD_RL_T", "TK_GRACE_PERIOD_RULE_ID"); 091 TABLE_TO_ID_MAP.put("TK_CLOCK_LOCATION_RL_T", "TK_CLOCK_LOC_RULE_ID"); 092 TABLE_TO_ID_MAP.put("HR_CALENDAR_ENTRIES_T", "HR_CALENDAR_ENTRY_ID"); 093 TABLE_TO_ID_MAP.put("TK_DOCUMENT_HEADER_T", "DOCUMENT_ID"); 094 TABLE_TO_ID_MAP.put("KREW_RULE_T", "RULE_ID"); 095 TABLE_TO_ID_MAP.put("KREW_RULE_RSP_T", "RULE_RSP_ID"); 096 TABLE_TO_ID_MAP.put("KREW_DLGN_RSP_T", "DLGN_RULE_ID"); 097 TABLE_TO_ID_MAP.put("KREW_RULE_ATTR_T", "RULE_ATTR_ID"); 098 TABLE_TO_ID_MAP.put("KREW_RULE_TMPL_T", "RULE_TMPL_ID"); 099 TABLE_TO_ID_MAP.put("KREW_DOC_TYP_T", "DOC_TYP_ID"); 100 } 101 102 private static final Map<String,Integer> TABLE_START_CLEAR_ID = new HashMap<String,Integer>(); 103 static{ 104 TABLE_START_CLEAR_ID.put("KREW_DOC_TYP_T", new Integer(3000)); 105 } 106 107 public static final String TEST_TABLE_NAME = "KR_UNITTEST_T"; 108 109 public static final Integer START_CLEAR_ID = 1000; 110 111 public void start() throws Exception { 112 if (new Boolean(ConfigContext.getCurrentContextConfig().getProperty("tk.use.clearDatabaseLifecycle"))) { 113 final StandardXAPoolDataSource dataSource = (StandardXAPoolDataSource) TkServiceLocator.getBean("kpmeDataSource"); 114 final PlatformTransactionManager transactionManager = (PlatformTransactionManager) TkServiceLocator.getPlatformTransactionManager(); 115 final String schemaName = dataSource.getUser().toUpperCase(); 116 clearTables(transactionManager, dataSource, schemaName); 117 super.start(); 118 } 119 } 120 121 protected Boolean isTestTableInSchema(final DataSource dataSource) { 122 Assert.assertNotNull("DataSource could not be located.", dataSource); 123 return (Boolean) new JdbcTemplate(dataSource).execute(new ConnectionCallback() { 124 public Object doInConnection(final Connection connection) throws SQLException { 125 final ResultSet resultSet = connection.getMetaData().getTables(null, null, TEST_TABLE_NAME, null); 126 return new Boolean(resultSet.next()); 127 } 128 }); 129 } 130 131 protected void verifyTestEnvironment(final DataSource dataSource) { 132 Assert.assertTrue("No table named '" + TEST_TABLE_NAME + "' was found in the configured database. " + "You are attempting to run tests against a non-test database!!!", 133 isTestTableInSchema(dataSource)); 134 } 135 136 protected void clearTables(final PlatformTransactionManager transactionManager, final DataSource dataSource, final String schemaName) { 137 LOG.info("Clearing tables for schema " + schemaName); 138 Assert.assertNotNull("DataSource could not be located.", dataSource); 139 140 if (schemaName == null || schemaName.equals("")) { 141 Assert.fail("Empty schema name given"); 142 } 143 new TransactionTemplate(transactionManager).execute(new TransactionCallback<Object>() { 144 public Object doInTransaction(final TransactionStatus status) { 145 verifyTestEnvironment(dataSource); 146 return new JdbcTemplate(dataSource).execute(new StatementCallback<Object>() { 147 public Object doInStatement(Statement statement) throws SQLException { 148 final List<String> reEnableConstraints = new ArrayList<String>(); 149 List<List<String>> tableLists = new ArrayList<List<String>>(2); 150 tableLists.add(TABLES_TO_CLEAR); 151 tableLists.add(alternativeTablesToClear); 152 for (List<String> list : tableLists) { 153 for (String tableName : list) { 154 //if there is an id name that doesnt follow convention check and limit accordingly 155 String idName = TABLE_TO_ID_MAP.get(tableName); 156 String deleteStatement = null; 157 Integer clearId = TABLE_START_CLEAR_ID.get(tableName) != null ? TABLE_START_CLEAR_ID.get(tableName) : START_CLEAR_ID; 158 if(idName == null){ 159 deleteStatement = "DELETE FROM " + tableName +" WHERE "+StringUtils.removeEnd(tableName,"_T")+"_ID"+ " >= "+clearId; 160 } else { 161 deleteStatement = "DELETE FROM " + tableName +" WHERE "+ idName + " >= "+clearId; 162 } 163 164 LOG.debug("Clearing contents using statement ->" + deleteStatement + "<-"); 165 statement.addBatch(deleteStatement); 166 } 167 } 168 169 for (final String constraint : reEnableConstraints) { 170 LOG.debug("Enabling constraints using statement ->" + constraint + "<-"); 171 statement.addBatch(constraint); 172 } 173 statement.executeBatch(); 174 return null; 175 } 176 }); 177 } 178 }); 179 LOG.info("Tables successfully cleared for schema " + schemaName); 180 } 181 182 public List<String> getTablesToClear() { 183 return TABLES_TO_CLEAR; 184 } 185 186 public List<String> getAlternativeTablesToClear() { 187 return this.alternativeTablesToClear; 188 } 189 190 } 191