mirror of
https://github.com/ChestShop-authors/ChestShop-3.git
synced 2024-11-27 12:38:40 +01:00
Make DB code nicer
This commit is contained in:
parent
6466b2d6aa
commit
02673dec94
@ -11,6 +11,7 @@ import java.util.UUID;
|
||||
* @author Andrzej Pomirski (Acrobot)
|
||||
*/
|
||||
@DatabaseTable(tableName = "accounts")
|
||||
@DatabaseFileName("users.db")
|
||||
public class Account {
|
||||
|
||||
@DatabaseField(canBeNull = false)
|
||||
|
59
src/main/java/com/Acrobot/ChestShop/Database/DaoCreator.java
Normal file
59
src/main/java/com/Acrobot/ChestShop/Database/DaoCreator.java
Normal file
@ -0,0 +1,59 @@
|
||||
package com.Acrobot.ChestShop.Database;
|
||||
|
||||
import com.Acrobot.ChestShop.ChestShop;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.dao.DaoManager;
|
||||
import com.j256.ormlite.dao.LruObjectCache;
|
||||
import com.j256.ormlite.db.SqliteDatabaseType;
|
||||
import com.j256.ormlite.jdbc.JdbcConnectionSource;
|
||||
import com.j256.ormlite.support.ConnectionSource;
|
||||
import com.j256.ormlite.table.TableUtils;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Creates a DAO appropriate for the plugin
|
||||
*
|
||||
* @author Andrzej Pomirski
|
||||
*/
|
||||
public class DaoCreator {
|
||||
|
||||
/**
|
||||
* Returns a DAO for the given entity and with the given ID
|
||||
* @param entity Entity's class
|
||||
* @param <ENTITY> Type of the entity
|
||||
* @return Dao
|
||||
* @throws InvalidParameterException
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static <ENTITY, ID> Dao<ENTITY, ID> getDao(Class<ENTITY> entity) throws InvalidParameterException, SQLException {
|
||||
if (!entity.isAnnotationPresent(DatabaseFileName.class)) {
|
||||
throw new InvalidParameterException("Entity not annotated with @DatabaseFileName!");
|
||||
}
|
||||
|
||||
String fileName = entity.getAnnotation(DatabaseFileName.class).value();
|
||||
String uri = ConnectionManager.getURI(ChestShop.loadFile(fileName));
|
||||
|
||||
ConnectionSource connectionSource = new JdbcConnectionSource(uri, new SqliteDatabaseType());
|
||||
|
||||
Dao<ENTITY, ID> dao = DaoManager.createDao(connectionSource, entity);
|
||||
dao.setObjectCache(new LruObjectCache(200));
|
||||
|
||||
return dao;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dao as well as a default table, if doesn't exist
|
||||
* @see #getDao(Class)
|
||||
* @throws SQLException
|
||||
* @throws InvalidParameterException
|
||||
*/
|
||||
public static <ENTITY, ID> Dao<ENTITY, ID> getDaoAndCreateTable(Class<ENTITY> entity) throws SQLException, InvalidParameterException {
|
||||
Dao<ENTITY, ID> dao = getDao(entity);
|
||||
|
||||
TableUtils.createTableIfNotExists(dao.getConnectionSource(), entity);
|
||||
|
||||
return dao;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.Acrobot.ChestShop.Database;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Represents the filename of the database (inside ChestShop's folder)
|
||||
* @author Andrzej Pomirski
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DatabaseFileName {
|
||||
String value();
|
||||
}
|
39
src/main/java/com/Acrobot/ChestShop/Database/Item.java
Normal file
39
src/main/java/com/Acrobot/ChestShop/Database/Item.java
Normal file
@ -0,0 +1,39 @@
|
||||
package com.Acrobot.ChestShop.Database;
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
|
||||
/**
|
||||
* Mapping for enchanted items
|
||||
* @author Andrzej Pomirski
|
||||
*/
|
||||
@DatabaseTable(tableName = "items")
|
||||
@DatabaseFileName("items.db")
|
||||
public class Item {
|
||||
|
||||
@DatabaseField(canBeNull = false, generatedId = true)
|
||||
private int id;
|
||||
|
||||
@DatabaseField(columnName = "code", canBeNull = false, unique = true)
|
||||
private String base64ItemCode;
|
||||
|
||||
public Item() {
|
||||
//empty constructor
|
||||
}
|
||||
|
||||
public Item(String base64ItemCode) {
|
||||
this.base64ItemCode = base64ItemCode;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getBase64ItemCode() {
|
||||
return base64ItemCode;
|
||||
}
|
||||
|
||||
public void setBase64ItemCode(String base64ItemCode) {
|
||||
this.base64ItemCode = base64ItemCode;
|
||||
}
|
||||
}
|
56
src/main/java/com/Acrobot/ChestShop/Database/Migrations.java
Normal file
56
src/main/java/com/Acrobot/ChestShop/Database/Migrations.java
Normal file
@ -0,0 +1,56 @@
|
||||
package com.Acrobot.ChestShop.Database;
|
||||
|
||||
import com.Acrobot.ChestShop.ChestShop;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* File handling the database migrations
|
||||
*
|
||||
* @author Andrzej Pomirski
|
||||
*/
|
||||
public class Migrations {
|
||||
public static final int CURRENT_DATABASE_VERSION = 2;
|
||||
|
||||
/**
|
||||
* Migrates a database from the given version
|
||||
*
|
||||
* @param currentVersion Current version of the database
|
||||
* @return Current database version
|
||||
*/
|
||||
public static int migrate(int currentVersion) {
|
||||
if (currentVersion != CURRENT_DATABASE_VERSION) {
|
||||
ChestShop.getBukkitLogger().info("Updating database...");
|
||||
} else {
|
||||
return CURRENT_DATABASE_VERSION;
|
||||
}
|
||||
|
||||
switch (currentVersion) {
|
||||
case 1:
|
||||
boolean migrated = migrateTo2();
|
||||
|
||||
if (migrated) {
|
||||
currentVersion++;
|
||||
}
|
||||
|
||||
case 2:
|
||||
default:
|
||||
//do nothing
|
||||
}
|
||||
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
private static boolean migrateTo2() {
|
||||
try {
|
||||
Dao<Account, String> accounts = DaoCreator.getDao(Account.class);
|
||||
|
||||
accounts.executeRaw("ALTER TABLE `accounts` ADD COLUMN lastSeenName VARCHAR");
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +1,19 @@
|
||||
package com.Acrobot.ChestShop.Metadata;
|
||||
|
||||
import com.Acrobot.Breeze.Database.Database;
|
||||
import com.Acrobot.Breeze.Database.Row;
|
||||
import com.Acrobot.Breeze.Database.Table;
|
||||
import com.Acrobot.Breeze.Utils.Encoding.Base62;
|
||||
import com.Acrobot.Breeze.Utils.Encoding.Base64;
|
||||
import com.Acrobot.ChestShop.ChestShop;
|
||||
import com.Acrobot.ChestShop.Database.DaoCreator;
|
||||
import com.Acrobot.ChestShop.Database.Item;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import org.bukkit.configuration.file.YamlConstructor;
|
||||
import org.bukkit.configuration.file.YamlRepresenter;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.nodes.Tag;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Saves items with Metadata in database, which allows for saving items on signs easily.
|
||||
@ -24,33 +21,15 @@ import java.util.Map;
|
||||
* @author Acrobot
|
||||
*/
|
||||
public class ItemDatabase {
|
||||
private static final Map<String, ItemStack> METADATA_CACHE = new HashMap<String, ItemStack>();
|
||||
private Dao<Item, Integer> itemDao;
|
||||
|
||||
private final Yaml yaml;
|
||||
private Table table;
|
||||
|
||||
public ItemDatabase() {
|
||||
try {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
ChestShop.getBukkitLogger().severe("You haven't got any SQLite JDBC installed!");
|
||||
}
|
||||
|
||||
Database database = new Database("jdbc:sqlite:" + ChestShop.loadFile("items.db").getAbsolutePath());
|
||||
yaml = new Yaml(new YamlConstructor(), new YamlRepresenter(), new DumperOptions());
|
||||
yaml = new Yaml(new YamlBukkitConstructor(), new YamlRepresenter(), new DumperOptions());
|
||||
|
||||
try {
|
||||
Statement statement = database.getConnection().createStatement();
|
||||
statement.executeUpdate("PRAGMA user_version = 1"); //We'll be able to change it later if we need to
|
||||
statement.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
table = database.getTable("items");
|
||||
table.create("id INTEGER PRIMARY KEY, code VARCHAR UNIQUE ON CONFLICT IGNORE");
|
||||
itemDao = DaoCreator.getDaoAndCreateTable(Item.class);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -66,21 +45,29 @@ public class ItemDatabase {
|
||||
try {
|
||||
ItemStack clone = new ItemStack(item);
|
||||
clone.setAmount(1);
|
||||
clone.setDurability((short) 0);
|
||||
|
||||
String code = Base64.encodeObject(yaml.dump(clone));
|
||||
table.insertRow("null, '" + code + '\'');
|
||||
Item itemEntity = itemDao.queryBuilder().where().eq("code", code).queryForFirst();
|
||||
|
||||
if (itemEntity != null) {
|
||||
return Base62.encode(itemEntity.getId());
|
||||
}
|
||||
|
||||
itemEntity = new Item(code);
|
||||
|
||||
itemDao.create(itemEntity);
|
||||
|
||||
int id = itemEntity.getId();
|
||||
|
||||
int id = Integer.parseInt(table.getRow("code='" + code + '\'').get("id"));
|
||||
return Base62.encode(id);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,32 +77,32 @@ public class ItemDatabase {
|
||||
* @return ItemStack represented by this code
|
||||
*/
|
||||
public ItemStack getFromCode(String code) {
|
||||
if (METADATA_CACHE.containsKey(code)) {
|
||||
return METADATA_CACHE.get(code);
|
||||
}
|
||||
|
||||
try {
|
||||
Row row = table.getRow("id='" + Base62.decode(code) + '\'');
|
||||
int id = Base62.decode(code);
|
||||
Item item = itemDao.queryBuilder().where().eq("id", id).queryForFirst();
|
||||
|
||||
if (row.getSize() == 0) {
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String serialized = row.get("code");
|
||||
String serialized = item.getBase64ItemCode();
|
||||
|
||||
ItemStack item = (ItemStack) yaml.load((String) Base64.decodeToObject(serialized));
|
||||
METADATA_CACHE.put(code, item);
|
||||
|
||||
return item;
|
||||
return yaml.loadAs((String) Base64.decodeToObject(serialized), ItemStack.class);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private class YamlBukkitConstructor extends YamlConstructor {
|
||||
public YamlBukkitConstructor() {
|
||||
this.yamlConstructors.put(new Tag(Tag.PREFIX + "org.bukkit.inventory.ItemStack"), yamlConstructors.get(Tag.MAP));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,17 @@
|
||||
package com.Acrobot.ChestShop.UUIDs;
|
||||
|
||||
import com.Acrobot.Breeze.Utils.NameUtil;
|
||||
import com.Acrobot.ChestShop.ChestShop;
|
||||
import com.Acrobot.ChestShop.Configuration.Properties;
|
||||
import com.Acrobot.ChestShop.Database.Account;
|
||||
import com.Acrobot.ChestShop.Database.ConnectionManager;
|
||||
import com.Acrobot.ChestShop.Database.DaoCreator;
|
||||
import com.Acrobot.ChestShop.Permission;
|
||||
import com.Acrobot.ChestShop.Signs.ChestShopSign;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.dao.DaoManager;
|
||||
import com.j256.ormlite.jdbc.JdbcConnectionSource;
|
||||
import com.j256.ormlite.support.ConnectionSource;
|
||||
import com.j256.ormlite.table.TableUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -28,6 +22,7 @@ import java.util.UUID;
|
||||
*
|
||||
* @author Andrzej Pomirski (Acrobot)
|
||||
*/
|
||||
@SuppressWarnings("UnusedAssignment") //I deliberately set the variables to null while initializing
|
||||
public class NameManager {
|
||||
private static Dao<Account, String> accounts;
|
||||
|
||||
@ -229,19 +224,12 @@ public class NameManager {
|
||||
}
|
||||
|
||||
public static boolean isAdminShop(UUID uuid) {
|
||||
return getUsername(uuid).equals(Properties.ADMIN_SHOP_NAME);
|
||||
return Properties.ADMIN_SHOP_NAME.equals(getUsername(uuid));
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
File databaseFile = ChestShop.loadFile("users.db");
|
||||
String uri = ConnectionManager.getURI(databaseFile);
|
||||
ConnectionSource connection;
|
||||
|
||||
try {
|
||||
connection = new JdbcConnectionSource(uri);
|
||||
accounts = DaoManager.createDao(connection, Account.class);
|
||||
|
||||
TableUtils.createTableIfNotExists(connection, Account.class);
|
||||
accounts = DaoCreator.getDaoAndCreateTable(Account.class);
|
||||
|
||||
Account adminAccount = new Account(Properties.ADMIN_SHOP_NAME, Bukkit.getOfflinePlayer(Properties.ADMIN_SHOP_NAME).getUniqueId());
|
||||
accounts.createOrUpdate(adminAccount);
|
||||
|
Loading…
Reference in New Issue
Block a user