[exo-jcr-commits] exo-jcr SVN: r5024 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/clean/rdbms and 4 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Oct 5 09:36:59 EDT 2011


Author: areshetnyak
Date: 2011-10-05 09:36:58 -0400 (Wed, 05 Oct 2011)
New Revision: 5024

Added:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DB2DBRestore.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/H2DBRestore.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/MySQLDBRestore.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/OracleDBRestore.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleaner.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DummyDBCleaner.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/RecursiveDBCleanHelper.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializerHelper.java
Removed:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java
Modified:
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/init/StorageDBInitializer.java
   jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java
   jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java
Log:
EXOJCR-1531 : Restoring operation for single-db configuration by optimization cleaning db was improved

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DB2DBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DB2DBRestore.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DB2DBRestore.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2003-2011 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.impl.backup.rdbms;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
+ * @version $Id: DB2DBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class DB2DBRestore extends DBRestore
+{
+   /**
+    * The constraint name is limited by 18 symbols.  
+    */
+   private static final int DB2_CONSTRAINT_NAME_LENGTH_LIMIT = 18;
+
+   /**
+    * Constructor DB2DBRestore.
+    */
+   public DB2DBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+      WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
+      RepositoryConfigurationException
+   {
+      super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected String validateConstraintName(String string)
+   {
+      return string.substring(0, DB2_CONSTRAINT_NAME_LENGTH_LIMIT);
+   }
+}

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -28,8 +28,7 @@
 import org.exoplatform.services.jcr.impl.Constants;
 import org.exoplatform.services.jcr.impl.backup.BackupException;
 import org.exoplatform.services.jcr.impl.backup.DataRestore;
-import org.exoplatform.services.jcr.impl.clean.rdbms.DBClean;
-import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
 import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectZipReaderImpl;
 import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
 import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
@@ -50,6 +49,7 @@
 import java.sql.Statement;
 import java.sql.Types;
 import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -62,7 +62,7 @@
  * Date: 22 01 2011
  * 
  * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a>
- * @version $Id: DBRestor.java 34360 2010-11-11 11:11:11Z tolusha $
+ * @version $Id: DBRestore.java 34360 2010-11-11 11:11:11Z tolusha $
  */
 public class DBRestore implements DataRestore
 {
@@ -102,7 +102,7 @@
    protected final Connection jdbcConn;
 
    /**
-    * Directory with tables dump.
+    * Directory for dumps.
     */
    private final File storageDir;
 
@@ -114,7 +114,7 @@
    /**
     * Database cleaner.
     */
-   private final DBClean dbClean;
+   private final DBCleaner dbCleaner;
 
    /**
     * Database dialect.
@@ -122,11 +122,21 @@
    protected final int dialect;
 
    /**
-    * Contains constraint for JCR_SITEM or JCR_MITEM table.  
+    * Contains queries for adding constraints and indexes.  
     */
-   private String constraint;
+   protected Map<String, String> addQueries = new LinkedHashMap<String, String>();
 
    /**
+    * Contains queries for dropping constraints and indexes.  
+    */
+   protected Map<String, String> dropQueries = new LinkedHashMap<String, String>();
+
+   /**
+    * Contains object names which executed queries.   
+    */
+   protected List<String> successfulExecuted;
+
+   /**
     * Constructor DBRestor.
     * 
     * @throws NamingException 
@@ -134,7 +144,7 @@
     * @throws RepositoryConfigurationException 
     */
    public DBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
-      WorkspaceEntry wsConfig, FileCleaner fileCleaner) throws NamingException, SQLException,
+      WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
       RepositoryConfigurationException
    {
       this.jdbcConn = jdbcConn;
@@ -145,7 +155,7 @@
 
       this.storageDir = storageDir;
       this.tables = tables;
-      this.dbClean = DBCleanService.getDBCleaner(this.jdbcConn, wsConfig);
+      this.dbCleaner = dbCleaner;
       this.dialect = DialectDetecter.detect(jdbcConn.getMetaData()).hashCode();
    }
 
@@ -156,7 +166,7 @@
    {
       try
       {
-         dbClean.clean();
+         dbCleaner.executeCleanScripts();
       }
       catch (SQLException e)
       {
@@ -171,17 +181,20 @@
    {
       try
       {
+         boolean isMultiDb = tables.entrySet().iterator().next().getValue().getDstMultiDb();
+         prepareQueries(isMultiDb);
+
+         preRestoreTables(isMultiDb);
+
          for (Entry<String, RestoreTableRule> entry : tables.entrySet())
          {
             String tableName = entry.getKey();
             RestoreTableRule restoreRule = entry.getValue();
 
-            preRestoreTable(tableName, restoreRule);
-
             restoreTable(storageDir, jdbcConn, tableName, restoreRule);
+         }
 
-            postRestoreTable(tableName, restoreRule);
-         }
+         postRestoreTables(isMultiDb);
       }
       catch (IOException e)
       {
@@ -194,106 +207,135 @@
    }
 
    /**
-    * Prepare of restore table. (Drop constraint, etc...)
+    * Prepare queries for restoring.
     * 
-    * @param tableName
-    *        name of table 
-    * @param restoreRule
-    *        rule of table 
-    * @throws SQLException
-    *           Will throw SQLException if fail.
+    * @param isMultiDb
+    *          indicates if we have multi-db configuration or not
     */
-   public void preRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+   protected void prepareQueries(boolean isMultiDb)
    {
-      Statement st = null;
+      String multiDb = isMultiDb ? "M" : "S";
+      
+      String constraintName = validateConstraintName("JCR_PK_" + multiDb + "VALUE");
+      String constraint = "CONSTRAINT " + constraintName + " PRIMARY KEY(ID)";
+      addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "VALUE ADD " + constraint);
+      dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "VALUE " + dropCommand(true, constraintName));
 
-      try
-      {
-         if (tableName.equals("JCR_SITEM") || tableName.equals("JCR_MITEM"))
-         {
-            // resolve constraint name depends on database
-            String constraintName;
-            if (dialect == DBBackup.DB_DIALECT_DB2 || dialect == DBBackup.DB_DIALECT_DB2V8)
-            {
-               constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PAREN";
-            }
-            else
-            {
-               constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PARENT";
-            }
-            constraint = "CONSTRAINT " + constraintName + " FOREIGN KEY(PARENT_ID) REFERENCES " + tableName + "(ID)";
+      constraintName = validateConstraintName("JCR_PK_" + multiDb + "ITEM");
+      constraint = "CONSTRAINT " + constraintName + " PRIMARY KEY(ID)";
+      addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "ITEM ADD " + constraint);
 
-            // drop constraint
-            st = jdbcConn.createStatement();
+      constraintName = validateConstraintName("JCR_FK_" + multiDb + "VALUE_PROPERTY");
+      constraint = "CONSTRAINT " + constraintName + " FOREIGN KEY(PROPERTY_ID) REFERENCES JCR_" + multiDb + "ITEM(ID)";
+      addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "VALUE ADD " + constraint);
+      dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "VALUE " + dropCommand(false, constraintName));
 
-            if (dialect == DBBackup.DB_DIALECT_MYSQL || dialect == DBBackup.DB_DIALECT_MYSQL_UTF8)
-            {
-               st.execute("ALTER TABLE " + tableName + " DROP FOREIGN KEY " + constraintName);
-            }
-            else
-            {
-               st.execute("ALTER TABLE " + tableName + " DROP CONSTRAINT " + constraintName);
-            }
-         }
-      }
-      finally
-      {
-         if (st != null)
-         {
-            try
-            {
-               st.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.warn("Can't close statemnt", e);
-            }
-         }
-      }
+      constraintName = validateConstraintName("JCR_FK_" + multiDb + "ITEM_PARENT");
+      constraint = "CONSTRAINT " + constraintName + " FOREIGN KEY(PARENT_ID) REFERENCES JCR_" + multiDb + "ITEM(ID)";
+      addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "ITEM ADD " + constraint);
+      dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "ITEM " + dropCommand(false, constraintName));
+
+      constraintName = validateConstraintName("JCR_PK_" + multiDb + "ITEM");
+      dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "ITEM " + dropCommand(true, constraintName));
+
+      constraintName = validateConstraintName("JCR_PK_" + multiDb + "REF");
+      constraint = "CONSTRAINT " + constraintName + " PRIMARY KEY(NODE_ID, PROPERTY_ID, ORDER_NUM)";
+      addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "REF ADD " + constraint);
+      dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "REF " + dropCommand(true, constraintName));
+
+      constraintName = validateConstraintName("JCR_PK_" + multiDb + "CONTAINER");
+      constraint = "CONSTRAINT " + constraintName + " PRIMARY KEY(VERSION)";
+      addQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "CONTAINER ADD " + constraint);
+      dropQueries.put(constraintName, "ALTER TABLE JCR_" + multiDb + "CONTAINER " + dropCommand(true, constraintName));
    }
 
    /**
-    * After of restore table. (Add constraint, etc...)
+    * Validate name of constraint. For some DBs constrains name is limited.
     * 
-    * @param tableName
-    *        name of table 
-    * @param restoreRule
-    *        rule of table 
+    * @param string
+    *          the constraint name
+    * @return the constraint name accepted for specific DB
+    */
+   protected String validateConstraintName(String string)
+   {
+      return string;
+   }
+
+   /**
+    * Return the command to drop primary or foreign key.  
+    * 
+    * @param isPrimaryKey
+    *          boolean
+    * @return String
+    */
+   protected String dropCommand(boolean isPrimaryKey, String constraintName)
+   {
+      return "DROP CONSTRAINT " + constraintName;
+   }
+
+   /**
+    * Prepare of restore tables. (Drop constraint, etc...)
+    * 
+    * @param isMultiDb
+    *          boolean
     * @throws SQLException
+    *           will throw SQLException if fail.          
+    */
+   public void preRestoreTables(boolean isMultiDb) throws SQLException
+   {
+      executeQueries(dropQueries);
+   }
+
+   /**
+    * After of restore tables. (Add constraint, etc...)
+    * 
+    * @param isMultiDb
+    *          boolean
+    * @throws SQLException
     *           Will throw SQLException if fail.
     */
