mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2025-02-26 08:41:37 +01:00
#1539 Use columns handler in more datasource methods; fix case-insensitivity for SQLite
This commit is contained in:
parent
881ef6a640
commit
137fc3d505
@ -1,6 +1,7 @@
|
|||||||
package fr.xephi.authme.datasource;
|
package fr.xephi.authme.datasource;
|
||||||
|
|
||||||
import ch.jalu.datasourcecolumns.data.DataSourceValues;
|
import ch.jalu.datasourcecolumns.data.DataSourceValues;
|
||||||
|
import ch.jalu.datasourcecolumns.predicate.AlwaysTruePredicate;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException;
|
import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException;
|
||||||
@ -23,11 +24,14 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static ch.jalu.datasourcecolumns.data.UpdateValues.with;
|
import static ch.jalu.datasourcecolumns.data.UpdateValues.with;
|
||||||
|
import static ch.jalu.datasourcecolumns.predicate.StandardPredicates.eq;
|
||||||
|
import static ch.jalu.datasourcecolumns.predicate.StandardPredicates.eqIgnoreCase;
|
||||||
import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong;
|
import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong;
|
||||||
import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
|
import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
|
||||||
|
|
||||||
@ -269,24 +273,20 @@ public class MySQL implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAuthAvailable(String user) {
|
public boolean isAuthAvailable(String user) {
|
||||||
String sql = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
try {
|
||||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
return columnsHandler.retrieve(user, AuthMeColumns.NAME).rowExists();
|
||||||
pst.setString(1, user.toLowerCase());
|
} catch (SQLException e) {
|
||||||
try (ResultSet rs = pst.executeQuery()) {
|
logSqlException(e);
|
||||||
return rs.next();
|
return false;
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HashedPassword getPassword(String user) {
|
public HashedPassword getPassword(String user) {
|
||||||
try {
|
try {
|
||||||
DataSourceValues passwordResult = columnsHandler.retrieve(user, AuthMeColumns.PASSWORD, AuthMeColumns.SALT);
|
DataSourceValues values = columnsHandler.retrieve(user, AuthMeColumns.PASSWORD, AuthMeColumns.SALT);
|
||||||
if (passwordResult.rowExists()) {
|
if (values.rowExists()) {
|
||||||
return new HashedPassword(passwordResult.get(AuthMeColumns.PASSWORD), passwordResult.get(AuthMeColumns.SALT));
|
return new HashedPassword(values.get(AuthMeColumns.PASSWORD), values.get(AuthMeColumns.SALT));
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
logSqlException(e);
|
logSqlException(e);
|
||||||
@ -354,19 +354,7 @@ public class MySQL implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean updateSession(PlayerAuth auth) {
|
public boolean updateSession(PlayerAuth auth) {
|
||||||
String sql = "UPDATE " + tableName + " SET "
|
return columnsHandler.update(auth, AuthMeColumns.LAST_IP, AuthMeColumns.LAST_LOGIN, AuthMeColumns.NICK_NAME);
|
||||||
+ col.LAST_IP + "=?, " + col.LAST_LOGIN + "=?, " + col.REAL_NAME + "=? WHERE " + col.NAME + "=?;";
|
|
||||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
|
||||||
pst.setString(1, auth.getLastIp());
|
|
||||||
pst.setObject(2, auth.getLastLogin());
|
|
||||||
pst.setString(3, auth.getRealName());
|
|
||||||
pst.setString(4, auth.getNickname());
|
|
||||||
pst.executeUpdate();
|
|
||||||
return true;
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -427,35 +415,17 @@ public class MySQL implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getAllAuthsByIp(String ip) {
|
public List<String> getAllAuthsByIp(String ip) {
|
||||||
List<String> result = new ArrayList<>();
|
try {
|
||||||
String sql = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.LAST_IP + "=?;";
|
return columnsHandler.retrieve(eq(AuthMeColumns.LAST_IP, ip), AuthMeColumns.NAME);
|
||||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
} catch (SQLException e) {
|
||||||
pst.setString(1, ip);
|
logSqlException(e);
|
||||||
try (ResultSet rs = pst.executeQuery()) {
|
return Collections.emptyList();
|
||||||
while (rs.next()) {
|
|
||||||
result.add(rs.getString(col.NAME));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countAuthsByEmail(String email) {
|
public int countAuthsByEmail(String email) {
|
||||||
String sql = "SELECT COUNT(1) FROM " + tableName + " WHERE UPPER(" + col.EMAIL + ") = UPPER(?)";
|
return columnsHandler.count(eqIgnoreCase(AuthMeColumns.EMAIL, email));
|
||||||
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
|
||||||
pst.setString(1, email);
|
|
||||||
try (ResultSet rs = pst.executeQuery()) {
|
|
||||||
if (rs.next()) {
|
|
||||||
return rs.getInt(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -566,18 +536,7 @@ public class MySQL implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAccountsRegistered() {
|
public int getAccountsRegistered() {
|
||||||
int result = 0;
|
return columnsHandler.count(new AlwaysTruePredicate<>());
|
||||||
String sql = "SELECT COUNT(*) FROM " + tableName;
|
|
||||||
try (Connection con = getConnection();
|
|
||||||
Statement st = con.createStatement();
|
|
||||||
ResultSet rs = st.executeQuery(sql)) {
|
|
||||||
if (rs.next()) {
|
|
||||||
result = rs.getInt(1);
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package fr.xephi.authme.datasource;
|
package fr.xephi.authme.datasource;
|
||||||
|
|
||||||
import ch.jalu.datasourcecolumns.data.DataSourceValues;
|
import ch.jalu.datasourcecolumns.data.DataSourceValues;
|
||||||
|
import ch.jalu.datasourcecolumns.predicate.AlwaysTruePredicate;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||||
@ -20,11 +21,14 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static ch.jalu.datasourcecolumns.data.UpdateValues.with;
|
import static ch.jalu.datasourcecolumns.data.UpdateValues.with;
|
||||||
|
import static ch.jalu.datasourcecolumns.predicate.StandardPredicates.eq;
|
||||||
|
import static ch.jalu.datasourcecolumns.predicate.StandardPredicates.eqIgnoreCase;
|
||||||
import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong;
|
import static fr.xephi.authme.datasource.SqlDataSourceUtils.getNullableLong;
|
||||||
import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
|
import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
|
||||||
|
|
||||||
@ -211,14 +215,10 @@ public class SQLite implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAuthAvailable(String user) {
|
public boolean isAuthAvailable(String user) {
|
||||||
String sql = "SELECT 1 FROM " + tableName + " WHERE LOWER(" + col.NAME + ")=LOWER(?);";
|
try {
|
||||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
return columnsHandler.retrieve(user, AuthMeColumns.NAME).rowExists();
|
||||||
pst.setString(1, user);
|
} catch (SQLException e) {
|
||||||
try (ResultSet rs = pst.executeQuery()) {
|
logSqlException(e);
|
||||||
return rs.next();
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
ConsoleLogger.warning(ex.getMessage());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,19 +273,7 @@ public class SQLite implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean updateSession(PlayerAuth auth) {
|
public boolean updateSession(PlayerAuth auth) {
|
||||||
String sql = "UPDATE " + tableName + " SET " + col.LAST_IP + "=?, " + col.LAST_LOGIN + "=?, "
|
return columnsHandler.update(auth, AuthMeColumns.LAST_IP, AuthMeColumns.LAST_LOGIN, AuthMeColumns.NICK_NAME);
|
||||||
+ col.REAL_NAME + "=? WHERE " + col.NAME + "=?;";
|
|
||||||
try (PreparedStatement pst = con.prepareStatement(sql)){
|
|
||||||
pst.setString(1, auth.getLastIp());
|
|
||||||
pst.setObject(2, auth.getLastLogin());
|
|
||||||
pst.setString(3, auth.getRealName());
|
|
||||||
pst.setString(4, auth.getNickname());
|
|
||||||
pst.executeUpdate();
|
|
||||||
return true;
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -360,36 +348,17 @@ public class SQLite implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getAllAuthsByIp(String ip) {
|
public List<String> getAllAuthsByIp(String ip) {
|
||||||
List<String> countIp = new ArrayList<>();
|
try {
|
||||||
String sql = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.LAST_IP + "=?;";
|
return columnsHandler.retrieve(eq(AuthMeColumns.LAST_IP, ip), AuthMeColumns.NAME);
|
||||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
} catch (SQLException e) {
|
||||||
pst.setString(1, ip);
|
logSqlException(e);
|
||||||
try (ResultSet rs = pst.executeQuery()) {
|
return Collections.emptyList();
|
||||||
while (rs.next()) {
|
|
||||||
countIp.add(rs.getString(col.NAME));
|
|
||||||
}
|
|
||||||
return countIp;
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countAuthsByEmail(String email) {
|
public int countAuthsByEmail(String email) {
|
||||||
String sql = "SELECT COUNT(1) FROM " + tableName + " WHERE " + col.EMAIL + " = ? COLLATE NOCASE;";
|
return columnsHandler.count(eqIgnoreCase(AuthMeColumns.EMAIL, email));
|
||||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
|
||||||
pst.setString(1, email);
|
|
||||||
try (ResultSet rs = pst.executeQuery()) {
|
|
||||||
if (rs.next()) {
|
|
||||||
return rs.getInt(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -491,15 +460,7 @@ public class SQLite implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAccountsRegistered() {
|
public int getAccountsRegistered() {
|
||||||
String sql = "SELECT COUNT(*) FROM " + tableName + ";";
|
return columnsHandler.count(new AlwaysTruePredicate<>());
|
||||||
try (PreparedStatement pst = con.prepareStatement(sql); ResultSet rs = pst.executeQuery()) {
|
|
||||||
if (rs.next()) {
|
|
||||||
return rs.getInt(1);
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -607,16 +568,6 @@ public class SQLite implements DataSource {
|
|||||||
+ currentTimestamp + ", to all " + updatedRows + " rows");
|
+ currentTimestamp + ", to all " + updatedRows + " rows");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void close(Statement st) {
|
|
||||||
if (st != null) {
|
|
||||||
try {
|
|
||||||
st.close();
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void close(Connection con) {
|
private static void close(Connection con) {
|
||||||
if (con != null) {
|
if (con != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -45,6 +45,9 @@ public final class AuthMeColumns<T> implements DependentColumn<T, ColumnContext,
|
|||||||
public static final AuthMeColumns<Integer> GROUP_ID = createInteger(
|
public static final AuthMeColumns<Integer> GROUP_ID = createInteger(
|
||||||
DatabaseSettings.MYSQL_COL_GROUP, PlayerAuth::getGroupId, OPTIONAL);
|
DatabaseSettings.MYSQL_COL_GROUP, PlayerAuth::getGroupId, OPTIONAL);
|
||||||
|
|
||||||
|
public static final AuthMeColumns<Long> LAST_LOGIN = createLong(
|
||||||
|
DatabaseSettings.MYSQL_COL_LASTLOGIN, PlayerAuth::getLastLogin);
|
||||||
|
|
||||||
public static final AuthMeColumns<String> REGISTRATION_IP = createString(
|
public static final AuthMeColumns<String> REGISTRATION_IP = createString(
|
||||||
DatabaseSettings.MYSQL_COL_REGISTER_IP, PlayerAuth::getRegistrationIp);
|
DatabaseSettings.MYSQL_COL_REGISTER_IP, PlayerAuth::getRegistrationIp);
|
||||||
|
|
||||||
|
@ -3,7 +3,9 @@ package fr.xephi.authme.datasource.columnshandler;
|
|||||||
import ch.jalu.datasourcecolumns.data.DataSourceValue;
|
import ch.jalu.datasourcecolumns.data.DataSourceValue;
|
||||||
import ch.jalu.datasourcecolumns.data.DataSourceValues;
|
import ch.jalu.datasourcecolumns.data.DataSourceValues;
|
||||||
import ch.jalu.datasourcecolumns.data.UpdateValues;
|
import ch.jalu.datasourcecolumns.data.UpdateValues;
|
||||||
|
import ch.jalu.datasourcecolumns.predicate.Predicate;
|
||||||
import ch.jalu.datasourcecolumns.sqlimplementation.PredicateSqlGenerator;
|
import ch.jalu.datasourcecolumns.sqlimplementation.PredicateSqlGenerator;
|
||||||
|
import ch.jalu.datasourcecolumns.sqlimplementation.PreparedStatementGenerator;
|
||||||
import ch.jalu.datasourcecolumns.sqlimplementation.ResultSetValueRetriever;
|
import ch.jalu.datasourcecolumns.sqlimplementation.ResultSetValueRetriever;
|
||||||
import ch.jalu.datasourcecolumns.sqlimplementation.SqlColumnsHandler;
|
import ch.jalu.datasourcecolumns.sqlimplementation.SqlColumnsHandler;
|
||||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||||
@ -12,6 +14,7 @@ import fr.xephi.authme.settings.properties.DatabaseSettings;
|
|||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
|
import static fr.xephi.authme.datasource.SqlDataSourceUtils.logSqlException;
|
||||||
|
|
||||||
@ -39,8 +42,9 @@ public final class AuthMeColumnsHandler {
|
|||||||
String tableName = settings.getProperty(DatabaseSettings.MYSQL_TABLE);
|
String tableName = settings.getProperty(DatabaseSettings.MYSQL_TABLE);
|
||||||
String nameColumn = settings.getProperty(DatabaseSettings.MYSQL_COL_NAME);
|
String nameColumn = settings.getProperty(DatabaseSettings.MYSQL_COL_NAME);
|
||||||
|
|
||||||
SqlColumnsHandler<ColumnContext, String> sqlColHandler =
|
SqlColumnsHandler<ColumnContext, String> sqlColHandler = new SqlColumnsHandler<>(
|
||||||
new SqlColumnsHandler<>(connection, columnContext, tableName, nameColumn);
|
PreparedStatementGenerator.fromConnection(connection), columnContext, tableName, nameColumn,
|
||||||
|
new ResultSetValueRetriever<>(columnContext), new PredicateSqlGenerator<>(columnContext, true));
|
||||||
return new AuthMeColumnsHandler(sqlColHandler);
|
return new AuthMeColumnsHandler(sqlColHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +139,18 @@ public final class AuthMeColumnsHandler {
|
|||||||
return internalHandler.retrieve(name.toLowerCase(), columns);
|
return internalHandler.retrieve(name.toLowerCase(), columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a column's value for all rows that satisfy the given predicate.
|
||||||
|
*
|
||||||
|
* @param predicate the predicate to fulfill
|
||||||
|
* @param column the column to retrieve from the matching rows
|
||||||
|
* @param <T> the column's value type
|
||||||
|
* @return the values of the matching rows
|
||||||
|
*/
|
||||||
|
public <T> List<T> retrieve(Predicate<ColumnContext> predicate, AuthMeColumns<T> column) throws SQLException {
|
||||||
|
return internalHandler.retrieve(predicate, column);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts the given values into a new row, as taken from the player auth.
|
* Inserts the given values into a new row, as taken from the player auth.
|
||||||
*
|
*
|
||||||
@ -150,4 +166,19 @@ public final class AuthMeColumnsHandler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of rows that match the provided predicate.
|
||||||
|
*
|
||||||
|
* @param predicate the predicate to test the rows for
|
||||||
|
* @return number of rows fulfilling the predicate
|
||||||
|
*/
|
||||||
|
public int count(Predicate<ColumnContext> predicate) {
|
||||||
|
try {
|
||||||
|
return internalHandler.count(predicate);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logSqlException(e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,9 @@ public class MySqlIntegrationTest extends AbstractDataSourceIntegrationTest {
|
|||||||
HikariConfig config = new HikariConfig();
|
HikariConfig config = new HikariConfig();
|
||||||
config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource");
|
config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource");
|
||||||
config.setConnectionTestQuery("VALUES 1");
|
config.setConnectionTestQuery("VALUES 1");
|
||||||
config.addDataSourceProperty("URL", "jdbc:h2:mem:test");
|
// Note "ignorecase=true": H2 does not support `COLLATE NOCASE` for case-insensitive equals queries.
|
||||||
|
// MySQL is by default case-insensitive so this is OK to make as an assumption.
|
||||||
|
config.addDataSourceProperty("URL", "jdbc:h2:mem:test;ignorecase=true");
|
||||||
config.addDataSourceProperty("user", "sa");
|
config.addDataSourceProperty("user", "sa");
|
||||||
config.addDataSourceProperty("password", "sa");
|
config.addDataSourceProperty("password", "sa");
|
||||||
HikariDataSource ds = new HikariDataSource(config);
|
HikariDataSource ds = new HikariDataSource(config);
|
||||||
|
Loading…
Reference in New Issue
Block a user