Author: tolusha
Date: 2011-02-03 02:32:17 -0500 (Thu, 03 Feb 2011)
New Revision: 3915
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/Indexable.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/NodeDataIndexingIterator.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
Log:
EXOJCR-1104: rely on JDBCStorageConnection class
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/Indexable.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/Indexable.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/Indexable.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -18,9 +18,8 @@
*/
package org.exoplatform.services.jcr.impl.core.query;
-import java.io.IOException;
+import javax.jcr.RepositoryException;
-
/**
* Created by The eXo Platform SAS.
*
@@ -31,5 +30,5 @@
*/
public interface Indexable
{
- NodeDataIndexingIterator getNodeDataIndexingIterator() throws IOException;
+ NodeDataIndexingIterator getNodeDataIndexingIterator(int pageSize) throws
RepositoryException;
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/NodeDataIndexingIterator.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/NodeDataIndexingIterator.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/NodeDataIndexingIterator.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -20,9 +20,10 @@
import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
-import java.io.IOException;
-import java.util.NoSuchElementException;
+import java.util.List;
+import javax.jcr.RepositoryException;
+
/**
* Created by The eXo Platform SAS.
*
@@ -33,10 +34,9 @@
*/
public interface NodeDataIndexingIterator
{
-
/**
* Returns <tt>true</tt> if the iteration has more elements. (In other
- * words, returns <tt>true</tt> if <tt>next</tt> would return
an element
+ * words, returns <tt>true</tt> if <tt>next</tt> would return
element
* rather than throwing an exception.)
*
* @return <tt>true</tt> if the iterator has more elements.
@@ -44,15 +44,10 @@
boolean hasNext();
/**
- * Returns the next element in the iteration.
+ * Returns the next list of elements in the iteration.
*
- * @return the next element in the iteration.
- * @exception NoSuchElementException iteration has no more elements.
+ * @return the next list of elements in the iteration
+ * @throws RepositoryException if any exception occurred
*/
- NodeDataIndexing next() throws IOException;
-
- /**
- * Closes the iterator and releases all resources.
- */
- void close() throws IOException;
+ List<NodeDataIndexing> next() throws RepositoryException;
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -1479,13 +1479,11 @@
private long createIndex(Indexable indexableComponent, NodeData rootNode,
ItemDataConsumer stateMgr, long count)
throws IOException, RepositoryException
{
- NodeDataIndexingIterator iterator =
indexableComponent.getNodeDataIndexingIterator();
- try
+ NodeDataIndexingIterator iterator =
indexableComponent.getNodeDataIndexingIterator(1000);
+ while (iterator.hasNext())
{
- while (iterator.hasNext())
+ for (NodeDataIndexing node : iterator.next())
{
- NodeDataIndexing node = iterator.next();
-
if (indexingTree.isExcluded(node))
{
continue;
@@ -1509,10 +1507,6 @@
checkVolatileCommit();
}
}
- finally
- {
- iterator.close();
- }
return count;
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/DBConstants.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -189,6 +189,11 @@
*/
protected String DELETE_REF;
+ /**
+ * FIND_NODES.
+ */
+ protected String FIND_NODES_AND_PROPERTIES;
+
// ======================== ITEMS table ========================
/**
* COLUMN_ID.
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -30,6 +30,7 @@
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.ItemType;
import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
@@ -59,8 +60,15 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
import java.util.StringTokenizer;
+import java.util.TreeSet;
import javax.jcr.InvalidItemStateException;
import javax.jcr.PropertyType;
@@ -185,6 +193,8 @@
protected PreparedStatement renameNode;
+ protected PreparedStatement findNodesAndProperties;
+
/**
* Read-only flag, if true the connection is marked as READ-ONLY.
*/
@@ -543,6 +553,11 @@
{
renameNode.close();
}
+
+ if (findNodesAndProperties != null)
+ {
+ findNodesAndProperties.close();
+ }
}
catch (SQLException e)
{
@@ -999,6 +1014,79 @@
/**
* {@inheritDoc}
*/
+ public List<NodeDataIndexing> getNodesAndProperties(int offset, int limit)
throws RepositoryException,
+ IllegalStateException
+ {
+ List<NodeDataIndexing> result = new ArrayList<NodeDataIndexing>();
+
+ checkIfOpened();
+ try
+ {
+ ResultSet resultSet = findNodesAndProperties(offset, limit);
+ try
+ {
+ TempNodeData tempNodeData = null;
+ while (resultSet.next())
+ {
+ if (tempNodeData == null)
+ {
+ tempNodeData = new TempNodeData(resultSet);
+ }
+ else if (!resultSet.getString(COLUMN_ID).equals(tempNodeData.cid))
+ {
+ result.add(createNodeData(tempNodeData));
+
+ tempNodeData = new TempNodeData(resultSet);
+ }
+
+ String key = resultSet.getString("P_NAME");
+
+ SortedSet<TempPropertyData> values =
tempNodeData.properties.get(key);
+ if (values == null)
+ {
+ values = new TreeSet<TempPropertyData>();
+ tempNodeData.properties.put(key, values);
+ }
+
+ values.add(new ExtendedTempPropertyData(resultSet));
+ }
+
+ if (tempNodeData != null)
+ {
+ result.add(createNodeData(tempNodeData));
+ }
+ }
+ finally
+ {
+ try
+ {
+ resultSet.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the ResultSet: " + e);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException(e);
+ }
+ catch (IllegalNameException e)
+ {
+ throw new RepositoryException(e);
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<PropertyData> listChildPropertiesData(NodeData parent) throws
RepositoryException, IllegalStateException
{
checkIfOpened();
@@ -2443,6 +2531,205 @@
}
}
+ /**
+ * Build node data and its properties data from temporary stored info.
+ *
+ * @return NodeDataIndexing
+ * @throws RepositoryException
+ * @throws IOException
+ * @throws SQLException
+ * @throws IllegalNameException
+ */
+ protected NodeDataIndexing createNodeData(TempNodeData tempNode) throws
RepositoryException, SQLException,
+ IOException, IllegalNameException
+ {
+ QPath parentPath;
+ String parentCid;
+
+ if (tempNode.cpid.equals(Constants.ROOT_PARENT_UUID))
+ {
+ // root node
+ parentPath = Constants.ROOT_PATH;
+ parentCid = null;
+ }
+ else
+ {
+ parentPath =
+ QPath.makeChildPath(traverseQPath(tempNode.cpid),
InternalQName.parse(tempNode.cname), tempNode.cindex);
+ parentCid = tempNode.cpid;
+ }
+
+ // primary type
+ SortedSet<TempPropertyData> primaryTypeTempProp =
+ tempNode.properties.get(Constants.JCR_PRIMARYTYPE.getAsString());
+ if (primaryTypeTempProp == null)
+ {
+ throw new PrimaryTypeNotFoundException("FATAL ERROR primary type record not
found. Node "
+ + parentPath.getAsString() + ", id " + tempNode.cid + ",
container " + this.containerName, null);
+ }
+
+ byte[] data = primaryTypeTempProp.first().getAsByteArray();
+ primaryTypeTempProp.first().data = new ByteArrayInputStream(data);
+
+ InternalQName ptName =
+ InternalQName.parse(new String((data != null ? data : new byte[]{}),
Constants.DEFAULT_ENCODING));
+
+ // mixins
+ List<InternalQName> mixins = new ArrayList<InternalQName>();
+ Set<TempPropertyData> mixinsTempProps =
tempNode.properties.get(Constants.JCR_MIXINTYPES.getAsString());
+ if (mixinsTempProps != null)
+ {
+
+ for (TempPropertyData mxnb : mixinsTempProps)
+ {
+ data = mxnb.getAsByteArray();
+ mxnb.data = new ByteArrayInputStream(data);
+
+ mixins.add(InternalQName.parse(new String(data,
Constants.DEFAULT_ENCODING)));
+ }
+ }
+
+ // build node data
+ NodeData nodeData =
+ new PersistedNodeData(getIdentifier(tempNode.cid), parentPath,
getIdentifier(parentCid), tempNode.cversion,
+ tempNode.cnordernumb, ptName, mixins.toArray(new
InternalQName[mixins.size()]), null);
+
+ List<PropertyData> childProps = new ArrayList<PropertyData>();
+
+ for (String propName : tempNode.properties.keySet())
+ {
+ ExtendedTempPropertyData prop =
(ExtendedTempPropertyData)tempNode.properties.get(propName).first();
+ String identifier = getIdentifier(prop.id);
+
+ // read values
+ List<ValueData> valueData = new ArrayList<ValueData>();
+ for (TempPropertyData tempProp : tempNode.properties.get(propName))
+ {
+ ExtendedTempPropertyData extTempProp = (ExtendedTempPropertyData)tempProp;
+
+ ValueData vdata =
+ extTempProp.storage_desc == null ? readValueData(extTempProp.id,
extTempProp.orderNum,
+ extTempProp.version, extTempProp.data) : readValueData(identifier,
extTempProp.orderNum,
+ extTempProp.storage_desc);
+
+ valueData.add(vdata);
+ }
+ Collections.sort(valueData, COMPARATOR_VALUE_DATA);
+
+ QPath qpath = QPath.makeChildPath(parentPath, InternalQName.parse(prop.name));
+
+ // build property data
+ PropertyData pdata =
+ new PersistedPropertyData(identifier, qpath, tempNode.cid, prop.version,
prop.type, prop.multi,
+ valueData);
+
+ childProps.add(pdata);
+ }
+
+ return new NodeDataIndexing(nodeData, childProps);
+ }
+
+ /**
+ * Class needed temporary to store node data info.
+ */
+ protected class TempNodeData
+ {
+ public String cid;
+
+ public String cname;
+
+ public int cversion;
+
+ public String cpid;
+
+ public int cindex;
+
+ public int cnordernumb;
+
+ public Map<String, SortedSet<TempPropertyData>> properties = new
HashMap<String, SortedSet<TempPropertyData>>();
+
+ 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);
+ }
+ }
+
+ /**
+ * Class needs temporary to store value info.
+ */
+ protected class TempPropertyData implements Comparable<TempPropertyData>
+ {
+ public int orderNum;
+
+ public InputStream data;
+
+ public TempPropertyData(ResultSet item) throws SQLException
+ {
+ orderNum = item.getInt(COLUMN_VORDERNUM);
+ data = item.getBinaryStream(COLUMN_VDATA);
+ }
+
+ public byte[] getAsByteArray() throws IOException
+ {
+ byte[] readBuffer = new byte[data.available()];
+ data.read(readBuffer);
+
+ return readBuffer;
+ }
+
+ public int compareTo(TempPropertyData o)
+ {
+ return orderNum - o.orderNum;
+ }
+ }
+
+ /**
+ * Class needs temporary to store whole property data info.
+ */
+ protected class ExtendedTempPropertyData extends TempPropertyData
+ {
+ public String id;
+
+ public String name;
+
+ public int version;
+
+ public int type;
+
+ boolean multi;
+
+ public String storage_desc;
+
+ public ExtendedTempPropertyData(ResultSet item) throws SQLException
+ {
+ super(item);
+
+ id = item.getString("P_ID");
+ name = item.getString("P_NAME");
+ version = item.getInt("P_VERSION");
+ type = item.getInt("P_TYPE");
+ multi = item.getBoolean("P_MULTIVALUED");
+ storage_desc = item.getString(COLUMN_VSTORAGE_DESC);
+ }
+ }
+
+ /**
+ * The comparator used to sort the value data
+ */
+ protected static Comparator<ValueData> COMPARATOR_VALUE_DATA = new
Comparator<ValueData>()
+ {
+
+ public int compare(ValueData vd1, ValueData vd2)
+ {
+ return vd1.getOrderNumber() - vd2.getOrderNumber();
+ }
+ };
+
protected abstract int addNodeRecord(NodeData data) throws SQLException;
protected abstract int addPropertyRecord(PropertyData prop) throws SQLException;
@@ -2459,6 +2746,8 @@
protected abstract ResultSet findChildPropertiesByParentIdentifier(String
parentIdentifier) throws SQLException;
+ protected abstract ResultSet findNodesAndProperties(int offset, int limit) throws
SQLException;
+
protected abstract int addReference(PropertyData data) throws SQLException,
IOException;
protected abstract int renameNode(NodeData data) throws SQLException;
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -1425,7 +1425,7 @@
/**
* {@inheritDoc}
*/
- public NodeDataIndexingIterator getNodeDataIndexingIterator() throws IOException
+ public NodeDataIndexingIterator getNodeDataIndexingIterator(int pageSize) throws
RepositoryException
{
try
{
@@ -1441,17 +1441,21 @@
return ds.getConnection();
}
});
- return new JdbcNodeDataIndexingIterator(jdbcConn, multiDb, containerName,
swapCleaner, maxBufferSize,
- swapDirectory, valueStorageProvider);
+
+ return new JdbcNodeDataIndexingIterator(connFactory, pageSize);
}
else
{
throw new NameNotFoundException("Data source " + dbSourceName +
" not found");
}
}
- catch (Exception e)
+ catch (SQLException e)
{
- throw new IOException(e);
+ throw new RepositoryException(e);
}
+ catch (NamingException e)
+ {
+ throw new RepositoryException(e);
+ }
}
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -74,6 +74,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected String getIdentifier(final String internalId)
{
return internalId;
@@ -82,6 +83,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected String getInternalId(final String identifier)
{
return identifier;
@@ -150,6 +152,13 @@
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=?";
+
+ FIND_NODES_AND_PROPERTIES =
+ "select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX,
I.N_ORDER_NUM,"
+ + " P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE,
P.P_MULTIVALUED,"
+ + " V.DATA, V.ORDER_NUM, V.STORAGE_DESC"
+ + " from JCR_MITEM I, JCR_MITEM P, JCR_MVALUE V where I.I_CLASS=1
and"
+ + " P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by ID";
}
/**
@@ -293,6 +302,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findItemByName(String parentId, String name, int index) throws
SQLException
{
if (findItemByName == null)
@@ -402,6 +412,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int addValueData(String cid, int orderNumber, InputStream stream, int
streamLength, String storageDesc)
throws SQLException
{
@@ -431,6 +442,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int deleteValueData(String cid) throws SQLException
{
if (deleteValue == null)
@@ -445,6 +457,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findValuesByPropertyId(String cid) throws SQLException
{
if (findValuesByPropertyId == null)
@@ -459,6 +472,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws
SQLException
{
if (findValueByPropertyIdOrderNumber == null)
@@ -507,4 +521,22 @@
findValuesStorageDescriptorsByPropertyId.setString(1, cid);
return findValuesStorageDescriptorsByPropertyId.executeQuery();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ResultSet findNodesAndProperties(int offset, int limit) throws SQLException
+ {
+ if (findNodesAndProperties == null)
+ {
+ findNodesAndProperties =
dbConnection.prepareStatement(FIND_NODES_AND_PROPERTIES);
+ }
+ else
+ {
+ findNodesAndProperties.clearParameters();
+ }
+
+ return findNodesAndProperties.executeQuery();
+ }
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -72,6 +72,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected String getInternalId(final String identifier)
{
return containerName + identifier;
@@ -80,6 +81,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected String getIdentifier(final String internalId)
{
@@ -158,6 +160,13 @@
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=?";
+
+ FIND_NODES_AND_PROPERTIES =
+ "select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX,
I.N_ORDER_NUM,"
+ + " P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE,
P.P_MULTIVALUED,"
+ + " V.DATA, V.ORDER_NUM, V.STORAGE_DESC"
+ + " from JCR_SITEM I, JCR_SITEM P, JCR_SVALUE V where I.I_CLASS=1 and
I.CONTAINER_NAME=? and"
+ + " P.I_CLASS=2 and P.CONTAINER_NAME=? and P.PARENT_ID=I.ID" +
" and V.PROPERTY_ID=P.ID order by ID";
}
/**
@@ -416,6 +425,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int addValueData(String cid, int orderNumber, InputStream stream, int
streamLength, String storageDesc)
throws SQLException
{
@@ -445,6 +455,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int deleteValueData(String cid) throws SQLException
{
if (deleteValue == null)
@@ -459,6 +470,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findValuesByPropertyId(String cid) throws SQLException
{
if (findValuesByPropertyId == null)
@@ -489,6 +501,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws
SQLException
{
if (findValueByPropertyIdOrderNumber == null)
@@ -529,4 +542,25 @@
renameNode.setString(6, getInternalId(data.getIdentifier()));
return renameNode.executeUpdate();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ResultSet findNodesAndProperties(int offset, int limit) throws SQLException
+ {
+ if (findNodesAndProperties == null)
+ {
+ findNodesAndProperties =
dbConnection.prepareStatement(FIND_NODES_AND_PROPERTIES);
+ }
+ else
+ {
+ findNodesAndProperties.clearParameters();
+ }
+
+ findNodesAndProperties.setString(1, containerName);
+ findNodesAndProperties.setString(2, containerName);
+
+ return findNodesAndProperties.executeQuery();
+ }
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -18,52 +18,17 @@
*/
package org.exoplatform.services.jcr.impl.storage.jdbc.indexing;
-import org.exoplatform.commons.utils.PrivilegedFileHelper;
-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.InternalQName;
-import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.NodeDataIndexing;
-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.query.NodeDataIndexingIterator;
-import
org.exoplatform.services.jcr.impl.dataflow.persistent.ByteArrayPersistedValueData;
-import
org.exoplatform.services.jcr.impl.dataflow.persistent.CleanableFilePersistedValueData;
-import org.exoplatform.services.jcr.impl.storage.jdbc.DBConstants;
-import org.exoplatform.services.jcr.impl.storage.jdbc.PrimaryTypeNotFoundException;
-import org.exoplatform.services.jcr.impl.storage.value.ValueStorageNotFoundException;
-import org.exoplatform.services.jcr.impl.storage.value.fs.operations.ValueFileIOHelper;
-import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
-import org.exoplatform.services.jcr.impl.util.io.SwapFile;
-import org.exoplatform.services.jcr.storage.value.ValueIOChannel;
-import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
+import org.exoplatform.services.jcr.impl.storage.jdbc.db.GenericConnectionFactory;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import javax.jcr.InvalidItemStateException;
+import javax.jcr.RepositoryException;
/**
* Created by The eXo Platform SAS.
@@ -75,122 +40,43 @@
* @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy
Bazko</a>
* @version $Id: JdbcIndexingDataIterator.java 34360 2010-11-11 11:11:11Z tolusha $
*/
-public class JdbcNodeDataIndexingIterator extends DBConstants implements
NodeDataIndexingIterator
+public class JdbcNodeDataIndexingIterator implements NodeDataIndexingIterator
{
/**
- * Logger.
+ * Connection factory. Allows to open jdbc storage connection.
*/
- protected static final Log LOG =
ExoLogger.getLogger("exo.jcr.component.core.JdbcIndexingDataIterator");
+ private final GenericConnectionFactory connFactory;
/**
- * Connection to the database. Should be released on close.
+ * The amount of the rows which could be retrieved from database for once.
*/
- private final Connection jdbcConn;
+ private final int pageSize;
/**
- * Temporary used prepared statement for query execution. Should be released on
close.
+ * The current offset in database.
*/
- private PreparedStatement st = null;
+ private int offset = 0;
/**
- * Temporary used prepared statement. Should be released on close.
+ * Logger.
*/
- private PreparedStatement findItemQPathByIdentifierCQ;
+ protected static final Log LOG =
ExoLogger.getLogger("exo.jcr.component.core.JdbcIndexingDataIterator");
/**
- * Temporary used result set during fetching data. Should be released on close.
+ * The list of nodes to return in next() method.
*/
- private ResultSet resultSet = null;
+ private List<NodeDataIndexing> current;
/**
- * Connection to the database. Should be released on close.
- */
- private TempNodeData data = null;
-
- /**
- * Indicates if mulit db is used or not.
- */
- private final boolean multiDb;
-
- /**
- * Container name.
- */
- private final String containerName;
-
- /**
- * The File Cleaner.
- */
- private final FileCleaner swapCleaner;
-
- /**
- * Maximum buffer size.
- */
- private final int maxBufferSize;
-
- /**
- * Swap directory.
- */
- private final File swapDirectory;
-
- /**
- * Value storage provider.
- */
- private final ValueStoragePluginProvider valueStorageProvider;
-
- /**
- * The next node data to return in next() method.
- */
- private NodeDataIndexing nextNode = null;
-
- /**
- * Search query for single db.
- */
- private static final String FIND_NODES_SINGLE_DB =
- "select I.ID AS N_ID, I.PARENT_ID AS N_PARENT_ID, I.NAME AS N_NAME, I.VERSION
AS N_VERSION, I.I_INDEX AS N_I_INDEX, I.N_ORDER_NUM, "
- + "P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE,
P.P_MULTIVALUED, "
- + "V.DATA, V.ORDER_NUM, V.STORAGE_DESC"
- + " from JCR_SITEM I, JCR_SITEM P, JCR_SVALUE V where I.I_CLASS=1 and
I.CONTAINER_NAME=? and"
- + " P.I_CLASS=2 and P.CONTAINER_NAME=? and P.PARENT_ID=I.ID" + "
and V.PROPERTY_ID=P.ID order by N_ID";
-
- /**
- * Search query for multi db.
- */
- private static final String FIND_NODES_MULTI_DB =
- "select I.ID AS N_ID, I.PARENT_ID AS N_PARENT_ID, I.NAME AS N_NAME, I.VERSION
AS N_VERSION, I.I_INDEX AS N_I_INDEX, I.N_ORDER_NUM, "
- + "P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE,
P.P_MULTIVALUED, "
- + "V.DATA, V.ORDER_NUM, V.STORAGE_DESC"
- + " from JCR_MITEM I, JCR_MITEM P, JCR_MVALUE V where I.I_CLASS=1
and"
- + " P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by N_ID";
-
- /**
* Constructor JdbcIndexingDataIterator.
*
*/
- public JdbcNodeDataIndexingIterator(Connection jdbcConn, boolean multiDb, String
containerName, FileCleaner swapCleaner,
- int maxBufferSize, File swapDirectory, ValueStoragePluginProvider
valueStorageProvider) throws SQLException,
- PrimaryTypeNotFoundException, InvalidItemStateException,
ValueStorageNotFoundException, IllegalNameException,
- IOException
+ public JdbcNodeDataIndexingIterator(GenericConnectionFactory connFactory, int
pageSize) throws RepositoryException
{
- this.jdbcConn = jdbcConn;
- this.multiDb = multiDb;
- this.containerName = containerName;
- this.swapCleaner = swapCleaner;
- this.maxBufferSize = maxBufferSize;
- this.swapDirectory = swapDirectory;
- this.valueStorageProvider = valueStorageProvider;
-
- String sql = multiDb ? FIND_NODES_MULTI_DB : FIND_NODES_SINGLE_DB;
- st = jdbcConn.prepareStatement(sql);
-
- if (!multiDb)
- {
- st.setString(1, containerName);
- st.setString(2, containerName);
- }
- resultSet = st.executeQuery();
-
- this.nextNode = readNext();
+ this.connFactory = connFactory;
+ this.pageSize = pageSize;
+ this.current = readNext();
}
/**
@@ -198,573 +84,38 @@
*/
public boolean hasNext()
{
- return this.nextNode != null;
+ return this.current.size() != 0;
}
/**
* {@inheritDoc}
*/
- public NodeDataIndexing next() throws IOException
+ public List<NodeDataIndexing> next() throws RepositoryException
{
- NodeDataIndexing current = this.nextNode;
+ List<NodeDataIndexing> next = this.current;
+ this.current = new ArrayList<NodeDataIndexing>();//readNext();
- try
- {
- this.nextNode = readNext();
- }
- catch (PrimaryTypeNotFoundException e)
- {
- throw new IOException(e);
- }
- catch (InvalidItemStateException e)
- {
- throw new IOException(e);
- }
- catch (ValueStorageNotFoundException e)
- {
- throw new IOException(e);
- }
- catch (SQLException e)
- {
- throw new IOException(e);
- }
- catch (IllegalNameException e)
- {
- throw new IOException(e);
- }
-
- return current;
+ return next;
}
/**
- * {@inheritDoc}
- */
- public void close() throws IOException
- {
- try
- {
- if (resultSet != null)
- {
- resultSet.close();
- }
-
- if (st != null)
- {
- st.close();
- }
-
- if (findItemQPathByIdentifierCQ != null)
- {
- findItemQPathByIdentifierCQ.close();
- }
-
- jdbcConn.close();
- }
- catch (SQLException e)
- {
- throw new IOException(e);
- }
- }
-
- /**
- * Read next node from database.
+ * Read next nodes from database.
*
- * @return NodeDataIndexing
+ * @return List<NodeDataIndexing>
+ * @throws RepositoryException
*/
- private NodeDataIndexing readNext() throws PrimaryTypeNotFoundException,
InvalidItemStateException,
- ValueStorageNotFoundException, SQLException, IllegalNameException, IOException
+ private List<NodeDataIndexing> readNext() throws RepositoryException
{
- while (resultSet.next())
- {
- if (data == null)
- {
- data = new TempNodeData(resultSet);
- readTempPropertyData();
- }
- else if (!resultSet.getString("N_ID").equals(data.cid))
- {
- NodeDataIndexing node = createNodeData(data);
-
- data = new TempNodeData(resultSet);
- readTempPropertyData();
-
- return node;
- }
- else
- {
- readTempPropertyData();
- }
- }
-
- if (data != null)
- {
- NodeDataIndexing node = createNodeData(data);
- data = null;
-
- return node;
- }
-
- return null;
- }
-
- /**
- * Read temporary property data.
- *
- * @throws SQLException
- */
- private void readTempPropertyData() throws SQLException
- {
- String key = resultSet.getString("P_NAME");
-
- SortedSet<TempPropertyData> values = data.properties.get(key);
- if (values == null)
- {
- values = new TreeSet<TempPropertyData>();
- data.properties.put(key, values);
- }
-
- values.add(new TempPropertyData(resultSet));
- }
-
- /**
- * Build node data and its properties data from temporary stored info.
- *
- * @return NodeDataIndexing
- */
- private NodeDataIndexing createNodeData(TempNodeData tempNode) throws
IllegalNameException,
- InvalidItemStateException, SQLException, PrimaryTypeNotFoundException, IOException,
ValueStorageNotFoundException
- {
- QPath parentPath;
- String parentCid;
-
- if (tempNode.cpid.equals(Constants.ROOT_PARENT_UUID))
- {
- // root node
- parentPath = Constants.ROOT_PATH;
- parentCid = null;
- }
- else
- {
- parentPath =
- QPath.makeChildPath(traverseQPath(tempNode.cpid),
InternalQName.parse(tempNode.cname), tempNode.cindex);
- parentCid = tempNode.cpid;
- }
-
- // primary type
- SortedSet<TempPropertyData> primaryTypeTempProp =
tempNode.properties.get(Constants.JCR_PRIMARYTYPE.getAsString());
- if (primaryTypeTempProp == null)
- {
- throw new PrimaryTypeNotFoundException("FATAL ERROR primary type record not
found. Node "
- + parentPath.getAsString() + ", id " + tempNode.cid + ",
container " + this.containerName, null);
- }
-
- ByteArrayInputStream ba =
((ByteArrayInputStream)primaryTypeTempProp.first().cdata);
- byte[] data = new byte[ba.available()];
- ba.read(data);
-
- primaryTypeTempProp.first().cdata = new ByteArrayInputStream(data);
-
- InternalQName ptName =
- InternalQName.parse(new String((data != null ? data : new byte[]{}),
Constants.DEFAULT_ENCODING));
-
- // mixins
- List<InternalQName> mixins = new ArrayList<InternalQName>();
- Set<TempPropertyData> mixinsTempProps =
tempNode.properties.get(Constants.JCR_MIXINTYPES.getAsString());
- if (mixinsTempProps != null)
- {
-
- for (TempPropertyData mxnb : mixinsTempProps)
- {
- ba = ((ByteArrayInputStream)mxnb.cdata);
- data = new byte[ba.available()];
- ba.read(data);
-
- mxnb.cdata = new ByteArrayInputStream(data);
-
- mixins.add(InternalQName.parse(new String(data,
Constants.DEFAULT_ENCODING)));
- }
- }
-
- // build node data
- NodeData nodeData =
- new PersistedNodeData(getIdentifier(tempNode.cid), parentPath,
getIdentifier(parentCid), tempNode.cversion,
- tempNode.cnordernumb, ptName, mixins.toArray(new
InternalQName[mixins.size()]), null);
-
- List<PropertyData> childProps = new ArrayList<PropertyData>();
-
- for (String propName : tempNode.properties.keySet())
- {
- TempPropertyData prop = tempNode.properties.get(propName).first();
- String identifier = getIdentifier(prop.cid);
-
- // read values
- List<ValueData> valueData = new ArrayList<ValueData>();
- for (TempPropertyData tempProp : tempNode.properties.get(propName))
- {
- ValueData vdata =
- tempProp.cstorage_desc == null ? readValueData(tempProp.cid,
tempProp.corderNum, tempProp.cversion,
- tempProp.cdata) : readValueData(identifier, tempProp.corderNum,
tempProp.cstorage_desc);
-
- valueData.add(vdata);
- }
- Collections.sort(valueData, COMPARATOR_VALUE_DATA);
-
- QPath qpath = QPath.makeChildPath(parentPath, InternalQName.parse(prop.cname));
-
- // build property data
- PropertyData pdata =
- new PersistedPropertyData(identifier, qpath, tempNode.cid, prop.cversion,
prop.ctype, prop.cmulti,
- valueData);
-
- childProps.add(pdata);
- }
-
- return new NodeDataIndexing(nodeData, childProps);
- }
-
- /**
- * Build Item path by id.
- *
- * @param cpid
- * - Item id (container id)
- * @return Item QPath
- * @throws SQLException
- * - if database error occurs
- * @throws InvalidItemStateException
- * - if parent not found
- * @throws IllegalNameException
- * - if name on the path is wrong
- */
- private QPath traverseQPath(String cpid) throws SQLException,
InvalidItemStateException, IllegalNameException
- {
- 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 = findItemQPathByIdentifier(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
- {
- if (result != null)
- {
- try
- {
- result.close();
- }
- catch (SQLException e)
- {
- LOG.error("Can't close the ResultSet: " + e);
- }
- }
- }
-
- 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);
- }
-
- /**
- * Invoke item identifier from internalId. In case of single db need to
- * remove prefix from internalId.
- *
- * @param internalId
- * the internal identifier
- */
- private String getIdentifier(final String internalId)
- {
- if (internalId == null)
- return null;
-
- return multiDb ? internalId : internalId.substring(containerName.length());
- }
-
- /**
- *
- * @param identifier
- * @return
- * @throws SQLException
- */
- private ResultSet findItemQPathByIdentifier(String identifier) throws SQLException
- {
- String findItemQPathByIdentifier;
- if (multiDb)
- {
- findItemQPathByIdentifier =
- "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";
- }
- else
- {
- findItemQPathByIdentifier =
- "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";
- }
-
- if (findItemQPathByIdentifierCQ == null)
- {
- findItemQPathByIdentifierCQ =
jdbcConn.prepareStatement(findItemQPathByIdentifier);
- }
- else
- {
- findItemQPathByIdentifierCQ.clearParameters();
- }
-
- findItemQPathByIdentifierCQ.setString(1, identifier);
- return findItemQPathByIdentifierCQ.executeQuery();
- }
-
- /**
- * Read ValueData from database.
- *
- * @param cid
- * property id
- * @param orderNumber
- * value order number
- * @param version
- * persistent version (used for BLOB swapping)
- * @param content
- * input stream
- * @return ValueData
- * @throws SQLException
- * database error
- * @throws IOException
- * I/O error (swap)
- */
- private ValueData readValueData(String cid, int orderNumber, int version, final
InputStream content)
- throws SQLException, IOException
- {
-
- byte[] buffer = new byte[0];
- byte[] spoolBuffer = new byte[ValueFileIOHelper.IOBUFFER_SIZE];
- int read;
- int len = 0;
- OutputStream out = null;
-
- SwapFile swapFile = null;
+ JDBCStorageConnection conn = (JDBCStorageConnection)connFactory.openConnection();
try
{
- // stream from database
- if (content != null)
- while ((read = content.read(spoolBuffer)) >= 0)
- {
- if (out != null)
- {
- // spool to temp file
- out.write(spoolBuffer, 0, read);
- len += read;
- }
- else if (len + read > maxBufferSize)
- {
- // threshold for keeping data in memory exceeded;
- // create temp file and spool buffer contents
- swapFile = SwapFile.get(swapDirectory, cid + orderNumber +
"." + version);
- if (swapFile.isSpooled())
- {
- // break, value already spooled
- buffer = null;
- break;
- }
- out = PrivilegedFileHelper.fileOutputStream(swapFile);
- out.write(buffer, 0, len);
- out.write(spoolBuffer, 0, read);
- buffer = null;
- len += read;
- }
- else
- {
- // reallocate new buffer and spool old buffer contents
- byte[] newBuffer = new byte[len + read];
- System.arraycopy(buffer, 0, newBuffer, 0, len);
- System.arraycopy(spoolBuffer, 0, newBuffer, len, read);
- buffer = newBuffer;
- len += read;
- }
- }
+ return conn.getNodesAndProperties(offset, pageSize);
+ // TODO offset + ?
}
finally
{
- if (out != null)
- {
- out.close();
- swapFile.spoolDone();
- }
+ conn.close();
}
-
- if (buffer == null)
- {
- return new CleanableFilePersistedValueData(orderNumber, swapFile, swapCleaner);
- }
-
- return new ByteArrayPersistedValueData(orderNumber, buffer);
}
-
- /**
- * Read ValueData from external storage.
- *
- * @param identifier
- * property identifier
- * @param orderNumber
- * value order number
- * @param storageId
- * external Value storage id
- * @return ValueData
- * @throws SQLException
- * database error
- * @throws IOException
- * I/O error
- * @throws ValueStorageNotFoundException
- * if no such storage found with Value storageId
- */
- private ValueData readValueData(String identifier, int orderNumber, String storageId)
throws SQLException,
- IOException, ValueStorageNotFoundException
- {
- ValueIOChannel channel = valueStorageProvider.getChannel(storageId);
- try
- {
- return channel.read(identifier, orderNumber, maxBufferSize);
- }
- finally
- {
- channel.close();
- }
- }
-
- /**
- * The comparator used to sort the value data
- */
- private static Comparator<ValueData> COMPARATOR_VALUE_DATA = new
Comparator<ValueData>()
- {
- public int compare(ValueData vd1, ValueData vd2)
- {
- return vd1.getOrderNumber() - vd2.getOrderNumber();
- }
- };
-
- /**
- * Class needed to store temporary node data.
- */
- private class TempNodeData
- {
- String cid;
-
- String cname;
-
- int cversion;
-
- String cpid;
-
- int cindex;
-
- int cnordernumb;
-
- Map<String, SortedSet<TempPropertyData>> properties = new
HashMap<String, SortedSet<TempPropertyData>>();
-
- public TempNodeData(ResultSet item) throws SQLException
- {
- cid = item.getString("N_ID");
- cname = item.getString("N_NAME");
- cversion = item.getInt("N_VERSION");
- cpid = item.getString("N_PARENT_ID");
- cindex = item.getInt("N_I_INDEX");
- cnordernumb = item.getInt("N_ORDER_NUM");
- }
- }
-
- /**
- * Class needs to store temporary property data.
- */
- private class TempPropertyData implements Comparable<TempPropertyData>
- {
- String cid;
-
- String cname;
-
- int cversion;
-
- int ctype;
-
- boolean cmulti;
-
- int corderNum;
-
- InputStream cdata;
-
- String cstorage_desc;
-
- public TempPropertyData(ResultSet item) throws SQLException
- {
- cid = item.getString("P_ID");
- cname = item.getString("P_NAME");
- cversion = item.getInt("P_VERSION");
- ctype = item.getInt("P_TYPE");
- cmulti = item.getBoolean("P_MULTIVALUED");
- cdata = item.getBinaryStream(COLUMN_VDATA);
- cstorage_desc = item.getString(COLUMN_VSTORAGE_DESC);
- corderNum = item.getInt(COLUMN_VORDERNUM);
- }
-
- public int compareTo(TempPropertyData o)
- {
- return corderNum - o.corderNum;
- }
- }
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -46,7 +46,6 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -101,69 +100,6 @@
protected PreparedStatement findItemQPathByIdentifierCQ;
/**
- * The comparator used to sort the value data
- */
- private static Comparator<ValueData> COMPARATOR_VALUE_DATA = new
Comparator<ValueData>()
- {
-
- public int compare(ValueData vd1, ValueData vd2)
- {
- return vd1.getOrderNumber() - vd2.getOrderNumber();
- }
- };
-
- /**
- * 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, SortedSet<TempPropertyData>> properties = new
HashMap<String, SortedSet<TempPropertyData>>();
-
- 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);
- }
- }
-
- /**
- * store temporary property data to allow to sort it manually
- */
- private static class TempPropertyData implements Comparable<TempPropertyData>
- {
- int orderNum;
-
- byte[] data;
-
- public TempPropertyData(ResultSet item) throws SQLException
- {
- orderNum = item.getInt(COLUMN_VORDERNUM);
- data = item.getBytes(COLUMN_VDATA);
- }
-
- public int compareTo(TempPropertyData o)
- {
- return orderNum - o.orderNum;
- }
- }
-
- /**
* JDBCStorageConnection constructor.
*
* @param dbConnection
@@ -191,6 +127,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public List<NodeData> getChildNodesData(NodeData parent) throws
RepositoryException, IllegalStateException
{
checkIfOpened();
@@ -257,6 +194,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public List<PropertyData> getChildPropertiesData(NodeData parent) throws
RepositoryException, IllegalStateException
{
checkIfOpened();
@@ -363,9 +301,10 @@
* @return list ACL
* @throws SQLException
* @throws IllegalACLException
+ * @throws IOException
*/
protected List<AccessControlEntry> readACLPermisions(String cid, Map<String,
SortedSet<TempPropertyData>> properties)
- throws SQLException, IllegalACLException
+ throws SQLException, IllegalACLException, IOException
{
List<AccessControlEntry> naPermissions = new
ArrayList<AccessControlEntry>();
Set<TempPropertyData> permValues =
properties.get(Constants.EXO_PERMISSIONS.getAsString());
@@ -374,7 +313,8 @@
{
for (TempPropertyData value : permValues)
{
- StringTokenizer parser = new StringTokenizer(new String(value.data),
AccessControlEntry.DELIMITER);
+ StringTokenizer parser =
+ new StringTokenizer(new String(value.getAsByteArray()),
AccessControlEntry.DELIMITER);
naPermissions.add(new AccessControlEntry(parser.nextToken(),
parser.nextToken()));
}
@@ -391,13 +331,14 @@
* @param properties - Property name and property values
* @return ACL owner
* @throws IllegalACLException
+ * @throws IOException
*/
protected String readACLOwner(String cid, Map<String,
SortedSet<TempPropertyData>> properties)
- throws IllegalACLException
+ throws IllegalACLException, IOException
{
SortedSet<TempPropertyData> ownerValues =
properties.get(Constants.EXO_OWNER.getAsString());
if (ownerValues != null)
- return new String(ownerValues.first().data);
+ return new String(ownerValues.first().getAsByteArray());
else
throw new IllegalACLException("Property exo:owner is not found for node
with id: " + getIdentifier(cid));
}
@@ -405,6 +346,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected PersistedNodeData loadNodeRecord(QPath parentPath, String cname, String cid,
String cpid, int cindex,
int cversion, int cnordernumb, AccessControlList parentACL) throws
RepositoryException, SQLException
{
@@ -426,6 +368,10 @@
return loadNodeRecord(parentPath, cname, cid, cpid, cindex, cversion,
cnordernumb, properties, parentACL);
}
+ catch (IOException e)
+ {
+ throw new RepositoryException(e);
+ }
finally
{
try
@@ -459,10 +405,11 @@
/**
* Create a new node from the given parameter.
+ * @throws IOException
*/
private PersistedNodeData loadNodeRecord(QPath parentPath, String cname, String cid,
String cpid, int cindex,
int cversion, int cnordernumb, Map<String, SortedSet<TempPropertyData>>
properties, AccessControlList parentACL)
- throws RepositoryException, SQLException
+ throws RepositoryException, SQLException, IOException
{
try
{
@@ -500,7 +447,7 @@
+ qpath.getAsString() + ", id " + cid + ", container "
+ this.containerName, null);
}
- byte[] data = primaryType.first().data;
+ byte[] data = primaryType.first().getAsByteArray();
InternalQName ptName = InternalQName.parse(new String((data != null ? data : new
byte[]{})));
// MIXIN
@@ -513,7 +460,7 @@
List<InternalQName> mNames = new ArrayList<InternalQName>();
for (TempPropertyData mxnb : mixTypes)
{
- InternalQName mxn = InternalQName.parse(new String(mxnb.data));
+ InternalQName mxn = InternalQName.parse(new
String(mxnb.getAsByteArray()));
mNames.add(mxn);
if (!privilegeable && Constants.EXO_PRIVILEGEABLE.equals(mxn))
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -86,6 +86,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected String getIdentifier(final String internalId)
{
return internalId;
@@ -94,6 +95,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected String getInternalId(final String identifier)
{
return identifier;
@@ -177,6 +179,13 @@
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=?";
+
+ FIND_NODES_AND_PROPERTIES =
+ "select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX,
I.N_ORDER_NUM,"
+ + " P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE,
P.P_MULTIVALUED,"
+ + " V.DATA, V.ORDER_NUM, V.STORAGE_DESC"
+ + " from JCR_MITEM I, JCR_MITEM P, JCR_MVALUE V where I.I_CLASS=1
and"
+ + " P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by ID";
}
/**
@@ -320,6 +329,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findItemByName(String parentId, String name, int index) throws
SQLException
{
if (findItemByName == null)
@@ -444,6 +454,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int addValueData(String cid, int orderNumber, InputStream stream, int
streamLength, String storageDesc)
throws SQLException
{
@@ -473,6 +484,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int deleteValueData(String cid) throws SQLException
{
if (deleteValue == null)
@@ -487,6 +499,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findValuesByPropertyId(String cid) throws SQLException
{
if (findValuesByPropertyId == null)
@@ -501,6 +514,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws
SQLException
{
if (findValueByPropertyIdOrderNumber == null)
@@ -596,4 +610,21 @@
return findItemQPathByIdentifierCQ.executeQuery();
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ResultSet findNodesAndProperties(int offset, int limit) throws SQLException
+ {
+ if (findNodesAndProperties == null)
+ {
+ findNodesAndProperties =
dbConnection.prepareStatement(FIND_NODES_AND_PROPERTIES);
+ }
+ else
+ {
+ findNodesAndProperties.clearParameters();
+ }
+
+ return findNodesAndProperties.executeQuery();
+ }
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2011-02-02
16:15:14 UTC (rev 3914)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2011-02-03
07:32:17 UTC (rev 3915)
@@ -84,6 +84,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected String getInternalId(final String identifier)
{
return containerName + identifier;
@@ -92,6 +93,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected String getIdentifier(final String internalId)
{
@@ -184,6 +186,13 @@
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=?";
+
+ FIND_NODES_AND_PROPERTIES =
+ "select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX,
I.N_ORDER_NUM,"
+ + " P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE,
P.P_MULTIVALUED,"
+ + " V.DATA, V.ORDER_NUM, V.STORAGE_DESC"
+ + " from JCR_SITEM I, JCR_SITEM P, JCR_SVALUE V where I.I_CLASS=1 and
I.CONTAINER_NAME=? and"
+ + " P.I_CLASS=2 and P.CONTAINER_NAME=? and P.PARENT_ID=I.ID" +
" and V.PROPERTY_ID=P.ID order by ID";
}
/**
@@ -442,6 +451,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int addValueData(String cid, int orderNumber, InputStream stream, int
streamLength, String storageDesc)
throws SQLException
{
@@ -471,6 +481,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected int deleteValueData(String cid) throws SQLException
{
if (deleteValue == null)
@@ -485,6 +496,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findValuesByPropertyId(String cid) throws SQLException
{
if (findValuesByPropertyId == null)
@@ -515,6 +527,7 @@
/**
* {@inheritDoc}
*/
+ @Override
protected ResultSet findValueByPropertyIdOrderNumber(String cid, int orderNumb) throws
SQLException
{
if (findValueByPropertyIdOrderNumber == null)
@@ -617,4 +630,25 @@
findItemQPathByIdentifierCQ.setString(1, identifier);
return findItemQPathByIdentifierCQ.executeQuery();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ResultSet findNodesAndProperties(int offset, int limit) throws SQLException
+ {
+ if (findNodesAndProperties == null)
+ {
+ findNodesAndProperties =
dbConnection.prepareStatement(FIND_NODES_AND_PROPERTIES);
+ }
+ else
+ {
+ findNodesAndProperties.clearParameters();
+ }
+
+ findNodesAndProperties.setString(1, containerName);
+ findNodesAndProperties.setString(2, containerName);
+
+ return findNodesAndProperties.executeQuery();
+ }
}