-   public void postRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+   public void postRestoreTables(boolean isMultiDb) throws SQLException
    {
+      executeQueries(addQueries);
+   }
+
+   /**
+    * Execute queries.
+    * 
+    * @param queries
+    *         the map with queries.
+    * @throws SQLException
+    */
+   protected List<String> executeQueries(final Map<String, String> queries) throws SQLException
+   {
+      successfulExecuted = new ArrayList<String>();
       Statement st = null;
 
-      try
+      for (String constraintName : queries.keySet())
       {
-         if (tableName.equals("JCR_SITEM") || tableName.equals("JCR_MITEM"))
+         try
          {
-            if (constraint != null)
-            {
-               // add constraint
-               st = jdbcConn.createStatement();
-               st.execute("ALTER TABLE " + tableName + " ADD " + constraint);
-            }
+            st = jdbcConn.createStatement();
+            st.execute(queries.get(constraintName));
+            successfulExecuted.add(constraintName);
          }
-      }
-      finally
-      {
-         constraint = null;
-
-         if (st != null)
+         finally
          {
-            try
+            if (st != null)
             {
-               st.close();
+               try
+               {
+                  st.close();
+               }
+               catch (SQLException e)
+               {
+                  LOG.warn("Can't close statemnt", e);
+               }
             }
-            catch (SQLException e)
-            {
-               LOG.warn("Can't close statemnt", e);
-            }
          }
       }
+
+      return successfulExecuted;
    }
 
    /**
@@ -303,6 +345,16 @@
    {
       try
       {
+         try
+         {
+            // don't care about any exception here
+            dbCleaner.executeCommitScripts();
+         }
+         catch (Exception e)
+         {
+            LOG.error("Can't remove temporary objects after cleaning", e);
+         }
+
          jdbcConn.commit();
       }
       catch (SQLException e)
@@ -319,6 +371,9 @@
       try
       {
          jdbcConn.rollback();
+
+         dbCleaner.executeRollbackScripts();
+         jdbcConn.commit();
       }
       catch (SQLException e)
       {

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/H2DBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/H2DBRestore.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/H2DBRestore.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2003-2011 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.impl.backup.rdbms;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
+ * @version $Id: H2DBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class H2DBRestore extends DBRestore
+{
+
+   /**
+    * Constructor H2DBRestore.
+    */
+   public H2DBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+      WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
+      RepositoryConfigurationException
+   {
+      super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected void prepareQueries(boolean isMultiDb)
+   {
+      super.prepareQueries(isMultiDb);
+
+      // H2 doesn't contain primary key for JCR_SVALUE (JCR_MVALUE) table
+      String constraintName = "JCR_PK_" + (isMultiDb ? "M" : "S") + "VALUE";
+      addQueries.remove(constraintName);
+      dropQueries.remove(constraintName);
+   }
+}

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/MySQLDBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/MySQLDBRestore.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/MySQLDBRestore.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003-2011 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.impl.backup.rdbms;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
+ * @version $Id: MySQLDBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class MySQLDBRestore extends DBRestore
+{
+
+   /**
+    * Constructor MySQLDBRestore.
+    */
+   public MySQLDBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+      WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
+      RepositoryConfigurationException
+   {
+      super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected String dropCommand(boolean isPrimaryKey, String constraintName)
+   {
+      return isPrimaryKey == true ? "DROP PRIMARY KEY" : "DROP FOREIGN KEY " + constraintName;
+   }
+
+}

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/OracleDBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/OracleDBRestore.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/OracleDBRestore.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2003-2011 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.impl.backup.rdbms;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
+ * @version $Id: OracleDBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class OracleDBRestore extends DBRestore
+{
+
+   /**
+    *  OracleDBRestore constructor.
+    */
+   public OracleDBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+      WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
+      RepositoryConfigurationException
+   {
+      super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected void prepareQueries(boolean isMultiDb)
+   {
+      String multiDb = isMultiDb ? "M" : "S";
+
+      String indexName = "JCR_IDX_" + multiDb + "ITEM_PARENT_FK";
+      addQueries.put(indexName, "CREATE INDEX " + indexName + " ON JCR_" + multiDb + "ITEM(PARENT_ID)");
+      dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+      indexName = "JCR_IDX_" + multiDb + "ITEM_PARENT";
+      addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+         + "ITEM(CONTAINER_NAME, PARENT_ID, NAME, I_INDEX, I_CLASS, VERSION DESC)");
+      dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+      indexName = "JCR_IDX_" + multiDb + "ITEM_PARENT_NAME";
+      addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+         + "ITEM(I_CLASS, CONTAINER_NAME, PARENT_ID, NAME, I_INDEX, VERSION DESC)");
+      dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+      indexName = "JCR_IDX_" + multiDb + "ITEM_PARENT_ID";
+      addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+         + "ITEM(I_CLASS, CONTAINER_NAME, PARENT_ID, ID, VERSION DESC)");
+      dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+      indexName = "JCR_IDX_" + multiDb + "VALUE_PROPERTY";
+      addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+         + "VALUE(PROPERTY_ID, ORDER_NUM)");
+      dropQueries.put(indexName, "DROP INDEX " + indexName);
+
+      indexName = "JCR_IDX_" + multiDb + "REF_PROPERTY";
+      addQueries.put(indexName, "CREATE UNIQUE INDEX " + indexName + " ON JCR_" + multiDb
+         + "REF(PROPERTY_ID, ORDER_NUM)");
+      dropQueries.put(indexName, "DROP INDEX " + indexName);
+      
+      super.prepareQueries(isMultiDb);
+   }
+}

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -20,13 +20,14 @@
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.config.WorkspaceEntry;
 import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
 import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
 
 import java.io.File;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.Map;
-import java.util.Map.Entry;
 
 import javax.naming.NamingException;
 
@@ -38,16 +39,19 @@
  * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
  * @version $Id: SybaseDBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
  */
-public class SybaseDBRestore
-   extends DBRestore
+public class SybaseDBRestore extends DBRestore
 {
-   private String restoreConstraint = null;
-   
+   private final Boolean isMultiDb;
+
+   /**
+    * Constructor SybaseDBRestore.
+    */
    public SybaseDBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
-            WorkspaceEntry wsConfig, FileCleaner fileCleaner) throws NamingException, SQLException,
+      WorkspaceEntry wsConfig, FileCleaner fileCleaner, DBCleaner dbCleaner) throws NamingException, SQLException,
             RepositoryConfigurationException
    {
-      super(storageDir, jdbcConn, tables, wsConfig, fileCleaner);
+      super(storageDir, jdbcConn, tables, wsConfig, fileCleaner, dbCleaner);
+      this.isMultiDb = tables.entrySet().iterator().next().getValue().getDstMultiDb();
    }
 
    /**
@@ -55,19 +59,13 @@
     */
    public void clean() throws BackupException
    {
-
       try
       {
          // the Sybase is not allowed DDL query (CREATE TABLE, DROP TABLE, etc. ) within a multi-statement transaction
          jdbcConn.setAutoCommit(true);
 
-         for (Entry<String, RestoreTableRule> entry : tables.entrySet())
-         {
-            String tableName = entry.getKey();
-            RestoreTableRule restoreRule = entry.getValue();
-
-            super.preRestoreTable(tableName, restoreRule);
-         }
+         super.prepareQueries(isMultiDb);
+         super.executeQueries(dropQueries);
       }
       catch (SQLException e)
       {
@@ -148,12 +146,22 @@
          // restore constraint
          jdbcConn.setAutoCommit(true);
 
-         for (Entry<String, RestoreTableRule> entry : tables.entrySet())
+         if (successfulExecuted.size() == addQueries.size())
          {
-            String tableName = entry.getKey();
-            RestoreTableRule restoreRule = entry.getValue();
+            executeQueries(addQueries);
+         }
+         else
+         {
+            ArrayList<String> notDeletedConstraints = new ArrayList<String>();
+            notDeletedConstraints.addAll(addQueries.keySet());
+            notDeletedConstraints.removeAll(successfulExecuted);
 
-            super.postRestoreTable(tableName, restoreRule);
+            for (String notDeletedConstraint : notDeletedConstraints)
+            {
+               addQueries.remove(notDeletedConstraint);
+            }
+
+            executeQueries(addQueries);
          }
       }
       catch (SQLException e)
@@ -176,14 +184,27 @@
    /**
     * {@inheritDoc}
     */
-   public void preRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+   public void preRestoreTables(boolean isMultiDb) throws SQLException
    {
    }
 
    /**
     * {@inheritDoc}
     */
-   public void postRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+   public void postRestoreTables(boolean isMultiDb) throws SQLException
    {
    }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected String validateConstraintName(String string)
+   {
+      if (string.equals("JCR_PK_SCONTAINER"))
+      {
+         return "JCR_PK_MCONTAINER";
+      }
+      
+      return super.validateConstraintName(string);
+   }
 }

Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,219 +0,0 @@
-/*
- * 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.impl.clean.rdbms;
-
-import org.exoplatform.commons.utils.SecurityHelper;
-import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCUtils;
-import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializer;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-
-import java.security.PrivilegedExceptionAction;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The goal of this class is removing workspace data from database.
- *
- * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
- * @version $Id: DBClean.java 3769 2011-01-04 15:36:06Z areshetnyak $
- */
-public class DBClean
-{
-   /**
-    * Logger.
-    */
-   protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBClean");
-
-   /**
-    * Connection to database.
-    */
-   protected final Connection connection;
-
-   /**
-    * Pattern for JCR tables.
-    */
-   protected final Pattern dbObjectNamePattern;
-
-   /**
-    * Common clean scripts for database.
-    */
-   protected final List<String> cleanScripts = new ArrayList<String>();
-
-   /**
-    * DB clean helper.
-    */
-   protected final DBCleanHelper dbCleanHelper;
-
-   /**
-    * WorkspaceDBCleaner constructor.
-    * 
-    * @param containerName 
-    *          container name (workspace name)
-    * @param connection 
-    *          connection to database where workspace tables is placed
-    */
-   public DBClean(Connection connection, List<String> cleanScripts)
-   {
-      this(connection, cleanScripts, null);
-   }
-
-   /**
-    * WorkspaceDBCleaner constructor.
-    * 
-    * @param containerName 
-    *          container name (workspace name)
-    * @param connection 
-    *          connection to database where workspace tables is placed
-    * @param dbCleanHelper
-    */
-   public DBClean(Connection connection, List<String> cleanScripts, DBCleanHelper dbCleanHelper)
-   {
-      this.dbObjectNamePattern = Pattern.compile(DBInitializer.SQL_OBJECTNAME, Pattern.CASE_INSENSITIVE);
-      this.connection = connection;
-      this.cleanScripts.addAll(cleanScripts);
-      this.dbCleanHelper = dbCleanHelper;
-   }
-
-   /**
-    * Clean data from database. The method doesn't close connection or perform commit.
-    * 
-    * @throws SQLException
-    *          if any errors occurred 
-    */
-   public void clean() throws SQLException
-   {
-      SecurityManager security = System.getSecurityManager();
-      if (security != null)
-      {
-         security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
-      }
-
-      String sql = null;
-      Statement st = null;
-      try
-      {
-         st = connection.createStatement();
-         for (String scr : cleanScripts)
-         {
-            String s = cleanWhitespaces(scr.trim());
-            if (s.length() > 0)
-            {
-               if (!canExecuteQuery(sql = s))
-               {
-                  // table from query not found, so try drop other
-                  continue;
-               }
-
-               if (LOG.isDebugEnabled())
-               {
-                  LOG.debug("Execute script: \n[" + sql + "]");
-               }
-               executeQuery(st, sql);
-            }
-         }
-
-         if (dbCleanHelper != null)
-         {
-            dbCleanHelper.clean();
-         }
-      }
-      finally
-      {
-         if (st != null)
-         {
-            try
-            {
-               st.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error("Can't close the Statement." + e);
-            }
-         }
-      }
-   }
-
-   /**
-    * Check if we can execute query.
-    * If tables used in query does not exists, we can not execute query.
-    */
-   protected boolean canExecuteQuery(String sql) throws SQLException
-   {
-      Matcher tMatcher = dbObjectNamePattern.matcher(sql);
-      while (tMatcher.find())
-      {
-         // get table name
-         String tableName = sql.substring(tMatcher.start(), tMatcher.end());
-         if (!isTableExists(connection, tableName))
-         {
-            LOG.warn("Table [" + tableName + "] from query [" + sql + "] was not found. So query will not be executed.");
-            return false;
-         }
-      }
-      return true;
-   }
-
-   /**
-    * Execute query.
-    */
-   protected void executeQuery(final Statement statement, final String sql) throws SQLException
-   {
-      SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
-      {
-         public Object run() throws Exception
-         {
-            statement.executeUpdate(sql);
-            return null;
-         }
-      });
-   }
-
-   /**
-    * Indicates if table exists or not.
-    */
-   protected boolean isTableExists(Connection conn, String tableName) throws SQLException
-   {
-      return JDBCUtils.tableExists(tableName, conn);
-   }
-
-   /**
-    * Cleans redundant whitespaces from query.
-    */
-   private String cleanWhitespaces(String string)
-   {
-      if (string != null)
-      {
-         char[] cc = string.toCharArray();
-         for (int ci = cc.length - 1; ci > 0; ci--)
-         {
-            if (Character.isWhitespace(cc[ci]))
-            {
-               cc[ci] = ' ';
-            }
-         }
-         return new String(cc);
-      }
-      return string;
-   }
-}

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2010 eXo Platform SAS.
+ * Copyright (C) 2003-2011 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
@@ -16,133 +16,23 @@
  */
 package org.exoplatform.services.jcr.impl.clean.rdbms;
 
