Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e931e1c
Starter Commit
Absolutionism Sep 6, 2024
d9c733a
Fixing
Absolutionism Sep 7, 2024
e67b6d5
Requested Changes
Absolutionism Sep 7, 2024
5e8788f
Fix Load
Absolutionism Sep 7, 2024
2d95bf7
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Sep 9, 2024
c2da56e
Requested Changes
Absolutionism Sep 19, 2024
d434186
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Sep 19, 2024
f9237a6
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Sep 21, 2024
6e2a395
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Sep 22, 2024
5c0f5b3
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Sep 22, 2024
d6125e5
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Oct 1, 2024
9f185a6
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Oct 2, 2024
3595a0e
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Oct 6, 2024
a338dda
Javadocs update
Absolutionism Oct 12, 2024
1390dcb
Fix
Absolutionism Oct 12, 2024
7a2caf0
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Oct 13, 2024
54c6d3c
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Oct 15, 2024
2cceda1
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Oct 15, 2024
9153a65
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Oct 27, 2024
7ecad1b
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Nov 11, 2024
8592c84
Merge branch 'dev/feature' into dev/database-file-limit
Absolutionism Nov 16, 2024
7126555
Merge branch 'dev/feature' into dev/database-file-limit
Moderocky Nov 30, 2024
ebd87bc
Merge branch 'dev/feature' into dev/database-file-limit
sovdeeth Dec 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/main/java/ch/njol/skript/variables/FlatFileStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ public class FlatFileStorage extends VariablesStorage {
/**
* Create a new CSV storage of the given name.
*
* @param name the name.
* @param type the databse type i.e. CSV.
*/
FlatFileStorage(String name) {
super(name);
FlatFileStorage(String type) {
super(type);
}

/**
Expand Down Expand Up @@ -439,7 +439,7 @@ public final void saveVariables(boolean finalSave) {
pw.close();
FileUtils.move(tempFile, file, true);
} catch (IOException e) {
Skript.error("Unable to make a final save of the database '" + databaseName +
Skript.error("Unable to make a final save of the database '" + getUserConfigurationName() +
"' (no variables are lost): " + ExceptionUtils.toString(e));
// FIXME happens at random - check locks/threads
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ch/njol/skript/variables/MySQLStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@

public class MySQLStorage extends SQLStorage {

MySQLStorage(String name) {
super(name, "CREATE TABLE IF NOT EXISTS %s (" +
MySQLStorage(String type) {
super(type, "CREATE TABLE IF NOT EXISTS %s (" +
"rowid BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY," +
"name VARCHAR(" + MAX_VARIABLE_NAME_LENGTH + ") NOT NULL UNIQUE," +
"type VARCHAR(" + MAX_CLASS_CODENAME_LENGTH + ")," +
Expand Down
44 changes: 22 additions & 22 deletions src/main/java/ch/njol/skript/variables/SQLStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ public abstract class SQLStorage extends VariablesStorage {
/**
* Creates a SQLStorage with a create table query.
*
* @param name The name to be sent through this constructor when newInstance creates this class.
* @param type The database type i.e. CSV.
* @param createTableQuery The create table query to send to the SQL engine.
*/
public SQLStorage(String name, String createTableQuery) {
super(name);
public SQLStorage(String type, String createTableQuery) {
super(type);
this.createTableQuery = createTableQuery;
this.tableName = "variables21";
}
Expand Down Expand Up @@ -160,14 +160,14 @@ protected boolean load_i(SectionNode n) {
final boolean hadNewTable = db.isTable(getTableName());

if (getFormattedCreateQuery() == null){
Skript.error("Could not create the variables table in the database. The query to create the variables table '" + tableName + "' in the database '" + databaseName + "' is null.");
Skript.error("Could not create the variables table in the database. The query to create the variables table '" + tableName + "' in the database '" + getUserConfigurationName() + "' is null.");
return false;
}

try {
db.query(getFormattedCreateQuery());
} catch (final SQLException e) {
Skript.error("Could not create the variables table '" + tableName + "' in the database '" + databaseName + "': " + e.getLocalizedMessage() + ". "
Skript.error("Could not create the variables table '" + tableName + "' in the database '" + getUserConfigurationName() + "': " + e.getLocalizedMessage() + ". "
+ "Please create the table yourself using the following query: " + String.format(createTableQuery, tableName).replace(",", ", ").replaceAll("\\s+", " "));
return false;
}
Expand Down Expand Up @@ -200,7 +200,7 @@ protected boolean load_i(SectionNode n) {
// store old variables in new table and delete the old table
if (hasOldTable) {
if (!hadNewTable) {
Skript.info("[2.1] Updating the database '" + databaseName + "' to the new format...");
Skript.info("[2.1] Updating the database '" + getUserConfigurationName() + "' to the new format...");
try {
Variables.getReadLock().lock();
for (final Entry<String, Object> v : Variables.getVariablesHashMap().entrySet()) {
Expand All @@ -221,7 +221,7 @@ protected boolean load_i(SectionNode n) {
final ResultSet r = db.query("SELECT * FROM " + OLD_TABLE_NAME + " LIMIT 1");
try {
if (r.next()) {// i.e. the old table is not empty
Skript.error("Could not successfully convert & transfer all variables to the new table in the database '" + databaseName + "'. "
Skript.error("Could not successfully convert & transfer all variables to the new table in the database '" + getUserConfigurationName() + "'. "
+ "Variables that could not be transferred are left in the old table and Skript will reattempt to transfer them whenever it starts until the old table is empty or is manually deleted. "
+ "Please note that variables recreated by scripts will count as converted and will be removed from the old table on the next restart.");
} else {
Expand All @@ -231,13 +231,13 @@ protected boolean load_i(SectionNode n) {
connect();
db.query("DROP TABLE " + OLD_TABLE_NAME);
} catch (final SQLException e) {
Skript.error("There was an error deleting the old variables table from the database '" + databaseName + "', please delete it yourself: " + e.getLocalizedMessage());
Skript.error("There was an error deleting the old variables table from the database '" + getUserConfigurationName() + "', please delete it yourself: " + e.getLocalizedMessage());
error = true;
}
if (!error)
Skript.info("Successfully deleted the old variables table from the database '" + databaseName + "'.");
Skript.info("Successfully deleted the old variables table from the database '" + getUserConfigurationName() + "'.");
if (!hadNewTable)
Skript.info("Database '" + databaseName + "' successfully updated.");
Skript.info("Database '" + getUserConfigurationName() + "' successfully updated.");
}
} finally {
r.close();
Expand Down Expand Up @@ -265,15 +265,15 @@ public void run() {
} catch (final InterruptedException e) {}
}
}
}, "Skript database '" + databaseName + "' connection keep-alive thread").start();
}, "Skript database '" + getUserConfigurationName() + "' connection keep-alive thread").start();

return true;
}
}

@Override
protected void allLoaded() {
Skript.debug("Database " + databaseName + " loaded. Queue size = " + changesQueue.size());
Skript.debug("Database " + getUserConfigurationName() + " loaded. Queue size = " + changesQueue.size());

// start committing thread. Its first execution will also commit the first batch of changed variables.
Skript.newThread(new Runnable() {
Expand All @@ -296,7 +296,7 @@ public void run() {
} catch (final InterruptedException e) {}
}
}
}, "Skript database '" + databaseName + "' transaction committing thread").start();
}, "Skript database '" + getUserConfigurationName() + "' transaction committing thread").start();

if (monitor) {
Skript.newThread(new Runnable() {
Expand Down Expand Up @@ -327,7 +327,7 @@ public void run() {
}
}
}
}, "Skript database '" + databaseName + "' monitor thread").start();
}, "Skript database '" + getUserConfigurationName() + "' monitor thread").start();
}

}
Expand All @@ -352,9 +352,9 @@ private final boolean connect(final boolean first) {
final Database db = this.db.get();
if (db == null || !db.open()) {
if (first)
Skript.error("Cannot connect to the database '" + databaseName + "'! Please make sure that all settings are correct");// + (type == Type.MYSQL ? " and that the database software is running" : "") + ".");
Skript.error("Cannot connect to the database '" + getUserConfigurationName() + "'! Please make sure that all settings are correct");// + (type == Type.MYSQL ? " and that the database software is running" : "") + ".");
else
Skript.exception("Cannot reconnect to the database '" + databaseName + "'!");
Skript.exception("Cannot reconnect to the database '" + getUserConfigurationName() + "'!");
return false;
}
try {
Expand Down Expand Up @@ -400,7 +400,7 @@ private boolean prepareQueries() {
} catch (final SQLException e) {}
monitorCleanUpQuery = db.prepare("DELETE FROM " + getTableName() + " WHERE value IS NULL AND rowid < ?");
} catch (final SQLException e) {
Skript.exception(e, "Could not prepare queries for the database '" + databaseName + "': " + e.getLocalizedMessage());
Skript.exception(e, "Could not prepare queries for the database '" + getUserConfigurationName() + "': " + e.getLocalizedMessage());
return false;
}
}
Expand Down Expand Up @@ -577,7 +577,7 @@ public SQLException call() throws Exception {
int i = 1;
final String name = r.getString(i++);
if (name == null) {
Skript.error("Variable with NULL name found in the database '" + databaseName + "', ignoring it");
Skript.error("Variable with NULL name found in the database '" + getUserConfigurationName() + "', ignoring it");
continue;
}
final String type = r.getString(i++);
Expand All @@ -590,15 +590,15 @@ public SQLException call() throws Exception {
@SuppressWarnings("unused")
Serializer<?> s;
if (c == null || (s = c.getSerializer()) == null) {
Skript.error("Cannot load the variable {" + name + "} from the database '" + databaseName + "', because the type '" + type + "' cannot be recognised or cannot be stored in variables");
Skript.error("Cannot load the variable {" + name + "} from the database '" + getUserConfigurationName() + "', because the type '" + type + "' cannot be recognised or cannot be stored in variables");
continue;
}
// if (s.mustSyncDeserialization()) {
// syncDeserializing.add(new VariableInfo(name, value, c));
// } else {
final Object d = Classes.deserialize(c, value);
if (d == null) {
Skript.error("Cannot load the variable {" + name + "} from the database '" + databaseName + "', because it cannot be loaded as " + c.getName().withIndefiniteArticle());
Skript.error("Cannot load the variable {" + name + "} from the database '" + getUserConfigurationName() + "', because it cannot be loaded as " + c.getName().withIndefiniteArticle());
continue;
}
Variables.variableLoaded(name, d, SQLStorage.this);
Expand All @@ -623,7 +623,7 @@ public SQLException call() throws Exception {
// for (final VariableInfo o : syncDeserializing) {
// final Object d = Classes.deserialize(o.ci, o.value);
// if (d == null) {
// Skript.error("Cannot load the variable {" + o.name + "} from the database " + databaseName + ", because it cannot be loaded as a " + o.ci.getName());
// Skript.error("Cannot load the variable {" + o.name + "} from the database " + getUserConfigurationName() + ", because it cannot be loaded as a " + o.ci.getName());
// continue;
// }
// Variables.variableLoaded(o.name, d, DatabaseStorage.this);
Expand Down Expand Up @@ -655,7 +655,7 @@ public SQLException call() throws Exception {
private void oldLoadVariables(final ResultSet r, final boolean hadNewTable) throws SQLException {
// synchronized (oldSyncDeserializing) {

final VariablesStorage temp = new VariablesStorage(databaseName + " old variables table") {
final VariablesStorage temp = new VariablesStorage(getUserConfigurationName() + " old variables table") {
@Override
protected boolean save(final String name, @Nullable final String type, @Nullable final byte[] value) {
assert type == null : name + "; " + type;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/ch/njol/skript/variables/SQLiteStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@

public class SQLiteStorage extends SQLStorage {

SQLiteStorage(String name) {
super(name, "CREATE TABLE IF NOT EXISTS %s (" +
SQLiteStorage(String type) {
super(type, "CREATE TABLE IF NOT EXISTS %s (" +
"name VARCHAR(" + MAX_VARIABLE_NAME_LENGTH + ") NOT NULL PRIMARY KEY," +
"type VARCHAR(" + MAX_CLASS_CODENAME_LENGTH + ")," +
"value BLOB(" + MAX_VALUE_SIZE + ")," +
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/ch/njol/skript/variables/Variables.java
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public static boolean load() {
constructor.setAccessible(true);
variablesStorage = (VariablesStorage) constructor.newInstance(type);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
Skript.error("Failed to initalize database type '" + type + "'");
Skript.error("Failed to initialize database `" + name + "`");
successful = false;
continue;
}
Expand Down Expand Up @@ -745,8 +745,8 @@ static boolean variableLoaded(String name, @Nullable Object value, VariablesStor
// Warn if needed
if (loadConflicts <= MAX_CONFLICT_WARNINGS) {
Skript.warning("The variable {" + name + "} was loaded twice from different databases (" +
existingVariableStorage.databaseName + " and " + source.databaseName +
"), only the one from " + source.databaseName + " will be kept.");
existingVariableStorage.getUserConfigurationName() + " and " + source.getUserConfigurationName() +
"), only the one from " + source.getUserConfigurationName() + " will be kept.");
} else if (loadConflicts == MAX_CONFLICT_WARNINGS + 1) {
Skript.warning("[!] More than " + MAX_CONFLICT_WARNINGS +
" variables were loaded more than once from different databases, " +
Expand Down
54 changes: 47 additions & 7 deletions src/main/java/ch/njol/skript/variables/VariablesStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
Expand Down Expand Up @@ -68,9 +71,14 @@ public abstract class VariablesStorage implements Closeable {
protected volatile boolean closed = false;

/**
* The name of the database, i.e. this storage.
* The name of the database
*/
protected final String databaseName;
private String databaseName;

/**
* The type of the database, i.e. CSV.
*/
private final String databaseType;

/**
* The file associated with this variable storage.
Expand Down Expand Up @@ -98,11 +106,11 @@ public abstract class VariablesStorage implements Closeable {
* This will also create the {@link #writeThread}, but it must be started
* with {@link #load(SectionNode)}.
*
* @param name the name.
* @param type the database type i.e. CSV.
*/
protected VariablesStorage(String name) {
assert name != null;
databaseName = name;
protected VariablesStorage(String type) {
assert type != null;
databaseType = type;

writeThread = Skript.newThread(() -> {
while (!closed) {
Expand All @@ -120,7 +128,29 @@ protected VariablesStorage(String name) {
// Ignored as the `closed` field will indicate whether the thread actually needs to stop
}
}
}, "Skript variable save thread for database '" + name + "'");
}, "Skript variable save thread for database '" + type + "'");
}

/**
* Get the config name of a database
* <p>
* Note: Returns the user set name for the database, ex:
* <pre>{@code
* default: <- Config Name
* type: CSV
* }</pre>
* @return name of database
*/
protected final String getUserConfigurationName() {
return databaseName;
}

/**
* Get the config type of a database
* @return type of databse
*/
protected final String getDatabaseType() {
return databaseType;
}

/**
Expand Down Expand Up @@ -170,6 +200,8 @@ protected <T> T getValue(SectionNode sectionNode, String key, Class<T> type) {
}
}

private static final Set<File> registeredFiles = new HashSet<>();

/**
* Loads the configuration for this variable storage
* from the given section node.
Expand All @@ -178,6 +210,8 @@ protected <T> T getValue(SectionNode sectionNode, String key, Class<T> type) {
* @return whether the loading succeeded.
*/
public final boolean load(SectionNode sectionNode) {
databaseName = sectionNode.getKey();

String pattern = getValue(sectionNode, "pattern");
if (pattern == null)
return false;
Expand Down Expand Up @@ -222,6 +256,12 @@ public final boolean load(SectionNode sectionNode) {
return false;
}

if (registeredFiles.contains(file)) {
Skript.error("Database `" + databaseName + "` failed to load. The file `" + fileName + "` is already registered to another database.");
return false;
}
registeredFiles.add(file);

// Set the backup interval, if present & enabled
if (!"0".equals(getValue(sectionNode, "backup interval"))) {
Timespan backupInterval = getValue(sectionNode, "backup interval", Timespan.class);
Expand Down