[exo-jcr-commits] exo-jcr SVN: r1347 - in jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core: src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc and 6 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Mon Jan 11 11:18:43 EST 2010


Author: tolusha
Date: 2010-01-11 11:18:42 -0500 (Mon, 11 Jan 2010)
New Revision: 1347

Added:
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLMultiDbJDBCConnection.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLSingleDbJDBCConnection.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLBenchmarkTest.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/SQLBenchmark/
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/SQLBenchmark/exodb_data.sql.zip
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-configuration.xml
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-jcr-config.xml
Modified:
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/pom.xml
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/PrimaryTypeNotFoundException.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/test-jbosscache-config.xml
Log:
EXOJCR-379: Merge complex queries (CQ) optimization

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/pom.xml	2010-01-11 15:57:12 UTC (rev 1346)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/pom.xml	2010-01-11 16:18:42 UTC (rev 1347)
@@ -369,7 +369,8 @@
                   <exclude>org/exoplatform/services/jcr/**/api/**/TestVersionRestore.java</exclude>
                   
                   <exclude>org/exoplatform/services/jcr/**/impl/**/TestSessionDataManager.java</exclude>
-                  
+		  <exclude>org/exoplatform/services/jcr/**/impl/**/SQLBenchmarkTest.java</exclude>                  
+		  
                   <exclude>org/exoplatform/services/jcr/**/usecases/**/ExportWorkspaceSystemViewTest.java</exclude>
                </excludes>
             </configuration>

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java	2010-01-11 15:57:12 UTC (rev 1346)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -600,16 +600,17 @@
          throw new RepositoryException(e);
       }
    }
-   
+
    /**
     * {@inheritDoc}
     */