-import org.exoplatform.commons.utils.SecurityHelper;
-import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-
-import java.security.PrivilegedExceptionAction;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.sql.SQLException;
 
 /**
- * 
  * Created by The eXo Platform SAS.
- *
- * Date: 21.01.2011
  * 
- * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a>
- * @version $Id: DBCleanHelper.java.java 34360 2010-11-11 11:11:11Z tolusha $
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
+ * @version $Id: DBCleanHelper.java 111 2011-11-11 11:11:11Z rainf0x $
  */
-public class DBCleanHelper
+public interface DBCleanHelper
 {
-
    /**
-    * Logger.
-    */
-   protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBCleanHelper");
-
-   /**
-    * Select items query.
-    */
-   private final String selectItems;
-
-   /**
-    * Remove items query.
-    */
-   private final String removeItems;
-
-   /**
-    * Connection to database.
-    */
-   protected final Connection connection;
-
-   /**
-    * DBCleanerHelper constructor.
-    */
-   public DBCleanHelper(Connection connection, String selectItemds, String removeItems)
-   {
-      this.connection = connection;
-      this.selectItems = selectItemds;
-      this.removeItems = removeItems;
-   }
-
-   /**
-    * Removing rows from table. Some database do not support cascade delete, 
-    * or need special sittings. In such case will be used deleting like
-    * visitor does. First traverse to the bottom of the tree and then go up to the root
-    * and perform deleting children.
+    * Clean data from database. The method doesn't close connection or perform commit.
     * 
-    * @throws SQLException 
-    *          SQL exception. 
+    * @throws SQLException
+    *          if any errors occurred 
     */
-   public void clean() throws SQLException
-   {
-      recursiveClean(Constants.ROOT_PARENT_UUID);
-   }
-
-   private void recursiveClean(String parentID) throws SQLException
-   {
-      PreparedStatement selectStatement = null;
-      PreparedStatement removeStatement = null;
-      ResultSet result = null;
-
-      try
-      {
-         selectStatement = connection.prepareStatement(this.selectItems);
-         selectStatement.setString(1, parentID);
-
-         final PreparedStatement fSelectStatement = selectStatement;
-         result = (ResultSet)SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
-         {
-            public Object run() throws Exception
-            {
-               return fSelectStatement.executeQuery();
-            }
-         });
-
-         // recursive traversing to the bottom of the tree
-         if (result.next())
-         {
-            do
-            {
-               recursiveClean(result.getString(1));
-            }
-            while (result.next());
-
-            // go up to the root and remove all nodes
-            removeStatement = connection.prepareStatement(this.removeItems);
-            removeStatement.setString(1, parentID);
-
-            final PreparedStatement fRemoveStatement = removeStatement;
-            SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
-            {
-               public Object run() throws Exception
-               {
-                  fRemoveStatement.executeUpdate();
-                  return null;
-               }
-            });
-         }
-      }
-      finally
-      {
-         if (selectStatement != null)
-         {
-            selectStatement.close();
-         }
-
-         if (removeStatement != null)
-         {
-            removeStatement.close();
-         }
-
-         if (result != null)
-         {
-            result.close();
-         }
-      }
-   }
+   public void executeCleanScripts() throws SQLException;
 }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanService.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -24,7 +24,11 @@
 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.util.jdbc.DBInitializerHelper;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
 
+import java.io.IOException;
 import java.security.PrivilegedExceptionAction;
 import java.sql.Connection;
 import java.sql.ResultSet;
