Перенос.
This commit is contained in:
261
src/Common/Database/SQLITE/SQLiteDatabase.java
Normal file
261
src/Common/Database/SQLITE/SQLiteDatabase.java
Normal file
@@ -0,0 +1,261 @@
|
||||
package Common.Database.SQLITE;
|
||||
import Common.Database.DBObject;
|
||||
import Common.Database.DBTable;
|
||||
import Common.Database.DBTableColumn;
|
||||
import Common.Database.Database;
|
||||
import Common.UI.UI;
|
||||
import Common.Utils.Utils;
|
||||
import Visual_DVM_2021.Passes.PassException;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Vector;
|
||||
|
||||
import static Common.Utils.Utils.requireNonNullElse;
|
||||
public abstract class SQLiteDatabase extends Database {
|
||||
protected Connection conn = null;
|
||||
protected Statement statement = null;
|
||||
protected ResultSet resSet = null;
|
||||
public LinkedHashMap<Class<? extends DBObject>, PreparedStatement> insertStatements = new LinkedHashMap<>();
|
||||
public LinkedHashMap<Class<? extends DBObject>, PreparedStatement> updateStatements = new LinkedHashMap<>();
|
||||
public LinkedHashMap<Class<? extends DBObject>, PreparedStatement> deleteStatements = new LinkedHashMap<>();
|
||||
//->>
|
||||
public SQLiteDatabase(File file_in) {
|
||||
super(file_in);
|
||||
}
|
||||
@Override
|
||||
protected void connect() throws Exception {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
try {
|
||||
conn = DriverManager.getConnection("jdbc:sqlite:" + file.getAbsolutePath());
|
||||
break;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
conn = null;
|
||||
System.gc();
|
||||
Utils.sleep(2000);
|
||||
}
|
||||
}
|
||||
if (conn == null)
|
||||
throw new PassException("Внутренняя ошибка sqlite. Не удалось установить соединение за 5 попыток.");
|
||||
statement = conn.createStatement();
|
||||
}
|
||||
@Override
|
||||
protected void disconnect() throws Exception {
|
||||
if (conn != null) {
|
||||
conn.close();
|
||||
conn = null;
|
||||
}
|
||||
if (statement != null) {
|
||||
statement.close();
|
||||
statement = null;
|
||||
}
|
||||
if (resSet != null) {
|
||||
resSet.close();
|
||||
resSet = null;
|
||||
}
|
||||
for (PreparedStatement preparedStatement : insertStatements.values()) {
|
||||
if (preparedStatement != null)
|
||||
preparedStatement.close();
|
||||
}
|
||||
for (PreparedStatement preparedStatement : updateStatements.values()) {
|
||||
if (preparedStatement != null)
|
||||
preparedStatement.close();
|
||||
}
|
||||
for (PreparedStatement preparedStatement : deleteStatements.values()) {
|
||||
if (preparedStatement != null)
|
||||
preparedStatement.close();
|
||||
}
|
||||
insertStatements.clear();
|
||||
updateStatements.clear();
|
||||
deleteStatements.clear();
|
||||
//-->>
|
||||
System.gc();
|
||||
//->>
|
||||
}
|
||||
@Override
|
||||
protected void beginTransaction() throws Exception {
|
||||
conn.setAutoCommit(false);
|
||||
}
|
||||
@Override
|
||||
protected void commit() throws Exception {
|
||||
conn.commit();
|
||||
conn.setAutoCommit(true);
|
||||
}
|
||||
@Override
|
||||
protected boolean TableExists(DBTable table) throws Exception {
|
||||
int count = 0;
|
||||
resSet = statement.executeQuery("SELECT count(*) FROM 'sqlite_master' WHERE type=\"table\" AND name=" + table.QName());
|
||||
if (resSet.next())
|
||||
count = resSet.getInt(1);
|
||||
return count > 0;
|
||||
}
|
||||
@Override
|
||||
public void CreateTable(DBTable table) throws Exception {
|
||||
if (table.columns.size() > 0) {
|
||||
if (TableExists(table)) {
|
||||
Vector<String> existing_columns = new Vector<>();
|
||||
Vector<String> columns_to_create = new Vector<>();
|
||||
//предполагаем что первичный ключ и атрибуты не изменятся.
|
||||
//и что не будет столбов с одинаковыми именами но разными типами.
|
||||
resSet = statement.executeQuery("pragma table_info(" + table.QName() + ")");
|
||||
while (resSet.next())
|
||||
existing_columns.add(resSet.getString(2));
|
||||
//-
|
||||
for (String target_column : table.columns.keySet()) {
|
||||
if (!existing_columns.contains(target_column))
|
||||
columns_to_create.add(target_column);
|
||||
}
|
||||
for (String cn : columns_to_create)
|
||||
statement.execute("ALTER TABLE " + table.QName() + " ADD COLUMN " + table.columns.get(cn));
|
||||
} else {
|
||||
String cmd = "CREATE TABLE if not exists " + table.QName() + " ";
|
||||
Vector<String> columns_names = new Vector<>();
|
||||
for (DBTableColumn column : table.columns.values())
|
||||
columns_names.add(column.toString());
|
||||
cmd += Utils.RBrackets(String.join(",", columns_names));
|
||||
statement.execute(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void prepareTablesStatements() throws Exception {
|
||||
for (DBTable table : tables.values()) {
|
||||
//---
|
||||
Vector<String> column_names = new Vector<>();
|
||||
Vector<String> column_values = new Vector<>();
|
||||
for (DBTableColumn column : table.columns.values()) {
|
||||
if (!column.AutoIncrement) {
|
||||
column_names.add(column.QName());
|
||||
column_values.add("?");
|
||||
}
|
||||
}
|
||||
insertStatements.put(table.d, conn.prepareStatement(
|
||||
"INSERT OR REPLACE INTO " + table.QName() + " " +
|
||||
Utils.RBrackets(String.join(",", column_names)) + " " + "VALUES " +
|
||||
Utils.RBrackets(String.join(",", column_values))));
|
||||
//------------------------------------------------------------------------------->>
|
||||
Vector<String> new_values = new Vector();
|
||||
for (DBTableColumn column : table.columns.values()) {
|
||||
if (!column.AutoIncrement) {
|
||||
new_values.add(column.QName() + "=?");
|
||||
}
|
||||
}
|
||||
updateStatements.put(table.d, conn.prepareStatement(
|
||||
"UPDATE " + table.QName() + " " +
|
||||
"SET " + String.join(",", new_values) + " " +
|
||||
"WHERE (" + table.PK.QName() + "=?)"
|
||||
));
|
||||
//---------------------------------------------------------------------------------->>>
|
||||
deleteStatements.put(table.d, conn.prepareStatement("DELETE FROM " + table.QName() + " WHERE " + table.PK.QName() + " = ?"));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void delete(DBTable table, DBObject o) throws Exception {
|
||||
PreparedStatement ps = deleteStatements.get(table.d);
|
||||
ps.setObject(1, o.getPK());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
protected <K, D extends DBObject> Pair<K, D> readRecord(DBTable<K, D> table) throws Exception {
|
||||
D o = table.d.newInstance();
|
||||
for (DBTableColumn column : table.columns.values()) {
|
||||
Object field_value = null;
|
||||
switch (column.type) {
|
||||
case DOUBLE:
|
||||
field_value = requireNonNullElse(resSet.getDouble(column.Name), 0);
|
||||
break;
|
||||
case UNDEFINED:
|
||||
break;
|
||||
case INT:
|
||||
field_value = requireNonNullElse(resSet.getInt(column.Name), 0);
|
||||
break;
|
||||
case LONG:
|
||||
field_value = requireNonNullElse(resSet.getLong(column.Name), 0);
|
||||
break;
|
||||
case STRING:
|
||||
if (table.d.getField(column.Name).getType().isEnum()) {
|
||||
Class enum_class = Class.forName(table.d.getField(column.Name).getType().getName());
|
||||
String string = resSet.getString(column.Name);
|
||||
Object[] enum_constants = enum_class.getEnumConstants();
|
||||
if (string != null) {
|
||||
try {
|
||||
field_value = Enum.valueOf(enum_class, string);
|
||||
} catch (Exception ignore) {
|
||||
System.out.println(Utils.Brackets(string) + "not found");
|
||||
field_value = enum_constants[0];
|
||||
System.out.println(field_value);
|
||||
}
|
||||
} else field_value = enum_constants[0];
|
||||
} else
|
||||
field_value = requireNonNullElse(resSet.getString(column.Name), "");
|
||||
break;
|
||||
}
|
||||
if (field_value != null) {
|
||||
table.d.getField(column.Name).set(o, field_value);
|
||||
} else
|
||||
throw new PassException("Ошибка при загрузке поля " + Utils.Brackets(column.Name) + " класса " + Utils.Brackets(table.d.getSimpleName()));
|
||||
}
|
||||
return new Pair<>((K) o.getPK(), o);
|
||||
}
|
||||
@Override
|
||||
protected <K, D extends DBObject> void loadAll(DBTable<K, D> table) throws Exception {
|
||||
resSet = statement.executeQuery("SELECT * FROM " + table.QName());
|
||||
while (resSet.next()) {
|
||||
Pair<K, D> record = readRecord(table);
|
||||
table.Data.put(record.getKey(), record.getValue());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void insert(DBTable table, DBObject o) throws Exception {
|
||||
PreparedStatement ps = insertStatements.get(table.d);
|
||||
if (ps == null)
|
||||
UI.Info("INSERT NULL");
|
||||
int i = 1;
|
||||
for (DBTableColumn column : table.columns.values()) {
|
||||
if (!column.AutoIncrement) {
|
||||
ps.setObject(i, o.getClass().getField(column.Name).get(o));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
ps.execute();
|
||||
//-->
|
||||
for (DBTableColumn column : table.columns.values()) {
|
||||
if (column.AutoIncrement) {
|
||||
resSet = statement.executeQuery("SELECT MAX(" + column.QName() + ") AS LAST FROM " + table.QName());
|
||||
String maxId = resSet.getString("LAST");
|
||||
int intMaxId = Integer.parseInt(maxId);
|
||||
o.getClass().getField(column.Name).set(o, intMaxId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void update(DBTable table, DBObject o) throws Exception {
|
||||
PreparedStatement ps = updateStatements.get(table.d);
|
||||
if (ps == null)
|
||||
UI.Info("UPDATE NULL");
|
||||
int i = 1;
|
||||
for (DBTableColumn column : table.columns.values()) {
|
||||
if (!column.AutoIncrement) {
|
||||
ps.setObject(i, o.getClass().getField(column.Name).get(o));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
ps.setObject(i, o.getPK());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
@Override
|
||||
protected void deleteAll(DBTable table) throws Exception {
|
||||
statement.executeUpdate("DELETE FROM " + table.QName());
|
||||
}
|
||||
@Override
|
||||
protected void resetAI(DBTable table) throws Exception {
|
||||
statement.executeUpdate("UPDATE SQLITE_SEQUENCE SET SEQ = 0 WHERE NAME =" + table.QName());
|
||||
}
|
||||
//--
|
||||
//https://stackoverflow.com/questions/8558099/sqlite-query-with-byte-where-clause
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user