Skip to content

Commit eb1d930

Browse files
authored
Merge pull request #16 from viniciusam/bugfix/con_str
Connection string parsing refactoring
2 parents d5670d5 + 6f303ed commit eb1d930

File tree

3 files changed

+157
-66
lines changed

3 files changed

+157
-66
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: 66 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,103 +5,134 @@
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 || barIdx == 0 || barIdx == 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) || barIdx == 0) // @host:port or // @/db
65+
throw invalidConnectionString();
66+
67+
if (colonIdx != -1) { // @host:port/db
68+
setHost(str.substring(0, colonIdx));
69+
setPort(Integer.parseInt(str.substring(colonIdx + 1, barIdx)));
70+
setDatabase(str.substring(barIdx + 1));
71+
}
72+
else
73+
if (barIdx != -1) { // @host/db
74+
setHost(str.substring(0, barIdx));
75+
setPort(DEFAULT_PORT);
76+
setDatabase(str.substring(barIdx + 1));
77+
}
78+
else { // @db
79+
setHost(DEFAULT_HOST);
80+
setPort(DEFAULT_PORT);
81+
setDatabase(str);
82+
}
83+
}
84+
85+
private ParameterException invalidConnectionString() {
86+
return new ParameterException("Invalid connection string.");
87+
}
88+
5889
public String getUser() {
5990
return user;
6091
}
6192

62-
public void setUser(String user) {
93+
private void setUser(String user) {
6394
this.user = user;
6495
}
6596

6697
public String getPassword() {
6798
return password;
6899
}
69100

70-
public void setPassword(String password) {
101+
private void setPassword(String password) {
71102
this.password = password;
72103
}
73104

74105
public String getHost() {
75106
return host;
76107
}
77108

78-
public void setHost(String host) {
109+
private void setHost(String host) {
79110
this.host = host;
80111
}
81112

82113
public int getPort() {
83114
return port;
84115
}
85116

86-
public void setPort(int port) {
117+
private void setPort(int port) {
87118
this.port = port;
88119
}
89120

90-
public String getDb() {
91-
return db;
121+
public String getDatabase() {
122+
return database;
92123
}
93124

94-
public void setDb(String db) {
95-
this.db = db;
125+
private void setDatabase(String database) {
126+
this.database = database;
96127
}
97128

98129
public String getConnectionUrl() {
99-
return String.format("jdbc:oracle:thin:@//%s:%d/%s", getHost(), getPort(), getDb());
130+
return String.format("jdbc:oracle:thin:@//%s:%d/%s", getHost(), getPort(), getDatabase());
100131
}
101132

102133
@Override
103134
public String toString() {
104-
return String.format("%s@%s:%d/%s", getUser(), getHost(), getPort(), getDb());
135+
return String.format("%s@%s:%d/%s", getUser(), getHost(), getPort(), getDatabase());
105136
}
106137

107138
}

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

Lines changed: 85 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,66 +11,124 @@ 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
21-
public void connectionStr_Full() {
20+
public void valid_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
}
3434
}
3535

3636
@Test
37-
public void connectionStr_WithoutPort() {
37+
public void valid_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
}
5051
}
5152

5253
@Test
53-
public void connectionStr_WithoutHostAndPort() {
54+
public void valid_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
}
6668
}
6769

6870
@Test
69-
public void connectionStr_Invalid() {
71+
public void invalid_WithoutDatabase_1() {
72+
try {
73+
new ConnectionInfo().parseConnectionString("user/pass@");
74+
Assert.fail();
75+
} catch (ParameterException ignored) {}
76+
}
77+
78+
@Test
79+
public void invalid_WithoutDatabase_2() {
7080
try {
7181
new ConnectionInfo().parseConnectionString("user/pass");
7282
Assert.fail();
7383
} catch (ParameterException ignored) {}
7484
}
7585

86+
@Test
87+
public void invalid_WithoutDatabase_3() {
88+
try {
89+
new ConnectionInfo().parseConnectionString("user/pass@localhost:1521");
90+
Assert.fail();
91+
} catch (ParameterException ignored) {}
92+
}
93+
94+
@Test
95+
public void invalid_WithoutHost() {
96+
try {
97+
new ConnectionInfo().parseConnectionString("user/pass@/db");
98+
Assert.fail();
99+
} catch (ParameterException ignored) {}
100+
}
101+
102+
@Test
103+
public void invalid_WithoutPassword() {
104+
try {
105+
new ConnectionInfo().parseConnectionString("user/@db");
106+
Assert.fail();
107+
} catch (ParameterException ignored) {}
108+
}
109+
110+
@Test
111+
public void invalid_WithoutUsername() {
112+
try {
113+
new ConnectionInfo().parseConnectionString("/pass@db");
114+
Assert.fail();
115+
} catch (ParameterException ignored) {}
116+
}
117+
118+
@Test
119+
public void invalid_WithoutUserPassDb_1() {
120+
try {
121+
new ConnectionInfo().parseConnectionString("/@db");
122+
Assert.fail();
123+
} catch (ParameterException ignored) {}
124+
}
125+
126+
@Test
127+
public void invalid_WithoutUserPass() {
128+
try {
129+
new ConnectionInfo().parseConnectionString("@db");
130+
Assert.fail();
131+
} catch (ParameterException ignored) {}
132+
}
133+
76134
}

0 commit comments

Comments
 (0)