@@ -49,6 +53,16 @@
 public class DBCleanService
 {
    /**
+    * Logger.
+    */
+   protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBCleanService");
+
+   /**
+    * Old object suffix. Will using in rename.
+    */
+   public static final String OLD_OBJECT_SUFFIX = "_OLD";
+
+   /**
     * Cleans workspace data from database.
     * 
     * @param wsEntry
@@ -78,14 +92,26 @@
       });
       jdbcConn.setAutoCommit(false);
 
+      DBCleaner dbCleaner = getWorkspaceDBCleaner(jdbcConn, wsEntry);
       try
       {
-         getDBCleaner(jdbcConn, wsEntry).clean();
+         dbCleaner.executeCleanScripts();
+         try
+         {
+            dbCleaner.executeCommitScripts();
+         }
+         catch (SQLException e)
+         {
+            LOG.error("Can't remove temporary objects", e);
+         }
          jdbcConn.commit();
       }
       catch (SQLException e)
       {
          jdbcConn.rollback();
+
+         dbCleaner.executeRollbackScripts();
+         jdbcConn.commit();
       }
       finally
       {
@@ -112,17 +138,307 @@
    }
 
    /**
-    * Returns database cleaner for manual cleaning.  
+    * Returns database cleaner for manual cleaning for repository. 
     * 
     * @param jdbcConn
     *          database connection which need to use
     * @param wsEntry
     *          workspace configuration
+    * @return database cleaner or null in case of multi-db configuration
+    * @throws SQLException
+    * @throws RepositoryConfigurationException
+    */
+   public static DBCleaner getRepositoryDBCleaner(Connection jdbcConn, RepositoryEntry repoEntry) throws SQLException,
+      RepositoryConfigurationException
+   {
+      final boolean isMultiDB =
+         Boolean.parseBoolean(repoEntry.getWorkspaceEntries().get(0).getContainer().getParameterValue(
+            JDBCWorkspaceDataContainer.MULTIDB));
+
+      if (isMultiDB)
+      {
+         return null;
+      }
+
+      String dialect = DialectDetecter.detect(jdbcConn.getMetaData());
+
+      if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+      {
+         ArrayList<String> dbCleanerScripts = new ArrayList<String>();
+         dbCleanerScripts.addAll(getRenameScripts(isMultiDB, dialect));
+         dbCleanerScripts.addAll(getInitializationDBScript(isMultiDB, dialect));
+
+         return new DBCleaner(jdbcConn, dbCleanerScripts, getRollbackRenamedScript(isMultiDB, dialect),
+            getAfterRestoreScript(isMultiDB, dialect));
+      }
+      else if (dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
+      {
+         ArrayList<String> dbCleanerScripts = new ArrayList<String>();
+         dbCleanerScripts.add("delete from JCR_" + (isMultiDB ? "M" : "S") + "VALUE");
+         dbCleanerScripts.add("delete from JCR_" + (isMultiDB ? "M" : "S") + "ITEM");
+         dbCleanerScripts.add("delete from JCR_" + (isMultiDB ? "M" : "S") + "REF");
+         dbCleanerScripts.add("delete from JCR_" + (isMultiDB ? "M" : "S") + "CONTAINER");
+         dbCleanerScripts.add(DBInitializerHelper.getRootNodeInitializeScript(isMultiDB));
+
+         return new DBCleaner(jdbcConn, dbCleanerScripts);
+      }
+
+      ArrayList<String> dbCleanerScripts = new ArrayList<String>();
+      dbCleanerScripts.addAll(getDropTableScripts(isMultiDB, dialect));
+      dbCleanerScripts.addAll(getInitializationDBScript(isMultiDB, dialect));
+
+      return new DBCleaner(jdbcConn, dbCleanerScripts);
+
+   }
+
+   /**
+    * Create list with queries to drop tables, etc...
+    * 
+    * @param multiDb
+    * @return List 
+    *           return list with query
+    */
+   protected static List<String> getDropTableScripts(boolean multiDb, String dialect)
+   {
+      final String isMultiDB = (multiDb ? "M" : "S");
+
+      List<String> cleanScripts = new ArrayList<String>();
+
+      if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+      {
+         cleanScripts.add("drop trigger BI_JCR_" + isMultiDB + "VALUE");
+         cleanScripts.add("drop sequence JCR_" + isMultiDB + "VALUE_SEQ");
+      }
+
+      cleanScripts.add("drop table JCR_" + isMultiDB + "VALUE");
+      cleanScripts.add("drop table JCR_" + isMultiDB + "ITEM");
+      cleanScripts.add("drop table JCR_" + isMultiDB + "REF");
+      cleanScripts.add("drop table JCR_" + isMultiDB + "CONTAINER");
+
+      return cleanScripts;
+   }
+
+   /**
+    * Create script to rename tables, indexes, etc...   
+    * 
+    * @param multiDb
+    *          boolean
+    * @param dialect
+    *          string
+    * @return List 
+    *           return list with query
+    */
+   protected static List<String> getRenameScripts(boolean multiDb, String dialect)
+   {
+      final String isMultiDB = (multiDb ? "M" : "S");
+
+      List<String> renameScripts = new ArrayList<String>();
+
+      // JCR_[S,M]VALUE
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE RENAME TO JCR_" + isMultiDB + "VALUE"
+         + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_PK_"
+         + isMultiDB + "VALUE TO JCR_PK_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_FK_"
+         + isMultiDB + "VALUE_PROPERTY TO JCR_FK_" + isMultiDB + "VALUE_PROPERTY" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "VALUE RENAME TO JCR_PK_" + isMultiDB + "VALUE"
+         + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "VALUE_PROPERTY RENAME TO JCR_IDX_" + isMultiDB
+         + "VALUE_PROPERTY" + OLD_OBJECT_SUFFIX);
+
+      if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+      {
+         renameScripts.add("RENAME JCR_" + isMultiDB + "VALUE_SEQ TO JCR_" + isMultiDB + "VALUE_SEQ"
+            + OLD_OBJECT_SUFFIX);
+         renameScripts.add("ALTER TRIGGER BI_JCR_" + isMultiDB + "VALUE RENAME TO BI_JCR_" + isMultiDB + "VALUE"
+            + OLD_OBJECT_SUFFIX);
+      }
+
+      // JCR_[S,M]ITEM
+      renameScripts
+         .add("ALTER TABLE JCR_" + isMultiDB + "ITEM RENAME TO JCR_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_PK_"
+         + isMultiDB + "ITEM TO JCR_PK_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_FK_"
+         + isMultiDB + "ITEM_PARENT TO JCR_FK_" + isMultiDB + "ITEM_PARENT" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "ITEM RENAME TO JCR_PK_" + isMultiDB + "ITEM"
+         + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_FK RENAME TO JCR_IDX_" + isMultiDB
+         + "ITEM_PARENT_FK" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT RENAME TO JCR_IDX_" + isMultiDB
+         + "ITEM_PARENT" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_NAME RENAME TO JCR_IDX_" + isMultiDB
+         + "ITEM_PARENT_NAME" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_ID RENAME TO JCR_IDX_" + isMultiDB
+         + "ITEM_PARENT_ID" + OLD_OBJECT_SUFFIX);
+
+      // JCR_[S,M]CONTAINER
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "CONTAINER RENAME TO JCR_" + isMultiDB + "CONTAINER"
+         + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "CONTAINER" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_PK_"
+         + isMultiDB + "CONTAINER TO JCR_PK_" + isMultiDB + "CONTAINER" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "CONTAINER RENAME TO JCR_PK_" + isMultiDB + "CONTAINER"
+         + OLD_OBJECT_SUFFIX);
+
+      // JCR_[S,M]REF
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "REF RENAME TO JCR_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER TABLE JCR_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX + " RENAME CONSTRAINT JCR_PK_"
+         + isMultiDB + "REF TO JCR_PK_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "REF RENAME TO JCR_PK_" + isMultiDB + "REF"
+         + OLD_OBJECT_SUFFIX);
+      renameScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "REF_PROPERTY RENAME TO JCR_IDX_" + isMultiDB
+         + "REF_PROPERTY" + OLD_OBJECT_SUFFIX);
+
+      return renameScripts;
+   }
+
+   /**
+    * Create script to rollback changes after rename.
+    * 
+    * @param multiDb
+    *          boolean
+    * @param dialect
+    *          string
+    * @return List 
+    *           return list with query
+    */
+   protected static List<String> getRollbackRenamedScript(boolean multiDb, String dialect)
+   {
+      final String isMultiDB = (multiDb ? "M" : "S");
+
+      List<String> rollbackScripts = new ArrayList<String>();
+
+      rollbackScripts.addAll(getDropTableScripts(multiDb, dialect));
+
+      // JCR_[S,M]VALUE
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_" + isMultiDB
+         + "VALUE");
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE RENAME CONSTRAINT JCR_PK_" + isMultiDB
+         + "VALUE" + OLD_OBJECT_SUFFIX + " TO JCR_PK_" + isMultiDB + "VALUE");
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "VALUE RENAME CONSTRAINT JCR_FK_" + isMultiDB
+         + "VALUE_PROPERTY" + OLD_OBJECT_SUFFIX + " TO JCR_FK_" + isMultiDB + "VALUE_PROPERTY");
+      rollbackScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_PK_"
+         + isMultiDB + "VALUE");
+      rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "VALUE_PROPERTY" + OLD_OBJECT_SUFFIX
+         + " RENAME TO JCR_IDX_" + isMultiDB + "VALUE_PROPERTY");
+
+      if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
+      {
+         rollbackScripts.add("RENAME JCR_" + isMultiDB + "VALUE_SEQ" + OLD_OBJECT_SUFFIX + " TO JCR_" + isMultiDB
+            + "VALUE_SEQ");
+         rollbackScripts.add("ALTER TRIGGER BI_JCR_" + isMultiDB + "VALUE" + OLD_OBJECT_SUFFIX + " RENAME TO BI_JCR_"
+            + isMultiDB + "VALUE");
+      }
+
+      // JCR_[S,M]ITEM
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_" + isMultiDB
+         + "ITEM");
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM RENAME CONSTRAINT JCR_PK_" + isMultiDB
+         + "ITEM" + OLD_OBJECT_SUFFIX + " TO JCR_PK_" + isMultiDB + "ITEM");
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "ITEM RENAME CONSTRAINT JCR_FK_" + isMultiDB
+         + "ITEM_PARENT" + OLD_OBJECT_SUFFIX + " TO JCR_FK_" + isMultiDB + "ITEM_PARENT");
+      rollbackScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "ITEM" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_PK_"
+         + isMultiDB + "ITEM");
+      rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_FK" + OLD_OBJECT_SUFFIX
+         + " RENAME TO JCR_IDX_" + isMultiDB + "ITEM_PARENT_FK");
+      rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT" + OLD_OBJECT_SUFFIX
+         + " RENAME TO JCR_IDX_" + isMultiDB + "ITEM_PARENT");
+      rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_NAME" + OLD_OBJECT_SUFFIX
+         + " RENAME TO JCR_IDX_" + isMultiDB + "ITEM_PARENT_NAME");
+      rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "ITEM_PARENT_ID" + OLD_OBJECT_SUFFIX
+         + " RENAME TO JCR_IDX_" + isMultiDB + "ITEM_PARENT_ID");
+
+      // JCR_[S,M]CONTAINER
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "CONTAINER" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_"
+         + isMultiDB + "CONTAINER");
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "CONTAINER RENAME CONSTRAINT JCR_PK_" + isMultiDB
+         + "CONTAINER" + OLD_OBJECT_SUFFIX + " TO JCR_PK_" + isMultiDB + "CONTAINER");
+      rollbackScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "CONTAINER" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_PK_"
+         + isMultiDB + "CONTAINER");
+
+      // JCR_[S,M]REF
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_" + isMultiDB
+         + "REF");
+      rollbackScripts.add("ALTER TABLE JCR_" + isMultiDB + "REF RENAME CONSTRAINT JCR_PK_" + isMultiDB
+         + "REF" + OLD_OBJECT_SUFFIX + " TO JCR_PK_" + isMultiDB + "REF");
+      rollbackScripts.add("ALTER INDEX JCR_PK_" + isMultiDB + "REF" + OLD_OBJECT_SUFFIX + " RENAME TO JCR_PK_"
+         + isMultiDB + "REF");
+      rollbackScripts.add("ALTER INDEX JCR_IDX_" + isMultiDB + "REF_PROPERTY" + OLD_OBJECT_SUFFIX
+         + " RENAME TO JCR_IDX_" + isMultiDB + "REF_PROPERTY");
+
+      return rollbackScripts;
+   }
+
+   /**
+    * Create script to drop old tables, indexes, etc...after successful restore DB. 
+    * 
+    * @param multiDb
+    *          boolean
+    * @param dialect
+    *         string  
+    * @return List 
+    *           return list with query
+    */
+   protected static List<String> getAfterRestoreScript(boolean multiDb, String dialect)
+   {
+      List<String> afterRetoreScripts = new ArrayList<String>();
+
+      for (String query : getDropTableScripts(multiDb, dialect))
+      {
+         afterRetoreScripts.add(query + OLD_OBJECT_SUFFIX);
+      }
+
+      return afterRetoreScripts;
+   }
+
+   /**
+    * Create list with queries to initialization database.
+    * 
+    * @param multiDb
+    * @param dialect
     * @return
+    * @throws RepositoryConfigurationException
+    */
+   protected static List<String> getInitializationDBScript(boolean multiDb, String dialect)
+      throws RepositoryConfigurationException
+   {
+      String scriptsPath = DBInitializerHelper.scriptPath(dialect, multiDb);
+      String script;
+      try
+      {
+         script = DBInitializerHelper.readScriptResource(scriptsPath);
+      }
+      catch (IOException e)
+      {
+         throw new RepositoryConfigurationException("Can not read script file " + scriptsPath, e);
+      }
+
+      List<String> scripts = new ArrayList<String>();
+
+      for (String query : DBInitializerHelper.scripts(script))
+      {
+         scripts.add(DBInitializerHelper.cleanWhitespaces(query));
+      }
+
+      String rootParent_container = DBInitializerHelper.getRootNodeInitializeScript(multiDb);
+
+      scripts.add(rootParent_container);
+
+      return scripts;
+   }
+
+   /**
+    * Returns database cleaner for manual cleaning for workspace.  
+    * 
+    * @param jdbcConn
+    *          database connection which need to use
+    * @param wsEntry
+    *          workspace configuration
+    * @return
     * @throws SQLException
     * @throws RepositoryConfigurationException
     */
