Remove logging to database!

This commit is contained in:
Andrzej Pomirski 2015-05-22 13:25:32 +02:00
parent 9200928dca
commit 6466b2d6aa
6 changed files with 19 additions and 805 deletions

View File

@ -7,17 +7,14 @@ import com.Acrobot.ChestShop.Commands.Toggle;
import com.Acrobot.ChestShop.Commands.Version;
import com.Acrobot.ChestShop.Configuration.Messages;
import com.Acrobot.ChestShop.Configuration.Properties;
import com.Acrobot.ChestShop.DB.Generator;
import com.Acrobot.ChestShop.DB.Queue;
import com.Acrobot.ChestShop.DB.Transaction;
import com.Acrobot.ChestShop.Database.Account;
import com.Acrobot.ChestShop.Database.ConnectionManager;
import com.Acrobot.ChestShop.Database.Migrations;
import com.Acrobot.ChestShop.Listeners.Block.BlockPlace;
import com.Acrobot.ChestShop.Listeners.Block.Break.ChestBreak;
import com.Acrobot.ChestShop.Listeners.Block.Break.SignBreak;
import com.Acrobot.ChestShop.Listeners.Block.SignCreate;
import com.Acrobot.ChestShop.Listeners.Economy.ServerAccountCorrector;
import com.Acrobot.ChestShop.Listeners.Economy.TaxModule;
import com.Acrobot.ChestShop.Listeners.GarbageTextListener;
import com.Acrobot.ChestShop.Listeners.Item.ItemMoveListener;
import com.Acrobot.ChestShop.Listeners.ItemInfoListener;
import com.Acrobot.ChestShop.Listeners.Modules.DiscountModule;
@ -39,12 +36,6 @@ import com.Acrobot.ChestShop.Metadata.ItemDatabase;
import com.Acrobot.ChestShop.Signs.RestrictedSign;
import com.Acrobot.ChestShop.UUIDs.NameManager;
import com.Acrobot.ChestShop.Updater.Updater;
import com.avaje.ebean.EbeanServer;
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.lennardf1989.bukkitex.Database;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Marker;
@ -55,7 +46,6 @@ import org.apache.logging.log4j.core.filter.AbstractFilter;
import org.apache.logging.log4j.message.Message;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
@ -65,8 +55,6 @@ import org.mcstats.Metrics;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
@ -82,19 +70,20 @@ public class ChestShop extends JavaPlugin {
private static PluginDescriptionFile description;
private static File dataFolder;
private static EbeanServer database;
private static ItemDatabase itemDatabase;
private static Logger logger;
private FileHandler handler;
public void onEnable() {
plugin = this;
logger = getLogger();
public ChestShop() {
dataFolder = getDataFolder();
logger = getLogger();
description = getDescription();
server = getServer();
plugin = this;
}
public void onEnable() {
Configuration.pairFileAndClass(loadFile("config.yml"), Properties.class);
Configuration.pairFileAndClass(loadFile("local.yml"), Messages.class);
@ -109,15 +98,6 @@ public class ChestShop extends JavaPlugin {
registerEvents();
if (Properties.LOG_TO_DATABASE || Properties.GENERATE_STATISTICS_PAGE) {
setupDB();
}
if (Properties.GENERATE_STATISTICS_PAGE) {
File htmlFolder = new File(Properties.STATISTICS_PAGE_PATH);
scheduleTask(new Generator(htmlFolder), 300L, Properties.STATISTICS_PAGE_GENERATION_INTERVAL * 20L);
}
if (Properties.LOG_TO_FILE) {
File log = loadFile("ChestShop.log");
@ -181,14 +161,13 @@ public class ChestShop extends JavaPlugin {
});
}
private final int CURRENT_DATABASE_VERSION = 2;
private void handleMigrations() {
File versionFile = loadFile("version");
YamlConfiguration previousVersion = YamlConfiguration.loadConfiguration(versionFile);
if (previousVersion.get("version") == null) {
previousVersion.set("version", CURRENT_DATABASE_VERSION);
previousVersion.set("version", Migrations.CURRENT_DATABASE_VERSION);
try {
previousVersion.save(versionFile);
@ -198,32 +177,16 @@ public class ChestShop extends JavaPlugin {
}
int lastVersion = previousVersion.getInt("version");
int newVersion = Migrations.migrate(lastVersion);
if (CURRENT_DATABASE_VERSION != lastVersion) {
logger.info("Updating database...");
}
if (lastVersion != newVersion) {
previousVersion.set("version", newVersion);
switch (lastVersion) {
case 1:
try {
File databaseFile = ChestShop.loadFile("users.db");
String uri = ConnectionManager.getURI(databaseFile);
ConnectionSource connection = new JdbcConnectionSource(uri);
Dao<Account, String> accounts = DaoManager.createDao(connection, Account.class);
accounts.executeRaw("ALTER TABLE `accounts` ADD COLUMN lastSeenName VARCHAR");
previousVersion.set("version", 2);
previousVersion.save(versionFile);
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
case CURRENT_DATABASE_VERSION:
default:
//do nothing
}
}
@ -296,6 +259,7 @@ public class ChestShop extends JavaPlugin {
registerEvent(new PlayerTeleport());
registerEvent(new ItemInfoListener());
registerEvent(new GarbageTextListener());
registerEvent(new RestrictedSign());
@ -394,40 +358,6 @@ public class ChestShop extends JavaPlugin {
new Updater(this, PROJECT_BUKKITDEV_ID, this.getFile(), Updater.UpdateType.DEFAULT, true);
}
///////////////////// DATABASE STUFF ////////////////////////////////
private void setupDB() {
loadFile(new File("ebean.properties"));
Database DB;
DB = new Database(this) {
protected java.util.List<Class<?>> getDatabaseClasses() {
List<Class<?>> list = new ArrayList<Class<?>>();
list.add(Transaction.class);
return list;
}
};
FileConfiguration config = YamlConfiguration.loadConfiguration(new File("bukkit.yml"));
DB.initializeDatabase(
config.getString("database.driver"),
config.getString("database.url"),
config.getString("database.username"),
config.getString("database.password"),
config.getString("database.isolation")
);
database = DB.getDatabase();
scheduleTask(new Queue(), 200L, 200L);
}
@Override
public EbeanServer getDatabase() {
return database;
}
///////////////////////////////////////////////////////////////////////////////
public static ItemDatabase getItemDatabase() {
@ -454,10 +384,6 @@ public class ChestShop extends JavaPlugin {
return description.getName();
}
public static EbeanServer getDB() {
return database;
}
public static List<String> getDependencies() {
return description.getSoftDepend();
}

View File

@ -1,171 +0,0 @@
package com.Acrobot.ChestShop.DB;
import com.Acrobot.Breeze.Utils.StringUtil;
import com.Acrobot.ChestShop.ChestShop;
import com.avaje.ebean.ExpressionList;
import org.bukkit.Material;
import javax.persistence.PersistenceException;
import java.io.*;
import java.util.List;
/**
* @author Acrobot
*/
public class Generator implements Runnable {
private final File pagePath;
private static String header;
private static String row;
private static String footer;
private static BufferedWriter buf;
public Generator(File pagePath) {
this.pagePath = pagePath;
}
public void run() {
header = fileToString("header");
row = fileToString("row");
footer = fileToString("footer");
if (row.isEmpty()) {
ChestShop.getBukkitLogger().severe("You lack the necessary HTML files in your plugins/ChestShop/HTML folder!");
return;
}
generateStats();
}
private void fileStart() throws IOException {
FileWriter fw = new FileWriter(pagePath);
fw.write(header);
fw.close();
}
private void fileEnd(long generationTime) throws IOException {
FileWriter fw = new FileWriter(pagePath, true);
fw.write(footer.replace("%time", String.valueOf(generationTime)));
fw.close();
}
private static String fileToString(String fileName) {
try {
File htmlFolder = new File(ChestShop.getFolder(), "HTML");
File fileToRead = new File(htmlFolder, fileName + ".html");
FileReader rd = new FileReader(fileToRead);
char[] buf = new char[(int) fileToRead.length()];
rd.read(buf);
return new String(buf);
} catch (Exception e) {
return "";
}
}
private static double generateItemTotal(Material item, boolean bought, boolean sold) {
List<Transaction> list;
ExpressionList<Transaction> checkIf = ChestShop.getDB().find(Transaction.class).where();
if (bought || sold) {
list = checkIf.eq("buy", bought ? 1 : 0).eq("itemID", item.getId()).findList();
} else {
list = checkIf.eq("itemID", item.getId()).findList();
}
return countTransactionAmount(list);
}
private static double countTransactionAmount(List<Transaction> list) {
double amount = 0;
for (Transaction transaction : list) {
amount += transaction.getAmount();
}
return amount;
}
private static double generateTotalBought(Material item) {
return generateItemTotal(item, true, false);
}
private static double generateTotalSold(Material item) {
return generateItemTotal(item, false, true);
}
private static double generateItemTotal(Material item) {
return generateItemTotal(item, false, false);
}
private static float generateAveragePrice(Material item) {
float price = 0;
List<Transaction> prices = ChestShop.getDB().find(Transaction.class).where().eq("itemID", item.getId()).eq("buy", true).findList();
for (Transaction t : prices) {
price += t.getAveragePricePerItem();
}
float toReturn = price / prices.size();
return (!Float.isNaN(toReturn) ? toReturn : 0);
}
private static float generateAverageBuyPrice(Material item) {
return generateAveragePrice(item);
}
private static void generateItemStats(Material material) throws IOException {
double total = generateItemTotal(material);
if (total == 0) return;
double bought = generateTotalBought(material);
double sold = generateTotalSold(material);
String matName = StringUtil.capitalizeFirstLetter(material.name(), '_');
int maxStackSize = material.getMaxStackSize();
float buyPrice = generateAverageBuyPrice(material);
buf.write(row.replace("%material", matName)
.replace("%total", String.valueOf(total))
.replace("%bought", String.valueOf(bought))
.replace("%sold", String.valueOf(sold))
.replace("%maxStackSize", String.valueOf(maxStackSize))
.replace("%pricePerStack", String.valueOf((buyPrice * maxStackSize)))
.replace("%pricePerItem", String.valueOf(buyPrice)));
}
private void generateStats() {
try {
File parentFolder = pagePath.getParentFile();
if (!parentFolder.exists()) {
parentFolder.mkdir();
}
fileStart();
buf = new BufferedWriter(new FileWriter(pagePath, true));
long genTime = System.currentTimeMillis();
for (Material m : Material.values()) {
generateItemStats(m);
}
buf.close();
long generationTime = (System.currentTimeMillis() - genTime) / 1000;
fileEnd(generationTime);
} catch (Exception e) {
ChestShop.getBukkitLogger().severe("Couldn't generate statistics page!");
if (!(e instanceof PersistenceException)) {
e.printStackTrace();
}
}
}
}

View File

@ -1,45 +0,0 @@
package com.Acrobot.ChestShop.DB;
import com.Acrobot.ChestShop.ChestShop;
import com.Acrobot.ChestShop.Configuration.Properties;
import javax.persistence.OptimisticLockException;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* @author Acrobot
*/
public class Queue implements Runnable {
private static final ConcurrentLinkedQueue<Transaction> queue = new ConcurrentLinkedQueue<Transaction>();
public static void addToQueue(Transaction t) {
queue.add(t);
}
public synchronized void run() {
if (Properties.RECORD_TIME_TO_LIVE != -1)
deleteOld();
ChestShop.getDB().save(queue);
queue.clear();
}
public synchronized static boolean deleteOld() {
try {
ChestShop.getDB().delete(getOld());
return true;
} catch (OptimisticLockException ex) {
return false;
}
}
public static List getOld() throws OptimisticLockException {
return ChestShop
.getDB()
.find(Transaction.class)
.where()
.lt("sec", (System.currentTimeMillis() / 1000L) - Properties.RECORD_TIME_TO_LIVE)
.findList();
}
}

View File

@ -1,104 +0,0 @@
package com.Acrobot.ChestShop.DB;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author Acrobot
*/
@Entity()
@Table(name = "cs_transactions")
public class Transaction {
@Id
private int id;
private boolean buy;
private String shopOwner;
private String shopUser;
private int itemID;
private int itemDurability;
private int amount;
private float price;
private long sec;
public Transaction() {
}
public float getAveragePricePerItem() {
return price / amount;
}
public int getId() {
return id;
}
public boolean isBuy() {
return buy;
}
public String getShopOwner() {
return shopOwner;
}
public String getShopUser() {
return shopUser;
}
public int getItemID() {
return itemID;
}
public int getItemDurability() {
return itemDurability;
}
public int getAmount() {
return amount;
}
public float getPrice() {
return price;
}
public long getSec() {
return sec;
}
public void setId(int id) {
this.id = id;
}
public void setBuy(boolean buy) {
this.buy = buy;
}
public void setShopOwner(String shopOwner) {
this.shopOwner = shopOwner;
}
public void setShopUser(String shopUser) {
this.shopUser = shopUser;
}
public void setItemID(int itemID) {
this.itemID = itemID;
}
public void setItemDurability(int itemDurability) {
this.itemDurability = itemDurability;
}
public void setAmount(int amount) {
this.amount = amount;
}
public void setPrice(float price) {
this.price = price;
}
public void setSec(long sec) {
this.sec = sec;
}
}

View File

@ -25,10 +25,7 @@ import org.bukkit.material.PistonBaseMaterial;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.*;
import static com.Acrobot.Breeze.Utils.BlockUtil.getAttachedBlock;
import static com.Acrobot.Breeze.Utils.BlockUtil.isSign;
@ -174,7 +171,7 @@ public class SignBreak implements Listener {
}
if (isSign(block)) {
return Arrays.asList((Sign) block.getState());
return Collections.singletonList((Sign) block.getState());
} else {
List<Sign> attachedSigns = new LinkedList<Sign>();

View File

@ -1,389 +0,0 @@
package com.lennardf1989.bukkitex;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.EbeanServerFactory;
import com.avaje.ebean.config.DataSourceConfig;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.SQLitePlatform;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.server.ddl.DdlGenerator;
import com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.BufferedReader;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public abstract class Database {
private JavaPlugin javaPlugin;
private ClassLoader classLoader;
private Level loggerLevel;
private boolean usingSQLite;
private ServerConfig serverConfig;
private EbeanServer ebeanServer;
/**
* Create an instance of Database
*
* @param javaPlugin Plugin instancing this database
*/
public Database(JavaPlugin javaPlugin) {
//Store the JavaPlugin
this.javaPlugin = javaPlugin;
//Try to get the ClassLoader of the plugin using Reflection
try {
//Find the "getClassLoader" method and make it "public" instead of "protected"
Method method = JavaPlugin.class.getDeclaredMethod("getClassLoader");
method.setAccessible(true);
//Store the ClassLoader
this.classLoader = (ClassLoader) method.invoke(javaPlugin);
} catch (Exception ex) {
throw new RuntimeException("Failed to retrieve the ClassLoader of the plugin using Reflection", ex);
}
}
/**
* Initialize the database using the passed arguments
*
* @param driver Database-driver to use. For example: org.sqlite.JDBC
* @param url Location of the database. For example: jdbc:sqlite:{DIR}{NAME}.db
* @param username Username required to access the database
* @param password Password belonging to the username, may be empty
* @param isolation Isolation type. For example: SERIALIZABLE, also see TransactionIsolation
*/
public void initializeDatabase(String driver, String url, String username, String password, String isolation) {
//Logging needs to be set back to the original level, no matter what happens
try {
//Disable all logging
disableDatabaseLogging(false);
//Prepare the database
prepareDatabase(driver, url, username, password, isolation);
//Load the database
loadDatabase();
//Create all tables
installDatabase(false);
} catch (Exception ex) {
throw new RuntimeException("An exception has occured while initializing the database", ex);
} finally {
//Enable all logging
enableDatabaseLogging(false);
}
}
private void prepareDatabase(String driver, String url, String username, String password, String isolation) {
//Setup the data source
DataSourceConfig ds = new DataSourceConfig();
ds.setDriver(driver);
ds.setUrl(replaceDatabaseString(url));
ds.setUsername(username);
ds.setPassword(password);
ds.setIsolationLevel(TransactionIsolation.getLevel(isolation));
//Setup the server configuration
ServerConfig sc = new ServerConfig();
sc.setDefaultServer(false);
sc.setRegister(false);
sc.setName(ds.getUrl().replaceAll("[^a-zA-Z0-9]", ""));
//Get all persistent classes
List<Class<?>> classes = getDatabaseClasses();
//Do a sanity check first
if (classes.isEmpty()) {
//Exception: There is no use in continuing to load this database
throw new RuntimeException("Database has been enabled, but no classes are registered to it");
}
//Register them with the EbeanServer
sc.setClasses(classes);
//Check if the SQLite JDBC supplied with Bukkit is being used
if (ds.getDriver().equalsIgnoreCase("org.sqlite.JDBC")) {
//Remember the database is a SQLite-database
usingSQLite = true;
//Modify the platform, as SQLite has no AUTO_INCREMENT field
sc.setDatabasePlatform(new SQLitePlatform());
sc.getDatabasePlatform().getDbDdlSyntax().setIdentity("");
}
prepareDatabaseAdditionalConfig(ds, sc);
//Finally the data source
sc.setDataSourceConfig(ds);
//Store the ServerConfig
serverConfig = sc;
}
private void loadDatabase() {
//Declare a few local variables for later use
ClassLoader currentClassLoader = null;
Field cacheField = null;
boolean cacheValue = true;
try {
//Store the current ClassLoader, so it can be reverted later
currentClassLoader = Thread.currentThread().getContextClassLoader();
//Set the ClassLoader to Plugin ClassLoader
Thread.currentThread().setContextClassLoader(classLoader);
//Get a reference to the private static "defaultUseCaches"-field in URLConnection
cacheField = URLConnection.class.getDeclaredField("defaultUseCaches");
//Make it accessible, store the default value and set it to false
cacheField.setAccessible(true);
cacheValue = cacheField.getBoolean(null);
cacheField.setBoolean(null, false);
//Setup Ebean based on the configuration
ebeanServer = EbeanServerFactory.create(serverConfig);
} catch (Exception ex) {
throw new RuntimeException("Failed to create a new instance of the EbeanServer", ex);
} finally {
//Revert the ClassLoader back to its original value
if (currentClassLoader != null) {
Thread.currentThread().setContextClassLoader(currentClassLoader);
}
//Revert the "defaultUseCaches"-field in URLConnection back to its original value
try {
if (cacheField != null) {
cacheField.setBoolean(null, cacheValue);
}
} catch (Exception e) {
System.out.println("Failed to revert the \"defaultUseCaches\"-field back to its original value, URLConnection-caching remains disabled.");
}
}
}
private void installDatabase(boolean rebuild) {
//Check if the database already (partially) exists
boolean databaseExists = false;
List<Class<?>> classes = getDatabaseClasses();
for (Class<?> aClass : classes) {
try {
//Do a simple query which only throws an exception if the table does not exist
ebeanServer.find(aClass).findRowCount();
//Query passed without throwing an exception, a database therefore already exists
databaseExists = true;
break;
} catch (Exception ex) {
//Do nothing
}
}
//Check if the database has to be created or rebuilt
if (!rebuild && databaseExists) {
return;
}
//Create a DDL generator
SpiEbeanServer serv = (SpiEbeanServer) ebeanServer;
DdlGenerator gen = serv.getDdlGenerator();
//Fire "before drop" event
try {
beforeDropDatabase();
} catch (Exception ex) {
//If the database exists, dropping has to be canceled to prevent data-loss
if (databaseExists) {
throw new RuntimeException("An unexpected exception occured", ex);
}
}
//Generate a DropDDL-script
gen.runScript(true, gen.generateDropDdl());
//If SQLite is being used, the database has to reloaded to release all resources
if (usingSQLite) {
loadDatabase();
}
//Generate a CreateDDL-script
if (usingSQLite) {
//If SQLite is being used, the CreateDLL-script has to be validated and potentially fixed to be valid
gen.runScript(false, validateCreateDDLSqlite(gen.generateCreateDdl()));
} else {
gen.runScript(false, gen.generateCreateDdl());
}
//Fire "after create" event
try {
afterCreateDatabase();
} catch (Exception ex) {
throw new RuntimeException("An unexpected exception occured", ex);
}
}
private String replaceDatabaseString(String input) {
input = input.replaceAll("\\{DIR\\}", javaPlugin.getDataFolder().getPath().replaceAll("\\\\", "/") + '/');
input = input.replaceAll("\\{NAME\\}", javaPlugin.getDescription().getName().replaceAll("[^\\w_-]", ""));
return input;
}
private static String validateCreateDDLSqlite(String oldScript) {
try {
//Create a BufferedReader out of the potentially invalid script
BufferedReader scriptReader = new BufferedReader(new StringReader(oldScript));
//Create an array to store all the lines
List<String> scriptLines = new ArrayList<String>();
//Create some additional variables for keeping track of tables
HashMap<String, Integer> foundTables = new HashMap<String, Integer>();
String currentTable = null;
int tableOffset = 0;
//Loop through all lines
String currentLine;
while ((currentLine = scriptReader.readLine()) != null) {
//Trim the current line to remove trailing spaces
currentLine = currentLine.trim();
//Add the current line to the rest of the lines
scriptLines.add(currentLine.trim());
//Check if the current line is of any use
if (currentLine.startsWith("create table")) {
//Found a table, so get its name and remember the line it has been encountered on
currentTable = currentLine.split(" ", 4)[2];
foundTables.put(currentLine.split(" ", 3)[2], scriptLines.size() - 1);
} else if (!currentLine.isEmpty() && currentLine.charAt(0) == ';' && currentTable != null && !currentTable.isEmpty()) {
//Found the end of a table definition, so update the entry
int index = scriptLines.size() - 1;
foundTables.put(currentTable, index);
//Remove the last ")" from the previous line
String previousLine = scriptLines.get(index - 1);
previousLine = previousLine.substring(0, previousLine.length() - 1);
scriptLines.set(index - 1, previousLine);
//Change ";" to ");" on the current line
scriptLines.set(index, ");");
//Reset the table-tracker
currentTable = null;
} else if (currentLine.startsWith("alter table")) {
//Found a potentially unsupported action
String[] alterTableLine = currentLine.split(" ", 4);
if (alterTableLine[3].startsWith("add constraint")) {
//Found an unsupported action: ALTER TABLE using ADD CONSTRAINT
String[] addConstraintLine = alterTableLine[3].split(" ", 4);
//Check if this line can be fixed somehow
if (addConstraintLine[3].startsWith("foreign key")) {
//Calculate the index of last line of the current table
int tableLastLine = foundTables.get(alterTableLine[2]) + tableOffset;
//Add a "," to the previous line
scriptLines.set(tableLastLine - 1, scriptLines.get(tableLastLine - 1) + ',');
//Add the constraint as a new line - Remove the ";" on the end
String constraintLine = String.format("%s %s %s", addConstraintLine[1], addConstraintLine[2], addConstraintLine[3]);
scriptLines.add(tableLastLine, constraintLine.substring(0, constraintLine.length() - 1));
//Remove this line and raise the table offset because a line has been inserted
scriptLines.remove(scriptLines.size() - 1);
tableOffset++;
} else {
//Exception: This line cannot be fixed but is known the be unsupported by SQLite
throw new RuntimeException("Unsupported action encountered: ALTER TABLE using ADD CONSTRAINT with " + addConstraintLine[3]);
}
}
}
}
//Turn all the lines back into a single string
StringBuilder newScript = new StringBuilder(5);
for (String newLine : scriptLines) {
newScript.append(newLine).append('\n');
}
//Print the new script
System.out.println(newScript);
//Return the fixed script
return newScript.toString();
} catch (Exception ex) {
//Exception: Failed to fix the DDL or something just went plain wrong
throw new RuntimeException("Failed to validate the CreateDDL-script for SQLite", ex);
}
}
private void disableDatabaseLogging(boolean logging) {
//If logging is allowed, nothing has to be changed
if (logging) {
return;
}
//Retrieve the level of the root logger
loggerLevel = Logger.getLogger("").getLevel();
//Set the level of the root logger to OFF
Logger.getLogger("").setLevel(Level.OFF);
}
private void enableDatabaseLogging(boolean logging) {
//If logging is allowed, nothing has to be changed
if (logging) {
return;
}
//Set the level of the root logger back to the original value
Logger.getLogger("").setLevel(loggerLevel);
}
/**
* Get a list of classes which should be registered with the EbeanServer
*
* @return List List of classes which should be registered with the EbeanServer
*/
protected List<Class<?>> getDatabaseClasses() {
return new ArrayList<Class<?>>();
}
/**
* Method called before the loaded database is being dropped
*/
protected void beforeDropDatabase() {}
/**
* Method called after the loaded database has been created
*/
protected void afterCreateDatabase() {}
/**
* Method called near the end of prepareDatabase, before the dataSourceConfig is attached to the serverConfig.
*
* @param dataSourceConfig
* @param serverConfig
*/
protected void prepareDatabaseAdditionalConfig(DataSourceConfig dataSourceConfig, ServerConfig serverConfig) {}
/**
* Get the instance of the EbeanServer
*
* @return EbeanServer Instance of the EbeanServer
*/
public EbeanServer getDatabase() {
return ebeanServer;
}
}