Skip to content

Commit 66c1231

Browse files
committed
Connection string parsing refactoring
1 parent d50b8b5 commit 66c1231

File tree

3 files changed

+104
-62
lines changed

3 files changed

+104
-62
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ You can download development versions on [Bintray](https://bintray.com/viniciusa
1717
* ~~When using reporters for Sonar or Coveralls client needs to be invoked from project's root directory.~~
1818

1919
## Usage
20-
utplsql run user/password@database [-p=(ut_path|ut_paths)] [-f=format [-o=output_file] [-s] ...]
20+
utplsql run user/pass@[[host][:port]/]db [-p=(ut_path|ut_paths)] [-f=format [-o=output_file] [-s] ...]
2121

2222
```
23-
user - username to connect as.
24-
password - password of the user.
25-
database - database to connect to.
23+
user - Username to connect as.
24+
password - Password of the user.
25+
host - Server address, defaults to 127.0.0.1.
26+
port - Server port, defaults to 1521.
27+
db - Database to connect to.
2628
-p=suite_path(s) - A suite path or a comma separated list of suite paths for unit test to be executed.
2729
The path(s) can be in one of the following formats:
2830
schema[.package[.procedure]]

src/main/java/io/github/utplsql/cli/ConnectionInfo.java

Lines changed: 67 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,103 +5,135 @@
55
import java.sql.Connection;
66
import java.sql.DriverManager;
77
import java.sql.SQLException;
8-
import java.util.regex.Matcher;
9-
import java.util.regex.Pattern;
108

119
/**
1210
* Created by Vinicius on 21/04/2017.
1311
*/
1412
public class ConnectionInfo {
1513

16-
/**
17-
* Regex pattern to match following connection strings:
18-
* user/pass@127.0.0.1:1521/db
19-
* user/pass@127.0.0.1/db
20-
* user/pass@db
21-
*/
22-
private static final String CONNSTR_PATTERN =
23-
"^(?<user>[0-9a-z]+)/(?<pass>[0-9a-z]+)" +
24-
"(?:(?:@(?<host>[^:/]+)?(?::(?<port>[0-9]+))?(?:/(?<db1>[0-9a-z]+))$)|(?:@(?<db2>[0-9a-z]+)$))";
25-
2614
private static final String DEFAULT_HOST = "127.0.0.1";
2715
private static final int DEFAULT_PORT = 1521;
2816

2917
private String user;
3018
private String password;
3119
private String host;
3220
private int port;
33-
private String db;
21+
private String database;
3422

35-
public ConnectionInfo() {
36-
}
23+
public ConnectionInfo() {}
3724

3825
public Connection getConnection() throws SQLException {
3926
return DriverManager.getConnection(getConnectionUrl(), getUser(), getPassword());
4027
}
4128

42-
public ConnectionInfo parseConnectionString(String connectionString) throws ParameterException {
43-
Pattern p = Pattern.compile(CONNSTR_PATTERN);
44-
Matcher m = p.matcher(connectionString);
29+
public ConnectionInfo parseConnectionString(String connectionString)
30+
throws ParameterException, IllegalArgumentException {
31+
32+
if (connectionString == null || connectionString.isEmpty())
33+
throw invalidConnectionString();
4534

46-
if (!m.matches())
47-
throw new ParameterException("Invalid connection string!");
35+
int i = connectionString.lastIndexOf("@");
36+
if (i == -1)
37+
throw invalidConnectionString();
4838

49-
this.setUser(m.group("user"));
50-
this.setPassword(m.group("pass"));
51-
this.setHost(m.group("host") != null ? m.group("host") : DEFAULT_HOST);
52-
this.setPort(m.group("port") != null ? Integer.parseInt(m.group("port")) : DEFAULT_PORT);
53-
this.setDb(m.group("db1") != null ? m.group("db1") : m.group("db2"));
39+
String credentials = connectionString.substring(0, i);
40+
String host = connectionString.substring(i+1);
41+
parseCredentials(credentials);
42+
parseHost(host);
5443

5544
return this;
5645
}
5746

47+
private void parseCredentials(String str) throws ParameterException, IllegalArgumentException {
48+
int barIdx = str.indexOf("/");
49+
50+
if (barIdx == -1 || str.length() == 1)
51+
throw invalidConnectionString();
52+
53+
this.setUser(str.substring(0, barIdx));
54+
this.setPassword(str.substring(barIdx+1));
55+
}
56+
57+
private void parseHost(String str) throws ParameterException, IllegalArgumentException {
58+
if (str == null || str.isEmpty())
59+
throw invalidConnectionString();
60+
61+
int colonIdx = str.indexOf(":");
62+
int barIdx = str.indexOf("/");
63+
64+
if (colonIdx != -1 && barIdx != -1) {
65+
setHost(str.substring(0, colonIdx));
66+
setPort(Integer.parseInt(str.substring(colonIdx + 1, barIdx)));
67+
setDatabase(str.substring(barIdx + 1));
68+
}
69+
else
70+
if (colonIdx == -1 && barIdx != -1) {
71+
setHost(str.substring(0, barIdx));
72+
setPort(DEFAULT_PORT);
73+
setDatabase(str.substring(barIdx + 1));
74+
}
75+
else
76+
if (colonIdx != -1) {
77+
throw invalidConnectionString();
78+
}
79+
else {
80+
setHost(DEFAULT_HOST);
81+
setPort(DEFAULT_PORT);
82+
setDatabase(str);
83+
}
84+
}
85+
86+
private ParameterException invalidConnectionString() {
87+
return new ParameterException("Invalid connection string.");
88+
}
89+
5890
public String getUser() {
5991
return user;
6092
}
6193

62-
public void setUser(String user) {
94+
private void setUser(String user) {
6395
this.user = user;
6496
}
6597

6698
public String getPassword() {
6799
return password;
68100
}
69101

70-
public void setPassword(String password) {
102+
private void setPassword(String password) {
71103
this.password = password;
72104
}
73105

74106
public String getHost() {
75107
return host;
76108
}
77109

78-
public void setHost(String host) {
110+
private void setHost(String host) {
79111
this.host = host;
80112
}
81113

82114
public int getPort() {
83115
return port;
84116
}
85117

86-
public void setPort(int port) {
118+
private void setPort(int port) {
87119
this.port = port;
88120
}
89121

90-
public String getDb() {
91-
return db;
122+
public String getDatabase() {
123+
return database;
92124
}
93125

94-
public void setDb(String db) {
95-
this.db = db;
126+
private void setDatabase(String database) {
127+
this.database = database;
96128
}
97129

98130
public String getConnectionUrl() {
99-
return String.format("jdbc:oracle:thin:@//%s:%d/%s", getHost(), getPort(), getDb());
131+
return String.format("jdbc:oracle:thin:@//%s:%d/%s", getHost(), getPort(), getDatabase());
100132
}
101133

102134
@Override
103135
public String toString() {
104-
return String.format("%s@%s:%d/%s", getUser(), getHost(), getPort(), getDb());
136+
return String.format("%s@%s:%d/%s", getUser(), getHost(), getPort(), getDatabase());
105137
}
106138

107139
}

src/test/java/io/github/utplsql/cli/ConnectionInfoTest.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@ public class ConnectionInfoTest {
1111

1212
/**
1313
* Regex pattern to match following connection strings:
14-
* user/pass@127.0.0.1:1521/db
15-
* user/pass@127.0.0.1/db
14+
* user/pass@host:port/db
15+
* user/pass@host/db
1616
* user/pass@db
17-
* user/pass
1817
*/
1918

2019
@Test
2120
public void connectionStr_Full() {
2221
try {
23-
ConnectionInfo ci = new ConnectionInfo().parseConnectionString("user/pass@localhost:3000/db");
24-
Assert.assertEquals("user", ci.getUser());
25-
Assert.assertEquals("pass", ci.getPassword());
26-
Assert.assertEquals("localhost", ci.getHost());
22+
ConnectionInfo ci = new ConnectionInfo()
23+
.parseConnectionString("my_user/p@ss!@some.server.123-abc.com:3000/db_1.acme.com");
24+
Assert.assertEquals("my_user", ci.getUser());
25+
Assert.assertEquals("p@ss!", ci.getPassword());
26+
Assert.assertEquals("some.server.123-abc.com", ci.getHost());
2727
Assert.assertEquals(3000, ci.getPort());
28-
Assert.assertEquals("db", ci.getDb());
29-
Assert.assertEquals("user@localhost:3000/db", ci.toString());
30-
Assert.assertEquals("jdbc:oracle:thin:@//localhost:3000/db", ci.getConnectionUrl());
28+
Assert.assertEquals("db_1.acme.com", ci.getDatabase());
29+
Assert.assertEquals("my_user@some.server.123-abc.com:3000/db_1.acme.com", ci.toString());
30+
Assert.assertEquals("jdbc:oracle:thin:@//some.server.123-abc.com:3000/db_1.acme.com", ci.getConnectionUrl());
3131
} catch (Exception e) {
3232
Assert.fail(e.getMessage());
3333
}
@@ -36,14 +36,15 @@ public void connectionStr_Full() {
3636
@Test
3737
public void connectionStr_WithoutPort() {
3838
try {
39-
ConnectionInfo ci = new ConnectionInfo().parseConnectionString("user/pass@localhost/db");
40-
Assert.assertEquals("user", ci.getUser());
41-
Assert.assertEquals("pass", ci.getPassword());
42-
Assert.assertEquals("localhost", ci.getHost());
39+
ConnectionInfo ci = new ConnectionInfo()
40+
.parseConnectionString("my_user/p@ss!@some.server.123-abc.com/db_1.acme.com");
41+
Assert.assertEquals("my_user", ci.getUser());
42+
Assert.assertEquals("p@ss!", ci.getPassword());
43+
Assert.assertEquals("some.server.123-abc.com", ci.getHost());
4344
Assert.assertEquals(1521, ci.getPort());
44-
Assert.assertEquals("db", ci.getDb());
45-
Assert.assertEquals("user@localhost:1521/db", ci.toString());
46-
Assert.assertEquals("jdbc:oracle:thin:@//localhost:1521/db", ci.getConnectionUrl());
45+
Assert.assertEquals("db_1.acme.com", ci.getDatabase());
46+
Assert.assertEquals("my_user@some.server.123-abc.com:1521/db_1.acme.com", ci.toString());
47+
Assert.assertEquals("jdbc:oracle:thin:@//some.server.123-abc.com:1521/db_1.acme.com", ci.getConnectionUrl());
4748
} catch (Exception e) {
4849
Assert.fail(e.getMessage());
4950
}
@@ -52,14 +53,15 @@ public void connectionStr_WithoutPort() {
5253
@Test
5354
public void connectionStr_WithoutHostAndPort() {
5455
try {
55-
ConnectionInfo ci = new ConnectionInfo().parseConnectionString("user/pass@db");
56-
Assert.assertEquals("user", ci.getUser());
57-
Assert.assertEquals("pass", ci.getPassword());
56+
ConnectionInfo ci = new ConnectionInfo()
57+
.parseConnectionString("my_user/p@ss!@127.0.0.1/db_1.acme.com");
58+
Assert.assertEquals("my_user", ci.getUser());
59+
Assert.assertEquals("p@ss!", ci.getPassword());
5860
Assert.assertEquals("127.0.0.1", ci.getHost());
5961
Assert.assertEquals(1521, ci.getPort());
60-
Assert.assertEquals("db", ci.getDb());
61-
Assert.assertEquals("user@127.0.0.1:1521/db", ci.toString());
62-
Assert.assertEquals("jdbc:oracle:thin:@//127.0.0.1:1521/db", ci.getConnectionUrl());
62+
Assert.assertEquals("db_1.acme.com", ci.getDatabase());
63+
Assert.assertEquals("my_user@127.0.0.1:1521/db_1.acme.com", ci.toString());
64+
Assert.assertEquals("jdbc:oracle:thin:@//127.0.0.1:1521/db_1.acme.com", ci.getConnectionUrl());
6365
} catch (Exception e) {
6466
Assert.fail(e.getMessage());
6567
}
@@ -68,7 +70,13 @@ public void connectionStr_WithoutHostAndPort() {
6870
@Test
6971
public void connectionStr_Invalid() {
7072
try {
73+
new ConnectionInfo().parseConnectionString("user/pass@");
7174
new ConnectionInfo().parseConnectionString("user/pass");
75+
new ConnectionInfo().parseConnectionString("user/@");
76+
new ConnectionInfo().parseConnectionString("/pass@");
77+
new ConnectionInfo().parseConnectionString("/@");
78+
new ConnectionInfo().parseConnectionString("@");
79+
new ConnectionInfo().parseConnectionString("@db");
7280
Assert.fail();
7381
} catch (ParameterException ignored) {}
7482
}

0 commit comments

Comments
 (0)