-   public static DBClean getDBCleaner(Connection jdbcConn, WorkspaceEntry wsEntry) throws SQLException,
+   public static DBCleaner getWorkspaceDBCleaner(Connection jdbcConn, WorkspaceEntry wsEntry) throws SQLException,
       RepositoryConfigurationException
    {
       boolean multiDb =
@@ -139,7 +455,7 @@
       else if (dialect.equals(DBConstants.DB_DIALECT_MYSQL) || dialect.equals(DBConstants.DB_DIALECT_MYSQL_UTF8))
       {
          cleanWithHelper = true;
-         
+
          Statement st = jdbcConn.createStatement();
          st.execute("SELECT ENGINE FROM information_schema.TABLES where TABLE_SCHEMA='" + jdbcConn.getCatalog()
             + "' and (TABLE_NAME='JCR_SITEM' or TABLE_NAME='JCR_MITEM')");
@@ -155,30 +471,40 @@
       }
 
       List<String> cleanScripts = new ArrayList<String>();
+
       if (multiDb)
       {
-         cleanScripts.add("delete from JCR_MVALUE");
-         cleanScripts.add("delete from JCR_MREF");
-
-         if (cleanWithHelper)
+         if (dialect.equals(DBConstants.DB_DIALECT_SYBASE) || dialect.equals(DBConstants.DB_DIALECT_HSQLDB))
          {
-            cleanScripts.add("delete from JCR_MITEM where I_CLASS=2");
+            cleanScripts.add("delete from JCR_MVALUE");
+            cleanScripts.add("delete from JCR_MREF");
 
-            String selectItems = "select ID from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
-            String deleteItems = "delete from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
+            if (cleanWithHelper)
+            {
+               cleanScripts.add("delete from JCR_MITEM where I_CLASS=2");
 
-            return new DBClean(jdbcConn, cleanScripts, new DBCleanHelper(jdbcConn, selectItems, deleteItems));
+               String selectItems = "select ID from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
+               String deleteItems = "delete from JCR_MITEM where I_CLASS=1 and PARENT_ID=?";
+
+               return new DBCleaner(jdbcConn, cleanScripts, new RecursiveDBCleanHelper(jdbcConn, selectItems,
+                  deleteItems));
+            }
+
+            cleanScripts.add("delete from JCR_MITEM where JCR_MITEM.name <> '" + Constants.ROOT_PARENT_NAME + "'");
          }
-
-         cleanScripts.add("delete from JCR_MITEM where JCR_MITEM.NAME <> '" + Constants.ROOT_PARENT_NAME + "'");
+         else
+         {
+            cleanScripts.addAll(getDropTableScripts(multiDb, dialect));
+            cleanScripts.addAll(getInitializationDBScript(multiDb, dialect));
+         }
       }
       else
       {
          cleanScripts
-                  .add("delete from JCR_SVALUE where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SVALUE.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
+            .add("delete from JCR_SVALUE where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SVALUE.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
                + containerName + "')");
          cleanScripts
-                  .add("delete from JCR_SREF where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SREF.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
+            .add("delete from JCR_SREF where exists(select * from JCR_SITEM where JCR_SITEM.ID=JCR_SREF.PROPERTY_ID and JCR_SITEM.CONTAINER_NAME='"
                + containerName + "')");
 
          if (cleanWithHelper)
@@ -190,27 +516,24 @@
             String deleteItems =
                "delete from JCR_SITEM where I_CLASS=1 and CONTAINER_NAME='" + containerName + "' and PARENT_ID=?";
 
-            return new DBClean(jdbcConn, cleanScripts, new DBCleanHelper(jdbcConn, selectItems, deleteItems));
+            return new DBCleaner(jdbcConn, cleanScripts, new RecursiveDBCleanHelper(jdbcConn, selectItems, deleteItems));
          }
 
          cleanScripts.add("delete from JCR_SITEM where CONTAINER_NAME='" + containerName + "'");
       }
 
-      if (dialect.equals(DBConstants.DB_DIALECT_PGSQL))
+      if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
       {
-         return new PgSQLDBClean(jdbcConn, cleanScripts);
+         ArrayList<String> dbCleanerScripts = new ArrayList<String>();
+         dbCleanerScripts.addAll(getRenameScripts(multiDb, dialect));
+         dbCleanerScripts.addAll(getInitializationDBScript(multiDb, dialect));
+
+         return new DBCleaner(jdbcConn, dbCleanerScripts, getRollbackRenamedScript(multiDb, dialect),
+            getAfterRestoreScript(multiDb, dialect));
       }
-      else if (dialect.equals(DBConstants.DB_DIALECT_INGRES))
-      {
-         return new IngresSQLDBClean(jdbcConn, cleanScripts);
-      }
-      else if (dialect.equals(DBConstants.DB_DIALECT_ORACLE) || dialect.equals(DBConstants.DB_DIALECT_ORACLEOCI))
-      {
-         return new OracleDBClean(jdbcConn, cleanScripts);
-      }
       else
       {
-         return new DBClean(jdbcConn, cleanScripts);
+         return new DBCleaner(jdbcConn, cleanScripts);
       }
    }
 }

