📄 schemamanager.java
字号:
/**
* $Revision$
* $Date$
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.database;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.wildfire.container.Plugin;
import org.jivesoftware.wildfire.container.PluginManager;
import java.io.*;
import java.sql.*;
import java.util.Arrays;
/**
* Manages database schemas for Wildfire and Wildfire plugins. The manager uses the
* jiveVersion database table to figure out which database schema is currently installed
* and then attempts to automatically apply database schema changes as necessary.<p>
*
* Running database schemas automatically requires appropriate database permissions.
* Without those permissions, the automatic installation/upgrade process will fail
* and users will be prompted to apply database changes manually.
*
* @see DbConnectionManager#getSchemaManager()
*
* @author Matt Tucker
*/
public class SchemaManager {
private static final String CHECK_VERSION_OLD =
"SELECT minorVersion FROM jiveVersion";
private static final String CHECK_VERSION =
"SELECT version FROM jiveVersion WHERE name=?";
/**
* Current Wildfire database schema version.
*/
private static final int DATABASE_VERSION = 10;
/**
* Creates a new Schema manager.
*/
SchemaManager() {
}
/**
* Checks the Wildfire database schema to ensure that it's installed and up to date.
* If the schema isn't present or up to date, an automatic update will be attempted.
*
* @param con a connection to the database.
* @return true if database schema checked out fine, or was automatically installed
* or updated successfully.
*/
public boolean checkWildfireSchema(Connection con) {
try {
return checkSchema(con, "wildfire", DATABASE_VERSION,
new ResourceLoader() {
public InputStream loadResource(String resourceName) {
File file = new File(JiveGlobals.getHomeDirectory() + File.separator +
"resources" + File.separator + "database", resourceName);
try {
return new FileInputStream(file);
}
catch (FileNotFoundException e) {
return null;
}
}
});
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("upgrade.database.failure"), e);
System.out.println(LocaleUtils.getLocalizedString("upgrade.database.failure"));
}
return false;
}
/**
* Checks the plugin's database schema (if one is required) to ensure that it's
* installed and up to date. If the schema isn't present or up to date, an automatic
* update will be attempted.
*
* @param plugin the plugin.
* @return true if database schema checked out fine, or was automatically installed
* or updated successfully, or if it isn't needed. False will only be returned
* if there is an error.
*/
public boolean checkPluginSchema(final Plugin plugin) {
final PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
String schemaKey = pluginManager.getDatabaseKey(plugin);
int schemaVersion = pluginManager.getDatabaseVersion(plugin);
// If the schema key or database version aren't defined, then the plugin doesn't
// need database tables.
if (schemaKey == null || schemaVersion == -1) {
return true;
}
Connection con = null;
try {
con = DbConnectionManager.getConnection();
return checkSchema(con, schemaKey, schemaVersion, new ResourceLoader() {
public InputStream loadResource(String resourceName) {
File file = new File(pluginManager.getPluginDirectory(plugin) +
File.separator + "database", resourceName);
try {
return new FileInputStream(file);
}
catch (FileNotFoundException e) {
return null;
}
}
});
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("upgrade.database.failure"), e);
System.out.println(LocaleUtils.getLocalizedString("upgrade.database.failure"));
}
finally {
DbConnectionManager.closeConnection(con);
}
return false;
}
/**
* Checks to see if the database needs to be upgraded. This method should be
* called once every time the application starts up.
*
* @param con the database connection to use to check the schema with.
* @param schemaKey the database schema key (name).
* @param requiredVersion the version that the schema should be at.
* @param resourceLoader a resource loader that knows how to load schema files.
* @throws Exception if an error occured.
*/
private boolean checkSchema(Connection con, String schemaKey, int requiredVersion,
ResourceLoader resourceLoader) throws Exception
{
int currentVersion = -1;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = con.prepareStatement(CHECK_VERSION);
pstmt.setString(1, schemaKey);
rs = pstmt.executeQuery();
if (rs.next()) {
currentVersion = rs.getInt(1);
}
}
catch (SQLException sqle) {
DbConnectionManager.closeResultSet(rs);
DbConnectionManager.closeStatement(pstmt);
// Releases of Wildfire before 2.6.0 stored a major and minor version
// number so the normal check for version can fail. Check for the
// version using the old format in that case.
if (schemaKey.equals("wildfire")) {
try {
if (pstmt != null) {
pstmt.close();
}
pstmt = con.prepareStatement(CHECK_VERSION_OLD);
rs = pstmt.executeQuery();
if (rs.next()) {
currentVersion = rs.getInt(1);
}
}
catch (SQLException sqle2) {
// The database schema must not be installed.
Log.debug("Error verifying server version", sqle2);
}
}
}
finally {
DbConnectionManager.closeResultSet(rs);
DbConnectionManager.closeStatement(pstmt);
}
// If already up to date, return.
if (currentVersion == requiredVersion) {
return true;
}
// If the database schema isn't installed at all, we need to install it.
else if (currentVersion == -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -