in odps-sqoop/src/java/org/apache/sqoop/manager/oracle/OraOopJdbcUrl.java [47:238]
public JdbcOracleThinConnection parseJdbcOracleThinConnectionString()
throws JdbcOracleThinConnectionParsingError {
/*
* http://wiki.oracle.com/page/JDBC
*
* There are different flavours of JDBC connections for Oracle, including:
* Thin E.g. jdbc:oracle:thin:@localhost.locadomain:1521:orcl
*
* A pure Java driver used on the client side that does not need an Oracle
* client installation. It is recommended that you use this driver unless
* you need support for non-TCP/IP networks because it provides for maximum
* portability and performance.
*
* Oracle Call Interface driver (OCI). E.g. jdbc:oracle:oci8:@orcl.world
* //<- "orcl.world" is a TNS entry
*
* This uses the Oracle client installation libraries and interfaces. If you
* want to support connection pooling or client side caching of requests,
* use this driver. You will also need this driver if you are using
* transparent application failover (TAF) from your application as well as
* strong authentication like Kerberos and PKI certificates.
*
* JDBC-ODBC bridge. E.g. jdbc:odbc:mydatabase //<- "mydatabase" is an ODBC
* data source.
*
* This uses the ODBC driver in Windows to connect to the database.
*/
String hostName = null;
int port = 0;
String sid = null;
String service = null;
String jdbcUrl = this.jdbcConnectString.trim();
// If there are any parameters included at the end of the connection URL,
// let's remove them now...
int paramsIdx = jdbcUrl.indexOf("?");
if (paramsIdx > -1) {
jdbcUrl = jdbcUrl.substring(0, paramsIdx);
}
/*
* The format of an Oracle jdbc URL is one of:
* jdbc:oracle:<driver-type>:@tnsname - for tnsname based login
* jdbc:oracle:<driver-type>:@<host>:<port>:<sid>
* jdbc:oracle:<driver-type>:@<host>:<port>/<service>
* jdbc:oracle:<driver-type>:@<host>:<port>/<service>?<parameters>
* jdbc:oracle:<driver-type>:@//<host>:<port>/<service>
* jdbc:oracle:<driver-type>:@//<host>:<port>/<service>?<parameters>
*/
// Split the URL on its ":" characters...
String[] jdbcFragments = jdbcUrl.trim().split(":");
// Clean up each fragment of the URL...
for (int idx = 0; idx < jdbcFragments.length; idx++) {
jdbcFragments[idx] = jdbcFragments[idx].trim();
}
// Check we can proceed...
if (jdbcFragments.length < 4 || jdbcFragments.length > 6) {
throw new JdbcOracleThinConnectionParsingError(
String.format(
"There should be 4, 5 or 6 colon-separated pieces of data in the "
+ "JDBC URL, such as:\n\tjdbc:oracle:<driver-type>:@tnsname\n"
+ "\tjdbc:oracle:<driver-type>:@<host>:<port>:<sid>\n"
+ "\tjdbc:oracle:<driver-type>:@<host>:<port>/<service>\n"
+ "\tjdbc:oracle:<driver-type>:@<host>:<port>/<service>?<parameters>\n"
+ "The JDBC URL specified was:\n"
+ "%s\n"
+ "which contains %d pieces of colon-separated data.",
this.jdbcConnectString, jdbcFragments.length));
}
// jdbc
if (!jdbcFragments[0].equalsIgnoreCase("jdbc")) {
throw new JdbcOracleThinConnectionParsingError(
"The first item in the colon-separated JDBC URL must be \"jdbc\".");
}
// jdbc:oracle
if (!jdbcFragments[1].equalsIgnoreCase("oracle")) {
throw new JdbcOracleThinConnectionParsingError(
"The second item in the colon-separated JDBC URL must be \"oracle\".");
}
// jdbc:oracle:thin
if (!jdbcFragments[2].equalsIgnoreCase("thin")) {
throw new JdbcOracleThinConnectionParsingError(
String
.format(
"The Oracle \"thin\" JDBC driver is not being used.\n"
+ "The third item in the colon-separated JDBC URL must "
+ "be \"thin\", not \"%s\".",
jdbcFragments[2]));
}
// jdbc:oracle:thin:@<host>
hostName = jdbcFragments[3];
if (hostName.isEmpty() || hostName.equalsIgnoreCase("@")) {
throw new JdbcOracleThinConnectionParsingError(
"The fourth item in the colon-separated JDBC URL (the host name) "
+ "must not be empty.");
}
if (!hostName.startsWith("@")) {
throw new JdbcOracleThinConnectionParsingError(
"The fourth item in the colon-separated JDBC URL (the host name) "
+ "must a prefixed with the \"@\" character.");
}
String portStr = "";
String tnsName = "";
switch (jdbcFragments.length) {
case 6:
// jdbc:oracle:<driver-type>:@<host>:<port>:<sid>
portStr = jdbcFragments[4];
sid = jdbcFragments[5];
break;
case 5:
// jdbc:oracle:<driver-type>:@<host>:<port>/<service>
String[] portAndService = jdbcFragments[4].split("/");
if (portAndService.length != 2) {
throw new JdbcOracleThinConnectionParsingError(
"The fifth colon-separated item in the JDBC URL "
+ "(<port>/<service>) must contain two items "
+ "separated by a \"/\".");
}
portStr = portAndService[0].trim();
service = portAndService[1].trim();
break;
case 4:
// jdbc:oracle:<driver-type>:@tnsname
tnsName = jdbcFragments[3].trim();
break;
default:
throw new JdbcOracleThinConnectionParsingError("Internal error parsing "
+ "JDBC connection string.");
}
if (jdbcFragments.length > 4) {
if (portStr.isEmpty()) {
throw new JdbcOracleThinConnectionParsingError(
"The fifth item in the colon-separated JDBC URL (the port) must not"
+ " be empty.");
}
try {
port = Integer.parseInt(portStr);
} catch (NumberFormatException ex) {
throw new JdbcOracleThinConnectionParsingError(
String
.format(
"The fifth item in the colon-separated JDBC URL (the port) "
+ "must be a valid number.\n"
+ "\"%s\" could not be parsed as an integer.", portStr));
}
if (port <= 0) {
throw new JdbcOracleThinConnectionParsingError(
String
.format(
"The fifth item in the colon-separated JDBC URL (the port) "
+ "must be greater than zero.\n"
+ "\"%s\" was specified.", portStr));
}
}
if (sid == null && service == null && tnsName == null) {
throw new JdbcOracleThinConnectionParsingError(
"The JDBC URL does not contain a SID or SERVICE. The URL should look "
+ "like one of these:\n\tjdbc:oracle:<driver-type>:@tnsname\n"
+ "\tjdbc:oracle:<driver-type>:@<host>:<port>:<sid>\n"
+ "\tjdbc:oracle:<driver-type>:@<host>:<port>/<service>\n"
+ "\tjdbc:oracle:<driver-type>:@<host>:<port>/<service>?<parameters>\n"
+ "\tjdbc:oracle:<driver-type>:@//<host>:<port>/<service>\n"
+ "\tjdbc:oracle:<driver-type>:@<host>:<port>/<service>?<parameters>");
}
// Remove the "@" prefix of the hostname
JdbcOracleThinConnection result =
new JdbcOracleThinConnection(hostName.replaceFirst("^[@][/]{0,2}", "")
, port, sid, service, tnsName.replaceFirst("^[@][/]{0,2}", ""));
return result;
}