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