Copied: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleaner.java (from rev 4913, jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBClean.java)
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleaner.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleaner.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,245 @@
+/*
+ * 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.impl.clean.rdbms;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializer;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerHelper;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * The goal of this class is removing workspace data from database.
+ *
+ * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
+ * @version $Id: DBCleaner.java 3769 2011-01-04 15:36:06Z areshetnyak $
+ */
+public class DBCleaner
+{
+   /**
+    * Logger.
+    */
+   protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBClean");
+
+   /**
+    * Connection to database.
+    */
+   protected final Connection connection;
+
+   /**
+    * Pattern for JCR tables.
+    */
+   protected final Pattern dbObjectNamePattern;
+
+   /**
+    * Common clean scripts for database.
+    */
+   protected final List<String> cleanScripts = new ArrayList<String>();
+
+   /**
+    * Rollback scripts for database.
+    */
+   protected final List<String> rollbackScripts = new ArrayList<String>();
+
+   /**
+    * Commit scripts for database.
+    */
+   protected final List<String> commitScripts = new ArrayList<String>();
+
+   /**
+    * DB clean helper.
+    */
+   protected final DBCleanHelper dbCleanHelper;
+
+   /**
+    * DBCleaner constructor.
+    * 
+    * @param connection 
+    *          connection to database where workspace tables is placed
+    * @param cleanScripts
+    *          scripts for cleaning database         
+    */
+   public DBCleaner(Connection connection, List<String> cleanScripts)
+   {
+      this(connection, cleanScripts, null);
+   }
+
+   /**
+    * DBCleaner constructor.
+    * 
+    * @param connection 
+    *          connection to database where workspace tables is placed
+    * @param cleanScripts
+    *          scripts for cleaning database         
+    * @param dbCleanHelper
+    *          class which help to clean database by executing special queries
+    */
+   public DBCleaner(Connection connection, List<String> cleanScripts, DBCleanHelper dbCleanHelper)
+   {
+      this.dbObjectNamePattern = Pattern.compile(DBInitializer.SQL_OBJECTNAME, Pattern.CASE_INSENSITIVE);
+      this.connection = connection;
+      this.cleanScripts.addAll(cleanScripts);
+      this.dbCleanHelper = dbCleanHelper;
+   }
+
+   /**
+    * DBCleaner constructor.
+    * 
+    * @param connection 
+    *          connection to database where workspace tables is placed
+    * @param cleanScripts
+    *          scripts for cleaning database
+    * @param rollbackScripts
+    *          scripts for execution when something failed         
+    * @param commitScripts
+    *          scripts for removing temporary objects         
+    * @param dbCleanHelper
+    *          class which help to clean database by executing special queries
+    */
+   public DBCleaner(Connection connection, List<String> cleanScripts, List<String> rollbackScripts,
+      List<String> commitScripts, DBCleanHelper cleanHelper)
+   {
+      this(connection, cleanScripts, cleanHelper);
+      this.rollbackScripts.addAll(rollbackScripts);
+      this.commitScripts.addAll(commitScripts);
+   }
+
+   /**
+    * DBCleaner constructor.
+    * 
+    * @param connection 
+    *          connection to database where workspace tables is placed
+    * @param cleanScripts
+    *          scripts for cleaning database
+    * @param rollbackScripts
+    *          scripts for execution when something failed         
+    * @param commitScripts
+    *          scripts for removing temporary objects         
+    */
+   public DBCleaner(Connection connection, List<String> cleanScripts, List<String> rollbackScripts,
+      List<String> commitScripts)
+   {
+      this(connection, cleanScripts, rollbackScripts, commitScripts, null);
+   }
+
+   /**
+    * Clean data from database. The method doesn't close connection or perform commit.
+    * 
+    * @throws SQLException
+    *          if any errors occurred 
+    */
+   public void executeCleanScripts() throws SQLException
+   {
+      executeScripts(cleanScripts);
+
+      if (dbCleanHelper != null)
+      {
+         dbCleanHelper.executeCleanScripts();
+      }
+   }
+
+   /** 
+    * Rollback changes. The method doesn't close connection or perform commit.
+    *
+    * @throws SQLException
+    *          if any errors occurred 
+    */
+   public void executeRollbackScripts() throws SQLException
+   {
+      executeScripts(rollbackScripts);
+   }
+
+   /**
+    * Cleaning temporary objects. The method doesn't close connection or perform commit.
+    *
+    * @throws SQLException
+    *          if any errors occurred 
+    */
+   public void executeCommitScripts() throws SQLException
+   {
+      executeScripts(commitScripts);
+   }
+
+   /**
+    * Execute script on database.  
+    * 
+    * @param scripts
+    *          the scripts for execution 
+    * @throws SQLException
+    *          if any exception occurred
+    */
+   protected void executeScripts(List<String> scripts) throws SQLException
+   {
+      SecurityManager security = System.getSecurityManager();
+      if (security != null)
+      {
+         security.checkPermission(JCRRuntimePermissions.MANAGE_REPOSITORY_PERMISSION);
+      }
+
+      Statement st = connection.createStatement();
+      try
+      {
+         for (String scr : scripts)
+         {
+            String sql = DBInitializerHelper.cleanWhitespaces(scr.trim());
+            if (sql.length() > 0)
+            {
+               if (LOG.isDebugEnabled())
+               {
+                  LOG.debug("Execute script: \n[" + sql + "]");
+               }
+               executeQuery(st, sql);
+            }
+         }
+      }
+      finally
+      {
+         try
+         {
+            st.close();
+         }
+         catch (SQLException e)
+         {
+            LOG.error("Can't close the Statement." + e);
+         }
+      }
+   }
+
+   /**
+    * Execute query.
+    */
+   protected void executeQuery(final Statement statement, final String sql) throws SQLException
+   {
+      SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+      {
+         public Object run() throws Exception
+         {
+            statement.executeUpdate(sql);
+            return null;
+         }
+      });
+   }
+}

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DummyDBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DummyDBCleaner.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DummyDBCleaner.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2003-2011 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.impl.clean.rdbms;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
+ * @version $Id: DummyDBCleaner.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class DummyDBCleaner extends DBCleaner
+{
+
+   /**
+    * DummyDBCleaner constructor.
+    */
+   public DummyDBCleaner(Connection connection, List<String> cleanScripts)
+   {
+      super(connection, cleanScripts);
+   }
+
+   /**
+    * DummyDBCleaner constructor.
+    */
+   public DummyDBCleaner(Connection connection, List<String> cleanScripts, DBCleanHelper dbCleanHelper)
+   {
+      super(connection, cleanScripts, dbCleanHelper);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void executeCleanScripts() throws SQLException
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void executeCommitScripts() throws SQLException
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void executeRollbackScripts() throws SQLException
+   {
+   }
+}

Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/IngresSQLDBClean.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,50 +0,0 @@
-/*
- * 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.impl.clean.rdbms;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.List;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 
- *
- * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
- * @version $Id: IngresSQLDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
- */
-public class IngresSQLDBClean extends DBClean
-{
-
-   /**
-    * IngresSQLDBClean constructor.
-    */
-   public IngresSQLDBClean(Connection connection, List<String> cleanScripts)
-   {
-      super(connection, cleanScripts);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   protected boolean isTableExists(Connection conn, String tableName) throws SQLException
-   {
-      return super.isTableExists(conn, tableName.toLowerCase());
-   }
-}

Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/OracleDBClean.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,78 +0,0 @@
-/*
- * 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.impl.clean.rdbms;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.List;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 
- *
- * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
- * @version $Id: OracleDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
- */
-public class OracleDBClean extends DBClean
-{
-
-   /**
-    * PgSQLDBClean constructor.
-    */
-   public OracleDBClean(Connection connection, List<String> cleanScripts)
-   {
-      super(connection, cleanScripts);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   protected boolean isTableExists(Connection conn, String tableName) throws SQLException
-   {
-      Statement st = null;
-      try
-      {
-         st = conn.createStatement();
-         st.executeUpdate("SELECT 1 FROM " + tableName);
-         return true;
-      }
-      catch (SQLException e)
-      {
-         // check: ORA-00942: table or view does not exist
-         if (e.getMessage().indexOf("ORA-00942") >= 0)
-            return false;
-         throw e;
-      }
-      finally
-      {
-         if (st != null)
-         {
-            try
-            {
-               st.close();
-            }
-            catch (SQLException e)
-            {
-               LOG.error("Can't close the Statement: " + e);
-            }
-         }
-      }
-   }
-}

Deleted: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/PgSQLDBClean.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -1,50 +0,0 @@
-/*
- * 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.impl.clean.rdbms;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.List;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 
- *
- * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
- * @version $Id: PgSQLDBClean.java 3655 2010-12-10 08:25:41Z tolusha $
- */
-public class PgSQLDBClean extends DBClean
-{
-
-   /**
-    * PgSQLDBClean constructor.
-    */
-   public PgSQLDBClean(Connection connection, List<String> cleanScripts)
-   {
-      super(connection, cleanScripts);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   protected boolean isTableExists(Connection conn, String tableName) throws SQLException
-   {
-      return super.isTableExists(conn, tableName.toLowerCase());
-   }
-}

Copied: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/RecursiveDBCleanHelper.java (from rev 4913, jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/DBCleanHelper.java)
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/RecursiveDBCleanHelper.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/clean/rdbms/RecursiveDBCleanHelper.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,148 @@
+/*
+ * 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.impl.clean.rdbms;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.security.PrivilegedExceptionAction;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * 
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 21.01.2011
+ * 
+ * @author <a href="mailto:anatoliy.bazko at exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: RecursiveDBCleanHelper.java.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class RecursiveDBCleanHelper implements DBCleanHelper
+{
+
+   /**
+    * Logger.
+    */
+   protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.RecursiveDBCleanHelper");
+
+   /**
+    * Select items query.
+    */
+   private final String selectItems;
+
+   /**
+    * Remove items query.
+    */
+   private final String removeItems;
+
+   /**
+    * Connection to database.
+    */
+   protected final Connection connection;
+
+   /**
+    * DBCleanerHelper constructor.
+    */
+   public RecursiveDBCleanHelper(Connection connection, String selectItemds, String removeItems)
+   {
+      this.connection = connection;
+      this.selectItems = selectItemds;
+      this.removeItems = removeItems;
+   }
+
+   /**
+    * Removing rows from table. Some database do not support cascade delete, 
+    * or need special sittings. In such case will be used deleting like
+    * visitor does. First traverse to the bottom of the tree and then go up to the root
+    * and perform deleting children.
+    * 
+    * @throws SQLException 
+    *          SQL exception. 
+    */
+   public void executeCleanScripts() throws SQLException
+   {
+      recursiveClean(Constants.ROOT_PARENT_UUID);
+   }
+
+   private void recursiveClean(String parentID) throws SQLException
+   {
+      PreparedStatement selectStatement = null;
+      PreparedStatement removeStatement = null;
+      ResultSet result = null;
+
+      try
+      {
+         selectStatement = connection.prepareStatement(this.selectItems);
+         selectStatement.setString(1, parentID);
+
+         final PreparedStatement fSelectStatement = selectStatement;
+         result = (ResultSet)SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+         {
+            public Object run() throws Exception
+            {
+               return fSelectStatement.executeQuery();
+            }
+         });
+
+         // recursive traversing to the bottom of the tree
+         if (result.next())
+         {
+            do
+            {
+               recursiveClean(result.getString(1));
+            }
+            while (result.next());
+
+            // go up to the root and remove all nodes
+            removeStatement = connection.prepareStatement(this.removeItems);
+            removeStatement.setString(1, parentID);
+
+            final PreparedStatement fRemoveStatement = removeStatement;
+            SecurityHelper.doPrivilegedSQLExceptionAction(new PrivilegedExceptionAction<Object>()
+            {
+               public Object run() throws Exception
+               {
+                  fRemoveStatement.executeUpdate();
+                  return null;
+               }
+            });
+         }
+      }
+      finally
+      {
+         if (selectStatement != null)
+         {
+            selectStatement.close();
+         }
+
+         if (removeStatement != null)
+         {
+            removeStatement.close();
+         }
+
+         if (result != null)
+         {
+            result.close();
+         }
+      }
+   }
+}

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -32,13 +32,18 @@
 import org.exoplatform.services.jcr.impl.backup.Backupable;
 import org.exoplatform.services.jcr.impl.backup.ComplexDataRestore;
 import org.exoplatform.services.jcr.impl.backup.DataRestore;
+import org.exoplatform.services.jcr.impl.backup.rdbms.DB2DBRestore;
 import org.exoplatform.services.jcr.impl.backup.rdbms.DBBackup;
 import org.exoplatform.services.jcr.impl.backup.rdbms.DBRestore;
 import org.exoplatform.services.jcr.impl.backup.rdbms.DataRestoreContext;
 import org.exoplatform.services.jcr.impl.backup.rdbms.DirectoryRestore;
+import org.exoplatform.services.jcr.impl.backup.rdbms.H2DBRestore;
+import org.exoplatform.services.jcr.impl.backup.rdbms.MySQLDBRestore;
+import org.exoplatform.services.jcr.impl.backup.rdbms.OracleDBRestore;
 import org.exoplatform.services.jcr.impl.backup.rdbms.RestoreTableRule;
 import org.exoplatform.services.jcr.impl.backup.rdbms.SybaseDBRestore;
 import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
 import org.exoplatform.services.jcr.impl.core.query.NodeDataIndexingIterator;
 import org.exoplatform.services.jcr.impl.core.query.Reindexable;
 import org.exoplatform.services.jcr.impl.dataflow.serialization.ObjectReaderImpl;
@@ -61,6 +66,7 @@
 import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
 import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
 import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerException;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerHelper;
 import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
 import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
 import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
@@ -270,7 +276,7 @@
       String pDbDialect = null;
       try
       {
-         pDbDialect = validateDialect(wsConfig.getContainer().getParameterValue(DB_DIALECT));
+         pDbDialect = DBInitializerHelper.validateDialect(wsConfig.getContainer().getParameterValue(DB_DIALECT));
       }
       catch (RepositoryConfigurationException e)
       {
@@ -642,7 +648,7 @@
                   valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
          }
 
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
 
          // a particular db initializer may be configured here too
          dbInitilizer = new OracleDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
@@ -650,13 +656,13 @@
       else if (dbDialect == DBConstants.DB_DIALECT_ORACLE)
       {
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = new OracleDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_PGSQL)
       {
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.pgsql.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = new PgSQLDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_MYSQL)
@@ -675,7 +681,7 @@
                   valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
          }
 
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_MYSQL_UTF8)
@@ -694,43 +700,43 @@
                   valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
          }
 
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql-utf8.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_MSSQL)
       {
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mssql.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_DERBY)
       {
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.derby.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_DB2)
       {
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_DB2V8)
       {
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2v8.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
       {
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sybase.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
       else if (dbDialect == DBConstants.DB_DIALECT_INGRES)
       {
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ingres.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          // using Postgres initializer
          dbInitilizer =
             new IngresSQLDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
@@ -749,14 +755,14 @@
                new HSQLDBConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
                   valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
          }
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
       else
       {
          // generic, DB_HSQLDB
          this.connFactory = defaultConnectionFactory();
-         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+         sqlPath = DBInitializerHelper.scriptPath(dbDialect, multiDb);
          dbInitilizer = defaultDBInitializer(sqlPath);
       }
 
@@ -781,19 +787,6 @@
       return connFactory;
    }
 
-   protected String validateDialect(String confParam)
-   {
-      for (String dbType : DBConstants.DB_DIALECTS)
-      {
-         if (dbType.equalsIgnoreCase(confParam))
-         {
-            return dbType;
-         }
-      }
-
-      return DBConstants.DB_DIALECT_GENERIC; // by default
-   }
-
    /**
     * {@inheritDoc}
     */
@@ -1294,15 +1287,43 @@
          }
          tables.put(dstTableName, restoreTableRule);
 
