org.opencms.setup.db.update6to7.CmsUpdateDBProjectId Maven / Gradle / Ivy
Show all versions of opencms-test Show documentation
/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software GmbH & Co. KG, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.setup.db.update6to7;
import org.opencms.file.CmsProject;
import org.opencms.security.CmsOrganizationalUnit;
import org.opencms.setup.CmsSetupDBWrapper;
import org.opencms.setup.CmsSetupDb;
import org.opencms.setup.db.A_CmsUpdateDBPart;
import org.opencms.util.CmsUUID;
import java.io.IOException;
import java.sql.Date;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* This class updates the project ids from integer values to CmsUUIDs in all existing database tables.
*
* It creates new UUIDs for each existing project and stores it into a temporary table.
*
* For each table using a project id a new column for the UUID is added and the according data is transferred.
* After that the original indexes and the column for the project id index is dropped and the new column with the
* project uuid becomes the primary key.
*
* @since 7.0.0
*/
public class CmsUpdateDBProjectId extends A_CmsUpdateDBPart {
/** Constant for the sql column PROJECT_ID.
*/
protected static final String COLUMN_PROJECT_ID = "PROJECT_ID";
/** Constant for the sql query to use the column PROJECT_LASTMODIFIED.
*/
protected static final String COLUMN_PROJECT_LASTMODIFIED = "PROJECT_LASTMODIFIED";
/** Constant for the sql column PROJECT_UUID.
*/
protected static final String COLUMN_PROJECT_UUID = "PROJECT_UUID";
/** Constant for the sql column TEMP_PROJECT_UUID.
*/
protected static final String COLUMN_TEMP_PROJECT_UUID = "TEMP_PROJECT_UUID";
/** Constant for the table name of the CMS_HISTORY_PROJECTS table.
*/
protected static final String HISTORY_PROJECTS_TABLE = "CMS_HISTORY_PROJECTS";
/** Constant for the sql query to add a new primary key.
*/
protected static final String QUERY_ADD_PRIMARY_KEY = "Q_ADD_PRIMARY_KEY";
/** Constant for the sql query to add a new column to the table.
*/
protected static final String QUERY_ADD_TEMP_UUID_COLUMN = "Q_ADD_COLUMN";
/** Constant for the sql query to create the new CMS_HISTORY_PROJECTS table.
*/
protected static final String QUERY_CREATE_HISTORY_PROJECTS_TABLE = "Q_CREATE_HISTORY_PROJECTS_TABLE";
/** Constant for the sql query to create the temporary table.
*/
protected static final String QUERY_CREATE_TEMP_TABLE_UUIDS = "Q_CREATE_TEMPORARY_TABLE_UUIDS";
/** Constant for the sql query to describe the given table.
*/
protected static final String QUERY_DESCRIBE_TABLE = "Q_DESCRIBE_TABLE";
/** Constant for the sql query to read max publish tag.
*/
protected static final String QUERY_READ_MAX_PUBTAG = "Q_READ_MAX_PUBTAG";
/** Constant for the replacement in the SQL query for the columnname.
*/
protected static final String REPLACEMENT_COLUMN = "${column}";
/** Constant for the replacement in the SQL query for the new columnname.
*/
protected static final String REPLACEMENT_NEW_COLUMN = "${newcolumn}";
/** Constant for the replacement in the SQL query for old id to update.
*/
protected static final String REPLACEMENT_OLDID = "${oldid}";
/** Constant for the replacement in the SQL query for the primary key.
*/
protected static final String REPLACEMENT_PRIMARY_KEY = "${primarykeycolumn}";
/** Constant for the replacement in the SQL query for the tablename.
*/
protected static final String REPLACEMENT_TABLENAME = "${tablename}";
/** Array of the online and offline resources tables.
*/
protected static final String[] RESOURCE_TABLES = {"CMS_OFFLINE_RESOURCES", "CMS_ONLINE_RESOURCES"};
/** Arraylist for the online and offline resources tables that shall be updated.
*/
protected static final List RESOURCES_TABLES_LIST = Collections.unmodifiableList(
Arrays.asList(RESOURCE_TABLES));
/** Array of the tables that are to be updated. */
protected static final String[] TABLES = {
"CMS_OFFLINE_RESOURCES",
"CMS_ONLINE_RESOURCES",
"CMS_PROJECTRESOURCES",
"CMS_PROJECTS"};
/** Arraylist for the tables that shall be updated.
*/
protected static final List TABLES_LIST = Collections.unmodifiableList(Arrays.asList(TABLES));
/** Constant for the temporary UUID column in the tables. */
protected static final String TEMP_UUID_COLUMN = "TEMP_PROJECT_UUID";
/** Constant for the name of temporary table containing the project ids and uuids.
*/
protected static final String TEMPORARY_TABLE_NAME = "TEMP_PROJECT_UUIDS";
/** Constant for the sql primary key of the CMS_PROJECTRESOURCES table.
*/
private static final String COLUMN_PROJECT_ID_RESOURCE_PATH = "PROJECT_ID,RESOURCE_PATH(255)";
/** Constant for the sql query to drop a given column.
*/
private static final String QUERY_DROP_COLUMN = "Q_DROP_COLUMN";
/** Constant for the sql query to get the project ids.
*/
private static final String QUERY_GET_PROJECT_IDS = "Q_SELECT_PROJECT_IDS";
/** Constant for the sql query to get the uuids and project ids.
*/
private static final String QUERY_GET_UUIDS = "Q_SELECT_UUIDS";
/** Constant for the sql query to insert the data into the CMS_HISTORY_PROJECTS table.
*/
private static final String QUERY_INSERT_CMS_HISTORY_TABLE = "Q_INSERT_CMS_HISTORY_TABLE";
/** Constant for the sql query to insert a pair of values to the temp table.
*/
private static final String QUERY_INSERT_UUIDS = "Q_INSERT_UUIDS_TEMP_TABLE";
/** Constant for the SQL query properties.
*/
private static final String QUERY_PROPERTY_FILE = "cms_projectid_queries.properties";
/** Constant for the sql query to read the id of the administrators group.
*/
private static final String QUERY_READ_ADMIN_GROUP = "Q_READ_ADMIN_GROUP";
/** Constant for the sql query to read the id of the admin user.
*/
private static final String QUERY_READ_ADMIN_USER = "Q_READ_ADMIN_USER";
/** Constant for the sql query to add a rename a column in the table.
*/
private static final String QUERY_RENAME_COLUMN = "Q_RENAME_COLUMN";
/** Constant for the sql query to count the hsitorical projects.
*/
private static final String QUERY_SELECT_COUNT_HISTORY_TABLE = "Q_SELECT_COUNT_HISTORY_TABLE";
/** Constant for the sql query to select the data from the CMS_BACKUP_PROJECTS table.
*/
private static final String QUERY_SELECT_DATA_FROM_BACKUP_PROJECTS = "Q_SELECT_DATA_FROM_BACKUP_PROJECTS";
/** Constant for the sql query to transfer the new uuids to the temporary column.
*/
private static final String QUERY_TRANSFER_UUID = "Q_TRANSFER_UUID";
/** Constant for the sql query to repair lost project ids.
*/
private static final String QUERY_UPDATE_NULL_PROJECTID = "Q_UPDATE_NULL_PROJECTID";
/**
* Constructor.
*
* @throws IOException if the query properties cannot be read
*/
public CmsUpdateDBProjectId()
throws IOException {
super();
loadQueryProperties(getPropertyFileLocation() + QUERY_PROPERTY_FILE);
}
/**
* Adds a new primary key to the given table.
*
* @param dbCon the db connection interface
* @param tablename the table to add the primary key to
* @param primaryKey the new primary key
*
* @throws SQLException if something goes wrong
*/
protected void addPrimaryKey(CmsSetupDb dbCon, String tablename, String primaryKey) throws SQLException {
System.out.println(new Exception().getStackTrace()[0].toString());
if (dbCon.hasTableOrColumn(tablename, null)) {
String query = readQuery(QUERY_ADD_PRIMARY_KEY);
Map replacer = new HashMap();
replacer.put(REPLACEMENT_TABLENAME, tablename);
replacer.put(REPLACEMENT_PRIMARY_KEY, primaryKey);
dbCon.updateSqlStatement(query, replacer, null);
} else {
System.out.println("table " + tablename + " does not exists");
}
}
/**
* Adds the new column for the uuids to a table.
*
* @param dbCon the db connection interface
* @param tablename the table to add the column to
* @param column the new colum to add
*
* @throws SQLException if something goes wrong
*/
protected void addUUIDColumnToTable(CmsSetupDb dbCon, String tablename, String column) throws SQLException {
System.out.println(new Exception().getStackTrace()[0].toString());
if (!dbCon.hasTableOrColumn(tablename, column)) {
String query = readQuery(QUERY_ADD_TEMP_UUID_COLUMN); // Get the query
// if the table is not one of the ONLINE or OFFLINE resources add the new column in the first position
if (!RESOURCES_TABLES_LIST.contains(tablename)) {
query += " FIRST";
}
Map replacer = new HashMap(); // Build the replacements
replacer.put(REPLACEMENT_TABLENAME, tablename);
replacer.put(REPLACEMENT_COLUMN, column);
dbCon.updateSqlStatement(query, replacer, null); // execute the query
} else {
System.out.println("column " + column + " in table " + tablename + " already exists");
}
}
/**
* Check if the column type of the project id is incorrect.
*
* @param type the type of the column from the meta data
*
* @return true if the type is incorrect
*/
protected boolean checkColumnTypeProjectId(int type) {
return type == java.sql.Types.INTEGER;
}
/**
* Creates the CMS_HISTORY_PROJECTS table if it does not exist yet.
*
* @param dbCon the db connection interface
*
* @throws SQLException if soemthing goes wrong
*/
protected void createHistProjectsTable(CmsSetupDb dbCon) throws SQLException {
System.out.println(new Exception().getStackTrace()[0].toString());
if (!dbCon.hasTableOrColumn(HISTORY_PROJECTS_TABLE, null)) {
String createStatement = readQuery(QUERY_CREATE_HISTORY_PROJECTS_TABLE);
dbCon.updateSqlStatement(createStatement, null, null);
transferDataToHistoryTable(dbCon);
} else {
System.out.println("table " + HISTORY_PROJECTS_TABLE + " already exists");
}
}
/**
* Creates the temp table for project ids if it does not exist yet.
*
* @param dbCon the db connection interface
*
* @throws SQLException if soemthing goes wrong
*/
protected void createTempTable(CmsSetupDb dbCon) throws SQLException {
System.out.println(new Exception().getStackTrace()[0].toString());
if (!dbCon.hasTableOrColumn(TEMPORARY_TABLE_NAME, null)) {
String createStatement = readQuery(QUERY_CREATE_TEMP_TABLE_UUIDS);
dbCon.updateSqlStatement(createStatement, null, null);
} else {
System.out.println("table " + TEMPORARY_TABLE_NAME + " already exists");
}
}
/**
* Returns the columns for the primary key of the project resources table.
*
* @return the columns for the primary key of the project resources table
*/
protected String getColumnProjectIdResourcePath() {
return COLUMN_PROJECT_ID_RESOURCE_PATH;
}
/**
* @see org.opencms.setup.db.A_CmsUpdateDBPart#internalExecute(org.opencms.setup.CmsSetupDb)
*/
@Override
protected void internalExecute(CmsSetupDb dbCon) throws SQLException {
System.out.println(new Exception().getStackTrace()[0].toString());
generateUUIDs(dbCon);
createHistProjectsTable(dbCon);
Map uuids = getUUIDs(dbCon); // Get the UUIDS
/*
* Add the temporary column for the new UUIDs and fill it with data
*/
for (Iterator it = TABLES_LIST.iterator(); it.hasNext();) {
String tablename = it.next();
if (needsUpdating(dbCon, tablename)) {
addUUIDColumnToTable(dbCon, tablename, TEMP_UUID_COLUMN);
boolean isInResourcesList = RESOURCES_TABLES_LIST.contains(tablename);
// Add the new uuids
Iterator> entries = uuids.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = entries.next();
if ((entry.getKey() != null) && (entry.getValue() != null)) {
if (isInResourcesList) {
fillUUIDSColumn(
dbCon,
tablename,
TEMP_UUID_COLUMN,
entry.getValue(),
COLUMN_PROJECT_LASTMODIFIED,
entry.getKey());
} else {
fillUUIDSColumn(
dbCon,
tablename,
TEMP_UUID_COLUMN,
entry.getValue(),
COLUMN_PROJECT_ID,
entry.getKey());
}
}
}
/*
* In this phase the primary keys or indexes are dropped and the old columns containing the
* old project ids are dropped. After that the temporary columns are renamed and the new
* indexes and primary keys are added.
*/
if (isInResourcesList) {
// fix lost project ids
Map replacer = Collections.singletonMap("${tablename}", tablename);
List