Skip to content

Commit 336ac9c

Browse files
authoredOct 18, 2018
Merge pull request #106 from utPLSQL/bugfix/NLS_LANG_handling
Bugfix: NLS_LANG handling
2 parents f87c61e + 6bb8b9e commit 336ac9c

File tree

3 files changed

+100
-17
lines changed

3 files changed

+100
-17
lines changed
 

‎src/main/java/org/utplsql/cli/LocaleInitializer.java

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package org.utplsql.cli;
22

3+
import org.utplsql.api.EnvironmentVariableUtil;
4+
35
import java.util.Locale;
46
import java.util.regex.Matcher;
57
import java.util.regex.Pattern;
68

79
/** This class makes sure the java locale is set according to the environment variables LC_ALL and LANG
810
* We experienced that, in some cases, the locale was not set as expected, therefore this class implements some clear
911
* rules:
10-
* 1. If environment variable NLS_LANG is set, we try to parse its content and set locale according to its value if valid
11-
* 2. If environment variable LC_ALL is set, we try to parse its content and set locale according to its value if valid
12-
* 3. If environment variable LANG is set, we try to parse its content and set locale according to its value if valid
13-
* 4. Otherwise we use default locale
12+
* 1. If environment variable LC_ALL is set, we try to parse its content and set locale according to its value if valid
13+
* 2. If environment variable LANG is set, we try to parse its content and set locale according to its value if valid
14+
* 3. Otherwise we use default locale
1415
*
1516
* @author pesse
1617
*/
@@ -23,12 +24,9 @@ class LocaleInitializer {
2324
*/
2425
static void initLocale() {
2526

26-
boolean localeChanged = setDefaultLocale(System.getenv("NLS_LANG"));
27-
28-
if ( !localeChanged )
29-
localeChanged = setDefaultLocale(System.getenv("LC_ALL"));
27+
boolean localeChanged = setDefaultLocale(EnvironmentVariableUtil.getEnvValue("LC_ALL"));
3028
if ( !localeChanged )
31-
setDefaultLocale(System.getenv("LANG"));
29+
setDefaultLocale(EnvironmentVariableUtil.getEnvValue("LANG"));
3230
}
3331

3432
/** Set the default locale from a given string like LC_ALL or LANG environment variable

‎src/main/java/org/utplsql/cli/datasource/TestedDataSourceProvider.java

+33-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package org.utplsql.cli.datasource;
22

33
import com.zaxxer.hikari.HikariDataSource;
4+
import org.utplsql.api.EnvironmentVariableUtil;
45
import org.utplsql.cli.ConnectionConfig;
56
import org.utplsql.cli.exception.DatabaseConnectionFailed;
67

7-
import java.io.File;
88
import java.sql.Connection;
99
import java.sql.SQLException;
1010
import java.util.ArrayList;
1111
import java.util.List;
12+
import java.util.regex.Matcher;
13+
import java.util.regex.Pattern;
1214

1315
public class TestedDataSourceProvider {
1416

@@ -17,7 +19,6 @@ interface ConnectStringPossibility {
1719
String getMaskedConnectString(ConnectionConfig config);
1820
}
1921

20-
2122
private final ConnectionConfig config;
2223
private List<ConnectStringPossibility> possibilities = new ArrayList<>();
2324

@@ -32,12 +33,13 @@ public HikariDataSource getDataSource() throws SQLException {
3233

3334
HikariDataSource ds = new HikariDataSource();
3435

35-
testAndSetJdbcUrl(ds);
36+
setInitSqlFrom_NLS_LANG(ds);
37+
setThickOrThinJdbcUrl(ds);
3638

3739
return ds;
3840
}
3941

40-
public void testAndSetJdbcUrl( HikariDataSource ds ) throws SQLException
42+
private void setThickOrThinJdbcUrl(HikariDataSource ds ) throws SQLException
4143
{
4244
List<String> errors = new ArrayList<>();
4345
Throwable lastException = null;
@@ -55,6 +57,33 @@ public void testAndSetJdbcUrl( HikariDataSource ds ) throws SQLException
5557
throw new DatabaseConnectionFailed(lastException);
5658
}
5759

60+
private void setInitSqlFrom_NLS_LANG(HikariDataSource ds ) {
61+
String nls_lang = EnvironmentVariableUtil.getEnvValue("NLS_LANG");
62+
63+
if ( nls_lang != null ) {
64+
Pattern pattern = Pattern.compile("^([a-zA-Z ]+)?_?([a-zA-Z ]+)?\\.?([a-zA-Z0-9]+)?$");
65+
Matcher matcher = pattern.matcher(nls_lang);
66+
67+
List<String> sqlCommands = new ArrayList<>(2);
68+
if (matcher.matches()) {
69+
if ( matcher.group(1) != null)
70+
sqlCommands.add(String.format("ALTER SESSION SET NLS_LANGUAGE='%s'", matcher.group(1)));
71+
if ( matcher.group(2) != null)
72+
sqlCommands.add(String.format("ALTER SESSION SET NLS_TERRITORY='%s'", matcher.group(2)));
73+
74+
if ( sqlCommands.size() > 0 ) {
75+
StringBuilder sb = new StringBuilder();
76+
sb.append("BEGIN\n");
77+
for (String command : sqlCommands)
78+
sb.append(String.format("EXECUTE IMMEDIATE q'[%s]';\n", command));
79+
sb.append("END;");
80+
81+
ds.setConnectionInitSql(sb.toString());
82+
}
83+
}
84+
}
85+
}
86+
5887
private static class ThickConnectStringPossibility implements ConnectStringPossibility {
5988
@Override
6089
public String getConnectString(ConnectionConfig config) {

‎src/test/java/org/utplsql/cli/DataSourceProviderIT.java

+60-4
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,75 @@
55

66
import javax.sql.DataSource;
77
import java.io.IOException;
8+
import java.sql.Connection;
9+
import java.sql.PreparedStatement;
10+
import java.sql.ResultSet;
811
import java.sql.SQLException;
912

13+
import static org.junit.jupiter.api.Assertions.assertEquals;
1014
import static org.junit.jupiter.api.Assertions.assertNotNull;
15+
import static org.junit.jupiter.api.Assertions.fail;
1116

12-
public class DataSourceProviderIT {
17+
class DataSourceProviderIT {
1318

1419
@Test
15-
public void connectToDatabase() throws IOException, SQLException {
20+
void connectToDatabase() throws SQLException {
21+
DataSource dataSource = getDataSource();
1622

17-
ConnectionConfig config = new ConnectionConfig(TestHelper.getConnectionString());
23+
assertNotNull(dataSource);
24+
}
25+
26+
@Test
27+
void initNlsLang() throws SQLException {
28+
System.setProperty("NLS_LANG", "BRAZILIAN PORTUGUESE_BRAZIL.WE8ISO8859P1");
29+
DataSource dataSource = getDataSource();
30+
31+
assertNotNull(dataSource);
32+
checkNlsSessionParameter(dataSource, "NLS_LANGUAGE", "BRAZILIAN PORTUGUESE");
33+
checkNlsSessionParameter(dataSource, "NLS_TERRITORY", "BRAZIL");
34+
}
35+
36+
@Test
37+
void initPartialNlsLangTerritory() throws SQLException {
38+
System.setProperty("NLS_LANG", "_SOMALIA");
39+
DataSource dataSource = getDataSource();
40+
41+
assertNotNull(dataSource);
42+
checkNlsSessionParameter(dataSource, "NLS_TERRITORY", "SOMALIA");
43+
}
44+
45+
@Test
46+
void initPartialNlsLangLanguage() throws SQLException {
47+
System.setProperty("NLS_LANG", "HINDI");
48+
DataSource dataSource = getDataSource();
49+
50+
assertNotNull(dataSource);
51+
checkNlsSessionParameter(dataSource, "NLS_LANGUAGE", "HINDI");
52+
}
1853

19-
DataSource dataSource = new TestedDataSourceProvider(config).getDataSource();
54+
@Test
55+
void initNlsLangEmpty() throws SQLException {
56+
System.setProperty("NLS_LANG", "");
57+
DataSource dataSource = getDataSource();
2058

2159
assertNotNull(dataSource);
2260
}
61+
62+
private DataSource getDataSource() throws SQLException {
63+
ConnectionConfig config = new ConnectionConfig(TestHelper.getConnectionString());
64+
return new TestedDataSourceProvider(config).getDataSource();
65+
}
66+
67+
private void checkNlsSessionParameter( DataSource dataSource, String parameterName, String expectedValue ) throws SQLException {
68+
try ( Connection con = dataSource.getConnection() ) {
69+
try (PreparedStatement stmt = con.prepareStatement("select value from nls_session_parameters where parameter = ?")) {
70+
stmt.setString(1, parameterName);
71+
ResultSet rs = stmt.executeQuery();
72+
if ( rs.next() )
73+
assertEquals(expectedValue, rs.getString(1));
74+
else
75+
fail("Could not get NLS Session parameter value for '" + parameterName + "'");
76+
}
77+
}
78+
}
2379
}

0 commit comments

Comments
 (0)