001package io.ebean.docker.commands; 002 003import io.ebean.docker.container.Container; 004import org.slf4j.Logger; 005import org.slf4j.LoggerFactory; 006 007import java.sql.Connection; 008import java.sql.SQLException; 009import java.util.List; 010import java.util.Properties; 011 012/** 013 * Commands for controlling an Oracle docker container. 014 */ 015public class OracleContainer extends JdbcBaseDbContainer implements Container { 016 017 /** 018 * Create Postgres container with configuration from properties. 019 */ 020 public static OracleContainer create(String version, Properties properties) { 021 return new OracleContainer(new OracleConfig(version, properties)); 022 } 023 024 private static final Logger log = LoggerFactory.getLogger(Commands.class); 025 026 private final OracleConfig oracleConfig; 027 028 private boolean oracleScript; 029 030 /** 031 * Create with configuration. 032 */ 033 public OracleContainer(OracleConfig config) { 034 super(config); 035 this.oracleConfig = config; 036 this.checkConnectivityUsingAdmin = true; 037 } 038 039 @Override 040 void createDatabase() { 041 createRoleAndDatabase(false); 042 } 043 044 @Override 045 void dropCreateDatabase() { 046 createRoleAndDatabase(true); 047 } 048 049 private void createRoleAndDatabase(boolean withDrop) { 050 try (Connection connection = config.createAdminConnection()) { 051 if (withDrop) { 052 dropUser(connection); 053 } 054 createUser(connection, withDrop); 055 056 } catch (SQLException e) { 057 throw new RuntimeException("Error when creating database and role", e); 058 } 059 } 060 061 private void sqlRunOracleScript(Connection connection) { 062 if (!oracleScript) { 063 sqlRun(connection, "alter session set \"_ORACLE_SCRIPT\"=true"); 064 oracleScript = true; 065 } 066 } 067 068 private void dropUser(Connection connection) { 069 if (userExists(connection)) { 070 sqlRunOracleScript(connection); 071 sqlRun(connection, "drop user " + dbConfig.getUsername() + " cascade"); 072 } 073 } 074 075 private void createUser(Connection connection, boolean withDrop) { 076 if (withDrop || !userExists(connection)) { 077 sqlRunOracleScript(connection); 078 sqlRun(connection, "create user " + dbConfig.getUsername() + " identified by " + dbConfig.getPassword()); 079 sqlRun(connection, "grant connect, resource, create view, unlimited tablespace to " + dbConfig.getUsername()); 080 } 081 } 082 083 private boolean userExists(Connection connection) { 084 String sql = "select 1 from dba_users where lower(username) = '"+dbConfig.getUsername().toLowerCase()+"'"; 085 return sqlHasRow(connection, sql); 086 } 087 088 @Override 089 protected ProcessBuilder runProcess() { 090 List<String> args = dockerRun(); 091 args.add("-p"); 092 args.add(oracleConfig.getApexPort() + ":" + oracleConfig.getInternalApexPort()); 093 args.add("-e"); 094 args.add("ORACLE_PWD=" + oracleConfig.getAdminPassword()); 095 args.add(config.getImage()); 096 return createProcessBuilder(args); 097 } 098 099}