/* * Copyright 1999-2015 dangdang.com. *

* 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 com.dangdang.ddframe.rdb.common.base; import com.dangdang.ddframe.rdb.common.env.DataBaseEnvironment; import com.dangdang.ddframe.rdb.common.env.DatabaseTestMode; import com.dangdang.ddframe.rdb.common.env.ShardingJdbcDatabaseTester; import com.dangdang.ddframe.rdb.sharding.constant.DatabaseType; import org.apache.commons.dbcp.BasicDataSource; import org.dbunit.IDatabaseTester; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.dbunit.operation.DatabaseOperation; import org.h2.tools.RunScript; import org.junit.Before; import javax.sql.DataSource; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.SQLException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public abstract class AbstractSQLTest { private static boolean initialized; private static final DatabaseTestMode CURRENT_TEST_MODE = DatabaseTestMode.TEST; private final Map> databaseTypeMap = new HashMap<>(); static { createSchema(); } private static synchronized void createSchema() { if (!initialized) { for (DatabaseType each : CURRENT_TEST_MODE.databaseTypes()) { if (DatabaseType.H2 == each) { createSchema(each); } } } initialized = true; } private static void createSchema(final DatabaseType dbType) { try { Connection conn; for (int i = 0; i < 10; i++) { for (String database : Arrays.asList("tbl", "db", "dbtbl", "nullable", "master", "slave", "jdbc")) { if ("tbl".equals(database)) { if (i == 0) { conn = initialConnection(database, dbType); RunScript.execute(conn, new InputStreamReader(AbstractSQLTest.class.getClassLoader().getResourceAsStream("integrate/schema/table/tbl.sql"))); conn.close(); } } else { if ("jdbc".equals(database) && i >= 2) { continue; } conn = initialConnection(database + "_" + i, dbType); RunScript.execute(conn, new InputStreamReader(AbstractSQLTest.class.getClassLoader().getResourceAsStream("integrate/schema/table/" + database + ".sql"))); conn.close(); } } } } catch (final SQLException ex) { ex.printStackTrace(); } } @Before public final void importDataSet() throws Exception { for (DatabaseType databaseType : CURRENT_TEST_MODE.databaseTypes()) { if (databaseType == getCurrentDatabaseType() || null == getCurrentDatabaseType()) { DataBaseEnvironment dbEnv = new DataBaseEnvironment(databaseType); for (String each : getDataSetFiles()) { InputStream is = AbstractSQLTest.class.getClassLoader().getResourceAsStream(each); IDataSet dataSet = new FlatXmlDataSetBuilder().build(new InputStreamReader(is)); IDatabaseTester databaseTester = new ShardingJdbcDatabaseTester(dbEnv.getDriverClassName(), dbEnv.getURL(getDatabaseName(each)), dbEnv.getUsername(), dbEnv.getPassword(), dbEnv.getSchema(getDatabaseName(each))); databaseTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT); databaseTester.setDataSet(dataSet); databaseTester.onSetup(); } } } } protected abstract List getDataSetFiles(); protected abstract DatabaseType getCurrentDatabaseType(); protected final Map> createDataSourceMap() { for (String each : getDataSetFiles()) { String dbName = getDatabaseName(each); for (DatabaseType type : CURRENT_TEST_MODE.databaseTypes()) { createDataSources(dbName, type); } } return databaseTypeMap; } private static Connection initialConnection(final String dbName, final DatabaseType type) throws SQLException { return buildDataSource(dbName, type).getConnection(); } private static BasicDataSource buildDataSource(final String dbName, final DatabaseType type) { DataBaseEnvironment dbEnv = new DataBaseEnvironment(type); BasicDataSource result = new BasicDataSource(); result.setDriverClassName(dbEnv.getDriverClassName()); result.setUrl(dbEnv.getURL(dbName)); result.setUsername(dbEnv.getUsername()); result.setPassword(dbEnv.getPassword()); result.setMaxActive(1000); if (DatabaseType.Oracle == dbEnv.getDatabaseType()) { result.setConnectionInitSqls(Collections.singleton("ALTER SESSION SET CURRENT_SCHEMA = " + dbName)); } return result; } private void createDataSources(final String dbName, final DatabaseType type) { String dataSource = "dataSource_" + dbName; Map dataSourceMap = databaseTypeMap.get(type); if (null == dataSourceMap) { dataSourceMap = new HashMap<>(); databaseTypeMap.put(type, dataSourceMap); } BasicDataSource result = buildDataSource(dbName, type); dataSourceMap.put(dataSource, result); } private String getDatabaseName(final String dataSetFile) { String fileName = new File(dataSetFile).getName(); if (-1 == fileName.lastIndexOf(".")) { return fileName; } return fileName.substring(0, fileName.lastIndexOf(".")); } }