Skip to content

Commit 9ea7cbd

Browse files
committed
more database improvements
1 parent 6211385 commit 9ea7cbd

10 files changed

Lines changed: 309 additions & 49 deletions

File tree

Database/src/main/java/org/broken/arrow/database/library/Database.java

Lines changed: 125 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package org.broken.arrow.database.library;
22

33
import org.broken.arrow.database.library.builders.DataWrapper;
4+
import org.broken.arrow.database.library.builders.LoadDataWrapper;
45
import org.broken.arrow.database.library.builders.TableWrapper;
56
import org.broken.arrow.database.library.builders.tables.TableRow;
67
import org.broken.arrow.database.library.log.LogMsg;
78
import org.broken.arrow.database.library.log.Validate;
89
import org.broken.arrow.database.library.utility.serialize.ConfigurationSerializeUtility;
10+
import org.broken.arrow.database.library.utility.serialize.DeSerialize;
911

1012
import javax.annotation.Nonnull;
1113
import javax.annotation.Nullable;
@@ -30,6 +32,7 @@
3032
public abstract class Database {
3133

3234
protected Connection connection;
35+
private DeSerialize deSerialize = new DeSerialize();
3336
protected boolean batchUpdateGoingOn = false;
3437
private final Map<String, TableWrapper> tables = new HashMap<>();
3538
protected boolean hasStartWriteToDb = false;
@@ -42,13 +45,17 @@ public Database() {
4245

4346
public abstract Connection connect();
4447

48+
protected abstract void batchUpdate(@Nonnull final List<String> batchList, @Nonnull final TableWrapper... tableWrappers);
49+
50+
protected abstract void remove(@Nonnull final List<String> batchList, @Nonnull final TableWrapper tableWrappers);
51+
52+
protected abstract void dropTable(@Nonnull final List<String> batchList, @Nonnull final TableWrapper tableWrappers);
53+
4554
public void createTables() {
4655
Validate.checkBoolean(tables.isEmpty(), "The table is empty, add tables to the map before call this method");
4756
try {
4857
openConnection();
49-
for (final Entry<String, TableWrapper> entitytables : tables.entrySet()) {
50-
load(entitytables);
51-
}
58+
createAllTables();
5259
try {
5360
for (final Entry<String, TableWrapper> entityTables : tables.entrySet()) {
5461
final List<String> columns = updateTableColumnsInDb(entityTables.getKey());
@@ -109,7 +116,7 @@ public void saveAll(@Nonnull final Map<String, DataWrapper> utilityMap) {
109116
}
110117
this.getSqlsCommands(sqls, tableWrapper);
111118
}
112-
this.batchUpdate(sqls);
119+
this.batchUpdate(sqls, this.getTables().values().toArray(new TableWrapper[0]));
113120
}
114121

115122
/**
@@ -142,10 +149,83 @@ public void save(@Nonnull final String tableName, @Nonnull final String primaryK
142149
tableWrapper.addCustom(entry.getKey(), column.getBuilder().setColumnValue(entry.getValue()));
143150
}
144151
this.getSqlsCommands(sqls, tableWrapper);
145-
this.batchUpdate(sqls);
152+
this.batchUpdate(sqls, tableWrapper);
153+
}
154+
155+
/**
156+
* Load one row from specified database table.
157+
*
158+
* @param tableName name of the table you want to get data from.
159+
* @param clazz the class you have your static deserialize method.
160+
* @return one row you have in the table.
161+
*/
162+
@Nullable
163+
public <T extends ConfigurationSerializeUtility> LoadDataWrapper<T> load(@Nonnull final String tableName, @Nonnull final Class<T> clazz) {
164+
TableWrapper tableWrapper = this.getTable(tableName);
165+
if (tableWrapper == null) {
166+
LogMsg.warn("Could not find table " + tableName);
167+
return null;
168+
}
169+
Validate.checkNotNull(tableWrapper.getPrimaryRow(), "Colud not find primary column for table " + tableName);
170+
String primaryColumn = tableWrapper.getPrimaryRow().getColumnName();
171+
Map<String, Object> dataFromDB = new HashMap<>();
172+
TableRow column = tableWrapper.getColumn(primaryColumn);
173+
Validate.checkNotNull(column, "Colud not find column for " + primaryColumn);
174+
175+
final String sql = "SELECT * FROM `" + tableWrapper.getTableName() + "` WHERE `" + primaryColumn + "` = '" + column.getColumnValue() + "'";
176+
PreparedStatement preparedStatement = null;
177+
ResultSet resultSet = null;
178+
try {
179+
preparedStatement = this.connection.prepareStatement(sql);
180+
resultSet = preparedStatement.executeQuery();
181+
dataFromDB.putAll(this.getDataFromDB(resultSet));
182+
183+
} catch (SQLException e) {
184+
e.printStackTrace();
185+
} finally {
186+
this.close(preparedStatement, resultSet);
187+
}
188+
T deserialize = this.deSerialize.invokeDeSerializeMethod(clazz, "deserialize", dataFromDB);
189+
return new LoadDataWrapper<>(tableWrapper.getPrimaryRow().getColumnName(), dataFromDB, deserialize);
190+
}
191+
192+
/**
193+
* Load all rows from specified database table.
194+
*
195+
* @param tableName name of the table you want to get data from.
196+
* @param clazz the class you have your static deserialize method.
197+
* @return list of all data you have in the table.
198+
*/
199+
public <T extends ConfigurationSerializeUtility> List<LoadDataWrapper<T>> loadAll(@Nonnull final String tableName, @Nonnull final Class<T> clazz) {
200+
final List<LoadDataWrapper<T>> loadDataWrappers = new ArrayList<>();
201+
PreparedStatement preparedStatement = null;
202+
ResultSet resultSet = null;
203+
204+
TableWrapper tableWrapper = this.getTable(tableName);
205+
if (tableWrapper == null) {
206+
LogMsg.warn("Could not find table " + tableName);
207+
return null;
208+
}
209+
try {
210+
final String sql = "SELECT * FROM `" + tableWrapper.getTableName() + "`";
211+
212+
preparedStatement = connection.prepareStatement(sql);
213+
resultSet = preparedStatement.executeQuery();
214+
while (resultSet.next()) {
215+
Map<String, Object> dataFromDB = this.getDataFromDB(resultSet);
216+
T deserialize = this.deSerialize.invokeDeSerializeMethod(clazz, "deserialize", dataFromDB);
217+
loadDataWrappers.add(new LoadDataWrapper<>(tableWrapper.getPrimaryRow().getColumnName(), dataFromDB, deserialize));
218+
}
219+
220+
} catch (SQLException e) {
221+
e.printStackTrace();
222+
} finally {
223+
this.close(preparedStatement, resultSet);
224+
}
225+
return loadDataWrappers;
146226
}
147227

148-
public boolean load(final String tableName) {
228+
public boolean createTable(final String tableName) {
149229
if (!openConnection()) return false;
150230

151231
try {
@@ -157,42 +237,53 @@ public boolean load(final String tableName) {
157237
final PreparedStatement statement = this.connection.prepareStatement(wrapperEntry.createTable());
158238
statement.executeUpdate();
159239
close(statement);
240+
TableRow wraper = wrapperEntry.getColumns().values().stream().findFirst().orElse(null);
241+
Validate.checkNotNull(wraper, "Could not find a column for this table " + tableName);
242+
checkIfTableExist(tableName, wraper.getColumnName());
160243
return true;
161244
} catch (final SQLException e) {
162245
e.printStackTrace();
163246
}
164247
return true;
165248
}
166249

167-
private void load(final Entry<String, TableWrapper> wrapperEntry) {
168-
if (!openConnection()) return;
169-
170-
try {
171-
final PreparedStatement statement = this.connection.prepareStatement(wrapperEntry.getValue().createTable());
172-
statement.executeUpdate();
173-
close(statement);
174-
} catch (final SQLException e) {
175-
e.printStackTrace();
250+
public void createAllTables() {
251+
for (final Entry<String, TableWrapper> wrapperEntry : tables.entrySet()) {
252+
try {
253+
final PreparedStatement statement = this.connection.prepareStatement(wrapperEntry.getValue().createTable());
254+
statement.executeUpdate();
255+
close(statement);
256+
} catch (final SQLException e) {
257+
e.printStackTrace();
258+
}
259+
TableRow wraper = wrapperEntry.getValue().getColumns().values().stream().findFirst().orElse(null);
260+
Validate.checkNotNull(wraper, "Could not find a column for this table " + wrapperEntry.getKey());
261+
checkIfTableExist(wrapperEntry.getKey(), wraper.getColumnName());
176262
}
177-
TableRow wraper = wrapperEntry.getValue().getColumns().values().stream().findFirst().orElse(null);
178-
Validate.checkNotNull(wraper, "Could not find a column for this table " + wrapperEntry.getKey());
179-
checkIfTableExist(wrapperEntry.getKey(), wraper.getColumnName());
180263
}
181264

182265
public void remove(final String tableName, final String columnName, final String value) {
266+
TableWrapper tableWrapper = this.getTable(tableName);
267+
if (tableWrapper == null) {
268+
LogMsg.warn("Could not find table " + tableName);
269+
return;
270+
}
183271
final String sql = "DELETE FROM `" + tableName + "` WHERE `" + columnName + "` = `" + value + "`";
184-
this.batchUpdate(Collections.singletonList(sql));
272+
this.remove(Collections.singletonList(sql), tableWrapper);
185273
}
186274

187275
public void dropTable(final String tableName) {
276+
TableWrapper tableWrapper = this.getTable(tableName);
277+
if (tableWrapper == null) {
278+
LogMsg.warn("Could not find table " + tableName);
279+
return;
280+
}
188281
final String sql = "DROP TABLE `" + tableName + "`";
189-
this.batchUpdate(Collections.singletonList(sql));
282+
this.dropTable(Collections.singletonList(sql), tableWrapper);
190283
}
191284

192-
protected abstract void batchUpdate(@Nonnull final List<String> batchupdate);
193-
194-
protected void batchUpdate(@Nonnull final List<String> batchupdate, int resultSetType, int resultSetConcurrency) {
195-
final ArrayList<String> sqls = new ArrayList<>(batchupdate);
285+
protected void batchUpdate(@Nonnull final List<String> batchList, int resultSetType, int resultSetConcurrency) {
286+
final ArrayList<String> sqls = new ArrayList<>(batchList);
196287
if (!openConnection()) return;
197288

198289
if (sqls.size() == 0)
@@ -415,6 +506,16 @@ protected void closeConnection() {
415506
}
416507
}
417508

509+
public Map<String, Object> getDataFromDB(final ResultSet resultSet) throws SQLException {
510+
final ResultSetMetaData rsmd = resultSet.getMetaData();
511+
final int columnCount = rsmd.getColumnCount();
512+
final Map<String, Object> objectMap = new HashMap<>();
513+
for (int i = 1; i <= columnCount; i++) {
514+
objectMap.put(rsmd.getColumnName(i), resultSet.getObject(i));
515+
}
516+
return objectMap;
517+
}
518+
418519
public abstract boolean isHasCastExeption();
419520

420521
}

Database/src/main/java/org/broken/arrow/database/library/MySQL.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.broken.arrow.database.library;
22

33
import org.broken.arrow.database.library.builders.MysqlPreferences;
4+
import org.broken.arrow.database.library.builders.TableWrapper;
45
import org.broken.arrow.database.library.log.LogMsg;
56
import org.broken.arrow.database.library.log.Validate;
67

@@ -16,7 +17,7 @@
1617
public class MySQL extends Database {
1718

1819
private final MysqlPreferences mysqlPreference;
19-
private final String driverConnection;
20+
private final String startSQLUrl;
2021
private final String driver;
2122
private boolean hasCastExeption = false;
2223
private final boolean isHikariAvailable;
@@ -29,7 +30,7 @@ public MySQL(@Nonnull MysqlPreferences mysqlPreference) {
2930
public MySQL(@Nonnull MysqlPreferences mysqlPreference, String hikariClazz) {
3031
this.mysqlPreference = mysqlPreference;
3132
this.isHikariAvailable = isHikariAvailable(hikariClazz);
32-
this.driverConnection = "jdbc:mysql://";
33+
this.startSQLUrl = "jdbc:mysql://";
3334
this.driver = "com.mysql.cj.jdbc.Driver";
3435
createMissingDatabase();
3536
connect();
@@ -56,8 +57,18 @@ public Connection connect() {
5657
}
5758

5859
@Override
59-
protected void batchUpdate(@Nonnull final List<String> batchupdate) {
60-
this.batchUpdate(batchupdate, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
60+
protected void batchUpdate(@Nonnull final List<String> batchList, @Nonnull final TableWrapper... tableWrappers) {
61+
this.batchUpdate(batchList, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
62+
}
63+
64+
@Override
65+
protected void remove(@Nonnull final List<String> batchList, @Nonnull final TableWrapper tableWrappers) {
66+
this.batchUpdate(batchList, tableWrappers);
67+
}
68+
69+
@Override
70+
protected void dropTable(@Nonnull final List<String> batchList, @Nonnull final TableWrapper tableWrappers) {
71+
this.batchUpdate(batchList, tableWrappers);
6172
}
6273

6374
public Connection setupConection() throws SQLException {
@@ -70,9 +81,9 @@ public Connection setupConection() throws SQLException {
7081
if (isHikariAvailable) {
7182
if (this.hikari == null)
7283
this.hikari = new HikariCP(this.mysqlPreference, this.driver);
73-
connection = this.hikari.getConection(driverConnection);
84+
connection = this.hikari.getConection(startSQLUrl);
7485
} else {
75-
connection = DriverManager.getConnection(driverConnection + hostAdress + ":" + port + "/" + databaseName + "?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&autoReconnect=" + true, user, password);
86+
connection = DriverManager.getConnection(startSQLUrl + hostAdress + ":" + port + "/" + databaseName + "?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&autoReconnect=" + true, user, password);
7687
}
7788
return connection;
7889
}
@@ -85,7 +96,7 @@ public void createMissingDatabase() {
8596
String password = mysqlPreference.getPassword();
8697

8798
try {
88-
Connection createDatabase = DriverManager.getConnection(driverConnection + hostAdress + ":" + port + "/?useSSL=false&useUnicode=yes&characterEncoding=UTF-8", user, password);
99+
Connection createDatabase = DriverManager.getConnection(startSQLUrl + hostAdress + ":" + port + "/?useSSL=false&useUnicode=yes&characterEncoding=UTF-8", user, password);
89100

90101
PreparedStatement createdatabase = createDatabase.prepareStatement("CREATE DATABASE IF NOT EXISTS " + databaseName);
91102
createdatabase.execute();

Database/src/main/java/org/broken/arrow/database/library/SQLite.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.broken.arrow.database.library;
22

3+
import org.broken.arrow.database.library.builders.TableWrapper;
34
import org.broken.arrow.database.library.log.LogMsg;
45

56
import javax.annotation.Nonnull;
@@ -51,8 +52,8 @@ public Connection connect() {
5152
}
5253

5354
@Override
54-
protected void batchUpdate(@Nonnull final List<String> batchupdate) {
55-
this.batchUpdate(batchupdate, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
55+
protected void batchUpdate(@Nonnull final List<String> batchList, @Nonnull final TableWrapper... tableWrappers) {
56+
this.batchUpdate(batchList, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
5657
}
5758

5859

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.broken.arrow.database.library.builders;
2+
3+
import javax.annotation.Nonnull;
4+
import javax.annotation.Nullable;
5+
import java.util.Map;
6+
7+
public class LoadDataWrapper<T> {
8+
9+
private final T deSerializedData;
10+
private final Object primaryValue;
11+
12+
public LoadDataWrapper(@Nonnull final String primaryColumn, @Nonnull final Map<String, Object> data, @Nonnull final T deSerializedData) {
13+
this.deSerializedData = deSerializedData;
14+
this.primaryValue = data.get(primaryColumn);
15+
}
16+
17+
@Nonnull
18+
public T getDeSerializedData() {
19+
return deSerializedData;
20+
}
21+
22+
@Nullable
23+
public Object getPrimaryValue() {
24+
return primaryValue;
25+
}
26+
27+
}

Database/src/main/java/org/broken/arrow/database/library/builders/TableWrapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ public TableWrapper setPrimaryRow(@Nonnull final TableRow primaryRow) {
138138
return this;
139139
}
140140

141+
@Nullable
141142
public TableRow getPrimaryRow() {
142143
return primaryRow;
143144
}

Database/src/main/java/org/broken/arrow/database/library/builders/tables/TableRow.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.broken.arrow.database.library.builders.tables;
22

3+
import javax.annotation.Nonnull;
4+
35
public final class TableRow {
46

57
private final String columnName;
@@ -63,7 +65,7 @@ public static class Builder {
6365
private boolean autoIncrement;
6466
private boolean notNull;
6567

66-
public Builder(final String columnName, final String datatype) {
68+
public Builder(@Nonnull final String columnName, @Nonnull final String datatype) {
6769
this.columnName = columnName;
6870
this.datatype = datatype;
6971
}

0 commit comments

Comments
 (0)