-   public int getChildNodesCount(NodeData parent) throws RepositoryException {
+   public int getChildNodesCount(NodeData parent) throws RepositoryException
+   {
       checkIfOpened();
       try
       {
          ResultSet count = findChildNodesCountByParentIdentifier(getInternalId(parent.getIdentifier()));
-         if (count.next()) 
+         if (count.next())
          {
             return count.getInt(1);
          }
@@ -622,7 +623,7 @@
       {
          throw new RepositoryException(e);
       }
-   }   
+   }
 
    /**
     * {@inheritDoc}
@@ -830,7 +831,7 @@
     * @throws IllegalNameException
     *           - if name on the path is wrong
     */
-   private QPath traverseQPath(String cpid) throws SQLException, InvalidItemStateException, IllegalNameException
+   protected QPath traverseQPath(String cpid) throws SQLException, InvalidItemStateException, IllegalNameException
    {
       // get item by Identifier usecase
       List<QPathEntry> qrpath = new ArrayList<QPathEntry>(); // reverted path
@@ -1218,7 +1219,7 @@
     * Mixin types description (internal use).
     * 
     */
-   class MixinInfo
+   public class MixinInfo
    {
 
       /**
@@ -1266,7 +1267,7 @@
        * @param privilegeable
        *          exo:privilegeable flag
        */
-      MixinInfo(List<InternalQName> mixinTypes, boolean owneable, boolean privilegeable)
+      public MixinInfo(List<InternalQName> mixinTypes, boolean owneable, boolean privilegeable)
       {
          this.mixinTypes = mixinTypes;
          this.owneable = owneable;
@@ -1278,7 +1279,7 @@
        * 
        * @return InternalQName[] Mixin names array
        */
-      InternalQName[] mixinNames()
+      public InternalQName[] mixinNames()
       {
          if (mixinTypes != null)
          {
@@ -1295,7 +1296,7 @@
        * 
        * @return boolean
        */
-      boolean hasPrivilegeable()
+      public boolean hasPrivilegeable()
       {
          return privilegeable;
       }
@@ -1305,10 +1306,15 @@
        * 
        * @return boolean
        */
-      boolean hasOwneable()
+      public boolean hasOwneable()
       {
          return owneable;
       }
+
+      public String getParentId()
+      {
+         return parentId;
+      }
    }
 
    /**
@@ -1702,7 +1708,7 @@
             final String storageId = valueRecords.getString(COLUMN_VSTORAGE_DESC);
             ValueData vdata =
                valueRecords.wasNull() ? readValueData(cid, orderNum, pdata.getPersistedVersion(), valueRecords
-                  .getBinaryStream(COLUMN_VDATA)) : readValueData(pdata, orderNum, storageId);
+                  .getBinaryStream(COLUMN_VDATA)) : readValueData(pdata.getIdentifier(), orderNum, storageId);
             data.add(vdata);
          }
       }
@@ -1731,13 +1737,13 @@
     * @throws ValueStorageNotFoundException
     *           if no such storage found with Value storageId
     */
-   protected ValueData readValueData(PropertyData pdata, int orderNumber, String storageId) throws SQLException,
+   protected ValueData readValueData(String identifier, int orderNumber, String storageId) throws SQLException,
       IOException, ValueStorageNotFoundException
    {
       ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
       try
       {
-         return channel.read(pdata.getIdentifier(), orderNumber, maxBufferSize);
+         return channel.read(identifier, orderNumber, maxBufferSize);
       }
       finally
       {
@@ -1894,7 +1900,7 @@
    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;

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/PrimaryTypeNotFoundException.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/PrimaryTypeNotFoundException.java	2010-01-11 15:57:12 UTC (rev 1346)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/PrimaryTypeNotFoundException.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -46,7 +46,7 @@
     * @param path
     *          - context path
     */
-   PrimaryTypeNotFoundException(String message, QPath path)
+   public PrimaryTypeNotFoundException(String message, QPath path)
    {
       super(message);
       this.path = path;

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,739 @@
+/*
+ * 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.access.AccessControlEntry;
+import org.exoplatform.services.jcr.access.AccessControlList;
+import org.exoplatform.services.jcr.dataflow.persistent.PersistedNodeData;
+import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
+import org.exoplatform.services.jcr.datamodel.IllegalACLException;
+import org.exoplatform.services.jcr.datamodel.IllegalNameException;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPath;
+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.storage.jdbc.JDBCStorageConnection;
+import org.exoplatform.services.jcr.impl.storage.jdbc.PrimaryTypeNotFoundException;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+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.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * @author <a href="mailto:gennady.azarenkov at exoplatform.com">Gennady Azarenkov</a>
+ * @version $Id$
+ */
+abstract public class CQJDBCStorageConnection extends JDBCStorageConnection
+{
+
+   /**
+    * Connection logger.
+    */
+   protected static final Log LOG = ExoLogger.getLogger("jcr.optimisation.CQJDBCStorageConnection");
+
+   /**
+    * FIND_NODES_BY_PARENTID NEW.
+    */
+   protected String FIND_NODES_BY_PARENTID_CQ;
+
+   /**
+    * FIND_PROPERTIES_BY_PARENTID NEW.
+    */
+   protected String FIND_PROPERTIES_BY_PARENTID_CQ;
+
+   /**
+    * FIND_NODE_MAIN_PROPERTIES_BY_PARENTID_CQ.
+    */
+   protected String FIND_NODE_MAIN_PROPERTIES_BY_PARENTID_CQ;
+
+   /**
+    * FIND_REFERENCE_PROPERTIES_CQ.
+    */
+   protected String FIND_REFERENCE_PROPERTIES_CQ;
+
+   /**
+    * FIND_ITEM_QPATH_BY_ID_CQ.
+    */
+   protected String FIND_ITEM_QPATH_BY_ID_CQ;
+
+   /**
+    * Class needed to store node details (property also) since result set is not sorted in valid way. 
+    */
+   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);
+      }
+   }
+
+   /**
+     * JDBCStorageConnection constructor.
+     * 
+     * @param dbConnection
+     *          JDBC connection
+     * @param containerName
+     *          Workspace container name
+     * @param valueStorageProvider
+     *          External Value Storage provider
+     * @param maxBufferSize
+     *          maximum buffer size (configuration)
+     * @param swapDirectory
+     *          swap directory (configuration)
+     * @param swapCleaner
+     *          swap cleaner (FileCleaner)
+     * @throws SQLException
+     *           database error
+     */
+   protected CQJDBCStorageConnection(Connection dbConnection, boolean readOnly, String containerName,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+      throws SQLException
+   {
+      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@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()));
+         TempNodeData data = null;
+         List<NodeData> childNodes = new ArrayList<NodeData>();
+         while (resultSet.next())
+         {
+            if (data == null)
+            {
+               data = new TempNodeData(resultSet);
+            }
+            else if (!resultSet.getString(COLUMN_ID).equals(data.cid))
+            {
+               NodeData nodeData = loadNodeFromTemporaryNodeData(data, parent.getQPath(), parent.getACL());
+               childNodes.add(nodeData);
+               data = new TempNodeData(resultSet);
+            }
+            Map<String, List<byte[]>> properties = data.properties;
+            String key = resultSet.getString("PROP_NAME");
+            List<byte[]> values = properties.get(key);
+            if (values == null)
+            {
+               values = new ArrayList<byte[]>();
+               properties.put(key, values);
+            }
+            values.add(resultSet.getBytes(COLUMN_VDATA));
+         }
+         if (data != null)
+         {
+            NodeData nodeData = loadNodeFromTemporaryNodeData(data, parent.getQPath(), parent.getACL());
+            childNodes.add(nodeData);
+         }
+         return childNodes;
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+      catch (IOException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public List<PropertyData> getChildPropertiesData(NodeData parent) throws RepositoryException, IllegalStateException
+   {
+      checkIfOpened();
+      try
+      {
+         ResultSet resultSet = findChildPropertiesByParentIdentifierCQ(getInternalId(parent.getIdentifier()));
+         List<PropertyData> children = new ArrayList<PropertyData>();
+         if (resultSet.next())
+         {
+            while (!resultSet.isAfterLast())
+               children.add(loadPropertyRecord(resultSet, parent.getQPath()));
+         }
+         return children;
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+      catch (IOException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public List<PropertyData> getReferencesData(String nodeIdentifier) throws RepositoryException, IllegalStateException
+   {
+      checkIfOpened();
+      try
+      {
+         ResultSet refProps = findReferencePropertiesCQ(getInternalId(nodeIdentifier));
+         return loadReferences(refProps);
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+      catch (IOException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+   /**
+    * Load Property references
+    * 
+    * @param resultSet
+    * @return
+    * @throws RepositoryException
+    * @throws SQLException
+    * @throws IOException
+    */
+   private List<PropertyData> loadReferences(ResultSet resultSet) throws RepositoryException, SQLException, IOException
+   {
+      List<PropertyData> resultProps = new ArrayList<PropertyData>();
+
+      // Property Id and amount of copies in result
+      Map<String, Integer> dublicatedProps = new HashMap<String, Integer>();
+      Map<String, PersistedPropertyData> propertyBuffer = new HashMap<String, PersistedPropertyData>();
+      Map<String, List<ValueData>> valuesBuffer = new HashMap<String, List<ValueData>>();
+
+      try
+      {
+         while (resultSet.next())
+         {
+            String cid = resultSet.getString(COLUMN_ID);
+            String identifier = getIdentifier(cid);
+
+            int cversion = resultSet.getInt(COLUMN_VERSION);
+
+            int valueOrderNum = resultSet.getInt(COLUMN_VORDERNUM);
+            PersistedPropertyData prop = propertyBuffer.get(identifier);
+
+            if (prop == null)
+            {
+               // make temporary PropertyData without values
+               String cname = resultSet.getString(COLUMN_NAME);
+
+               String cpid = resultSet.getString(COLUMN_PARENTID);
+               int cptype = resultSet.getInt(COLUMN_PTYPE);
+               boolean cpmultivalued = resultSet.getBoolean(COLUMN_PMULTIVALUED);
+               QPath qpath = QPath.makeChildPath(traverseQPath(cpid), InternalQName.parse(cname));
+
+               prop =
+                  new PersistedPropertyData(identifier, qpath, getIdentifier(cpid), cversion, cptype, cpmultivalued);
+               propertyBuffer.put(identifier, prop);
+               valuesBuffer.put(identifier, new ArrayList<ValueData>());
+               dublicatedProps.put(identifier, new Integer(1));
+            }
+
+            List<ValueData> values = valuesBuffer.get(identifier);
+            if (valueOrderNum == 0 && values.size() > 0)
+            {
+               // ignore it, this is a new copy
+               Integer copies = dublicatedProps.get(identifier);
+               copies++;
+               dublicatedProps.put(identifier, copies);
+            }
+            else if (values.size() <= valueOrderNum)
+            {
+               // read value and put into values buffer
+               final String storageId = resultSet.getString(COLUMN_VSTORAGE_DESC);
+               ValueData vdata =
+                  resultSet.wasNull() ? readValueData(cid, valueOrderNum, cversion, resultSet
+                     .getBinaryStream(COLUMN_VDATA)) : readValueData(identifier, valueOrderNum, storageId);
+
+               values.add(vdata);
+               valuesBuffer.put(identifier, values);
+            }
+         }
+
+         for (String id : propertyBuffer.keySet())
+         {
+
+            PersistedPropertyData prop = propertyBuffer.get(id);
+            List<ValueData> values = valuesBuffer.get(id);
+            int count = dublicatedProps.get(id).intValue();
+
+            for (int i = 0; i < count; i++)
+            {
+               //make a copy
+               List<ValueData> newValues = new ArrayList<ValueData>();
+               for (ValueData vd : values)
+               {
+                  newValues.add(new ByteArrayPersistedValueData(vd.getAsByteArray(), vd.getOrderNumber()));
+               }
+
+               PersistedPropertyData pdata =
+                  new PersistedPropertyData(prop.getIdentifier(), prop.getQPath(), prop.getParentIdentifier(), prop
+                     .getPersistedVersion(), prop.getType(), prop.isMultiValued());
+               pdata.setValues(newValues); // TODO remove after whole merge, EXOJCR-378
+
+               resultProps.add(pdata);
+            }
+            values.clear();
+         }
+      }
+      catch (IllegalNameException e)
+      {
+         throw new RepositoryException(e);
+      }
+      finally
+      {
+         // clean buffers
+         propertyBuffer.clear();
+         valuesBuffer.clear();
+         dublicatedProps.clear();
+      }
+
+      return resultProps;
+   }
+
+   /**
+    * Read ACL Permissions from properties set.
+    * 
+    * @param cid node id (used only for error messages)
+    * @param properties - Property name and property values
+    * @return list ACL
+    * @throws SQLException
+    * @throws IllegalACLException
+    */
+   protected List<AccessControlEntry> readACLPermisions(String cid, Map<String, List<byte[]>> properties)
+      throws SQLException, IllegalACLException
+   {
+      List<AccessControlEntry> naPermissions = new ArrayList<AccessControlEntry>();
+      List<byte[]> permValues = properties.get(Constants.EXO_PERMISSIONS.getAsString());
+
+      if (permValues != null)
+      {
+         for (byte[] value : permValues)
+         {
+            StringTokenizer parser = new StringTokenizer(new String(value), AccessControlEntry.DELIMITER);
+            naPermissions.add(new AccessControlEntry(parser.nextToken(), parser.nextToken()));
+         }
+
+         return naPermissions;
+      }
+      else
+         throw new IllegalACLException("Property exo:permissions is not found for node with id: " + getIdentifier(cid));
+   }
+
+   /**
+    * Read ACL owner.
+    * 
+    * @param cid - node id (used only in exception message)
+    * @param properties - Proeprty name and property values
+    * @return ACL owner
+    * @throws IllegalACLException
+    */
+   protected String readACLOwner(String cid, Map<String, List<byte[]>> properties) throws IllegalACLException
+   {
+      List<byte[]> ownerValues = properties.get(Constants.EXO_OWNER.getAsString());
+      if (ownerValues != null)
+         return new String(ownerValues.get(0));
+      else
+         throw new IllegalACLException("Property exo:owner is not found for node with id: " + getIdentifier(cid));
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected PersistedNodeData loadNodeRecord(QPath parentPath, String cname, String cid, String cpid, int cindex,
+      int cversion, int cnordernumb, AccessControlList parentACL) throws RepositoryException, SQLException
+   {
+      ResultSet ptProp = findNodeMainPropertiesByParentIdentifierCQ(cid);
+      Map<String, List<byte[]>> properties = new HashMap<String, List<byte[]>>();
+      while (ptProp.next())
+      {
+         String key = ptProp.getString(COLUMN_NAME);
+         List<byte[]> values = properties.get(key);
+         if (values == null)
+         {
+            values = new ArrayList<byte[]>();
+            properties.put(key, values);
+         }
+         values.add(ptProp.getBytes(COLUMN_VDATA));
+      }
+
+      return loadNodeRecord(parentPath, cname, cid, cpid, cindex, cversion, cnordernumb, properties, parentACL);
+   }
+
+   /**
+    * Create NodeData from TempNodeData content.
+    * 
+    * @param tempData
+    * @param parentPath
+    * @param parentACL
+    * @return
+    * @throws RepositoryException
+    * @throws SQLException
+    * @throws IOException
+    */
+   protected PersistedNodeData loadNodeFromTemporaryNodeData(TempNodeData tempData, QPath parentPath,
+      AccessControlList parentACL) throws RepositoryException, SQLException, IOException
+   {
+      return loadNodeRecord(parentPath, tempData.cname, tempData.cid, tempData.cpid, tempData.cindex,
+         tempData.cversion, tempData.cnordernumb, tempData.properties, parentACL);
+   }
+
+   /**
+    * Create a new node from the given parameter.
+    */
+   private PersistedNodeData loadNodeRecord(QPath parentPath, String cname, String cid, String cpid, int cindex,
+      int cversion, int cnordernumb, Map<String, List<byte[]>> properties, 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;
+            }
+         }
+
+         // PRIMARY
+         List<byte[]> primaryType = properties.get(Constants.JCR_PRIMARYTYPE.getAsString());
+         if (primaryType == null || primaryType.isEmpty())
+         {
+            throw new PrimaryTypeNotFoundException("FATAL ERROR primary type record not found. Node "
+               + qpath.getAsString() + ", id " + cid + ", container " + this.containerName, null);
+         }
+
+         byte[] data = primaryType.get(0);
+         InternalQName ptName = InternalQName.parse(new String((data != null ? data : new byte[]{})));
+
+         // MIXIN
+         InternalQName[] mts;
+         boolean owneable = false;
+         boolean privilegeable = false;
+         List<byte[]> mixTypes = properties.get(Constants.JCR_MIXINTYPES.getAsString());
+         if (mixTypes != null)
+         {
+            List<InternalQName> mNames = new ArrayList<InternalQName>();
+            for (byte[] mxnb : mixTypes)
+            {
+               InternalQName mxn = InternalQName.parse(new String(mxnb));
+               mNames.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
+         {
+            mts = new InternalQName[0];
+         }
+
+         try
+         {
+            // ACL
+            AccessControlList acl; // NO DEFAULT values!
+
+            if (owneable)
+            {
+               // has own owner
+               if (privilegeable)
+               {
+                  // and permissions
+                  acl = new AccessControlList(readACLOwner(cid, properties), readACLPermisions(cid, properties));
+               }
+               else if (parentACL != null)
+               {
+                  // use permissions from existed parent
+                  acl =
+                     new AccessControlList(readACLOwner(cid, properties), parentACL.hasPermissions() ? parentACL
+                        .getPermissionEntries() : null);
+               }
+               else
+               {
+                  // have to search nearest ancestor permissions in ACL manager
+                  acl = new AccessControlList(readACLOwner(cid, properties), null);
+               }
+            }
+            else if (privilegeable)
+            {
+               // has own permissions
+               if (owneable)
+               {
+                  // and owner
+                  acl = new AccessControlList(readACLOwner(cid, properties), readACLPermisions(cid, properties));
+               }
+               else if (parentACL != null)
+               {
+                  // use owner from existed parent
+                  acl = new AccessControlList(parentACL.getOwner(), readACLPermisions(cid, properties));
+               }
+               else
+               {
+                  // have to search nearest ancestor owner in ACL manager
+                  // acl = new AccessControlList(traverseACLOwner(cpid), readACLPermisions(cid));
+                  acl = new AccessControlList(null, readACLPermisions(cid, properties));
+               }
+            }
+            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, mts, 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 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)
+      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
+      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));
+
+         List<ValueData> data = new ArrayList<ValueData>();
+         String identifier = getIdentifier(cid);
+
+         do
+         {
+            int orderNum = resultSet.getInt(COLUMN_VORDERNUM);
+            //check is there value columns
+            if (!resultSet.wasNull())
+            {
+               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);
+            }
+         }
+         while (resultSet.next() && resultSet.getString(COLUMN_ID).equals(cid));
+
+         PersistedPropertyData pdata =
+            new PersistedPropertyData(identifier, qpath, getIdentifier(cpid), cversion, cptype, cpmultivalued);
+         pdata.setValues(data); // TODO remove after whole merge, EXOJCR-378
+
+         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: "
+            + getIdentifier(cid) + ". " + e);
+      }
+   }
+
+   /**
+    * {@inheritDoc} 
+    */
+   @Override
+   protected QPath traverseQPath(String cpid) throws SQLException, InvalidItemStateException, IllegalNameException
+   {
+      String id = getIdentifier(cpid);
+      if (id.equals(Constants.ROOT_UUID))
+      {
+         return Constants.ROOT_PATH;
+      }
+      // get item by Identifier usecase
+      List<QPathEntry> qrpath = new ArrayList<QPathEntry>(); // reverted path
+      String caid = cpid; // container ancestor id
+      boolean isRoot = false;
+      do
+      {
+         ResultSet result = null;
+         try
+         {
+            result = findItemQPathByIdentifierCQ(caid);
+            if (!result.next())
+               throw new InvalidItemStateException("Parent not found, uuid: " + getIdentifier(caid));
+
+            QPathEntry qpe1 =
+               new QPathEntry(InternalQName.parse(result.getString(COLUMN_NAME)), result.getInt(COLUMN_INDEX));
+            boolean isChild = caid.equals(result.getString(COLUMN_ID));
+            caid = result.getString(COLUMN_PARENTID);
+            if (result.next())
+            {
+               QPathEntry qpe2 =
+                  new QPathEntry(InternalQName.parse(result.getString(COLUMN_NAME)), result.getInt(COLUMN_INDEX));
+               if (isChild)
+               {
+                  // The child is the first result then we have the parent
+                  qrpath.add(qpe1);
+                  qrpath.add(qpe2);
+                  // We need to take the value of the parent node
+                  caid = result.getString(COLUMN_PARENTID);
+               }
+               else
+               {
+                  // The parent is the first result then we have the child
+                  qrpath.add(qpe2);
+                  qrpath.add(qpe1);
+               }
+            }
+            else
+            {
+               qrpath.add(qpe1);
+            }
+         }
+         finally
+         {
+            result.close();
+         }
+         if (caid.equals(Constants.ROOT_PARENT_UUID) || (id = getIdentifier(caid)).equals(Constants.ROOT_UUID))
+         {
+            if (id.equals(Constants.ROOT_UUID))
+            {
+               qrpath.add(Constants.ROOT_PATH.getEntries()[0]);
+            }
+            isRoot = true;
+         }
+      }
+      while (!isRoot);
+
+      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);
+   }
+
+   protected abstract ResultSet findItemQPathByIdentifierCQ(String identifier) throws SQLException;
+
+   protected abstract ResultSet findChildNodesByParentIdentifierCQ(String parentIdentifier) throws SQLException;
+
+   protected abstract ResultSet findChildPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException;
+
+   protected abstract ResultSet findNodeMainPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException;
+
+   protected abstract ResultSet findReferencePropertiesCQ(String nodeIdentifier) throws SQLException;
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,264 @@
+/*
+ * 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.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.RepositoryEntry;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+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.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.storage.value.ValueStoragePluginProvider;
+import org.exoplatform.services.naming.InitialContextInitializer;
+import org.picocontainer.Startable;
+
+import java.io.IOException;
+
+import javax.jcr.RepositoryException;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+/**
+ * Created by The eXo Platform SAS.
+ * 
+ * @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
+{
+
+   /**
+    * 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 CQJDBCWorkspaceDataContainer(WorkspaceEntry wsConfig, RepositoryEntry repConfig,
+      InitialContextInitializer contextInit, ValueStoragePluginProvider valueStorageProvider)
+      throws RepositoryConfigurationException, NamingException, RepositoryException, IOException
+   {
+      super(wsConfig, repConfig, contextInit, valueStorageProvider);
+   }
+
+   /**
+    * Init storage database.
+    * 
+    * @throws NamingException
+    *           on JNDI error
+    * @throws RepositoryException
+    *           on storage error
+    * @throws IOException
+    *           on I/O error
+    */
+   protected void initDatabase() throws NamingException, RepositoryException, IOException
+   {
+
+      DBInitializer dbInitilizer = null;
+      String sqlPath = null;
+      if (dbDialect == DBConstants.DB_DIALECT_ORACLEOCI)
+      {
+         LOG.warn(DBConstants.DB_DIALECT_ORACLEOCI + " dialect is experimental!");
+         // sample of connection factory customization
+         if (dbSourceName != null)
+            this.connFactory = defaultConnectionFactory();
+         else
+            this.connFactory =
+               new OracleConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
+                  valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ora.sql";
+
+         // a particular db initializer may be configured here too
+         dbInitilizer = new OracleDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
+      }
+      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)
+      {
+         this.connFactory = defaultConnectionFactory();
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.pgsql.sql";
+         dbInitilizer = new PgSQLDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_MYSQL)
+      {
+         // [PN] 28.06.07
+         if (dbSourceName != null)
+         {
+            DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+            if (ds != null)
+               this.connFactory =
+                  new MySQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
+                     swapDirectory, swapCleaner);
+            else
+               throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+         }
+         else
+            this.connFactory =
+               new MySQLConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
+                  valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_MYSQL_UTF8)
+      {
+         // [PN] 13.07.08
+         if (dbSourceName != null)
+         {
+            DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+            if (ds != null)
+               this.connFactory =
+                  new MySQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
+                     swapDirectory, swapCleaner);
+            else
+               throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+         }
+         else
+            this.connFactory =
+               new MySQLConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
+                  valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mysql-utf8.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_MSSQL)
+      {
+         this.connFactory = defaultConnectionFactory();
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mssql.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_DERBY)
+      {
+         this.connFactory = defaultConnectionFactory();
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.derby.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_DB2)
+      {
+         this.connFactory = defaultConnectionFactory();
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_DB2V8)
+      {
+         this.connFactory = defaultConnectionFactory();
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.db2v8.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
+      {
+         this.connFactory = defaultConnectionFactory();
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sybase.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_INGRES)
+      {
+         this.connFactory = defaultConnectionFactory();
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.ingres.sql";
+         // using Postgres initializer
+         dbInitilizer =
+            new IngresSQLDBInitializer(containerName, this.connFactory.getJdbcConnection(), sqlPath, multiDb);
+      }
+      else if (dbDialect == DBConstants.DB_DIALECT_HSQLDB)
+      {
+         if (dbSourceName != null)
+         {
+            DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+            if (ds != null)
+               this.connFactory =
+                  new HSQLDBConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
+                     swapDirectory, swapCleaner);
+            else
+               throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+         }
+         else
+            this.connFactory =
+               new HSQLDBConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
+                  valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+      else
+      {
+         // generic, DB_HSQLDB
+         this.connFactory = defaultConnectionFactory();
+         sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.sql";
+         dbInitilizer = defaultDBInitializer(sqlPath);
+      }
+
+      // database type
+      try
+      {
+         dbInitilizer.init();
+      }
+      catch (DBInitializerException e)
+      {
+         LOG.error("Error of init db " + e, e);
+      }
+   }
+
+   /**
+    * Prepare default 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 GenericCQConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
+               swapDirectory, swapCleaner);
+
+         throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+      }
+
+      return new GenericCQConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
+         valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,220 @@
+/*
+ * 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.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$
+ */
+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 : null;
+      }
+      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);
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/GenericCQConnectionFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2003-2007 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.db;
+
+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.SQLException;
+
+import javax.jcr.RepositoryException;
+import javax.sql.DataSource;
+
+/**
+ * Created by The eXo Platform SAS
+ * 
+ * 26.08.2009
+ * 
+ * @author <a href="mailto:dezder at bk.ru">Denis Grebenyuk</a>
+ * @version $Id:$
+ */
+public class HSQLDBConnectionFactory extends GenericCQConnectionFactory
+{
+
+   /**
+      * HSQLDBConnectionFactory 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 HSQLDBConnectionFactory(DataSource dataSource, String containerName, boolean multiDb,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+   {
+
+      super(dataSource, containerName, multiDb, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * HSQLDBConnectionFactory 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).
+    * @throws RepositoryException
+    *           if error eccurs
+    */
+   public HSQLDBConnectionFactory(String dbDriver, String dbUrl, String dbUserName, String dbPassword,
+      String containerName, boolean multiDb, ValueStoragePluginProvider valueStorageProvider, int maxBufferSize,
+      File swapDirectory, FileCleaner swapCleaner) throws RepositoryException
+   {
+
+      super(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb, valueStorageProvider, maxBufferSize,
+         swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException
+   {
+      try
+      {
+
+         if (multiDb)
+         {
+            return new HSQLDBMultiDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
+               valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+         }
+
+         return new HSQLDBSingleDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
+            valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBConnectionFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2003-2007 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.db;
+
+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
+ * 
+ * 26.08.2009
+ * 
+ * @author <a href="mailto:dezder at bk.ru">Denis Grebenyuk</a>
+ * @version $Id:$
+ */
+public class HSQLDBMultiDbJDBCConnection extends MultiDbJDBCConnection
+{
+
+   /**
+      * HSQLDB Multidatabase JDBC Connection constructor.
+      * 
+      * @param dbConnection
+      *          JDBC connection, shoudl be opened before
+      * @param readOnly
+      *          boolean if true the dbConnection was marked as READ-ONLY.
+      * @param containerName
+      *          Workspace Storage Container name (see configuration)
+      * @param valueStorageProvider
+      *          External Value Storages provider
+      * @param maxBufferSize
+      *          Maximum buffer size (see configuration)
+      * @param swapDirectory
+      *          Swap directory File (see configuration)
+      * @param swapCleaner
+      *          Swap cleaner (internal FileCleaner).
+      * @throws SQLException
+      * 
+      * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+      */
+   public HSQLDBMultiDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+      throws SQLException
+   {
+      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void prepareQueries() throws SQLException
+   {
+
+      super.prepareQueries();
+      FIND_PROPERTY_BY_NAME =
+         "select V.DATA" + " from JCR_MITEM I, JCR_MVALUE V"
+            + " where I.PARENT_ID=? and I.I_CLASS=2 and I.NAME=? and I.ID=V.PROPERTY_ID order by V.ORDER_NUM";
+      FIND_NODES_BY_PARENTID = "select * from JCR_MITEM" + " where PARENT_ID=? and I_CLASS=1" + " order by N_ORDER_NUM";
+      FIND_NODES_COUNT_BY_PARENTID = "select count(ID) from JCR_MITEM" + " where PARENT_ID=? and I_CLASS=1";
+      FIND_PROPERTIES_BY_PARENTID = "select * from JCR_MITEM" + " where PARENT_ID=? and I_CLASS=2" + " order by ID";
+   }
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBMultiDbJDBCConnection.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2003-2007 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.db;
+
+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.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Created by The eXo Platform SAS
+ * 
+ * 26.08.2009
+ * 
+ * @author <a href="mailto:dezder at bk.ru">Denis Grebenyuk</a>
+ * @version $Id:$
+ */
+public class HSQLDBSingleDbJDBCConnection extends SingleDbJDBCConnection
+{
+
+   /**
+      * HSQLDB Singledatabase JDBC Connection constructor.
+      * 
+      * @param dbConnection
+      *          JDBC connection, shoudl be opened before
+      * @param readOnly
+      *          boolean if true the dbConnection was marked as READ-ONLY.
+      * @param containerName
+      *          Workspace Storage Container name (see configuration)
+      * @param valueStorageProvider
+      *          External Value Storages provider
+      * @param maxBufferSize
+      *          Maximum buffer size (see configuration)
+      * @param swapDirectory
+      *          Swap directory File (see configuration)
+      * @param swapCleaner
+      *          Swap cleaner (internal FileCleaner).
+      * @throws SQLException
+      * 
+      * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+      */
+   public HSQLDBSingleDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+      throws SQLException
+   {
+      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected final void prepareQueries() throws SQLException
+   {
+
+      super.prepareQueries();
+
+      FIND_ITEM_BY_NAME =
+         "select * from JCR_SITEM"
+            + " where PARENT_ID=? and CONTAINER_NAME=? and NAME=? and I_INDEX=? order by I_CLASS, VERSION DESC";
+      FIND_PROPERTY_BY_NAME =
+         "select V.DATA"
+            + " from JCR_SITEM I, JCR_SVALUE V"
+            + " where I.PARENT_ID=? and I.I_CLASS=2 and I.CONTAINER_NAME=? and I.NAME=? and I.ID=V.PROPERTY_ID order by V.ORDER_NUM";
+      FIND_NODES_BY_PARENTID =
+         "select * from JCR_SITEM" + " where PARENT_ID=? and I_CLASS=1 and CONTAINER_NAME=?" + " order by N_ORDER_NUM";
+      FIND_NODES_COUNT_BY_PARENTID =
+         "select count(ID) from JCR_SITEM" + " where PARENT_ID=? and I_CLASS=1 and CONTAINER_NAME=?";
+      FIND_PROPERTIES_BY_PARENTID =
+         "select * from JCR_SITEM" + " where PARENT_ID=? and I_CLASS=2 and CONTAINER_NAME=?" + " order by ID";
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findItemByName(String parentId, String name, int index) throws SQLException
+   {
+      if (findItemByName == null)
+         findItemByName = dbConnection.prepareStatement(FIND_ITEM_BY_NAME);
+      else
+         findItemByName.clearParameters();
+
+      findItemByName.setString(1, parentId);
+      findItemByName.setString(2, containerName);
+      findItemByName.setString(3, name);
+      findItemByName.setInt(4, index);
+      return findItemByName.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findPropertyByName(String parentCid, String name) throws SQLException
+   {
+      if (findPropertyByName == null)
+         findPropertyByName = dbConnection.prepareStatement(FIND_PROPERTY_BY_NAME);
+      else
+         findPropertyByName.clearParameters();
+
+      findPropertyByName.setString(1, parentCid);
+      findPropertyByName.setString(2, containerName);
+      findPropertyByName.setString(3, name);
+      return findPropertyByName.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildNodesByParentIdentifier(String parentCid) throws SQLException
+   {
+      if (findNodesByParentId == null)
+         findNodesByParentId = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID);
+      else
+         findNodesByParentId.clearParameters();
+
+      findNodesByParentId.setString(1, parentCid);
+      findNodesByParentId.setString(2, containerName);
+      return findNodesByParentId.executeQuery();
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildNodesCountByParentIdentifier(String parentCid) throws SQLException
+   {
+      if (findNodesCountByParentId == null)
+         findNodesCountByParentId = dbConnection.prepareStatement(FIND_NODES_COUNT_BY_PARENTID);
+      else
+         findNodesCountByParentId.clearParameters();
+
+      findNodesCountByParentId.setString(1, parentCid);
+      findNodesCountByParentId.setString(2, containerName);
+      return findNodesCountByParentId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildPropertiesByParentIdentifier(String parentCid) throws SQLException
+   {
+      if (findPropertiesByParentId == null)
+         findPropertiesByParentId = dbConnection.prepareStatement(FIND_PROPERTIES_BY_PARENTID);
+      else
+         findPropertiesByParentId.clearParameters();
+
+      findPropertiesByParentId.setString(1, parentCid);
+      findPropertiesByParentId.setString(2, containerName);
+      return findPropertiesByParentId.executeQuery();
+   }
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/HSQLDBSingleDbJDBCConnection.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,685 @@
+/*
+ * 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.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.ValueData;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.dataflow.ValueDataConvertor;
+import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCStorageConnection;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.List;
+
+/**
+ * Single database connection implementation.
+ * 
+ * Created by The eXo Platform SAS. </br>
+ * 
+ * @author <a href="mailto:gennady.azarenkov at exoplatform.com">Gennady
+ *         Azarenkov</a>
+ * @version $Id: MultiDbJDBCConnection.java 20950 2008-10-06 14:23:07Z
+ *          pnedonosko $
+ */
+
+public class MultiDbJDBCConnection extends CQJDBCStorageConnection
+{
+
+   protected PreparedStatement findItemById;
+
+   protected PreparedStatement findItemByPath;
+
+   protected PreparedStatement findItemByName;
+
+   protected PreparedStatement findChildPropertyByPath;
+
+   protected PreparedStatement findPropertyByName;
+
+   protected PreparedStatement findDescendantNodes;
+
+   protected PreparedStatement findDescendantProperties;
+
+   protected PreparedStatement findReferences;
+
+   protected PreparedStatement findReferencePropertiesCQ;
+
+   protected PreparedStatement findValuesByPropertyId;
+
+   protected PreparedStatement findValuesDataByPropertyId;
+
+   protected PreparedStatement findValuesStorageDescriptorsByPropertyId;
+
+   @Deprecated
+   protected PreparedStatement findValueByPropertyIdOrderNumber;
+
+   protected PreparedStatement findNodesByParentId;
+
+   protected PreparedStatement findNodesByParentIdCQ;
+
+   protected PreparedStatement findNodesCountByParentId;
+
+   protected PreparedStatement findPropertiesByParentId;
+
+   protected PreparedStatement findPropertiesByParentIdCQ;
+
+   protected PreparedStatement findNodeMainPropertiesByParentIdentifierCQ;
+
+   protected PreparedStatement findItemQPathByIdentifierCQ;
+
+   protected PreparedStatement insertNode;
+
+   protected PreparedStatement insertProperty;
+
+   protected PreparedStatement insertReference;
+
+   protected PreparedStatement insertValue;
+
+   protected PreparedStatement updateItem;
+
+   protected PreparedStatement updateItemPath;
+
+   protected PreparedStatement updateNode;
+
+   protected PreparedStatement updateProperty;
+
+   protected PreparedStatement updateValue;
+
+   protected PreparedStatement deleteItem;
+
+   protected PreparedStatement deleteNode;
+
+   protected PreparedStatement deleteProperty;
+
+   protected PreparedStatement deleteReference;
+
+   protected PreparedStatement deleteValue;
+
+   protected PreparedStatement renameNode;
+
+   /**
+    * Multidatabase JDBC Connection constructor.
+    * 
+    * @param dbConnection JDBC connection, shoudl be opened before
+    * @param readOnly, boolean if true the dbConnection was marked as READ-ONLY. 
+    * @param containerName Workspace Storage Container name (see configuration)
+    * @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 SQLException
+    * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+    */
+   public MultiDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+      throws SQLException
+   {
+
+      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected String getIdentifier(final String internalId)
+   {
+      return internalId;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected String getInternalId(final String identifier)
+   {
+      return identifier;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void prepareQueries() throws SQLException
+   {
+      JCR_PK_ITEM = "JCR_PK_MITEM";
+      JCR_FK_ITEM_PARENT = "JCR_FK_MITEM_PARENT";
+      JCR_IDX_ITEM_PARENT = "JCR_IDX_MITEM_PARENT";
+      JCR_IDX_ITEM_PARENT_NAME = "JCR_IDX_MITEM_PARENT_NAME";
+      JCR_IDX_ITEM_PARENT_ID = "JCR_IDX_MITEM_PARENT_ID";
+      JCR_PK_VALUE = "JCR_PK_MVALUE";
+      JCR_FK_VALUE_PROPERTY = "JCR_FK_MVALUE_PROPERTY";
+      JCR_IDX_VALUE_PROPERTY = "JCR_IDX_MVALUE_PROPERTY";
+      JCR_PK_REF = "JCR_PK_MREF";
+      JCR_IDX_REF_PROPERTY = "JCR_IDX_MREF_PROPERTY";
+
+      FIND_ITEM_BY_ID = "select * from JCR_MITEM where ID=?";
+
+      FIND_ITEM_BY_NAME =
+         "select * from JCR_MITEM" + " where PARENT_ID=? and NAME=? and I_INDEX=? order by I_CLASS, VERSION DESC";
+
+      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";
+
+      FIND_REFERENCES =
+         "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";
+
+      FIND_REFERENCE_PROPERTIES_CQ =
+         "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"
+            + " where R.NODE_ID=? and P.ID=R.PROPERTY_ID and P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by P.ID, V.ORDER_NUM";
+
+      FIND_VALUES_BY_PROPERTYID =
+         "select PROPERTY_ID, ORDER_NUM, DATA, STORAGE_DESC from JCR_MVALUE where PROPERTY_ID=? order by ORDER_NUM";
+
+      FIND_VALUES_VSTORAGE_DESC_BY_PROPERTYID = "select distinct STORAGE_DESC from JCR_MVALUE where PROPERTY_ID=?";
+
+      FIND_VALUE_BY_PROPERTYID_OREDERNUMB = "select DATA from JCR_MVALUE where PROPERTY_ID=? and ORDER_NUM=?";
+
+      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.*, P.NAME AS PROP_NAME, V.ORDER_NUM, V.DATA"
+            + " from (select * from JCR_MITEM where PARENT_ID=? and I_CLASS=1) I, JCR_MITEM P, JCR_MVALUE V"
+            + " where (P.PARENT_ID=I.ID and P.I_CLASS=2 and (P.NAME='[http://www.jcp.org/jcr/1.0]primaryType' or P.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes' or P.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner' or P.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions') and V.PROPERTY_ID=P.ID)"
+            + " order by I.N_ORDER_NUM, I.ID, PROP_NAME DESC, V.ORDER_NUM";
+
+      FIND_NODE_MAIN_PROPERTIES_BY_PARENTID_CQ =
+         "select I.NAME, V.DATA"
+            + " from JCR_MITEM I, JCR_MVALUE V"
+            + " where I.I_CLASS=2 and I.PARENT_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') and I.ID=V.PROPERTY_ID order by V.ORDER_NUM";
+
+      FIND_ITEM_QPATH_BY_ID_CQ =
+         "select I.ID, I.PARENT_ID, I.NAME, I.I_INDEX"
+            + " from JCR_MITEM I, (SELECT ID, PARENT_ID from JCR_MITEM where ID=?) J"
+            + " where I.ID = J.ID or I.ID = J.PARENT_ID";
+
+      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
+      FIND_PROPERTIES_BY_PARENTID_CQ =
+         "select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_CLASS, I.I_INDEX, I.N_ORDER_NUM, I.P_TYPE, I.P_MULTIVALUED,"
+            + " 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 I.ID, V.ORDER_NUM";
+
+      INSERT_NODE =
+         "insert into JCR_MITEM(ID, PARENT_ID, NAME, VERSION, I_CLASS, I_INDEX, N_ORDER_NUM) VALUES(?,?,?,?,"
+            + I_CLASS_NODE + ",?,?)";
+      INSERT_PROPERTY =
+         "insert into JCR_MITEM(ID, PARENT_ID, NAME, VERSION, I_CLASS, I_INDEX, P_TYPE, P_MULTIVALUED) VALUES(?,?,?,?,"
+            + I_CLASS_PROPERTY + ",?,?,?)";
+
+      INSERT_VALUE = "insert into JCR_MVALUE(DATA, ORDER_NUM, PROPERTY_ID, STORAGE_DESC) VALUES(?,?,?,?)";
+      INSERT_REF = "insert into JCR_MREF(NODE_ID, PROPERTY_ID, ORDER_NUM) VALUES(?,?,?)";
+
+      RENAME_NODE = "update JCR_MITEM set PARENT_ID=?, NAME =?, VERSION=?, I_INDEX =?, N_ORDER_NUM =? where ID=?";
+
+      UPDATE_NODE = "update JCR_MITEM set VERSION=?, I_INDEX=?, N_ORDER_NUM=? where ID=?";
+      UPDATE_PROPERTY = "update JCR_MITEM set VERSION=?, P_TYPE=? where ID=?";
+      //UPDATE_VALUE = "update JCR_MVALUE set DATA=?, STORAGE_DESC=? where PROPERTY_ID=?, ORDER_NUM=?";
+
+      DELETE_ITEM = "delete from JCR_MITEM where ID=?";
+      DELETE_VALUE = "delete from JCR_MVALUE where PROPERTY_ID=?";
+      DELETE_REF = "delete from JCR_MREF where PROPERTY_ID=?";
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addNodeRecord(NodeData data) throws SQLException
+   {
+      if (insertNode == null)
+         insertNode = dbConnection.prepareStatement(INSERT_NODE);
+      else
+         insertNode.clearParameters();
+
+      insertNode.setString(1, data.getIdentifier());
+      insertNode.setString(2, data.getParentIdentifier() == null ? Constants.ROOT_PARENT_UUID : data
+         .getParentIdentifier());
+      insertNode.setString(3, data.getQPath().getName().getAsString());
+      insertNode.setInt(4, data.getPersistedVersion());
+      insertNode.setInt(5, data.getQPath().getIndex());
+      insertNode.setInt(6, data.getOrderNumber());
+      return insertNode.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addPropertyRecord(PropertyData data) throws SQLException
+   {
+      if (insertProperty == null)
+         insertProperty = dbConnection.prepareStatement(INSERT_PROPERTY);
+      else
+         insertProperty.clearParameters();
+
+      insertProperty.setString(1, data.getIdentifier());
+      insertProperty.setString(2, data.getParentIdentifier());
+      insertProperty.setString(3, data.getQPath().getName().getAsString());
+      insertProperty.setInt(4, data.getPersistedVersion());
+      insertProperty.setInt(5, data.getQPath().getIndex());
+      insertProperty.setInt(6, data.getType());
+      insertProperty.setBoolean(7, data.isMultiValued());
+
+      return insertProperty.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addReference(PropertyData data) throws SQLException, IOException
+   {
+      if (insertReference == null)
+         insertReference = dbConnection.prepareStatement(INSERT_REF);
+      else
+         insertReference.clearParameters();
+
+      if (data.getQPath().getAsString().indexOf("versionableUuid") > 0)
+         LOG.info("add ref versionableUuid " + data.getQPath().getAsString());
+
+      List<ValueData> values = data.getValues();
+      int added = 0;
+      for (int i = 0; i < values.size(); i++)
+      {
+         ValueData vdata = values.get(i);
+         String refNodeIdentifier = ValueDataConvertor.readString(vdata);
+
+         insertReference.setString(1, refNodeIdentifier);
+         insertReference.setString(2, data.getIdentifier());
+         insertReference.setInt(3, i);
+         added += insertReference.executeUpdate();
+      }
+
+      return added;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int deleteReference(String propertyIdentifier) throws SQLException
+   {
+      if (deleteReference == null)
+         deleteReference = dbConnection.prepareStatement(DELETE_REF);
+      else
+         deleteReference.clearParameters();
+
+      deleteReference.setString(1, propertyIdentifier);
+      return deleteReference.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int deleteItemByIdentifier(String identifier) throws SQLException
+   {
+      if (deleteItem == null)
+         deleteItem = dbConnection.prepareStatement(DELETE_ITEM);
+      else
+         deleteItem.clearParameters();
+
+      deleteItem.setString(1, identifier);
+      return deleteItem.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int updateNodeByIdentifier(int version, int index, int orderNumb, String identifier) throws SQLException
+   {
+      if (updateNode == null)
+         updateNode = dbConnection.prepareStatement(UPDATE_NODE);
+      else
+         updateNode.clearParameters();
+
+      updateNode.setInt(1, version);
+      updateNode.setInt(2, index);
+      updateNode.setInt(3, orderNumb);
+      updateNode.setString(4, identifier);
+      return updateNode.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int updatePropertyByIdentifier(int version, int type, String identifier) throws SQLException
+   {
+      if (updateProperty == null)
+         updateProperty = dbConnection.prepareStatement(UPDATE_PROPERTY);
+      else
+         updateProperty.clearParameters();
+
+      updateProperty.setInt(1, version);
+      updateProperty.setInt(2, type);
+      updateProperty.setString(3, identifier);
+      return updateProperty.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected ResultSet findItemByName(String parentId, String name, int index) throws SQLException
+   {
+      if (findItemByName == null)
+         findItemByName = dbConnection.prepareStatement(FIND_ITEM_BY_NAME);
+      else
+         findItemByName.clearParameters();
+
+      findItemByName.setString(1, parentId);
+      findItemByName.setString(2, name);
+      findItemByName.setInt(3, index);
+      return findItemByName.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findPropertyByName(String parentId, String name) throws SQLException
+   {
+      if (findPropertyByName == null)
+         findPropertyByName = dbConnection.prepareStatement(FIND_PROPERTY_BY_NAME);
+      else
+         findPropertyByName.clearParameters();
+
+      findPropertyByName.setString(1, parentId);
+      findPropertyByName.setString(2, name);
+      return findPropertyByName.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findItemByIdentifier(String identifier) throws SQLException
+   {
+      if (findItemById == null)
+         findItemById = dbConnection.prepareStatement(FIND_ITEM_BY_ID);
+      else
+         findItemById.clearParameters();
+
+      findItemById.setString(1, identifier);
+      return findItemById.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findReferences(String nodeIdentifier) throws SQLException
+   {
+      if (findReferences == null)
+         findReferences = dbConnection.prepareStatement(FIND_REFERENCES);
+      else
+         findReferences.clearParameters();
+
+      findReferences.setString(1, nodeIdentifier);
+      return findReferences.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildNodesByParentIdentifier(String parentIdentifier) throws SQLException
+   {
+      if (findNodesByParentId == null)
+         findNodesByParentId = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID);
+      else
+         findNodesByParentId.clearParameters();
+
+      findNodesByParentId.setString(1, parentIdentifier);
+      return findNodesByParentId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildNodesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   {
+      if (findNodesByParentIdCQ == null)
+         findNodesByParentIdCQ = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID_CQ);
+      else
+         findNodesByParentIdCQ.clearParameters();
+
+      findNodesByParentIdCQ.setString(1, parentIdentifier);
+      return findNodesByParentIdCQ.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildNodesCountByParentIdentifier(String parentIdentifier) throws SQLException
+   {
+      if (findNodesCountByParentId == null)
+         findNodesCountByParentId = dbConnection.prepareStatement(FIND_NODES_COUNT_BY_PARENTID);
+      else
+         findNodesCountByParentId.clearParameters();
+
+      findNodesCountByParentId.setString(1, parentIdentifier);
+      return findNodesCountByParentId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildPropertiesByParentIdentifier(String parentIdentifier) throws SQLException
+   {
+      if (findPropertiesByParentId == null)
+         findPropertiesByParentId = dbConnection.prepareStatement(FIND_PROPERTIES_BY_PARENTID);
+      else
+         findPropertiesByParentId.clearParameters();
+
+      findPropertiesByParentId.setString(1, parentIdentifier);
+      return findPropertiesByParentId.executeQuery();
+   }
+
+   // -------- values processing ------------
+
+   /**
+    * {@inheritDoc}
+    */
+   protected int addValueData(String cid, int orderNumber, InputStream stream, int streamLength, String storageDesc)
+      throws SQLException
+   {
+
+      if (insertValue == null)
+         insertValue = dbConnection.prepareStatement(INSERT_VALUE);
+      else
+         insertValue.clearParameters();
+
+      if (stream == null)
+      {
+         // [PN] store vd reference to external storage etc.
+         insertValue.setNull(1, Types.BINARY);
+         insertValue.setString(4, storageDesc);
+      }
+      else
+      {
+         insertValue.setBinaryStream(1, stream, streamLength);
+         insertValue.setNull(4, Types.VARCHAR);
+      }
+
+      insertValue.setInt(2, orderNumber);
+      insertValue.setString(3, cid);
+      return insertValue.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected int deleteValueData(String cid) throws SQLException
+   {
+      if (deleteValue == null)
+         deleteValue = dbConnection.prepareStatement(DELETE_VALUE);
+      else
+         deleteValue.clearParameters();
+
+      deleteValue.setString(1, cid);
+      return deleteValue.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected ResultSet findValuesByPropertyId(String cid) throws SQLException
+   {
+      if (findValuesByPropertyId == null)
+         findValuesByPropertyId = dbConnection.prepareStatement(FIND_VALUES_BY_PROPERTYID);
+      else
+         findValuesByPropertyId.clearParameters();
+
+      findValuesByPropertyId.setString(1, cid);
+      return findValuesByPropertyId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws SQLException
+   {
+      if (findValueByPropertyIdOrderNumber == null)
+         findValueByPropertyIdOrderNumber = dbConnection.prepareStatement(FIND_VALUE_BY_PROPERTYID_OREDERNUMB);
+      else
+         findValueByPropertyIdOrderNumber.clearParameters();
+
+      findValueByPropertyIdOrderNumber.setString(1, cid);
+      findValueByPropertyIdOrderNumber.setInt(2, orderNumb);
+      return findValueByPropertyIdOrderNumber.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int renameNode(NodeData data) throws SQLException
+   {
+      if (renameNode == null)
+         renameNode = dbConnection.prepareStatement(RENAME_NODE);
+      else
+         renameNode.clearParameters();
+
+      renameNode.setString(1, data.getParentIdentifier() == null ? Constants.ROOT_PARENT_UUID : data
+         .getParentIdentifier());
+      renameNode.setString(2, data.getQPath().getName().getAsString());
+      renameNode.setInt(3, data.getPersistedVersion());
+      renameNode.setInt(4, data.getQPath().getIndex());
+      renameNode.setInt(5, data.getOrderNumber());
+      renameNode.setString(6, data.getIdentifier());
+      return renameNode.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findValuesStorageDescriptorsByPropertyId(String cid) throws SQLException
+   {
+      if (findValuesStorageDescriptorsByPropertyId == null)
+         findValuesStorageDescriptorsByPropertyId =
+            dbConnection.prepareStatement(FIND_VALUES_VSTORAGE_DESC_BY_PROPERTYID);
+      else
+         findValuesStorageDescriptorsByPropertyId.clearParameters();
+
+      findValuesStorageDescriptorsByPropertyId.setString(1, cid);
+      return findValuesStorageDescriptorsByPropertyId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   {
+      if (findPropertiesByParentIdCQ == null)
+         findPropertiesByParentIdCQ = dbConnection.prepareStatement(FIND_PROPERTIES_BY_PARENTID_CQ);
+      else
+         findPropertiesByParentIdCQ.clearParameters();
+
+      findPropertiesByParentIdCQ.setString(1, parentIdentifier);
+      return findPropertiesByParentIdCQ.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findNodeMainPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   {
+      if (findNodeMainPropertiesByParentIdentifierCQ == null)
+         findNodeMainPropertiesByParentIdentifierCQ =
+            dbConnection.prepareStatement(FIND_NODE_MAIN_PROPERTIES_BY_PARENTID_CQ);
+      else
+         findNodeMainPropertiesByParentIdentifierCQ.clearParameters();
+
+      findNodeMainPropertiesByParentIdentifierCQ.setString(1, parentIdentifier);
+      return findNodeMainPropertiesByParentIdentifierCQ.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findItemQPathByIdentifierCQ(String identifier) throws SQLException
+   {
+      if (findItemQPathByIdentifierCQ == null)
+         findItemQPathByIdentifierCQ = dbConnection.prepareStatement(FIND_ITEM_QPATH_BY_ID_CQ);
+      else
+         findItemQPathByIdentifierCQ.clearParameters();
+
+      findItemQPathByIdentifierCQ.setString(1, identifier);
+      return findItemQPathByIdentifierCQ.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findReferencePropertiesCQ(String nodeIdentifier) throws SQLException
+   {
+      if (findReferencePropertiesCQ == null)
+         findReferencePropertiesCQ = dbConnection.prepareStatement(FIND_REFERENCE_PROPERTIES_CQ);
+      else
+         findReferencePropertiesCQ.clearParameters();
+
+      findReferencePropertiesCQ.setString(1, nodeIdentifier);
+      return findReferencePropertiesCQ.executeQuery();
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,129 @@
+/*
+ * 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.WorkspaceStorageConnection;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.sql.SQLException;
+
+import javax.jcr.RepositoryException;
+import javax.sql.DataSource;
+
+/**
+ * Created by The eXo Platform SAS
+ * 
+ * 16.03.2007
+ * 
+ * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a>
+ * @version $Id$
+ */
+public class MySQLConnectionFactory extends GenericCQConnectionFactory
+{
+
+   /**
+    * MySQLConnectionFactory 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).
+    * @throws RepositoryException
+    *           if error eccurs
+    */
+   public MySQLConnectionFactory(String dbDriver, String dbUrl, String dbUserName, String dbPassword,
+      String containerName, boolean multiDb, ValueStoragePluginProvider valueStorageProvider, int maxBufferSize,
+      File swapDirectory, FileCleaner swapCleaner) throws RepositoryException
+   {
+
+      super(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb, valueStorageProvider, maxBufferSize,
+         swapDirectory, swapCleaner);
+   }
+
+   /**
+    * MySQLConnectionFactory  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 MySQLConnectionFactory(DataSource dbDataSource, String containerName, boolean multiDb,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+   {
+
+      super(dbDataSource, containerName, multiDb, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException
+   {
+      try
+      {
+
+         if (multiDb)
+         {
+            return new MySQLMultiDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
+               valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+         }
+
+         return new MySQLSingleDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
+            valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+      }
+      catch (SQLException e)
+      {
+         throw new RepositoryException(e);
+      }
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLConnectionFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLMultiDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLMultiDbJDBCConnection.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLMultiDbJDBCConnection.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,117 @@
+/*
+ * 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.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+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.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Created by The eXo Platform SAS
+ * 
+ * 20.03.2007
+ * 
+ * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a>
+ * @version $Id$
+ */
+public class MySQLMultiDbJDBCConnection extends MultiDbJDBCConnection
+{
+
+   /**
+    * MySQL Multidatabase JDBC Connection constructor.
+    * 
+    * @param dbConnection
+    *          JDBC connection, shoudl be opened before
+    * @param readOnly
+    *          boolean if true the dbConnection was marked as READ-ONLY.
+    * @param containerName
+    *          Workspace Storage Container name (see configuration)
+    * @param valueStorageProvider
+    *          External Value Storages provider
+    * @param maxBufferSize
+    *          Maximum buffer size (see configuration)
+    * @param swapDirectory
+    *          Swap directory File (see configuration)
+    * @param swapCleaner
+    *          Swap cleaner (internal FileCleaner).
+    * @throws SQLException
+    * 
+    * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+    */
+   public MySQLMultiDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+      throws SQLException
+   {
+
+      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addNodeRecord(NodeData data) throws SQLException
+   {
+      // check if parent exists
+      if (data.getParentIdentifier() != null)
+      {
+         ResultSet item = findItemByIdentifier(data.getParentIdentifier());
+         try
+         {
+            if (!item.next())
+               throw new SQLException("Parent is not found. Behaviour of " + JCR_FK_ITEM_PARENT);
+         }
+         finally
+         {
+            item.close();
+         }
+      }
+      return super.addNodeRecord(data);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addPropertyRecord(PropertyData data) throws SQLException
+   {
+      // check if parent exists
+      if (data.getParentIdentifier() != null)
+      {
+         ResultSet item = findItemByIdentifier(data.getParentIdentifier());
+         try
+         {
+            if (!item.next())
+               throw new SQLException("Parent is not found. Behaviour of " + JCR_FK_ITEM_PARENT);
+         }
+         finally
+         {
+            item.close();
+         }
+      }
+      return super.addPropertyRecord(data);
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLMultiDbJDBCConnection.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLSingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLSingleDbJDBCConnection.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLSingleDbJDBCConnection.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,117 @@
+/*
+ * 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.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+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.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Created by The eXo Platform SAS
+ * 
+ * 20.03.2007
+ * 
+ * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter Nedonosko</a>
+ * @version $Id$
+ */
+public class MySQLSingleDbJDBCConnection extends SingleDbJDBCConnection
+{
+
+   /**
+    * MySQL Singledatabase JDBC Connection constructor.
+    * 
+    * @param dbConnection
+    *          JDBC connection, shoudl be opened before
+    * @param readOnly
+    *          boolean if true the dbConnection was marked as READ-ONLY.
+    * @param containerName
+    *          Workspace Storage Container name (see configuration)
+    * @param valueStorageProvider
+    *          External Value Storages provider
+    * @param maxBufferSize
+    *          Maximum buffer size (see configuration)
+    * @param swapDirectory
+    *          Swap directory File (see configuration)
+    * @param swapCleaner
+    *          Swap cleaner (internal FileCleaner).
+    * @throws SQLException
+    * 
+    * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+    */
+   public MySQLSingleDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+      throws SQLException
+   {
+
+      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addNodeRecord(NodeData data) throws SQLException
+   {
+      // check if parent exists
+      if (data.getParentIdentifier() != null)
+      {
+         ResultSet item = findItemByIdentifier(getInternalId(data.getParentIdentifier()));
+         try
+         {
+            if (!item.next())
+               throw new SQLException("Parent is not found. Behaviour of " + JCR_FK_ITEM_PARENT);
+         }
+         finally
+         {
+            item.close();
+         }
+      }
+      return super.addNodeRecord(data);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addPropertyRecord(PropertyData data) throws SQLException
+   {
+      // check if parent exists
+      if (data.getParentIdentifier() != null)
+      {
+         ResultSet item = findItemByIdentifier(getInternalId(data.getParentIdentifier()));
+         try
+         {
+            if (!item.next())
+               throw new SQLException("Parent is not found. Behaviour of " + JCR_FK_ITEM_PARENT);
+         }
+         finally
+         {
+            item.close();
+         }
+      }
+      return super.addPropertyRecord(data);
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MySQLSingleDbJDBCConnection.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,213 @@
+/*
+ * 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$
+ */
+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;
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleConnectionFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,240 @@
+/*
+ * 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$
+ */
+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[]{}));
+      }
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OraclePoolConnectionFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,705 @@
+/*
+ * 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.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.ValueData;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCStorageConnection;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.List;
+
+/**
+ * Single database connection implementation.
+ * 
+ * Created by The eXo Platform SAS 27.04.2006
+ * 
+ * @author <a href="mailto:peter.nedonosko at exoplatform.com.ua">Peter
+ *         Nedonosko</a>
+ * @version $Id: SingleDbJDBCConnection.java 20950 2008-10-06 14:23:07Z
+ *          pnedonosko $
+ */
+public class SingleDbJDBCConnection extends CQJDBCStorageConnection
+{
+
+   protected PreparedStatement findItemById;
+
+   protected PreparedStatement findItemByPath;
+
+   protected PreparedStatement findItemByName;
+
+   protected PreparedStatement findChildPropertyByPath;
+
+   protected PreparedStatement findPropertyByName;
+
+   protected PreparedStatement findDescendantNodes;
+
+   protected PreparedStatement findDescendantProperties;
+
+   protected PreparedStatement findReferences;
+
+   protected PreparedStatement findReferencePropertiesCQ;
+
+   protected PreparedStatement findValuesByPropertyId;
+
+   protected PreparedStatement findValuesStorageDescriptorsByPropertyId;
+
+   protected PreparedStatement findValuesDataByPropertyId;
+
+   protected PreparedStatement findValueByPropertyIdOrderNumber;
+
+   protected PreparedStatement findNodesByParentId;
+
+   protected PreparedStatement findNodesByParentIdCQ;
+
+   protected PreparedStatement findNodesCountByParentId;
+
+   protected PreparedStatement findPropertiesByParentId;
+
+   protected PreparedStatement findPropertiesByParentIdCQ;
+
+   protected PreparedStatement findNodeMainPropertiesByParentIdentifierCQ;
+
+   protected PreparedStatement findItemQPathByIdentifierCQ;
+
+   protected PreparedStatement insertItem;
+
+   protected PreparedStatement insertNode;
+
+   protected PreparedStatement insertProperty;
+
+   protected PreparedStatement insertReference;
+
+   protected PreparedStatement insertValue;
+
+   protected PreparedStatement updateItem;
+
+   protected PreparedStatement updateItemPath;
+
+   protected PreparedStatement updateNode;
+
+   protected PreparedStatement updateProperty;
+
+   protected PreparedStatement updateValue;
+
+   protected PreparedStatement deleteItem;
+
+   protected PreparedStatement deleteNode;
+
+   protected PreparedStatement deleteProperty;
+
+   protected PreparedStatement deleteReference;
+
+   protected PreparedStatement deleteValue;
+
+   protected PreparedStatement renameNode;
+
+   /**
+    * Singledatabase JDBC Connection constructor.
+    * 
+    * @param dbConnection JDBC connection, shoudl be opened before
+    * @param readOnly, boolean if true the dbConnection was marked as READ-ONLY.
+    * @param containerName Workspace Storage Container name (see configuration)
+    * @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 SQLException in case of database error
+    * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+    */
+   public SingleDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+      ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+      throws SQLException
+   {
+
+      super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected String getInternalId(final String identifier)
+   {
+      return containerName + identifier;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected String getIdentifier(final String internalId)
+   {
+
+      if (internalId == null) // possible for root parent
+         return null;
+
+      return internalId.substring(containerName.length());
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void prepareQueries() throws SQLException
+   {
+
+      JCR_PK_ITEM = "JCR_PK_SITEM";
+      JCR_FK_ITEM_PARENT = "JCR_FK_SITEM_PARENT";
+      JCR_IDX_ITEM_PARENT = "JCR_IDX_SITEM_PARENT";
+      JCR_IDX_ITEM_PARENT_NAME = "JCR_IDX_SITEM_PARENT_NAME";
+      JCR_IDX_ITEM_PARENT_ID = "JCR_IDX_SITEM_PARENT_ID";
+      JCR_PK_VALUE = "JCR_PK_SVALUE";
+      JCR_FK_VALUE_PROPERTY = "JCR_FK_SVALUE_PROPERTY";
+      JCR_IDX_VALUE_PROPERTY = "JCR_IDX_SVALUE_PROPERTY";
+      JCR_PK_REF = "JCR_PK_SREF";
+      JCR_IDX_REF_PROPERTY = "JCR_IDX_SREF_PROPERTY";
+
+      FIND_ITEM_BY_ID = "select * from JCR_SITEM where ID=?";
+
+      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_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";
+
+      FIND_REFERENCE_PROPERTIES_CQ =
+         "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_SREF R, JCR_SITEM P, JCR_SVALUE V"
+            + " where R.NODE_ID=? and P.CONTAINER_NAME=? and P.ID=R.PROPERTY_ID and P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by P.ID, V.ORDER_NUM";
+
+      FIND_VALUES_BY_PROPERTYID =
+         "select PROPERTY_ID, ORDER_NUM, DATA, STORAGE_DESC from JCR_SVALUE where PROPERTY_ID=? order by ORDER_NUM";
+
+      FIND_VALUES_VSTORAGE_DESC_BY_PROPERTYID = "select distinct STORAGE_DESC from JCR_SVALUE where PROPERTY_ID=?";
+
+      FIND_VALUE_BY_PROPERTYID_OREDERNUMB = "select DATA from JCR_SVALUE where PROPERTY_ID=? and ORDER_NUM=?";
+
+      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.*, P.NAME AS PROP_NAME, V.ORDER_NUM, V.DATA"
+            + " from (select * from JCR_SITEM where CONTAINER_NAME=? and PARENT_ID=? AND I_CLASS=1) I, JCR_SITEM P, JCR_SVALUE V"
+            + " where (P.CONTAINER_NAME=? and P.PARENT_ID=I.ID and P.I_CLASS=2 and (P.NAME='[http://www.jcp.org/jcr/1.0]primaryType' or P.NAME='[http://www.jcp.org/jcr/1.0]mixinTypes' or P.NAME='[http://www.exoplatform.com/jcr/exo/1.0]owner' or P.NAME='[http://www.exoplatform.com/jcr/exo/1.0]permissions') and V.PROPERTY_ID=P.ID)"
+            + " order by I.N_ORDER_NUM, I.ID, PROP_NAME DESC, V.ORDER_NUM";
+
+      FIND_NODE_MAIN_PROPERTIES_BY_PARENTID_CQ =
+         "select I.NAME, 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='[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') and I.ID=V.PROPERTY_ID order by V.ORDER_NUM";
+
+      FIND_ITEM_QPATH_BY_ID_CQ =
+         "select I.ID, I.PARENT_ID, I.NAME, I.I_INDEX"
+            + " from JCR_SITEM I, (SELECT ID, PARENT_ID from JCR_SITEM where ID=?) J"
+            + " where I.ID = J.ID or I.ID = J.PARENT_ID";
+
+      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";
+
+      FIND_PROPERTIES_BY_PARENTID_CQ =
+         "select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_CLASS, I.I_INDEX, I.N_ORDER_NUM, I.P_TYPE, I.P_MULTIVALUED, 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 I.ID, V.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 + ",?,?)";
+      INSERT_PROPERTY =
+         "insert into JCR_SITEM(ID, PARENT_ID, NAME, CONTAINER_NAME, VERSION, I_CLASS, I_INDEX, P_TYPE, P_MULTIVALUED) VALUES(?,?,?,?,?,"
+            + I_CLASS_PROPERTY + ",?,?,?)";
+
+      INSERT_VALUE = "insert into JCR_SVALUE(DATA, ORDER_NUM, PROPERTY_ID, STORAGE_DESC) VALUES(?,?,?,?)";
+      INSERT_REF = "insert into JCR_SREF(NODE_ID, PROPERTY_ID, ORDER_NUM) VALUES(?,?,?)";
+
+      RENAME_NODE = "update JCR_SITEM set PARENT_ID=?, NAME=?, VERSION=?, I_INDEX=?, N_ORDER_NUM=? where ID=?";
+
+      UPDATE_NODE = "update JCR_SITEM set VERSION=?, I_INDEX=?, N_ORDER_NUM=? where ID=?";
+      UPDATE_PROPERTY = "update JCR_SITEM set VERSION=?, P_TYPE=? where ID=?";
+      //UPDATE_VALUE = "update JCR_SVALUE set DATA=?, STORAGE_DESC=? where PROPERTY_ID=?, ORDER_NUM=?";
+
+      DELETE_ITEM = "delete from JCR_SITEM where ID=?";
+      DELETE_VALUE = "delete from JCR_SVALUE where PROPERTY_ID=?";
+      DELETE_REF = "delete from JCR_SREF where PROPERTY_ID=?";
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addNodeRecord(NodeData data) throws SQLException
+   {
+      if (insertNode == null)
+         insertNode = dbConnection.prepareStatement(INSERT_NODE);
+      else
+         insertNode.clearParameters();
+
+      insertNode.setString(1, getInternalId(data.getIdentifier()));
+      // if root then parent identifier equals space string
+      insertNode.setString(2, data.getParentIdentifier() == null ? Constants.ROOT_PARENT_UUID : getInternalId(data
+         .getParentIdentifier()));
+      insertNode.setString(3, data.getQPath().getName().getAsString());
+      insertNode.setString(4, containerName);
+      insertNode.setInt(5, data.getPersistedVersion());
+      insertNode.setInt(6, data.getQPath().getIndex());
+      insertNode.setInt(7, data.getOrderNumber());
+      return insertNode.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addPropertyRecord(PropertyData data) throws SQLException
+   {
+      if (insertProperty == null)
+         insertProperty = dbConnection.prepareStatement(INSERT_PROPERTY);
+      else
+         insertProperty.clearParameters();
+
+      insertProperty.setString(1, getInternalId(data.getIdentifier()));
+      insertProperty.setString(2, getInternalId(data.getParentIdentifier()));
+      insertProperty.setString(3, data.getQPath().getName().getAsString());
+      insertProperty.setString(4, containerName);
+      insertProperty.setInt(5, data.getPersistedVersion());
+      insertProperty.setInt(6, data.getQPath().getIndex());
+      insertProperty.setInt(7, data.getType());
+      insertProperty.setBoolean(8, data.isMultiValued());
+
+      return insertProperty.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int addReference(PropertyData data) throws SQLException, IOException
+   {
+      if (insertReference == null)
+         insertReference = dbConnection.prepareStatement(INSERT_REF);
+      else
+         insertReference.clearParameters();
+
+      List<ValueData> values = data.getValues();
+      int added = 0;
+      for (int i = 0; i < values.size(); i++)
+      {
+         ValueData vdata = values.get(i);
+         String refNodeIdentifier = new String(vdata.getAsByteArray());
+
+         insertReference.setString(1, getInternalId(refNodeIdentifier));
+         insertReference.setString(2, getInternalId(data.getIdentifier()));
+         insertReference.setInt(3, i);
+         added += insertReference.executeUpdate();
+      }
+      return added;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int deleteReference(String propertyCid) throws SQLException
+   {
+      if (deleteReference == null)
+         deleteReference = dbConnection.prepareStatement(DELETE_REF);
+      else
+         deleteReference.clearParameters();
+
+      deleteReference.setString(1, propertyCid);
+      return deleteReference.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int deleteItemByIdentifier(String cid) throws SQLException
+   {
+      if (deleteItem == null)
+         deleteItem = dbConnection.prepareStatement(DELETE_ITEM);
+      else
+         deleteItem.clearParameters();
+
+      deleteItem.setString(1, cid);
+      return deleteItem.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildNodesByParentIdentifier(String parentCid) throws SQLException
+   {
+      if (findNodesByParentId == null)
+         findNodesByParentId = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID);
+      else
+         findNodesByParentId.clearParameters();
+
+      findNodesByParentId.setString(1, containerName);
+      findNodesByParentId.setString(2, parentCid);
+      return findNodesByParentId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildNodesCountByParentIdentifier(String parentCid) throws SQLException
+   {
+      if (findNodesCountByParentId == null)
+         findNodesCountByParentId = dbConnection.prepareStatement(FIND_NODES_COUNT_BY_PARENTID);
+      else
+         findNodesCountByParentId.clearParameters();
+
+      findNodesCountByParentId.setString(1, containerName);
+      findNodesCountByParentId.setString(2, parentCid);
+      return findNodesCountByParentId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildPropertiesByParentIdentifier(String parentCid) throws SQLException
+   {
+      if (findPropertiesByParentId == null)
+         findPropertiesByParentId = dbConnection.prepareStatement(FIND_PROPERTIES_BY_PARENTID);
+      else
+         findPropertiesByParentId.clearParameters();
+
+      findPropertiesByParentId.setString(1, containerName);
+      findPropertiesByParentId.setString(2, parentCid);
+      return findPropertiesByParentId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findItemByName(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}
+    */
+   @Override
+   protected ResultSet findPropertyByName(String parentCid, String name) throws SQLException
+   {
+      if (findPropertyByName == null)
+         findPropertyByName = dbConnection.prepareStatement(FIND_PROPERTY_BY_NAME);
+      else
+         findPropertyByName.clearParameters();
+
+      findPropertyByName.setString(1, containerName);
+      findPropertyByName.setString(2, parentCid);
+      findPropertyByName.setString(3, name);
+      return findPropertyByName.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findItemByIdentifier(String cid) throws SQLException
+   {
+      if (findItemById == null)
+         findItemById = dbConnection.prepareStatement(FIND_ITEM_BY_ID);
+      else
+         findItemById.clearParameters();
+
+      findItemById.setString(1, cid);
+      return findItemById.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findReferences(String cid) throws SQLException
+   {
+      if (findReferences == null)
+         findReferences = dbConnection.prepareStatement(FIND_REFERENCES);
+      else
+         findReferences.clearParameters();
+
+      findReferences.setString(1, cid);
+      findReferences.setString(2, containerName);
+      return findReferences.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int updateNodeByIdentifier(int version, int index, int orderNumb, String cid) throws SQLException
+   {
+      if (updateNode == null)
+         updateNode = dbConnection.prepareStatement(UPDATE_NODE);
+      else
+         updateNode.clearParameters();
+
+      updateNode.setInt(1, version);
+      updateNode.setInt(2, index);
+      updateNode.setInt(3, orderNumb);
+      updateNode.setString(4, cid);
+      return updateNode.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int updatePropertyByIdentifier(int version, int type, String cid) throws SQLException
+   {
+      if (updateProperty == null)
+         updateProperty = dbConnection.prepareStatement(UPDATE_PROPERTY);
+      else
+         updateProperty.clearParameters();
+
+      updateProperty.setInt(1, version);
+      updateProperty.setInt(2, type);
+      updateProperty.setString(3, cid);
+      return updateProperty.executeUpdate();
+   }
+
+   // -------- values processing ------------
+
+   /**
+    * {@inheritDoc}
+    */
+   protected int addValueData(String cid, int orderNumber, InputStream stream, int streamLength, String storageDesc)
+      throws SQLException
+   {
+
+      if (insertValue == null)
+         insertValue = dbConnection.prepareStatement(INSERT_VALUE);
+      else
+         insertValue.clearParameters();
+
+      if (stream == null)
+      {
+         // [PN] store vd reference to external storage etc.
+         insertValue.setNull(1, Types.BINARY);
+         insertValue.setString(4, storageDesc);
+      }
+      else
+      {
+         insertValue.setBinaryStream(1, stream, streamLength);
+         insertValue.setNull(4, Types.VARCHAR);
+      }
+
+      insertValue.setInt(2, orderNumber);
+      insertValue.setString(3, cid);
+      return insertValue.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected int deleteValueData(String cid) throws SQLException
+   {
+      if (deleteValue == null)
+         deleteValue = dbConnection.prepareStatement(DELETE_VALUE);
+      else
+         deleteValue.clearParameters();
+
+      deleteValue.setString(1, cid);
+      return deleteValue.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected ResultSet findValuesByPropertyId(String cid) throws SQLException
+   {
+      if (findValuesByPropertyId == null)
+         findValuesByPropertyId = dbConnection.prepareStatement(FIND_VALUES_BY_PROPERTYID);
+      else
+         findValuesByPropertyId.clearParameters();
+
+      findValuesByPropertyId.setString(1, cid);
+      return findValuesByPropertyId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findValuesStorageDescriptorsByPropertyId(String cid) throws SQLException
+   {
+      if (findValuesStorageDescriptorsByPropertyId == null)
+         findValuesStorageDescriptorsByPropertyId =
+            dbConnection.prepareStatement(FIND_VALUES_VSTORAGE_DESC_BY_PROPERTYID);
+      else
+         findValuesStorageDescriptorsByPropertyId.clearParameters();
+
+      findValuesStorageDescriptorsByPropertyId.setString(1, cid);
+      return findValuesStorageDescriptorsByPropertyId.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Deprecated
+   protected ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws SQLException
+   {
+      if (findValueByPropertyIdOrderNumber == null)
+         findValueByPropertyIdOrderNumber = dbConnection.prepareStatement(FIND_VALUE_BY_PROPERTYID_OREDERNUMB);
+      else
+         findValueByPropertyIdOrderNumber.clearParameters();
+
+      findValueByPropertyIdOrderNumber.setString(1, cid);
+      findValueByPropertyIdOrderNumber.setInt(2, orderNumb);
+      return findValueByPropertyIdOrderNumber.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected int renameNode(NodeData data) throws SQLException
+   {
+      if (renameNode == null)
+         renameNode = dbConnection.prepareStatement(RENAME_NODE);
+      else
+         renameNode.clearParameters();
+
+      renameNode.setString(1, data.getParentIdentifier() == null ? Constants.ROOT_PARENT_UUID : getInternalId(data
+         .getParentIdentifier()));
+      renameNode.setString(2, data.getQPath().getName().getAsString());
+      renameNode.setInt(3, data.getPersistedVersion());
+      renameNode.setInt(4, data.getQPath().getIndex());
+      renameNode.setInt(5, data.getOrderNumber());
+      renameNode.setString(6, getInternalId(data.getIdentifier()));
+      return renameNode.executeUpdate();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildNodesByParentIdentifierCQ(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);
+      findNodesByParentIdCQ.setString(3, containerName);
+      return findNodesByParentIdCQ.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findChildPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   {
+      if (findPropertiesByParentIdCQ == null)
+         findPropertiesByParentIdCQ = dbConnection.prepareStatement(FIND_PROPERTIES_BY_PARENTID_CQ);
+      else
+         findPropertiesByParentIdCQ.clearParameters();
+
+      findPropertiesByParentIdCQ.setString(1, containerName);
+      findPropertiesByParentIdCQ.setString(2, parentIdentifier);
+      return findPropertiesByParentIdCQ.executeQuery();
+
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findNodeMainPropertiesByParentIdentifierCQ(String parentIdentifier) throws SQLException
+   {
+      if (findNodeMainPropertiesByParentIdentifierCQ == null)
+         findNodeMainPropertiesByParentIdentifierCQ =
+            dbConnection.prepareStatement(FIND_NODE_MAIN_PROPERTIES_BY_PARENTID_CQ);
+      else
+         findNodeMainPropertiesByParentIdentifierCQ.clearParameters();
+
+      findNodeMainPropertiesByParentIdentifierCQ.setString(1, containerName);
+      findNodeMainPropertiesByParentIdentifierCQ.setString(2, parentIdentifier);
+      return findNodeMainPropertiesByParentIdentifierCQ.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findItemQPathByIdentifierCQ(String identifier) throws SQLException
+   {
+      if (findItemQPathByIdentifierCQ == null)
+         findItemQPathByIdentifierCQ = dbConnection.prepareStatement(FIND_ITEM_QPATH_BY_ID_CQ);
+      else
+         findItemQPathByIdentifierCQ.clearParameters();
+
+      findItemQPathByIdentifierCQ.setString(1, identifier);
+      return findItemQPathByIdentifierCQ.executeQuery();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected ResultSet findReferencePropertiesCQ(String nodeIdentifier) throws SQLException
+   {
+      if (findReferencePropertiesCQ == null)
+         findReferencePropertiesCQ = dbConnection.prepareStatement(FIND_REFERENCE_PROPERTIES_CQ);
+      else
+         findReferencePropertiesCQ.clearParameters();
+
+      findReferencePropertiesCQ.setString(1, nodeIdentifier);
+      findReferencePropertiesCQ.setString(2, containerName);
+      return findReferencePropertiesCQ.executeQuery();
+   }
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLBenchmarkTest.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLBenchmarkTest.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLBenchmarkTest.java	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,705 @@
+package org.exoplatform.services.jcr.impl.storage.jdbc;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.RepositoryException;
+
+import org.exoplatform.container.StandaloneContainer;
+import org.exoplatform.services.jcr.BaseStandaloneTest;
+import org.exoplatform.services.jcr.RepositoryService;
+import org.exoplatform.services.jcr.core.WorkspaceContainerFacade;
+import org.exoplatform.services.jcr.dataflow.persistent.PersistedNodeData;
+import org.exoplatform.services.jcr.dataflow.persistent.PersistedPropertyData;
+import org.exoplatform.services.jcr.datamodel.IllegalNameException;
+import org.exoplatform.services.jcr.datamodel.ItemData;
+import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
+import org.exoplatform.services.jcr.datamodel.QPath;
+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.core.RepositoryImpl;
+import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
+import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
+
+/*
+ * 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&lt;http://www.gnu.org/licenses/&gt;.
+ */
+
+/**
+ * This benchmark only works with mysql with the dump that you can find in src/test/resources/SQLBenchmark/exodb_data.sql.zip
+ * 
+ * 
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto 
+ *          nicolas.filotto at exoplatform.com
+ * 18 nov. 2009  
+ */
+public class SQLBenchmarkTest
+{
+/*   
+   static
+   {
+      try
+      {
+         Class.forName("com.jdbmonitor.MonitorDriver");
+         System.out.println("Driver Loaded");
+      }
+      catch (ClassNotFoundException e)
+      {
+         e.printStackTrace();
+      }
+
+   }
+*/
+   /**
+    * @param args
+    */
+   public static void main(String[] args) throws Exception
+   {
+      String containerConf =
+         BaseStandaloneTest.class.getResource("/conf/standalone/sql-benchmark-configuration.xml").toString();
+      String loginConf = BaseStandaloneTest.class.getResource("/login.conf").toString();
+
+      StandaloneContainer.addConfigurationURL(containerConf);
+
+      StandaloneContainer container = StandaloneContainer.getInstance();
+
+      if (System.getProperty("java.security.auth.login.config") == null)
+         System.setProperty("java.security.auth.login.config", loginConf);
+
+      benchmark(1, container);
+      benchmark(10, container);
+      benchmark(20, container);
+      benchmark(50, container);
+      benchmark(100, container);
+   }
+
+   private static void benchmark(int threads, StandaloneContainer container) throws Exception
+   {
+      RepositoryService repositoryService =
+         (RepositoryService)container.getComponentInstanceOfType(RepositoryService.class);
+      RepositoryImpl repository1 = (RepositoryImpl)repositoryService.getRepository("repository1");
+      WorkspaceContainerFacade wsc1 = repository1.getWorkspaceContainer("collaboration");
+      final WorkspaceDataContainer dataContainer1 =
+         (WorkspaceDataContainer)wsc1.getComponent(WorkspaceDataContainer.class);
+      WorkspaceContainerFacade wsc1s = repository1.getWorkspaceContainer("system");
+      final WorkspaceDataContainer dataContainer1s =
+         (WorkspaceDataContainer)wsc1s.getComponent(WorkspaceDataContainer.class);
+      RepositoryImpl repository2 = (RepositoryImpl)repositoryService.getRepository("repository2");
+      WorkspaceContainerFacade wsc2 = repository2.getWorkspaceContainer("collaboration");
+      final WorkspaceDataContainer dataContainer2 =
+         (WorkspaceDataContainer)wsc2.getComponent(WorkspaceDataContainer.class);
+      WorkspaceContainerFacade wsc2s = repository2.getWorkspaceContainer("system");
+      final WorkspaceDataContainer dataContainer2s =
+         (WorkspaceDataContainer)wsc2s.getComponent(WorkspaceDataContainer.class);
+
+      System.out.println("########################################");
+
+      int totalTimes;
+      long time;
+      NodeData parent;
+
+      totalTimes = 5000 / threads;
+      QPath path1 = null;
+      Task<QPath> traverseQPath = new Task<QPath>()
+      {
+         public QPath execute(Object... args) throws Exception
+         {
+            return traverseQPath((WorkspaceDataContainer)args[0], (String)args[1]);
+         }
+
+      };
+      Result<QPath> rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer1, Constants.ROOT_UUID);
+      path1 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 0, thread " + threads
+         + ": Total time with the old strategy (n queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      QPath path2 = null;
+      rTraverseQPath = executeTask(traverseQPath, totalTimes, threads, dataContainer2, Constants.ROOT_UUID);
+      path2 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 0, thread " + threads + ": Total time with the new strategy 0 = "
+         + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("path1 == path2 = " + equals(path1, path2));
+
+      rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer1, "dfcbd34bc0a8010b006357806c7f108d");
+      path1 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 1, thread " + threads
+         + ": Total time with the old strategy (n queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+
+      rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer2, "dfcbd34bc0a8010b006357806c7f108d");
+      path2 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 1, thread " + threads
+         + ": Total time with the new strategy (n/2 queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("path1 == path2 = " + equals(path1, path2));
+
+      rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer1, "dfcbe240c0a8010b00ff024d54e46b9f");
+      path1 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 2, thread " + threads
+         + ": Total time with the old strategy (n queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+
+      rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer2, "dfcbe240c0a8010b00ff024d54e46b9f");
+      path2 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 2, thread " + threads
+         + ": Total time with the new strategy (n/2 queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("path1 == path2 = " + equals(path1, path2));
+
+      rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer1, "dfcbffaec0a8010b00ed7dad7cb43540");
+      path1 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 5, thread " + threads
+         + ": Total time with the old strategy (n queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+
+      rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer2, "dfcbffaec0a8010b00ed7dad7cb43540");
+      path2 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 5, thread " + threads
+         + ": Total time with the new strategy (n/2 queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("path1 == path2 = " + equals(path1, path2));
+
+      rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer1, "83cb7ebeac1b00a400bf3596e43c8f18");
+      path1 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 9, thread " + threads
+         + ": Total time with the old strategy (n queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+
+      rTraverseQPath =
+         executeTask(traverseQPath, totalTimes, threads, dataContainer2, "83cb7ebeac1b00a400bf3596e43c8f18");
+      path2 = rTraverseQPath.getResult();
+      time = rTraverseQPath.getTime();
+      System.out.println("traverseQPath with deep 9, thread " + threads
+         + ": Total time with the new strategy (n/2 queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("path1 == path2 = " + equals(path1, path2));
+
+      totalTimes = 1;
+      parent =
+         new PersistedNodeData("83cb2a36ac1b00a400bdbe4f3f4f6e0e", Constants.ROOT_PATH, null, 0, 0, null, null, null);
+
+      Task<List<NodeData>> getChildNodesData = new Task<List<NodeData>>()
+      {
+         public List<NodeData> execute(Object... args) throws Exception
+         {
+            return getChildNodesData((WorkspaceDataContainer)args[0], (NodeData)args[1]);
+         }
+
+      };
+      List<NodeData> nodesData1 = null;
+
+      Result<List<NodeData>> rGetChildNodesData =
+         executeTask(getChildNodesData, totalTimes, threads, dataContainer1, parent);
+      nodesData1 = rGetChildNodesData.getResult();
+      time = rGetChildNodesData.getTime();
+      System.out.println("getChildNodesData with 1034 subnodes, thread " + threads
+         + ": Total time with the old strategy (4*n + 1 queries) = " + time + ", avg = "
+         + (time / (threads * totalTimes)));
+      List<NodeData> nodesData2 = null;
+      rGetChildNodesData = executeTask(getChildNodesData, totalTimes, threads, dataContainer2, parent);
+      nodesData2 = rGetChildNodesData.getResult();
+      time = rGetChildNodesData.getTime();
+      System.out.println("getChildNodesData with 1034 subnodes, thread " + threads
+         + ": Total time with the new strategy (1 query) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      try
+      {
+         System.out.println("length = " + nodesData1.size());
+         System.out.println("nodesData1 == nodesData2 = " + equals(nodesData1, nodesData2) + " length = "
+            + nodesData1.size());
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+      }
+      totalTimes = 100 / threads;
+      parent =
+         new PersistedNodeData("83c6e36cac1b00a400688aeb844539b2", Constants.ROOT_PATH, null, 0, 0, null, null, null);
+      rGetChildNodesData = executeTask(getChildNodesData, totalTimes, threads, dataContainer1, parent);
+      nodesData1 = rGetChildNodesData.getResult();
+      time = rGetChildNodesData.getTime();
+      System.out.println("getChildNodesData with 4 subnodes, thread " + threads
+         + ": Total time with the old strategy (4*n + 1 queries) = " + time + ", avg = "
+         + (time / (threads * totalTimes)));
+
+      rGetChildNodesData = executeTask(getChildNodesData, totalTimes, threads, dataContainer2, parent);
+      nodesData2 = rGetChildNodesData.getResult();
+      time = rGetChildNodesData.getTime();
+      System.out.println("getChildNodesData with 4 subnodes, thread " + threads
+         + ": Total time with the new strategy (1 query) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("nodesData1 == nodesData2 = " + equals(nodesData1, nodesData2) + " length = "
+         + nodesData1.size());
+
+      totalTimes = 1000 / threads;
+
+      Task<ItemData> getItemData = new Task<ItemData>()
+      {
+         public ItemData execute(Object... args) throws Exception
+         {
+            return getItemData((WorkspaceDataContainer)args[0], (String)args[1]);
+         }
+
+      };
+      PersistedNodeData nodeData1 = null;
+      Result<ItemData> rGetItemData =
+         executeTask(getItemData, totalTimes, threads, dataContainer1, "83c6e36cac1b00a400688aeb844539b2");
+      nodeData1 = (PersistedNodeData)rGetItemData.getResult();
+      time = rGetItemData.getTime();
+      System.out.println("getItemData by Id for a node, thread " + threads
+         + ": Total time with the old strategy (5 queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+
+      PersistedNodeData nodeData2 = null;
+      rGetItemData = executeTask(getItemData, totalTimes, threads, dataContainer2, "83c6e36cac1b00a400688aeb844539b2");
+      nodeData2 = (PersistedNodeData)rGetItemData.getResult();
+      time = rGetItemData.getTime();
+      System.out.println("getItemData by Id for a node, thread " + threads
+         + ": Total time with the new strategy (2 queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("nodeData1 == nodeData2 = " + equals(nodeData1, nodeData2));
+
+      PersistedPropertyData propertyData1 = null;
+      rGetItemData = executeTask(getItemData, totalTimes, threads, dataContainer1, "83c6e36cac1b00a40038e9e950ecff39");
+      propertyData1 = (PersistedPropertyData)rGetItemData.getResult();
+      time = rGetItemData.getTime();
+      System.out.println("getItemData by Id for a property, thread " + threads
+         + ": Total time with the old strategy (2 queries) = " + time + ", avg = " + (time / (threads * totalTimes)));
+
+      PersistedPropertyData propertyData2 = null;
+      rGetItemData = executeTask(getItemData, totalTimes, threads, dataContainer2, "83c6e36cac1b00a40038e9e950ecff39");
+      propertyData2 = (PersistedPropertyData)rGetItemData.getResult();
+      time = rGetItemData.getTime();
+      System.out.println("getItemData by Id for a property, thread " + threads
+         + ": Total time with the new strategy (2 queries) (=old strategy) = " + time + ", avg = "
+         + (time / (threads * totalTimes)));
+      System.out.println("propertyData1 == propertyData2 = " + equals(propertyData1, propertyData2));
+
+      NodeData parent2 =
+         new PersistedNodeData("00exo0jcr0root0uuid0000000000000", Constants.ROOT_PATH, null, 0, 0, null, null, null);
+      QPathEntry name2 = new QPathEntry(null, "Documents", 1);
+
+      Task<ItemData> getItemData2 = new Task<ItemData>()
+      {
+         public ItemData execute(Object... args) throws Exception
+         {
+            return getItemData((WorkspaceDataContainer)args[0], (NodeData)args[1], (QPathEntry)args[2]);
+         }
+
+      };
+      rGetItemData = executeTask(getItemData2, totalTimes, threads, dataContainer1, parent2, name2);
+      nodeData1 = (PersistedNodeData)rGetItemData.getResult();
+      time = rGetItemData.getTime();
+      System.out.println("getItemData by QPathEntry for a node, thread " + threads
+         + ": Total time with the old strategy = " + time + ", avg = " + (time / (threads * totalTimes)));
+
+      rGetItemData = executeTask(getItemData2, totalTimes, threads, dataContainer2, parent2, name2);
+      nodeData2 = (PersistedNodeData)rGetItemData.getResult();
+      time = rGetItemData.getTime();
+      System.out.println("getItemData by QPathEntry for a node, thread " + threads
+         + ": Total time with the new strategy = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("nodeData1 == nodeData2 = " + equals(nodeData1, nodeData2));
+
+      NodeData parent3 = nodeData1;
+      QPathEntry name3 = new QPathEntry("http://www.exoplatform.com/jcr/exo/1.0", "permissions", 1);
+
+      rGetItemData = executeTask(getItemData2, totalTimes, threads, dataContainer1, parent3, name3);
+      propertyData1 = (PersistedPropertyData)rGetItemData.getResult();
+      time = rGetItemData.getTime();
+      System.out.println("getItemData by QPathEntry for a property, thread " + threads
+         + ": Total time with the old strategy = " + time + ", avg = " + (time / (threads * totalTimes)));
+
+      rGetItemData = executeTask(getItemData2, totalTimes, threads, dataContainer2, parent3, name3);
+      propertyData2 = (PersistedPropertyData)rGetItemData.getResult();
+      time = rGetItemData.getTime();
+      System.out.println("getItemData by QPathEntry for a property, thread " + threads
+         + ": Total time with the new strategy = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("propertyData1 == propertyData2 = " + equals(propertyData1, propertyData2));
+
+      parent =
+         new PersistedNodeData("83c7507eac1b00a400cf6d951b948e23", Constants.ROOT_PATH, null, 0, 0, null, null, null);
+
+      totalTimes = 100 / threads;
+      Task<List<PropertyData>> getChildPropertiesData = new Task<List<PropertyData>>()
+      {
+         public List<PropertyData> execute(Object... args) throws Exception
+         {
+            return getChildPropertiesData((WorkspaceDataContainer)args[0], (NodeData)args[1]);
+         }
+
+      };
+      List<PropertyData> propertiesData1 = null;
+      Result<List<PropertyData>> rGetChildPropertiesData =
+         executeTask(getChildPropertiesData, totalTimes, threads, dataContainer1, parent);
+      propertiesData1 = rGetChildPropertiesData.getResult();
+      time = rGetChildPropertiesData.getTime();
+      System.out.println("getChildPropertiesData with 20 properties, thread " + threads
+         + ": Total time with the old strategy (n + 1 queries) = " + time + ", avg = "
+         + (time / (threads * totalTimes)));
+      List<PropertyData> propertiesData2 = null;
+      rGetChildPropertiesData = executeTask(getChildPropertiesData, totalTimes, threads, dataContainer2, parent);
+      propertiesData2 = rGetChildPropertiesData.getResult();
+      time = rGetChildPropertiesData.getTime();
+      System.out.println("getChildPropertiesData with 20 properties, thread " + threads
+         + ": Total time with the new strategy (1 query) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      try
+      {
+         System.out.println("propertiesData1 == propertiesData2 = " + equalsP(propertiesData1, propertiesData2)
+            + " length = " + propertiesData1.size());
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+      }
+      totalTimes = 100 / threads;
+      parent =
+         new PersistedNodeData("83c6e36cac1b00a400688aeb844539b2", Constants.ROOT_PATH, null, 0, 0, null, null, null);
+      rGetChildPropertiesData = executeTask(getChildPropertiesData, totalTimes, threads, dataContainer1, parent);
+      propertiesData1 = rGetChildPropertiesData.getResult();
+      time = rGetChildPropertiesData.getTime();
+      System.out.println("getChildPropertiesData with 6 properties, thread " + threads
+         + ": Total time with the old strategy (n + 1 queries) = " + time + ", avg = "
+         + (time / (threads * totalTimes)));
+
+      rGetChildPropertiesData = executeTask(getChildPropertiesData, totalTimes, threads, dataContainer2, parent);
+      propertiesData2 = rGetChildPropertiesData.getResult();
+      time = rGetChildPropertiesData.getTime();
+      System.out.println("getChildPropertiesData with 6 properties, thread " + threads
+         + ": Total time with the new strategy (1 query) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("propertiesData1 == propertiesData2 = " + equalsP(propertiesData1, propertiesData2)
+         + " length = " + propertiesData1.size());
+
+      totalTimes = 100 / threads;
+      Task<List<PropertyData>> getReferencesData = new Task<List<PropertyData>>()
+      {
+         public List<PropertyData> execute(Object... args) throws Exception
+         {
+            return getReferencesData((WorkspaceDataContainer)args[0], (String)args[1]);
+         }
+
+      };
+      Result<List<PropertyData>> rGetReferencesData =
+         executeTask(getReferencesData, totalTimes, threads, dataContainer1s, "dfcbf3cfc0a8010b00a3f5f3b962c76a");
+      propertiesData1 = rGetReferencesData.getResult();
+      time = rGetReferencesData.getTime();
+      System.out.println("getReferencesData with 3 properties, thread " + threads
+         + ": Total time with the old strategy (n + 1 queries) = " + time + ", avg = "
+         + (time / (threads * totalTimes)));
+
+      rGetReferencesData =
+         executeTask(getReferencesData, totalTimes, threads, dataContainer2s, "dfcbf3cfc0a8010b00a3f5f3b962c76a");
+      propertiesData2 = rGetReferencesData.getResult();
+      time = rGetReferencesData.getTime();
+      System.out.println("getReferencesData with 3 properties, thread " + threads
+         + ": Total time with the new strategy (1 query) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      try
+      {
+         System.out.println("propertiesData1 == propertiesData2 = " + equalsP(propertiesData1, propertiesData2)
+            + " length = " + propertiesData1.size());
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+      }
+      totalTimes = 100 / threads;
+      rGetReferencesData =
+         executeTask(getReferencesData, totalTimes, threads, dataContainer1, "dfcbe9d6c0a8010b004ccac41a161c5d");
+      propertiesData1 = rGetReferencesData.getResult();
+      time = rGetReferencesData.getTime();
+      System.out.println("getReferencesData with 1 property, thread " + threads
+         + ": Total time with the old strategy (n + 1 queries) = " + time + ", avg = "
+         + (time / (threads * totalTimes)));
+
+      rGetReferencesData =
+         executeTask(getReferencesData, totalTimes, threads, dataContainer2, "dfcbe9d6c0a8010b004ccac41a161c5d");
+      propertiesData2 = rGetReferencesData.getResult();
+      time = rGetReferencesData.getTime();
+      System.out.println("getReferencesData with 1 property, thread " + threads
+         + ": Total time with the new strategy (1 query) = " + time + ", avg = " + (time / (threads * totalTimes)));
+      System.out.println("propertiesData1 == propertiesData2 = " + equalsP(propertiesData1, propertiesData2)
+         + " length = " + propertiesData1.size());
+   }
+
+   private static boolean equals(PersistedNodeData nodeData1, PersistedNodeData nodeData2)
+   {
+      return nodeData1.getACL().equals(nodeData2.getACL())
+         && nodeData1.getIdentifier().equals(nodeData2.getIdentifier())
+         && Arrays.equals(nodeData1.getMixinTypeNames(), nodeData2.getMixinTypeNames())
+         && nodeData1.getOrderNumber() == nodeData2.getOrderNumber()
+         && nodeData1.getParentIdentifier().equals(nodeData2.getParentIdentifier())
+         && nodeData1.getPersistedVersion() == nodeData2.getPersistedVersion()
+         && nodeData1.getPrimaryTypeName().equals(nodeData2.getPrimaryTypeName())
+         && nodeData1.getQPath().equals(nodeData2.getQPath()) && nodeData1.isNode() == nodeData2.isNode();
+   }
+
+   private static boolean equals(PersistedPropertyData propertyData1, PersistedPropertyData propertyData2)
+   {
+      boolean result =
+         propertyData1.isMultiValued() == propertyData2.isMultiValued()
+            && propertyData1.isNode() == propertyData2.isNode()
+            && propertyData1.getIdentifier().equals(propertyData2.getIdentifier())
+            && propertyData1.getParentIdentifier().equals(propertyData2.getParentIdentifier())
+            && propertyData1.getPersistedVersion() == propertyData2.getPersistedVersion()
+            && propertyData1.getQPath().equals(propertyData2.getQPath())
+            && propertyData1.getType() == propertyData2.getType();
+      if (!result)
+      {
+         return false;
+      }
+      List<ValueData> values1 = propertyData1.getValues();
+      List<ValueData> values2 = propertyData2.getValues();
+      if (values1 == null)
+      {
+         return values2 == null;
+      }
+      else if (values2 == null || values1.size() != values2.size())
+      {
+         return false;
+      }
+      else
+      {
+         for (int i = 0; i < values1.size(); i++)
+         {
+            ValueData value1 = values1.get(i);
+            ValueData value2 = values2.get(i);
+            result =
+               value1.isByteArray() == value2.isByteArray() && value1.getLength() == value2.getLength()
+                  && value1.getOrderNumber() == value2.getOrderNumber();
+            if (!result)
+            {
+               return false;
+            }
+         }
+      }
+      return true;
+   }
+
+   private static boolean equals(QPath path1, QPath path2)
+   {
+      return path1.equals(path2);
+   }
+
+   private static boolean equalsP(List<PropertyData> propertiesData1, List<PropertyData> propertiesData2)
+   {
+      if (propertiesData1 == null)
+      {
+         return propertiesData2 == null;
+      }
+      else if (propertiesData2 == null || propertiesData1.size() != propertiesData2.size())
+      {
+         return false;
+      }
+      else
+      {
+         for (int i = 0; i < propertiesData1.size(); i++)
+         {
+            PersistedPropertyData propertyData1 = (PersistedPropertyData)propertiesData1.get(i);
+            PersistedPropertyData propertyData2 = (PersistedPropertyData)propertiesData2.get(i);
+            if (!equals(propertyData1, propertyData2))
+            {
+               return false;
+            }
+         }
+      }
+      return true;
+   }
+
+   private static boolean equals(List<NodeData> nodesData1, List<NodeData> nodesData2)
+   {
+      if (nodesData1 == null)
+      {
+         return nodesData2 == null;
+      }
+      else if (nodesData2 == null || nodesData1.size() != nodesData2.size())
+      {
+         return false;
+      }
+      else
+      {
+         for (int i = 0; i < nodesData1.size(); i++)
+         {
+            PersistedNodeData nodeData1 = (PersistedNodeData)nodesData1.get(i);
+            PersistedNodeData nodeData2 = (PersistedNodeData)nodesData2.get(i);
+            if (!equals(nodeData1, nodeData2))
+            {
+               return false;
+            }
+         }
+      }
+      return true;
+   }
+
+   public static ItemData getItemData(WorkspaceDataContainer dataContainer, NodeData parentData, QPathEntry name)
+      throws RepositoryException, IllegalStateException
+   {
+      final WorkspaceStorageConnection con = dataContainer.openConnection();
+      try
+      {
+         return con.getItemData(parentData, name);
+      }
+      finally
+      {
+         con.close();
+      }
+   }
+
+   private static ItemData getItemData(WorkspaceDataContainer dataContainer, final String identifier)
+      throws RepositoryException
+   {
+      final WorkspaceStorageConnection con = dataContainer.openConnection();
+      try
+      {
+         return con.getItemData(identifier);
+      }
+      finally
+      {
+         con.close();
+      }
+   }
+
+   private static List<NodeData> getChildNodesData(WorkspaceDataContainer dataContainer, final NodeData parent)
+      throws RepositoryException
+   {
+      final WorkspaceStorageConnection con = dataContainer.openConnection();
+      try
+      {
+         return con.getChildNodesData(parent);
+      }
+      finally
+      {
+         con.close();
+      }
+   }
+
+   private static List<PropertyData> getChildPropertiesData(WorkspaceDataContainer dataContainer, final NodeData parent)
+      throws RepositoryException
+   {
+      final WorkspaceStorageConnection con = dataContainer.openConnection();
+      try
+      {
+         return con.getChildPropertiesData(parent);
+      }
+      finally
+      {
+         con.close();
+      }
+   }
+
+   private static List<PropertyData> getReferencesData(WorkspaceDataContainer dataContainer, final String identifier)
+      throws RepositoryException
+   {
+      final WorkspaceStorageConnection con = dataContainer.openConnection();
+      try
+      {
+         return con.getReferencesData(identifier);
+      }
+      finally
+      {
+         con.close();
+      }
+   }
+
+   private static QPath traverseQPath(WorkspaceDataContainer dataContainer, final String identifier)
+      throws RepositoryException, SQLException, InvalidItemStateException, IllegalNameException
+   {
+      final JDBCStorageConnection con = (JDBCStorageConnection)dataContainer.openConnection();
+      try
+      {
+         return con.traverseQPath(con.getInternalId(identifier));
+      }
+      finally
+      {
+         con.close();
+      }
+   }
+
+   private static interface Task<R>
+   {
+      R execute(Object... args) throws Exception;
+   }
+
+   private static class Result<R>
+   {
+      private final R result;
+
+      private final long time;
+
+      public Result(R result, long time)
+      {
+         this.result = result;
+         this.time = time;
+      }
+
+      public R getResult()
+      {
+         return result;
+      }
+
+      public long getTime()
+      {
+         return time;
+      }
+   }
+
+   private static <R> Result<R> executeTask(final Task<R> task, final int totalTimes, int threads, final Object... args)
+      throws InterruptedException
+   {
+      final CountDownLatch startSignal = new CountDownLatch(1);
+      final CountDownLatch doneSignal = new CountDownLatch(threads);
+      final AtomicReference<R> result = new AtomicReference<R>();
+      for (int i = 0; i < threads; i++)
+      {
+         Thread t = new Thread()
+         {
+            public void run()
+            {
+               try
+               {
+                  startSignal.await();
+                  for (int i = 0; i < totalTimes; i++)
+                  {
+                     result.set(task.execute(args));
+                  }
+               }
+               catch (Exception e)
+               {
+                  e.printStackTrace();
+               }
+               finally
+               {
+                  doneSignal.countDown();
+               }
+            }
+         };
+         t.start();
+      }
+      long time = System.currentTimeMillis();
+      startSignal.countDown();
+      doneSignal.await();
+      return new Result<R>(result.get(), System.currentTimeMillis() - time);
+   }
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/jdbc/SQLBenchmarkTest.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/SQLBenchmark/exodb_data.sql.zip
===================================================================
(Binary files differ)


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/SQLBenchmark/exodb_data.sql.zip
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-configuration.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-configuration.xml	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-configuration.xml	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+
+    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.
+
+-->
+<configuration
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+   xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+  <component>
+    <key>org.exoplatform.services.log.LogConfigurationInitializer</key>
+    <type>org.exoplatform.services.log.LogConfigurationInitializer</type>
+    <init-params>
+      <value-param>
+        <name>logger</name>
+        <value>org.exoplatform.services.log.impl.BufferedLog4JLogger</value>
+      </value-param>
+      <value-param>
+        <name>configurator</name>
+        <value>org.exoplatform.services.log.impl.Log4JConfigurator</value>
+      </value-param>
+      <properties-param>
+        <name>properties</name>
+        <description>Log4J properties</description>
+        <property name="log4j.rootLogger" value="INFO, stdout, file"/>
+        
+        <property name="log4j.appender.stdout" value="org.apache.log4j.ConsoleAppender"/>
+        <property name="log4j.appender.stdout.threshold" value="DEBUG"/>
+        
+        <property name="log4j.appender.stdout.layout" value="org.apache.log4j.PatternLayout"/>
+        <property name="log4j.appender.stdout.layout.ConversionPattern"
+          value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n"/>
+        
+        <property name="log4j.appender.file" value="org.apache.log4j.FileAppender"/>
+        <property name="log4j.appender.file.File" value="target/jcr.log"/>
+        
+        <property name="log4j.appender.file.layout" value="org.apache.log4j.PatternLayout"/>
+        <property name="log4j.appender.file.layout.ConversionPattern"
+          value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n"/>
+        
+        <property name="log4j.category.jcr.FileCleaner" value="DEBUG"/>
+        
+        <!-- property name="log4j.category.jcr.JDBCStorageConnection" value="DEBUG"/>
+        <property name="log4j.category.jcr.NodeImpl" value="DEBUG"/ -->
+        
+        <!-- property name="log4j.category.jcr.WorkspaceStorageCacheImpl" value="DEBUG"/ -->
+        <!-- property name="log4j.category.database.DBSchemaCreator" value="DEBUG"/ -->
+        <!-- property name="log4j.category.jcr.WorkspaceDataReplicator" value="DEBUG"/ -->
+        
+        <!-- property name="log4j.category.jcr.WorkspaceStorageCacheImpl" value="DEBUG"/ -->
+        <!-- property name="log4j.category.jcr.WorkspacePersistentDataManager" value="DEBUG"/ -->
+        <!-- property name="log4j.category.jcr.SessionDataManager" value="DEBUG"/ -->
+      </properties-param>
+      
+      <!-- value-param>
+      <name>logger</name>
+      <value>org.exoplatform.services.log.impl.BufferedSimpleLog</value>
+      </value-param>
+      <value-param>
+      <name>configurator</name>
+      <value>org.exoplatform.services.log.impl.SimpleLogConfigurator</value>
+      </value-param>
+      <properties-param>
+      <name>properties</name>
+      <description>SimpleLog properties</description>
+      <property name="org.apache.commons.logging.simplelog.defaultlog" value="debug"/>
+      <property name="org.apache.commons.logging.simplelog.showdatetime" value="true"/>
+      </properties-param -->
+      
+      <!-- value-param>
+      <name>logger</name>
+      <value>org.exoplatform.services.log.impl.BufferedJdk14Logger</value>
+      </value-param>
+      <value-param>
+      <name>configurator</name>
+      <value>org.exoplatform.services.log.impl.Jdk14Configurator</value>
+      </value-param>
+      <properties-param>
+      <name>properties</name>
+      <description>jdk1.4 Logger properties</description>
+      <property name="handlers" value="java.util.logging.ConsoleHandler"/>
+      <property name=".level" value="FINE"/>
+      <property name="java.util.logging.ConsoleHandler.level" value="FINE"/>
+      </properties-param -->
+      
+    </init-params>
+  </component>
+
+  <component>
+    <key>org.exoplatform.services.jcr.RepositoryService</key>
+    <type>org.exoplatform.services.jcr.impl.RepositoryServiceImpl</type>
+    <component-plugins>
+      <component-plugin>
+        <name>add.namespaces</name>
+        <set-method>addPlugin</set-method>
+        <type>org.exoplatform.services.jcr.impl.AddNamespacesPlugin</type>
+        <init-params>
+          <properties-param>
+            <name>namespaces</name>
+            <property name="test" value="http://www.apache.org/jackrabbit/test"/>
+            <property name="exojcrtest" value="http://www.exoplatform.org/jcr/test/1.0"/>
+            <property name="rma" value="http://www.rma.com/jcr/"/>
+            <property name="metadata" value="http://www.exoplatform.com/jcr/metadata/1.1/"/>
+            <property name="dc" value="http://purl.org/dc/elements/1.1/"/>
+          </properties-param>
+        </init-params>
+      </component-plugin>
+    </component-plugins>
+  </component>
+  
+  <component>
+    <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+    <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+    <init-params>
+      <value-param>
+        <name>conf-path</name>
+        <description>JCR configuration file</description>
+        <value>jar:/conf/standalone/sql-benchmark-jcr-config.xml</value>
+      </value-param>
+    </init-params>
+  </component>
+  
+  <component>
+    <type>org.exoplatform.services.organization.impl.mock.DummyOrganizationService</type>
+  </component>
+  
+  <component>
+    <key>org.exoplatform.services.security.Authenticator</key>
+    <type>org.exoplatform.services.organization.auth.OrganizationAuthenticatorImpl</type>
+  </component>
+  
+  <component>
+    <type>org.exoplatform.services.jcr.impl.ext.action.SessionActionCatalog</type>
+  </component>
+  
+  <component>
+    <key>org.exoplatform.services.transaction.TransactionService</key>
+    <type>org.exoplatform.services.transaction.impl.jotm.TransactionServiceJotmImpl</type>
+    <init-params>
+      <value-param>
+        <name>timeout</name>
+        <value>5</value>
+      </value-param>
+    </init-params>
+  </component>
+  
+  <external-component-plugins>
+    <target-component>org.exoplatform.services.naming.InitialContextInitializer</target-component>
+    <component-plugin>
+      <name>bind.datasource</name>
+      <set-method>addPlugin</set-method>
+      <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+      <init-params>
+        <value-param>
+          <name>bind-name</name>
+          <value>jdbcexo</value>
+        </value-param>
+        <value-param>
+          <name>class-name</name>
+          <value>javax.sql.DataSource</value>
+        </value-param>
+        <value-param>
+          <name>factory</name>
+          <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+        </value-param>
+        <properties-param>
+          <name>ref-addresses</name>
+          <description>ref-addresses</description>
+          <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
+          <property name="url" value="jdbc:mysql://localhost:3306/exodb?relaxAutoCommit=true&amp;autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
+          <property name="username" value="root"/>
+          <property name="password" value="root"/>
+          <property name="maxActive" value="50" />
+          <property name="maxIdle" value="5" />
+          <property name="initialSize" value="50" />                  
+        </properties-param>
+      </init-params>
+    </component-plugin>
+  </external-component-plugins>
+  
+  <remove-configuration>org.exoplatform.services.scheduler.JobSchedulerService</remove-configuration>
+</configuration>


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-configuration.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-jcr-config.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-jcr-config.xml	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-jcr-config.xml	2010-01-11 16:18:42 UTC (rev 1347)
@@ -0,0 +1,474 @@
+<repository-service default-repository="repository">
+	<repositories>
+		<repository name="repository1" system-workspace="system"
+			default-workspace="collaboration">
+			<security-domain>exo-domain</security-domain>
+			<access-control>optional</access-control>
+			<authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+			<workspaces>
+				<workspace name="system">
+					<container
+						class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+						<properties>
+							<property name="source-name" value="jdbcexo" />
+							<property name="dialect" value="MySQL" />
+							<!--<property name="dialect" value="hsqldb"/>-->
+							<property name="multi-db" value="false" />
+							<property name="max-buffer-size" value="200k" />
+							<property name="swap-directory" value="../temp/swap/system" />
+						</properties>
+						<value-storages>
+							<value-storage id="system"
+								class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+								<properties>
+									<property name="path" value="../temp/values/system" />
+								</properties>
+								<filters>
+									<filter property-type="Binary" />
+								</filters>
+							</value-storage>
+						</value-storages>
+					</container>
+					<initializer
+						class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+						<properties>
+							<property name="root-nodetype" value="nt:unstructured" />
+							<property name="root-permissions"
+								value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+						</properties>
+					</initializer>
+					<cache enabled="true"
+						class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+						<properties>
+							<property name="max-size" value="20k" />
+							<property name="live-time" value="1h" />
+						</properties>
+					</cache>
+<!--					<query-handler-->
+<!--						class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">-->
+<!--						<properties>-->
+<!--							<property name="index-dir" value="../temp/jcrlucenedb/system" />-->
+<!--							<property name="support-highlighting" value="true" />-->
+<!--							<property name="excerptprovider-class"-->
+<!--								value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt" />-->
+<!--						</properties>-->
+<!--					</query-handler>-->
+					<lock-manager>
+						<time-out>15m</time-out>
+						<persister
+							class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+							<properties>
+								<property name="path" value="../temp/lock/system" />
+							</properties>
+						</persister>
+					</lock-manager>
+				</workspace>
+				<workspace name="collaboration">
+					<container
+						class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+						<properties>
+							<property name="source-name" value="jdbcexo" />
+							<property name="dialect" value="MySQL" />
+							<!--<property name="dialect" value="hsqldb"/> -->
+							<property name="multi-db" value="false" />
+							<property name="max-buffer-size" value="200k" />
+							<property name="swap-directory" value="../temp/swap/collaboration" />
+						</properties>
+						<value-storages>
+							<value-storage id="collaboration"
+								class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+								<properties>
+									<property name="path" value="../temp/values/collaboration" />
+								</properties>
+								<filters>
+									<filter property-type="Binary" />
+								</filters>
+							</value-storage>
+						</value-storages>
+					</container>
+					<initializer
+						class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+						<properties>
+							<property name="root-nodetype" value="nt:unstructured" />
+							<property name="root-permissions"
+								value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+						</properties>
+					</initializer>
+					<cache enabled="true"
+						class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+						<properties>
+							<property name="max-size" value="20k" />
+							<property name="live-time" value="1h" />
+						</properties>
+					</cache>
+<!--					<query-handler-->
+<!--						class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">-->
+<!--						<properties>-->
+<!--							<property name="index-dir" value="../temp/jcrlucenedb/collaboration" />-->
+<!--							<property name="support-highlighting" value="true" />-->
+<!--							<property name="excerptprovider-class"-->
+<!--								value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt" />-->
+<!--						</properties>-->
+<!--					</query-handler>-->
+					<lock-manager>
+						<time-out>15m</time-out>
+						<persister
+							class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+							<properties>
+								<property name="path" value="../temp/lock/collaboration" />
+							</properties>
+						</persister>
+					</lock-manager>
+				</workspace>
+				<workspace name="backup">
+					<container
+						class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+						<properties>
+							<property name="source-name" value="jdbcexo" />
+							<property name="dialect" value="MySQL" />
+							<!--<property name="dialect" value="hsqldb"/> -->
+							<property name="multi-db" value="false" />
+							<property name="max-buffer-size" value="200k" />
+							<property name="swap-directory" value="../temp/swap/backup" />
+						</properties>
+						<value-storages>
+							<value-storage id="backup"
+								class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+								<properties>
+									<property name="path" value="../temp/values/backup" />
+								</properties>
+								<filters>
+									<filter property-type="Binary" />
+								</filters>
+							</value-storage>
+						</value-storages>
+					</container>
+					<initializer
+						class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+						<properties>
+							<property name="root-nodetype" value="nt:unstructured" />
+							<property name="root-permissions"
+								value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+						</properties>
+					</initializer>
+					<cache enabled="true"
+						class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+						<properties>
+							<property name="max-size" value="5k" />
+							<property name="live-time" value="20m" />
+						</properties>
+					</cache>
+<!--					<query-handler-->
+<!--						class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">-->
+<!--						<properties>-->
+<!--							<property name="index-dir" value="../temp/jcrlucenedb/backup" />-->
+<!--							<property name="support-highlighting" value="true" />-->
+<!--							<property name="excerptprovider-class"-->
+<!--								value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt" />-->
+<!--						</properties>-->
+<!--					</query-handler>-->
+					<lock-manager>
+						<time-out>15m</time-out>
+						<persister
+							class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+							<properties>
+								<property name="path" value="../temp/lock/backup" />
+							</properties>
+						</persister>
+					</lock-manager>
+				</workspace>
+				<workspace name="gadgets">
+					<!-- for system storage -->
+					<container
+						class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+						<properties>
+							<property name="source-name" value="jdbcexo" />
+							<property name="dialect" value="MySQL" />
+							<!--<property name="dialect" value="hsqldb"/> -->
+							<property name="multi-db" value="false" />
+							<property name="update-storage" value="true" />
+							<property name="max-buffer-size" value="200k" />
+							<property name="swap-directory" value="../temp/swap/gadgets" />
+						</properties>
+						<value-storages>
+							<value-storage id="gadgets"
+								class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+								<properties>
+									<property name="path" value="../temp/values/gadgets" />
+								</properties>
+								<filters>
+									<filter property-type="Binary" />
+								</filters>
+							</value-storage>
+						</value-storages>
+					</container>
+					<initializer
+						class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+						<properties>
+							<property name="root-nodetype" value="nt:unstructured" />
+							<property name="root-permissions"
+								value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+						</properties>
+					</initializer>
+					<cache enabled="true"
+						class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+						<properties>
+							<property name="max-size" value="20k" />
+							<property name="live-time" value="1h" />
+						</properties>
+					</cache>
+<!--					<query-handler-->
+<!--						class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">-->
+<!--						<properties>-->
+<!--							<property name="index-dir" value="../temp/jcrlucenedb/gadgets" />-->
+<!--						</properties>-->
+<!--					</query-handler>-->
+					<lock-manager>
+						<time-out>15m</time-out><!-- 15min -->
+						<persister
+							class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+							<properties>
+								<property name="path" value="../temp/lock/gadgets" />
+							</properties>
+						</persister>
+					</lock-manager>
+				</workspace>
+			</workspaces>
+		</repository>
+		<repository name="repository2" system-workspace="system"
+			default-workspace="collaboration">
+			<security-domain>exo-domain</security-domain>
+			<access-control>optional</access-control>
+			<authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+			<workspaces>
+				<workspace name="system">
+					<container
+						class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+						<properties>
+							<property name="source-name" value="jdbcexo" />
+							<property name="dialect" value="MySQL" />
+							<!--<property name="dialect" value="hsqldb"/>-->
+							<property name="multi-db" value="false" />
+							<property name="max-buffer-size" value="200k" />
+							<property name="swap-directory" value="../temp/swap/system" />
+						</properties>
+						<value-storages>
+							<value-storage id="system"
+								class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+								<properties>
+									<property name="path" value="../temp/values/system" />
+								</properties>
+								<filters>
+									<filter property-type="Binary" />
+								</filters>
+							</value-storage>
+						</value-storages>
+					</container>
+					<initializer
+						class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+						<properties>
+							<property name="root-nodetype" value="nt:unstructured" />
+							<property name="root-permissions"
+								value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+						</properties>
+					</initializer>
+					<cache enabled="true"
+						class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+						<properties>
+							<property name="max-size" value="20k" />
+							<property name="live-time" value="1h" />
+						</properties>
+					</cache>
+<!--					<query-handler-->
+<!--						class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">-->
+<!--						<properties>-->
+<!--							<property name="index-dir" value="../temp/jcrlucenedb/system2" />-->
+<!--							<property name="support-highlighting" value="true" />-->
+<!--							<property name="excerptprovider-class"-->
+<!--								value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt" />-->
+<!--						</properties>-->
+<!--					</query-handler>-->
+					<lock-manager>
+						<time-out>15m</time-out>
+						<persister
+							class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+							<properties>
+								<property name="path" value="../temp/lock/system" />
+							</properties>
+						</persister>
+					</lock-manager>
+				</workspace>
+				<workspace name="collaboration">
+					<container
+						class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+						<properties>
+							<property name="source-name" value="jdbcexo" />
+							<property name="dialect" value="MySQL" />
+							<!--<property name="dialect" value="hsqldb"/> -->
+							<property name="multi-db" value="false" />
+							<property name="max-buffer-size" value="200k" />
+							<property name="swap-directory" value="../temp/swap/collaboration" />
+						</properties>
+						<value-storages>
+							<value-storage id="collaboration"
+								class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+								<properties>
+									<property name="path" value="../temp/values/collaboration" />
+								</properties>
+								<filters>
+									<filter property-type="Binary" />
+								</filters>
+							</value-storage>
+						</value-storages>
+					</container>
+					<initializer
+						class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+						<properties>
+							<property name="root-nodetype" value="nt:unstructured" />
+							<property name="root-permissions"
+								value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+						</properties>
+					</initializer>
+					<cache enabled="true"
+						class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+						<properties>
+							<property name="max-size" value="20k" />
+							<property name="live-time" value="1h" />
+						</properties>
+					</cache>
+<!--					<query-handler-->
+<!--						class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">-->
+<!--						<properties>-->
+<!--							<property name="index-dir" value="../temp/jcrlucenedb/collaboration2" />-->
+<!--							<property name="support-highlighting" value="true" />-->
+<!--							<property name="excerptprovider-class"-->
+<!--								value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt" />-->
+<!--						</properties>-->
+<!--					</query-handler>-->
+					<lock-manager>
+						<time-out>15m</time-out>
+						<persister
+							class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+							<properties>
+								<property name="path" value="../temp/lock/collaboration" />
+							</properties>
+						</persister>
+					</lock-manager>
+				</workspace>
+				<workspace name="backup">
+					<container
+						class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+						<properties>
+							<property name="source-name" value="jdbcexo" />
+							<property name="dialect" value="MySQL" />
+							<!--<property name="dialect" value="hsqldb"/> -->
+							<property name="multi-db" value="false" />
+							<property name="max-buffer-size" value="200k" />
+							<property name="swap-directory" value="../temp/swap/backup" />
+						</properties>
+						<value-storages>
+							<value-storage id="backup"
+								class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+								<properties>
+									<property name="path" value="../temp/values/backup" />
+								</properties>
+								<filters>
+									<filter property-type="Binary" />
+								</filters>
+							</value-storage>
+						</value-storages>
+					</container>
+					<initializer
+						class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+						<properties>
+							<property name="root-nodetype" value="nt:unstructured" />
+							<property name="root-permissions"
+								value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+						</properties>
+					</initializer>
+					<cache enabled="true"
+						class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+						<properties>
+							<property name="max-size" value="5k" />
+							<property name="live-time" value="20m" />
+						</properties>
+					</cache>
+<!--					<query-handler-->
+<!--						class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">-->
+<!--						<properties>-->
+<!--							<property name="index-dir" value="../temp/jcrlucenedb/backup2" />-->
+<!--							<property name="support-highlighting" value="true" />-->
+<!--							<property name="excerptprovider-class"-->
+<!--								value="org.exoplatform.services.jcr.impl.core.query.lucene.DefaultHTMLExcerpt" />-->
+<!--						</properties>-->
+<!--					</query-handler>-->
+					<lock-manager>
+						<time-out>15m</time-out>
+						<persister
+							class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+							<properties>
+								<property name="path" value="../temp/lock/backup" />
+							</properties>
+						</persister>
+					</lock-manager>
+				</workspace>
+				<workspace name="gadgets">
+					<!-- for system storage -->
+					<container
+						class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+						<properties>
+							<property name="source-name" value="jdbcexo" />
+							<property name="dialect" value="MySQL" />
+							<!--<property name="dialect" value="hsqldb"/> -->
+							<property name="multi-db" value="false" />
+							<property name="update-storage" value="true" />
+							<property name="max-buffer-size" value="200k" />
+							<property name="swap-directory" value="../temp/swap/gadgets" />
+						</properties>
+						<value-storages>
+							<value-storage id="gadgets"
+								class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+								<properties>
+									<property name="path" value="../temp/values/gadgets" />
+								</properties>
+								<filters>
+									<filter property-type="Binary" />
+								</filters>
+							</value-storage>
+						</value-storages>
+					</container>
+					<initializer
+						class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+						<properties>
+							<property name="root-nodetype" value="nt:unstructured" />
+							<property name="root-permissions"
+								value="any read;*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+						</properties>
+					</initializer>
+					<cache enabled="true"
+						class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+						<properties>
+							<property name="max-size" value="20k" />
+							<property name="live-time" value="1h" />
+						</properties>
+					</cache>
+<!--					<query-handler-->
+<!--						class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">-->
+<!--						<properties>-->
+<!--							<property name="index-dir" value="../temp/jcrlucenedb/gadgets2" />-->
+<!--						</properties>-->
+<!--					</query-handler>-->
+					<lock-manager>
+						<time-out>15m</time-out><!-- 15min -->
+						<persister
+							class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+							<properties>
+								<property name="path" value="../temp/lock/gadgets" />
+							</properties>
+						</persister>
+					</lock-manager>
+				</workspace>
+			</workspaces>
+		</repository>		
+	</repositories>
+</repository-service>


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/sql-benchmark-jcr-config.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/test-jbosscache-config.xml
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/test-jbosscache-config.xml	2010-01-11 15:57:12 UTC (rev 1346)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/resources/conf/standalone/test-jbosscache-config.xml	2010-01-11 16:18:42 UTC (rev 1347)
@@ -12,11 +12,11 @@
    <!-- Eviction configuration -->
    <eviction wakeUpInterval="5000">
       <default algorithmClass="org.jboss.cache.eviction.LRUAlgorithm">
-         <property name="maxNodes" value="5000" />
+         <property name="maxNodes" value="50" />
          <property name="timeToLiveSeconds" value="120" />
       </default>
       <region name="/" algorithmClass="org.jboss.cache.eviction.LRUAlgorithm" actionPolicyClass="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.ChildListEvictionActionPolicy" eventQueueSize="1000000">
-         <property name="maxNodes" value="5000" />
+         <property name="maxNodes" value="50" />
          <property name="timeToLiveSeconds" value="120" />
       </region>
    </eviction>



More information about the exo-jcr-commits mailing list