-         if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
+         DBCleaner dbCleaner = null;
+         if (context.getObject(DataRestoreContext.DB_CLEANER) != null)
          {
-            restorers.add(new SybaseDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
+            dbCleaner = (DBCleaner)context.getObject(DataRestoreContext.DB_CLEANER);
          }
          else
          {
-            restorers.add(new DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
+            dbCleaner = DBCleanService.getWorkspaceDBCleaner(jdbcConn, wsConfig);
          }
 
+         if (dbDialect == DBConstants.DB_DIALECT_DB2 || dbDialect == DBConstants.DB_DIALECT_DB2V8)
+         {
+            restorers.add(new DB2DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+         }
+         else if (dbDialect == DBConstants.DB_DIALECT_MYSQL || dbDialect == DBConstants.DB_DIALECT_MYSQL_UTF8)
+         {
+            restorers.add(new MySQLDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+         }
+         else if (dbDialect == DBConstants.DB_DIALECT_H2)
+         {
+            restorers.add(new H2DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+         }
+         else if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
+         {
+            restorers.add(new SybaseDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+         }
+         else if (dbDialect == DBConstants.DB_DIALECT_ORACLE || dbDialect == DBConstants.DB_DIALECT_ORACLEOCI)
+         {
+            restorers.add(new OracleDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+         }
+         else
+         {
+            restorers.add(new DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner, dbCleaner));
+         }
+
+         // prepare value storage restorer
+         File backupValueStorageDir = new File(storageDir, "values");
          if (wsConfig.getContainer().getValueStorages() != null)
          {
             List<File> dataDirs = new ArrayList<File>();

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/init/StorageDBInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/init/StorageDBInitializer.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/init/StorageDBInitializer.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -20,6 +20,7 @@
 
 import org.exoplatform.services.jcr.impl.Constants;
 import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializer;
+import org.exoplatform.services.jcr.impl.util.jdbc.DBInitializerHelper;
 
 import java.io.IOException;
 import java.sql.Connection;
@@ -58,11 +59,7 @@
 
       if (!connection.createStatement().executeQuery(select).next())
       {
-         String insert =
-            "insert into JCR_" + MDB + "ITEM(ID, PARENT_ID, NAME, " + (multiDb ? "" : "CONTAINER_NAME, ")
-               + "VERSION, I_CLASS, I_INDEX, N_ORDER_NUM)" + " VALUES('" + Constants.ROOT_PARENT_UUID + "', '"
-               + Constants.ROOT_PARENT_UUID + "', '" + Constants.ROOT_PARENT_NAME + "', "
-               + (multiDb ? "" : "'" + Constants.ROOT_PARENT_CONAINER_NAME + "', ") + "0, 0, 0, 0)";
+         String insert = DBInitializerHelper.getRootNodeInitializeScript(multiDb);
 
          connection.createStatement().executeUpdate(insert);
       }

Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -25,8 +25,6 @@
 import org.exoplatform.services.log.Log;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
 import java.sql.Connection;
@@ -47,10 +45,6 @@
 public class DBInitializer
 {
 
-   static public String SQL_DELIMITER = ";";
-
-   static public String SQL_DELIMITER_COMMENT_PREFIX = "/*$DELIMITER:";
-
    static public String SQL_CREATETABLE = "^(CREATE(\\s)+TABLE(\\s)+(IF(\\s)+NOT(\\s)+EXISTS(\\s)+)*){1}";
 
    static public String SQL_CREATEVIEW = "^(CREATE(\\s)+VIEW(\\s)+(IF(\\s)+NOT(\\s)+EXISTS(\\s)+)*){1}";
@@ -109,70 +103,9 @@
 
    protected String script(String scriptPath) throws IOException
    {
-      return readScriptResource(scriptPath);
+      return DBInitializerHelper.readScriptResource(scriptPath);
    }
 
-   protected String readScriptResource(final String path) throws IOException
-   {
-      PrivilegedAction<InputStream> action = new PrivilegedAction<InputStream>()
-      {
-         public InputStream run()
-         {
-            return this.getClass().getResourceAsStream(path);
-         }
-      };
-      final InputStream is = SecurityHelper.doPrivilegedAction(action);
-
-      PrivilegedAction<InputStreamReader> actionGetReader = new PrivilegedAction<InputStreamReader>()
-      {
-         public InputStreamReader run()
-         {
-            return new InputStreamReader(is);
-         }
-      };
-      InputStreamReader isr = SecurityHelper.doPrivilegedAction(actionGetReader);
-
-      try
-      {
-         StringBuilder sbuff = new StringBuilder();
-         char[] buff = new char[is.available()];
-         int r = 0;
-         while ((r = isr.read(buff)) > 0)
-         {
-            sbuff.append(buff, 0, r);
-         }
-
-         return sbuff.toString();
-      }
-      finally
-      {
-         try
-         {
-            is.close();
-         }
-         catch (IOException e)
-         {
-         }
-      }
-   }
-
-   public String cleanWhitespaces(String string)
-   {
-      if (string != null)
-      {
-         char[] cc = string.toCharArray();
-         for (int ci = cc.length - 1; ci > 0; ci--)
-         {
-            if (Character.isWhitespace(cc[ci]))
-            {
-               cc[ci] = ' ';
-            }
-         }
-         return new String(cc);
-      }
-      return string;
-   }
-
    protected boolean isTableExists(final Connection conn, final String tableName) throws SQLException
    {
       return SecurityHelper.doPrivilegedAction(new PrivilegedAction<Boolean>()
@@ -317,32 +250,7 @@
 
    public void init() throws DBInitializerException
    {
-      String[] scripts = null;
-      if (script.startsWith(SQL_DELIMITER_COMMENT_PREFIX))
-      {
-         // read custom prefix
-         try
-         {
-            String s = script.substring(SQL_DELIMITER_COMMENT_PREFIX.length());
-            int endOfDelimIndex = s.indexOf("*/");
-            String delim = s.substring(0, endOfDelimIndex).trim();
-            s = s.substring(endOfDelimIndex + 2).trim();
-            scripts = s.split(delim);
-         }
-         catch (IndexOutOfBoundsException e)
-         {
-            LOG.warn("Error of parse SQL-script file. Invalid DELIMITER configuration. Valid format is '"
-               + SQL_DELIMITER_COMMENT_PREFIX + "XXX*/' at begin of the SQL-script file, where XXX - DELIMITER string."
-               + " Spaces will be trimed. ", e);
-            LOG.info("Using DELIMITER:[" + SQL_DELIMITER + "]");
-            scripts = script.split(SQL_DELIMITER);
-         }
-      }
-      else
-      {
-         scripts = script.split(SQL_DELIMITER);
-      }
-
+      String[] scripts = DBInitializerHelper.scripts(script);
       String sql = null;
       Statement st = null;
       Set<String> existingTables = new HashSet<String>();
@@ -355,7 +263,7 @@
          connection.setAutoCommit(true);
          for (String scr : scripts)
          {
-            String s = cleanWhitespaces(scr.trim());
+            String s = DBInitializerHelper.cleanWhitespaces(scr.trim());
             if (s.length() > 0)
             {
                if (isObjectExists(connection, sql = s, existingTables))

Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializerHelper.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializerHelper.java	                        (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializerHelper.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2003-2011 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.impl.util.jdbc;
+
+import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.PrivilegedAction;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak at exoplatform.com.ua">Alex Reshetnyak</a> 
+ * @version $Id: DBInitializerHelper.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class DBInitializerHelper
+{
+   /**
+    * Logger.
+    */
+   protected final static Log LOG = ExoLogger.getLogger("exo.jcr.component.core.DBInitializerHelper");
+   
+   /**
+    * Default SQL delimiter.
+    */
+   static public String SQL_DELIMITER = ";";
+
+   /**
+    * SQL delimiter comment prefix.
+    */
+   static public String SQL_DELIMITER_COMMENT_PREFIX = "/*$DELIMITER:";
+
+   /**
+    * Getting path to initialization by specific dialect and multidb.
+    * 
+    * @param dbDialect
+    *          String
+    * @param multiDb
+    *          Boolean
+    * @return String
+    *           Path to DB initialization script.
+    */
+   public static String scriptPath(String dbDialect, boolean multiDb)
+   {
+      String sqlPath = null;
+      if (dbDialect == DBConstants.DB_DIALECT_ORACLEOCI)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_ORACLE)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_PGSQL)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.pgsql.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_MYSQL)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_MYSQL_UTF8)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql-utf8.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_MSSQL)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mssql.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_DERBY)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.derby.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_DB2)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_DB2V8)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2v8.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sybase.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_INGRES)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ingres.sql";
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_HSQLDB)
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+      }
+      else
+      {
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+      }
+
+      return sqlPath;
+   }
+
+   /**
+    * Validate dialect.
+    * 
+    * @param confParam
+    *          String, dialect from configuration.
+    * @return String
+    *           return dialect. By default return DB_DIALECT_GENERIC. 
+    * 
+    */
+   public static String validateDialect(String confParam)
+   {
+      for (String dbType : DBConstants.DB_DIALECTS)
+      {
+         if (dbType.equalsIgnoreCase(confParam))
+         {
+            return dbType;
+         }
+      }
+
+      return DBConstants.DB_DIALECT_GENERIC; // by default
+   }
+
+   /**
+    * Read DB initialization script as string.
+    * 
+    * @param path
+    *          String, path to DB initialization script.
+    * @return String,
+    *           DB initialization script as string.
+    * @throws IOException
+    *           Will throw IOException if file with DB initialization script is not exists.
+    */
+   public static String readScriptResource(final String path) throws IOException
+   {
+      PrivilegedAction<InputStream> action = new PrivilegedAction<InputStream>()
+      {
+         public InputStream run()
+         {
+            return this.getClass().getResourceAsStream(path);
+         }
+      };
+      final InputStream is = SecurityHelper.doPrivilegedAction(action);
+
+      PrivilegedAction<InputStreamReader> actionGetReader = new PrivilegedAction<InputStreamReader>()
+      {
+         public InputStreamReader run()
+         {
+            return new InputStreamReader(is);
+         }
+      };
+      InputStreamReader isr = SecurityHelper.doPrivilegedAction(actionGetReader);
+
+      try
+      {
+         StringBuilder sbuff = new StringBuilder();
+         char[] buff = new char[is.available()];
+         int r = 0;
+         while ((r = isr.read(buff)) > 0)
+         {
+            sbuff.append(buff, 0, r);
+         }
+
+         return sbuff.toString();
+      }
+      finally
+      {
+         try
+         {
+            is.close();
+         }
+         catch (IOException e)
+         {
+         }
+      }
+   }
+   
+   /**
+    * Determinate DB initialization script by separate query.
+    * 
+    * @param script
+    *         String, DB initialization script as String. 
+    * @return String[]
+    *           Queries to DB initialization.
+    */
+   public static String[] scripts(String script)
+   {
+      if (script.startsWith(SQL_DELIMITER_COMMENT_PREFIX))
+      {
+         // read custom prefix
+         try
+         {
+            String s = script.substring(SQL_DELIMITER_COMMENT_PREFIX.length());
+            int endOfDelimIndex = s.indexOf("*/");
+            String delim = s.substring(0, endOfDelimIndex).trim();
+            s = s.substring(endOfDelimIndex + 2).trim();
+            return s.split(delim);
+         }
+         catch (IndexOutOfBoundsException e)
+         {
+            LOG.warn("Error of parse SQL-script file. Invalid DELIMITER configuration. Valid format is '"
+                     + SQL_DELIMITER_COMMENT_PREFIX
+                     + "XXX*/' at begin of the SQL-script file, where XXX - DELIMITER string."
+                     + " Spaces will be trimed. ", e);
+            LOG.info("Using DELIMITER:[" + SQL_DELIMITER + "]");
+            return script.split(SQL_DELIMITER);
+         }
+      }
+      else
+      {
+         return script.split(SQL_DELIMITER);
+      }
+   }
+
+   /**
+    * Initialization script for root node.
+    * 
+    * @param multiDb
+    *          indicates if we have multi-db configuration or not
+    * @return SQL script
+    */
+   public static String getRootNodeInitializeScript(boolean multiDb)
+   {
+      return "insert into JCR_" + (multiDb ? "M" : "S") + "ITEM(ID, PARENT_ID, NAME, " + (multiDb ? "" : "CONTAINER_NAME, ") 
+         + "VERSION, I_CLASS, I_INDEX, N_ORDER_NUM)" + " VALUES('"
+         + Constants.ROOT_PARENT_UUID + "', '" + Constants.ROOT_PARENT_UUID + "', '" + Constants.ROOT_PARENT_NAME
+         + "', " + (multiDb ? "" : "'" + Constants.ROOT_PARENT_CONAINER_NAME + "', ") + "0, 0, 0, 0)";
+   }
+
+   /**
+    * Cleans redundant whitespaces from query.
+    */
+   public static String cleanWhitespaces(String string)
+   {
+      if (string != null)
+      {
+         char[] cc = string.toCharArray();
+         for (int ci = cc.length - 1; ci > 0; ci--)
+         {
+            if (Character.isWhitespace(cc[ci]))
+            {
+               cc[ci] = ' ';
+            }
+         }
+         return new String(cc);
+      }
+      return string;
+   }
+}

Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java	2011-10-05 12:23:45 UTC (rev 5023)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/util/jdbc/TestDBCleaner.java	2011-10-05 13:36:58 UTC (rev 5024)
@@ -21,6 +21,7 @@
 import org.exoplatform.services.jcr.config.RepositoryEntry;
 import org.exoplatform.services.jcr.config.WorkspaceEntry;
 import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
+import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleaner;
 import org.exoplatform.services.jcr.impl.core.NodeImpl;
 import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
 import org.exoplatform.services.jcr.impl.core.SessionImpl;
@@ -219,6 +220,96 @@
       service.removeRepository(repositoryName);
    }
 
+   public void testRemoveRepositorySingleDBRepositoryDBCleaner() throws Exception
+   {
+      String repositoryName = "repoTestRemoveSingleRepositoryDBCleaner";
+
+      RepositoryEntry repositoryEntry = createSingleDB(repositoryName);
+
+      RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+      RepositoryImpl newRepository = (RepositoryImpl)service.getRepository(repositoryName);
+      assertTrue(service.canRemoveRepository(repositoryName));
+
+      String wsName = repositoryEntry.getWorkspaceEntries().get(0).getName();
+      SessionImpl sess = newRepository.getSystemSession(wsName);
+
+      // now add nodes to workspaces and check it via datasource      
+      NodeImpl node = (NodeImpl)sess.getRootNode().addNode("testNode");
+      String id = node.getData().getIdentifier();
+      sess.save();
+      sess.logout();
+
+      DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
+      Connection conn = ds.getConnection();
+      Statement statement = conn.createStatement();
+      ResultSet res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
+      assertTrue(res.next());
+
+      // remove content
+      Connection jdbcConn = ds.getConnection();
+      jdbcConn.setAutoCommit(false);
+      DBCleaner repositoryDBCleaner = DBCleanService.getRepositoryDBCleaner(jdbcConn, repositoryEntry);
+
+      repositoryDBCleaner.executeCleanScripts();
+      jdbcConn.commit();
+      repositoryDBCleaner.executeCommitScripts();
+
+      // check - does JCR_SITEM become empty
+      res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
+      assertFalse(res.next());
+
+      res = statement.executeQuery("select * from JCR_SITEM");
+      assertTrue(res.next());
+      assertFalse(res.next());
+
+      statement.close();
+
+      service.removeRepository(repositoryName);
+   }
+
+   public void testRemoveRepositorySingleDBRepositoryDBCleanerRollBack() throws Exception
+   {
+      String repositoryName = "repoTestRemoveSingleRepositoryDBCleanerRollBack";
+
+      RepositoryEntry repositoryEntry = createSingleDB(repositoryName);
+
+      RepositoryService service = (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+      RepositoryImpl newRepository = (RepositoryImpl)service.getRepository(repositoryName);
+      assertTrue(service.canRemoveRepository(repositoryName));
+
+      String wsName = repositoryEntry.getWorkspaceEntries().get(0).getName();
+      SessionImpl sess = newRepository.getSystemSession(wsName);
+
+      // now add nodes to workspaces and check it via datasource      
+      NodeImpl node = (NodeImpl)sess.getRootNode().addNode("testNode");
+      String id = node.getData().getIdentifier();
+      sess.save();
+      sess.logout();
+
+      DataSource ds = (DataSource)new InitialContext().lookup(DS_NAME);
+      Connection conn = ds.getConnection();
+      Statement statement = conn.createStatement();
+      ResultSet res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
+      assertTrue(res.next());
+
+      // remove content
+      Connection jdbcConn = ds.getConnection();
+      jdbcConn.setAutoCommit(false);
+      DBCleaner repositoryDBCleaner = DBCleanService.getRepositoryDBCleaner(jdbcConn, repositoryEntry);
+
+      repositoryDBCleaner.executeCleanScripts();
+      jdbcConn.rollback();
+      repositoryDBCleaner.executeRollbackScripts();
+
+      // check - does JCR_SITEM become empty
+      res = statement.executeQuery("select * from JCR_SITEM where ID='" + wsName + id + "'");
+      assertTrue(res.next());
+
+      statement.close();
+
+      service.removeRepository(repositoryName);
+   }
+
    public void testRemoveWorkspaceMultiDB() throws Exception
    {
       String repositoryName = "repoTestRemoveMulti";
@@ -317,8 +408,8 @@
       repositoryEntry.setDefaultWorkspaceName(repositoryName + "ws");
 
       WorkspaceEntry workspaceEntry =
-         helper.getNewWs(repositoryName + "ws", true, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
-            wsEntry.getContainer(), false);
+         helper.getNewWs(repositoryName + "ws", true, DS_NAME, "target/temp/values/" + IdGenerator.generate(), wsEntry
+            .getContainer(), false);
 
       repositoryEntry.addWorkspace(workspaceEntry);
 
@@ -340,8 +431,8 @@
       repositoryEntry.setDefaultWorkspaceName(repositoryName + "ws");
 
       WorkspaceEntry workspaceEntry =
-         helper.getNewWs(repositoryName + "ws", false, DS_NAME, "target/temp/values/" + IdGenerator.generate(),
-            wsEntry.getContainer(), false);
+         helper.getNewWs(repositoryName + "ws", false, DS_NAME, "target/temp/values/" + IdGenerator.generate(), wsEntry
+            .getContainer(), false);
 
       repositoryEntry.addWorkspace(workspaceEntry);
 



More information about the exo-jcr-commits mailing list