Author: tolusha
Date: 2010-12-15 05:23:42 -0500 (Wed, 15 Dec 2010)
New Revision: 3666
Added:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/TesterRdbmsWorkspaceInitializer.java
Removed:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/RdbmsWorkspaceInitializerWrapper.java
Modified:
jcr/trunk/exo.jcr.component.ext/pom.xml
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/FullBackupJob.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsWorkspaceInitializer.java
Log:
JCR-1097: support restore singleDb->multiDb, mulitDb->SingleDB
Modified: jcr/trunk/exo.jcr.component.ext/pom.xml
===================================================================
--- jcr/trunk/exo.jcr.component.ext/pom.xml 2010-12-14 11:59:31 UTC (rev 3665)
+++ jcr/trunk/exo.jcr.component.ext/pom.xml 2010-12-15 10:23:42 UTC (rev 3666)
@@ -185,9 +185,10 @@
<include>**/replication/*.java</include>
<include>**/replication/external/*.java</include>
<include>**/replication/async/**/*.java</include>
+ <include>**/backup/*.java</include>
</includes>
<excludes>
- <exclude>**/backup/*.java</exclude>
+ <exclude>**/backup/TestRDBMSBackupManager.java</exclude>
<exclude>**/BaseStandaloneTest.java</exclude>
<exclude>**/backup/AbstractBackupTestCase.java</exclude>
<exclude>**/backup/BaseRDBMSBackupTest.java</exclude>
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2010-12-14
11:59:31 UTC (rev 3665)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/BackupManagerImpl.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -54,11 +54,11 @@
import org.exoplatform.services.jcr.ext.backup.RepositoryRestoreExeption;
import org.exoplatform.services.jcr.ext.backup.WorkspaceRestoreException;
import org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob;
+import org.exoplatform.services.jcr.ext.backup.impl.rdbms.RdbmsWorkspaceInitializer;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.ext.registry.RegistryEntry;
import org.exoplatform.services.jcr.ext.registry.RegistryService;
import org.exoplatform.services.jcr.ext.replication.FixupStream;
-import org.exoplatform.services.jcr.impl.core.RdbmsWorkspaceInitializer;
import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.SysViewWorkspaceInitializer;
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java 2010-12-14
11:59:31 UTC (rev 3665)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/JobRepositoryRestore.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -28,7 +28,7 @@
import org.exoplatform.services.jcr.ext.backup.RepositoryBackupChainLog;
import org.exoplatform.services.jcr.ext.backup.RepositoryRestoreExeption;
import org.exoplatform.services.jcr.ext.backup.impl.fs.FullBackupJob;
-import org.exoplatform.services.jcr.impl.core.RdbmsWorkspaceInitializer;
+import org.exoplatform.services.jcr.ext.backup.impl.rdbms.RdbmsWorkspaceInitializer;
import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
import org.exoplatform.services.jcr.impl.core.SessionRegistry;
import org.exoplatform.services.jcr.impl.core.SysViewWorkspaceInitializer;
Modified:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/FullBackupJob.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/FullBackupJob.java 2010-12-14
11:59:31 UTC (rev 3665)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/FullBackupJob.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -20,6 +20,7 @@
import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.config.LockManagerEntry;
import org.exoplatform.services.jcr.config.QueryHandlerParams;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.ValueStorageEntry;
@@ -31,7 +32,6 @@
import org.exoplatform.services.jcr.ext.backup.impl.AbstractFullBackupJob;
import org.exoplatform.services.jcr.ext.backup.impl.FileNameProducer;
import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.RdbmsWorkspaceInitializer;
import
org.exoplatform.services.jcr.impl.core.lock.cacheable.AbstractCacheableLockManager;
import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectWriterImpl;
@@ -57,6 +57,7 @@
import java.sql.SQLException;
import java.sql.Types;
import java.util.Calendar;
+import java.util.List;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
@@ -69,7 +70,51 @@
*/
public class FullBackupJob extends AbstractFullBackupJob
{
+ /**
+ * Index directory in full backup storage.
+ */
+ public static final String INDEX_DIR = "index";
+ /**
+ * System index directory in full backup storage.
+ */
+ public static final String SYSTEM_INDEX_DIR = INDEX_DIR + "_" +
SystemSearchManager.INDEX_DIR_SUFFIX;
+
+ /**
+ * Value storage directory in full backup storage.
+ */
+ public static final String VALUE_STORAGE_DIR = "values";
+
+ /**
+ * Suffix for content file.
+ */
+ public static final String CONTENT_FILE_SUFFIX = ".dump";
+
+ /**
+ * Suffix for content length file.
+ */
+ public static final String CONTENT_LEN_FILE_SUFFIX = ".len";
+
+ /**
+ * Content is absent.
+ */
+ public static final byte NULL_LEN = 0;
+
+ /**
+ * Content length value has byte type.
+ */
+ public static final byte BYTE_LEN = 1;
+
+ /**
+ * Content length value has integer type.
+ */
+ public static final byte INT_LEN = 2;
+
+ /**
+ * Content length value has long type.
+ */
+ public static final byte LONG_LEN = 3;
+
/**
* Logger.
*/
@@ -163,6 +208,7 @@
throw new
RepositoryConfigurationException(JDBCWorkspaceDataContainer.MULTIDB
+ " parameter not found in workspace " + workspaceName + "
configuration");
}
+ boolean isMultiDb = Boolean.parseBoolean(multiDb);
final DataSource ds = (DataSource)new InitialContext().lookup(dsName);
if (ds == null)
@@ -182,50 +228,63 @@
transactionIsolation = jdbcConn.getTransactionIsolation();
jdbcConn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+ RDBMSBackupInfoWriter backupInfoWriter = new
RDBMSBackupInfoWriter(getStorageURL().getFile());
+
+ backupInfoWriter.setRepositoryName(repository.getConfiguration().getName());
+ backupInfoWriter.setWorkspaceName(workspaceName);
+ backupInfoWriter.setMultiDb(isMultiDb);
+
// dump JCR data
String[][] scripts;
- if (Boolean.parseBoolean(multiDb))
+ if (isMultiDb)
{
scripts =
- new String[][]{{"JCR_MVALUE", "select * from
JCR_MVALUE"}, {"JCR_MREF", "select * from JCR_MREF"},
- {"JCR_MITEM", "select * from JCR_MITEM where JCR_MITEM.name
<> '__root_parent'"}};
+ new String[][]{
+ {"JCR_MITEM", "select * from JCR_MITEM where
JCR_MITEM.name <> '" + Constants.ROOT_PARENT_NAME + "'"},
+ {"JCR_MVALUE", "select * from JCR_MVALUE"},
{"JCR_MREF", "select * from JCR_MREF"}};
}
else
{
scripts =
new String[][]{
+ {"JCR_SITEM", "select * from JCR_SITEM where
CONTAINER_NAME='" + workspaceName + "'"},
{
"JCR_SVALUE",
- "select from JCR_SVALUE where exists(select * from JCR_SITEM
where JCR_SITEM.ID=JCR_SVALUE.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME="
- + workspaceName + ")"},
+ "select * from JCR_SVALUE where exists(select * from JCR_SITEM
where JCR_SITEM.ID=JCR_SVALUE.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
+ + workspaceName + "')"},
{
"JCR_SREF",
- "select from JCR_SREF where exists(select * from JCR_SITEM
where JCR_SITEM.ID=JCR_SREF.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME="
- + workspaceName + ")"},
- {"JCR_SITEM", "select from JCR_SITEM where
CONTAINER_NAME=" + workspaceName}};
+ "select * from JCR_SREF where exists(select * from JCR_SITEM
where JCR_SITEM.ID=JCR_SREF.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
+ + workspaceName + "')"}};
}
+ backupInfoWriter.setItemTableName(scripts[0][0]);
+ backupInfoWriter.setValueTableName(scripts[1][0]);
+ backupInfoWriter.setRefTableName(scripts[2][0]);
+
for (String script[] : scripts)
{
dumpTable(jdbcConn, script[0], script[1]);
}
// dump LOCK data
- String lockTableName =
AbstractCacheableLockManager.getLockTableName(workspaceEntry.getLockManager());
- if (lockTableName != null)
+ LockManagerEntry lockEntry = workspaceEntry.getLockManager();
+ if (lockEntry != null)
{
- scripts =
- new String[][]{{lockTableName, "select * from " +
lockTableName},
- {lockTableName + "_D", "select * from " +
lockTableName + "_D"}};
+ List<String> lockTableNames =
AbstractCacheableLockManager.getLockTableNames(lockEntry);
+ backupInfoWriter.setLockTableNames(lockTableNames);
- for (String script[] : scripts)
+ for (String tableName : lockTableNames)
{
- dumpTable(jdbcConn, script[0], script[1]);
+ dumpTable(jdbcConn, tableName,
AbstractCacheableLockManager.getSelectScript(tableName));
}
}
backupValueStorage(workspaceEntry);
backupIndex(workspaceEntry);
+
+ // write backup information
+ backupInfoWriter.write();
}
catch (RepositoryConfigurationException e)
{
@@ -302,7 +361,7 @@
}
else
{
- File destDir = new File(getStorageURL().getFile(),
RdbmsWorkspaceInitializer.INDEX_DIR);
+ File destDir = new File(getStorageURL().getFile(), INDEX_DIR);
copyDirectory(srcDir, destDir);
}
@@ -317,7 +376,7 @@
}
else
{
- File destDir = new File(getStorageURL().getFile(),
RdbmsWorkspaceInitializer.SYSTEM_INDEX_DIR);
+ File destDir = new File(getStorageURL().getFile(), SYSTEM_INDEX_DIR);
copyDirectory(srcDir, destDir);
}
}
@@ -347,7 +406,7 @@
}
else
{
- File destValuesDir = new File(getStorageURL().getFile(),
RdbmsWorkspaceInitializer.VALUE_STORAGE_DIR);
+ File destValuesDir = new File(getStorageURL().getFile(),
VALUE_STORAGE_DIR);
File destDir = new File(destValuesDir, valueStorage.getId());
copyDirectory(srcDir, destDir);
@@ -370,12 +429,10 @@
ResultSet rs = null;
try
{
- File contentFile =
- new File(getStorageURL().getFile(), tableName +
RdbmsWorkspaceInitializer.CONTENT_FILE_SUFFIX);
+ File contentFile = new File(getStorageURL().getFile(), tableName +
CONTENT_FILE_SUFFIX);
contentWriter = new
ObjectWriterImpl(PrivilegedFileHelper.fileOutputStream(contentFile));
- File contentLenFile =
- new File(getStorageURL().getFile(), tableName +
RdbmsWorkspaceInitializer.CONTENT_LEN_FILE_SUFFIX);
+ File contentLenFile = new File(getStorageURL().getFile(), tableName +
CONTENT_LEN_FILE_SUFFIX);
contentLenWriter = new
ObjectWriterImpl(PrivilegedFileHelper.fileOutputStream(contentLenFile));
stmt = jdbcConn.prepareStatement(script);
@@ -418,7 +475,7 @@
if (value == null)
{
- contentLenWriter.writeByte(RdbmsWorkspaceInitializer.NULL_LEN);
+ contentLenWriter.writeByte(NULL_LEN);
}
else
{
@@ -467,17 +524,17 @@
{
if (len < Byte.MAX_VALUE)
{
- out.writeByte(RdbmsWorkspaceInitializer.BYTE_LEN);
+ out.writeByte(BYTE_LEN);
out.writeByte((byte)len);
}
else if (len < Integer.MAX_VALUE)
{
- out.writeByte(RdbmsWorkspaceInitializer.INT_LEN);
+ out.writeByte(INT_LEN);
out.writeInt((int)len);
}
else
{
- out.writeByte(RdbmsWorkspaceInitializer.LONG_LEN);
+ out.writeByte(LONG_LEN);
out.writeLong(len);
}
}
Copied:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java
(from rev 3662,
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/RdbmsBackupWorkspaceInitializer.java)
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,
see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.ext.backup.impl.rdbms;
+
+import org.exoplatform.services.jcr.access.AccessManager;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.LocationFactory;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
+import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
+import
org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2010
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex
Reshetnyak</a>
+ * @version $Id$
+ */
+public class RdbmsBackupWorkspaceInitializer extends RdbmsWorkspaceInitializer
+{
+ /**
+ * Logger.
+ */
+ protected static final Log log =
ExoLogger.getLogger("exo.jcr.component.core.RdbmsBackupWorkspaceInitializer");
+
+ /**
+ * Constructor RdbmsBackupWorkspaceInitializer.
+ */
+ public RdbmsBackupWorkspaceInitializer(WorkspaceEntry config, RepositoryEntry
repConfig,
+ CacheableWorkspaceDataManager dataManager, NamespaceRegistryImpl
namespaceRegistry,
+ LocationFactory locationFactory, NodeTypeManagerImpl nodeTypeManager,
ValueFactoryImpl valueFactory,
+ AccessManager accessManager) throws RepositoryConfigurationException,
PathNotFoundException, RepositoryException
+ {
+ super(config, repConfig, dataManager, namespaceRegistry, locationFactory,
nodeTypeManager, valueFactory,
+ accessManager);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NodeData initWorkspace() throws RepositoryException
+ {
+ if (isWorkspaceInitialized())
+ {
+ return (NodeData)dataManager.getItemData(Constants.ROOT_UUID);
+ }
+
+ long start = System.currentTimeMillis();
+
+ // restore from full rdbms backup
+ fullRdbmsRestore();
+
+ // restore from incremental backup
+ incrementalRead();
+
+ final NodeData root = (NodeData)dataManager.getItemData(Constants.ROOT_UUID);
+
+ log.info("Workspace [" + workspaceName + "] restored from storage
" + restorePath + " in "
+ + (System.currentTimeMillis() - start) * 1d / 1000 + "sec");
+
+ return root;
+ }
+
+}
Property changes on:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsBackupWorkspaceInitializer.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied:
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java
(from rev 3662,
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/RdbmsWorkspaceInitializer.java)
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.ext/src/main/java/org/exoplatform/services/jcr/ext/backup/impl/rdbms/RdbmsWorkspaceInitializer.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -0,0 +1,1065 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This 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 software 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.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.ext.backup.impl.rdbms;
+
+import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.access.AccessManager;
+import org.exoplatform.services.jcr.config.LockManagerEntry;
+import org.exoplatform.services.jcr.config.QueryHandlerParams;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.config.ValueStorageEntry;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.dataflow.serialization.ObjectReader;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.BackupWorkspaceInitializer;
+import org.exoplatform.services.jcr.impl.core.LocationFactory;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+import
org.exoplatform.services.jcr.impl.core.lock.cacheable.AbstractCacheableLockManager;
+import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
+import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
+import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
+import
org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
+import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectReaderImpl;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
+import org.exoplatform.services.jcr.impl.storage.value.fs.FileValueStorage;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+/**
+ * @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy
Bazko</a>
+ * @version $Id: RdbmsWorkspaceInitializer.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class RdbmsWorkspaceInitializer extends BackupWorkspaceInitializer
+{
+ /**
+ * Logger.
+ */
+ protected static final Log log =
ExoLogger.getLogger("exo.jcr.component.core.RdbmsWorkspaceInitializer");
+
+
+ /**
+ * List of temporary files.
+ */
+ protected List<File> spoolFileList = new ArrayList<File>();
+
+ /**
+ * Constructor RdbmsWorkspaceInitializer.
+ */
+ public RdbmsWorkspaceInitializer(WorkspaceEntry config, RepositoryEntry repConfig,
+ CacheableWorkspaceDataManager dataManager, NamespaceRegistryImpl
namespaceRegistry,
+ LocationFactory locationFactory, NodeTypeManagerImpl nodeTypeManager,
ValueFactoryImpl valueFactory,
+ AccessManager accessManager) throws RepositoryConfigurationException,
PathNotFoundException, RepositoryException
+ {
+ super(config, repConfig, dataManager, namespaceRegistry, locationFactory,
nodeTypeManager, valueFactory,
+ accessManager);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public NodeData initWorkspace() throws RepositoryException
+ {
+ if (isWorkspaceInitialized())
+ {
+ return (NodeData)dataManager.getItemData(Constants.ROOT_UUID);
+ }
+
+ long start = System.currentTimeMillis();
+
+ fullRdbmsRestore();
+
+ final NodeData root = (NodeData)dataManager.getItemData(Constants.ROOT_UUID);
+
+ log.info("Workspace [" + workspaceName + "] restored from storage
" + restorePath + " in "
+ + (System.currentTimeMillis() - start) * 1d / 1000 + "sec");
+
+ return root;
+ }
+
+ /**
+ * Restore from full rdbms backup.
+ */
+ protected void fullRdbmsRestore() throws RepositoryException
+ {
+ Connection jdbcConn = null;
+ Integer transactionIsolation = null;
+ Statement st = null;
+ try
+ {
+ String dsName =
workspaceEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.SOURCE_NAME);
+ if (dsName == null)
+ {
+ throw new RepositoryConfigurationException("Data source name not found
in workspace configuration "
+ + workspaceName);
+ }
+
+ String multiDb =
workspaceEntry.getContainer().getParameterValue(JDBCWorkspaceDataContainer.MULTIDB);
+ if (multiDb == null)
+ {
+ throw new
RepositoryConfigurationException(JDBCWorkspaceDataContainer.MULTIDB
+ + " parameter not found in workspace " + workspaceName + "
configuration");
+ }
+ boolean isMultiDb = Boolean.parseBoolean(multiDb);
+
+ final DataSource ds = (DataSource)new InitialContext().lookup(dsName);
+ if (ds == null)
+ {
+ throw new NameNotFoundException("Data source " + dsName + "
not found");
+ }
+
+ jdbcConn = SecurityHelper.doPriviledgedSQLExceptionAction(new
PrivilegedExceptionAction<Connection>()
+ {
+ public Connection run() throws Exception
+ {
+ return ds.getConnection();
+
+ }
+ });
+
+ transactionIsolation = jdbcConn.getTransactionIsolation();
+ jdbcConn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+
+ jdbcConn.setAutoCommit(false);
+
+ RDBMSBackupInfoReader backupInfo = new RDBMSBackupInfoReader(restorePath);
+
+ // restore JCR data
+ Integer[] tableTypes =
+ new Integer[]{RestoreTableHelper.ITEM_TABLE, RestoreTableHelper.VALUE_TABLE,
RestoreTableHelper.REF_TABLE};
+
+ for (Integer tableType : tableTypes)
+ {
+ RestoreTableHelper helper = new RestoreTableHelper(tableType, isMultiDb,
backupInfo);
+
+ if (tableType == RestoreTableHelper.ITEM_TABLE)
+ {
+ // resolve constraint name depends on database
+ String constraintName;
+ String dbDialect = DialectDetecter.detect(jdbcConn.getMetaData());
+
+ if (dbDialect.equals(DBConstants.DB_DIALECT_DB2) ||
dbDialect.equals(DBConstants.DB_DIALECT_DB2V8))
+ {
+ constraintName = "JCR_FK_" + (Boolean.parseBoolean(multiDb) ?
"M" : "S") + "ITEM_PAREN";
+ }
+ else
+ {
+ constraintName = "JCR_FK_" + (Boolean.parseBoolean(multiDb) ?
"M" : "S") + "ITEM_PARENT";
+ }
+ String constraint =
+ "CONSTRAINT " + constraintName + " FOREIGN
KEY(PARENT_ID) REFERENCES " + helper.getTableName()
+ + "(ID)";
+
+ // drop constraint
+ st = jdbcConn.createStatement();
+ st.execute("ALTER TABLE " + helper.getTableName() + " DROP
CONSTRAINT " + constraintName);
+ jdbcConn.commit();
+
+ restoreTable(jdbcConn, helper);
+
+ // add constraint
+ st = jdbcConn.createStatement();
+ st.execute("ALTER TABLE " + helper.getTableName() + " ADD
" + constraint);
+ jdbcConn.commit();
+ }
+ else
+ {
+ if (PrivilegedFileHelper.exists(helper.getContentFile()))
+ {
+ restoreTable(jdbcConn, helper);
+ }
+ else
+ {
+ throw new IOException("File " +
PrivilegedFileHelper.getCanonicalPath(helper.getContentFile())
+ + " not found");
+ }
+ }
+ }
+
+ // restore Lock data
+ LockManagerEntry lockEntry = workspaceEntry.getLockManager();
+ if (lockEntry != null)
+ {
+ List<String> existedLockTablesNames =
AbstractCacheableLockManager.getLockTableNames(lockEntry);
+ if (existedLockTablesNames.size() != backupInfo.getLockTableNames().size())
+ {
+ throw new RepositoryException("The amount of existed lock tables
differs from backup");
+ }
+
+ for (int i = 0; i < backupInfo.getLockTableNames().size(); i++)
+ {
+ RestoreTableHelper helper = new
RestoreTableHelper(RestoreTableHelper.LOCK_TABLE, isMultiDb, backupInfo);
+
+ helper.setContentFile(new File(restorePath,
backupInfo.getLockTableNames().get(i)
+ + FullBackupJob.CONTENT_FILE_SUFFIX));
+ helper.setContentLenFile(new File(restorePath,
backupInfo.getLockTableNames().get(i)
+ + FullBackupJob.CONTENT_LEN_FILE_SUFFIX));
+ helper.setTableName(existedLockTablesNames.get(i));
+
+ if (PrivilegedFileHelper.exists(helper.contentFile))
+ {
+ restoreTable(jdbcConn, helper);
+ }
+ else
+ {
+ throw new IOException("File " +
PrivilegedFileHelper.getCanonicalPath(helper.contentFile)
+ + " not found");
+ }
+ }
+ }
+ else if (backupInfo.getLockTableNames().size() != 0)
+ {
+ throw new RepositoryException("There are no lock tables for new
workspace configuration [" + workspaceName
+ + "] but backup lock data exist");
+ }
+
+ // restore value storage and index
+ restoreValueStorage();
+ restoreIndex();
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ throw new RepositoryException(e);
+ }
+ catch (NamingException e)
+ {
+ throw new RepositoryException(e);
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException(e);
+ }
+ catch (SQLException e)
+ {
+ if (jdbcConn != null)
+ {
+ try
+ {
+ jdbcConn.rollback();
+ }
+ catch (SQLException e1)
+ {
+ log.error("Rollback error", e1);
+ }
+ }
+
+ SQLException next = e.getNextException();
+ String errorTrace = "";
+ while (next != null)
+ {
+ errorTrace += next.getMessage() + "; ";
+ next = next.getNextException();
+ }
+
+ Throwable cause = e.getCause();
+ String msg = "SQL Exception: " + errorTrace + (cause != null ? "
(Cause: " + cause.getMessage() + ")" : "");
+
+ throw new RepositoryException(msg, e);
+ }
+ finally
+ {
+ if (st != null)
+ {
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+
+ if (jdbcConn != null)
+ {
+ try
+ {
+ if (transactionIsolation != null)
+ {
+ jdbcConn.setTransactionIsolation(transactionIsolation);
+ }
+
+ jdbcConn.close();
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Restore index from backup.
+ */
+ protected void restoreIndex() throws RepositoryConfigurationException, IOException
+ {
+ File indexDir = new File(restorePath, FullBackupJob.INDEX_DIR);
+ File systemIndexDir = new File(restorePath, FullBackupJob.SYSTEM_INDEX_DIR);
+
+ if (workspaceEntry.getQueryHandler() != null)
+ {
+ if (!PrivilegedFileHelper.exists(indexDir))
+ {
+ throw new RepositoryConfigurationException("Can't restore index.
Directory " + indexDir.getName()
+ + " doesn't exists");
+ }
+ else
+ {
+ File destDir =
+ new
File(workspaceEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR));
+ copyDirectory(indexDir, destDir);
+ }
+
+ // try to restore system index
+ if (repositoryEntry.getSystemWorkspaceName().equals(workspaceName))
+ {
+ if (!PrivilegedFileHelper.exists(systemIndexDir))
+ {
+ throw new RepositoryConfigurationException("Can't restore system
index. Directory "
+ + systemIndexDir.getName() + " doesn't exists");
+ }
+ else
+ {
+ File destDir =
+ new
File(workspaceEntry.getQueryHandler().getParameterValue(QueryHandlerParams.PARAM_INDEX_DIR)
+ "_"
+ + SystemSearchManager.INDEX_DIR_SUFFIX);
+ copyDirectory(systemIndexDir, destDir);
+ }
+ }
+ else if (PrivilegedFileHelper.exists(systemIndexDir))
+ {
+ throw new RepositoryConfigurationException("Workspace [" +
workspaceName
+ + "] is not a system in repository configuration but system index
backup files exist");
+ }
+ }
+ else
+ {
+ if (PrivilegedFileHelper.exists(indexDir) ||
PrivilegedFileHelper.exists(systemIndexDir))
+ {
+ throw new RepositoryConfigurationException("Query handler didn't
configure in workspace [" + workspaceName
+ + "] configuration but index backup files exist");
+ }
+ }
+ }
+
+ /**
+ * Rollback changes due to errors.
+ */
+ protected void rollback(Connection jdbcConn)
+ {
+ // TODO
+ }
+
+ /**
+ * Restoring value storage from backup.
+ */
+ protected void restoreValueStorage() throws RepositoryConfigurationException,
IOException
+ {
+ File backupValueStorageDir = new File(restorePath,
FullBackupJob.VALUE_STORAGE_DIR);
+ if (workspaceEntry.getContainer().getValueStorages() != null)
+ {
+ List<ValueStorageEntry> valueStorages =
workspaceEntry.getContainer().getValueStorages();
+ String[] valueStoragesFiles = PrivilegedFileHelper.list(backupValueStorageDir);
+
+ if ((valueStoragesFiles == null && valueStorages.size() != 0)
+ || (valueStoragesFiles != null && valueStoragesFiles.length !=
valueStorages.size()))
+ {
+ throw new RepositoryConfigurationException("Workspace configuration
[" + workspaceName
+ + "] has a different amount of value storages than exist in
backup");
+ }
+
+ for (ValueStorageEntry valueStorage : valueStorages)
+ {
+ File srcDir = new File(backupValueStorageDir, valueStorage.getId());
+ if (!PrivilegedFileHelper.exists(srcDir))
+ {
+ throw new RepositoryConfigurationException("Can't restore value
storage. Directory " + srcDir.getName()
+ + " doesn't exists");
+ }
+ else
+ {
+ File destDir = new
File(valueStorage.getParameterValue(FileValueStorage.PATH));
+
+ copyDirectory(srcDir, destDir);
+ }
+ }
+ }
+ else
+ {
+ if (PrivilegedFileHelper.exists(backupValueStorageDir))
+ {
+ throw new RepositoryConfigurationException("Value storage didn't
configure in workspace [" + workspaceName
+ + "] configuration but value storage backup files exist");
+ }
+ }
+ }
+
+ /**
+ * Copy directory.
+ *
+ * @param srcPath
+ * source path
+ * @param dstPath
+ * destination path
+ * @throws IOException
+ * if any exception occurred
+ */
+ private void copyDirectory(File srcPath, File dstPath) throws IOException
+ {
+ if (PrivilegedFileHelper.isDirectory(srcPath))
+ {
+ if (!PrivilegedFileHelper.exists(dstPath))
+ {
+ PrivilegedFileHelper.mkdirs(dstPath);
+ }
+
+ String files[] = PrivilegedFileHelper.list(srcPath);
+ for (int i = 0; i < files.length; i++)
+ {
+ copyDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]));
+ }
+ }
+ else
+ {
+ InputStream in = null;
+ OutputStream out = null;
+
+ try
+ {
+ in = PrivilegedFileHelper.fileInputStream(srcPath);
+ out = PrivilegedFileHelper.fileOutputStream(dstPath);
+
+ // Transfer bytes from in to out
+ byte[] buf = new byte[2048];
+
+ int len;
+
+ while ((len = in.read(buf)) > 0)
+ {
+ out.write(buf, 0, len);
+ }
+ }
+ finally
+ {
+ if (in != null)
+ {
+ in.close();
+ }
+
+ if (out != null)
+ {
+ out.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * Restore table.
+ */
+ protected void restoreTable(Connection jdbcConn, RestoreTableHelper helper)
+ throws IOException, SQLException
+ {
+ String insertNodeQuery = null;
+
+ ObjectReader contentReader = null;
+ ObjectReader contentLenReader = null;
+
+ PreparedStatement insertNode = null;
+ ResultSet tableMetaData = null;
+
+ int dialect = DialectDetecter.detect(jdbcConn.getMetaData()).hashCode();
+
+ try
+ {
+ contentReader = new
ObjectReaderImpl(PrivilegedFileHelper.fileInputStream(helper.contentFile));
+ contentLenReader = new
ObjectReaderImpl(PrivilegedFileHelper.fileInputStream(helper.contentLenFile));
+
+ // get information about backup table
+ int sourceColumnCount = contentReader.readInt();
+
+ List<Integer> columnType = new ArrayList<Integer>();
+ List<String> columnName = new ArrayList<String>();
+
+ for (int i = 0; i < sourceColumnCount; i++)
+ {
+ columnType.add(contentReader.readInt());
+ columnName.add(contentReader.readString());
+ }
+
+ // collect information about target table
+ List<Integer> newColumnType = new ArrayList<Integer>();
+ List<String> newColumnName = new ArrayList<String>();
+
+ tableMetaData = jdbcConn.getMetaData().getColumns(null, null, helper.tableName,
"%");
+ while (tableMetaData.next())
+ {
+ newColumnName.add(tableMetaData.getString("COLUMN_NAME"));
+ newColumnType.add(tableMetaData.getInt("DATA_TYPE"));
+ }
+
+ // construct query
+ int targetColumnCount = sourceColumnCount;
+ if (helper.getSkipColumnIndex() != null)
+ {
+ targetColumnCount--;
+ }
+ else if (helper.getNewColumnIndex() != null)
+ {
+ targetColumnCount++;
+ columnType.add(helper.getNewColumnIndex(),
newColumnType.get((helper.getNewColumnIndex())));
+ }
+
+ for (int i = 0; i < targetColumnCount; i++)
+ {
+ if (i == 0)
+ {
+ insertNodeQuery = "INSERT INTO " + helper.getTableName() +
" VALUES(?";
+ }
+ else
+ {
+ insertNodeQuery += ",?";
+ }
+
+ if (i == targetColumnCount - 1)
+ {
+ insertNodeQuery += ")";
+ }
+ }
+ insertNode = jdbcConn.prepareStatement(insertNodeQuery);
+
+ // set data
+ outer : while (true)
+ {
+ for (int i = 0, targetIndex = 0; i < columnType.size(); i++,
targetIndex++)
+ {
+ InputStream stream;
+ long len;
+
+ if (helper.getNewColumnIndex() != null &&
helper.getNewColumnIndex() == i)
+ {
+ stream = new
ByteArrayInputStream(workspaceName.getBytes(Constants.DEFAULT_ENCODING));
+ len = ((ByteArrayInputStream)stream).available();
+ }
+ else
+ {
+ try
+ {
+ len = readCompressedContentLen(contentLenReader);
+ }
+ catch (EOFException e)
+ {
+ if (i == 0)
+ {
+ // content length file is empty check content file
+ try
+ {
+ contentReader.readByte();
+ }
+ catch (EOFException e1)
+ {
+ break outer;
+ }
+ }
+
+ throw new IOException("Content length file is empty but content
still present", e);
+ }
+ stream = spoolInputStream(contentReader, len);
+ }
+
+ if (helper.getSkipColumnIndex() != null &&
helper.getSkipColumnIndex() == i)
+ {
+ targetIndex--;
+ continue;
+ }
+ else if (helper.getConvertColumnIndexes().contains(i))
+ {
+ ByteArrayInputStream ba = (ByteArrayInputStream)stream;
+ byte[] readBuffer = new byte[ba.available()];
+ ba.read(readBuffer);
+
+ String currentValue = new String(readBuffer,
Constants.DEFAULT_ENCODING);
+ if (currentValue.equals(Constants.ROOT_PARENT_UUID))
+ {
+ stream = new
ByteArrayInputStream(Constants.ROOT_PARENT_UUID.getBytes());
+ }
+ else
+ {
+ if (!helper.isMultiDb && helper.isBackupMutliDb())
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(workspaceName);
+ builder.append(currentValue);
+
+ stream = new
ByteArrayInputStream(builder.toString().getBytes());
+ }
+ else
+ {
+ stream =
+ new ByteArrayInputStream(new String(readBuffer,
Constants.DEFAULT_ENCODING).substring(
+ helper.getBackupWorkspaceName().length()).getBytes());
+ }
+ }
+
+ len = ((ByteArrayInputStream)stream).available();
+ }
+
+ // set
+ if (len != FullBackupJob.NULL_LEN)
+ {
+ if (columnType.get(i) == Types.INTEGER || columnType.get(i) ==
Types.BIGINT
+ || columnType.get(i) == Types.SMALLINT || columnType.get(i) ==
Types.TINYINT)
+ {
+ ByteArrayInputStream ba = (ByteArrayInputStream)stream;
+ byte[] readBuffer = new byte[ba.available()];
+ ba.read(readBuffer);
+
+ String value = new String(readBuffer, Constants.DEFAULT_ENCODING);
+ insertNode.setLong(targetIndex + 1, Integer.parseInt(value));
+ }
+ else if (columnType.get(i) == Types.BIT)
+ {
+ ByteArrayInputStream ba = (ByteArrayInputStream)stream;
+ byte[] readBuffer = new byte[ba.available()];
+ ba.read(readBuffer);
+
+ String value = new String(readBuffer);
+ insertNode.setBoolean(targetIndex + 1,
value.equals("t"));
+ }
+ else if (columnType.get(i) == Types.BOOLEAN)
+ {
+ ByteArrayInputStream ba = (ByteArrayInputStream)stream;
+ byte[] readBuffer = new byte[ba.available()];
+ ba.read(readBuffer);
+
+ String value = new String(readBuffer);
+ insertNode.setBoolean(targetIndex + 1,
value.equals("true"));
+ }
+ else
+ {
+ if (dialect == FullBackupJob.DB_DIALECT_HSQLDB)
+ {
+ if (columnType.get(i) == Types.VARBINARY)
+ {
+ insertNode.setBinaryStream(targetIndex + 1, stream,
(int)len);
+ }
+ else
+ {
+ byte[] readBuffer = new byte[(int)len];
+ stream.read(readBuffer);
+
+ insertNode.setString(targetIndex + 1, new String(readBuffer,
Constants.DEFAULT_ENCODING));
+ }
+ }
+ else
+ {
+ insertNode.setBinaryStream(targetIndex + 1, stream, (int)len);
+ }
+ }
+ }
+ else
+ {
+ insertNode.setNull(targetIndex + 1, columnType.get(i));
+ }
+ }
+ insertNode.addBatch();
+ }
+
+ insertNode.executeBatch();
+ jdbcConn.commit();
+ }
+ finally
+ {
+ if (contentReader != null)
+ {
+ contentReader.close();
+ }
+
+ if (contentLenReader != null)
+ {
+ contentLenReader.close();
+ }
+
+ if (insertNode != null)
+ {
+ insertNode.close();
+ }
+
+ // delete all temporary files
+ for (File file : spoolFileList)
+ {
+ if (!PrivilegedFileHelper.delete(file))
+ {
+ fileCleaner.addFile(file);
+ }
+ }
+
+ if (tableMetaData != null)
+ {
+ tableMetaData.close();
+ }
+ }
+ }
+
+ /**
+ * Write content length in output.
+ */
+ private long readCompressedContentLen(ObjectReader in) throws IOException
+ {
+ byte lenType = in.readByte();
+
+ if (lenType == FullBackupJob.NULL_LEN)
+ {
+ return lenType;
+ }
+ else if (lenType == FullBackupJob.BYTE_LEN)
+ {
+ return in.readByte();
+ }
+ else if (lenType == FullBackupJob.INT_LEN)
+ {
+ return in.readInt();
+ }
+ else
+ {
+ throw new RuntimeException("Does not support to restore value more than
2G.");
+ }
+ }
+
+ /**
+ * Spool input stream.
+ */
+ private InputStream spoolInputStream(ObjectReader in, long contentLen) throws
IOException
+ {
+ byte[] buffer = new byte[0];
+ byte[] tmpBuff;
+ long readLen = 0;
+ File sf = null;
+ OutputStream sfout = null;
+
+ try
+ {
+ while (true)
+ {
+ int needToRead = contentLen - readLen > 2048 ? 2048 : (int)(contentLen -
readLen);
+ tmpBuff = new byte[needToRead];
+
+ if (needToRead == 0)
+ {
+ break;
+ }
+
+ in.readFully(tmpBuff);
+
+ if (sfout != null)
+ {
+ sfout.write(tmpBuff);
+ }
+ else if (readLen + needToRead > maxBufferSize)
+ {
+ sf = PrivilegedFileHelper.createTempFile("jcrvd", null,
tempDir);
+ sfout = PrivilegedFileHelper.fileOutputStream(sf);
+
+ sfout.write(buffer);
+ sfout.write(tmpBuff);
+ buffer = null;
+ }
+ else
+ {
+ // reallocate new buffer and spool old buffer contents
+ byte[] newBuffer = new byte[(int)(readLen + needToRead)];
+ System.arraycopy(buffer, 0, newBuffer, 0, (int)readLen);
+ System.arraycopy(tmpBuff, 0, newBuffer, (int)readLen, needToRead);
+ buffer = newBuffer;
+ }
+
+ readLen += needToRead;
+ }
+
+ if (buffer != null)
+ {
+ return new ByteArrayInputStream(buffer);
+ }
+ else
+ {
+ return PrivilegedFileHelper.fileInputStream(sf);
+ }
+ }
+ finally
+ {
+ if (sfout != null)
+ {
+ sfout.close();
+ }
+
+ if (sf != null)
+ {
+ spoolFileList.add(sf);
+ }
+ }
+ }
+
+ /**
+ * Class which helps to restore data.
+ */
+ protected class RestoreTableHelper
+ {
+ public static final int ITEM_TABLE = 0;
+
+ public static final int VALUE_TABLE = 1;
+
+ public static final int REF_TABLE = 2;
+
+ public static final int LOCK_TABLE = 3;
+
+ private String tableName;
+
+ private File contentFile;
+
+ private File contentLenFile;
+
+ private Integer skipColumnIndex = null;
+
+ private Integer newColumnIndex = null;
+
+ private Set<Integer> convertColumnIndex = new HashSet<Integer>();
+
+ private final boolean isMultiDb;
+
+ private final RDBMSBackupInfoReader backupInfo;
+
+ public RestoreTableHelper(int tableType, boolean isMultiDb, RDBMSBackupInfoReader
backupInfo)
+ throws IOException
+ {
+ this.backupInfo = backupInfo;
+ this.isMultiDb = isMultiDb;
+
+ if (tableType == ITEM_TABLE)
+ {
+ contentFile = new File(restorePath, backupInfo.getItemTableName() +
FullBackupJob.CONTENT_FILE_SUFFIX);
+ contentLenFile =
+ new File(restorePath, backupInfo.getItemTableName() +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX);
+
+ tableName = "JCR_" + (isMultiDb ? "M" : "S") +
"ITEM";
+
+ if (isMultiDb)
+ {
+ tableName = "JCR_MITEM";
+ if (!backupInfo.isMultiDb())
+ {
+ // CONTAINER_NAME column index
+ skipColumnIndex = 4;
+
+ // ID and PARENT_ID column indexes
+ convertColumnIndex.add(0);
+ convertColumnIndex.add(1);
+ }
+ }
+ else
+ {
+ tableName = "JCR_SITEM";
+ if (backupInfo.isMultiDb())
+ {
+ // CONTAINER_NAME column index
+ newColumnIndex = 4;
+
+ // ID and PARENT_ID column indexes
+ convertColumnIndex.add(0);
+ convertColumnIndex.add(1);
+ }
+ }
+
+ }
+ else if (tableType == VALUE_TABLE)
+ {
+ contentFile = new File(restorePath, backupInfo.getValueTableName() +
FullBackupJob.CONTENT_FILE_SUFFIX);
+ contentLenFile =
+ new File(restorePath, backupInfo.getValueTableName() +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX);
+
+ tableName = "JCR_" + (isMultiDb ? "M" : "S") +
"VALUE";
+
+ if (isMultiDb != backupInfo.isMultiDb())
+ {
+ // PROPERTY_ID column index
+ convertColumnIndex.add(3);
+ }
+ }
+ else if (tableType == REF_TABLE)
+ {
+ contentFile = new File(restorePath, backupInfo.getRefTableName() +
FullBackupJob.CONTENT_FILE_SUFFIX);
+ contentLenFile =
+ new File(restorePath, backupInfo.getRefTableName() +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX);
+
+ tableName = "JCR_" + (isMultiDb ? "M" : "S") +
"REF";
+
+ if (isMultiDb != backupInfo.isMultiDb())
+ {
+ // NODE_ID and PROPERTY_ID column indexes
+ convertColumnIndex.add(0);
+ convertColumnIndex.add(1);
+ }
+ }
+ }
+
+ /**
+ * Returns the table name for restore.
+ *
+ * @return table name
+ */
+ public String getTableName()
+ {
+ return tableName;
+ }
+
+ /**
+ * Returns the content file for restore.
+ *
+ * @return file
+ */
+ public File getContentFile()
+ {
+ return contentFile;
+ }
+
+ /**
+ * Returns the content length file for restore.
+ *
+ * @return file
+ */
+ public File getContentLenFile()
+ {
+ return contentLenFile;
+ }
+
+ /**
+ * Set table name for restore.
+ */
+ public void setTableName(String tableName)
+ {
+ this.tableName = tableName;
+ }
+
+ /**
+ * Set content file for restore.
+ */
+ public void setContentFile(File file)
+ {
+ this.contentFile = file;
+ }
+
+ /**
+ * Set content length file for restore.
+ */
+ public void setContentLenFile(File file)
+ {
+ this.contentLenFile = file;
+ }
+
+ /**
+ * Returns index of column which should be skipped during restore.
+ *
+ * @return Integer
+ */
+ public Integer getSkipColumnIndex()
+ {
+ return skipColumnIndex;
+ }
+
+ /**
+ * Returns index of column which should be added during restore.
+ *
+ * @return Integer
+ */
+ public Integer getNewColumnIndex()
+ {
+ return newColumnIndex;
+ }
+
+ /**
+ * Returns indexes of columns which should be converted during restore.
+ *
+ * @return Integer
+ */
+ public Set<Integer> getConvertColumnIndexes()
+ {
+ return convertColumnIndex;
+ }
+
+ /**
+ * Returns the target workspace name for restore.
+ *
+ * @return workspace name
+ */
+ public boolean isMultiDb()
+ {
+ return isMultiDb;
+ }
+
+ /**
+ * Returns the original workspace name where backup was performed.
+ *
+ * @return workspace name
+ */
+ public String getBackupWorkspaceName()
+ {
+ return backupInfo.getWorkspaceName();
+ }
+
+ /**
+ * Returns the original value of multi-db parameter of workspace from which backup
was performed.
+ *
+ * @return multi-db parameter
+ */
+ public boolean isBackupMutliDb()
+ {
+ return backupInfo.isMultiDb();
+ }
+ }
+}
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java 2010-12-14
11:59:31 UTC (rev 3665)
+++
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsFullBackupJob.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -18,13 +18,12 @@
*/
package org.exoplatform.services.jcr.ext.backup;
+import org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob;
+
import java.io.File;
import java.net.URL;
import java.util.Calendar;
-import org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob;
-import org.exoplatform.services.jcr.impl.core.RdbmsWorkspaceInitializer;
-
/**
* @author <a href="mailto:anatoliy.bazko@gmail.com">Anatoliy
Bazko</a>
* @version $Id: TestFullBackupJob.java 34360 2009-07-22 23:58:59Z tolusha $
@@ -49,27 +48,27 @@
URL url = job.getStorageURL();
assertNotNull(url);
- File valuesDir = new File(url.getFile(),
RdbmsWorkspaceInitializer.VALUE_STORAGE_DIR);
+ File valuesDir = new File(url.getFile(), FullBackupJob.VALUE_STORAGE_DIR);
assertTrue(valuesDir.exists());
String values[] = valuesDir.list();
assertEquals(values.length, 1);
assertTrue(new File(valuesDir, values[0]).isDirectory());
- File indexesDir = new File(url.getFile(), RdbmsWorkspaceInitializer.INDEX_DIR);
+ File indexesDir = new File(url.getFile(), FullBackupJob.INDEX_DIR);
assertTrue(indexesDir.exists());
- indexesDir = new File(url.getFile(), RdbmsWorkspaceInitializer.SYSTEM_INDEX_DIR);
+ indexesDir = new File(url.getFile(), FullBackupJob.SYSTEM_INDEX_DIR);
assertTrue(indexesDir.exists());
- assertTrue(new File(url.getFile(), "JCR_MITEM" +
RdbmsWorkspaceInitializer.CONTENT_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MITEM" +
RdbmsWorkspaceInitializer.CONTENT_LEN_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MITEM" +
FullBackupJob.CONTENT_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MITEM" +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MVALUE" +
RdbmsWorkspaceInitializer.CONTENT_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MVALUE" +
RdbmsWorkspaceInitializer.CONTENT_LEN_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MVALUE" +
FullBackupJob.CONTENT_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MVALUE" +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MREF" +
RdbmsWorkspaceInitializer.CONTENT_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MREF" +
RdbmsWorkspaceInitializer.CONTENT_LEN_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MREF" +
FullBackupJob.CONTENT_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MREF" +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX).exists());
}
@@ -89,23 +88,23 @@
URL url = job.getStorageURL();
assertNotNull(url);
- File valuesDir = new File(url.getFile(),
RdbmsWorkspaceInitializer.VALUE_STORAGE_DIR);
+ File valuesDir = new File(url.getFile(), FullBackupJob.VALUE_STORAGE_DIR);
assertFalse(valuesDir.exists());
- File indexesDir = new File(url.getFile(), RdbmsWorkspaceInitializer.INDEX_DIR);
+ File indexesDir = new File(url.getFile(), FullBackupJob.INDEX_DIR);
assertTrue(indexesDir.exists());
- indexesDir = new File(url.getFile(), RdbmsWorkspaceInitializer.SYSTEM_INDEX_DIR);
+ indexesDir = new File(url.getFile(), FullBackupJob.SYSTEM_INDEX_DIR);
assertFalse(indexesDir.exists());
- assertTrue(new File(url.getFile(), "JCR_MITEM" +
RdbmsWorkspaceInitializer.CONTENT_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MITEM" +
RdbmsWorkspaceInitializer.CONTENT_LEN_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MITEM" +
FullBackupJob.CONTENT_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MITEM" +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MVALUE"
+RdbmsWorkspaceInitializer.CONTENT_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MVALUE" +
RdbmsWorkspaceInitializer.CONTENT_LEN_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MVALUE" +
FullBackupJob.CONTENT_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MVALUE" +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MREF" +
RdbmsWorkspaceInitializer.CONTENT_FILE_SUFFIX).exists());
- assertTrue(new File(url.getFile(), "JCR_MREF" +
RdbmsWorkspaceInitializer.CONTENT_LEN_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MREF" +
FullBackupJob.CONTENT_FILE_SUFFIX).exists());
+ assertTrue(new File(url.getFile(), "JCR_MREF" +
FullBackupJob.CONTENT_LEN_FILE_SUFFIX).exists());
}
}
Modified:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsWorkspaceInitializer.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsWorkspaceInitializer.java 2010-12-14
11:59:31 UTC (rev 3665)
+++
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/ext/backup/TestRdbmsWorkspaceInitializer.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -22,9 +22,9 @@
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.config.WorkspaceInitializerEntry;
import org.exoplatform.services.jcr.ext.backup.impl.rdbms.FullBackupJob;
-import org.exoplatform.services.jcr.impl.core.RdbmsWorkspaceInitializer;
-import org.exoplatform.services.jcr.impl.core.RdbmsWorkspaceInitializerWrapper;
+import org.exoplatform.services.jcr.ext.backup.impl.rdbms.RdbmsWorkspaceInitializer;
import org.exoplatform.services.jcr.impl.core.SysViewWorkspaceInitializer;
+import org.exoplatform.services.jcr.impl.core.TesterRdbmsWorkspaceInitializer;
import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.util.IdGenerator;
@@ -88,8 +88,8 @@
newEntry.setInitializer(wiEntry);
- RdbmsWorkspaceInitializerWrapper initializer =
- new RdbmsWorkspaceInitializerWrapper(newEntry,
+ TesterRdbmsWorkspaceInitializer initializer =
+ new TesterRdbmsWorkspaceInitializer(newEntry,
repositoryService.getRepository("db1").getConfiguration(),
cacheableDataManager, null, null, null,
(ValueFactoryImpl)valueFactory, null);
@@ -143,8 +143,8 @@
newEntry.setInitializer(wiEntry);
- RdbmsWorkspaceInitializerWrapper initializer =
- new RdbmsWorkspaceInitializerWrapper(newEntry,
+ TesterRdbmsWorkspaceInitializer initializer =
+ new TesterRdbmsWorkspaceInitializer(newEntry,
repositoryService.getRepository("db1").getConfiguration(),
cacheableDataManager, null, null, null,
(ValueFactoryImpl)valueFactory, null);
@@ -158,7 +158,7 @@
}
}
- public void testRDBMSInitializerRestoreTables() throws Exception
+ public void testRDBMSInitializerRestoreTablesMultiDB() throws Exception
{
FullBackupJob job = new FullBackupJob();
BackupConfig config = new BackupConfig();
@@ -186,9 +186,18 @@
Connection conn = ds.getConnection();
Statement st = conn.createStatement();
- st.execute("CREATE TABLE JCR_MITEM(ID VARCHAR(96) NOT NULL,PARENT_ID
VARCHAR(96) NOT NULL,NAME VARCHAR(512) NOT NULL,VERSION INTEGER NOT NULL,I_CLASS INTEGER
NOT NULL,I_INDEX INTEGER NOT NULL,N_ORDER_NUM INTEGER,P_TYPE INTEGER,P_MULTIVALUED
INTEGER,CONSTRAINT JCR_PK_MITEM PRIMARY KEY(ID))");
+ st.execute("CREATE TABLE JCR_MITEM(ID VARCHAR(96) NOT NULL,PARENT_ID
VARCHAR(96) NOT NULL,NAME VARCHAR(512) NOT NULL,VERSION INTEGER NOT NULL,I_CLASS INTEGER
NOT NULL,I_INDEX INTEGER NOT NULL,N_ORDER_NUM INTEGER,P_TYPE INTEGER,P_MULTIVALUED
BOOLEAN,CONSTRAINT JCR_PK_MITEM PRIMARY KEY(ID))");
conn.commit();
+ st.execute("INSERT INTO JCR_MITEM VALUES(' ','
','__root_parent',0,0,0,0,NULL,NULL)");
+ conn.commit();
+
+ st.execute("CREATE TABLE JCR_MVALUE(ID BIGINT generated by default as
identity (START WITH 2, INCREMENT BY 1) NOT NULL, DATA VARBINARY(65535),ORDER_NUM INTEGER
NOT NULL,PROPERTY_ID VARCHAR(96) NOT NULL,STORAGE_DESC VARCHAR(512),CONSTRAINT
JCR_PK_MVALUE PRIMARY KEY(ID),CONSTRAINT JCR_FK_MVALUE_PROPERTY FOREIGN KEY(PROPERTY_ID)
REFERENCES JCR_MITEM(ID))");
+ conn.commit();
+
+ st.execute("CREATE TABLE JCR_MREF(NODE_ID VARCHAR(96) NOT NULL,
PROPERTY_ID VARCHAR(96) NOT NULL, ORDER_NUM INTEGER NOT NULL, CONSTRAINT JCR_PK_MREF
PRIMARY KEY(NODE_ID, PROPERTY_ID, ORDER_NUM))");
+ conn.commit();
+
// set the initializer
WorkspaceEntry newEntry =
helper.getNewWs("ws1", true, dsName, newValueStoragePath,
newIndexPath, workspaceEntry.getContainer(),
@@ -205,14 +214,182 @@
newEntry.setInitializer(wiEntry);
- RdbmsWorkspaceInitializerWrapper initializer =
- new RdbmsWorkspaceInitializerWrapper(newEntry,
+ TesterRdbmsWorkspaceInitializer initializer =
+ new TesterRdbmsWorkspaceInitializer(newEntry,
repositoryService.getRepository("db1").getConfiguration(),
cacheableDataManager, null, null, null,
(ValueFactoryImpl)valueFactory, null);
- initializer.restoreTables(conn, "JCR_MITEM");
+ // restore multi -> multi
+ initializer.restoreTables(conn, 0, true, workspaceEntry.getLockManager(),
url.getFile());
+ initializer.restoreTables(conn, 1, true, workspaceEntry.getLockManager(),
url.getFile());
+ initializer.restoreTables(conn, 2, true, workspaceEntry.getLockManager(),
url.getFile());
+
+ st.execute("ALTER TABLE JCR_MITEM ADD CONSTRAINT JCR_FK_MITEM_PARENT
FOREIGN KEY(PARENT_ID) REFERENCES JCR_MITEM(ID)");
+ conn.commit();
+
+ dsName = helper.getNewDataSource("");
+ ds = (DataSource)new InitialContext().lookup(dsName);
+
+ conn = ds.getConnection();
+ st = conn.createStatement();
+ st.execute("CREATE TABLE JCR_SITEM(ID VARCHAR(96) NOT NULL,PARENT_ID
VARCHAR(96) NOT NULL,NAME VARCHAR(512) NOT NULL,VERSION INTEGER NOT NULL,CONTAINER_NAME
VARCHAR(96) NOT NULL,I_CLASS INTEGER NOT NULL,I_INDEX INTEGER NOT NULL,N_ORDER_NUM
INTEGER,P_TYPE INTEGER,P_MULTIVALUED BOOLEAN,CONSTRAINT JCR_PK_SITEM PRIMARY
KEY(ID))");
+ conn.commit();
+
+ st.execute("INSERT INTO JCR_SITEM VALUES(' ','
','__root_parent',0,'__root_parent_container',0,0,0,NULL,NULL)");
+ conn.commit();
+
+ st.execute("CREATE TABLE JCR_SVALUE(ID BIGINT generated by default as
identity (START WITH 2, INCREMENT BY 1) NOT NULL, DATA VARBINARY(65535),ORDER_NUM INTEGER
NOT NULL,PROPERTY_ID VARCHAR(96) NOT NULL,STORAGE_DESC VARCHAR(512),CONSTRAINT
JCR_PK_MVALUE PRIMARY KEY(ID),CONSTRAINT JCR_FK_SVALUE_PROPERTY FOREIGN KEY(PROPERTY_ID)
REFERENCES JCR_SITEM(ID))");
+ conn.commit();
+
+ st.execute("CREATE TABLE JCR_SREF(NODE_ID VARCHAR(96) NOT NULL,
PROPERTY_ID VARCHAR(96) NOT NULL, ORDER_NUM INTEGER NOT NULL, CONSTRAINT JCR_PK_SREF
PRIMARY KEY(NODE_ID, PROPERTY_ID, ORDER_NUM))");
+ conn.commit();
+
+ // set the initializer
+ newEntry =
+ helper.getNewWs("ws1", true, dsName, newValueStoragePath,
newIndexPath, workspaceEntry.getContainer(),
+ workspaceEntry.getContainer().getValueStorages());
+
+ wiEntry = new WorkspaceInitializerEntry();
+ wiEntry.setType(RdbmsWorkspaceInitializer.class.getCanonicalName());
+
+ wieParams = new ArrayList<SimpleParameterEntry>();
+ wieParams.add(new
SimpleParameterEntry(SysViewWorkspaceInitializer.RESTORE_PATH_PARAMETER, new File(url
+ .getFile()).getParent()));
+
+ wiEntry.setParameters(wieParams);
+
+ newEntry.setInitializer(wiEntry);
+
+ initializer =
+ new TesterRdbmsWorkspaceInitializer(newEntry,
repositoryService.getRepository("db1").getConfiguration(),
+ cacheableDataManager, null, null, null, (ValueFactoryImpl)valueFactory,
null);
+
+ // restore multi -> single
+ initializer.restoreTables(conn, 0, false, workspaceEntry.getLockManager(),
url.getFile());
+ initializer.restoreTables(conn, 1, false, workspaceEntry.getLockManager(),
url.getFile());
+ initializer.restoreTables(conn, 2, false, workspaceEntry.getLockManager(),
url.getFile());
+
+ st.execute("ALTER TABLE JCR_SITEM ADD CONSTRAINT JCR_FK_SITEM_PARENT
FOREIGN KEY(PARENT_ID) REFERENCES JCR_SITEM(ID)");
+ conn.commit();
+
}
}
}
+ public void testRDBMSInitializerRestoreTablesSingleDB() throws Exception
+ {
+ FullBackupJob job = new FullBackupJob();
+ BackupConfig config = new BackupConfig();
+ config.setRepository("db3");
+ config.setWorkspace("ws");
+ config.setBackupDir(new File("target/backup/testJob"));
+
+ Calendar calendar = Calendar.getInstance();
+
+ job.init(repositoryService.getRepository("db3"), "ws", config,
calendar);
+ job.run();
+
+ URL url = job.getStorageURL();
+
+ for (WorkspaceEntry workspaceEntry :
repositoryService.getRepository("db3").getConfiguration()
+ .getWorkspaceEntries())
+ {
+ if (workspaceEntry.getName().equals("ws"))
+ {
+ String newValueStoragePath = "target/temp/values/" +
IdGenerator.generate();
+ String newIndexPath = "target/temp/index/" +
IdGenerator.generate();
+
+ String dsName = helper.getNewDataSource("");
+ DataSource ds = (DataSource)new InitialContext().lookup(dsName);
+
+ Connection conn = ds.getConnection();
+ Statement st = conn.createStatement();
+ st.execute("CREATE TABLE JCR_MITEM(ID VARCHAR(96) NOT NULL,PARENT_ID
VARCHAR(96) NOT NULL,NAME VARCHAR(512) NOT NULL,VERSION INTEGER NOT NULL,I_CLASS INTEGER
NOT NULL,I_INDEX INTEGER NOT NULL,N_ORDER_NUM INTEGER,P_TYPE INTEGER,P_MULTIVALUED
BOOLEAN,CONSTRAINT JCR_PK_MITEM PRIMARY KEY(ID))");
+ conn.commit();
+
+ st.execute("INSERT INTO JCR_MITEM VALUES(' ','
','__root_parent',0,0,0,0,NULL,NULL)");
+ conn.commit();
+
+ st.execute("CREATE TABLE JCR_MVALUE(ID BIGINT generated by default as
identity (START WITH 2, INCREMENT BY 1) NOT NULL, DATA VARBINARY(65535),ORDER_NUM INTEGER
NOT NULL,PROPERTY_ID VARCHAR(96) NOT NULL,STORAGE_DESC VARCHAR(512),CONSTRAINT
JCR_PK_MVALUE PRIMARY KEY(ID),CONSTRAINT JCR_FK_MVALUE_PROPERTY FOREIGN KEY(PROPERTY_ID)
REFERENCES JCR_MITEM(ID))");
+ conn.commit();
+
+ st.execute("CREATE TABLE JCR_MREF(NODE_ID VARCHAR(96) NOT NULL,
PROPERTY_ID VARCHAR(96) NOT NULL, ORDER_NUM INTEGER NOT NULL, CONSTRAINT JCR_PK_MREF
PRIMARY KEY(NODE_ID, PROPERTY_ID, ORDER_NUM))");
+ conn.commit();
+
+ // set the initializer
+ WorkspaceEntry newEntry =
+ helper.getNewWs("ws", true, dsName, newValueStoragePath,
newIndexPath, workspaceEntry.getContainer(),
+ workspaceEntry.getContainer().getValueStorages());
+
+ WorkspaceInitializerEntry wiEntry = new WorkspaceInitializerEntry();
+ wiEntry.setType(RdbmsWorkspaceInitializer.class.getCanonicalName());
+
+ List<SimpleParameterEntry> wieParams = new
ArrayList<SimpleParameterEntry>();
+ wieParams.add(new
SimpleParameterEntry(SysViewWorkspaceInitializer.RESTORE_PATH_PARAMETER, new File(url
+ .getFile()).getParent()));
+
+ wiEntry.setParameters(wieParams);
+
+ newEntry.setInitializer(wiEntry);
+
+ TesterRdbmsWorkspaceInitializer initializer =
+ new TesterRdbmsWorkspaceInitializer(newEntry,
repositoryService.getRepository("db3").getConfiguration(),
+ cacheableDataManager, null, null, null, (ValueFactoryImpl)valueFactory,
null);
+
+ // restore single -> multi
+ initializer.restoreTables(conn, 0, true, workspaceEntry.getLockManager(),
url.getFile());
+ initializer.restoreTables(conn, 1, true, workspaceEntry.getLockManager(),
url.getFile());
+ initializer.restoreTables(conn, 2, true, workspaceEntry.getLockManager(),
url.getFile());
+
+ st.execute("ALTER TABLE JCR_MITEM ADD CONSTRAINT JCR_FK_MITEM_PARENT
FOREIGN KEY(PARENT_ID) REFERENCES JCR_MITEM(ID)");
+ conn.commit();
+
+ dsName = helper.getNewDataSource("");
+ ds = (DataSource)new InitialContext().lookup(dsName);
+
+ conn = ds.getConnection();
+ st = conn.createStatement();
+ st.execute("CREATE TABLE JCR_SITEM(ID VARCHAR(96) NOT NULL,PARENT_ID
VARCHAR(96) NOT NULL,NAME VARCHAR(512) NOT NULL,VERSION INTEGER NOT NULL,CONTAINER_NAME
VARCHAR(96) NOT NULL,I_CLASS INTEGER NOT NULL,I_INDEX INTEGER NOT NULL,N_ORDER_NUM
INTEGER,P_TYPE INTEGER,P_MULTIVALUED BOOLEAN,CONSTRAINT JCR_PK_SITEM PRIMARY
KEY(ID))");
+ conn.commit();
+
+ st.execute("INSERT INTO JCR_SITEM VALUES(' ','
','__root_parent',0,'__root_parent_container',0,0,0,NULL,NULL)");
+ conn.commit();
+
+ st.execute("CREATE TABLE JCR_SVALUE(ID BIGINT generated by default as
identity (START WITH 2, INCREMENT BY 1) NOT NULL, DATA VARBINARY(65535),ORDER_NUM INTEGER
NOT NULL,PROPERTY_ID VARCHAR(96) NOT NULL,STORAGE_DESC VARCHAR(512),CONSTRAINT
JCR_PK_MVALUE PRIMARY KEY(ID),CONSTRAINT JCR_FK_SVALUE_PROPERTY FOREIGN KEY(PROPERTY_ID)
REFERENCES JCR_SITEM(ID))");
+ conn.commit();
+
+ st.execute("CREATE TABLE JCR_SREF(NODE_ID VARCHAR(96) NOT NULL,
PROPERTY_ID VARCHAR(96) NOT NULL, ORDER_NUM INTEGER NOT NULL, CONSTRAINT JCR_PK_SREF
PRIMARY KEY(NODE_ID, PROPERTY_ID, ORDER_NUM))");
+ conn.commit();
+
+ // set the initializer
+ newEntry =
+ helper.getNewWs("ws", true, dsName, newValueStoragePath,
newIndexPath, workspaceEntry.getContainer(),
+ workspaceEntry.getContainer().getValueStorages());
+
+ wiEntry = new WorkspaceInitializerEntry();
+ wiEntry.setType(RdbmsWorkspaceInitializer.class.getCanonicalName());
+
+ wieParams = new ArrayList<SimpleParameterEntry>();
+ wieParams.add(new
SimpleParameterEntry(SysViewWorkspaceInitializer.RESTORE_PATH_PARAMETER, new File(url
+ .getFile()).getParent()));
+
+ wiEntry.setParameters(wieParams);
+
+ newEntry.setInitializer(wiEntry);
+
+ initializer =
+ new TesterRdbmsWorkspaceInitializer(newEntry,
repositoryService.getRepository("db3").getConfiguration(),
+ cacheableDataManager, null, null, null, (ValueFactoryImpl)valueFactory,
null);
+
+ // restore single -> single
+ initializer.restoreTables(conn, 0, false, workspaceEntry.getLockManager(),
url.getFile());
+ initializer.restoreTables(conn, 1, false, workspaceEntry.getLockManager(),
url.getFile());
+ initializer.restoreTables(conn, 2, false, workspaceEntry.getLockManager(),
url.getFile());
+
+ st.execute("ALTER TABLE JCR_SITEM ADD CONSTRAINT JCR_FK_SITEM_PARENT
FOREIGN KEY(PARENT_ID) REFERENCES JCR_SITEM(ID)");
+ conn.commit();
+
+ }
+ }
+ }
}
Deleted:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/RdbmsWorkspaceInitializerWrapper.java
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/RdbmsWorkspaceInitializerWrapper.java 2010-12-14
11:59:31 UTC (rev 3665)
+++
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/RdbmsWorkspaceInitializerWrapper.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This 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 software 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.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.core;
-
-import org.exoplatform.services.jcr.access.AccessManager;
-import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
-import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
-import
org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import javax.jcr.PathNotFoundException;
-import javax.jcr.RepositoryException;
-
-/**
- * Created by The eXo Platform SAS
- *
- * 04.12.2006
- *
- * For testing purpose
- *
- * @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter
Nedonosko</a>
- * @version $Id: SessionDataManagerTestWrapper.java 11907 2008-03-13 15:36:21Z ksm $
- */
-public class RdbmsWorkspaceInitializerWrapper extends RdbmsWorkspaceInitializer
-{
-
- public RdbmsWorkspaceInitializerWrapper(WorkspaceEntry config, RepositoryEntry
repConfig,
- CacheableWorkspaceDataManager dataManager, NamespaceRegistryImpl
namespaceRegistry,
- LocationFactory locationFactory, NodeTypeManagerImpl nodeTypeManager,
ValueFactoryImpl valueFactory,
- AccessManager accessManager) throws RepositoryConfigurationException,
PathNotFoundException, RepositoryException
- {
- super(config, repConfig, dataManager, namespaceRegistry, locationFactory,
nodeTypeManager, valueFactory,
- accessManager);
- }
-
- public void restoreValueFiles() throws RepositoryConfigurationException, IOException
- {
- super.restoreValueStorage();
- }
-
- public void restoreIndexFiles() throws RepositoryConfigurationException, IOException
- {
- super.restoreIndex();
- }
-
- public void restoreTables(Connection jdbcConn, String tableName) throws
RepositoryConfigurationException,
- IOException, SQLException
- {
- // super.restoreTable(jdbcConn, new RestoreTableHelper(RestoreTableHelper,
arg1));
- }
-
-}
Copied:
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/TesterRdbmsWorkspaceInitializer.java
(from rev 3658,
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/RdbmsWorkspaceInitializerWrapper.java)
===================================================================
---
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/TesterRdbmsWorkspaceInitializer.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.ext/src/test/java/org/exoplatform/services/jcr/impl/core/TesterRdbmsWorkspaceInitializer.java 2010-12-15
10:23:42 UTC (rev 3666)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This 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 software 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.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core;
+
+import org.exoplatform.services.jcr.access.AccessManager;
+import org.exoplatform.services.jcr.config.LockManagerEntry;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.ext.backup.impl.rdbms.RDBMSBackupInfoReader;
+import org.exoplatform.services.jcr.ext.backup.impl.rdbms.RdbmsWorkspaceInitializer;
+import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
+import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
+import
org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS
+ *
+ * 04.12.2006
+ *
+ * For testing purpose
+ *
+ * @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter
Nedonosko</a>
+ * @version $Id: SessionDataManagerTestWrapper.java 11907 2008-03-13 15:36:21Z ksm $
+ */
+public class TesterRdbmsWorkspaceInitializer extends RdbmsWorkspaceInitializer
+{
+
+ public TesterRdbmsWorkspaceInitializer(WorkspaceEntry config, RepositoryEntry
repConfig,
+ CacheableWorkspaceDataManager dataManager, NamespaceRegistryImpl
namespaceRegistry,
+ LocationFactory locationFactory, NodeTypeManagerImpl nodeTypeManager,
ValueFactoryImpl valueFactory,
+ AccessManager accessManager) throws RepositoryConfigurationException,
PathNotFoundException, RepositoryException
+ {
+ super(config, repConfig, dataManager, namespaceRegistry, locationFactory,
nodeTypeManager, valueFactory,
+ accessManager);
+ }
+
+ public void restoreValueFiles() throws RepositoryConfigurationException, IOException
+ {
+ super.restoreValueStorage();
+ }
+
+ public void restoreIndexFiles() throws RepositoryConfigurationException, IOException
+ {
+ super.restoreIndex();
+ }
+
+ public void restoreTables(Connection jdbcConn, int tableType, boolean isMultiDB,
LockManagerEntry lockManagerEntry,
+ String storageDir) throws RepositoryConfigurationException, IOException,
SQLException
+ {
+ RDBMSBackupInfoReader backupInfo = new RDBMSBackupInfoReader(storageDir);
+ RestoreTableHelper helper = new RestoreTableHelper(tableType, isMultiDB,
backupInfo);
+
+ super.restoreTable(jdbcConn, helper);
+ }
+
+}