master
坏黑 2018-12-08 13:57:19 +08:00
parent 881cb2c4a9
commit 11140c0bd0
19 changed files with 451 additions and 138 deletions

View File

@ -6,7 +6,7 @@
<groupId>me.skymc</groupId>
<artifactId>TabooLib</artifactId>
<version>4.65</version>
<version>4.67</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@ -91,8 +91,6 @@ public class Main extends JavaPlugin {
TabooLibLoader.setup();
// 载入大饼
TLib.initPost();
// 载入连接池
HikariHandler.init();
}
@Override

View File

@ -109,7 +109,13 @@ public class TabooLibLoader implements Listener {
public static void runTaskOnEnabled(Runnable runnable) {
if (Main.isStarted()) {
runnable.run();
Bukkit.getScheduler().runTask(TabooLib.instance(), () -> {
try {
runnable.run();
} catch (Throwable t) {
t.printStackTrace();
}
});
} else {
tasks.add(runnable);
}
@ -212,6 +218,7 @@ public class TabooLibLoader implements Listener {
} catch (Exception e) {
e.printStackTrace();
}
loaders.sort(Comparator.comparingInt(Loader::priority));
});
}
@ -274,6 +281,10 @@ public class TabooLibLoader implements Listener {
default void unload(Plugin plugin, Class<?> cancelClass) {
}
default int priority() {
return 0;
}
}
@Target(ElementType.TYPE)

View File

@ -77,6 +77,11 @@ public class TInjectLoader implements TabooLibLoader.Loader {
});
}
@Override
public int priority() {
return -999;
}
@Override
public void preLoad(Plugin plugin, Class<?> pluginClass) {
for (Field declaredField : pluginClass.getDeclaredFields()) {

View File

@ -100,5 +100,7 @@ public class ListenerPlugin implements Listener {
TLocale.Logger.error("MYSQL-CONNECTION.FAIL-EXECUTE-TASK");
runnable.run();
}
// 注销异常拦截
e.getPlugin().getLogger().setFilter(null);
}
}

View File

@ -0,0 +1,11 @@
package me.skymc.taboolib.mysql;
/**
* @Author
* @Since 2018-12-08 13:46
*/
public abstract class IColumn {
abstract public String convertToCommand();
}

View File

@ -0,0 +1,42 @@
package me.skymc.taboolib.mysql;
import org.bukkit.plugin.Plugin;
/**
* @Author sky
* @Since 2018-05-14 19:07
*/
public abstract class IHost {
private Plugin plugin;
private boolean autoClose;
public IHost(Plugin plugin) {
this.plugin = plugin;
}
public IHost(Plugin plugin, boolean autoClose) {
this.plugin = plugin;
this.autoClose = autoClose;
}
public Plugin getPlugin() {
return plugin;
}
public void setPlugin(Plugin plugin) {
this.plugin = plugin;
}
public boolean isAutoClose() {
return autoClose;
}
public void setAutoClose(boolean autoClose) {
this.autoClose = autoClose;
}
abstract public String getConnectionUrl();
abstract public String getConnectionUrlSimple();
}

View File

