package ru.testing.client.common;
import org.h2.tools.RunScript;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.testing.client.common.objects.*;
import ru.testing.client.common.properties.AppProperties;
import ru.testing.client.common.properties.DefaultProperties;
import java.io.*;
import java.sql.*;
/**
* H2 database with application settings
*/
public class DataBase {
private static final Logger LOGGER = LoggerFactory.getLogger(DataBase.class);
private static final String APP_FOLDER = ".ws.client";
private static final String DB_TYPE = "jdbc:h2";
private static final String DB_NAME = "data.v%s";
private static final String CREATE_SQL_SCRIPT = "create.db.sql";
private static String dbPath;
private static DataBase instance;
private Connection connection;
static {
// Add database driver to class path
try {
Class.forName("org.h2.Driver");
} catch (ClassNotFoundException e) {
LOGGER.error("Error load sqlite jdbc driver: {}", e.getMessage());
System.exit(1);
}
// Setup paths
AppProperties properties = AppProperties.getAppProperties();
String appFolder = String.format("%s/%s/", System.getProperty("user.home"), APP_FOLDER);
dbPath = String.format("%s/%s", appFolder, String.format(DB_NAME, properties.getDbVersion()));
// Check app folder exist
File path = new File(appFolder);
boolean settingPathExists = path.exists() || path.mkdirs();
// Create
if (settingPathExists && !new File(dbPath + ".h2.db").exists()) {
getInstance().createTables();
}
}
/**
* Get database class instance
*
* @return DataBase
*/
public synchronized static DataBase getInstance() {
if (instance == null) {
instance = new DataBase();
}
return instance;
}
/**
* Get global application settings
*
* @return Settings
*/
public Settings getSettings() {
Settings settings = null;
try (Connection connection = getConnection()) {
Statement s = connection.createStatement();
ResultSet r = s.executeQuery("SELECT * FROM global_settings");
while (r.next()) {
settings = new Settings(
r.getInt("font_size"),
r.getBoolean("text_wrap"),
r.getBoolean("auto_scroll"),
r.getBoolean("ws_ssl_validate")
);
}
} catch (SQLException e) {
LOGGER.error("Error get global settings: {}", e.getMessage());
}
return settings;
}
/**
* Set current settings state
*
* @param settings Settings
* @return boolean status
*/
public boolean setSettings(Settings settings) {
try (Connection connection = getConnection()) {
PreparedStatement ps = connection.prepareStatement("UPDATE global_settings SET " +
"font_size=?, text_wrap=?, auto_scroll=?, ws_ssl_validate=?");
ps.setInt(1, settings.getFontSize());
ps.setBoolean(2, settings.isTextWrap());
ps.setBoolean(3, settings.isAutoScroll());
ps.setBoolean(4, settings.isWsSslValidate());
ps.executeUpdate();
return true;
}catch (SQLException e) {
LOGGER.error("Error set current settings state: {}", e.getMessage());
return false;
}
}
/**
* Create database connection
*
* @return Connection
* @throws SQLException DriverManager get connection
*/
private Connection getConnection() throws SQLException {
if (connection == null || connection.isClosed()) {
connection = DriverManager.getConnection(String.format("%s:%s", DB_TYPE, dbPath), "sa", "");
}
return connection;
}
/**
* Create default tables in database
*/
private void createTables() {
try (final Connection connection = getConnection()) {
// Default properties values
DefaultProperties properties = DefaultProperties.getInstance();
// Create tables
LOGGER.debug("Create tables in database ...");
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream is = classloader.getResourceAsStream(CREATE_SQL_SCRIPT);
RunScript.execute(connection, new InputStreamReader(is));
// Insert default settings values
LOGGER.debug("Insert default settings ...");
PreparedStatement pss = connection.prepareStatement("INSERT INTO global_settings " +
"(font_size, text_wrap, auto_scroll, ws_ssl_validate) " +
"VALUES (?, ?, ?, ?)");
pss.setInt(1, properties.getMsgFontSize());
pss.setBoolean(2, properties.isMsgWrap());
pss.setBoolean(3, properties.isAutoScroll());
pss.setBoolean(4, properties.isWsSslValidate());
pss.executeUpdate();
LOGGER.debug("Database create successful");
} catch (SQLException e) {
LOGGER.error("Error create default tables: {}", e.getMessage());
}
}
}