[exo-jcr-commits] exo-jcr SVN: r1247 - in jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation: db and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Dec 29 11:50:32 EST 2009


Author: sergiykarpenko
Date: 2009-12-29 11:50:31 -0500 (Tue, 29 Dec 2009)
New Revision: 1247

Added:
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/DBConstants.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/NewSQLExceptionHandler.java
Removed:
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnectionIJ.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainerIJ.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java
Modified:
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java
   jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
Log:
EXOJCR-302: CQJDBCStorageConnection reverted to rev.1174

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -18,23 +18,9 @@
  */
 package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation;
 
-import java.io.File;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.jcr.InvalidItemStateException;
-import javax.jcr.RepositoryException;
-
 import org.exoplatform.services.jcr.access.AccessControlEntry;
 import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.dataflow.ItemState;
 import org.exoplatform.services.jcr.dataflow.persistent.PersistedNodeData;
 import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
 import org.exoplatform.services.jcr.datamodel.IllegalACLException;
@@ -47,76 +33,88 @@
 import org.exoplatform.services.jcr.datamodel.QPathEntry;
 import org.exoplatform.services.jcr.datamodel.ValueData;
 import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.ByteArrayPersistedValueData;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.CleanableFilePersistedValueData;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.StreamPersistedValueData;
+import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
 import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
+import org.exoplatform.services.jcr.impl.storage.jdbc.PrimaryTypeNotFoundException;
 import org.exoplatform.services.jcr.impl.storage.value.ValueStorageNotFoundException;
+import org.exoplatform.services.jcr.impl.storage.value.fs.operations.ValueFileIOHelper;
 import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.impl.util.io.SwapFile;
+import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
 import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
 import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
 
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
 /**
  * Created by The eXo Platform SAS.
  * 
  * @author <a href="mailto:gennady.azarenkov at exoplatform.com">Gennady Azarenkov</a>
  * @version $Id: JDBCStorageConnection.java 34801 2009-07-31 15:44:50Z dkatayev $
  */