@ -1,6 +1,7 @@
package me.skymc.taboolib.mysql.builder;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.mysql.IColumn;
import java.util.Arrays;
@ -8,7 +9,7 @@ import java.util.Arrays;
* @Author sky
* @Since 2018-05-14 19:09
*/
public class SQLColumn {
public class SQLColumn extends IColumn {
public static final SQLColumn PRIMARY_KEY_ID = new SQLColumn(SQLColumnType.INT, "id", SQLColumnOption.NOTNULL, SQLColumnOption.PRIMARY_KEY, SQLColumnOption.AUTO_INCREMENT);
@ -94,6 +95,7 @@ public class SQLColumn {
return this;
}
@Override
public String convertToCommand() {
if (this.m == 0 && this.d == 0) {
return Strings.replaceWithOrder("`{0}` {1}{2}", columnName, columnType.name().toLowerCase(), convertToOptions());
@ -106,23 +108,7 @@ public class SQLColumn {
private String convertToOptions() {
StringBuilder builder = new StringBuilder();
for (SQLColumnOption options : columnOptions) {
switch (options) {
case NOTNULL:
builder.append(" NOT NULL");
break;
case PRIMARY_KEY:
builder.append(" PRIMARY KEY");
break;
case AUTO_INCREMENT:
builder.append(" AUTO_INCREMENT");
break;
case UNIQUE_KEY:
builder.append(" UNIQUE KEY");
break;
default:
}
}
Arrays.stream(columnOptions).forEach(option -> builder.append(" ").append(option));
if (defaultValue != null) {
if (defaultValue instanceof String) {
builder.append(" DEFAULT '").append(defaultValue).append("'");
@ -135,6 +121,13 @@ public class SQLColumn {
@Override
public String toString() {
return "columnType=" + "SQLColumn{" + columnType + ", m=" + m + ", d=" + d + ", columnName='" + columnName + '\'' + ", defaultValue=" + defaultValue + ", columnOptions=" + Arrays.toString(columnOptions) + '}';
return "SQLColumn{" +
"columnType=" + columnType +
", m=" + m +
", d=" + d +
", columnName='" + columnName + '\'' +
", defaultValue=" + defaultValue +
", columnOptions=" + Arrays.toString(columnOptions) +
'}';
}
}

View File

@ -9,21 +9,30 @@ public enum SQLColumnOption {
/**
*
*/
NOTNULL,
NOTNULL("NOT NULL"),
/**
*
*/
UNIQUE_KEY,
UNIQUE_KEY("UNIQUE KEY"),
/**
*
*/
PRIMARY_KEY,
PRIMARY_KEY("PRIMARY KEY"),
/**
*
*/
AUTO_INCREMENT
AUTO_INCREMENT("AUTO_INCREMENT");
String text;
SQLColumnOption(String text) {
this.text = text;
}
public String getText() {
return text;
}
}

View File

@ -1,6 +1,7 @@
package me.skymc.taboolib.mysql.builder;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.mysql.IHost;
import me.skymc.taboolib.string.ArrayUtils;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
@ -13,15 +14,13 @@ import java.util.stream.Collectors;
* @Author sky
* @Since 2018-05-14 19:01
*/
public class SQLHost {
public class SQLHost extends IHost {
private String host;
private String user;
private String port;
private String password;
private String database;
private Plugin plugin;
private boolean autoClose;
private List<String> flags = ArrayUtils.asList("characterEncoding=utf-8", "useSSL=false");
public SQLHost(ConfigurationSection section, Plugin plugin) {
@ -32,18 +31,32 @@ public class SQLHost {
this(section.getString("host", "localhost"), section.getString("user", "root"), section.getString("port", "3306"), section.getString("password", ""), section.getString("database", "test"), plugin);
}
public SQLHost(String host, int port, String user, String password, String database, Plugin plugin) {
this(host, user, String.valueOf(port), password, database, plugin, false);
}
@Deprecated
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin) {
this(host, user, port, password, database, plugin, false);
}
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin, boolean autoClose) {
super(plugin, autoClose);
this.host = host;
this.user = user;
this.port = port;
this.password = password;
this.database = database;
this.plugin = plugin;
this.autoClose = false;
}
@Override
public String getConnectionUrl() {
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}" + getFlagsInUrl(), this.host, this.port, this.database);
}
@Override
public String getConnectionUrlSimple() {
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}", this.host, this.port, this.database);
}
public String getHost() {
@ -66,26 +79,10 @@ public class SQLHost {
return database;
}
public Plugin getPlugin() {
return plugin;
}
public boolean isAutoClose() {
return autoClose;
}
public List<String> getFlags() {
return flags;
}
public String getConnectionUrl() {
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}" + getFlagsInUrl(), this.host, this.port, this.database);
}
public String getConnectionUrlSimple() {
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}", this.host, this.port, this.database);
}
public String getFlagsInUrl() {
if (flags.isEmpty()) {
return "";
@ -103,18 +100,17 @@ public class SQLHost {
return false;
}
SQLHost sqlHost = (SQLHost) o;
return autoClose == sqlHost.autoClose &&
Objects.equals(getHost(), sqlHost.getHost()) &&
return Objects.equals(getHost(), sqlHost.getHost()) &&
Objects.equals(getUser(), sqlHost.getUser()) &&
Objects.equals(getPort(), sqlHost.getPort()) &&
Objects.equals(getPassword(), sqlHost.getPassword()) &&
Objects.equals(getDatabase(), sqlHost.getDatabase()) &&
Objects.equals(getPlugin(), sqlHost.getPlugin());
Objects.equals(getFlags(), sqlHost.getFlags());
}
@Override
public int hashCode() {
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase(), getPlugin(), autoClose);
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase(), getFlags());
}
@Override
@ -125,8 +121,7 @@ public class SQLHost {
", port='" + port + '\'' +
", password='" + password + '\'' +
", database='" + database + '\'' +
", plugin=" + plugin +
", autoClose=" + autoClose +
", flags=" + flags +
'}';
}
}

View File

@ -1,14 +1,12 @@
package me.skymc.taboolib.mysql.builder;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.mysql.builder.data.Insert;
import me.skymc.taboolib.mysql.builder.data.Select;
import me.skymc.taboolib.mysql.IColumn;
import me.skymc.taboolib.mysql.builder.query.RunnableQuery;
import me.skymc.taboolib.mysql.builder.query.RunnableUpdate;
import me.skymc.taboolib.string.ArrayUtils;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* @Author sky
@ -17,17 +15,28 @@ import java.util.stream.Collectors;
public class SQLTable {
private String tableName;
private SQLColumn[] columns;
private IColumn[] columns;
public SQLTable(String tableName) {
this.tableName = tableName;
}
public SQLTable(String tableName, IColumn... column) {
this.tableName = tableName;
this.columns = column;
}
public SQLTable(String tableName, SQLColumn... column) {
this.tableName = tableName;
this.columns = column;
}
public SQLTable column(IColumn column) {
columns = columns == null ? new IColumn[] {column} : ArrayUtils.arrayAppend(columns, column);
return this;
}
@Deprecated
public SQLTable addColumn(SQLColumn sqlColumn) {
columns = columns == null ? new SQLColumn[] {sqlColumn} : ArrayUtils.arrayAppend(columns, sqlColumn);
return this;
@ -51,18 +60,6 @@ public class SQLTable {
return Strings.replaceWithOrder("truncate table `{0}`", tableName);
}
public RunnableQuery select(Select where) {
return executeSelect(Arrays.stream(where.getColumn()).map(s -> s + " = ?").collect(Collectors.joining(", ")));
}
public RunnableUpdate insert(Insert... inserts) {
return executeInsert(Arrays.stream(inserts).map(Insert::getText).collect(Collectors.joining(", ")));
}
public RunnableUpdate update(Select update, Select where) {
return executeUpdate(Arrays.stream(update.getColumn()).map(s -> s + " = ?").collect(Collectors.joining(", ")), Arrays.stream(where.getColumn()).map(s -> s + " = ?").collect(Collectors.joining(", ")));
}
public RunnableQuery executeQuery(String query) {
return new RunnableQuery(query);
}
@ -97,7 +94,7 @@ public class SQLTable {
return tableName;
}
public SQLColumn[] getColumns() {
public IColumn[] getColumns() {
return columns;
}
}

View File

@ -1,22 +0,0 @@
package me.skymc.taboolib.mysql.builder.data;
/**
* @Author
* @Since 2018-12-01 23:32
*/
public enum Insert {
NULL("null"),
VARIABLE("?");
private String text;
Insert(String text) {
this.text = text;
}
public String getText() {
return text;
}
}

View File

@ -1,22 +0,0 @@
package me.skymc.taboolib.mysql.builder.data;
/**
* @Author
* @Since 2018-12-02 11:12
*/
public class Select {
private String[] column;
public Select(String... column) {
this.column = column;
}
public String[] getColumn() {
return column;
}
public static Select of(String... column) {
return new Select(column);
}
}

View File

@ -6,7 +6,9 @@ import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.mysql.IHost;
import me.skymc.taboolib.mysql.builder.SQLHost;
import me.skymc.taboolib.mysql.sqlite.SQLiteHost;
import org.bukkit.configuration.file.FileConfiguration;
import javax.sql.DataSource;
@ -18,24 +20,20 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public class HikariHandler {
private static ConcurrentHashMap<SQLHost, MapDataSource> dataSource = new ConcurrentHashMap<>();
private static FileConfiguration settings;
private static ConcurrentHashMap<IHost, MapDataSource> dataSource = new ConcurrentHashMap<>();
private static FileConfiguration settings = ConfigUtils.saveDefaultConfig(Main.getInst(), "hikarisettings.yml");
public static void init() {
settings = ConfigUtils.saveDefaultConfig(Main.getInst(), "hikarisettings.yml");
}
public static DataSource createDataSource(SQLHost host) {
public static DataSource createDataSource(IHost host) {
return createDataSource(host, null);
}
public static HikariDataSource createDataSource(SQLHost host, HikariConfig hikariConfig) {
public static HikariDataSource createDataSource(IHost host, HikariConfig hikariConfig) {
MapDataSource mapDataSource = dataSource.computeIfAbsent(host, x -> new MapDataSource(x, new HikariDataSource(hikariConfig == null ? createConfig(host) : hikariConfig)));
mapDataSource.getActivePlugin().getAndIncrement();
if (mapDataSource.getActivePlugin().get() == 1) {
TLocale.Logger.info("MYSQL-HIKARI.CREATE-SUCCESS", host.getPlugin().getName(), host.getConnectionUrlSimple());
} else {
TLocale.Logger.info("MYSQL-HIKARI.CREATE-EXISTS", host.getPlugin().getName(), mapDataSource.getSqlHost().getPlugin().getName());
TLocale.Logger.info("MYSQL-HIKARI.CREATE-EXISTS", host.getPlugin().getName(), mapDataSource.getHost().getPlugin().getName());
}
return mapDataSource.getHikariDataSource();
}
@ -45,7 +43,7 @@ public class HikariHandler {
dataSource.values().forEach(x -> x.getHikariDataSource().close());
}
public static void closeDataSource(SQLHost host) {
public static void closeDataSource(IHost host) {
if (host != null && dataSource.containsKey(host)) {
MapDataSource mapDataSource = dataSource.get(host);
if (mapDataSource.getActivePlugin().getAndDecrement() <= 1) {
@ -58,14 +56,20 @@ public class HikariHandler {
}
}
public static HikariConfig createConfig(SQLHost sqlHost) {
public static HikariConfig createConfig(IHost host) {
HikariConfig config = new HikariConfig();
config.setDriverClassName(settings.getString("DefaultSettings.DriverClassName", "com.mysql.jdbc.Driver"));
config.setJdbcUrl(sqlHost.getConnectionUrl());
config.setUsername(sqlHost.getUser());
config.setPassword(sqlHost.getPassword());
config.setJdbcUrl(host.getConnectionUrl());
if (host instanceof SQLHost) {
config.setDriverClassName(settings.getString("DefaultSettings.DriverClassName", "com.mysql.jdbc.Driver"));
config.setUsername(((SQLHost) host).getUser());
config.setPassword(((SQLHost) host).getPassword());
} else if (host instanceof SQLiteHost) {
config.setDriverClassName("org.sqlite.JDBC");
} else {
throw new IllegalArgumentException("Invalid host: " + host.getClass().getName());
}
config.setAutoCommit(settings.getBoolean("DefaultSettings.AutoCommit", true));
config.setMinimumIdle(settings.getInt("DefaultSettings.MinimumIdle", -1));
config.setMinimumIdle(settings.getInt("DefaultSettings.MinimumIdle", 1));
config.setMaximumPoolSize(settings.getInt("DefaultSettings.MaximumPoolSize", 10));
config.setValidationTimeout(settings.getInt("DefaultSettings.ValidationTimeout", 5000));
config.setConnectionTimeout(settings.getInt("DefaultSettings.ConnectionTimeout", 30000));
@ -80,13 +84,33 @@ public class HikariHandler {
return config;
}
@Deprecated
public static DataSource createDataSource(SQLHost host) {
return createDataSource((IHost) host, null);
}
@Deprecated
public static HikariConfig createConfig(SQLHost host) {
return createConfig((IHost) host);
}
@Deprecated
public static HikariDataSource createDataSource(SQLHost host, HikariConfig hikariConfig) {
return createDataSource((IHost) host, hikariConfig);
}
@Deprecated
public static void closeDataSource(SQLHost host) {
closeDataSource((IHost) host);
}
// *********************************
//
// Getter and Setter
//
// *********************************
public static ConcurrentHashMap<SQLHost, MapDataSource> getDataSource() {
public static ConcurrentHashMap<IHost, MapDataSource> getDataSource() {
return dataSource;
}

View File

@ -1,7 +1,7 @@
package me.skymc.taboolib.mysql.hikari;
import com.zaxxer.hikari.HikariDataSource;
import me.skymc.taboolib.mysql.builder.SQLHost;
import me.skymc.taboolib.mysql.IHost;
import java.util.concurrent.atomic.AtomicInteger;
@ -11,18 +11,18 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class MapDataSource {
private SQLHost sqlHost;
private IHost host;
private AtomicInteger activePlugin;
private HikariDataSource hikariDataSource;
MapDataSource(SQLHost sqlHost, HikariDataSource hikariDataSource) {
this.sqlHost = sqlHost;
MapDataSource(IHost host, HikariDataSource hikariDataSource) {
this.host = host;
this.activePlugin = new AtomicInteger();
this.hikariDataSource = hikariDataSource;
}
public SQLHost getSqlHost() {
return sqlHost;
public IHost getHost() {
return host;
}
public AtomicInteger getActivePlugin() {

View File

@ -0,0 +1,132 @@
package me.skymc.taboolib.mysql.sqlite;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.mysql.IColumn;
import java.util.Arrays;
/**
* @Author sky
* @Since 2018-05-14 19:09
*/
public class SQLiteColumn extends IColumn {
public static final SQLiteColumn PRIMARY_KEY_ID = new SQLiteColumn(SQLiteColumnType.INTEGER, "id", SQLiteColumnOption.NOTNULL, SQLiteColumnOption.PRIMARY_KEY, SQLiteColumnOption.AUTOINCREMENT);
private SQLiteColumnType columnType;
private int m;
private int d;
private String columnName;
private Object defaultValue;
private SQLiteColumnOption[] columnOptions;
/**
*
* new SQLColumn(SQLiteColumnType.TEXT, "username");
*/
public SQLiteColumn(SQLiteColumnType columnType, String columnName) {
this(columnType, 0, 0, columnName, null);
}
/**
* CHAR
*
* @param columnType
* @param columnName
*/
public SQLiteColumn(SQLiteColumnType columnType, int m, String columnName) {
this(columnType, m, 0, columnName, null);
}
/**
*
* new SQLColumn(SQLiteColumnType.TEXT, "username", SQLiteColumnOption.PRIMARY_KEY, SQLiteColumnOption.AUTO_INCREMENT);
*/
public SQLiteColumn(SQLiteColumnType columnType, String columnName, SQLiteColumnOption... columnOptions) {
this(columnType, 0, 0, columnName, null, columnOptions);
}
/**
*
* new SQLColumn(SQLiteColumnType.TEXT, "player_group", "PLAYER");
*/
public SQLiteColumn(SQLiteColumnType columnType, String columnName, Object defaultValue) {
this(columnType, 0, 0, columnName, defaultValue);
}
/**
*
*
* @param columnType
* @param m m
* @param d d
* @param columnName
* @param defaultValue
* @param columnOptions
*/
public SQLiteColumn(SQLiteColumnType columnType, int m, int d, String columnName, Object defaultValue, SQLiteColumnOption... columnOptions) {
this.columnType = columnType;
this.m = m;
this.d = d;
this.columnName = columnName;
this.defaultValue = defaultValue;
this.columnOptions = columnOptions;
}
public SQLiteColumn m(int m) {
this.m = m;
return this;
}
public SQLiteColumn d(int d) {
this.d = d;
return this;
}
public SQLiteColumn defaultValue(Object defaultValue) {
this.defaultValue = defaultValue;
return this;
}
public SQLiteColumn columnOptions(SQLiteColumnOption... columnOptions) {
this.columnOptions = columnOptions;
return this;
}
public String convertToCommand() {
if (this.m == 0 && this.d == 0) {
return Strings.replaceWithOrder("`{0}` {1}{2}", columnName, columnType.name().toLowerCase(), convertToOptions());
} else if (this.d == 0) {
return Strings.replaceWithOrder("`{0}` {1}({2}){3}", columnName, columnType.name().toLowerCase(), m, convertToOptions());
} else {
return Strings.replaceWithOrder("`{0}` {1}({2},{3}){4}", columnName, columnType.name().toLowerCase(), m, d, convertToOptions());
}
}
private String convertToOptions() {
StringBuilder builder = new StringBuilder();
Arrays.stream(columnOptions).forEach(option -> builder.append(" ").append(option.getText()));
if (defaultValue != null) {
if (defaultValue instanceof String) {
builder.append(" DEFAULT '").append(defaultValue).append("'");
} else {
builder.append(" DEFAULT ").append(defaultValue);
}
}
return builder.toString();
}
@Override
public String toString() {
return "SQLiteColumn{" +
"columnType=" + columnType +
", m=" + m +
", d=" + d +
", columnName='" + columnName + '\'' +
", defaultValue=" + defaultValue +
", columnOptions=" + Arrays.toString(columnOptions) +
'}';
}
}

View File

@ -0,0 +1,38 @@
package me.skymc.taboolib.mysql.sqlite;
/**
* @Author sky
* @Since 2018-05-14 21:43
*/
public enum SQLiteColumnOption {
/**
*
*/
NOTNULL("NOT NULL"),
/**
*
*/
UNIQUE("UNIQUE"),
/**
*
*/
PRIMARY_KEY("PRIMARY KEY"),
/**
*
*/
AUTOINCREMENT("AUTOINCREMENT");
String text;
SQLiteColumnOption(String text) {
this.text = text;
}
public String getText() {
return text;
}
}

View File

@ -0,0 +1,36 @@
package me.skymc.taboolib.mysql.sqlite;
/**
* @Author
* @Since 2018-12-08 13:28
*/
public enum SQLiteColumnType {
NULL,
/**
* 12346 8
*/
INTEGER,
/**
* 8 IEEE
*/
REAL,
/**
* 使UTF-8UTF-16BE UTF-16LE
*/
TEXT,
/**
* blob
*/
BLOB,
/**
*
*/
NUMERIC
}

View File

@ -0,0 +1,64 @@
package me.skymc.taboolib.mysql.sqlite;
import me.skymc.taboolib.mysql.IHost;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.util.Objects;
/**
* @Author
* @Since 2018-12-08 12:58
*/
public class SQLiteHost extends IHost {
private final File file;
public SQLiteHost(File file, Plugin plugin) {
super(plugin);
this.file = file;
}
public SQLiteHost(File file, Plugin plugin, boolean autoClose) {
super(plugin, autoClose);
this.file = file;
}
public File getFile() {
return file;
}
@Override
public String getConnectionUrl() {
return "jdbc:sqlite:" + file.getPath();
}
@Override
public String getConnectionUrlSimple() {
return "jdbc:sqlite:" + file.getPath();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SQLiteHost)) {
return false;
}
SQLiteHost that = (SQLiteHost) o;
return Objects.equals(getFile(), that.getFile());
}
@Override
public int hashCode() {
return Objects.hash(getFile());
}
@Override
public String toString() {
return "SQLiteHost{" +
"file=" + file +
'}';
}
}