Use prepared sql statements
This commit is contained in:
parent
68125c7c92
commit
728d65f220
1 changed files with 174 additions and 105 deletions
|
@ -186,7 +186,6 @@ public class DatabaseController {
|
|||
dropTables(() -> initTables(callback, errorCallback), errorCallback);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetches the list of users for which we already have a chat history
|
||||
*
|
||||
|
@ -232,82 +231,6 @@ public class DatabaseController {
|
|||
executor.start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a message to the database for this user.
|
||||
* If the user does not exist, we create it.
|
||||
*
|
||||
* @param message The message to add to the database
|
||||
* @param callback Function called when the request is done
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public void addMessage(Message message, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
// Insert the correspondent if not already in the database
|
||||
Log.v(getClass().getSimpleName(), "Inserting correspondent into db... ");
|
||||
addUser(message.getCorrespondent(), () -> {
|
||||
// Handle messages containing a file
|
||||
String filePath = "NULL";
|
||||
if (message instanceof FileMessage) {
|
||||
filePath = "'" + ((FileMessage) message).getPath() + "'";
|
||||
}
|
||||
|
||||
String recipientId = message.getRecipient().id;
|
||||
String senderId = message.getSender().id;
|
||||
|
||||
// Insert the new message
|
||||
@Language("SQL") String sql = "INSERT INTO message " +
|
||||
"(timestamp, sender, recipient, text, file_path) " +
|
||||
"VALUES (" +
|
||||
message.getDate().getTime() + ", " +
|
||||
"'" + senderId + "', " +
|
||||
"'" + recipientId + "', " +
|
||||
"'" + message.getText() + "', " +
|
||||
filePath +
|
||||
")";
|
||||
Log.v(getClass().getSimpleName(), "Inserting message into db... ");
|
||||
UpdateExecutor executor = new UpdateExecutor(sql, callback, errorCallback);
|
||||
executor.start();
|
||||
|
||||
}, errorCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the given user if not existing
|
||||
*
|
||||
* @param user The user information to store
|
||||
* @param callback The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public void addUser(UserInformation user, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
@Language("SQL") String sql;
|
||||
if (user.getUsername() != null) {
|
||||
sql = "INSERT OR IGNORE INTO user (id, username) " +
|
||||
"VALUES ('" + user.id + "', '" + user.getUsername() + "')";
|
||||
} else {
|
||||
sql = "INSERT OR IGNORE INTO user (id) " +
|
||||
"VALUES ('" + user.id + "')";
|
||||
}
|
||||
|
||||
Log.v(getClass().getSimpleName(), "Adding user to db: " + user.id + " / " + user.getUsername());
|
||||
UpdateExecutor executor = new UpdateExecutor(sql, callback, errorCallback);
|
||||
executor.start();
|
||||
}
|
||||
|
||||
public void addCurrentUser(UserInformation user, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
@Language("SQL") String sql;
|
||||
if (user.getUsername() != null) {
|
||||
sql = "INSERT OR IGNORE INTO current_user (id, username) " +
|
||||
"VALUES ('" + user.id + "', '" + user.getUsername() + "')";
|
||||
} else {
|
||||
sql = "INSERT OR IGNORE INTO current_user (id) " +
|
||||
"VALUES ('" + user.id + "')";
|
||||
}
|
||||
|
||||
Log.v(getClass().getSimpleName(), "Adding current_user to db: " + user.id + " / " + user.getUsername());
|
||||
UpdateExecutor executor = new UpdateExecutor(sql, callback, errorCallback);
|
||||
executor.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chat history for a given time frame
|
||||
*
|
||||
|
@ -319,20 +242,14 @@ public class DatabaseController {
|
|||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public void getChatHistory(UserInformation user1, UserInformation user2, Date from, Date to, HistoryCallback callback, ErrorCallback errorCallback) {
|
||||
// TODO update to search in current_user table as well
|
||||
@Language("SQL") String sql =
|
||||
"SELECT timestamp," +
|
||||
" sender," +
|
||||
" recipient," +
|
||||
" text," +
|
||||
" file_path " +
|
||||
"FROM message WHERE (sender = '" + user1.id + "'" +
|
||||
" OR recipient = '" + user1.id + "')" +
|
||||
" AND timestamp > " + from.getTime() + " AND timestamp < " + to.getTime() + " " +
|
||||
"SELECT timestamp, sender, recipient, text, file_path " +
|
||||
"FROM message WHERE (sender = ? OR recipient = ?)" +
|
||||
" AND timestamp > ? AND timestamp < ? " +
|
||||
"ORDER BY timestamp";
|
||||
|
||||
Log.v(getClass().getSimpleName(), "Fetching chat history from db... ");
|
||||
QueryExecutor executor = new QueryExecutor(sql, res -> {
|
||||
executeGetChatHistory(user1, from, to, sql, res -> {
|
||||
ArrayList<Message> chatHistory = new ArrayList<>();
|
||||
while (res.next()) {
|
||||
Date date = new Date(res.getTimestamp("timestamp").getTime());
|
||||
|
@ -365,20 +282,141 @@ public class DatabaseController {
|
|||
Log.v(getClass().getSimpleName(), chatHistory.size() + " messages fetched");
|
||||
callback.onHistoryFetched(chatHistory);
|
||||
}, errorCallback);
|
||||
}
|
||||
|
||||
executor.start();
|
||||
private void executeGetChatHistory(UserInformation user, Date from, Date to, @Language("SQL") String sql, QueryCallback callback, ErrorCallback errorCallback) {
|
||||
try {
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
||||
preparedStatement.setString(1, user.id);
|
||||
preparedStatement.setString(2, user.id);
|
||||
preparedStatement.setLong(3, from.getTime());
|
||||
preparedStatement.setLong(4, to.getTime());
|
||||
QueryExecutor executor = new QueryExecutor(
|
||||
preparedStatement,
|
||||
callback,
|
||||
errorCallback);
|
||||
executor.start();
|
||||
} catch (SQLException e) {
|
||||
Log.e(this.getClass().getSimpleName(), "Could not prepare statement: ", e);
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a message to the database for this user.
|
||||
* If the user does not exist, we create it.
|
||||
*
|
||||
* @param message The message to add to the database
|
||||
* @param callback Function called when the request is done
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public void addMessage(Message message, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
// Insert the correspondent if not already in the database
|
||||
Log.v(getClass().getSimpleName(), "Inserting correspondent into db... ");
|
||||
addUser(message.getCorrespondent(), () -> {
|
||||
// Handle messages containing a file
|
||||
String filePath = null;
|
||||
if (message instanceof FileMessage) {
|
||||
filePath = "'" + ((FileMessage) message).getPath() + "'";
|
||||
}
|
||||
@Language("SQL") String sql = "INSERT INTO message " +
|
||||
"(timestamp, sender, recipient, text, file_path) VALUES (?, ?, ?, ?, ?)";
|
||||
Log.v(getClass().getSimpleName(), "Inserting message into db... ");
|
||||
executeAddMessage(message, filePath, sql, callback, errorCallback);
|
||||
}, errorCallback);
|
||||
}
|
||||
|
||||
private void executeAddMessage(Message message, String filePath, @Language("SQL") String sql, @Nullable UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
try {
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
||||
preparedStatement.setLong(1, message.getDate().getTime());
|
||||
preparedStatement.setString(2, message.getSender().id);
|
||||
preparedStatement.setString(3, message.getRecipient().id);
|
||||
preparedStatement.setString(4, message.getText());
|
||||
preparedStatement.setString(5, filePath);
|
||||
UpdateExecutor executor = new UpdateExecutor(
|
||||
preparedStatement,
|
||||
callback,
|
||||
errorCallback);
|
||||
executor.start();
|
||||
} catch (SQLException e) {
|
||||
Log.e(this.getClass().getSimpleName(), "Could not prepare statement: ", e);
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the given user if not existing
|
||||
*
|
||||
* @param user The user information to store
|
||||
* @param callback The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public void addUser(UserInformation user, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
@Language("SQL") String sql;
|
||||
if (user.getUsername() != null) {
|
||||
sql = "INSERT OR IGNORE INTO user (id, username) VALUES (?, ?)";
|
||||
} else {
|
||||
sql = "INSERT OR IGNORE INTO user (id) VALUES (?)";
|
||||
}
|
||||
Log.v(getClass().getSimpleName(), "Adding user to db: " + user.id + " / " + user.getUsername());
|
||||
executeAddUser(user, sql, callback, errorCallback);
|
||||
}
|
||||
|
||||
public void addCurrentUser(UserInformation user, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
@Language("SQL") String sql;
|
||||
if (user.getUsername() != null) {
|
||||
sql = "INSERT OR IGNORE INTO current_user (id, username) VALUES (?, ?)";
|
||||
} else {
|
||||
sql = "INSERT OR IGNORE INTO current_user (id) VALUES (?)";
|
||||
}
|
||||
Log.v(getClass().getSimpleName(), "Adding current_user to db: " + user.id + " / " + user.getUsername());
|
||||
executeAddUser(user, sql, callback, errorCallback);
|
||||
}
|
||||
|
||||
private void executeAddUser(UserInformation user, @Language("SQL") String sql, @Nullable UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
try {
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
||||
preparedStatement.setString(1, user.id);
|
||||
if (user.getUsername() != null) {
|
||||
preparedStatement.setString(2, user.getUsername());
|
||||
}
|
||||
UpdateExecutor executor = new UpdateExecutor(
|
||||
preparedStatement,
|
||||
callback,
|
||||
errorCallback);
|
||||
executor.start();
|
||||
} catch (SQLException e) {
|
||||
Log.e(this.getClass().getSimpleName(), "Could not prepare statement: ", e);
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUsername(UserInformation user, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
@Language("SQL") String sql = "UPDATE user SET username = '" + user.getUsername() + "' where id = '" + user.id + "'";
|
||||
UpdateExecutor executor = new UpdateExecutor(sql, callback, errorCallback);
|
||||
executor.start();
|
||||
@Language("SQL") String sql = "UPDATE user SET username = ? where id = ?";
|
||||
executeUsernameUpdate(user, sql, callback, errorCallback);
|
||||
}
|
||||
|
||||
public void updateCurrentUsername(UserInformation user, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
@Language("SQL") String sql = "UPDATE current_user SET username = '" + user.getUsername() + "' where id = '" + user.id + "'";
|
||||
UpdateExecutor executor = new UpdateExecutor(sql, callback, errorCallback);
|
||||
executor.start();
|
||||
@Language("SQL") String sql = "UPDATE current_user SET username = ? where id = ?";
|
||||
executeUsernameUpdate(user, sql, callback, errorCallback);
|
||||
}
|
||||
|
||||
private void executeUsernameUpdate(UserInformation user, @Language("SQL") String sql, @Nullable UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
try {
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
||||
preparedStatement.setString(1, user.getUsername());
|
||||
preparedStatement.setString(2, user.id);
|
||||
UpdateExecutor executor = new UpdateExecutor(
|
||||
preparedStatement,
|
||||
callback,
|
||||
errorCallback);
|
||||
executor.start();
|
||||
} catch (SQLException e) {
|
||||
Log.e(this.getClass().getSimpleName(), "Could not prepare statement: ", e);
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public interface UsersCallback {
|
||||
|
@ -389,11 +427,6 @@ public class DatabaseController {
|
|||
void onFetched(UserInformation user);
|
||||
}
|
||||
|
||||
|
||||
public interface UsernameCallback {
|
||||
void onUsernameFetched(String username);
|
||||
}
|
||||
|
||||
public interface HistoryCallback {
|
||||
void onHistoryFetched(ArrayList<Message> history);
|
||||
}
|
||||
|
@ -408,6 +441,7 @@ public class DatabaseController {
|
|||
|
||||
private class UpdateExecutor extends Thread {
|
||||
private final String sqlQuery;
|
||||
private final PreparedStatement preparedStatement;
|
||||
private final UpdateCallback callback;
|
||||
private final ErrorCallback errorCallback;
|
||||
|
||||
|
@ -419,18 +453,33 @@ public class DatabaseController {
|
|||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public UpdateExecutor(@Language("SQL") String sqlQuery, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
this.preparedStatement = null;
|
||||
this.sqlQuery = sqlQuery;
|
||||
this.callback = callback;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
public UpdateExecutor(PreparedStatement preparedStatement, @Nullable DatabaseController.UpdateCallback callback, ErrorCallback errorCallback) {
|
||||
this.preparedStatement = preparedStatement;
|
||||
this.sqlQuery = null;
|
||||
this.callback = callback;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Statement statement = connection.createStatement();
|
||||
final int rowsModified = statement.executeUpdate(sqlQuery);
|
||||
int rowsModified;
|
||||
if (preparedStatement == null) {
|
||||
Statement statement = connection.createStatement();
|
||||
rowsModified = statement.executeUpdate(sqlQuery);
|
||||
statement.close();
|
||||
} else {
|
||||
rowsModified = preparedStatement.executeUpdate();
|
||||
preparedStatement.close();
|
||||
}
|
||||
Log.v(getClass().getSimpleName(), rowsModified + " rows modified");
|
||||
statement.close();
|
||||
|
||||
if (callback != null) {
|
||||
callback.onUpdateExecuted();
|
||||
}
|
||||
|
@ -443,6 +492,7 @@ public class DatabaseController {
|
|||
|
||||
private class QueryExecutor extends Thread {
|
||||
private final String sqlQuery;
|
||||
private final PreparedStatement preparedStatement;
|
||||
private final QueryCallback callback;
|
||||
private final ErrorCallback errorCallback;
|
||||
|
||||
|
@ -454,21 +504,40 @@ public class DatabaseController {
|
|||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public QueryExecutor(@Language("SQL") String sqlQuery, @Nullable QueryCallback callback, ErrorCallback errorCallback) {
|
||||
this.preparedStatement = null;
|
||||
this.sqlQuery = sqlQuery;
|
||||
this.callback = callback;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
public QueryExecutor(PreparedStatement preparedStatement, @Nullable QueryCallback callback, ErrorCallback errorCallback) {
|
||||
this.preparedStatement = preparedStatement;
|
||||
this.sqlQuery = null;
|
||||
this.callback = callback;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Statement statement = connection.createStatement();
|
||||
final ResultSet resultSet = statement.executeQuery(sqlQuery);
|
||||
Statement statement = null;
|
||||
final ResultSet resultSet;
|
||||
if (preparedStatement == null) {
|
||||
statement = connection.createStatement();
|
||||
resultSet = statement.executeQuery(sqlQuery);
|
||||
} else {
|
||||
resultSet = preparedStatement.executeQuery();
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.onQueryExecuted(resultSet);
|
||||
}
|
||||
resultSet.close();
|
||||
statement.close();
|
||||
if (statement != null) {
|
||||
statement.close();
|
||||
}
|
||||
if (preparedStatement != null) {
|
||||
preparedStatement.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Log.e(this.getClass().getSimpleName(), "Error executing update: ", e);
|
||||
errorCallback.onError(e);
|
||||
|
|
Loading…
Reference in a new issue