-abstract public class CQJDBCStorageConnection extends JDBCStorageConnection
+abstract public class CQJDBCStorageConnection extends DBConstants implements WorkspaceStorageConnection
 {
 
    /**
-    * FIND_ITEM_BY_NAME NEW.
+    * Connection logger.
     */
-   protected String FIND_ITEM_BY_NAME_CQ;
+   protected static final Log LOG = ExoLogger.getLogger("jcr.JDBCStorageConnection");
 
    /**
-    * FIND_NODE_BY_ID.
+    * NODE type.
     */
-   protected String FIND_ITEM_BY_ID_CQ;
+   public static final int I_CLASS_NODE = 1;
 
    /**
-    * FIND_NODES_BY_PARENTID NEW.
+    * PROPERTY type.
     */
-   protected String FIND_NODES_BY_PARENTID_CQ;
+   public static final int I_CLASS_PROPERTY = 2;
 
-   /**
-    * GET_PROPERTIES_BY_PARENT_ID
-    */
-   protected String GET_PROPERTIES_BY_PARENTID_CQ;
+   protected final ValueStoragePluginProvider valueStorageProvider;
 
-   /**
-    * FIND_REFERENCE_PROPERTIES 
-    */
-   protected String FIND_REFERENCE_PROPERTIES;
+   protected final int maxBufferSize;
 
-   /**
-    * Class needed to store node details (property also) since result set is not sorted in valid way. 
-    */
-   private static class TempNodeData
-   {
-      String cid;
+   protected final File swapDirectory;
 
-      String cname;
+   protected final FileCleaner swapCleaner;
 
-      int cversion;
+   protected final Connection dbConnection;
 
-      String cpid;
+   protected final String containerName;
 
-      int cindex;
+   protected final NewSQLExceptionHandler exceptionHandler;
 
-      int cnordernumb;
+   protected final List<ValueIOChannel> valueChanges;
 
-      Map<String, List<byte[]>> properties = new HashMap<String, List<byte[]>>();
+   /**
+    * Read-only flag, if true the connection is marked as READ-ONLY.
+    */
+   protected final boolean readOnly;
 
-      public TempNodeData(ResultSet item) throws SQLException
-      {
-         cid = item.getString(COLUMN_ID);
-         cname = item.getString(COLUMN_NAME);
-         cversion = item.getInt(COLUMN_VERSION);
-         cpid = item.getString(COLUMN_PARENTID);
-         cindex = item.getInt(COLUMN_INDEX);
-         cnordernumb = item.getInt(COLUMN_NORDERNUM);
-      }
-   }
-
    /**
      * JDBCStorageConnection constructor.
      * 
@@ -139,32 +137,479 @@
       ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
       throws SQLException
    {
-      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+      this.valueStorageProvider = valueStorageProvider;
+
+      this.maxBufferSize = maxBufferSize;
+      this.swapDirectory = swapDirectory;
+      this.swapCleaner = swapCleaner;
+      this.containerName = containerName;
+
+      this.dbConnection = dbConnection;
+      this.readOnly = readOnly;
+
+      // Fix for Sybase jConnect JDBC driver bug.
+      // Which throws SQLException(JZ016: The AutoCommit option is already set to
+      // false)
+      // if conn.setAutoCommit(false) called twise or more times with value
+      // 'false'.
+      if (dbConnection.getAutoCommit())
+      {
+         dbConnection.setAutoCommit(false);
+      }
+
+      prepareQueries();
+      this.exceptionHandler = new NewSQLExceptionHandler(containerName, this);
+
+      this.valueChanges = new ArrayList<ValueIOChannel>();
    }
 
    /**
     * {@inheritDoc}
     */
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj == this)
+         return true;
+
+      if (obj instanceof JDBCStorageConnection)
+      {
+         JDBCStorageConnection another = (JDBCStorageConnection)obj;
+         return getJdbcConnection() == another.getJdbcConnection();
+      }
+
+      return false;
+   }
+
+   /**
+    * Return JDBC connection obtained from initialized data source. NOTE: Helper can obtain one new
+    * connection per each call of the method or return one obtained once.
+    */
+   public Connection getJdbcConnection()
+   {
+      return dbConnection;
+   }
+
+   /**
+    * Prepared queries at start time.
+    * 
+    * @throws SQLException
+    *           database error
+    */
+   abstract protected void prepareQueries() throws SQLException;
+
+   /**
+    * Used in Single Db Connection classes for Identifier related queries.
+    * 
+    * @param identifier
+    *          Item id
+    * @return String with container internal id
+    */
+   protected abstract String getInternalId(String identifier);
+
+   /**
+    * Used in loadXYZRecord methods for extract real Identifier from container value.
+    * 
+    * @param internalId
+    * @return
+    */
+   protected abstract String getIdentifier(String internalId);
+
+   // ---------------- WorkspaceStorageConnection -------------
+
+   /**
+    * @throws IllegalStateException
+    *           if connection is closed.
+    */
+   protected void checkIfOpened() throws IllegalStateException
+   {
+      if (!isOpened())
+         throw new IllegalStateException("Connection is closed");
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isOpened()
+   {
+      try
+      {
+         return !dbConnection.isClosed();
+      }
+      catch (SQLException e)
+      {
+         LOG.error(e);
+         return false;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public final void rollback() throws IllegalStateException, RepositoryException
+   {
+      checkIfOpened();
+      try
+      {
+         dbConnection.rollback();
+         dbConnection.close();
+
+         // rollback from the end
+         for (int p = valueChanges.size() - 1; p >= 0; p--)
+            valueChanges.get(p).rollback();
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+      catch (IOException e)
+      {
+         throw new RepositoryException(e);
+      }
+      finally
+      {
+         valueChanges.clear();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public final void close() throws IllegalStateException, RepositoryException
+   {
+      checkIfOpened();
+      try
+      {
+         // If READ-ONLY status back it to READ-WRITE (we assume it was original state)
+         if (readOnly)
+            dbConnection.setReadOnly(true);
+
+         dbConnection.close();
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public final void commit() throws IllegalStateException, RepositoryException
+   {
+      checkIfOpened();
+      try
+      {
+         dbConnection.commit();
+         dbConnection.close();
+
+         try
+         {
+            for (ValueIOChannel vo : valueChanges)
+               vo.commit();
+
+         }
+         catch (IOException e)
+         {
+            throw new RepositoryException(e);
+         }
+         finally
+         {
+            valueChanges.clear();
+         }
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void add(NodeData data) throws RepositoryException, UnsupportedOperationException, InvalidItemStateException,
+      IllegalStateException
+   {
+      checkIfOpened();
+      try
+      {
+         addNodeRecord(data);
+         if (LOG.isDebugEnabled())
+            LOG.debug("Node added " + data.getQPath().getAsString() + ", " + data.getIdentifier() + ", "
+               + data.getPrimaryTypeName().getAsString());
+
+      }
+      catch (SQLException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Node add. Database error: " + e);
+
+         exceptionHandler.handleAddException(e, data);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void add(PropertyData data) throws RepositoryException, UnsupportedOperationException,
+      InvalidItemStateException, IllegalStateException
+   {
+      checkIfOpened();
+
+      try
+      {
+         addPropertyRecord(data);
+
+         if (data.getType() == PropertyType.REFERENCE)
+         {
+            try
+            {
+               addReference(data);
+            }
+            catch (IOException e)
+            {
+               throw new RepositoryException("Can't read REFERENCE property (" + data.getQPath() + " "
+                  + data.getIdentifier() + ") value: " + e.getMessage(), e);
+            }
+         }
+
+         addValues(getInternalId(data.getIdentifier()), data);
+
+         if (LOG.isDebugEnabled())
+            LOG.debug("Property added " + data.getQPath().getAsString() + ", " + data.getIdentifier()
+               + (data.getValues() != null ? ", values count: " + data.getValues().size() : ", NULL data"));
+
+      }
+      catch (IOException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Property add. IO error: " + e, e);
+         throw new RepositoryException("Error of Property Value add " + e, e);
+      }
+      catch (SQLException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Property add. Database error: " + e, e);
+         exceptionHandler.handleAddException(e, data);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void rename(NodeData data) throws RepositoryException, UnsupportedOperationException,
+      InvalidItemStateException, IllegalStateException
+   {
+
+      checkIfOpened();
+      try
+      {
+         if (renameNode(data) <= 0)
+            throw new JCRInvalidItemStateException("(rename) Node not found " + data.getQPath().getAsString() + " "
+               + data.getIdentifier() + ". Probably was deleted by another session ", data.getIdentifier(),
+               ItemState.RENAMED);
+      }
+      catch (SQLException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Property add. Database error: " + e, e);
+         exceptionHandler.handleAddException(e, data);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void delete(NodeData data) throws RepositoryException, UnsupportedOperationException,
+      InvalidItemStateException, IllegalStateException
+   {
+      checkIfOpened();
+
+      final String cid = getInternalId(data.getIdentifier());
+
+      try
+      {
+         int nc = deleteItemByIdentifier(cid);
+         if (nc <= 0)
+            throw new JCRInvalidItemStateException("(delete) Node not found " + data.getQPath().getAsString() + " "
+               + data.getIdentifier() + ". Probably was deleted by another session ", data.getIdentifier(),
+               ItemState.DELETED);
+
+         if (LOG.isDebugEnabled())
+            LOG.debug("Node deleted " + data.getQPath().getAsString() + ", " + data.getIdentifier() + ", "
+               + ((NodeData)data).getPrimaryTypeName().getAsString());
+
+      }
+      catch (SQLException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Node remove. Database error: " + e, e);
+         exceptionHandler.handleDeleteException(e, data);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void delete(PropertyData data) throws RepositoryException, UnsupportedOperationException,
+      InvalidItemStateException, IllegalStateException
+   {
+      checkIfOpened();
+
+      final String cid = getInternalId(data.getIdentifier());
+
+      try
+      {
+         deleteValues(cid, data, false);
+
+         // delete references
+         deleteReference(cid);
+
+         // delete item
+         int nc = deleteItemByIdentifier(cid);
+         if (nc <= 0)
+            throw new JCRInvalidItemStateException("(delete) Property not found " + data.getQPath().getAsString() + " "
+               + data.getIdentifier() + ". Probably was deleted by another session ", data.getIdentifier(),
+               ItemState.DELETED);
+
+         if (LOG.isDebugEnabled())
+            LOG.debug("Property deleted "
+               + data.getQPath().getAsString()
+               + ", "
+               + data.getIdentifier()
+               + (((PropertyData)data).getValues() != null ? ", values count: "
+                  + ((PropertyData)data).getValues().size() : ", NULL data"));
+
+      }
+      catch (IOException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Property remove. IO error: " + e, e);
+         throw new RepositoryException("Error of Property Value delete " + e, e);
+      }
+      catch (SQLException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Property remove. Database error: " + e, e);
+         exceptionHandler.handleDeleteException(e, data);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void update(NodeData data) throws RepositoryException, UnsupportedOperationException,
+      InvalidItemStateException, IllegalStateException
+   {
+      checkIfOpened();
+      try
+      {
+         String cid = getInternalId(data.getIdentifier());
+         // order numb update
+         if (updateNodeByIdentifier(data.getPersistedVersion(), data.getQPath().getIndex(), data.getOrderNumber(), cid) <= 0)
+            throw new JCRInvalidItemStateException("(update) Node not found " + data.getQPath().getAsString() + " "
+               + data.getIdentifier() + ". Probably was deleted by another session ", data.getIdentifier(),
+               ItemState.UPDATED);
+
+         if (LOG.isDebugEnabled())
+            LOG.debug("Node updated " + data.getQPath().getAsString() + ", " + data.getIdentifier() + ", "
+               + data.getPrimaryTypeName().getAsString());
+
+      }
+      catch (SQLException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Node update. Database error: " + e, e);
+         exceptionHandler.handleUpdateException(e, data);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void update(PropertyData data) throws RepositoryException, UnsupportedOperationException,
+      InvalidItemStateException, IllegalStateException
+   {
+      checkIfOpened();
+
+      try
+      {
+         String cid = getInternalId(data.getIdentifier());
+
+         // update type
+         if (updatePropertyByIdentifier(data.getPersistedVersion(), data.getType(), cid) <= 0)
+            throw new JCRInvalidItemStateException("(update) Property not found " + data.getQPath().getAsString() + " "
+               + data.getIdentifier() + ". Probably was deleted by another session ", data.getIdentifier(),
+               ItemState.UPDATED);
+
+         // update reference
+         try
+         {
+            deleteReference(cid);
+
+            if (data.getType() == PropertyType.REFERENCE)
+            {
+               addReference(data);
+            }
+         }
+         catch (IOException e)
+         {
+            throw new RepositoryException("Can't update REFERENCE property (" + data.getQPath() + " "
+               + data.getIdentifier() + ") value: " + e.getMessage(), e);
+         }
+
+         // do Values update: delete all and add all
+         deleteValues(cid, data, true);
+         addValues(cid, data);
+
+         if (LOG.isDebugEnabled())
+            LOG.debug("Property updated " + data.getQPath().getAsString() + ", " + data.getIdentifier()
+               + (data.getValues() != null ? ", values count: " + data.getValues().size() : ", NULL data"));
+
+      }
+      catch (IOException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Property update. IO error: " + e, e);
+         throw new RepositoryException("Error of Property Value update " + e, e);
+      }
+      catch (SQLException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.error("Property update. Database error: " + e, e);
+         exceptionHandler.handleUpdateException(e, data);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
    public List<NodeData> getChildNodesData(NodeData parent) throws RepositoryException, IllegalStateException
    {
       checkIfOpened();
       try
       {
-         // query will return nodes and properties in same result set
-         ResultSet resultSet = findChildNodesByParentIdentifierCQ(getInternalId(parent.getIdentifier()));
+         //         ResultSet node = findChildNodesByParentIdentifier(getInternalId(parent.getIdentifier()));
+         //         List<NodeData> childrens = new ArrayList<NodeData>();
+         //         while (node.next())
+         //            childrens.add((NodeData)itemData(parent.getQPath(), node, I_CLASS_NODE, parent.getACL()));
+         //
+         //         return childrens;
+         ResultSet resultSet = findChildNodesByParentIdentifierNew(getInternalId(parent.getIdentifier()));
          if (resultSet.next())
          {
-            Map<String, TempNodeData> tempNodes = loadTempNodesFromResultSet(resultSet);
+            Map<String, TempNodeData> tempNodes = loadNodesData(resultSet, parent);
 
-            List<NodeData> childNodes = new ArrayList<NodeData>(tempNodes.size());
+            List<NodeData> childrens = new ArrayList<NodeData>(tempNodes.size());
             QPath parentQPath = parent.getQPath();
             AccessControlList parentACL = parent.getACL();
             for (TempNodeData data : tempNodes.values())
             {
-               NodeData nodeData = loadNodeFromTemporaryNodeData(data, parentQPath, parentACL);
-               childNodes.add(nodeData);
+               NodeData nodeData = loadNodeRecordFromBuffer(data, parentQPath, parentACL);
+               childrens.add(nodeData);
             }
-            return childNodes;
+            return childrens;
          }
          else
          {
@@ -182,7 +627,7 @@
       }
    }
 
-   protected Map<String, TempNodeData> loadTempNodesFromResultSet(ResultSet resultSet) throws RepositoryException,
+   protected Map<String, TempNodeData> loadNodesData(ResultSet resultSet, NodeData parent) throws RepositoryException,
       IOException, SQLException
    {
 
@@ -220,13 +665,57 @@
 
    }
 
+   private static class TempNodeData
+   {
+      String cid;
+
+      String cname;
+
+      int cversion;
+
+      String cpid;
+
+      int cindex;
+
+      int cnordernumb;
+
+      Map<String, List<byte[]>> properties = new HashMap<String, List<byte[]>>();
+
+      public TempNodeData(ResultSet item) throws SQLException
+      {
+         cid = item.getString(COLUMN_ID);
+         cname = item.getString(COLUMN_NAME);
+         cversion = item.getInt(COLUMN_VERSION);
+
+         cpid = item.getString(COLUMN_PARENTID);
+
+         cindex = item.getInt(COLUMN_INDEX);
+         cnordernumb = item.getInt(COLUMN_NORDERNUM);
+      }
+   }
+
    /**
     * {@inheritDoc}
     */
    public int getChildNodesCount(NodeData parent) throws RepositoryException
    {
-      // nothing to optimize
-      return super.getChildNodesCount(parent);
+      checkIfOpened();
+      try
+      {
+         ResultSet count = findChildNodesCountByParentIdentifier(getInternalId(parent.getIdentifier()));
+         if (count.next())
+         {
+            return count.getInt(1);
+         }
+         else
+         {
+            throw new RepositoryException("FATAL No resulton childNodes count for " + parent.getQPath().getAsString());
+         }
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
    }
 
    /**
@@ -238,7 +727,7 @@
       try
       {
 
-         ResultSet resultSet = getChildPropertiesByParentIdentifierCQ(getInternalId(parent.getIdentifier()));
+         ResultSet resultSet = getChildPropertiesByParentIdentifier(getInternalId(parent.getIdentifier()));
          List<PropertyData> children = new ArrayList<PropertyData>();
          if (resultSet.next())
          {
@@ -261,11 +750,29 @@
 
    /**
     * {@inheritDoc}
+    * 
+    * TODO left as current
     */
    public List<PropertyData> listChildPropertiesData(NodeData parent) throws RepositoryException, IllegalStateException
    {
-      // nothing to optimize   
-      return super.listChildPropertiesData(parent);
+      checkIfOpened();
+      try
+      {
+         ResultSet prop = findChildPropertiesByParentIdentifier(getInternalId(parent.getIdentifier()));
+         List<PropertyData> children = new ArrayList<PropertyData>();
+         while (prop.next())
+            children.add(propertyData(parent.getQPath(), prop));
+
+         return children;
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+      catch (IOException e)
+      {
+         throw new RepositoryException(e);
+      }
    }
 
    /**
@@ -276,9 +783,6 @@
       return getItemByIdentifier(getInternalId(identifier));
    }
 
-   /**
-    * {@inheritDoc}
-    */
    public ItemData getItemData(NodeData parentData, QPathEntry name) throws RepositoryException, IllegalStateException
    {
 
@@ -296,10 +800,38 @@
     */
    public List<PropertyData> getReferencesData(String nodeIdentifier) throws RepositoryException, IllegalStateException
    {
-      // can't optimize - result may return same node more than one time, so parse result set is difficult
-      return super.getReferencesData(nodeIdentifier);
+      checkIfOpened();
+      try
+      {
+         ResultSet refProps = findReferences(getInternalId(nodeIdentifier));
+         List<PropertyData> references = new ArrayList<PropertyData>();
+         while (refProps.next())
+         {
+            references.add((PropertyData)itemData(null, refProps, I_CLASS_PROPERTY, null));
+         }
+
+         //         ResultSet resultSet = findReferenceProperties(getInternalId(nodeIdentifier));
+         //         List<PropertyData> references = new ArrayList<PropertyData>(); //
+         //         if (resultSet.next())
+         //         {
+         //            while (!resultSet.isAfterLast())
+         //               references.add(loadPropertyRecord(resultSet, null));
+         //         }
+
+         return references;
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+      catch (IOException e)
+      {
+         throw new RepositoryException(e);
+      }
    }
 
+   // ------------------ Private methods ---------------
+
    /**
     * Get Item By Identifier.
     * 
@@ -317,14 +849,13 @@
       ResultSet resultSet = null;
       try
       {
-         resultSet = findItemByIdentifierCQ(cid);
+         resultSet = findItemByIdentifierNew(cid);
          if (resultSet.next())
          {
             int itemType = resultSet.getInt(COLUMN_CLASS);
             if (itemType == I_CLASS_NODE)
             {
-               Map<String, TempNodeData> node = loadTempNodesFromResultSet(resultSet);
-               return loadNodeFromTemporaryNodeData(node.get(cid), null, null);
+               return loadNodeRecord(resultSet, null, null);
             }
             else
             {
@@ -379,7 +910,7 @@
       ResultSet resultSet = null;
       try
       {
-         resultSet = findItemByNameCQ(parentId, name.getAsString(), name.getIndex());
+         resultSet = findItemByNameNew(parentId, name.getAsString(), name.getIndex());
          if (resultSet.next())
          {
             //  return itemData(parent.getQPath(), item, item.getInt(COLUMN_CLASS), parent.getACL());
@@ -390,14 +921,15 @@
                String firstNodeId = resultSet.getString(COLUMN_ID);
 
                // There may be two or more nodes, so load temp NodeDatas and return first one.
-               Map<String, TempNodeData> tempNodes = loadTempNodesFromResultSet(resultSet);
+               Map<String, TempNodeData> tempNodes = loadNodesData(resultSet, parent);
 
                QPath parentQPath = parent.getQPath();
                AccessControlList parentACL = parent.getACL();
 
-               NodeData nodeData = loadNodeFromTemporaryNodeData(tempNodes.get(firstNodeId), parentQPath, parentACL);
-               tempNodes.clear();
+               NodeData nodeData = loadNodeRecordFromBuffer(tempNodes.get(firstNodeId), parentQPath, parentACL);
                return nodeData;
+
+               //return loadNodeRecord(resultSet, parent.getQPath(), parent.getACL());
             }
             else
             {
@@ -429,57 +961,818 @@
       }
    }
 
-   protected List<AccessControlEntry> readACLPermisions(String cid, Map<String, List<byte[]>> properties)
-      throws SQLException, IllegalACLException
+   /**
+    * Build Item path by id.
+    * 
+    * @param cpid
+    *          - Item id (container id)
+    * @return Item QPath
+    * @throws SQLException
+    *           - if database error occurs
+    * @throws InvalidItemStateException
+    *           - if parent not found
+    * @throws IllegalNameException
+    *           - if name on the path is wrong
+    */
+   private QPath traverseQPath(String cpid) throws SQLException, InvalidItemStateException, IllegalNameException
    {
-      List<AccessControlEntry> naPermissions = new ArrayList<AccessControlEntry>();
-      List<byte[]> permValues = properties.get(Constants.EXO_PERMISSIONS.getAsString());
+      // get item by Identifier usecase
+      List<QPathEntry> qrpath = new ArrayList<QPathEntry>(); // reverted path
+      String caid = cpid; // container ancestor id
+      do
+      {
+         ResultSet parent = null;
+         try
+         {
+            parent = findItemByIdentifier(caid);
+            if (!parent.next())
+               throw new InvalidItemStateException("Parent not found, uuid: " + getIdentifier(caid));
 
-      if (permValues != null)
+            QPathEntry qpe =
+               new QPathEntry(InternalQName.parse(parent.getString(COLUMN_NAME)), parent.getInt(COLUMN_INDEX));
+            qrpath.add(qpe);
+            caid = parent.getString(COLUMN_PARENTID);
+         }
+         finally
+         {
+            parent.close();
+         }
+      }
+      while (!caid.equals(Constants.ROOT_PARENT_UUID));
+
+      QPathEntry[] qentries = new QPathEntry[qrpath.size()];
+      int qi = 0;
+      for (int i = qrpath.size() - 1; i >= 0; i--)
       {
-         for (byte[] value : permValues)
+         qentries[qi++] = qrpath.get(i);
+      }
+      return new QPath(qentries);
+   }
+
+   /**
+    * ItemLocationInfo.
+    * 
+    */
+   class ItemLocationInfo
+   {
+      /**
+       * Item qpath
+       */
+      final QPath qpath;
+
+      /**
+       * All ancestors of the item with qpath
+       */
+      final List<String> ancestors;
+
+      /**
+       * Item id.
+       */
+      final String itemId;
+
+      /**
+       * ItemLocationInfo constructor.
+       * 
+       * @param qpath
+       *          Item path
+       * @param ancestors
+       *          ancesstors id list
+       * @param itemId
+       *          Item id
+       */
+      ItemLocationInfo(QPath qpath, List<String> ancestors, String itemId)
+      {
+         this.qpath = qpath;
+         this.ancestors = ancestors;
+         this.itemId = itemId;
+      }
+   }
+
+   /**
+    * Find ancestor permissions by cpid. Will search till find the permissions or meet a root node.
+    * 
+    * @param cpid
+    *          - initial parent node id
+    * @return Collection<String>
+    * @throws SQLException
+    *           if database error
+    * @throws IllegalACLException
+    *           if wrong ACL
+    * @throws IllegalNameException
+    *           if wrong QName
+    * @throws RepositoryException
+    *           if Repository error
+    */
+   private List<AccessControlEntry> traverseACLPermissions(String cpid) throws SQLException, IllegalACLException,
+      IllegalNameException, RepositoryException
+   {
+      String caid = cpid;
+      while (!caid.equals(Constants.ROOT_PARENT_UUID))
+      {
+         MixinInfo naMixins = readMixins(caid);
+         if (naMixins.hasPrivilegeable())
+            return readACLPermisions(caid);
+
+         if (naMixins.parentId == null)
+            caid = findParentId(caid);
+         else
+            caid = naMixins.parentId;
+      }
+
+      throw new IllegalACLException("Can not find permissions for a node with id " + getIdentifier(cpid));
+   }
+
+   protected String findParentId(String cid) throws SQLException, RepositoryException
+   {
+      ResultSet pidrs = findItemByIdentifier(cid);
+      try
+      {
+         if (pidrs.next())
+            return pidrs.getString(COLUMN_PARENTID);
+         else
+            throw new RepositoryException("Item not found id: " + getIdentifier(cid));
+      }
+      finally
+      {
+         pidrs.close();
+      }
+   }
+
+   /**
+    * Find ancestor owner by cpid. Will search till find the owner or meet a root node.
+    * 
+    * @param cpid
+    *          - initial parent node id
+    * @return owner name
+    * @throws SQLException
+    *           if database error
+    * @throws IllegalACLException
+    *           if wrong ACL
+    * @throws IllegalNameException
+    *           if wrong QName
+    * @throws RepositoryException
+    *           if Repository error
+    */
+   private String traverseACLOwner(String cpid) throws SQLException, IllegalACLException, IllegalNameException,
+      RepositoryException
+   {
+      String caid = cpid;
+
+      while (!caid.equals(Constants.ROOT_PARENT_UUID))
+      {
+         MixinInfo naMixins = readMixins(caid);
+         if (naMixins.hasOwneable())
+            return readACLOwner(caid);
+
+         if (naMixins.parentId == null)
+            caid = findParentId(caid);
+         else
+            caid = naMixins.parentId;
+      }
+
+      throw new IllegalACLException("Can not find owner for a node with id " + getIdentifier(cpid));
+   }
+
+   /**
+    * Find ancestor ACL by cpid. Will search till find the ACL or meet a root node.
+    * 
+    * @param cpid
+    *          - initial parent node id
+    * @return owner name
+    * @throws SQLException
+    *           if database error
+    * @throws IllegalACLException
+    *           if wrong ACL
+    * @throws IllegalNameException
+    *           if wrong QName
+    * @throws RepositoryException
+    *           if Repository error
+    */
+   private AccessControlList traverseACL(String cpid) throws SQLException, IllegalACLException, IllegalNameException,
+      RepositoryException
+   {
+      String naOwner = null;
+      List<AccessControlEntry> naPermissions = null;
+
+      String caid = cpid;
+
+      while (!caid.equals(Constants.ROOT_PARENT_UUID))
+      {
+         MixinInfo naMixins = readMixins(caid);
+         if (naOwner == null && naMixins.hasOwneable())
          {
-            StringTokenizer parser = new StringTokenizer(new String(value), AccessControlEntry.DELIMITER);
-            naPermissions.add(new AccessControlEntry(parser.nextToken(), parser.nextToken()));
+            naOwner = readACLOwner(caid);
+            if (naPermissions != null)
+               break;
          }
+         if (naPermissions == null && naMixins.hasPrivilegeable())
+         {
+            naPermissions = readACLPermisions(caid);
+            if (naOwner != null)
+               break;
+         }
 
-         return naPermissions;
+         if (naMixins.parentId == null)
+            caid = findParentId(caid);
+         else
+            caid = naMixins.parentId;
       }
+
+      if (naOwner != null && naPermissions != null)
+      {
+         // got all
+         return new AccessControlList(naOwner, naPermissions);
+      }
+      else if (naOwner == null && naPermissions == null)
+      {
+         // Default values (i.e. ACL is disabled in repository)
+         return new AccessControlList();
+      }
       else
-         throw new IllegalACLException("Property exo:permissions is not found for node with id: " + getIdentifier(cid));
+         throw new IllegalACLException("ACL is not found for node with id " + getIdentifier(cpid)
+            + " or for its ancestors. But repository is ACL enabled.");
    }
 
-   protected String readACLOwner(String cid, Map<String, List<byte[]>> properties) throws IllegalACLException
+   /**
+    * [PN] Experimental. Use SP for traversing Qpath on the database server side. Hm, I haven't a
+    * good result for that yet. Few seconds only for TCK execution. PGSQL SP: CREATE OR REPLACE
+    * FUNCTION get_qpath(parentId VARCHAR) RETURNS SETOF record AS $$ DECLARE cur_item RECORD; cur_id
+    * varchar; BEGIN cur_id := parentId; WHILE NOT cur_id = ' ' LOOP SELECT id, name, parent_id,
+    * i_index INTO cur_item FROM JCR_SITEM WHERE ID=cur_id; IF NOT found THEN RETURN; END IF; RETURN
+    * NEXT cur_item; cur_id := cur_item.parent_id; END LOOP; RETURN; END; $$ LANGUAGE plpgsql;
+    * 
+    * @param cpid
+    * @return
+    * @throws SQLException
+    *           if database error
+    * @throws InvalidItemStateException
+    *           if Item state is obsolete
+    * @throws IllegalNameException
+    *           if invalid QName
+    */
+   private QPath traverseQPath_SP_PGSQL(String cpid) throws SQLException, InvalidItemStateException,
+      IllegalNameException
    {
-      List<byte[]> ownerValues = properties.get(Constants.EXO_OWNER.getAsString());
-      if (ownerValues != null)
-         return new String(ownerValues.get(0));
+      // get item by Identifier usecase:
+      // find parent path in db by cpid
+      if (cpid == null)
+      {
+         // root node
+         return null; // Constants.ROOT_PATH
+      }
       else
-         throw new IllegalACLException("Property exo:owner is not found for node with id: " + getIdentifier(cid));
+      {
+         List<QPathEntry> qrpath = new ArrayList<QPathEntry>(); // reverted path
+         PreparedStatement cstmt = null;
+         try
+         {
+            cstmt =
+               dbConnection
+                  .prepareStatement("select * from get_qpath(?) AS (id varchar, name varchar, parent_id varchar, i_index int)");
+            cstmt.setString(1, cpid);
+            // cstmt.setString(2, caid);
+            ResultSet parent = cstmt.executeQuery();
 
+            while (parent.next())
+            {
+               QPathEntry qpe =
+                  new QPathEntry(InternalQName.parse(parent.getString(COLUMN_NAME)), parent.getInt(COLUMN_INDEX));
+               qrpath.add(qpe);
+            }
+
+            // parent = findItemByIdentifier(caid);
+            if (qrpath.size() <= 0)
+               throw new InvalidItemStateException("Parent not found, uuid: " + getIdentifier(cpid));
+         }
+         finally
+         {
+            if (cstmt != null)
+               cstmt.close();
+         }
+
+         QPathEntry[] qentries = new QPathEntry[qrpath.size()];
+         int qi = 0;
+         for (int i = qrpath.size() - 1; i >= 0; i--)
+         {
+            qentries[qi++] = qrpath.get(i);
+         }
+         return new QPath(qentries);
+      }
    }
 
    /**
-    * Create NodeData from TempNodeData content.
+    * Build ItemData.
     * 
-    * @param tempData
     * @param parentPath
-    * @param pACL
-    * @return
+    *          - parent path
+    * @param item
+    *          database - ResultSet with Item record(s)
+    * @param itemClass
+    *          - Item type (Node or Property)
+    * @param parentACL
+    *          - parent ACL
+    * @return ItemData instance
     * @throws RepositoryException
+    *           Repository error
     * @throws SQLException
+    *           database error
     * @throws IOException
+    *           I/O error
     */
-   protected PersistedNodeData loadNodeFromTemporaryNodeData(TempNodeData tempData, QPath parentPath,
-      AccessControlList pACL) throws RepositoryException, SQLException, IOException
+   private ItemData itemData(QPath parentPath, ResultSet item, int itemClass, AccessControlList parentACL)
+      throws RepositoryException, SQLException, IOException
    {
+      String cid = item.getString(COLUMN_ID);
+      String cname = item.getString(COLUMN_NAME);
+      int cversion = item.getInt(COLUMN_VERSION);
 
-      String cid = tempData.cid;
-      String cname = tempData.cname;
-      int cversion = tempData.cversion;
-      String cpid = tempData.cpid;
-      int cindex = tempData.cindex;
-      int cnordernumb = tempData.cnordernumb;
+      String cpid = item.getString(COLUMN_PARENTID);
+      // if parent ID is empty string - it's a root node
+      // cpid = cpid.equals(Constants.ROOT_PARENT_UUID) ? null : cpid;
+
+      try
+      {
+         if (itemClass == I_CLASS_NODE)
+         {
+            int cindex = item.getInt(COLUMN_INDEX);
+            int cnordernumb = item.getInt(COLUMN_NORDERNUM);
+            return loadNodeRecord(parentPath, cname, cid, cpid, cindex, cversion, cnordernumb, parentACL);
+         }
+
+         int cptype = item.getInt(COLUMN_PTYPE);
+         boolean cpmultivalued = item.getBoolean(COLUMN_PMULTIVALUED);
+         return loadPropertyRecord(parentPath, cname, cid, cpid, cversion, cptype, cpmultivalued);
+      }
+      catch (InvalidItemStateException e)
+      {
+         throw new InvalidItemStateException("FATAL: Can't build item path for name " + cname + " id: "
+            + getIdentifier(cid) + ". " + e);
+      }
+   }
+
+   /**
+    * Read property data without value data. For listChildPropertiesData(NodeData).
+    * 
+    * @param parentPath
+    *          - parent path
+    * @param item
+    *          database - ResultSet with Item record(s)
+    * @return PropertyData instance
+    * @throws RepositoryException
+    *           Repository error
+    * @throws SQLException
+    *           database error
+    * @throws IOException
+    *           I/O error
+    */
+   private PropertyData propertyData(QPath parentPath, ResultSet item) throws RepositoryException, SQLException,
+      IOException
+   {
+      String cid = item.getString(COLUMN_ID);
+      String cname = item.getString(COLUMN_NAME);
+      int cversion = item.getInt(COLUMN_VERSION);
+      String cpid = item.getString(COLUMN_PARENTID);
+      int cptype = item.getInt(COLUMN_PTYPE);
+      boolean cpmultivalued = item.getBoolean(COLUMN_PMULTIVALUED);
+
+      try
+      {
+         InternalQName qname = InternalQName.parse(cname);
+
+         QPath qpath = QPath.makeChildPath(parentPath == null ? traverseQPath(cpid) : parentPath, qname);
+
+         PersistedPropertyData pdata =
+            new PersistedPropertyData(getIdentifier(cid), qpath, getIdentifier(cpid), cversion, cptype, cpmultivalued,
+               new ArrayList<ValueData>());
+
+         return pdata;
+      }
+      catch (InvalidItemStateException e)
+      {
+         throw new InvalidItemStateException("FATAL: Can't build property path for name " + cname + " id: "
+            + getIdentifier(cid) + ". " + e);
+      }
+      catch (IllegalNameException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * Mixin types description (internal use).
+    * 
+    */
+   class MixinInfo
+   {
+
+      /**
+       * OWNEABLE constant.
+       */
+      static final int OWNEABLE = 0x0001; // bits 0001
+
+      /**
+       * PRIVILEGEABLE constant.
+       */
+      static final int PRIVILEGEABLE = 0x0002; // bits 0010
+
+      /**
+       * OWNEABLE_PRIVILEGEABLE constant.
+       */
+      static final int OWNEABLE_PRIVILEGEABLE = OWNEABLE | PRIVILEGEABLE; // bits 0011
+
+      /**
+       * Mixin types.
+       */
+      final List<InternalQName> mixinTypes;
+
+      /**
+       * oexo:owneable flag.
+       */
+      final boolean owneable;
+
+      /**
+       * exo:privilegeable flag.
+       */
+      final boolean privilegeable;
+
+      /**
+       * Parent Id.
+       */
+      final String parentId = null;
+
+      /**
+       * MixinInfo constructor.
+       * 
+       * @param mixinTypes
+       *          mixin types
+       * @param owneable
+       *          exo:owneable flag
+       * @param privilegeable
+       *          exo:privilegeable flag
+       */
+      MixinInfo(List<InternalQName> mixinTypes, boolean owneable, boolean privilegeable)
+      {
+         this.mixinTypes = mixinTypes;
+         this.owneable = owneable;
+         this.privilegeable = privilegeable;
+      }
+
+      /**
+       * Return Mixin names array.
+       * 
+       * @return InternalQName[] Mixin names array
+       */
+      InternalQName[] mixinNames()
+      {
+         if (mixinTypes != null)
+         {
+            InternalQName[] mns = new InternalQName[mixinTypes.size()];
+            mixinTypes.toArray(mns);
+            return mns;
+         }
+         else
+            return new InternalQName[0];
+      }
+
+      /**
+       * Tell is exo:privilegeable.
+       * 
+       * @return boolean
+       */
+      boolean hasPrivilegeable()
+      {
+         return privilegeable;
+      }
+
+      /**
+       * Tell is exo:owneable.
+       * 
+       * @return boolean
+       */
+      boolean hasOwneable()
+      {
+         return owneable;
+      }
+   }
+
+   /**
+    * Read mixins from database.
+    * 
+    * @param cid
+    *          - Item id (internal)
+    * @return MixinInfo
+    * @throws SQLException
+    *           database error
+    * @throws IllegalNameException
+    *           if nodetype name in mixin record is wrong
+    */
+   protected MixinInfo readMixins(String cid) throws SQLException, IllegalNameException
+   {
+      ResultSet mtrs = findPropertyByName(cid, Constants.JCR_MIXINTYPES.getAsString());
+
+      try
+      {
+         List<InternalQName> mts = null;
+         boolean owneable = false;
+         boolean privilegeable = false;
+         if (mtrs.next())
+         {
+            mts = new ArrayList<InternalQName>();
+            do
+            {
+               byte[] mxnb = mtrs.getBytes(COLUMN_VDATA);
+               if (mxnb != null)
+               {
+                  InternalQName mxn = InternalQName.parse(new String(mxnb));
+                  mts.add(mxn);
+
+                  if (!privilegeable && Constants.EXO_PRIVILEGEABLE.equals(mxn))
+                     privilegeable = true;
+                  else if (!owneable && Constants.EXO_OWNEABLE.equals(mxn))
+                     owneable = true;
+               } // else, if SQL NULL - skip it
+            }
+            while (mtrs.next());
+         }
+
+         return new MixinInfo(mts, owneable, privilegeable);
+      }
+      finally
+      {
+         mtrs.close();
+      }
+   }
+
+   /**
+    * Return permission values or throw an exception. We assume the node is mix:privilegeable.
+    * 
+    * @param cid
+    *          Node id
+    * @return list of ACL entries
+    * @throws SQLException
+    *           database error
+    * @throws IllegalACLException
+    *           if property exo:permissions is not found for node
+    */
+   protected List<AccessControlEntry> readACLPermisions(String cid) throws SQLException, IllegalACLException
+   {
+      List<AccessControlEntry> naPermissions = new ArrayList<AccessControlEntry>();
+      ResultSet exoPerm = findPropertyByName(cid, Constants.EXO_PERMISSIONS.getAsString());
+      try
+      {
+         if (exoPerm.next())
+         {
+            do
+            {
+               StringTokenizer parser =
+                  new StringTokenizer(new String(exoPerm.getBytes(COLUMN_VDATA)), AccessControlEntry.DELIMITER);
+               naPermissions.add(new AccessControlEntry(parser.nextToken(), parser.nextToken()));
+            }
+            while (exoPerm.next());
+
+            return naPermissions;
+         }
+         else
+            throw new IllegalACLException("Property exo:permissions is not found for node with id: "
+               + getIdentifier(cid));
+      }
+      finally
+      {
+         exoPerm.close();
+      }
+   }
+
+   /**
+    * Return owner value or throw an exception. We assume the node is mix:owneable.
+    * 
+    * @param cid
+    *          Node id
+    * @return ACL owner
+    * @throws SQLException
+    *           database error
+    * @throws IllegalACLException
+    *           Property exo:owner is not found for node
+    */
+   protected String readACLOwner(String cid) throws SQLException, IllegalACLException
+   {
+      ResultSet exoOwner = findPropertyByName(cid, Constants.EXO_OWNER.getAsString());
+      try
+      {
+         if (exoOwner.next())
+            return new String(exoOwner.getBytes(COLUMN_VDATA));
+         else
+            throw new IllegalACLException("Property exo:owner is not found for node with id: " + getIdentifier(cid));
+      }
+      finally
+      {
+         exoOwner.close();
+      }
+   }
+
+   /**
+    * Load NodeData record.
+    * 
+    * @param parentPath
+    *          parent path
+    * @param cname
+    *          Node name
+    * @param cid
+    *          Node id
+    * @param cpid
+    *          Node parent id
+    * @param cindex
+    *          Node index
+    * @param cversion
+    *          Node persistent version
+    * @param cnordernumb
+    *          Node order number
+    * @param parentACL
+    *          Node parent ACL
+    * @return PersistedNodeData
+    * @throws RepositoryException
+    *           Repository error
+    * @throws SQLException
+    *           database error
+    */
+   protected PersistedNodeData loadNodeRecord(QPath parentPath, String cname, String cid, String cpid, int cindex,
+      int cversion, int cnordernumb, AccessControlList parentACL) throws RepositoryException, SQLException
+   {
+
+      try
+      {
+         InternalQName qname = InternalQName.parse(cname);
+
+         QPath qpath;
+         String parentCid;
+         if (parentPath != null)
+         {
+            // get by parent and name
+            qpath = QPath.makeChildPath(parentPath, qname, cindex);
+            parentCid = cpid;
+         }
+         else
+         {
+            // get by id
+            if (cpid.equals(Constants.ROOT_PARENT_UUID))
+            {
+               // root node
+               qpath = Constants.ROOT_PATH;
+               parentCid = null;
+            }
+            else
+            {
+               qpath = QPath.makeChildPath(traverseQPath(cpid), qname, cindex);
+               parentCid = cpid;
+            }
+         }
+
+         try
+         {
+            // PRIMARY
+            ResultSet ptProp = findPropertyByName(cid, Constants.JCR_PRIMARYTYPE.getAsString());
+
+            if (!ptProp.next())
+               throw new PrimaryTypeNotFoundException("FATAL ERROR primary type record not found. Node "
+                  + qpath.getAsString() + ", id " + cid + ", container " + this.containerName, null);
+
+            byte[] data = ptProp.getBytes(COLUMN_VDATA);
+            InternalQName ptName = InternalQName.parse(new String((data != null ? data : new byte[]{})));
+
+            // MIXIN
+            MixinInfo mixins = readMixins(cid);
+
+            // ACL
+            AccessControlList acl; // NO DEFAULT values!
+
+            if (mixins.hasOwneable())
+            {
+               // has own owner
+               if (mixins.hasPrivilegeable())
+               {
+                  // and permissions
+                  acl = new AccessControlList(readACLOwner(cid), readACLPermisions(cid));
+               }
+               else if (parentACL != null)
+               {
+                  // use permissions from existed parent
+                  acl =
+                     new AccessControlList(readACLOwner(cid), parentACL.hasPermissions() ? parentACL
+                        .getPermissionEntries() : null);
+               }
+               else
+               {
+                  // have to search nearest ancestor permissions in ACL manager
+                  // acl = new AccessControlList(readACLOwner(cid), traverseACLPermissions(cpid));
+                  acl = new AccessControlList(readACLOwner(cid), null);
+               }
+            }
+            else if (mixins.hasPrivilegeable())
+            {
+               // has own permissions
+               if (mixins.hasOwneable())
+               {
+                  // and owner
+                  acl = new AccessControlList(readACLOwner(cid), readACLPermisions(cid));
+               }
+               else if (parentACL != null)
+               {
+                  // use owner from existed parent
+                  acl = new AccessControlList(parentACL.getOwner(), readACLPermisions(cid));
+               }
+               else
+               {
+                  // have to search nearest ancestor owner in ACL manager
+                  // acl = new AccessControlList(traverseACLOwner(cpid), readACLPermisions(cid));
+                  acl = new AccessControlList(null, readACLPermisions(cid));
+               }
+            }
+            else
+            {
+               if (parentACL != null)
+                  // construct ACL from existed parent ACL
+                  acl =
+                     new AccessControlList(parentACL.getOwner(), parentACL.hasPermissions() ? parentACL
+                        .getPermissionEntries() : null);
+               else
+                  // have to search nearest ancestor owner and permissions in ACL manager
+                  // acl = traverseACL(cpid);
+                  acl = null;
+            }
+
+            return new PersistedNodeData(getIdentifier(cid), qpath, getIdentifier(parentCid), cversion, cnordernumb,
+               ptName, mixins.mixinNames(), acl);
+         }
+         catch (IllegalACLException e)
+         {
+            throw new RepositoryException("FATAL ERROR Node " + getIdentifier(cid) + " " + qpath.getAsString()
+               + " has wrong formed ACL. ", e);
+         }
+      }
+      catch (IllegalNameException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * Load PropertyData record.
+    * 
+    * @param parentPath
+    *          parent path
+    * @param cname
+    *          Property name
+    * @param cid
+    *          Property id
+    * @param cpid
+    *          Property parent id
+    * @param cversion
+    *          Property persistent verison
+    * @param cptype
+    *          Property type
+    * @param cpmultivalued
+    *          Property multivalued status
+    * @return PersistedPropertyData
+    * @throws RepositoryException
+    *           Repository error
+    * @throws SQLException
+    *           database error
+    * @throws IOException
+    *           I/O error
+    */
+   protected PersistedPropertyData loadPropertyRecord(QPath parentPath, String cname, String cid, String cpid,
+      int cversion, int cptype, boolean cpmultivalued) throws RepositoryException, SQLException, IOException
+   {
+
+      // NOTE: cpid never should be null or root parent (' ')
+
+      try
+      {
+         QPath qpath =
+            QPath.makeChildPath(parentPath == null ? traverseQPath(cpid) : parentPath, InternalQName.parse(cname));
+
+         String identifier = getIdentifier(cid);
+         List<ValueData> values = readValues(cid, identifier, cversion);
+         PersistedPropertyData pdata =
+            new PersistedPropertyData(identifier, qpath, getIdentifier(cpid), cversion, cptype, cpmultivalued, values);
+
+         return pdata;
+      }
+      catch (IllegalNameException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   protected PersistedNodeData loadNodeRecord(ResultSet item, QPath parentPath, AccessControlList pACL)
+      throws RepositoryException, SQLException, IOException
+   {
+
+      String cid = item.getString(COLUMN_ID);
+      String cname = item.getString(COLUMN_NAME);
+      int cversion = item.getInt(COLUMN_VERSION);
+      String cpid = item.getString(COLUMN_PARENTID);
+      int cindex = item.getInt(COLUMN_INDEX);
+      int cnordernumb = item.getInt(COLUMN_NORDERNUM);
       AccessControlList parentACL = pACL;
 
       try
@@ -511,88 +1804,94 @@
             }
          }
 
-         Map<String, List<byte[]>> properties = tempData.properties;
-
          // PRIMARY
-         List<byte[]> primaryType = properties.get(Constants.JCR_PRIMARYTYPE.getAsString());
-         if (primaryType == null || primaryType.size() == 0)
+         if (!item.next() || !item.getString(COLUMN_NAME).equals(Constants.JCR_PRIMARYTYPE.getAsString()))
          {
             throw new SQLException("Node finded but primaryType property not " + cid);
          }
 
-         byte[] data = primaryType.get(0);
+         byte[] data = item.getBytes(COLUMN_VDATA);
          InternalQName ptName = InternalQName.parse(new String((data != null ? data : new byte[]{})));
 
+         //            // PRIMARY
+         //            ResultSet ptProp = findPropertyByName(cid, Constants.JCR_PRIMARYTYPE.getAsString());
+         //
+         //            if (!ptProp.next())
+         //               throw new PrimaryTypeNotFoundException("FATAL ERROR primary type record not found. Node "
+         //                  + qpath.getAsString() + ", id " + cid + ", container " + this.containerName, null);
+         //
+         //            byte[] data = ptProp.getBytes(COLUMN_VDATA);
+         //            InternalQName ptName = InternalQName.parse(new String((data != null ? data : new byte[]{})));
+
          // MIXIN
-         InternalQName[] mts;
+         MixinInfo mixins = null;
+         List<InternalQName> mts = null;
          boolean owneable = false;
          boolean privilegeable = false;
-         List<byte[]> mixTypes = properties.get(Constants.JCR_MIXINTYPES.getAsString());
-         if (mixTypes != null)
+         while (item.next() && item.getString(COLUMN_NAME).equals(Constants.JCR_MIXINTYPES.getAsString()))
          {
-            List<InternalQName> mNames = new ArrayList<InternalQName>();
-            for (byte[] mxnb : mixTypes)
+            mts = new ArrayList<InternalQName>();
+            byte[] mxnb = item.getBytes(COLUMN_VDATA);
+            if (mxnb != null)
             {
                InternalQName mxn = InternalQName.parse(new String(mxnb));
-               mNames.add(mxn);
+               mts.add(mxn);
 
                if (!privilegeable && Constants.EXO_PRIVILEGEABLE.equals(mxn))
                   privilegeable = true;
                else if (!owneable && Constants.EXO_OWNEABLE.equals(mxn))
                   owneable = true;
-            }
-            mts = new InternalQName[mNames.size()];
-            mNames.toArray(mts);
+            } // else, if SQL NULL - skip it
+
          }
-         else
-         {
-            mts = new InternalQName[0];
-         }
 
+         mixins = new MixinInfo(mts, owneable, privilegeable);
+
          try
          {
             // ACL
             AccessControlList acl; // NO DEFAULT values!
 
-            if (owneable)
+            if (mixins.hasOwneable())
             {
                // has own owner
-               if (privilegeable)
+               if (mixins.hasPrivilegeable())
                {
                   // and permissions
-                  acl = new AccessControlList(readACLOwner(cid, properties), readACLPermisions(cid, properties));
+                  acl = new AccessControlList(readACLOwner(cid), readACLPermisions(cid));
                }
                else if (parentACL != null)
                {
                   // use permissions from existed parent
                   acl =
-                     new AccessControlList(readACLOwner(cid, properties), parentACL.hasPermissions() ? parentACL
+                     new AccessControlList(readACLOwner(cid), parentACL.hasPermissions() ? parentACL
                         .getPermissionEntries() : null);
                }
                else
                {
                   // have to search nearest ancestor permissions in ACL manager
-                  acl = new AccessControlList(readACLOwner(cid, properties), null);
+                  // acl = new AccessControlList(readACLOwner(cid), traverseACLPermissions(cpid));
+                  acl = new AccessControlList(readACLOwner(cid), null);
                }
             }
-            else if (privilegeable)
+            else if (mixins.hasPrivilegeable())
             {
                // has own permissions
-               if (owneable)
+               if (mixins.hasOwneable())
                {
                   // and owner
-                  acl = new AccessControlList(readACLOwner(cid, properties), readACLPermisions(cid, properties));
+                  acl = new AccessControlList(readACLOwner(cid), readACLPermisions(cid));
                }
                else if (parentACL != null)
                {
                   // use owner from existed parent
-                  acl = new AccessControlList(parentACL.getOwner(), readACLPermisions(cid, properties));
+                  acl = new AccessControlList(parentACL.getOwner(), readACLPermisions(cid));
                }
                else
                {
                   // have to search nearest ancestor owner in ACL manager
                   // acl = new AccessControlList(traverseACLOwner(cpid), readACLPermisions(cid));
-                  acl = new AccessControlList(null, readACLPermisions(cid, properties));
+                  acl = new AccessControlList(null, readACLPermisions(cid));
                }
             }
             else
@@ -609,7 +1908,7 @@
             }
 
             return new PersistedNodeData(getIdentifier(cid), qpath, getIdentifier(parentCid), cversion, cnordernumb,
-               ptName, mts, acl);
+               ptName, mixins.mixinNames(), acl);
 
          }
          catch (IllegalACLException e)
@@ -624,58 +1923,202 @@
       }
    }
 
-   /**
-    * Load property record from result set. Result set must be ordered by property id.
-    * In other way there may be mistaces.
-    * 
-    * @param resultSet - Result set
-    * @param parentPath - parent qpath - needed to create property qpath. May be null.
-    * @return PersistedPropertyData
-    * @throws RepositoryException
-    * @throws SQLException
-    * @throws IOException
-    */
-   protected PersistedPropertyData loadPropertyRecord(ResultSet resultSet, QPath parentPath)
+   protected PersistedNodeData loadNodeRecordFromBuffer(TempNodeData buf, QPath parentPath, AccessControlList pACL)
       throws RepositoryException, SQLException, IOException
    {
-      String cid = resultSet.getString(COLUMN_ID);
-      String cname = resultSet.getString(COLUMN_NAME);
-      int cversion = resultSet.getInt(COLUMN_VERSION);
 
-      String cpid = resultSet.getString(COLUMN_PARENTID);
-      // if parent ID is empty string - it's a root node
-      // cpid = cpid.equals(Constants.ROOT_PARENT_UUID) ? null : cpid;
+      String cid = buf.cid;
+      String cname = buf.cname;
+      int cversion = buf.cversion;
+      String cpid = buf.cpid;
+      int cindex = buf.cindex;
+      int cnordernumb = buf.cnordernumb;
+      AccessControlList parentACL = pACL;
 
       try
       {
-         int cptype = resultSet.getInt(COLUMN_PTYPE);
-         boolean cpmultivalued = resultSet.getBoolean(COLUMN_PMULTIVALUED);
-         QPath qpath =
-            QPath.makeChildPath(parentPath == null ? traverseQPath(cpid) : parentPath, InternalQName.parse(cname));
+         InternalQName qname = InternalQName.parse(cname);
 
-         List<ValueData> data = new ArrayList<ValueData>();
-         String identifier = getIdentifier(cid);
+         // TODO can't avoid QPath traverse
+         QPath qpath;
+         String parentCid;
+         if (parentPath != null)
+         {
+            // get by parent and name
+            qpath = QPath.makeChildPath(parentPath, qname, cindex);
+            parentCid = cpid;
+         }
+         else
+         {
+            // get by id
+            if (cpid.equals(Constants.ROOT_PARENT_UUID))
+            {
+               // root node
+               qpath = Constants.ROOT_PATH;
+               parentCid = null;
+            }
+            else
+            {
+               qpath = QPath.makeChildPath(traverseQPath(cpid), qname, cindex);
+               parentCid = cpid;
+            }
+         }
 
-         do
+         // PRIMARY
+
+         List<byte[]> primaryType = buf.properties.get(Constants.JCR_PRIMARYTYPE.getAsString());
+         if (primaryType == null || primaryType.size() == 0)
          {
-            final int orderNum = resultSet.getInt(COLUMN_VORDERNUM);
-            final String storageId = resultSet.getString(COLUMN_VSTORAGE_DESC);
-            ValueData vdata =
-               resultSet.wasNull() ? readValueData(cid, orderNum, cversion, resultSet.getBinaryStream(COLUMN_VDATA))
-                  : readValueData(identifier, orderNum, storageId);
-            data.add(vdata);
+            throw new SQLException("Node finded but primaryType property not " + cid);
          }
-         while (resultSet.next() && resultSet.getString(COLUMN_ID) == cid);
 
-         PersistedPropertyData pdata =
-            new PersistedPropertyData(identifier, qpath, getIdentifier(cpid), cversion, cptype, cpmultivalued, data);
+         byte[] data = primaryType.get(0);
+         InternalQName ptName = InternalQName.parse(new String((data != null ? data : new byte[]{})));
 
-         return pdata;
+         // MIXIN
+         MixinInfo mixins = null;
+         List<InternalQName> mts = null;
+         boolean owneable = false;
+         boolean privilegeable = false;
+         List<byte[]> mixinTypes = buf.properties.get(Constants.JCR_MIXINTYPES.getAsString());
+         if (mixinTypes != null)
+         {
+            mts = new ArrayList<InternalQName>();
+            for (byte[] mxnb : mixinTypes)
+            {
+               InternalQName mxn = InternalQName.parse(new String(mxnb));
+               mts.add(mxn);
+
+               if (!privilegeable && Constants.EXO_PRIVILEGEABLE.equals(mxn))
+                  privilegeable = true;
+               else if (!owneable && Constants.EXO_OWNEABLE.equals(mxn))
+                  owneable = true;
+            }
+         }
+
+         mixins = new MixinInfo(mts, owneable, privilegeable);
+
+         try
+         {
+            // ACL
+            AccessControlList acl; // NO DEFAULT values!
+
+            if (mixins.hasOwneable())
+            {
+               // has own owner
+               if (mixins.hasPrivilegeable())
+               {
+                  // and permissions
+                  acl = new AccessControlList(readACLOwner(cid), readACLPermisions(cid));
+               }
+               else if (parentACL != null)
+               {
+                  // use permissions from existed parent
+                  acl =
+                     new AccessControlList(readACLOwner(cid), parentACL.hasPermissions() ? parentACL
+                        .getPermissionEntries() : null);
+               }
+               else
+               {
+                  // have to search nearest ancestor permissions in ACL manager
+                  // acl = new AccessControlList(readACLOwner(cid), traverseACLPermissions(cpid));
+                  acl = new AccessControlList(readACLOwner(cid), null);
+               }
+            }
+            else if (mixins.hasPrivilegeable())
+            {
+               // has own permissions
+               if (mixins.hasOwneable())
+               {
+                  // and owner
+                  acl = new AccessControlList(readACLOwner(cid), readACLPermisions(cid));
+               }
+               else if (parentACL != null)
+               {
+                  // use owner from existed parent
+                  acl = new AccessControlList(parentACL.getOwner(), readACLPermisions(cid));
+               }
+               else
+               {
+                  // have to search nearest ancestor owner in ACL manager
+                  // acl = new AccessControlList(traverseACLOwner(cpid), readACLPermisions(cid));
+                  acl = new AccessControlList(null, readACLPermisions(cid));
+               }
+            }
+            else
+            {
+               if (parentACL != null)
+                  // construct ACL from existed parent ACL
+                  acl =
+                     new AccessControlList(parentACL.getOwner(), parentACL.hasPermissions() ? parentACL
+                        .getPermissionEntries() : null);
+               else
+                  // have to search nearest ancestor owner and permissions in ACL manager
+                  // acl = traverseACL(cpid);
+                  acl = null;
+            }
+
+            return new PersistedNodeData(getIdentifier(cid), qpath, getIdentifier(parentCid), cversion, cnordernumb,
+               ptName, mixins.mixinNames(), acl);
+
+         }
+         catch (IllegalACLException e)
+         {
+            throw new RepositoryException("FATAL ERROR Node " + getIdentifier(cid) + " " + qpath.getAsString()
+               + " has wrong formed ACL. ", e);
+         }
       }
       catch (IllegalNameException e)
       {
          throw new RepositoryException(e);
       }
+   }
+
+   protected PersistedPropertyData loadPropertyRecord(ResultSet item, QPath parentPath) throws RepositoryException,
+      SQLException, IOException
+   {
+      String cid = item.getString(COLUMN_ID);
+      String cname = item.getString(COLUMN_NAME);
+      int cversion = item.getInt(COLUMN_VERSION);
+
+      String cpid = item.getString(COLUMN_PARENTID);
+      // if parent ID is empty string - it's a root node
+      // cpid = cpid.equals(Constants.ROOT_PARENT_UUID) ? null : cpid;
+
+      try
+      {
+         int cptype = item.getInt(COLUMN_PTYPE);
+         boolean cpmultivalued = item.getBoolean(COLUMN_PMULTIVALUED);
+         try
+         {
+            QPath qpath =
+               QPath.makeChildPath(parentPath == null ? traverseQPath(cpid) : parentPath, InternalQName.parse(cname));
+
+            List<ValueData> data = new ArrayList<ValueData>();
+
+            String identifier = getIdentifier(cid);
+
+            do
+            {
+               final int orderNum = item.getInt(COLUMN_VORDERNUM);
+               final String storageId = item.getString(COLUMN_VSTORAGE_DESC);
+               ValueData vdata =
+                  item.wasNull() ? readValueData(cid, orderNum, cversion, item.getBinaryStream(COLUMN_VDATA))
+                     : readValueData(identifier, orderNum, storageId);
+               data.add(vdata);
+            }
+            while (item.next() && item.getString(COLUMN_ID) == cid);
+
+            PersistedPropertyData pdata =
+               new PersistedPropertyData(identifier, qpath, getIdentifier(cpid), cversion, cptype, cpmultivalued, data);
+
+            return pdata;
+         }
+         catch (IllegalNameException e)
+         {
+            throw new RepositoryException(e);
+         }
+      }
       catch (InvalidItemStateException e)
       {
          throw new InvalidItemStateException("FATAL: Can't build item path for name " + cname + " id: "
@@ -684,6 +2127,104 @@
    }
 
    /**
+    * Delete Property Values.
+    * 
+    * @param cid
+    *          Property id
+    * @param pdata
+    *          PropertyData
+    * @param update
+    *          boolean true if it's delete-add sequence (update operation)
+    * @throws IOException
+    *           i/O error
+    * @throws SQLException
+    *           if database error occurs
+    * @throws ValueStorageNotFoundException
+    *           if no such storage found with Value storageId
+    */
+   private void deleteValues(String cid, PropertyData pdata, boolean update) throws IOException, SQLException,
+      ValueStorageNotFoundException
+   {
+
+      final ResultSet valueRecords = findValuesStorageDescriptorsByPropertyId(cid);
+      try
+      {
+         if (valueRecords.next())
+         {
+            // delete all Values in database
+            deleteValueData(cid);
+
+            do
+            {
+               final String storageId = valueRecords.getString(COLUMN_VSTORAGE_DESC);
+               if (!valueRecords.wasNull())
+               {
+                  final ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
+                  try
+                  {
+                     channel.delete(pdata.getIdentifier());
+                     valueChanges.add(channel);
+                  }
+                  finally
+                  {
+                     channel.close();
+                  }
+               }
+            }
+            while (valueRecords.next());
+         }
+      }
+      finally
+      {
+         valueRecords.close();
+      }
+   }
+
+   /**
+    * Read Property Values.
+    * 
+    * @param identifier
+    *          property identifier
+    * @param cid
+    *          Property id
+    * @param pdata
+    *          PropertyData
+    * @return list of ValueData
+    * @throws IOException
+    *           i/O error
+    * @throws SQLException
+    *           if database errro occurs
+    * @throws ValueStorageNotFoundException
+    *           if no such storage found with Value storageId
+    */
+   private List<ValueData> readValues(String cid, String identifier, int cversion) throws IOException, SQLException,
+      ValueStorageNotFoundException
+   {
+
+      List<ValueData> data = new ArrayList<ValueData>();
+
+      final ResultSet valueRecords = findValuesByPropertyId(cid);
+      try
+      {
+         while (valueRecords.next())
+         {
+            final int orderNum = valueRecords.getInt(COLUMN_VORDERNUM);
+            final String storageId = valueRecords.getString(COLUMN_VSTORAGE_DESC);
+            ValueData vdata =
+               valueRecords.wasNull() ? readValueData(cid, orderNum, cversion, valueRecords
+                  .getBinaryStream(COLUMN_VDATA)) : readValueData(identifier, orderNum, storageId);
+            data.add(vdata);
+         }
+      }
+      finally
+      {
+         valueRecords.close();
+      }
+
+      return data;
+   }
+
+   /**
     * Read ValueData from External Storage.
     * 
     * @param pdata
@@ -714,165 +2255,271 @@
       }
    }
 
-   //   protected PersistedNodeData loadNodeRecord(ResultSet item, QPath parentPath, AccessControlList pACL)
-   //      throws RepositoryException, SQLException, IOException
-   //   {
-   //
-   //      String cid = item.getString(COLUMN_ID);
-   //      String cname = item.getString(COLUMN_NAME);
-   //      int cversion = item.getInt(COLUMN_VERSION);
-   //      String cpid = item.getString(COLUMN_PARENTID);
-   //      int cindex = item.getInt(COLUMN_INDEX);
-   //      int cnordernumb = item.getInt(COLUMN_NORDERNUM);
-   //      AccessControlList parentACL = pACL;
-   //
-   //      try
-   //      {
-   //         InternalQName qname = InternalQName.parse(cname);
-   //
-   //         // TODO can't avoid QPath traverse
-   //         QPath qpath;
-   //         String parentCid;
-   //         if (parentPath != null)
-   //         {
-   //            // get by parent and name
-   //            qpath = QPath.makeChildPath(parentPath, qname, cindex);
-   //            parentCid = cpid;
-   //         }
-   //         else
-   //         {
-   //            // get by id
-   //            if (cpid.equals(Constants.ROOT_PARENT_UUID))
-   //            {
-   //               // root node
-   //               qpath = Constants.ROOT_PATH;
-   //               parentCid = null;
-   //            }
-   //            else
-   //            {
-   //               qpath = QPath.makeChildPath(traverseQPath(cpid), qname, cindex);
-   //               parentCid = cpid;
-   //            }
-   //         }
-   //
-   //         // preload properties
-   //
-   //         Map<String, List<byte[]>> properties = new LinkedHashMap<String, List<byte[]>>();
-   //
-   //         // PRIMARY
-   //         if (!item.next() || !item.getString(COLUMN_NAME).equals(Constants.JCR_PRIMARYTYPE.getAsString()))
-   //         {
-   //            throw new SQLException("Node finded but primaryType property not " + cid);
-   //         }
-   //
-   //         byte[] data = item.getBytes(COLUMN_VDATA);
-   //         InternalQName ptName = InternalQName.parse(new String((data != null ? data : new byte[]{})));
-   //
-   //         // MIXIN
-   //         MixinInfo mixins = null;
-   //         List<InternalQName> mts = null;
-   //         boolean owneable = false;
-   //         boolean privilegeable = false;
-   //         while (item.next() && item.getString(COLUMN_NAME).equals(Constants.JCR_MIXINTYPES.getAsString()))
-   //         {
-   //            mts = new ArrayList<InternalQName>();
-   //            byte[] mxnb = item.getBytes(COLUMN_VDATA);
-   //            if (mxnb != null)
-   //            {
-   //               InternalQName mxn = InternalQName.parse(new String(mxnb));
-   //               mts.add(mxn);
-   //
-   //               if (!privilegeable && Constants.EXO_PRIVILEGEABLE.equals(mxn))
-   //                  privilegeable = true;
-   //               else if (!owneable && Constants.EXO_OWNEABLE.equals(mxn))
-   //                  owneable = true;
-   //            } // else, if SQL NULL - skip it
-   //
-   //         }
-   //
-   //         mixins = new MixinInfo(mts, owneable, privilegeable);
-   //
-   //         try
-   //         {
-   //            // ACL
-   //            AccessControlList acl; // NO DEFAULT values!
-   //
-   //            if (mixins.hasOwneable())
-   //            {
-   //               // has own owner
-   //               if (mixins.hasPrivilegeable())
-   //               {
-   //                  // and permissions
-   //                  acl = new AccessControlList(readACLOwner(cid), readACLPermisions(cid));
-   //               }
-   //               else if (parentACL != null)
-   //               {
-   //                  // use permissions from existed parent
-   //                  acl =
-   //                     new AccessControlList(readACLOwner(cid), parentACL.hasPermissions() ? parentACL
-   //                        .getPermissionEntries() : null);
-   //               }
-   //               else
-   //               {
-   //                  // have to search nearest ancestor permissions in ACL manager
-   //                  // acl = new AccessControlList(readACLOwner(cid), traverseACLPermissions(cpid));
-   //                  acl = new AccessControlList(readACLOwner(cid), null);
-   //               }
-   //            }
-   //            else if (mixins.hasPrivilegeable())
-   //            {
-   //               // has own permissions
-   //               if (mixins.hasOwneable())
-   //               {
-   //                  // and owner
-   //                  acl = new AccessControlList(readACLOwner(cid), readACLPermisions(cid));
-   //               }
-   //               else if (parentACL != null)
-   //               {
-   //                  // use owner from existed parent
-   //                  acl = new AccessControlList(parentACL.getOwner(), readACLPermisions(cid));
-   //               }
-   //               else
-   //               {
-   //                  // have to search nearest ancestor owner in ACL manager
-   //                  // acl = new AccessControlList(traverseACLOwner(cpid), readACLPermisions(cid));
-   //                  acl = new AccessControlList(null, readACLPermisions(cid));
-   //               }
-   //            }
-   //            else
-   //            {
-   //               if (parentACL != null)
-   //                  // construct ACL from existed parent ACL
-   //                  acl =
-   //                     new AccessControlList(parentACL.getOwner(), parentACL.hasPermissions() ? parentACL
-   //                        .getPermissionEntries() : null);
-   //               else
-   //                  // have to search nearest ancestor owner and permissions in ACL manager
-   //                  // acl = traverseACL(cpid);
-   //                  acl = null;
-   //            }
-   //
-   //            return new PersistedNodeData(getIdentifier(cid), qpath, getIdentifier(parentCid), cversion, cnordernumb,
-   //               ptName, mixins.mixinNames(), acl);
-   //
-   //         }
-   //         catch (IllegalACLException e)
-   //         {
-   //            throw new RepositoryException("FATAL ERROR Node " + getIdentifier(cid) + " " + qpath.getAsString()
-   //               + " has wrong formed ACL. ", e);
-   //         }
-   //      }
-   //      catch (IllegalNameException e)
-   //      {
-   //         throw new RepositoryException(e);
-   //      }
-   //   }
+   /**
+    * Read ValueData from database.
+    * 
+    * @param cid
+    *          Property id
+    * @param orderNumber
+    *          Value order number
+    * @param version
+    *          persistent version (used for BLOB swapping)
+    * @param content
+    * @return ValueData
+    * @throws SQLException
+    *           database error
+    * @throws IOException
+    *           I/O error (swap)
+    */
+   protected ValueData readValueData(String cid, int orderNumber, int version, final InputStream content)
+      throws SQLException, IOException
+   {
 
-   protected abstract ResultSet findItemByIdentifierCQ(String identifier) throws SQLException;
+      ResultSet valueResultSet = null;
 
-   protected abstract ResultSet findItemByNameCQ(String parentId, String name, int index) throws SQLException;
+      byte[] buffer = new byte[0];
+      byte[] spoolBuffer = new byte[ValueFileIOHelper.IOBUFFER_SIZE];
+      int read;
+      int len = 0;
+      OutputStream out = null;
 
-   protected abstract ResultSet findChildNodesByParentIdentifierCQ(String parentIdentifier) throws SQLException;
+      SwapFile swapFile = null;
+      try
+      {
+         // stream from database
+         if (content != null)
+            while ((read = content.read(spoolBuffer)) >= 0)
+            {
+               if (out != null)
+               {
+                  // spool to temp file
+                  out.write(spoolBuffer, 0, read);
+                  len += read;
+               }
+               else if (len + read > maxBufferSize)
+               {
+                  // threshold for keeping data in memory exceeded;
+                  // create temp file and spool buffer contents
+                  swapFile = SwapFile.get(swapDirectory, cid + orderNumber + "." + version);
+                  if (swapFile.isSpooled())
+                  {
+                     // break, value already spooled
+                     buffer = null;
+                     break;
+                  }
+                  out = new FileOutputStream(swapFile);
+                  out.write(buffer, 0, len);
+                  out.write(spoolBuffer, 0, read);
+                  buffer = null;
+                  len += read;
+               }
+               else
+               {
+                  // reallocate new buffer and spool old buffer contents
+                  byte[] newBuffer = new byte[len + read];
+                  System.arraycopy(buffer, 0, newBuffer, 0, len);
+                  System.arraycopy(spoolBuffer, 0, newBuffer, len, read);
+                  buffer = newBuffer;
+                  len += read;
+               }
+            }
+      }
+      finally
+      {
+         if (valueResultSet != null)
+            valueResultSet.close();
+         if (out != null)
+         {
+            out.close();
+            swapFile.spoolDone();
+         }
+      }
 
-   protected abstract ResultSet getChildPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException;
+      if (buffer == null)
+         return new CleanableFilePersistedValueData(orderNumber, swapFile, swapCleaner);
+
+      return new ByteArrayPersistedValueData(orderNumber, buffer);
+   }
+
+   /**
+    * Writes value data to swap file.
+    * 
+    * @param cid
+    *          Property id
+    * @param orderNumber
+    *          Value order number
+    * @param version
+    *          persistent version (used for BLOB swapping)
+    * @param content
+    * @return ValueData
+    * @throws SQLException
+    *           database error
+    * @throws IOException
+    *           I/O error (swap)
+    */
+   protected SwapFile swapValueData(String cid, int orderNumber, int version, final InputStream content)
+      throws SQLException, IOException
+   {
+
+      byte[] spoolBuffer = new byte[ValueFileIOHelper.IOBUFFER_SIZE];
+      int read;
+      int len = 0;
+
+      SwapFile swapFile = SwapFile.get(swapDirectory, cid + orderNumber + "." + version);
+      OutputStream out = new FileOutputStream(swapFile);;
+
+      if (swapFile.isSpooled())
+      {
+         return swapFile;
+      }
+
+      try
+      {
+         if (content != null)
+            while ((read = content.read(spoolBuffer)) >= 0)
+            {
+               // spool to temp file
+               out.write(spoolBuffer, 0, read);
+               len += read;
+            }
+      }
+      finally
+      {
+         out.close();
+         swapFile.spoolDone();
+      }
+
+      return swapFile;
+   }
+
+   /**
+    * Add Values to Property record.
+    * 
+    * @param data
+    *          PropertyData
+    * @throws SQLException
+    *           database error
+    * @throws IOException
+    *           I/O error
+    * @thorws RepositoryException if Value data large of JDBC accepted (Integer.MAX_VALUE)
+    */
+   protected void addValues(String cid, PropertyData data) throws IOException, SQLException, RepositoryException
+   {
+      List<ValueData> vdata = data.getValues();
+
+      for (int i = 0; i < vdata.size(); i++)
+      {
+         ValueData vd = vdata.get(i);
+         ValueIOChannel channel = valueStorageProvider.getApplicableChannel(data, i);
+         InputStream stream;
+         int streamLength;
+         String storageId;
+         if (channel == null)
+         {
+            // prepare write of Value in database
+            if (vd.isByteArray())
+            {
+               byte[] dataBytes = vd.getAsByteArray();
+               stream = new ByteArrayInputStream(dataBytes);
+               streamLength = dataBytes.length;
+            }
+            else
+            {
+               // it's StreamPersistedValueData
+               StreamPersistedValueData streamData = (StreamPersistedValueData)vd;
+               stream = streamData.getStream();
+
+               // TODO spool on JDBC driver read - multiplexing the data to two stores, database and spool file, with one read.
+               SwapFile swapFile = swapValueData(cid, i, data.getPersistedVersion(), stream);
+
+               long vlen = swapFile.length();
+               if (vlen < 0)
+               {
+                  // TODO not actual with SwapFile, but if it will be reworked can be so
+                  streamLength = stream.available();
+                  LOG.warn("Cannot obtain exact Value data length, will use available from the stream " + streamLength
+                     + ". Property " + data.getQPath().getAsString());
+               }
+               else if (vlen <= Integer.MAX_VALUE)
+               {
+                  streamLength = (int)vlen;
+               }
+               else
+               {
+                  throw new RepositoryException("Value data large of allowed by JDBC (Integer.MAX_VALUE) " + vlen
+                     + ". Property " + data.getQPath().getAsString());
+               }
+
+               // set persistent file to ValueData, will be available for saving Property.
+               streamData.setPersistedFile(swapFile);
+               stream = streamData.getAsStream();
+            }
+            storageId = null;
+         }
+         else
+         {
+            // write Value in external VS
+            channel.write(data.getIdentifier(), vd);
+            valueChanges.add(channel);
+            storageId = channel.getStorageId();
+            stream = null;
+            streamLength = 0;
+         }
+         addValueData(cid, i, stream, streamLength, storageId);
+      }
+   }
+
+   protected abstract int addNodeRecord(NodeData data) throws SQLException;
+
+   protected abstract int addPropertyRecord(PropertyData prop) throws SQLException;
+
+   protected abstract ResultSet findItemByIdentifier(String identifier) throws SQLException;
+
+   protected abstract ResultSet findPropertyByName(String parentId, String name) throws SQLException;
+
+   protected abstract ResultSet findItemByName(String parentId, String name, int index) throws SQLException;
+
+   protected abstract ResultSet findChildNodesByParentIdentifier(String parentIdentifier) throws SQLException;
+
+   protected abstract ResultSet findChildNodesCountByParentIdentifier(String parentIdentifier) throws SQLException;
+
+   protected abstract ResultSet findChildPropertiesByParentIdentifier(String parentIdentifier) throws SQLException;
+
+   protected abstract int addReference(PropertyData data) throws SQLException, IOException;
+
+   protected abstract int renameNode(NodeData data) throws SQLException;
+
+   protected abstract int deleteReference(String propertyIdentifier) throws SQLException;
+
+   protected abstract ResultSet findReferences(String nodeIdentifier) throws SQLException;
+
+   protected abstract int deleteItemByIdentifier(String identifier) throws SQLException;
+
+   protected abstract int updateNodeByIdentifier(int version, int index, int orderNumb, String identifier)
+      throws SQLException;
+
+   protected abstract int updatePropertyByIdentifier(int version, int type, String identifier) throws SQLException;
+
+   // -------- values processing ------------
+   protected abstract int addValueData(String cid, int orderNumber, InputStream stream, int streamLength,
+      String storageId) throws SQLException;
+
+   protected abstract int deleteValueData(String cid) throws SQLException;
+
+   protected abstract ResultSet findValuesByPropertyId(String cid) throws SQLException;
+
+   protected abstract ResultSet findValuesStorageDescriptorsByPropertyId(String cid) throws SQLException;
+
+   @Deprecated
+   protected abstract ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws SQLException;
+
+   protected abstract ResultSet findItemByIdentifierNew(String identifier) throws SQLException;
+
+   protected abstract ResultSet findItemByNameNew(String parentId, String name, int index) throws SQLException;
+
+   protected abstract ResultSet findChildNodesByParentIdentifierNew(String parentIdentifier) throws SQLException;
+
+   protected abstract ResultSet getChildPropertiesByParentIdentifier(String parentIdentifier) throws SQLException;
+
+   protected abstract ResultSet findReferenceProperties(String parentIdentifier) throws SQLException;
 }

Deleted: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnectionIJ.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnectionIJ.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnectionIJ.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2003-2009 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.storage.jdbc.optimisation;
-
-import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
-
-import java.io.File;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 
- *
- * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
- * @version $Id: CQJDBCStorageConnectionIJ.java 111 2008-11-11 11:11:11Z serg $
- */
-abstract class CQJDBCStorageConnectionIJ extends CQJDBCStorageConnection
-{
-
-   /**
-    * JDBCStorageConnection constructor.
-    * 
-    * @param dbConnection
-    *          JDBC connection
-    * @param containerName
-    *          Workspace conatiner name
-    * @param valueStorageProvider
-    *          External Value Storage provider
-    * @param maxBufferSize
-    *          maximum buffer size (config)
-    * @param swapDirectory
-    *          swap directory (config)
-    * @param swapCleaner
-    *          swap cleaner (FileCleaner)
-    * @throws SQLException
-    *           database error
-    */
-   protected CQJDBCStorageConnectionIJ(Connection dbConnection, boolean readOnly, String containerName,
-      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
-      throws SQLException
-   {
-      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
-
-   }
-
-}

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -21,23 +21,31 @@
 import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
 import org.exoplatform.services.jcr.config.RepositoryEntry;
 import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.storage.WorkspaceDataContainerBase;
 import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
-import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer;
 import org.exoplatform.services.jcr.impl.storage.jdbc.db.GenericConnectionFactory;
+import org.exoplatform.services.jcr.impl.storage.jdbc.db.OracleConnectionFactory;
+import org.exoplatform.services.jcr.impl.storage.jdbc.db.WorkspaceStorageConnectionFactory;
 import org.exoplatform.services.jcr.impl.storage.jdbc.init.DBInitializer;
 import org.exoplatform.services.jcr.impl.storage.jdbc.init.DBInitializerException;
 import org.exoplatform.services.jcr.impl.storage.jdbc.init.IngresSQLDBInitializer;
 import org.exoplatform.services.jcr.impl.storage.jdbc.init.OracleDBInitializer;
 import org.exoplatform.services.jcr.impl.storage.jdbc.init.PgSQLDBInitializer;
-import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.GenericCQConnectionFactory;
 import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.HSQLDBConnectionFactory;
 import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.MySQLConnectionFactory;
-import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.OracleConnectionFactory;
+import org.exoplatform.services.jcr.impl.storage.jdbc.update.StorageUpdateManager;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
 import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
 import org.exoplatform.services.naming.InitialContextInitializer;
 import org.picocontainer.Startable;
 
+import java.io.File;
 import java.io.IOException;
+import java.sql.Connection;
 
 import javax.jcr.RepositoryException;
 import javax.naming.InitialContext;
@@ -50,10 +58,113 @@
  * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a>
  * @version $Id:GenericWorkspaceDataContainer.java 13433 2007-03-15 16:07:23Z peterit $
  */
-public class CQJDBCWorkspaceDataContainer extends JDBCWorkspaceDataContainer implements Startable
+public class CQJDBCWorkspaceDataContainer extends WorkspaceDataContainerBase implements Startable
 {
 
+   protected static final Log LOG = ExoLogger.getLogger("jcr.JDBCWorkspaceDataContainer");
+
+   //configuration params
+
+   public final static String SOURCE_NAME = "source-name";
+
+   public final static String MULTIDB = "multi-db";
+
+   public final static String SINGLEDB = "single-db";
+
    /**
+    * Describe which type of RDBMS will be used (DB creation metadata etc.)
+    */
+   public final static String DB_DIALECT = "dialect";
+
+   public final static String DB_DRIVER = "driverClassName";
+
+   public final static String DB_URL = "url";
+
+   public final static String DB_USERNAME = "username";
+
+   public final static String DB_PASSWORD = "password";
+
+   protected final String containerName;
+
+   protected final String dbSourceName;
+
+   protected final boolean multiDb;
+
+   protected final String dbDriver;
+
+   protected final String dbDialect;
+
+   protected final String dbUrl;
+
+   protected final String dbUserName;
+
+   protected final String dbPassword;
+
+   protected final ValueStoragePluginProvider valueStorageProvider;
+
+   protected String storageVersion;
+
+   protected int maxBufferSize;
+
+   protected File swapDirectory;
+
+   protected FileCleaner swapCleaner;
+
+   protected GenericConnectionFactory connFactory;
+
+   /**
+    * Shared connection factory.
+    * 
+    * Issued to share JDBC connection between system and regular workspace in case of same database
+    * used for storage.
+    * 
+    */
+   class SharedConnectionFactory extends GenericConnectionFactory
+   {
+
+      /**
+       * JDBC connection.
+       */
+      final private Connection connection;
+
+      /**
+       * SharedConnectionFactory constructor.
+       * 
+       * @param connection
+       *          JDBC - connection
+       * @param containerName
+       *          - container name
+       * @param multiDb
+       *          - multidatabase status
+       * @param valueStorageProvider
+       *          - external Value Storages provider
+       * @param maxBufferSize
+       *          - Maximum buffer size (see configuration)
+       * @param swapDirectory
+       *          - Swap directory (see configuration)
+       * @param swapCleaner
+       *          - Swap cleaner (internal FileCleaner).
+       */
+      SharedConnectionFactory(Connection connection, String containerName, boolean multiDb,
+         ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+      {
+
+         super(null, null, null, null, null, containerName, multiDb, valueStorageProvider, maxBufferSize,
+            swapDirectory, swapCleaner);
+
+         this.connection = connection;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public Connection getJdbcConnection() throws RepositoryException
+      {
+         return connection;
+      }
+   }
+
+   /**
     * Constructor with value storage plugins.
     * 
     * @param wsConfig
@@ -69,10 +180,275 @@
       InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider)
       throws RepositoryConfigurationException, NamingException, RepositoryException, IOException
    {
-      super(wsConfig, repConfig, contextInit, valueStorageProvider);
+
+      checkIntegrity(wsConfig, repConfig);
+
+      this.containerName = wsConfig.getName();
+      this.multiDb = Boolean.parseBoolean(wsConfig.getContainer().getParameterValue(MULTIDB));
+      this.valueStorageProvider = valueStorageProvider;
+
+      // ------------- Database config ------------------
+      String pDbDialect = null;
+      try
+      {
+         pDbDialect = detectDialect(wsConfig.getContainer().getParameterValue(DB_DIALECT));
+         LOG.info("Using a dialect '" + pDbDialect + "'");
+      }
+      catch (RepositoryConfigurationException e)
+      {
+         LOG.info("Using a default dialect '" + DBConstants.DB_DIALECT_GENERIC + "'");
+         pDbDialect = DBConstants.DB_DIALECT_GENERIC;
+      }
+      this.dbDialect = pDbDialect;
+
+      String pDbDriver = null;
+      String pDbUrl = null;
+      String pDbUserName = null;
+      String pDbPassword = null;
+      try
+      {
+         pDbDriver = wsConfig.getContainer().getParameterValue(DB_DRIVER);
+
+         // username/passwd may not pesent
+         try
+         {
+            pDbUserName = wsConfig.getContainer().getParameterValue(DB_USERNAME);
+            pDbPassword = wsConfig.getContainer().getParameterValue(DB_PASSWORD);
+         }
+         catch (RepositoryConfigurationException e)
+         {
+            pDbUserName = pDbPassword = null;
+         }
+
+         pDbUrl = wsConfig.getContainer().getParameterValue(DB_URL); // last here!
+      }
+      catch (RepositoryConfigurationException e)
+      {
+      }
+
+      if (pDbUrl != null)
+      {
+         this.dbDriver = pDbDriver;
+         this.dbUrl = pDbUrl;
+         this.dbUserName = pDbUserName;
+         this.dbPassword = pDbPassword;
+         this.dbSourceName = null;
+         LOG.info("Connect to JCR database as user '" + this.dbUserName + "'");
+      }
+      else
+      {
+         this.dbDriver = null;
+         this.dbUrl = null;
+         this.dbUserName = null;
+         this.dbPassword = null;
+
+         String sn;
+         try
+         {
+            sn = wsConfig.getContainer().getParameterValue(SOURCE_NAME);
+         }
+         catch (RepositoryConfigurationException e)
+         {
+            sn = wsConfig.getContainer().getParameterValue("sourceName"); // TODO for backward comp,
+            // remove in rel.2.0
+         }
+         this.dbSourceName = sn;
+      }
+
+      // ------------- Values swap config ------------------
+      try
+      {
+         this.maxBufferSize = wsConfig.getContainer().getParameterInteger(MAXBUFFERSIZE_PROP);
+      }
+      catch (RepositoryConfigurationException e)
+      {
+         this.maxBufferSize = DEF_MAXBUFFERSIZE;
+      }
+
+      try
+      {
+         String sdParam = wsConfig.getContainer().getParameterValue(SWAPDIR_PROP);
+         this.swapDirectory = new File(sdParam);
+      }
+      catch (RepositoryConfigurationException e1)
+      {
+         this.swapDirectory = new File(DEF_SWAPDIR);
+      }
+      if (!swapDirectory.exists())
+         swapDirectory.mkdirs();
+
+      this.swapCleaner = new FileCleaner(false);
+
+      initDatabase();
+
+      String suParam = null;
+      boolean enableStorageUpdate = false;
+      try
+      {
+         suParam = wsConfig.getContainer().getParameterValue("update-storage");
+         enableStorageUpdate = Boolean.parseBoolean(suParam);
+      }
+      catch (RepositoryConfigurationException e)
+      {
+         if (LOG.isDebugEnabled())
+            LOG.debug("update-storage parameter is not set " + dbSourceName);
+      }
+
+      this.storageVersion =
+         StorageUpdateManager.checkVersion(dbSourceName, this.connFactory.getJdbcConnection(), multiDb,
+            enableStorageUpdate);
+
+      LOG.info(getInfo());
    }
 
    /**
+    * Prepare sefault connection factory.
+    * 
+    * @return GenericConnectionFactory
+    * @throws NamingException
+    *           on JNDI error
+    * @throws RepositoryException
+    *           on Storage error
+    */
+   protected GenericConnectionFactory defaultConnectionFactory() throws NamingException, RepositoryException
+   {
+      // by default
+      if (dbSourceName != null)
+      {
+         DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+         if (ds != null)
+            return new GenericConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
+               swapDirectory, swapCleaner);
+
+         throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+      }
+
+      return new GenericConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
+         valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * Prepare default DB initializer.
+    * 
+    * @param sqlPath
+    *          - path to SQL script (database creation script)
+    * @return DBInitializer instance
+    * @throws NamingException
+    *           on JNDI error
+    * @throws RepositoryException
+    *           on Storage error
+    * @throws IOException
+    *           on I/O error
+    */
+   protected DBInitializer defaultDBInitializer(String sqlPath) throws NamingException, RepositoryException,
+      IOException
+   {
+      return new DBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
+   }
+
+   /**
+    * Checks if DataSources used in right manner.
+    * 
+    * @param wsConfig
+    *          Workspace configuration
+    * @param repConfig
+    *          Repository configuration
+    * @throws RepositoryConfigurationException
+    *           in case of configuration errors
+    */
+   protected void checkIntegrity(WorkspaceEntry wsConfig, RepositoryEntry repConfig)
+      throws RepositoryConfigurationException
+   {
+      boolean isMulti;
+      for (WorkspaceEntry wsEntry : repConfig.getWorkspaceEntries())
+      {
+         if (wsEntry.getName().equals(wsConfig.getName())
+            || !wsEntry.getContainer().getType().equals(wsConfig.getContainer().getType())
+            || !wsEntry.getContainer().getType().equals(this.getClass().getName()))
+            continue;
+
+         // MULTIDB
+         if (!wsEntry.getContainer().getParameterValue(MULTIDB).equals(
+            wsConfig.getContainer().getParameterValue(MULTIDB)))
+         {
+            throw new RepositoryConfigurationException("All workspaces must be " + MULTIDB + " or " + SINGLEDB
+               + ". But " + wsEntry.getName() + "- multi-db=" + wsEntry.getContainer().getParameterValue(MULTIDB)
+               + " and " + wsConfig.getName() + "- multi-db=" + wsConfig.getContainer().getParameterValue(MULTIDB));
+         }
+
+         isMulti = Boolean.parseBoolean(wsConfig.getContainer().getParameterValue(MULTIDB));
+
+         // source name
+         String wsSourceName = null;
+         String newWsSourceName = null;
+         try
+         {
+            wsSourceName = wsEntry.getContainer().getParameterValue("sourceName");
+            newWsSourceName = wsConfig.getContainer().getParameterValue("sourceName");
+         }
+         catch (RepositoryConfigurationException e)
+         {
+         }
+
+         if (wsSourceName != null && newWsSourceName != null)
+         {
+            if (isMulti)
+            {
+               if (wsSourceName.equals(newWsSourceName))
+               {
+                  throw new RepositoryConfigurationException("SourceName " + wsSourceName + " alredy in use in "
+                     + wsEntry.getName() + ". SourceName must be different in " + MULTIDB
+                     + ". Check configuration for " + wsConfig.getName());
+               }
+            }
+            else
+            {
+               if (!wsSourceName.equals(newWsSourceName))
+               {
+                  throw new RepositoryConfigurationException("SourceName must be equals in " + SINGLEDB + " "
+                     + "repository." + " Check " + wsEntry.getName() + " and " + wsConfig.getName());
+               }
+            }
+            continue;
+         }
+
+         // db-url
+         String wsUri = null;
+         String newWsUri = null;
+         try
+         {
+            wsUri = wsEntry.getContainer().getParameterValue("db-url");
+            newWsUri = wsConfig.getContainer().getParameterValue("db-url");
+         }
+         catch (RepositoryConfigurationException e)
+         {
+         }
+
+         if (wsUri != null && newWsUri != null)
+         {
+            if (isMulti)
+            {
+               if (wsUri.equals(newWsUri))
+               {
+                  throw new RepositoryConfigurationException("db-url  " + wsUri + " alredy in use in "
+                     + wsEntry.getName() + ". db-url must be different in " + MULTIDB + ". Check configuration for "
+                     + wsConfig.getName());
+
+               }
+            }
+            else
+            {
+               if (!wsUri.equals(newWsUri))
+               {
+                  throw new RepositoryConfigurationException("db-url must be equals in " + SINGLEDB + " "
+                     + "repository." + " Check " + wsEntry.getName() + " and " + wsConfig.getName());
+               }
+            }
+         }
+      }
+   }
+
+   /**
     * Init storage database.
     * 
     * @throws NamingException
@@ -105,11 +481,9 @@
       }
       else if (dbDialect == DBConstants.DB_DIALECT_ORACLE)
       {
-
          this.connFactory = defaultConnectionFactory();
          sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
          dbInitilizer = new OracleDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
-
       }
       else if (dbDialect == DBConstants.DB_DIALECT_PGSQL)
       {
@@ -236,29 +610,193 @@
    }
 
    /**
-    * Prepare sefault connection factory.
+    * Return ConnectionFactory.
     * 
-    * @return GenericConnectionFactory
-    * @throws NamingException
-    *           on JNDI error
-    * @throws RepositoryException
-    *           on Storage error
+    * @return WorkspaceStorageConnectionFactory connection
     */
-   protected GenericConnectionFactory defaultConnectionFactory() throws NamingException, RepositoryException
+   protected GenericConnectionFactory getConnectionFactory()
    {
-      // by default
-      if (dbSourceName != null)
+      return connFactory;
+   }
+
+   protected String detectDialect(String confParam)
+   {
+      for (String dbType : DBConstants.DB_DIALECTS)
       {
-         DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
-         if (ds != null)
-            return new GenericCQConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
-               swapDirectory, swapCleaner);
+         if (dbType.equalsIgnoreCase(confParam))
+            return dbType;
+      }
 
-         throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+      return DBConstants.DB_DIALECT_GENERIC; // by default
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public WorkspaceStorageConnection openConnection() throws RepositoryException
+   {
+
+      return connFactory.openConnection();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException
+   {
+
+      return connFactory.openConnection(readOnly);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public WorkspaceStorageConnection reuseConnection(WorkspaceStorageConnection original) throws RepositoryException
+   {
+
+      if (original instanceof CQJDBCStorageConnection)
+      {
+         WorkspaceStorageConnectionFactory cFactory =
+            new SharedConnectionFactory(((CQJDBCStorageConnection)original).getJdbcConnection(), containerName,
+               multiDb, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+         return cFactory.openConnection();
       }
+      else
+      {
+         return openConnection();
+      }
+   }
 
-      return new GenericCQConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
-         valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   /**
+    * {@inheritDoc}
+    */
+   public String getName()
+   {
+      return containerName;
    }
 
+   /**
+    * {@inheritDoc}
+    */
+   public String getInfo()
+   {
+      String str =
+         "JDBC based JCR Workspace Data container \n" + "container name: " + containerName + " \n"
+            + "data source JNDI name: " + dbSourceName + "\n" + "is multi database: " + multiDb + "\n"
+            + "storage version: " + storageVersion + "\n" + "value storage provider: " + valueStorageProvider + "\n"
+            + "max buffer size (bytes): " + maxBufferSize + "\n" + "swap directory path: "
+            + swapDirectory.getAbsolutePath();
+      return str;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String getStorageVersion()
+   {
+      return storageVersion;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void start()
+   {
+      this.swapCleaner.start();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void stop()
+   {
+      this.swapCleaner.halt();
+      this.swapCleaner.interrupt();
+
+      // TODO HSQLDB Stop (debug)
+      // if (dbDialect.equals(DB_DIALECT_GENERIC) ||
+      // dbDialect.equals(DB_DIALECT_HSQLDB)) {
+      // // shutdown in-process HSQLDB database
+      // System.out.println("Shutdown in-process HSQLDB database...");
+      // try {
+      // JDBCStorageConnection conn = (JDBCStorageConnection) openConnection();
+      // Connection jdbcConn = conn.getJdbcConnection();
+      // String dbUrl = jdbcConn.getMetaData().getURL();
+      // if (dbUrl.startsWith("jdbc:hsqldb:file") ||
+      // dbUrl.startsWith("jdbc:hsqldb:mem")) {
+      // // yeah, there is in-process hsqldb, shutdown it now
+      // jdbcConn.createStatement().execute("SHUTDOWN");
+      // System.out.println("Shutdown in-process HSQLDB database... done.");
+      // }
+      // } catch (Throwable e) {
+      // log.error("JDBC Data container stop error " + e);
+      // e.printStackTrace();
+      // }
+      // }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isSame(WorkspaceDataContainer another)
+   {
+      if (another == this)
+         return true;
+
+      if (another instanceof CQJDBCWorkspaceDataContainer)
+      {
+         CQJDBCWorkspaceDataContainer anotherJdbc = (CQJDBCWorkspaceDataContainer)another;
+
+         if (getDbSourceName() != null)
+            // by jndi ds name
+            return getDbSourceName().equals(anotherJdbc.getDbSourceName());
+
+         // by db connection params
+         return getDbDriver().equals(anotherJdbc.getDbDriver()) && getDbUrl().equals(anotherJdbc.getDbUrl())
+            && getDbUserName().equals(anotherJdbc.getDbUserName());
+      }
+
+      return false;
+   }
+
+   /**
+    * Used in <code>equals()</code>.
+    * 
+    * @return DataSource name
+    */
+   protected String getDbSourceName()
+   {
+      return dbSourceName;
+   }
+
+   /**
+    * Used in <code>equals()</code>.
+    * 
+    * @return JDBC driver
+    */
+   protected String getDbDriver()
+   {
+      return dbDriver;
+   }
+
+   /**
+    * Used in <code>equals()</code>.
+    * 
+    * @return Database URL
+    */
+   protected String getDbUrl()
+   {
+      return dbUrl;
+   }
+
+   /**
+    * Used in <code>equals()</code>.
+    * 
+    * @return Database username
+    */
+   protected String getDbUserName()
+   {
+      return dbUserName;
+   }
 }

Deleted: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainerIJ.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainerIJ.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainerIJ.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2003-2009 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.storage.jdbc.optimisation;
-
-import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
-import org.exoplatform.services.jcr.config.RepositoryEntry;
-import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
-import org.exoplatform.services.naming.InitialContextInitializer;
-
-import java.io.IOException;
-
-import javax.jcr.RepositoryException;
-import javax.naming.NamingException;
-
-/**
- * Created by The eXo Platform SAS.
- * 
- * <br/>Date: 
- *
- * @author <a href="karpenko.sergiy at gmail.com">Karpenko Sergiy</a> 
- * @version $Id: CQJDBWorkspaceDataContainerIJ.java 111 2008-11-11 11:11:11Z serg $
- */
-public class CQJDBCWorkspaceDataContainerIJ extends CQJDBCWorkspaceDataContainer
-{
-   /**
-    * Constructor with value storage plugins.
-    * 
-    * @param wsConfig
-    *          Workspace configuration
-    * @param valueStrorageProvider
-    *          External Value Stprages provider
-    * @throws RepositoryConfigurationException
-    *           if Repository configuration is wrong
-    * @throws NamingException
-    *           if JNDI exception (on DataSource lookup)
-    */
-   public CQJDBCWorkspaceDataContainerIJ(WorkspaceEntry wsConfig, RepositoryEntry repConfig,
-      InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider)
-      throws RepositoryConfigurationException, NamingException, RepositoryException, IOException
-   {
-      super(wsConfig, repConfig, contextInit, valueStorageProvider);
-   }
-}

Added: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/DBConstants.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/DBConstants.java	                        (rev 0)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/DBConstants.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * @author Gennady Azarenkov
+ * @version $Id: DBConstants.java 34801 2009-07-31 15:44:50Z dkatayev $
+ */
+
+public class DBConstants
+{
+   // ======================== Error constants ======================== 
+   /**
+    * JCR_PK_ITEM.
+    */
+   protected String JCR_PK_ITEM;
+
+   /**
+    * JCR_FK_ITEM_PARENT.
+    */
+   protected String JCR_FK_ITEM_PARENT;
+
+   /**
+    * JCR_IDX_ITEM_PARENT.
+    */
+   protected String JCR_IDX_ITEM_PARENT;
+
+   /**
+    * JCR_IDX_ITEM_PARENT_NAME.
+    */
+   protected String JCR_IDX_ITEM_PARENT_NAME;
+
+   /**
+    * JCR_IDX_ITEM_PARENT_ID.
+    */
+   protected String JCR_IDX_ITEM_PARENT_ID;
+
+   /**
+    * JCR_PK_VALUE.
+    */
+   protected String JCR_PK_VALUE;
+
+   /**
+    * JCR_FK_VALUE_PROPERTY.
+    */
+   protected String JCR_FK_VALUE_PROPERTY;
+
+   /**
+    * JCR_IDX_VALUE_PROPERTY.
+    */
+   protected String JCR_IDX_VALUE_PROPERTY;
+
+   /**
+    * JCR_PK_REF.
+    */
+   protected String JCR_PK_REF;
+
+   /**
+    * JCR_IDX_REF_PROPERTY.
+    */
+   protected String JCR_IDX_REF_PROPERTY;
+
+   // ======================== SQL scripts ======================== 
+   /**
+    * FIND_ITEM_BY_ID.
+    */
+   protected String FIND_ITEM_BY_ID;
+
+   /**
+    * FIND_ITEM_BY_PATH.
+    */
+   protected String FIND_ITEM_BY_PATH;
+
+   /**
+    * FIND_ITEM_BY_NAME.
+    */
+   protected String FIND_ITEM_BY_NAME;
+
+   /**
+    * FIND_ITEM_BY_NAME NEW.
+    */
+   protected String FIND_ITEM_BY_NAME_NEW;
+
+   /**
+    * FIND_NODE_BY_ID.
+    */
+   protected String FIND_ITEM_BY_ID_NEW;
+
+   /**
+    * FIND_CHILD_PROPERTY_BY_PATH.
+    */
+   protected String FIND_CHILD_PROPERTY_BY_PATH;
+
+   /**
+    * FIND_PROPERTY_BY_NAME.
+    */
+   protected String FIND_PROPERTY_BY_NAME;
+
+   /**
+    * FIND_REFERENCES.
+    */
+   protected String FIND_REFERENCES;
+
+   protected String FIND_REFERENCE_PROPERTIES;
+
+   /**
+    * FIND_VALUES_BY_PROPERTYID.
+    */
+   protected String FIND_VALUES_BY_PROPERTYID;
+
+   /**
+    * FIND_VALUE_BY_PROPERTYID_OREDERNUMB.
+    */
+   protected String FIND_VALUES_VSTORAGE_DESC_BY_PROPERTYID;
+
+   @Deprecated
+   protected String FIND_VALUE_BY_PROPERTYID_OREDERNUMB;
+
+   /**
+    * FIND_NODES_BY_PARENTID.
+    */
+   protected String FIND_NODES_BY_PARENTID;
+
+   /**
+    * FIND_NODES_BY_PARENTID NEW.
+    */
+   protected String FIND_NODES_BY_PARENTID_NEW;
+
+   /**
+    * FIND_NODES_COUNT_BY_PARENTID.
+    */
+   protected String FIND_NODES_COUNT_BY_PARENTID;
+
+   /**
+    * FIND_PROPERTIES_BY_PARENTID.
+    */
+   protected String FIND_PROPERTIES_BY_PARENTID;
+
+   /**
+    * FIND_PROPERTIES_BY_PARENTID_NEW.
+    */
+   protected String GET_PROPERTIES_BY_PARENTID;
+
+   /**
+    * INSERT_NODE.
+    */
+   protected String INSERT_NODE;
+
+   /**
+    * INSERT_PROPERTY.
+    */
+   protected String INSERT_PROPERTY;
+
+   /**
+    * INSERT_VALUE.
+    */
+   protected String INSERT_VALUE;
+
+   /**
+    * INSERT_REF.
+    */
+   protected String INSERT_REF;
+
+   /**
+    * RENAME_NODE.
+    */
+   protected String RENAME_NODE;
+
+   /**
+    * UPDATE_NODE.
+    */
+   protected String UPDATE_NODE;
+
+   /**
+    * UPDATE_PROPERTY.
+    */
+   protected String UPDATE_PROPERTY;
+
+   /**
+    * DELETE_ITEM.
+    */
+   protected String DELETE_ITEM;
+
+   /**
+    * DELETE_VALUE.
+    */
+   protected String DELETE_VALUE;
+
+   /**
+    * DELETE_REF.
+    */
+   protected String DELETE_REF;
+
+   // ======================== ITEMS table ======================== 
+   /**
+    * COLUMN_ID.
+    */
+   protected static final String COLUMN_ID = "ID";
+
+   /**
+    * COLUMN_PARENTID.
+    */
+   protected static final String COLUMN_PARENTID = "PARENT_ID";
+
+   /**
+    * COLUMN_NAME.
+    */
+   protected static final String COLUMN_NAME = "NAME";
+
+   /**
+    * COLUMN_VERSION.
+    */
+   protected static final String COLUMN_VERSION = "VERSION";
+
+   /**
+    * COLUMN_CLASS.
+    */
+   protected static final String COLUMN_CLASS = "I_CLASS";
+
+   /**
+    * COLUMN_INDEX.
+    */
+   protected static final String COLUMN_INDEX = "I_INDEX";
+
+   /**
+    * COLUMN_NORDERNUM.
+    */
+   protected static final String COLUMN_NORDERNUM = "N_ORDER_NUM";
+
+   /**
+    * COLUMN_PTYPE.
+    */
+   protected static final String COLUMN_PTYPE = "P_TYPE";
+
+   /**
+    * COLUMN_PMULTIVALUED.
+    */
+   protected static final String COLUMN_PMULTIVALUED = "P_MULTIVALUED";
+
+   // VALUE table
+   /**
+    * COLUMN_VDATA.
+    */
+   protected static final String COLUMN_VDATA = "DATA";
+
+   /**
+    * COLUMN_VORDERNUM.
+    */
+   protected static final String COLUMN_VORDERNUM = "ORDER_NUM";
+
+   /**
+    * COLUMN_VSTORAGE_DESC.
+    */
+   protected static final String COLUMN_VSTORAGE_DESC = "STORAGE_DESC";
+
+   // Dialects
+   /**
+    * DB_DIALECT_GENERIC.
+    */
+   public final static String DB_DIALECT_GENERIC = "Generic".intern();
+
+   /**
+    * DB_DIALECT_ORACLE.
+    */
+   public final static String DB_DIALECT_ORACLE = "Oracle".intern();
+
+   /**
+    * DB_DIALECT_ORACLEOCI.
+    */
+   public final static String DB_DIALECT_ORACLEOCI = "Oracle-OCI".intern();
+
+   /**
+    * DB_DIALECT_PGSQL.
+    */
+   public final static String DB_DIALECT_PGSQL = "PgSQL".intern();
+
+   /**
+    * DB_DIALECT_MYSQL.
+    */
+   public final static String DB_DIALECT_MYSQL = "MySQL".intern();
+
+   /**
+    * DB_DIALECT_MYSQL_UTF8.
+    */
+   public final static String DB_DIALECT_MYSQL_UTF8 = "MySQL-UTF8".intern();
+
+   /**
+    * DB_DIALECT_HSQLDB.
+    */
+   public final static String DB_DIALECT_HSQLDB = "HSQLDB".intern();
+
+   /**
+    * DB_DIALECT_DB2.
+    */
+   public final static String DB_DIALECT_DB2 = "DB2".intern();
+
+   /**
+    * DB_DIALECT_DB2V8.
+    */
+   public final static String DB_DIALECT_DB2V8 = "DB2V8".intern();
+
+   /**
+    * DB_DIALECT_MSSQL.
+    */
+   public final static String DB_DIALECT_MSSQL = "MSSQL".intern();
+
+   /**
+    * DB_DIALECT_SYBASE.
+    */
+   public final static String DB_DIALECT_SYBASE = "Sybase".intern();
+
+   /**
+    * DB_DIALECT_DERBY.
+    */
+   public final static String DB_DIALECT_DERBY = "Derby".intern();
+
+   /**
+    * DB_DIALECT_INGRES.
+    */
+   public final static String DB_DIALECT_INGRES = "Ingres".intern();
+
+   /**
+    * DB_DIALECTS.
+    */
+   public final static String[] DB_DIALECTS =
+      {DB_DIALECT_GENERIC, DB_DIALECT_ORACLE, DB_DIALECT_ORACLEOCI, DB_DIALECT_PGSQL, DB_DIALECT_MYSQL,
+         DB_DIALECT_HSQLDB, DB_DIALECT_DB2, DB_DIALECT_DB2V8, DB_DIALECT_MSSQL, DB_DIALECT_SYBASE, DB_DIALECT_DERBY,
+         DB_DIALECT_MYSQL_UTF8, DB_DIALECT_INGRES};
+
+}

Added: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/NewSQLExceptionHandler.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/NewSQLExceptionHandler.java	                        (rev 0)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/NewSQLExceptionHandler.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation;
+
+import org.exoplatform.services.jcr.dataflow.ItemState;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.impl.storage.JCRInvalidItemStateException;
+import org.exoplatform.services.jcr.impl.storage.JCRItemExistsException;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.ItemExistsException;
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * The eXo JCR database has constraints can be violated.
+ * 
+ * JCR_PK_XCONTAINER - Can not be exisits two containers with same version
+ * 
+ * JCR_PK_XITEM - Item already exists with this ID JCR_FK_XITEM_PARENT - Parent not found by ID
+ * JCR_IDX_XITEM_PARENT - Item already exists with the parent, name, index, type(N/P), persisted
+ * version JCR_IDX_XITEM_PARENT_NAME - Item already exists with the type(N/P), parent, name, index,
+ * persisted version JCR_IDX_XITEM_PARENT_ID - Item already exists with the type(N/P), parent, ID,
+ * persisted version
+ * 
+ * JCR_PK_XVALUE - Value already exists with the ID (impossible, ID is autiincremented)
+ * JCR_FK_XVALUE_PROPERTY - There is no property exists for the value. JCR_IDX_XVALUE_PROPERTY -
+ * Value already exists with the property and order number
+ * 
+ * JCR_PK_XREF - Reference already exists to the node from property with order number
+ * JCR_IDX_XREF_PROPERTY - Reference already exists with the property and order number
+ * 
+ * @author Peter Nedonosko
+ * @version $Id: SQLExceptionHandler.java 34801 2009-07-31 15:44:50Z dkatayev $
+ */
+
+public class NewSQLExceptionHandler
+{
+
+   /**
+    * Ccontainer name.
+    */
+   private final String containerName;
+
+   /**
+    * Storage connection.
+    */
+   private final CQJDBCStorageConnection conn;
+
+   // ---------------- SQLException handler -------------------
+
+   /**
+    * SQLExceptionHandler constructor.
+    * 
+    * @param containerName
+    *          - workspace container name
+    * @param conn
+    *          - storage connection
+    */
+   NewSQLExceptionHandler(String containerName, CQJDBCStorageConnection conn)
+   {
+      this.containerName = containerName;
+      this.conn = conn;
+   }
+
+   /**
+    * Handle Add SQLException.
+    * 
+    * @param e
+    *          - an SQLException
+    * @param item
+    *          - context ItemData
+    * @return String with error message
+    * @throws RepositoryException
+    *           if <code>RepositoryException</code> should be thrown
+    * @throws InvalidItemStateException
+    *           if <code>InvalidItemStateException</code> should be thrown
+    */
+   protected String handleAddException(SQLException e, ItemData item) throws RepositoryException,
+      InvalidItemStateException
+   {
+      String message = "[" + containerName + "] ADD " + (item.isNode() ? "NODE. " : "PROPERTY. ");
+      String errMessage = e.getMessage();
+      String itemInfo =
+         item.getQPath().getAsString() + ", ID: " + item.getIdentifier() + ", ParentID: " + item.getParentIdentifier()
+            + (errMessage != null ? ". Cause >>>> " + errMessage : "");
+
+      if (errMessage != null)
+      {
+         // try detect error by foreign key names
+         String umsg = errMessage.toLowerCase().toUpperCase();
+         if (umsg.indexOf(conn.JCR_FK_ITEM_PARENT) >= 0)
+         {
+            message += "Parent not found. Item " + itemInfo;
+            throw new JCRInvalidItemStateException(message, item.getIdentifier(), ItemState.ADDED, e);
+         }
+         else if (umsg.indexOf(conn.JCR_PK_ITEM) >= 0)
+         {
+            message += "Item already exists. Condition: ID. " + itemInfo;
+            // InvalidItemStateException ! - because it's impossible add new item with existed UUID
+            throw new JCRInvalidItemStateException(message, item.getIdentifier(), ItemState.ADDED, e);
+         }
+         else if (umsg.indexOf(conn.JCR_IDX_ITEM_PARENT) >= 0 || umsg.indexOf(conn.JCR_IDX_ITEM_PARENT_NAME) >= 0)
+         {
+            message += "Item already exists. Condition: parent ID, name, index. " + itemInfo;
+            throw new ItemExistsException(message, e);
+         }
+         else if (umsg.indexOf(conn.JCR_IDX_ITEM_PARENT_ID) >= 0)
+         {
+            message += "Item already exists. Condition: parent ID and ID. " + itemInfo;
+            throw new ItemExistsException(message, e);
+         }
+         else if (umsg.indexOf(conn.JCR_FK_VALUE_PROPERTY) >= 0)
+         {
+            message += "Property is not exist but the value is being created. Condition: property ID. " + itemInfo;
+            throw new RepositoryException(message, e);
+         }
+         else if (umsg.indexOf(conn.JCR_IDX_VALUE_PROPERTY) >= 0)
+         {
+            message += "Property already exists. Condition: property ID, order number. " + itemInfo;
+            throw new RepositoryException(message, e);
+         }
+         else if (umsg.indexOf(conn.JCR_PK_VALUE) >= 0)
+         {
+            message +=
+               "[FATAL] Value already exists with the ValueID. Impossible state, check is ValueID is autoincremented. "
+                  + itemInfo;
+            throw new RepositoryException(message, e);
+         }
+         else if (umsg.indexOf(conn.JCR_PK_REF) >= 0)
+         {
+            message += "Reference chain already exists. Condition: node ID, property ID, order number. " + itemInfo;
+            throw new RepositoryException(message, e);
+         }
+         else if (umsg.indexOf(conn.JCR_IDX_REF_PROPERTY) >= 0)
+         {
+            message += "Referenceable property value already exists. Condition: property ID, order number. " + itemInfo;
+            throw new RepositoryException(message, e);
+         }
+      }
+
+      // try detect integrity violation
+      RepositoryException ownException = null;
+      try
+      {
+         NodeData parent = (NodeData)conn.getItemData(item.getParentIdentifier());
+         if (parent != null)
+         {
+            // have a parent
+            try
+            {
+               ItemData me = conn.getItemData(item.getIdentifier());
+               if (me != null)
+               {
+                  // item already exists
+                  message += "Item already exists in storage: " + itemInfo;
+                  ownException = new JCRItemExistsException(message, me.getIdentifier(), ItemState.ADDED, e);
+                  throw ownException;
+               }
+
+               me = conn.getItemData(parent, new QPathEntry(item.getQPath().getName(), item.getQPath().getIndex()));
+               if (me != null)
+               {
+                  message += "Item already exists in storage: " + itemInfo;
+                  ownException = new JCRItemExistsException(message, me.getIdentifier(), ItemState.ADDED, e);
+                  throw ownException;
+               }
+
+            }
+            catch (Exception ep)
+            {
+               // item not found or other things but error of item reading
+               if (ownException != null)
+                  throw ownException;
+            }
+
+            // MySQL violation
+            if (e.getClass().getName().indexOf("MySQLIntegrityConstraintViolationException") >= 0
+               && errMessage.indexOf(item.getIdentifier()) >= 0)
+            {
+               // it's JCR_PK_ITEM violation 
+               message += "Item already exists. Condition: ID. " + itemInfo;
+               throw new JCRInvalidItemStateException(message, item.getIdentifier(), ItemState.ADDED, e);
+            }
+
+            message += "Error of item add. " + itemInfo;
+            ownException = new RepositoryException(message, e);
+            throw ownException;
+         }
+      }
+      catch (Exception ep)
+      {
+         // no parent or error access it
+         if (ownException != null)
+            throw ownException;
+      }
+      message += "Error of item add. " + itemInfo;
+      throw new JCRInvalidItemStateException(message, item.getIdentifier(), ItemState.ADDED, e);
+   }
+
+   /**
+    * Handle Add IOException.
+    * 
+    * @param e
+    *          - an IOException
+    * @param item
+    *          - context ItemData
+    * @return String with error message
+    * @throws RepositoryException
+    *           if <code>RepositoryException</code> should be thrown
+    * @throws InvalidItemStateException
+    *           if <code>InvalidItemStateException</code> should be thrown
+    */
+   protected String handleAddException(IOException e, ItemData item) throws RepositoryException,
+      InvalidItemStateException
+   {
+      String message = "[" + containerName + "] ADD " + (item.isNode() ? "NODE. " : "PROPERTY. ");
+      String errMessage = e.getMessage();
+      String itemInfo =
+         item.getQPath().getAsString() + ", ID: " + item.getIdentifier() + ", ParentID: " + item.getParentIdentifier()
+            + (errMessage != null ? ". Cause >>>> " + errMessage : "");
+
+      // try detect integrity violation
+      RepositoryException ownException = null;
+      try
+      {
+         NodeData parent = (NodeData)conn.getItemData(item.getParentIdentifier());
+         if (parent != null)
+         {
+            // have a parent
+            try
+            {
+               ItemData me = conn.getItemData(item.getIdentifier());
+               if (me != null)
+               {
+                  // item already exists
+                  message += "Item already exists in storage: " + itemInfo;
+                  ownException = new ItemExistsException(message, e);
+                  throw ownException;
+               }
+
+               me = conn.getItemData(parent, new QPathEntry(item.getQPath().getName(), item.getQPath().getIndex()));
+               if (me != null)
+               {
+                  message += "Item already exists in storage: " + itemInfo;
+                  ownException = new ItemExistsException(message, e);
+                  throw ownException;
+               }
+
+            }
+            catch (Exception ep)
+            {
+               // item not found or other things but error of item reading
+               if (ownException != null)
+                  throw ownException;
+            }
+            message += "Error of item add. " + itemInfo;
+            ownException = new RepositoryException(message, e);
+            throw ownException;
+         }
+      }
+      catch (Exception ep)
+      {
+         // no parent or error access it
+         if (ownException != null)
+            throw ownException;
+      }
+      message += "Error of item add. " + itemInfo;
+      throw new JCRInvalidItemStateException(message, item.getIdentifier(), ItemState.ADDED, e);
+   }
+
+   /**
+    * Handle delete Exceptions.
+    * 
+    * @param e
+    *          - an SQLException
+    * @param item
+    *          - context ItemData
+    * @return String with error message
+    * @throws RepositoryException
+    *           if <code>RepositoryException</code> should be thrown
+    * @throws InvalidItemStateException
+    *           if <code>InvalidItemStateException</code> should be thrown
+    */
+   protected String handleDeleteException(SQLException e, ItemData item) throws RepositoryException,
+      InvalidItemStateException
+   {
+      String message = "[" + containerName + "] DELETE " + (item.isNode() ? "NODE. " : "PROPERTY. ");
+      String errMessage = e.getMessage();
+      String itemInfo =
+         item.getQPath().getAsString() + " " + item.getIdentifier()
+            + (errMessage != null ? ". Cause >>>> " + errMessage : "");
+
+      if (errMessage != null)
+      {
+         // try detect error by foreign key names
+         String umsg = errMessage.toLowerCase().toUpperCase();
+         if (umsg.indexOf(conn.JCR_FK_ITEM_PARENT) >= 0)
+         {
+            message += "Can not delete parent till childs exists. Item " + itemInfo;
+            throw new JCRInvalidItemStateException(message, item.getIdentifier(), ItemState.DELETED, e);
+         }
+         else if (umsg.indexOf(conn.JCR_FK_VALUE_PROPERTY) >= 0)
+         {
+            message +=
+               "[FATAL] Can not delete property item till it contains values. Condition: property ID. " + itemInfo;
+            throw new RepositoryException(message, e);
+         }
+      }
+
+      message += "Error of item delete " + itemInfo;
+      throw new RepositoryException(message, e);
+   }
+
+   /**
+    * Handle update Exceptions.
+    * 
+    * @param e
+    *          - an SQLException
+    * @param item
+    *          - context ItemData
+    * @return String with error message
+    * @throws RepositoryException
+    *           if <code>RepositoryException</code> should be thrown
+    * @throws InvalidItemStateException
+    *           if <code>InvalidItemStateException</code> should be thrown
+    */
+   protected String handleUpdateException(SQLException e, ItemData item) throws RepositoryException,
+      InvalidItemStateException
+   {
+      String message = "[" + containerName + "] EDIT " + (item.isNode() ? "NODE. " : "PROPERTY. ");
+      String errMessage = e.getMessage();
+      String itemInfo =
+         item.getQPath().getAsString() + " " + item.getIdentifier()
+            + (errMessage != null ? ". Cause >>>> " + errMessage : "");
+
+      if (errMessage != null)
+         // try detect error by foreign key names
+         if (errMessage.toLowerCase().toUpperCase().indexOf(conn.JCR_FK_VALUE_PROPERTY) >= 0)
+         {
+            message += "Property is not exists but the value is being created. Condition: property ID. " + itemInfo;
+            throw new RepositoryException(message, e);
+         }
+         else if (errMessage.toLowerCase().toUpperCase().indexOf(conn.JCR_PK_ITEM) >= 0)
+         {
+            message += "Item already exists. Condition: ID. " + itemInfo;
+            throw new JCRInvalidItemStateException(message, item.getIdentifier(), ItemState.UPDATED, e);
+         }
+
+      // try detect integrity violation
+      RepositoryException ownException = null;
+      try
+      {
+         ItemData me = conn.getItemData(item.getIdentifier());
+         if (me != null)
+         {
+            // item already exists
+            message += "Item already exists. But update errors. " + itemInfo;
+            ownException = new RepositoryException(message, e);
+            throw ownException;
+         }
+      }
+      catch (Exception ep)
+      {
+         // item not found or other things but error of item reading
+         if (ownException != null)
+            throw ownException;
+      }
+      message += "Error of item update. " + itemInfo;
+      throw new JCRInvalidItemStateException(message, item.getIdentifier(), ItemState.UPDATED, e);
+   }
+
+}

Deleted: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db;
-
-import org.exoplatform.services.jcr.impl.storage.jdbc.db.GenericConnectionFactory;
-import org.exoplatform.services.jcr.impl.storage.jdbc.monitor.ManagedConnection;
-import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
-import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
-
-import java.io.File;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-
-import javax.jcr.RepositoryException;
-import javax.sql.DataSource;
-
-/**
- * Created by The eXo Platform SAS
- * 
- * 15.03.2007
- * 
- * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a>
- * @version $Id: GenericConnectionFactory.java 34801 2009-07-31 15:44:50Z dkatayev $
- */
-public class GenericCQConnectionFactory extends GenericConnectionFactory
-{
-
-   /**
-    * GenericConnectionFactory constructor.
-    * 
-    * @param dataSource
-    *          - DataSource
-    * @param dbDriver
-    *          - JDBC Driver
-    * @param dbUrl
-    *          - JDBC URL
-    * @param dbUserName
-    *          - database username
-    * @param dbPassword
-    *          - database user password
-    * @param containerName
-    *          - Container name (see configuration)
-    * @param multiDb
-    *          - multidatabase state flag
-    * @param valueStorageProvider
-    *          - external Value Storages provider
-    * @param maxBufferSize
-    *          - Maximum buffer size (see configuration)
-    * @param swapDirectory
-    *          - Swap directory (see configuration)
-    * @param swapCleaner
-    *          - Swap cleaner (internal FileCleaner).
-    */
-   protected GenericCQConnectionFactory(DataSource dataSource, String dbDriver, String dbUrl, String dbUserName,
-      String dbPassword, String containerName, boolean multiDb, ValueStoragePluginProvider valueStorageProvider,
-      int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
-   {
-      super(dataSource, dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb, valueStorageProvider,
-         maxBufferSize, swapDirectory, swapCleaner);
-   }
-
-   /**
-    * GenericConnectionFactory constructor.
-    * 
-    * @param dataSource
-    *          - DataSource
-    * @param containerName
-    *          - Container name (see configuration)
-    * @param multiDb
-    *          - multidatabase state flag
-    * @param valueStorageProvider
-    *          - external Value Storages provider
-    * @param maxBufferSize
-    *          - Maximum buffer size (see configuration)
-    * @param swapDirectory
-    *          - Swap directory (see configuration)
-    * @param swapCleaner
-    *          - Swap cleaner (internal FileCleaner).
-    */
-   public GenericCQConnectionFactory(DataSource dataSource, String containerName, boolean multiDb,
-      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
-   {
-
-      this(dataSource, null, null, null, null, containerName, multiDb, valueStorageProvider, maxBufferSize,
-         swapDirectory, swapCleaner);
-   }
-
-   /**
-    * GenericConnectionFactory constructor.
-    * 
-    * @param dbDriver
-    *          - JDBC Driver
-    * @param dbUrl
-    *          - JDBC URL
-    * @param dbUserName
-    *          - database username
-    * @param dbPassword
-    *          - database user password
-    * @param containerName
-    *          - Container name (see configuration)
-    * @param multiDb
-    *          - multidatabase state flag
-    * @param valueStorageProvider
-    *          - external Value Storages provider
-    * @param maxBufferSize
-    *          - Maximum buffer size (see configuration)
-    * @param swapDirectory
-    *          - Swap directory (see configuration)
-    * @param swapCleaner
-    *          - Swap cleaner (internal FileCleaner).
-    */
-   public GenericCQConnectionFactory(String dbDriver, String dbUrl, String dbUserName, String dbPassword,
-      String containerName, boolean multiDb, ValueStoragePluginProvider valueStorageProvider, int maxBufferSize,
-      File swapDirectory, FileCleaner swapCleaner) throws RepositoryException
-   {
-
-      this(null, dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb, valueStorageProvider, maxBufferSize,
-         swapDirectory, swapCleaner);
-
-      try
-      {
-         Class.forName(dbDriver).newInstance();
-      }
-      catch (InstantiationException e)
-      {
-         throw new RepositoryException(e);
-      }
-      catch (IllegalAccessException e)
-      {
-         throw new RepositoryException(e);
-      }
-      catch (ClassNotFoundException e)
-      {
-         throw new RepositoryException(e);
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public WorkspaceStorageConnection openConnection() throws RepositoryException
-   {
-      return openConnection(false);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException
-   {
-      try
-      {
-
-         if (multiDb)
-         {
-            return new MultiDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
-               valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
-         }
-
-         return new SingleDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName, valueStorageProvider,
-            maxBufferSize, swapDirectory, swapCleaner);
-
-      }
-      catch (SQLException e)
-      {
-         throw new RepositoryException(e);
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public Connection getJdbcConnection(boolean readOnly) throws RepositoryException
-   {
-      try
-      {
-         final Connection conn =
-            dbDataSource != null ? dbDataSource.getConnection() : (dbUserName != null ? DriverManager.getConnection(
-               dbUrl, dbUserName, dbPassword) : DriverManager.getConnection(dbUrl));
-
-         if (readOnly) // set this feature only if it asked
-            conn.setReadOnly(readOnly);
-
-         return monitorInterest == 0 ? conn : new ManagedConnection(conn, monitorInterest);
-      }
-      catch (SQLException e)
-      {
-         String err =
-            "Error of JDBC connection open. SQLException: " + e.getMessage() + ", SQLState: " + e.getSQLState()
-               + ", VendorError: " + e.getErrorCode();
-         throw new RepositoryException(err, e);
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public Connection getJdbcConnection() throws RepositoryException
-   {
-      return getJdbcConnection(false);
-   }
-
-}

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -16,6 +16,7 @@
  */
 package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db;
 
+import org.exoplatform.services.jcr.impl.storage.jdbc.db.GenericConnectionFactory;
 import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
 import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
 import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
@@ -34,7 +35,7 @@
  * @author <a href="mailto:dezder at bk.ru">Denis Grebenyuk</a>
  * @version $Id:$
  */
-public class HSQLDBConnectionFactory extends GenericCQConnectionFactory
+public class HSQLDBConnectionFactory extends GenericConnectionFactory
 {
 
    /**

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -53,13 +53,13 @@
 
    protected PreparedStatement findItemById;
 
-   protected PreparedStatement findItemByIdCQ;
+   protected PreparedStatement findItemByIdNew;
 
    protected PreparedStatement findItemByPath;
 
    protected PreparedStatement findItemByName;
 
-   protected PreparedStatement findItemByNameCQ;
+   protected PreparedStatement findItemByNameNew;
 
    protected PreparedStatement findChildPropertyByPath;
 
@@ -83,14 +83,12 @@
    protected PreparedStatement findValueByPropertyIdOrderNumber;
 
    protected PreparedStatement findNodesByParentId;
-   
-   protected PreparedStatement findNodesByParentIdCQ;
 
    protected PreparedStatement findNodesCountByParentId;
 
    protected PreparedStatement findPropertiesByParentId;
 
-   protected PreparedStatement getPropertiesByParentIdCQ;
+   protected PreparedStatement getPropertiesByParentId;
 
    protected PreparedStatement insertNode;
 
@@ -178,22 +176,30 @@
 
       FIND_ITEM_BY_ID = "select * from JCR_MITEM where ID=?";
 
-      FIND_ITEM_BY_ID_CQ =
+      FIND_ITEM_BY_ID_NEW =
+      //         "select I.*, P.DATA from JCR_MITEM I, (select I2.PARENT_ID, V.DATA from JCR_MITEM I2, JCR_MVALUE V where I2.I_CLASS=2 and I2.PARENT_ID=?"
+         //            + " and I2.NAME='[http://www.jcp.org/jcr/1.0]primaryType' and I2.ID=V.PROPERTY_ID) P"
+         //            + " where I.ID=P.PARENT_ID";
+
+         //         "select I2.*, V.DATA from JCR_MITEM I LEFT OUTER JOIN JCR_MVALUE V ON (V.PROPERTY_ID=I.ID), (select * from JCR_MITEM where ID=? AND I_CLASS=1) I2"
+         //            + " where I2.ID=I.ID and I2.ID=I.PARENT_ID and I.NAME IN ('[http://www.jcp.org/jcr/1.0]primaryType')";// order by I.I_CLASS, I.N_ORDER_NUM"
+
          "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC from JCR_MITEM I LEFT OUTER JOIN JCR_MVALUE V ON (V.PROPERTY_ID=I.ID)"
-            + " where (I.ID=?) or (I.PARENT_ID=? and I.I_CLASS=2 and (I.NAME='[http://www.jcp.org/jcr/1.0]primaryType'"
-            + " or I.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes' or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner'"
-            + " or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')) order by I.I_CLASS, I.N_ORDER_NUM, V.ORDER_NUM";
+            + " where (I.ID=?) or (I.PARENT_ID=? and I.I_CLASS=2 and I.NAME IN ('[http://www.jcp.org/jcr/1.0]primaryType','[http://www.jcp.org/jcr/1.0]mixinTypes')) order by I.I_CLASS, I.NAME DESC";// order by I.I_CLASS, I.N_ORDER_NUM"
 
       FIND_ITEM_BY_NAME =
          "select * from JCR_MITEM" + " where PARENT_ID=? and NAME=? and I_INDEX=? order by I_CLASS, VERSION DESC";
 
-      FIND_ITEM_BY_NAME_CQ =
+      FIND_ITEM_BY_NAME_NEW =
          "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC from JCR_MITEM I LEFT OUTER JOIN JCR_MVALUE V ON (V.PROPERTY_ID=I.ID)"
             + ", (select ID from JCR_MITEM where PARENT_ID=? and NAME=? and I_INDEX=?) I2"
-            + " where (I.ID=I2.ID) or (I.PARENT_ID=I2.ID and I.I_CLASS=2 and (I.NAME='[http://www.jcp.org/jcr/1.0]primaryType'"
-            + " or I.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes' or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner'"
-            + " or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')) order by I.I_CLASS, I.N_ORDER_NUM, V.ORDER_NUM";
+            + " where (I.ID=I2.ID) or (I.PARENT_ID=I2.ID and I.I_CLASS=2 and I.NAME IN ('[http://www.jcp.org/jcr/1.0]primaryType','[http://www.jcp.org/jcr/1.0]mixinTypes'))"
+            + " order by I.I_CLASS, I.NAME DESC";
 
+      //         "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC from (select * from JCR_MITEM where PARENT_ID=? and NAME=?) I LEFT OUTER JOIN JCR_MVALUE V ON (V.PROPERTY_ID=I.ID)"
+      //         + ", (select ID from JCR_MITEM where I_CLASS=1 and PARENT_ID=? and NAME=?) I2"
+      //         + " where (I.ID=I2.ID) or (I.PARENT_ID=I2.ID and I.I_CLASS=2 and I.NAME IN ('[http://www.jcp.org/jcr/1.0]primaryType','[http://www.jcp.org/jcr/1.0]mixinTypes')) order by I.I_CLASS, I.NAME DESC";// order by I.I_CLASS, I.N_ORDER_NUM";
+
       FIND_PROPERTY_BY_NAME =
          "select V.DATA" + " from JCR_MITEM I, JCR_MVALUE V"
             + " where I.I_CLASS=2 and I.PARENT_ID=? and I.NAME=? and I.ID=V.PROPERTY_ID order by V.ORDER_NUM";
@@ -202,7 +208,6 @@
          "select P.ID, P.PARENT_ID, P.VERSION, P.P_TYPE, P.P_MULTIVALUED, P.NAME" + " from JCR_MREF R, JCR_MITEM P"
             + " where R.NODE_ID=? and P.ID=R.PROPERTY_ID and P.I_CLASS=2";
 
-      //TODO useless - remove
       FIND_REFERENCE_PROPERTIES =
          "select P.ID, P.PARENT_ID, P.VERSION, P.P_TYPE, P.P_MULTIVALUED, P.NAME, V.ORDER_NUM, V.DATA, V.STORAGE_DESC"
             + " from JCR_MREF R, JCR_MITEM P, JCR_MVALUE V"
@@ -217,19 +222,23 @@
 
       FIND_NODES_BY_PARENTID = "select * from JCR_MITEM" + " where I_CLASS=1 and PARENT_ID=?" + " order by N_ORDER_NUM";
 
-      FIND_NODES_BY_PARENTID_CQ =
-         "select I.*, V.DATA, V.ORDER_NUM"
-            + " from JCR_MITEM I LEFT OUTER JOIN JCR_MVALUE V ON (V.PROPERTY_ID=I.ID), (select ID from JCR_MITEM where PARENT_ID=? and I_CLASS=1) I2"
-            + " where (I.I_CLASS=1 AND I.ID=I2.ID) or (I.I_CLASS=2 and I.PARENT_ID=I2.ID and"
-            + " (I.NAME='[http://www.jcp.org/jcr/1.0]primaryType' or I.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes'"
-            + " or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner' or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')) order by I.I_CLASS, I.N_ORDER_NUM, V.ORDER_NUM";
+      FIND_NODES_BY_PARENTID_NEW =
+         "select I.*, V.DATA"
+            + " from JCR_MITEM I LEFT OUTER JOIN JCR_MVALUE V ON (V.PROPERTY_ID=I.ID), (select ID from JCR_MITEM where PARENT_ID=? AND I_CLASS=1) I2"
+            + " where (I.I_CLASS=1 AND I.ID=I2.ID) OR (I.I_CLASS=2 and I.PARENT_ID=I2.ID and"
+            + " (I.NAME='[http://www.jcp.org/jcr/1.0]primaryType' OR I.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes')) order by I.I_CLASS, I.N_ORDER_NUM";
+      //,'[http://www.exoplatform.com/jcr/exo/1.0]owner','[http://www.exoplatform.com/jcr/exo/1.0]permissions'
 
       FIND_NODES_COUNT_BY_PARENTID = "select count(ID) from JCR_MITEM" + " where I_CLASS=1 and PARENT_ID=?";
 
       FIND_PROPERTIES_BY_PARENTID = "select * from JCR_MITEM" + " where I_CLASS=2 and PARENT_ID=?" + " order by ID";
 
-      // property may contain no values
-      GET_PROPERTIES_BY_PARENTID_CQ =
+      //TODO this query is incorrect because property may have not value
+      //      GET_PROPERTIES_BY_PARENTID =
+      //         "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC from JCR_MITEM I, JCR_MVALUE V"
+      //            + " where I.I_CLASS=2 and I.PARENT_ID=? and V.PROPERTY_ID=I.ID order by I.ID";
+
+      GET_PROPERTIES_BY_PARENTID =
          "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC from JCR_MITEM I LEFT OUTER JOIN JCR_MVALUE V ON (V.PROPERTY_ID=I.ID)"
             + " where I.I_CLASS=2 and I.PARENT_ID=? order by ID, ORDER_NUM";
 
@@ -411,17 +420,17 @@
    /**
     * {@inheritDoc}
     */
-   protected ResultSet findItemByNameCQ(String parentId, String name, int index) throws SQLException
+   protected ResultSet findItemByNameNew(String parentId, String name, int index) throws SQLException
    {
-      if (findItemByNameCQ == null)
-         findItemByNameCQ = dbConnection.prepareStatement(FIND_ITEM_BY_NAME_CQ);
+      if (findItemByNameNew == null)
+         findItemByNameNew = dbConnection.prepareStatement(FIND_ITEM_BY_NAME_NEW);
       else
-         findItemByNameCQ.clearParameters();
+         findItemByNameNew.clearParameters();
 
-      findItemByNameCQ.setString(1, parentId);
-      findItemByNameCQ.setString(2, name);
-      findItemByNameCQ.setInt(3, index);
-      return findItemByNameCQ.executeQuery();
+      findItemByNameNew.setString(1, parentId);
+      findItemByNameNew.setString(2, name);
+      findItemByNameNew.setInt(3, index);
+      return findItemByNameNew.executeQuery();
    }
 
    /**
@@ -489,16 +498,16 @@
     * {@inheritDoc}
     */
    @Override
-   protected ResultSet findChildNodesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   protected ResultSet findChildNodesByParentIdentifierNew(String parentIdentifier) throws SQLException
    {
-      if (findNodesByParentIdCQ == null)
-         findNodesByParentIdCQ = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID_CQ);
+      if (findNodesByParentId == null)
+         findNodesByParentId = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID_NEW);
       else
-         findNodesByParentIdCQ.clearParameters();
+         findNodesByParentId.clearParameters();
 
-      findNodesByParentIdCQ.setString(1, parentIdentifier);
+      findNodesByParentId.setString(1, parentIdentifier);
       //findNodesByParentId.setString(2, parentIdentifier);
-      return findNodesByParentIdCQ.executeQuery();
+      return findNodesByParentId.executeQuery();
    }
 
    /**
@@ -643,27 +652,38 @@
    }
 
    @Override
-   protected ResultSet findItemByIdentifierCQ(String identifier) throws SQLException
+   protected ResultSet findItemByIdentifierNew(String identifier) throws SQLException
    {
-      if (findItemByIdCQ == null)
-         findItemByIdCQ = dbConnection.prepareStatement(FIND_ITEM_BY_ID_CQ);
+      if (findItemByIdNew == null)
+         findItemByIdNew = dbConnection.prepareStatement(FIND_ITEM_BY_ID_NEW);
       else
-         findItemByIdCQ.clearParameters();
-      findItemByIdCQ.setString(1, identifier);
-      findItemByIdCQ.setString(2, identifier);
-      return findItemByIdCQ.executeQuery();
+         findItemByIdNew.clearParameters();
+      findItemByIdNew.setString(1, identifier);
+      findItemByIdNew.setString(2, identifier);
+      return findItemByIdNew.executeQuery();
    }
 
    @Override
-   protected ResultSet getChildPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   protected ResultSet getChildPropertiesByParentIdentifier(String parentIdentifier) throws SQLException
    {
-      if (getPropertiesByParentIdCQ == null)
-         getPropertiesByParentIdCQ = dbConnection.prepareStatement(GET_PROPERTIES_BY_PARENTID_CQ);
+      if (getPropertiesByParentId == null)
+         getPropertiesByParentId = dbConnection.prepareStatement(GET_PROPERTIES_BY_PARENTID);
       else
-         getPropertiesByParentIdCQ.clearParameters();
+         getPropertiesByParentId.clearParameters();
 
-      getPropertiesByParentIdCQ.setString(1, parentIdentifier);
-      return getPropertiesByParentIdCQ.executeQuery();
+      getPropertiesByParentId.setString(1, parentIdentifier);
+      return getPropertiesByParentId.executeQuery();
    }
 
+   @Override
+   protected ResultSet findReferenceProperties(String nodeIdentifier) throws SQLException
+   {
+      if (findReferenceProperties == null)
+         findReferenceProperties = dbConnection.prepareStatement(FIND_REFERENCE_PROPERTIES);
+      else
+         findReferenceProperties.clearParameters();
+
+      findReferenceProperties.setString(1, nodeIdentifier);
+      return findReferenceProperties.executeQuery();
+   }
 }

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -18,6 +18,7 @@
  */
 package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db;
 
+import org.exoplatform.services.jcr.impl.storage.jdbc.db.GenericConnectionFactory;
 import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
 import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
 import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
@@ -36,7 +37,7 @@
  * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a>
  * @version $Id: MySQLConnectionFactory.java 34801 2009-07-31 15:44:50Z dkatayev $
  */
-public class MySQLConnectionFactory extends GenericCQConnectionFactory
+public class MySQLConnectionFactory extends GenericConnectionFactory
 {
 
    /**

Deleted: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db;
-
-import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.sql.Connection;
-import java.util.Properties;
-
-import javax.jcr.RepositoryException;
-
-/**
- * Created by The eXo Platform SAS
- * 
- * 23.03.2007
- * 
- * Access Oracle implicit connection caching and pooling stuff using reflection to prevent Maven
- * dependecies on ora drivers from POM.
- * 
- * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a>
- * @version $Id: OracleConnectionFactory.java 34801 2009-07-31 15:44:50Z dkatayev $
- */
-public class OracleConnectionFactory extends GenericCQConnectionFactory
-{
-
-   public static int CONNCACHE_MAX_LIMIT = 25;
-
-   public static int CONNCACHE_MIN_LIMIT = 2;
-
-   public static int CONNCACHE_INACTIVITY_TIMEOUT = 3600;
-
-   public static int CONNCACHE_ABADONDED_TIMEOUT = 1800;
-
-   protected final Object ociDataSource;
-
-   /**
-    * OracleConnectionFactory constructor. For CLI interface ONLY!
-    * 
-    * @param dbDriver
-    *          - JDBC Driver
-    * @param dbUrl
-    *          - JDBC URL
-    * @param dbUserName
-    *          - database username
-    * @param dbPassword
-    *          - database user password
-    * @param containerName
-    *          - Container name (see configuration)
-    * @param multiDb
-    *          - multidatabase state flag
-    * @param valueStorageProvider
-    *          - external Value Storages provider
-    * @param maxBufferSize
-    *          - Maximum buffer size (see configuration)
-    * @param swapDirectory
-    *          - Swap directory (see configuration)
-    * @param swapCleaner
-    *          - Swap cleaner (internal FileCleaner).
-    * @throws RepositoryException
-    *           if error occurs
-    */
-   public OracleConnectionFactory(String dbDriver, String dbUrl, String dbUserName, String dbPassword,
-      String containerName, boolean multiDb, ValueStoragePluginProvider valueStorageProvider, int maxBufferSize,
-      File swapDirectory, FileCleaner swapCleaner) throws RepositoryException
-   {
-
-      // ;D:\Devel\oracle_instantclient_10_2\;C:\oracle\ora92\bin;
-
-      /*
-       * ERROR: if no oci in path and oci url requested Error:
-       * java.lang.reflect.InvocationTargetException java.lang.reflect.InvocationTargetException at
-       * sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at
-       * sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
-       * at
-       * sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl
-       * .java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at
-       * ocipool.ConnPoolAppl.main(ConnPoolAppl.java:58) Caused by: java.lang.UnsatisfiedLinkError: no
-       * ocijdbc10 in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
-       * --------------------------------------------------------------------------- ERROR: if thin
-       * url used and trying obtain oci data source java.lang.reflect.InvocationTargetException at
-       * sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at
-       * sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
-       * at
-       * sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl
-       * .java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at
-       * ocipool.ConnPoolAppl.main(ConnPoolAppl.java:58) Caused by: java.lang.ClassCastException:
-       * oracle.jdbc.driver.T4CConnection at
-       * oracle.jdbc.pool.OracleOCIConnectionPool.createConnectionPool
-       * (OracleOCIConnectionPool.java:893)
-       */
-
-      super(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb, valueStorageProvider, maxBufferSize,
-         swapDirectory, swapCleaner);
-
-      Object cds = null;
-      try
-      {
-         Class cdsClass = OracleConnectionFactory.class.getClassLoader().loadClass("oracle.jdbc.pool.OracleDataSource");
-         Constructor cdsConstructor = cdsClass.getConstructor(new Class[]{});
-         cds = cdsConstructor.newInstance(new Object[]{});
-
-         // set cache properties
-         Properties prop = new java.util.Properties();
-         prop.setProperty("InitialLimit", String.valueOf(CONNCACHE_MIN_LIMIT));
-         prop.setProperty("MinLimit", String.valueOf(CONNCACHE_MIN_LIMIT));
-         prop.setProperty("MaxLimit", String.valueOf(CONNCACHE_MAX_LIMIT));
-         prop.setProperty("InactivityTimeout", String.valueOf(CONNCACHE_INACTIVITY_TIMEOUT));
-         prop.setProperty("AbandonedConnectionTimeout", String.valueOf(CONNCACHE_ABADONDED_TIMEOUT));
-
-         Method setURL = cds.getClass().getMethod("setURL", new Class[]{String.class});
-         setURL.invoke(cds, new Object[]{this.dbUrl});
-
-         Method setUser = cds.getClass().getMethod("setUser", new Class[]{String.class});
-         setUser.invoke(cds, new Object[]{this.dbUserName});
-
-         Method setPassword = cds.getClass().getMethod("setPassword", new Class[]{String.class});
-         setPassword.invoke(cds, new Object[]{this.dbPassword});
-
-         Method setConnectionCachingEnabled =
-            cds.getClass().getMethod("setConnectionCachingEnabled", new Class[]{boolean.class});
-         setConnectionCachingEnabled.invoke(cds, new Object[]{true});
-
-         Method setConnectionCacheProperties =
-            cds.getClass().getMethod("setConnectionCacheProperties", new Class[]{Properties.class});
-         setConnectionCacheProperties.invoke(cds, new Object[]{prop});
-
-         Method setConnectionCacheName = cds.getClass().getMethod("setConnectionCacheName", new Class[]{String.class});
-         setConnectionCacheName.invoke(cds, new Object[]{"EXOJCR_OCI__" + containerName});
-
-      }
-      catch (Throwable e)
-      {
-         cds = null;
-         String err = "Oracle OCI connection cache is unavailable due to error " + e;
-         if (e.getCause() != null)
-         {
-            err += " (" + e.getCause() + ")";
-         }
-         err += ". Standard JDBC DriverManager will be used for connections opening.";
-         if (log.isDebugEnabled())
-            log.warn(err, e);
-         else
-            log.warn(err);
-      }
-      this.ociDataSource = cds; // actually instance of javax.sql.DataSource
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public Connection getJdbcConnection(boolean readOnly) throws RepositoryException
-   {
-      if (ociDataSource != null)
-         try
-         {
-            Connection conn = getCachedConnection();
-
-            if (readOnly) // set this feature only if it asked
-               conn.setReadOnly(true);
-
-            return conn;
-         }
-         catch (Throwable e)
-         {
-            throw new RepositoryException("Oracle OCI cached connection open error " + e, e);
-         }
-
-      return super.getJdbcConnection(readOnly);
-   }
-
-   /**
-    * Get CachedConnection.
-    *
-    * @return
-    * @throws NoSuchMethodException
-    * @throws IllegalArgumentException
-    * @throws IllegalAccessException
-    * @throws InvocationTargetException
-    */
-   protected Connection getCachedConnection() throws NoSuchMethodException, IllegalArgumentException,
-      IllegalAccessException, InvocationTargetException
-   {
-
-      // NOTE: ociDataSource - actually instance of javax.sql.DataSource
-      Method getConnection = ociDataSource.getClass().getMethod("getConnection", new Class[]{});
-      Connection conn = (Connection)getConnection.invoke(ociDataSource, new Object[]{});
-
-      return conn;
-   }
-
-}

Deleted: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db;
-
-import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.sql.Connection;
-import java.util.Properties;
-
-import javax.jcr.RepositoryException;
-
-/**
- * Created by The eXo Platform SAS
- * 
- * 16.03.2007
- * 
- * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a>
- * @version $Id: OraclePoolConnectionFactory.java 34801 2009-07-31 15:44:50Z dkatayev $
- */
-public class OraclePoolConnectionFactory extends GenericCQConnectionFactory
-{
-
-   public static int CONNPOOL_MAX_LIMIT = 20;
-
-   public static int CONNPOOL_MIN_LIMIT = 2;
-
-   public static int CONNPOOL_INCREMENT = 1;
-
-   protected final Object ociPool;
-
-   /**
-    * OraclePoolConnectionFactory constructor. For CLI interface ONLY!
-    * 
-    * @param dbDriver
-    *          - JDBC Driver
-    * @param dbUrl
-    *          - JDBC URL
-    * @param dbUserName
-    *          - database username
-    * @param dbPassword
-    *          - database user password
-    * @param containerName
-    *          - Container name (see configuration)
-    * @param multiDb
-    *          - multidatabase state flag
-    * @param valueStorageProvider
-    *          - external Value Storages provider
-    * @param maxBufferSize
-    *          - Maximum buffer size (see configuration)
-    * @param swapDirectory
-    *          - Swap directory (see configuration)
-    * @param swapCleaner
-    *          - Swap cleaner (internal FileCleaner).
-    * @throws RepositoryException
-    *           if error occurs
-    */
-   public OraclePoolConnectionFactory(String dbDriver, String dbUrl, String dbUserName, String dbPassword,
-      String containerName, boolean multiDb, ValueStoragePluginProvider valueStorageProvider, int maxBufferSize,
-      File swapDirectory, FileCleaner swapCleaner) throws RepositoryException
-   {
-
-      // ;D:\Devel\oracle_instantclient_10_2\;C:\oracle\ora92\bin;
-
-      /*
-       * ERROR: if no oci in path and oci url requested Error:
-       * java.lang.reflect.InvocationTargetException java.lang.reflect.InvocationTargetException at
-       * sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at
-       * sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
-       * at
-       * sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl
-       * .java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at
-       * ocipool.ConnPoolAppl.main(ConnPoolAppl.java:58) Caused by: java.lang.UnsatisfiedLinkError: no
-       * ocijdbc10 in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
-       * --------------------------------------------------------------------------- ERROR: if thin
-       * url used and trying obtain oci data source java.lang.reflect.InvocationTargetException at
-       * sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at
-       * sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
-       * at
-       * sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl
-       * .java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at
-       * ocipool.ConnPoolAppl.main(ConnPoolAppl.java:58) Caused by: java.lang.ClassCastException:
-       * oracle.jdbc.driver.T4CConnection at
-       * oracle.jdbc.pool.OracleOCIConnectionPool.createConnectionPool
-       * (OracleOCIConnectionPool.java:893)
-       */
-
-      super(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb, valueStorageProvider, maxBufferSize,
-         swapDirectory, swapCleaner);
-
-      Object cpool = null;
-      try
-      {
-         Class cpoolClass =
-            OraclePoolConnectionFactory.class.getClassLoader().loadClass("oracle.jdbc.pool.OracleOCIConnectionPool");
-         Constructor cpoolConstructor =
-            cpoolClass.getConstructor(new Class[]{String.class, String.class, String.class, Properties.class});
-
-         cpool = cpoolConstructor.newInstance(new Object[]{this.dbUserName, this.dbPassword, this.dbUrl, null});
-         Method setConnectionCachingEnabled =
-            cpool.getClass().getMethod("setConnectionCachingEnabled", new Class[]{boolean.class});
-         setConnectionCachingEnabled.invoke(cpool, new Object[]{true});
-      }
-      catch (Throwable e)
-      {
-         cpool = null;
-         String err = "Oracle OCI connection pool is unavailable due to error " + e;
-         if (e.getCause() != null)
-         {
-            err += " (" + e.getCause() + ")";
-         }
-         err += ". Standard JDBC DriverManager will be used for connections opening.";
-         if (log.isDebugEnabled())
-            log.warn(err, e);
-         else
-            log.warn(err);
-      }
-      this.ociPool = cpool;
-
-      // configure using CONNPOOL_MAX_LIMIT, CONNPOOL_MIN_LIMIT, CONNPOOL_INCREMENT
-      try
-      {
-         reconfigure();
-         displayPoolConfig();
-      }
-      catch (Throwable e)
-      {
-         if (log.isDebugEnabled())
-            log.warn("Oracle OCI connection pool configuration error " + e, e);
-         else
-            log.warn("Oracle OCI connection pool configuration error " + e);
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public Connection getJdbcConnection(boolean readOnly) throws RepositoryException
-   {
-      if (ociPool != null)
-         try
-         {
-            Connection conn = getPoolConnection();
-
-            if (readOnly) // set this feature only if it asked
-               conn.setReadOnly(true);
-
-            return conn;
-         }
-         catch (Throwable e)
-         {
-            throw new RepositoryException("Oracle OCI pool connection open error " + e, e);
-         }
-
-      return super.getJdbcConnection(readOnly);
-   }
-
-   /**
-    * getPoolConnection.
-    *
-    * @return
-    * @throws NoSuchMethodException
-    * @throws IllegalArgumentException
-    * @throws IllegalAccessException
-    * @throws InvocationTargetException
-    */
-   protected Connection getPoolConnection() throws NoSuchMethodException, IllegalArgumentException,
-      IllegalAccessException, InvocationTargetException
-   {
-      Method getConnection = ociPool.getClass().getMethod("getConnection", new Class[]{});
-      return (Connection)getConnection.invoke(ociPool, new Object[]{});
-   }
-
-   protected void reconfigure() throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException,
-      InvocationTargetException, NoSuchFieldException
-   {
-      if (ociPool != null)
-      {
-         // Set up the initial pool configuration
-         Properties p1 = new Properties();
-         String minLimitName = (String)ociPool.getClass().getField("CONNPOOL_MIN_LIMIT").get(null);
-         String maxLimitName = (String)ociPool.getClass().getField("CONNPOOL_MAX_LIMIT").get(null);
-         String incrName = (String)ociPool.getClass().getField("CONNPOOL_INCREMENT").get(null);
-
-         p1.put(minLimitName, Integer.toString(CONNPOOL_MIN_LIMIT));
-         p1.put(maxLimitName, Integer.toString(CONNPOOL_MAX_LIMIT));
-         p1.put(incrName, Integer.toString(CONNPOOL_INCREMENT));
-
-         // Enable the initial configuration
-         ociPool.getClass().getMethod("setPoolConfig", new Class[]{Properties.class}).invoke(ociPool, new Object[]{p1});
-      }
-   }
-
-   /**
-    * Display the current status of the OracleOCIConnectionPool.
-    */
-   protected void displayPoolConfig() throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException,
-      InvocationTargetException
-   {
-      if (ociPool != null)
-      {
-
-         log.info(" =========== Oracle OCI connection pool config =========== ");
-
-         log.info(" Min poolsize Limit:\t"
-            + ociPool.getClass().getMethod("getMinLimit", new Class[]{}).invoke(ociPool, new Object[]{}));
-
-         log.info(" Max poolsize Limit:\t"
-            + ociPool.getClass().getMethod("getMaxLimit", new Class[]{}).invoke(ociPool, new Object[]{}));
-
-         log.info(" PoolSize:\t\t\t"
-            + ociPool.getClass().getMethod("getPoolSize", new Class[]{}).invoke(ociPool, new Object[]{}));
-
-         log.info(" ActiveSize:\t\t"
-            + ociPool.getClass().getMethod("getActiveSize", new Class[]{}).invoke(ociPool, new Object[]{}));
-      }
-   }
-
-}

Modified: jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java	2009-12-29 16:45:43 UTC (rev 1246)
+++ jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java	2009-12-29 16:50:31 UTC (rev 1247)
@@ -51,14 +51,12 @@
 
    protected PreparedStatement findItemById;
 
-   protected PreparedStatement findItemByIdCQ;
+   protected PreparedStatement findItemByIdNew;
 
    protected PreparedStatement findItemByPath;
 
    protected PreparedStatement findItemByName;
 
-   protected PreparedStatement findItemByNameCQ;
-
    protected PreparedStatement findChildPropertyByPath;
 
    protected PreparedStatement findPropertyByName;
@@ -79,14 +77,10 @@
 
    protected PreparedStatement findNodesByParentId;
 
-   protected PreparedStatement findNodesByParentIdCQ;
-
    protected PreparedStatement findNodesCountByParentId;
 
    protected PreparedStatement findPropertiesByParentId;
 
-   protected PreparedStatement getPropertiesByParentIdCQ;
-
    protected PreparedStatement insertItem;
 
    protected PreparedStatement insertNode;
@@ -183,26 +177,17 @@
       FIND_ITEM_BY_NAME =
          "select * from JCR_SITEM"
             + " where CONTAINER_NAME=? and PARENT_ID=? and NAME=? and I_INDEX=? order by I_CLASS, VERSION DESC";
-      
-      FIND_ITEM_BY_NAME_CQ =
-         "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC from JCR_SITEM I LEFT OUTER JOIN JCR_SVALUE V ON (V.PROPERTY_ID=I.ID)"
-            + ", (select ID from JCR_SITEM where CONTAINER_NAME=? and PARENT_ID=? and NAME=? and I_INDEX=?) I2"
-            + " where (I.ID=I2.ID) or (I.PARENT_ID=I2.ID and I.I_CLASS=2 and (I.NAME='[http://www.jcp.org/jcr/1.0]primaryType'"
-            + " or I.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes' or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner'"
-            + " or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')) order by I.I_CLASS, I.N_ORDER_NUM, V.ORDER_NUM";
 
-      FIND_ITEM_BY_ID_CQ =
-         "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC from JCR_SITEM I LEFT OUTER JOIN JCR_SVALUE V ON (V.PROPERTY_ID=I.ID)"
-            + " where (I.ID=?) or (I.PARENT_ID=? and I.I_CLASS=2 and (I.NAME='[http://www.jcp.org/jcr/1.0]primaryType'"
-            + " or I.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes' or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner'"
-            + " or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')) order by I.I_CLASS, I.N_ORDER_NUM, V.ORDER_NUM";
+      FIND_ITEM_BY_ID_NEW =
+         "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC"
+            + " from JCR_SITEM I LEFT OUTER JOIN JCR_SVALUE V ON (V.PROPERTY_ID=I.ID)"
+            + " where I.ID=? OR (I.I_CLASS=2 and I.CONTAINER_NAME=? and I.PARENT_ID=? and I.NAME IN ('[http://www.jcp.org/jcr/1.0]primaryType')) order by V.ORDER_NUM";
 
       FIND_PROPERTY_BY_NAME =
          "select V.DATA"
             + " from JCR_SITEM I, JCR_SVALUE V"
             + " where I.I_CLASS=2 and I.CONTAINER_NAME=? and I.PARENT_ID=? and I.NAME=? and I.ID=V.PROPERTY_ID order by V.ORDER_NUM";
 
-
       FIND_REFERENCES =
          "select P.ID, P.PARENT_ID, P.VERSION, P.P_TYPE, P.P_MULTIVALUED, P.NAME" + " from JCR_SREF R, JCR_SITEM P"
             + " where R.NODE_ID=? and P.CONTAINER_NAME=? and P.ID=R.PROPERTY_ID and P.I_CLASS=2";
@@ -217,23 +202,12 @@
       FIND_NODES_BY_PARENTID =
          "select * from JCR_SITEM" + " where I_CLASS=1 and CONTAINER_NAME=? and PARENT_ID=?" + " order by N_ORDER_NUM";
 
-      FIND_NODES_BY_PARENTID_CQ =
-         "select I.*, V.DATA, V.ORDER_NUM"
-            + " from JCR_SITEM I LEFT OUTER JOIN JCR_SVALUE V ON (V.PROPERTY_ID=I.ID), (select ID from JCR_SITEM where I_CLASS=1 and CONTAINER_NAME=? and PARENT_ID=?) I2"
-            + " where (I.I_CLASS=1 AND I.ID=I2.ID) or (I.I_CLASS=2 and I.PARENT_ID=I2.ID and"
-            + " (I.NAME='[http://www.jcp.org/jcr/1.0]primaryType' or I.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes'"
-            + " or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner' or I.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions')) order by I.I_CLASS, I.N_ORDER_NUM, V.ORDER_NUM";
-
       FIND_NODES_COUNT_BY_PARENTID =
          "select count(ID) from JCR_SITEM" + " where I_CLASS=1 and CONTAINER_NAME=? and PARENT_ID=?";
 
       FIND_PROPERTIES_BY_PARENTID =
          "select * from JCR_SITEM" + " where I_CLASS=2 and CONTAINER_NAME=? and PARENT_ID=?" + " order by ID";
 
-      GET_PROPERTIES_BY_PARENTID_CQ =
-         "select I.*, V.ORDER_NUM, V.DATA, V.STORAGE_DESC from JCR_SITEM I LEFT OUTER JOIN JCR_SVALUE V ON (V.PROPERTY_ID=I.ID)"
-            + " where I.I_CLASS=2 and CONTAINER_NAME=? and I.PARENT_ID=? order by ID, ORDER_NUM";
-
       INSERT_NODE =
          "insert into JCR_SITEM(ID, PARENT_ID, NAME, CONTAINER_NAME, VERSION, I_CLASS, I_INDEX, N_ORDER_NUM) VALUES(?,?,?,?,?,"
             + I_CLASS_NODE + ",?,?)";
@@ -423,7 +397,21 @@
       return findItemByName.executeQuery();
    }
 
+   @Override
+   protected ResultSet findItemByNameNew(String parentId, String name, int index) throws SQLException
+   {
+      if (findItemByName == null)
+         findItemByName = dbConnection.prepareStatement(FIND_ITEM_BY_NAME);
+      else
+         findItemByName.clearParameters();
 
+      findItemByName.setString(1, containerName);
+      findItemByName.setString(2, parentId);
+      findItemByName.setString(3, name);
+      findItemByName.setInt(4, index);
+      return findItemByName.executeQuery();
+   }
+
    /**
     * {@inheritDoc}
     */
@@ -620,61 +608,37 @@
    }
 
    @Override
-   protected ResultSet findItemByNameCQ(String parentId, String name, int index) throws SQLException
+   protected ResultSet findItemByIdentifierNew(String identifier) throws SQLException
    {
-      if (findItemByNameCQ == null)
-         findItemByNameCQ = dbConnection.prepareStatement(FIND_ITEM_BY_NAME_CQ);
+      if (findItemByIdNew == null)
+         findItemByIdNew = dbConnection.prepareStatement(FIND_ITEM_BY_ID_NEW);
       else
-         findItemByNameCQ.clearParameters();
-
-      findItemByNameCQ.setString(1, containerName);
-      findItemByNameCQ.setString(2, parentId);
-      findItemByNameCQ.setString(3, name);
-      findItemByNameCQ.setInt(4, index);
-      return findItemByNameCQ.executeQuery();
+         findItemByIdNew.clearParameters();
+      findItemByIdNew.setString(1, identifier);
+      findItemByIdNew.setString(2, containerName);
+      findItemByIdNew.setString(3, identifier);
+      return findItemByIdNew.executeQuery();
    }
 
-   
    @Override
-   protected ResultSet findItemByIdentifierCQ(String identifier) throws SQLException
+   protected ResultSet findChildNodesByParentIdentifierNew(String parentIdentifier) throws SQLException
    {
-      
-      if (findItemByIdCQ == null)
-         findItemByIdCQ = dbConnection.prepareStatement(FIND_ITEM_BY_ID_CQ);
-      else
-         findItemByIdCQ.clearParameters();
-      findItemByIdCQ.setString(1, identifier);
-      findItemByIdCQ.setString(2, identifier);
-      return findItemByIdCQ.executeQuery();
+      // TODO Auto-generated method stub
+      return null;
    }
 
    @Override
-   protected ResultSet findChildNodesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   protected ResultSet getChildPropertiesByParentIdentifier(String parentIdentifier) throws SQLException
    {
-      
-      
-      if (findNodesByParentIdCQ == null)
-         findNodesByParentIdCQ = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID_CQ);
-      else
-         findNodesByParentIdCQ.clearParameters();
-
-      findNodesByParentIdCQ.setString(1, containerName);
-      findNodesByParentIdCQ.setString(2, parentIdentifier);
-      return findNodesByParentIdCQ.executeQuery();
+      // TODO Auto-generated method stub
+      return null;
    }
 
    @Override
-   protected ResultSet getChildPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   protected ResultSet findReferenceProperties(String parentIdentifier) throws SQLException
    {
-      if (getPropertiesByParentIdCQ == null)
-         getPropertiesByParentIdCQ = dbConnection.prepareStatement(GET_PROPERTIES_BY_PARENTID_CQ);
-      else
-         getPropertiesByParentIdCQ.clearParameters();
-
-      getPropertiesByParentIdCQ.setString(1, containerName);
-      getPropertiesByParentIdCQ.setString(2, parentIdentifier);
-      return getPropertiesByParentIdCQ.executeQuery();
-
+      // TODO Auto-generated method stub
+      return null;
    }
 
 }



More information about the exo-jcr-commits mailing list