exo-jcr SVN: r4688 - in jcr/trunk/exo.jcr.component.core/src: test/java/org/exoplatform/services/jcr/api/writing and 1 other directory.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-07-29 10:37:45 -0400 (Fri, 29 Jul 2011)
New Revision: 4688
Modified:
jcr/trunk/exo.jcr.component.core/src/main/resources/conf/storage/jcr-mjdbc.mysql.sql
jcr/trunk/exo.jcr.component.core/src/main/resources/conf/storage/jcr-sjdbc.mysql.sql
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestAddNode.java
Log:
EXOJCR-1341 : fixed in way mysql-utf8 dialect does. Table columns in database that must be case-sensitive are created with right collation.
Modified: jcr/trunk/exo.jcr.component.core/src/main/resources/conf/storage/jcr-mjdbc.mysql.sql
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/resources/conf/storage/jcr-mjdbc.mysql.sql 2011-07-28 13:07:41 UTC (rev 4687)
+++ jcr/trunk/exo.jcr.component.core/src/main/resources/conf/storage/jcr-mjdbc.mysql.sql 2011-07-29 14:37:45 UTC (rev 4688)
@@ -5,7 +5,7 @@
CREATE TABLE JCR_MITEM(
ID VARCHAR(96) NOT NULL,
PARENT_ID VARCHAR(96) NOT NULL,
- NAME VARCHAR(512) NOT NULL,
+ NAME VARCHAR(512) CHARSET latin1 COLLATE latin1_general_cs NOT NULL,
VERSION INTEGER NOT NULL,
I_CLASS INTEGER NOT NULL,
I_INDEX INTEGER NOT NULL,
Modified: jcr/trunk/exo.jcr.component.core/src/main/resources/conf/storage/jcr-sjdbc.mysql.sql
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/resources/conf/storage/jcr-sjdbc.mysql.sql 2011-07-28 13:07:41 UTC (rev 4687)
+++ jcr/trunk/exo.jcr.component.core/src/main/resources/conf/storage/jcr-sjdbc.mysql.sql 2011-07-29 14:37:45 UTC (rev 4688)
@@ -5,7 +5,7 @@
CREATE TABLE JCR_SITEM(
ID VARCHAR(96) NOT NULL,
PARENT_ID VARCHAR(96) NOT NULL,
- NAME VARCHAR(512) NOT NULL,
+ NAME VARCHAR(512) CHARSET latin1 COLLATE latin1_general_cs NOT NULL,
VERSION INTEGER NOT NULL,
CONTAINER_NAME VARCHAR(96) NOT NULL,
I_CLASS INTEGER NOT NULL,
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestAddNode.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestAddNode.java 2011-07-28 13:07:41 UTC (rev 4687)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestAddNode.java 2011-07-29 14:37:45 UTC (rev 4688)
@@ -68,6 +68,25 @@
super.tearDown();
}
+ /**
+ * Test case-sensitive names
+ */
+ public void testAddNodeCSNames() throws RepositoryException
+ {
+ try
+ {
+ Node localRoot = root.addNode("testCI", "nt:folder");
+ root.save();
+ localRoot.addNode("test", "nt:folder");
+ localRoot.addNode("Test", "nt:folder");
+ root.save();
+ }
+ catch (ItemExistsException e)
+ {
+ fail("Repository must be case-sensitive!");
+ }
+ }
+
public void testAddNode() throws RepositoryException
{
Node root = session.getRootNode();
@@ -201,10 +220,14 @@
String[] wsNames = repository.getWorkspaceNames();
if (wsNames.length < 2)
+ {
fail("Too few number of ws for test should be > 1");
+ }
log.debug(">>>>>>>> " + wsNames.length);
for (int i = 0; i < wsNames.length; i++)
+ {
log.debug(">>>>>>>> " + wsNames[i]);
+ }
// Session s1 = repository.login(credentials, wsNames[0]);
Session s1 = repository.getSystemSession(wsNames[0]);
12 years, 9 months
exo-jcr SVN: r4687 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl: dataflow/session and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-07-28 09:07:41 -0400 (Thu, 28 Jul 2011)
New Revision: 4687
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
Log:
EXOJCR-1452: fix bugs
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-07-28 09:07:13 UTC (rev 4686)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-07-28 13:07:41 UTC (rev 4687)
@@ -3627,10 +3627,15 @@
Collections.sort(storedNodes, new NodeDataOrderComparator());
int size = storedNodes.size();
+
+ fromOrderNum =
+ size == 0 ? fromOrderNum + limit : Math.max(fromOrderNum + limit, storedNodes.get(size - 1)
+ .getOrderNumber() + 1);
+
+
+ // skip some nodes
if (size != 0)
{
- fromOrderNum = storedNodes.get(size - 1).getOrderNumber() + 1;
-
while (skip > 0 && storedNodes.size() > 0)
{
storedNodes.remove(0);
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-07-28 09:07:13 UTC (rev 4686)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-07-28 13:07:41 UTC (rev 4687)
@@ -985,31 +985,20 @@
{
NodeData data = (NodeData)state.getData();
+ // we have only last states, so remove nodes first
+ descendants.remove(data.getIdentifier());
+
if ((state.isAdded() || state.isRenamed()) && !hasNext)
{
descendants.put(data.getIdentifier(), data);
}
- else if (state.isDeleted())
+ else if (state.isMixinChanged() || state.isUpdated())
{
- descendants.remove(data.getIdentifier());
- }
- else if (state.isMixinChanged())
- {
- NodeData removedData = descendants.remove(data.getIdentifier());
- if (removedData != null)
+ if (minOrderNum <= data.getOrderNumber() && data.getOrderNumber() <= maxOrderNum)
{
descendants.put(data.getIdentifier(), data);
}
}
- else if (state.isUpdated())
- {
- NodeData removedData = descendants.remove(data.getIdentifier());
- if (removedData != null && minOrderNum <= data.getOrderNumber()
- && data.getOrderNumber() <= maxOrderNum)
- {
- descendants.put(data.getIdentifier(), data);
- }
- }
}
childs.clear();
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-07-28 09:07:13 UTC (rev 4686)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-07-28 13:07:41 UTC (rev 4687)
@@ -132,22 +132,14 @@
{
childs.remove(data);
}
- else if (state.isMixinChanged())
+ else if (state.isMixinChanged() || state.isUpdated())
{
- boolean isExists = childs.remove(state.getData());
- if (isExists)
+ childs.remove(state.getData());
+ if (minOrderNum <= data.getOrderNumber() && data.getOrderNumber() <= maxOrderNum)
{
childs.add(data);
}
}
- else if (state.isUpdated())
- {
- boolean isExists = childs.remove(state.getData());
- if (isExists && minOrderNum <= data.getOrderNumber() && data.getOrderNumber() <= maxOrderNum)
- {
- childs.add(data);
- }
- }
}
}
}
12 years, 9 months
exo-jcr SVN: r4686 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-07-28 05:07:13 -0400 (Thu, 28 Jul 2011)
New Revision: 4686
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
Log:
EXOJCR-1453: Adoption and testing on all supported DB
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-07-28 07:36:19 UTC (rev 4685)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-07-28 09:07:13 UTC (rev 4686)
@@ -51,6 +51,7 @@
import org.exoplatform.services.transaction.TransactionService;
import java.io.Serializable;
+import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
@@ -981,7 +982,15 @@
// The listeners will need to be executed outside the current tx so we suspend
// the current tx we can face enlistment issues on product like ISPN
transactionManager.suspend();
- notifySaveItems(logWrapper.getChangesLog(), false);
+
+ SecurityHelper.doPrivilegedAction(new PrivilegedAction<Void>()
+ {
+ public Void run()
+ {
+ notifySaveItems(logWrapper.getChangesLog(), false);
+ return null;
+ }
+ });
// Since the resume method could cause issue with some TM at this stage, we don't resume the tx
}
}
12 years, 9 months
exo-jcr SVN: r4685 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-07-28 03:36:19 -0400 (Thu, 28 Jul 2011)
New Revision: 4685
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/SingleDbJDBCConnection.java
Log:
EXOJCR-1453: Adoption and testing on all supported DB
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-07-28 06:01:42 UTC (rev 4684)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2011-07-28 07:36:19 UTC (rev 4685)
@@ -207,11 +207,13 @@
UPDATE_VALUE = "update JCR_MVALUE set DATA=?, STORAGE_DESC=? where PROPERTY_ID=? and ORDER_NUM=?";
FIND_NODES_BY_PARENTID_LAZILY_CQ =
- "select I.*, P.NAME AS PROP_NAME, V.ORDER_NUM, V.DATA"
- + " from JCR_MITEM I, JCR_MITEM P, JCR_MVALUE V"
+ "select I.*, P.NAME AS PROP_NAME, V.ORDER_NUM, V.DATA from JCR_MITEM I, JCR_MITEM P, JCR_MVALUE V"
+ " where I.I_CLASS=1 and I.PARENT_ID=? and I.N_ORDER_NUM >= ? and"
- + " P.I_CLASS=2 and P.PARENT_ID=I.ID 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 LIMIT ?";
+ + " P.I_CLASS=2 and P.PARENT_ID=I.ID 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";
}
/**
@@ -578,7 +580,7 @@
findNodesByParentIdLazilyCQ.setString(1, parentCid);
findNodesByParentIdLazilyCQ.setInt(2, fromOrderNum);
- findNodesByParentIdLazilyCQ.setInt(3, limit);
+ findNodesByParentIdLazilyCQ.setMaxRows(limit);
return findNodesByParentIdLazilyCQ.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-07-28 06:01:42 UTC (rev 4684)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2011-07-28 07:36:19 UTC (rev 4685)
@@ -212,11 +212,14 @@
UPDATE_VALUE = "update JCR_SVALUE set DATA=?, STORAGE_DESC=? where PROPERTY_ID=? and ORDER_NUM=?";
FIND_NODES_BY_PARENTID_LAZILY_CQ =
- "select I.*, P.NAME AS PROP_NAME, V.ORDER_NUM, V.DATA"
- + " from JCR_SITEM I, JCR_SITEM P, JCR_SVALUE V"
+ "select I.*, P.NAME AS PROP_NAME, V.ORDER_NUM, V.DATA from JCR_SITEM I, JCR_SITEM P, JCR_SVALUE V"
+ " where I.I_CLASS=1 and I.CONTAINER_NAME=? and I.PARENT_ID=? and I.N_ORDER_NUM >= ? and "
- + " P.I_CLASS=2 and P.CONTAINER_NAME=? and P.PARENT_ID=I.ID 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 LIMIT ?";
+ + " P.I_CLASS=2 and P.CONTAINER_NAME=? and P.PARENT_ID=I.ID 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";
}
/**
@@ -501,7 +504,7 @@
findNodesByParentIdLazilyCQ.setString(2, parentCid);
findNodesByParentIdLazilyCQ.setInt(3, fromOrderNum);
findNodesByParentIdLazilyCQ.setString(4, containerName);
- findNodesByParentIdLazilyCQ.setInt(5, limit);
+ findNodesByParentIdLazilyCQ.setMaxRows(limit);
return findNodesByParentIdLazilyCQ.executeQuery();
}
12 years, 9 months
exo-jcr SVN: r4684 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/impl/dataflow/session and 1 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-07-28 02:01:42 -0400 (Thu, 28 Jul 2011)
New Revision: 4684
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestGetNodesLazily.java
Log:
EXOJCR-1452: Implementation
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-07-28 06:01:42 UTC (rev 4684)
@@ -976,14 +976,21 @@
NodeData childNode = childs.get(i);
descendants.put(childNode.getIdentifier(), childNode);
}
+
+ int minOrderNum = childs.size() != 0 ? childs.get(0).getOrderNumber() :-1;
+ int maxOrderNum = childs.size() != 0 ? childs.get(childs.size() - 1).getOrderNumber() : -1;
// merge data
for (ItemState state : transientDescendants)
{
NodeData data = (NodeData)state.getData();
- if (state.isDeleted())
+ if ((state.isAdded() || state.isRenamed()) && !hasNext)
{
+ descendants.put(data.getIdentifier(), data);
+ }
+ else if (state.isDeleted())
+ {
descendants.remove(data.getIdentifier());
}
else if (state.isMixinChanged())
@@ -994,9 +1001,14 @@
descendants.put(data.getIdentifier(), data);
}
}
- else if (!hasNext && (state.isAdded() || state.isRenamed() || state.isUpdated()))
+ else if (state.isUpdated())
{
- descendants.put(data.getIdentifier(), data);
+ NodeData removedData = descendants.remove(data.getIdentifier());
+ if (removedData != null && minOrderNum <= data.getOrderNumber()
+ && data.getOrderNumber() <= maxOrderNum)
+ {
+ descendants.put(data.getIdentifier(), data);
+ }
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-07-28 06:01:42 UTC (rev 4684)
@@ -116,23 +116,37 @@
List<ItemState> txChanges = transactionLog.getChildrenChanges(parent.getIdentifier(), true);
if (txChanges.size() > 0)
{
+
+ int minOrderNum = childs.size() != 0 ? childs.get(0).getOrderNumber() :-1;
+ int maxOrderNum = childs.size() != 0 ? childs.get(childs.size() - 1).getOrderNumber() : -1;
+
for (ItemState state : txChanges)
{
- if (state.isDeleted())
+ NodeData data = (NodeData)state.getData();
+
+ if ((state.isAdded() || state.isRenamed()) && !hasNext)
{
- childs.remove(state.getData());
+ childs.add(data);
}
- if (state.isMixinChanged())
+ else if (state.isDeleted())
{
+ childs.remove(data);
+ }
+ else if (state.isMixinChanged())
+ {
boolean isExists = childs.remove(state.getData());
if (isExists)
{
- childs.add((NodeData)state.getData());
+ childs.add(data);
}
}
- else if (!hasNext && (state.isAdded() || state.isRenamed() || state.isUpdated()))
+ else if (state.isUpdated())
{
- childs.add((NodeData)state.getData());
+ boolean isExists = childs.remove(state.getData());
+ if (isExists && minOrderNum <= data.getOrderNumber() && data.getOrderNumber() <= maxOrderNum)
+ {
+ childs.add(data);
+ }
}
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestGetNodesLazily.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestGetNodesLazily.java 2011-07-27 14:23:57 UTC (rev 4683)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestGetNodesLazily.java 2011-07-28 06:01:42 UTC (rev 4684)
@@ -20,6 +20,7 @@
import org.exoplatform.services.jcr.JcrImplBaseTest;
import org.exoplatform.services.jcr.core.ExtendedNode;
+import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.transaction.TransactionService;
@@ -158,6 +159,28 @@
}
/**
+ * New nodes moved into session log and not save
+ */
+ public void testGetNodesLazilySessionUpdatedNodes() throws Exception
+ {
+ testRoot.orderBefore("child110", "child0");
+ RangeIterator iterator = testRoot.getNodesLazily();
+
+ NodeImpl next = (NodeImpl)iterator.next();
+ assertEquals(next.getName(), "child110");
+ assertEquals(((NodeData)next.getData()).getOrderNumber(), 0);
+
+ next = (NodeImpl)iterator.next();
+ assertEquals(next.getName(), "child0");
+ assertEquals(((NodeData)next.getData()).getOrderNumber(), 1);
+
+ iterator.skip(108);
+ next = (NodeImpl)iterator.next();
+ assertEquals(next.getName(), "child109");
+ assertEquals(((NodeData)next.getData()).getOrderNumber(), 110);
+ }
+
+ /**
* Change mixin in node.
*/
public void testGetNodesLazilySessionMixinChanged() throws Exception
12 years, 9 months
exo-jcr SVN: r4683 - in jcr/trunk/exo.jcr.component.core/src: main/java/org/exoplatform/services/jcr/dataflow/persistent and 12 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-07-27 10:23:57 -0400 (Wed, 27 Jul 2011)
New Revision: 4683
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesByPageId.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestGetNodesLazily.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataConsumer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.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/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/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
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java
Log:
EXOJCR-1452: Implementation
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataConsumer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataConsumer.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemDataConsumer.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -87,6 +87,22 @@
List<NodeData> getChildNodesData(NodeData parent) throws RepositoryException;
/**
+ * Get child Nodes of the parent node.
+ *
+ * @param parent
+ * the parent data
+ * @param fromOrderNum
+ * the last order number returned in previous request
+ * @param limit
+ * the recommended amount of children nodes to return
+ * @param childs
+ * will contain the resulted children nodes
+ * @return true if there are data to retrieve for next request and false in other case
+ */
+ boolean getChildNodesDataByPage(NodeData parent, int fromOrderNum, int limit, List<NodeData> childs)
+ throws RepositoryException;
+
+ /**
* Get child Nodes of the parent node.ItemDataFilter used to reduce count of returned items.
* But not guarantee that only items matching filter will be returned.
*
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 eXo Platform SAS.
+R * 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
@@ -91,6 +91,18 @@
List<NodeData> getChildNodes(NodeData parent);
/**
+ * Get page of child nodes.
+ *
+ * @param parent
+ * the parent data
+ * @param fromOrderNum
+ * the order number related to page of child nodes
+ * @return child nodes for parent if found; empty list if no items found; null if no items
+ * initialized
+ */
+ List<NodeData> getChildNodesByPage(final NodeData parent, final int fromOrderNum);
+
+ /**
* Get child nodes by pattern.
*
* @param parent
@@ -166,6 +178,18 @@
void put(ItemData item);
/**
+ * Adds page of child nodes.
+ *
+ * @param parent
+ * the parent data
+ * @param childs
+ * the list of child nodes
+ * @param fromOrderNum
+ * the order number related to page of child nodes
+ */
+ void addChildNodesByPage(NodeData parent, List<NodeData> childs, int fromOrderNum);
+
+ /**
* Adds (update should not be the case!) list of child nodes. The list can be empty. If list is
* null the operation is ignored.
*
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -1036,7 +1036,6 @@
*/
public NodeIterator getNodes() throws RepositoryException
{
-
long start = 0;
if (LOG.isDebugEnabled())
{
@@ -1086,7 +1085,7 @@
*/
public NodeIterator getNodesLazily() throws RepositoryException
{
- return null;
+ return new LazyNodeIteratorByPage(dataManager);
}
/**
@@ -3336,7 +3335,6 @@
protected boolean canRead(ItemData item)
{
- // TODO check if deleted // if (session.getTransientNodesManager().isDeleted(item.getQPath()))
return (filter != null ? filter.accept(item) : true)
&& session.getAccessManager().hasPermission(
item.isNode() ? ((NodeData)item).getACL() : nodeData().getACL(), new String[]{PermissionType.READ},
@@ -3388,10 +3386,33 @@
*/
public void skip(long skipNum)
{
+ trySkip(skipNum, true);
+ }
+
+ /**
+ * Tries to skip some elements.
+ *
+ * @param throwException
+ * indicates to throw an NoSuchElementException if can't skip defined count of elements
+ * @return how many elememnts remained to skip
+ */
+ protected long trySkip(long skipNum, boolean throwException)
+ {
pos += skipNum;
while (skipNum-- > 1)
{
- iter.next();
+ try
+ {
+ iter.next();
+ }
+ catch (NoSuchElementException e)
+ {
+ if (throwException)
+ {
+ throw e;
+ }
+ return skipNum;
+ }
}
try
@@ -3403,6 +3424,8 @@
LOG.error(e);
throw new NoSuchElementException(e.toString());
}
+
+ return 0;
}
/**
@@ -3413,7 +3436,6 @@
if (size == -1)
{
// calc size
-
int sz = pos + (next != null ? 1 : 0);
if (iter.hasNext())
{
@@ -3454,6 +3476,201 @@
}
}
+ protected class LazyNodeIteratorByPage implements RangeIterator, NodeIterator
+ {
+ private final SessionDataManager dataManager;
+
+ private int limit = session.getLazyNodeIteratorPageSize();
+
+ private int fromOrderNum = 0;
+
+ private boolean hasNext = true;
+
+ private int pos = 0;
+
+ private LazyNodeIterator lazyNodeItetator = new LazyNodeIterator(new ArrayList<NodeData>());
+
+ LazyNodeIteratorByPage(SessionDataManager dataManager) throws RepositoryException
+ {
+ this.dataManager = dataManager;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node nextNode()
+ {
+ return (Node)next();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNext()
+ {
+ boolean hasNext = lazyNodeItetator.hasNext();
+
+ if (!hasNext)
+ {
+ if (this.hasNext)
+ {
+ try
+ {
+ readNextPage(0);
+ return hasNext();
+ }
+ catch (NoSuchElementException e)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object next()
+ {
+ try
+ {
+ return nextItem();
+ }
+ catch (NoSuchElementException e)
+ {
+ if (hasNext)
+ {
+ try
+ {
+ readNextPage(0);
+ return next();
+ }
+ catch (NoSuchElementException e1)
+ {
+ throw e1;
+ }
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void remove()
+ {
+ LOG.warn("remove() method is not supported in LazyNodeIteratorByPage");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void skip(long skipNum)
+ {
+ pos += skipNum;
+
+ long leftToSkip = lazyNodeItetator.trySkip(skipNum, false);
+ if (leftToSkip != 0)
+ {
+ readNextPage(leftToSkip);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getSize()
+ {
+ return -1;
+ }
+
+ public ItemImpl nextItem()
+ {
+ ItemImpl item = lazyNodeItetator.nextItem();
+ pos++;
+
+ return item;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getPosition()
+ {
+ return pos;
+ }
+
+ private void readNextPage(long skip) throws NoSuchElementException
+ {
+ List<NodeData> storedNodes = new ArrayList<NodeData>();
+ try
+ {
+ hasNext = dataManager.getChildNodesDataByPage(nodeData(), fromOrderNum, limit, storedNodes);
+ }
+ catch (RepositoryException e)
+ {
+ LOG.error("There are no more elements in iterator", e);
+ throw new NoSuchElementException(e.toString());
+ }
+
+ Collections.sort(storedNodes, new NodeDataOrderComparator());
+
+ int size = storedNodes.size();
+ if (size != 0)
+ {
+ fromOrderNum = storedNodes.get(size - 1).getOrderNumber() + 1;
+
+ while (skip > 0 && storedNodes.size() > 0)
+ {
+ storedNodes.remove(0);
+ skip--;
+ }
+ }
+
+ if (skip != 0)
+ {
+ if (hasNext)
+ {
+ readNextPage(skip);
+ }
+ else
+ {
+ throw new NoSuchElementException("There are no more elements in iterator");
+ }
+ }
+ else
+ {
+ try
+ {
+ lazyNodeItetator = new LazyNodeIterator(storedNodes);
+ }
+ catch (RepositoryException e)
+ {
+ if (hasNext)
+ {
+ readNextPage(skip);
+ }
+ else
+ {
+ LOG.error("There are no more elements in iterator", e);
+ throw new NoSuchElementException(e.toString());
+ }
+ }
+ }
+ }
+ }
+
protected class LazyNodeIterator extends LazyItemsIterator implements NodeIterator
{
LazyNodeIterator(List<? extends ItemData> nodes) throws RepositoryException
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -946,6 +946,79 @@
/**
* {@inheritDoc}
*/
+ public boolean getChildNodesDataByPage(final NodeData parent, int fromOrderNum, int limit, List<NodeData> childs)
+ throws RepositoryException
+ {
+ long start = 0;
+ if (log.isDebugEnabled())
+ {
+ start = System.currentTimeMillis();
+ log.debug("getChildNodesData(" + parent.getQPath().getAsString() + " , itemDataFilter) >>>>>");
+ }
+
+ try
+ {
+ boolean hasNext = false;
+ if (!isNew(parent.getIdentifier()))
+ {
+ hasNext = transactionableManager.getChildNodesDataByPage(parent, fromOrderNum, limit, childs);
+ }
+
+ // merge data
+ Collection<ItemState> transientDescendants = changesLog.getLastChildrenStates(parent, true);
+
+ if (!transientDescendants.isEmpty())
+ {
+ // 2 get ALL persisted descendants
+ Map<String, NodeData> descendants = new LinkedHashMap<String, NodeData>();
+ for (int i = 0, length = childs.size(); i < length; i++)
+ {
+ NodeData childNode = childs.get(i);
+ descendants.put(childNode.getIdentifier(), childNode);
+ }
+
+ // merge data
+ for (ItemState state : transientDescendants)
+ {
+ NodeData data = (NodeData)state.getData();
+
+ if (state.isDeleted())
+ {
+ descendants.remove(data.getIdentifier());
+ }
+ else if (state.isMixinChanged())
+ {
+ NodeData removedData = descendants.remove(data.getIdentifier());
+ if (removedData != null)
+ {
+ descendants.put(data.getIdentifier(), data);
+ }
+ }
+ else if (!hasNext && (state.isAdded() || state.isRenamed() || state.isUpdated()))
+ {
+ descendants.put(data.getIdentifier(), data);
+ }
+ }
+
+ childs.clear();
+ childs.addAll(descendants.values());
+ }
+
+ return hasNext;
+ }
+ finally
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("getChildNodesData(" + parent.getQPath().getAsString() + ") <<<<< "
+ + ((System.currentTimeMillis() - start) / 1000d) + "sec");
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<NodeData> getChildNodesData(NodeData parent) throws RepositoryException
{
long start = 0;
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionImpl.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -167,6 +167,8 @@
private boolean triggerEventsForDescendentsOnRename;
+ private int lazyNodeIteatorPageSize;
+
private final int lazyReadThreshold;
private final SessionRegistry sessionRegistry;
@@ -244,9 +246,14 @@
sessionRegistry.registerSession(this);
this.lastAccessTime = System.currentTimeMillis();
+
this.triggerEventsForDescendentsOnRename =
wsConfig.getContainer().getParameterBoolean(WorkspaceDataContainer.TRIGGER_EVENTS_FOR_DESCENDENTS_ON_RENAME,
WorkspaceDataContainer.TRIGGER_EVENTS_FOR_DESCENDENTS_ON_RENAME_DEFAULT);
+
+ this.lazyNodeIteatorPageSize =
+ wsConfig.getContainer().getParameterInteger(WorkspaceDataContainer.LAZY_NODE_ITERATOR_PAGE_SIZE,
+ WorkspaceDataContainer.LAZY_NODE_ITERATOR_PAGE_SIZE_DEFAULT);
}
/**
@@ -1127,6 +1134,11 @@
return lazyReadThreshold;
}
+ int getLazyNodeIteratorPageSize()
+ {
+ return lazyNodeIteatorPageSize;
+ }
+
@Override
public String toString()
{
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ACLInheritanceSupportedWorkspaceDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -73,6 +73,15 @@
/**
* {@inheritDoc}
*/
+ public boolean getChildNodesDataByPage(NodeData parent, int fromOrderNum, int limit, List<NodeData> childs)
+ throws RepositoryException
+ {
+ return persistentManager.getChildNodesDataByPage(parent, fromOrderNum, limit, childs);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public int getLastOrderNumber(final NodeData parent) throws RepositoryException
{
return persistentManager.getLastOrderNumber(parent);
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -513,6 +513,79 @@
/**
* {@inheritDoc}
*/
+ public boolean getChildNodesDataByPage(final NodeData nodeData, final int fromOrderNum, final int limit,
+ final List<NodeData> childs) throws RepositoryException
+ {
+ List<NodeData> childNodes = null;
+ if (cache.isEnabled())
+ {
+ childNodes = cache.getChildNodes(nodeData);
+ if (childNodes != null)
+ {
+ childs.addAll(childNodes);
+ return false;
+ }
+ else
+ {
+ childNodes = cache.getChildNodesByPage(nodeData, fromOrderNum);
+ if (childNodes != null)
+ {
+ childs.addAll(childNodes);
+ return true;
+ }
+ }
+ }
+ final DataRequest request = new DataRequest(nodeData.getIdentifier(), DataRequest.GET_NODES);
+
+ try
+ {
+ request.start();
+ if (cache.isEnabled())
+ {
+ // Try first to get the value from the cache since a
+ // request could have been launched just before
+ childNodes = cache.getChildNodes(nodeData);
+ if (childNodes != null)
+ {
+ childs.addAll(childNodes);
+ return false;
+ }
+ else
+ {
+ childNodes = cache.getChildNodesByPage(nodeData, fromOrderNum);
+ if (childNodes != null)
+ {
+ childs.addAll(childNodes);
+ return true;
+ }
+ }
+ }
+
+ return executeAction(new PrivilegedExceptionAction<Boolean>()
+ {
+ public Boolean run() throws RepositoryException
+ {
+ boolean hasNext =
+ CacheableWorkspaceDataManager.super.getChildNodesDataByPage(nodeData, fromOrderNum, limit, childs);
+
+ if (cache.isEnabled())
+ {
+ cache.addChildNodesByPage(nodeData, childs, fromOrderNum);
+ }
+
+ return hasNext;
+ }
+ });
+ }
+ finally
+ {
+ request.done();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public List<NodeData> getChildNodesData(NodeData parentData, List<QPathEntryFilter> patternFilters)
throws RepositoryException
@@ -1003,21 +1076,8 @@
List<NodeData> childNodes = CacheableWorkspaceDataManager.super.getChildNodesData(nodeData);
if (cache.isEnabled())
{
- NodeData parentData = (NodeData)getItemData(nodeData.getIdentifier());
-
- if (parentData != null)
- {
- cache.addChildNodes(parentData, childNodes);
- }
+ cache.addChildNodes(nodeData, childNodes);
}
- else
- {
- // ini ACL
- for (int i = 0; i < childNodes.size(); i++)
- {
- childNodes.set(i, (NodeData)initACL(nodeData, childNodes.get(i)));
- }
- }
return childNodes;
}
@@ -1322,12 +1382,7 @@
// TODO childProperties.size() > 0 for SDB
if (childProperties.size() > 0 && cache.isEnabled())
{
- NodeData parentData = (NodeData)getItemData(nodeData.getIdentifier());
-
- if (parentData != null)
- {
- cache.addChildProperties(parentData, childProperties);
- }
+ cache.addChildProperties(nodeData, childProperties);
}
return childProperties;
}
@@ -1644,12 +1699,7 @@
// TODO propertiesList.size() > 0 for SDB
if (propertiesList.size() > 0 && cache.isEnabled())
{
- NodeData parentData = (NodeData)getItemData(nodeData.getIdentifier());
-
- if (parentData != null)
- {
- cache.addChildPropertiesList(parentData, propertiesList);
- }
+ cache.addChildPropertiesList(nodeData, propertiesList);
}
return propertiesList;
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -2184,24 +2184,28 @@
public void addChildProperties(NodeData parent, QPathEntryFilter pattern, List<PropertyData> childProperties)
{
- // TODO Auto-generated method stub
}
public List<PropertyData> getChildProperties(NodeData parent, QPathEntryFilter pattern)
{
- // TODO Auto-generated method stub
return null;
}
public void addChildNodes(NodeData parent, QPathEntryFilter pattern, List<NodeData> childNodes)
{
- // TODO Auto-generated method stub
-
}
public List<NodeData> getChildNodes(NodeData parent, QPathEntryFilter pattern)
{
- // TODO Auto-generated method stub
return null;
}
+
+ public List<NodeData> getChildNodesByPage(NodeData parent, int fromOrderNum)
+ {
+ return null;
+ }
+
+ public void addChildNodesByPage(NodeData parent, List<NodeData> childs, int fromOrderNum)
+ {
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/VersionableWorkspaceDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -91,6 +91,20 @@
* {@inheritDoc}
*/
@Override
+ public boolean getChildNodesDataByPage(NodeData nodeData, int fromOrderNum, int limit, List<NodeData> childs)
+ throws RepositoryException
+ {
+ if (isSystemDescendant(nodeData.getQPath()) && !this.equals(versionDataManager))
+ {
+ return versionDataManager.getChildNodesDataByPage(nodeData, fromOrderNum, limit, childs);
+ }
+ return super.getChildNodesDataByPage(nodeData, fromOrderNum, limit, childs);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public List<NodeData> getChildNodesData(final NodeData nodeData, final List<QPathEntryFilter> patternFilters)
throws RepositoryException
{
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/WorkspacePersistentDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -45,6 +45,7 @@
import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManager;
import org.exoplatform.services.jcr.impl.dataflow.session.TransactionableResourceManagerListener;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
+import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
import org.exoplatform.services.log.ExoLogger;
@@ -614,7 +615,6 @@
*/
public List<NodeData> getChildNodesData(final NodeData nodeData) throws RepositoryException
{
-
final WorkspaceStorageConnection con = dataContainer.openConnection();
try
{
@@ -629,6 +629,32 @@
/**
* {@inheritDoc}
*/
+ public boolean getChildNodesDataByPage(final NodeData nodeData, int fromOrderNum, int limit, List<NodeData> childs)
+ throws RepositoryException
+ {
+ final WorkspaceStorageConnection con = dataContainer.openConnection();
+ if (con instanceof JDBCStorageConnection)
+ {
+ try
+ {
+ childs.addAll(((JDBCStorageConnection)con).getChildNodesDataByPage(nodeData, fromOrderNum, limit));
+ return childs.size() == limit;
+ }
+ finally
+ {
+ con.close();
+ }
+ }
+ else
+ {
+ throw new UnsupportedOperationException(
+ "The method getChildNodesDataLazily is supported only for JDBCStorageConnection");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<NodeData> getChildNodesData(final NodeData nodeData, List<QPathEntryFilter> patternFilters)
throws RepositoryException
{
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesByPageId.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesByPageId.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/CacheNodesByPageId.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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.dataflow.persistent.infinispan;
+
+/**
+ * @author <a href="abazko(a)exoplatform.com">Anatoliy Bazko</a>
+ * @version $Id: CachePagedNodes.java 34360 2009-07-22 23:58:59Z tolusha $
+ */
+public class CacheNodesByPageId extends CacheKey
+{
+
+ CacheNodesByPageId()
+ {
+ super();
+ }
+
+ CacheNodesByPageId(String id)
+ {
+ super(id);
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof CacheNodesByPageId)
+ {
+ CacheNodesByPageId cacheNodesByPageId = (CacheNodesByPageId)obj;
+ return (cacheNodesByPageId.hash == hash && cacheNodesByPageId.fullId.equals(fullId));
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/infinispan/ISPNCacheWorkspaceStorageCache.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -592,6 +592,57 @@
/**
* {@inheritDoc}
*/
+ public void addChildNodesByPage(NodeData parent, List<NodeData> childs, int fromOrderNum)
+ {
+ boolean inTransaction = cache.isTransactionActive();
+ try
+ {
+ if (!inTransaction)
+ {
+ cache.beginTransaction();
+ }
+
+ cache.setLocal(true);
+
+ CacheNodesByPageId cacheId = new CacheNodesByPageId(parent.getIdentifier());
+ Map<Integer, Set<String>> pages = (Map<Integer, Set<String>>)cache.get(cacheId);
+ if (pages == null)
+ {
+ pages = new HashMap<Integer, Set<String>>();
+ }
+
+ if (childs.size() > 0)
+ {
+ Set<String> set = new HashSet<String>();
+ for (NodeData child : childs)
+ {
+ putNode(child, ModifyChildOption.NOT_MODIFY);
+ set.add(child.getIdentifier());
+ }
+
+ pages.put(fromOrderNum, set);
+ cache.put(cacheId, pages);
+ }
+ else
+ {
+ // cache fact of empty childs list
+ pages.put(fromOrderNum, new HashSet<String>());
+ cache.put(cacheId, pages);
+ }
+ }
+ finally
+ {
+ cache.setLocal(false);
+ if (!inTransaction)
+ {
+ dedicatedTxCommit();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void addChildNodes(NodeData parent, List<NodeData> childs)
{
boolean inTransaction = cache.isTransactionActive();
@@ -611,12 +662,12 @@
putNode(child, ModifyChildOption.NOT_MODIFY);
set.add(child.getIdentifier());
}
- cache.putIfAbsent(new CacheNodesId(parent.getIdentifier()), set);
+ cache.put(new CacheNodesId(parent.getIdentifier()), set);
}
else
{
// cache fact of empty childs list
- cache.putIfAbsent(new CacheNodesId(parent.getIdentifier()), new HashSet<Object>());
+ cache.put(new CacheNodesId(parent.getIdentifier()), new HashSet<Object>());
}
}
finally
@@ -796,6 +847,43 @@
/**
* {@inheritDoc}
*/
+ public List<NodeData> getChildNodesByPage(final NodeData parent, final int fromOrderNum)
+ {
+ // get list of children uuids
+ final Map<Integer, Set<String>> pages =
+ (Map<Integer, Set<String>>)cache.get(new CacheNodesByPageId(parent.getIdentifier()));
+
+ if (pages == null)
+ {
+ return null;
+ }
+
+ Set<String> set = pages.get(fromOrderNum);
+ if (set == null)
+ {
+ return null;
+ }
+
+ final List<NodeData> childs = new ArrayList<NodeData>();
+ for (String childId : set)
+ {
+ NodeData child = (NodeData)cache.get(new CacheId(childId));
+ if (child == null)
+ {
+ return null;
+ }
+
+ childs.add(child);
+ }
+
+ // order children by orderNumber, as HashSet returns children in other order
+ Collections.sort(childs, new NodesOrderComparator<NodeData>());
+ return childs;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<NodeData> getChildNodes(final NodeData parent, final QPathEntryFilter pattern)
{
// get list of children uuids
@@ -986,6 +1074,8 @@
cache.addToPatternList(new CachePatternNodesId(node.getParentIdentifier()), node);
cache.addToList(new CacheNodesId(node.getParentIdentifier()), node.getIdentifier(),
modifyListsOfChild == ModifyChildOption.FORCE_MODIFY);
+
+ cache.remove(new CacheNodesByPageId(node.getParentIdentifier()));
}
}
@@ -1122,24 +1212,27 @@
cache.remove(new CacheId(item.getIdentifier()));
cache.remove(new CacheQPath(item.getParentIdentifier(), item.getQPath(), ItemType.getItemType(item)));
- if (item.getParentIdentifier() != null)
+ if (item.isNode())
{
- if (item.isNode())
+ if (item.getParentIdentifier() != null)
{
- cache.remove(new CacheNodesId(item.getIdentifier()));
- cache.remove(new CachePropsId(item.getIdentifier()));
cache.removeFromPatternList(new CachePatternNodesId(item.getParentIdentifier()), item);
- cache.remove(new CachePatternNodesId(item.getIdentifier()));
- cache.remove(new CachePatternPropsId(item.getIdentifier()));
cache.removeFromList(new CacheNodesId(item.getParentIdentifier()), item.getIdentifier());
- cache.remove(new CacheRefsId(item.getIdentifier()));
+ cache.remove(new CacheNodesByPageId(item.getParentIdentifier()));
}
- else
- {
- cache.removeFromPatternList(new CachePatternPropsId(item.getParentIdentifier()), item);
- cache.removeFromList(new CachePropsId(item.getParentIdentifier()), item.getIdentifier());
- }
+
+ cache.remove(new CacheNodesId(item.getIdentifier()));
+ cache.remove(new CachePropsId(item.getIdentifier()));
+ cache.remove(new CacheNodesByPageId(item.getIdentifier()));
+ cache.remove(new CachePatternNodesId(item.getIdentifier()));
+ cache.remove(new CachePatternPropsId(item.getIdentifier()));
+ cache.remove(new CacheRefsId(item.getIdentifier()));
}
+ else
+ {
+ cache.removeFromPatternList(new CachePatternPropsId(item.getParentIdentifier()), item);
+ cache.removeFromList(new CachePropsId(item.getParentIdentifier()), item.getIdentifier());
+ }
}
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -71,9 +71,11 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
@@ -149,6 +151,8 @@
public static final String CHILD_NODES_BY_PATTERN_LIST = "$CHILD_NODES_BY_PATTERN_LIST".intern();
+ public static final String CHILD_NODES_BY_PAGE_LIST = "$CHILD_NODES_BY_PAGE_LIST".intern();
+
public static final String LOCKS = "$LOCKS".intern();
public static final String REFERENCE = "$REFERENCE".intern();
@@ -175,6 +179,8 @@
protected final Fqn<String> childPropsList;
+ protected final Fqn<String> childNodesByPageList;
+
protected final Fqn<String> childPropsByPatternList;
protected final Fqn<String> childNodesByPatternList;
@@ -219,7 +225,7 @@
{
NodeData node = (NodeData)cache.get(makeItemFqn((String)child), ITEM_DATA);
- if (node == null || node instanceof NullItemData)
+ if (node == null)
{
return null;
}
@@ -404,7 +410,7 @@
protected Long execute(Void arg) throws RuntimeException
{
// Total number of JBC nodes in the cache - the total amount of resident nodes
- return numNodes(cache.getNode(rootFqn)) - 9;
+ return numNodes(cache.getNode(rootFqn)) - 10;
}
};
@@ -612,6 +618,7 @@
this.childProps = Fqn.fromRelativeElements(rootFqn, CHILD_PROPS);
this.childNodesList = Fqn.fromRelativeElements(rootFqn, CHILD_NODES_LIST);
this.childPropsList = Fqn.fromRelativeElements(rootFqn, CHILD_PROPS_LIST);
+ this.childNodesByPageList = Fqn.fromRelativeElements(rootFqn, CHILD_NODES_BY_PAGE_LIST);
this.childPropsByPatternList = Fqn.fromRelativeElements(rootFqn, CHILD_PROPS_BY_PATTERN_LIST);
this.childNodesByPatternList = Fqn.fromRelativeElements(rootFqn, CHILD_NODES_BY_PATTERN_LIST);
@@ -669,6 +676,7 @@
createResidentNode(childNodesList);
createResidentNode(childProps);
createResidentNode(childPropsList);
+ createResidentNode(childNodesByPageList);
createResidentNode(childPropsByPatternList);
createResidentNode(childNodesByPatternList);
createResidentNode(itemsRoot);
@@ -899,7 +907,8 @@
else
{
// cache fact of empty childs list
- cache.putIfAbsent(makeChildListFqn(childNodesList, parent.getIdentifier()), ITEM_LIST, new HashSet<Object>());
+ cache.putIfAbsent(makeChildListFqn(childNodesList, parent.getIdentifier()), ITEM_LIST,
+ new HashSet<Object>());
}
}
finally
@@ -912,17 +921,68 @@
}
}
+
/**
* {@inheritDoc}
*/
- public void addChildNodes(NodeData parent, QPathEntryFilter pattern, List<NodeData> childs)
+ public void addChildNodesByPage(NodeData parent, List<NodeData> childs, int fromOrderNum)
{
boolean inTransaction = cache.isTransactionActive();
try
{
+ if (!inTransaction)
+ {
+ cache.beginTransaction();
+ }
+ cache.setLocal(true);
+
+ Fqn<String> fqn = makeChildListFqn(childNodesByPageList, parent.getIdentifier());
+ Map<Integer, Set<String>> pages = (Map<Integer, Set<String>>)cache.get(fqn, ITEM_LIST);
+ if (pages == null)
+ {
+ pages = new HashMap<Integer, Set<String>>();
+ }
+
+ if (childs.size() > 0)
+ {
+ Set<String> set = new HashSet<String>();
+ for (NodeData child : childs)
+ {
+ putNode(child, ModifyChildOption.NOT_MODIFY);
+ set.add(child.getIdentifier());
+ }
+
+ pages.put(fromOrderNum, set);
+ cache.put(fqn, ITEM_LIST, pages);
+ }
+ else
+ {
+ // cache fact of empty childs list
+ pages.put(fromOrderNum, new HashSet<String>());
+ cache.put(fqn, ITEM_LIST, pages);
+ }
+ }
+ finally
+ {
+ cache.setLocal(false);
if (!inTransaction)
{
+ dedicatedTxCommit();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addChildNodes(NodeData parent, QPathEntryFilter pattern, List<NodeData> childs)
+ {
+ boolean inTransaction = cache.isTransactionActive();
+ try
+ {
+ if (!inTransaction)
+ {
cache.beginTransaction();
}
@@ -1077,6 +1137,43 @@
/**
* {@inheritDoc}
*/
+ public List<NodeData> getChildNodesByPage(final NodeData parent, final int fromOrderNum)
+ {
+ final Map<Integer, Set<String>> pages =
+ (Map<Integer, Set<String>>)cache
+ .get(makeChildListFqn(childNodesByPageList, parent.getIdentifier()), ITEM_LIST);
+
+ if (pages == null)
+ {
+ return null;
+ }
+
+ Set<String> set = pages.get(fromOrderNum);
+ if (set == null)
+ {
+ return null;
+ }
+
+ final List<NodeData> childs = new ArrayList<NodeData>();
+ for (Object child : set)
+ {
+ NodeData node = (NodeData)cache.get(makeItemFqn((String)child), ITEM_DATA);
+ if (node == null)
+ {
+ return null;
+ }
+
+ childs.add(node);
+ }
+
+ // order children by orderNumber, as HashSet returns children in other order
+ Collections.sort(childs, new NodesOrderComparator<NodeData>());
+ return childs;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<NodeData> getChildNodes(final NodeData parent, final QPathEntryFilter pattern)
{
// empty Set<Object> marks that there is no child nodes
@@ -1094,7 +1191,7 @@
{
NodeData node = (NodeData)cache.get(makeItemFqn((String)child), ITEM_DATA);
- if (node == null || node instanceof NullItemData)
+ if (node == null)
{
return null;
}
@@ -1390,6 +1487,8 @@
ITEM_LIST, node);
cache.addToList(makeChildListFqn(childNodesList, node.getParentIdentifier()), ITEM_LIST,
node.getIdentifier(), modifyListsOfChild == ModifyChildOption.FORCE_MODIFY);
+
+ cache.removeNode(makeChildListFqn(childNodesByPageList, node.getParentIdentifier()));
}
}
@@ -1537,23 +1636,35 @@
cache.removeFromList(makeChildListFqn(childNodesList, item.getParentIdentifier()), ITEM_LIST, item
.getIdentifier());
- // remove from CHILD_NODES as parent
- cache.removeNode(makeChildListFqn(childNodes, item.getIdentifier()));
+ // remove from CHILD_NODES_BY_PATTERN_LIST of parent
+ cache.removeFromPatternList(makeChildListFqn(childNodesByPatternList, item.getParentIdentifier()),
+ PATTERN_OBJ, ITEM_LIST, item);
- // remove from CHILD_NODES_LIST as parent
- cache.removeNode(makeChildListFqn(childNodesList, item.getIdentifier()));
+ // remove from CHILD_NODES_BY_PAGE_LIST of parent
+ cache.removeNode(makeChildListFqn(childNodesByPageList, item.getParentIdentifier()));
+ }
- // remove from CHILD_PROPS as parent
- cache.removeNode(makeChildListFqn(childProps, item.getIdentifier()));
+ // remove from CHILD_NODES as parent
+ cache.removeNode(makeChildListFqn(childNodes, item.getIdentifier()));
- // remove from CHILD_PROPS_LIST as parent
- cache.removeNode(makeChildListFqn(childPropsList, item.getIdentifier()));
- }
+ // remove from CHILD_NODES_LIST as parent
+ cache.removeNode(makeChildListFqn(childNodesList, item.getIdentifier()));
- cache.removeFromPatternList(makeChildListFqn(childNodesByPatternList, item.getParentIdentifier()),
- PATTERN_OBJ, ITEM_LIST, item);
+ // remove from CHILD_PROPS as parent
+ cache.removeNode(makeChildListFqn(childProps, item.getIdentifier()));
+
+ // remove from CHILD_PROPS_LIST as parent
+ cache.removeNode(makeChildListFqn(childPropsList, item.getIdentifier()));
+
+ // remove from CHILD_NODES_BY_PAGE_LIST as parent
+ cache.removeNode(makeChildListFqn(childNodesByPageList, item.getIdentifier()));
+
+ // remove from CHILD_NODES_BY_PATTERN_LIST as parent
cache.removeNode(makeChildListFqn(childNodesByPatternList, item.getIdentifier()));
+
+ // remove from CHILD_PROPS_BY_PATTERN_LIST as parent
cache.removeNode(makeChildListFqn(childPropsByPatternList, item.getIdentifier()));
+
cache.removeNode(makeRefFqn(item.getIdentifier()));
}
else
@@ -1569,6 +1680,7 @@
cache.removeFromPatternList(makeChildListFqn(childPropsByPatternList, item.getParentIdentifier()),
PATTERN_OBJ, ITEM_LIST, item);
}
+
// remove from ITEMS
cache.removeNode(makeItemFqn(item.getIdentifier()));
}
@@ -1942,6 +2054,7 @@
cache.removeNode(childProps);
cache.removeNode(childNodesList);
cache.removeNode(childPropsList);
+ cache.removeNode(childNodesByPageList);
cache.removeNode(childNodesByPatternList);
cache.removeNode(childPropsByPatternList);
@@ -1952,6 +2065,7 @@
createResidentNode(childNodesList);
createResidentNode(childProps);
createResidentNode(childPropsList);
+ createResidentNode(childNodesByPageList);
createResidentNode(childNodesByPatternList);
createResidentNode(childPropsByPatternList);
createResidentNode(itemsRoot);
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/LocalWorkspaceStorageDataManagerProxy.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -144,6 +144,15 @@
/**
* {@inheritDoc}
*/
+ public boolean getChildNodesDataByPage(NodeData parent, int fromOrderNum, int limit, List<NodeData> childs)
+ throws RepositoryException
+ {
+ return storageDataManager.getChildNodesDataByPage(parent, fromOrderNum, limit, copyNodes(childs));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public int getLastOrderNumber(final NodeData parent) throws RepositoryException
{
return storageDataManager.getLastOrderNumber(parent);
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/session/TransactionableDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -102,6 +102,45 @@
return nodes;
}
+ /**
+ * {@inheritDoc}
+ */
+ public boolean getChildNodesDataByPage(final NodeData parent, int fromOrderNum, int limit, List<NodeData> childs)
+ throws RepositoryException
+ {
+ boolean hasNext = storageDataManager.getChildNodesDataByPage(parent, fromOrderNum, limit, childs);
+
+ if (txStarted())
+ {
+ // merge data
+ List<ItemState> txChanges = transactionLog.getChildrenChanges(parent.getIdentifier(), true);
+ if (txChanges.size() > 0)
+ {
+ for (ItemState state : txChanges)
+ {
+ if (state.isDeleted())
+ {
+ childs.remove(state.getData());
+ }
+ if (state.isMixinChanged())
+ {
+ boolean isExists = childs.remove(state.getData());
+ if (isExists)
+ {
+ childs.add((NodeData)state.getData());
+ }
+ }
+ else if (!hasNext && (state.isAdded() || state.isRenamed() || state.isUpdated()))
+ {
+ childs.add((NodeData)state.getData());
+ }
+ }
+ }
+ }
+
+ return hasNext;
+ }
+
public List<NodeData> getChildNodesData(NodeData parent, List<QPathEntryFilter> patternFilters) throws RepositoryException
{
List<NodeData> nodes = storageDataManager.getChildNodesData(parent, patternFilters);
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-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCStorageConnection.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -1164,6 +1164,54 @@
}
/**
+ *
+ * @param parent
+ * @param lastOrderNum
+ * @param limit
+ * @return
+ * @throws RepositoryException
+ * @throws IllegalStateException
+ */
+ public List<NodeData> getChildNodesDataByPage(NodeData parent, int fromOrderNum, int limit) throws RepositoryException,
+ IllegalStateException
+ {
+ checkIfOpened();
+ try
+ {
+ ResultSet node = findChildNodesByParentIdentifier(getInternalId(parent.getIdentifier()), fromOrderNum, limit);
+ try
+ {
+ List<NodeData> childrens = new ArrayList<NodeData>();
+ while (node.next())
+ {
+ childrens.add((NodeData)itemData(parent.getQPath(), node, I_CLASS_NODE, parent.getACL()));
+ }
+
+ return childrens;
+ }
+ finally
+ {
+ try
+ {
+ node.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.error("Can't close the ResultSet: " + e);
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+
+ /**
* {@inheritDoc}
*/
public List<PropertyData> listChildPropertiesData(NodeData parent) throws RepositoryException, IllegalStateException
@@ -2133,7 +2181,6 @@
protected PersistedNodeData loadNodeRecord(QPath parentPath, String cname, String cid, String cpid, int cindex,
int cversion, int cnordernumb, AccessControlList parentACL) throws RepositoryException, SQLException
{
-
try
{
InternalQName qname = InternalQName.parse(cname);
@@ -2851,6 +2898,9 @@
protected abstract ResultSet findNodesAndProperties(String lastNodeId, int offset, int limit) throws SQLException;
+ protected abstract ResultSet findChildNodesByParentIdentifier(String parentCid, int fromOrderNum, 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/db/MultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MultiDbJDBCConnection.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -418,6 +418,15 @@
return findPropertiesByParentId.executeQuery();
}
+ /**
+ * {@inheritDoc}
+ */
+ protected ResultSet findChildNodesByParentIdentifier(String parentCid, int lastOrderNum, int limit)
+ throws SQLException
+ {
+ throw new UnsupportedOperationException("findChildNodesByParentIdentifier is not supported for old queries");
+ }
+
// -------- values processing ------------
/**
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-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/SingleDbJDBCConnection.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -432,6 +432,15 @@
return updateProperty.executeUpdate();
}
+ /**
+ * {@inheritDoc}
+ */
+ protected ResultSet findChildNodesByParentIdentifier(String parentCid, int lastOrderNum, int limit)
+ throws SQLException
+ {
+ throw new UnsupportedOperationException("findChildNodesByParentIdentifier is not supported for old queries");
+ }
+
// -------- values processing ------------
/**
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-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCStorageConnection.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -99,13 +99,18 @@
protected String FIND_NODE_MAIN_PROPERTIES_BY_PARENTID_CQ;
/**
- * FIND_PROPERTIES_BY_PARENTID_AND_PATTERN_CQ_TEMPLATE;
+ * FIND_PROPERTIES_BY_PARENTID_AND_PATTERN_CQ_TEMPLATE.
*/
protected String FIND_PROPERTIES_BY_PARENTID_AND_PATTERN_CQ_TEMPLATE;
/**
- * FIND_NODES_BY_PARENTID_AND_PATTERN_CQ_TEMPLATE;
+ * FIND_NODES_BY_PARENTID_LAZILY.
*/
+ protected String FIND_NODES_BY_PARENTID_LAZILY_CQ;
+
+ /**
+ * FIND_NODES_BY_PARENTID_AND_PATTERN_CQ_TEMPLATE.
+ */
protected String FIND_NODES_BY_PARENTID_AND_PATTERN_CQ_TEMPLATE;
/**
@@ -138,6 +143,8 @@
protected PreparedStatement findPropertyById;
+ protected PreparedStatement findNodesByParentIdLazilyCQ;
+
protected PreparedStatement deleteValueDataByOrderNum;
protected PreparedStatement updateValue;
@@ -1123,6 +1130,11 @@
{
findNodesByParentIdAndComplexPatternCQ.close();
}
+
+ if (findNodesByParentIdLazilyCQ != null)
+ {
+ findNodesByParentIdLazilyCQ.close();
+ }
}
catch (SQLException e)
{
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-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MultiDbJDBCConnection.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -205,6 +205,13 @@
"select I.P_TYPE, V.STORAGE_DESC from JCR_MITEM I, JCR_MVALUE V where I.ID = ? and V.PROPERTY_ID = I.ID";
DELETE_VALUE_BY_ORDER_NUM = "delete from JCR_MVALUE where PROPERTY_ID=? and ORDER_NUM >= ?";
UPDATE_VALUE = "update JCR_MVALUE set DATA=?, STORAGE_DESC=? where PROPERTY_ID=? and ORDER_NUM=?";
+
+ FIND_NODES_BY_PARENTID_LAZILY_CQ =
+ "select I.*, P.NAME AS PROP_NAME, V.ORDER_NUM, V.DATA"
+ + " from JCR_MITEM I, JCR_MITEM P, JCR_MVALUE V"
+ + " where I.I_CLASS=1 and I.PARENT_ID=? and I.N_ORDER_NUM >= ? and"
+ + " P.I_CLASS=2 and P.PARENT_ID=I.ID 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 LIMIT ?";
}
/**
@@ -558,6 +565,24 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
+ protected ResultSet findChildNodesByParentIdentifier(String parentCid, int fromOrderNum, int limit)
+ throws SQLException
+ {
+ if (findNodesByParentIdLazilyCQ == null)
+ findNodesByParentIdLazilyCQ = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID_LAZILY_CQ);
+ else
+ findNodesByParentIdLazilyCQ.clearParameters();
+
+ findNodesByParentIdLazilyCQ.setString(1, parentCid);
+ findNodesByParentIdLazilyCQ.setInt(2, fromOrderNum);
+ findNodesByParentIdLazilyCQ.setInt(3, limit);
+
+ return findNodesByParentIdLazilyCQ.executeQuery();
+ }
+
// -------- values processing ------------
/**
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-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/SingleDbJDBCConnection.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -194,7 +194,6 @@
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=?";
@@ -205,12 +204,19 @@
+ " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM P"
+ " join (select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_SITEM I"
+ " where I.CONTAINER_NAME=? AND I.I_CLASS=1 AND I.ID > ? order by I.ID LIMIT ? OFFSET ?) J on P.PARENT_ID = J.ID"
- + " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
+ + " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
FIND_PROPERTY_BY_ID =
"select I.P_TYPE, V.STORAGE_DESC from JCR_SITEM I, JCR_SVALUE V where I.CONTAINER_NAME=? and I.ID = ? and V.PROPERTY_ID = I.ID";
DELETE_VALUE_BY_ORDER_NUM = "delete from JCR_SVALUE where PROPERTY_ID=? and ORDER_NUM >= ?";
UPDATE_VALUE = "update JCR_SVALUE set DATA=?, STORAGE_DESC=? where PROPERTY_ID=? and ORDER_NUM=?";
+
+ FIND_NODES_BY_PARENTID_LAZILY_CQ =
+ "select I.*, P.NAME AS PROP_NAME, V.ORDER_NUM, V.DATA"
+ + " from JCR_SITEM I, JCR_SITEM P, JCR_SVALUE V"
+ + " where I.I_CLASS=1 and I.CONTAINER_NAME=? and I.PARENT_ID=? and I.N_ORDER_NUM >= ? and "
+ + " P.I_CLASS=2 and P.CONTAINER_NAME=? and P.PARENT_ID=I.ID 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 LIMIT ?";
}
/**
@@ -480,6 +486,26 @@
return updateProperty.executeUpdate();
}
+ /**
+ * {@inheritDoc}
+ */
+ protected ResultSet findChildNodesByParentIdentifier(String parentCid, int fromOrderNum, int limit)
+ throws SQLException
+ {
+ if (findNodesByParentIdLazilyCQ == null)
+ findNodesByParentIdLazilyCQ = dbConnection.prepareStatement(FIND_NODES_BY_PARENTID_LAZILY_CQ);
+ else
+ findNodesByParentIdLazilyCQ.clearParameters();
+
+ findNodesByParentIdLazilyCQ.setString(1, containerName);
+ findNodesByParentIdLazilyCQ.setString(2, parentCid);
+ findNodesByParentIdLazilyCQ.setInt(3, fromOrderNum);
+ findNodesByParentIdLazilyCQ.setString(4, containerName);
+ findNodesByParentIdLazilyCQ.setInt(5, limit);
+
+ return findNodesByParentIdLazilyCQ.executeQuery();
+ }
+
// -------- values processing ------------
/**
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/storage/WorkspaceDataContainer.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -42,6 +42,10 @@
public static final boolean TRIGGER_EVENTS_FOR_DESCENDENTS_ON_RENAME_DEFAULT = true;
+ public static final String LAZY_NODE_ITERATOR_PAGE_SIZE = "lazy-node-iterator-page-size";
+
+ public static final int LAZY_NODE_ITERATOR_PAGE_SIZE_DEFAULT = 100;
+
public final static String CONTAINER_NAME = "containerName";
public final static String MAXBUFFERSIZE_PROP = "max-buffer-size";
Added: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestGetNodesLazily.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestGetNodesLazily.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/TestGetNodesLazily.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core;
+
+import org.exoplatform.services.jcr.JcrImplBaseTest;
+import org.exoplatform.services.jcr.core.ExtendedNode;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.transaction.TransactionService;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RangeIterator;
+import javax.jcr.RepositoryException;
+import javax.transaction.UserTransaction;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * @author <a href="mailto:nzamosenchuk@exoplatform.com">Nikolay Zamosenchuk</a>
+ * @version $Id: TestGetNode.java 111 2009-11-11 11:11:11Z nzamosenchuk $
+ */
+public class TestGetNodesLazily extends JcrImplBaseTest
+{
+ private static String INDEX_PROPERTY = "indexNumber";
+
+ private NodeImpl testRoot;
+
+ private int nodesCount;
+
+ private TransactionService txService;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ testRoot = (NodeImpl)session.getRootNode().addNode("TestGetNodesLazily");
+
+ // add first 150 child nodes
+ nodesCount = 150;
+ for (int i = 0; i < nodesCount; i++)
+ {
+ testRoot.addNode("child" + i).setProperty(INDEX_PROPERTY, i);
+ }
+ session.save();
+ txService = (TransactionService)container.getComponentInstanceOfType(TransactionService.class);
+ }
+
+ /**
+ * Simple check, session log empty.
+ */
+ public void testGetNodesLazilyBasicUsecase() throws Exception
+ {
+ // 150 nodes added in setup
+ assertChildNodes(testRoot, nodesCount);
+ }
+
+ /**
+ * All child they reordered one by one and though must be returned in same order
+ */
+ public void _testGetNodesLazilyReordered() throws Exception
+ {
+ // 150 nodes added in setup
+ for (int i = 0; i < nodesCount; i++)
+ {
+ NodeImpl node = (NodeImpl)testRoot.getNode("child" + i);
+ session.move(node.getPath(), node.getPath());
+ }
+ session.save();
+ assertChildNodes(testRoot, nodesCount);
+ }
+
+ /**
+ * All child they reordered one by one and though must be returned in same order
+ */
+ public void _testGetNodesLazilyReorderedBackwards() throws Exception
+ {
+ // 150 nodes added in setup
+ // TODO : testcase fails
+ for (int i = nodesCount - 1; i >= 0; i--)
+ {
+ NodeImpl node = (NodeImpl)testRoot.getNode("child" + i);
+ session.move(node.getPath(), node.getPath());
+ }
+ session.save();
+ assertChildNodes(testRoot, nodesCount, true);
+ }
+
+ /**
+ * Session move with save
+ */
+ public void testGetNodesLazilyRenamedParent() throws Exception
+ {
+ // 150 nodes added in setup
+ // renaming parent
+ String newName = "new Name";
+ session.move("/" + testRoot.getName(), "/" + newName);
+ NodeImpl newTestRoot = (NodeImpl)root.getNode(newName);
+ session.save();
+ assertChildNodes(newTestRoot, nodesCount);
+ }
+
+ //=============== Tests with non-empty changesLog ===============
+
+ /**
+ * New nodes added into session log and not save
+ */
+ public void testGetNodesLazilySessionAddedNodes() throws Exception
+ {
+ // 150 nodes added in setup
+ // adding 10 more nodes without save, so it is missing in persistent layer but exist in session changes log
+ for (int i = 0; i < 10; i++)
+ {
+ testRoot.addNode("child" + nodesCount).setProperty(INDEX_PROPERTY, nodesCount);
+ nodesCount++;
+ }
+
+ assertChildNodes(testRoot, nodesCount);
+ }
+
+ /**
+ * New nodes moved into session log and not save
+ */
+ public void testGetNodesLazilySessionMovedNodes() throws Exception
+ {
+ session.getRootNode().addNode("child" + nodesCount).setProperty(INDEX_PROPERTY, nodesCount);
+ session.save();
+
+ nodesCount++;
+
+ String newNodeName = "child" + (nodesCount - 1);
+
+ session.move("/" + newNodeName, testRoot.getPath() + "/" + newNodeName);
+ assertChildNodes(testRoot, nodesCount);
+
+ testRoot.getNode(newNodeName).remove();
+ nodesCount--;
+
+ assertChildNodes(testRoot, nodesCount);
+
+ session.save();
+ assertChildNodes(testRoot, nodesCount);
+ }
+
+ /**
+ * Change mixin in node.
+ */
+ public void testGetNodesLazilySessionMixinChanged() throws Exception
+ {
+ testRoot.getNode("child0").addMixin("mix:lockable");
+
+ NodeIterator iterator = testRoot.getNodesLazily();
+ NodeImpl node = (NodeImpl)iterator.nextNode();
+
+ assertTrue(node.isNodeType(Constants.MIX_LOCKABLE));
+ }
+
+ /**
+ * New nodes added into session log and not save
+ */
+ public void testGetNodesLazilySessionNewAddedNodes() throws Exception
+ {
+ // adding 150 new nodes
+ NodeImpl localRoot = (NodeImpl)testRoot.addNode("localRoot");
+ for (int i = 0; i < nodesCount; i++)
+ {
+ localRoot.addNode("child" + i).setProperty(INDEX_PROPERTY, i);
+ }
+ assertChildNodes(localRoot, nodesCount);
+ }
+
+ /**
+ * Last 10 nodes removed. Session log has removed states for them
+ */
+ public void testGetNodesLazilySessionRemovedNodes() throws Exception
+ {
+ // 150 nodes added in setup
+ // removing 10 nodes without save
+ for (int i = 0; i < 10; i++)
+ {
+ nodesCount--;
+ testRoot.getNode("child" + nodesCount).remove();
+ }
+ assertChildNodes(testRoot, nodesCount);
+ }
+
+ /**
+ * Session move without save
+ */
+ public void testGetNodesLazilySessionRenamedParent() throws Exception
+ {
+ // 150 nodes added in setup
+ // renaming parent
+ String newName = "new Name";
+ session.move("/" + testRoot.getName(), "/" + newName);
+ NodeImpl newTestRoot = (NodeImpl)root.getNode(newName);
+ assertChildNodes(newTestRoot, nodesCount);
+ }
+
+ /**
+ * All child nodes are in session changes log and both in persisted layer. All they reordered one by one and though must
+ * be returned in same order
+ */
+ public void _testGetNodesLazilySessionReordered() throws Exception
+ {
+ // 150 nodes added in setup
+ // TODO : testcase fails
+ for (int i = nodesCount - 1; i >= 0; i--)
+ {
+ NodeImpl node = (NodeImpl)testRoot.getNode("child" + i);
+ session.move(node.getPath(), node.getPath());
+ }
+ assertChildNodes(testRoot, nodesCount, true);
+ }
+
+ //=============== transactions related ===============
+
+ public void testGetNodesLazilyTransaction() throws Exception
+ {
+ assertNotNull(txService);
+ UserTransaction ut = txService.getUserTransaction();
+ ut.begin();
+
+ NodeImpl localRoot = (NodeImpl)testRoot.addNode("localRoot");
+ for (int i = 0; i < nodesCount; i++)
+ {
+ localRoot.addNode("child" + i).setProperty(INDEX_PROPERTY, i);
+ }
+ // assert within session changes log
+ assertChildNodes(localRoot, nodesCount);
+ session.save();
+ // assert within transaction changes log
+ assertChildNodes(localRoot, nodesCount);
+ ut.commit();
+ // assert within persistent layer
+ assertChildNodes(localRoot, nodesCount);
+ }
+
+ public void testGetNodesLazilyTransactionRollbackAdded() throws Exception
+ {
+ assertNotNull(txService);
+ UserTransaction ut = txService.getUserTransaction();
+ ut.begin();
+
+ int txNodesCount = nodesCount;
+ // 150 nodes added in setup
+ // adding 10 more nodes without save, so it is missing in persistent layer but exist in session changes log
+ for (int i = 0; i < 10; i++)
+ {
+ testRoot.addNode("child" + txNodesCount).setProperty(INDEX_PROPERTY, txNodesCount);
+ txNodesCount++;
+ }
+ session.save();
+ // assert within transaction changes log
+ assertChildNodes(testRoot, txNodesCount);
+ ut.rollback();
+ // assert within persistent layer, nodes should be rolled back
+ assertChildNodes(testRoot, nodesCount);
+ }
+
+ public void testGetNodesLazilyTransactionRollbackRemoved() throws Exception
+ {
+ assertNotNull(txService);
+ UserTransaction ut = txService.getUserTransaction();
+ ut.begin();
+
+ // 150 nodes added in setup
+ // removing 10 nodes
+ int txNodesCount = nodesCount;
+ for (int i = 0; i < 10; i++)
+ {
+ txNodesCount--;
+ testRoot.getNode("child" + txNodesCount).remove();
+ }
+ session.save();
+
+ // assert within transaction changes log
+ assertChildNodes(testRoot, txNodesCount);
+ ut.rollback();
+ // assert within persistent layer, nodes should be rolled back
+ assertChildNodes(testRoot, nodesCount);
+ }
+
+ //=============== test iterator ===============
+
+ public void testGetNodesLazilyIterator() throws Exception
+ {
+ RangeIterator iterator = testRoot.getNodesLazily();
+
+ // there are 150 node, so it must have next
+ assertTrue(iterator.hasNext());
+ // position is before first node
+ assertEquals(0, iterator.getPosition());
+
+ // fetch first one (/child0)
+ iterator.next();
+ assertEquals(1, iterator.getPosition());
+
+ // fetch second one (/child1)
+ iterator.next();
+ assertEquals(2, iterator.getPosition());
+
+ // skip to /child12
+ iterator.skip(10);
+ NodeImpl next = (NodeImpl)iterator.next();
+ assertEquals(13, iterator.getPosition());
+ assertEquals(12, next.getProperty(INDEX_PROPERTY).getLong());
+
+ iterator.skip(1);
+ next = (NodeImpl)iterator.next();
+ assertEquals(15, iterator.getPosition());
+ assertEquals(14, next.getProperty(INDEX_PROPERTY).getLong());
+
+ iterator.skip(100);
+ next = (NodeImpl)iterator.next();
+ assertEquals(116, iterator.getPosition());
+ assertEquals(115, next.getProperty(INDEX_PROPERTY).getLong());
+ }
+
+ //=============== stuff ===============
+
+ /**
+ * Performs complex assert, that retrieves child nodes in a lazy way and asserts it's order, content
+ * and quantity
+ */
+ private void assertChildNodes(ExtendedNode testNode, int expectedSize) throws RepositoryException
+ {
+ assertChildNodes(testNode, expectedSize, false);
+ }
+
+ /**
+ * Performs complex assert, that retrieves child nodes in a lazy way and asserts it's order, content
+ * and quantity
+ */
+ private void assertChildNodes(ExtendedNode testNode, int expectedSize, boolean backwardOrder)
+ throws RepositoryException
+ {
+ NodeIterator lazyIterator = testNode.getNodesLazily();
+
+ // getSize shouldn't return actual size, since it works in a lazy manner and nodes are retrieved "on demand"
+ // int actualSize = (int)lazyIterator.getSize();
+ // assertEquals("getSize should return -1, but returned " + actualSize, -1, actualSize);
+
+ if (expectedSize == 0)
+ {
+ assertFalse(lazyIterator.hasNext());
+ }
+ else
+ {
+ int number = 0;
+ if (!backwardOrder)
+ {
+ int i = 0;
+ while (lazyIterator.hasNext())
+ {
+ Node node = lazyIterator.nextNode();
+
+ long actualNodeIndex = node.getProperty(INDEX_PROPERTY).getLong();
+ assertEquals("Iterator must return nodes ordered by \"order num\". Occurred at: child" + actualNodeIndex
+ + " expecting <" + i + ">", i, actualNodeIndex);
+ i++;
+ number++;
+ }
+ }
+ else
+ {
+ int i = expectedSize - 1;
+ while (lazyIterator.hasNext())
+ {
+ NodeImpl node = (NodeImpl)lazyIterator.nextNode();
+ long actualNodeIndex = node.getProperty(INDEX_PROPERTY).getLong();
+ assertEquals("Iterator must return nodes ordered by \"order num\". Occurred at: child" + actualNodeIndex
+ + " expecting <" + i + ">", i, actualNodeIndex);
+ i--;
+ number++;
+ }
+ }
+
+ // assert all returned
+ assertEquals(
+ "Iterator returned wrong number of nodes. Expected: " + expectedSize + ", but returned " + number,
+ expectedSize, number);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ session.refresh(false);
+ testRoot.remove();
+ session.save();
+ super.tearDown();
+ }
+
+}
\ No newline at end of file
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2011-07-27 14:23:32 UTC (rev 4682)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2011-07-27 14:23:57 UTC (rev 4683)
@@ -422,6 +422,15 @@
return null;
}
+ public List<NodeData> getChildNodesByPage(NodeData parent, int fromOrderNum)
+ {
+ return null;
+ }
+
+ public void addChildNodesByPage(NodeData parent, List<NodeData> childs, int fromOrderNum)
+ {
+ }
+
}
private static class MyWorkspaceStorageConnection implements WorkspaceStorageConnection
12 years, 9 months
exo-jcr SVN: r4682 - jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-07-27 10:23:32 -0400 (Wed, 27 Jul 2011)
New Revision: 4682
Modified:
jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
Log:
EXOJCR-1452: Implementation
Modified: jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml
===================================================================
--- jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2011-07-27 13:44:30 UTC (rev 4681)
+++ jcr/trunk/exo.jcr.docs/exo.jcr.docs.developer/en/src/main/docbook/en-US/modules/jcr/configuration/exo-jcr-configuration.xml 2011-07-27 14:23:32 UTC (rev 4682)
@@ -264,6 +264,18 @@
</row>
</tbody>
</tgroup>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>lazy-node-iterator-page-size</entry>
+
+ <entry>the page size for lazy iterator. Indicates how many nodes
+ can be retrieved from storage per request. The default value is
+ 100</entry>
+ </row>
+ </tbody>
+ </tgroup>
</table>
<para><emphasis role="bold">value-storages</emphasis>: The list of value
12 years, 9 months
exo-jcr SVN: r4681 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2011-07-27 09:44:30 -0400 (Wed, 27 Jul 2011)
New Revision: 4681
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLMultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java
Log:
EXOJCR-1393: mssql range pattern symbols escape added
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLMultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLMultiDbJDBCConnection.java 2011-07-26 11:44:20 UTC (rev 4680)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLMultiDbJDBCConnection.java 2011-07-27 13:44:30 UTC (rev 4681)
@@ -75,7 +75,7 @@
+ " from JCR_SITEM I where I.I_CLASS=1) as A where A.r__ <= ? and A.r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by J.ID";
}
-
+
/**
* {@inheritDoc}
*/
@@ -95,5 +95,36 @@
findNodesAndProperties.setInt(2, offset);
return findNodesAndProperties.executeQuery();
- }
+ }
+
+ /**
+ * Replace underscore in pattern with escaped symbol. Replace jcr-wildcard '*' with sql-wildcard '%'.
+ * <p>
+ * MSSQL have a range pattern '[..]' so we need to escape it too.
+ *
+ * @param pattern
+ * @return pattern with escaped underscore and fixed wildcard symbols
+ */
+ protected String fixEscapeSymbols(String pattern)
+ {
+ char[] chars = pattern.toCharArray();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < chars.length; i++)
+ {
+ switch (chars[i])
+ {
+ case '*' :
+ sb.append('%');
+ break;
+ case '_' :
+ case '%' :
+ case '[' :
+ case ']' :
+ sb.append(getWildcardEscapeSymbold());
+ default :
+ sb.append(chars[i]);
+ }
+ }
+ return sb.toString();
+ }
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java 2011-07-26 11:44:20 UTC (rev 4680)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java 2011-07-27 13:44:30 UTC (rev 4681)
@@ -78,7 +78,7 @@
+ " ) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
}
-
+
/**
* {@inheritDoc}
*/
@@ -100,5 +100,37 @@
findNodesAndProperties.setString(4, containerName);
return findNodesAndProperties.executeQuery();
- }
+ }
+
+ /**
+ * Replace underscore in pattern with escaped symbol. Replace jcr-wildcard '*' with sql-wildcard '%'.
+ * <p>
+ * MSSQL have a range pattern '[..]' so we need to escape it too.
+ *
+ * @param pattern
+ * @return pattern with escaped underscore and fixed wildcard symbols
+ */
+ protected String fixEscapeSymbols(String pattern)
+ {
+ char[] chars = pattern.toCharArray();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < chars.length; i++)
+ {
+ switch (chars[i])
+ {
+ case '*' :
+ sb.append('%');
+ break;
+ case '_' :
+ case '%' :
+ case '[' :
+ case ']' :
+ sb.append(getWildcardEscapeSymbold());
+ default :
+ sb.append(chars[i]);
+ }
+ }
+ return sb.toString();
+ }
+
}
12 years, 9 months
exo-jcr SVN: r4680 - in jcr/trunk/exo.jcr.component.core: src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms and 2 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-07-26 07:44:20 -0400 (Tue, 26 Jul 2011)
New Revision: 4680
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java
Modified:
jcr/trunk/exo.jcr.component.core/pom.xml
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBBackup.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java
Log:
EXOJCR-1287 : The problem with restore RDBMS backup on Sybase was fixed.
Modified: jcr/trunk/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/trunk/exo.jcr.component.core/pom.xml 2011-07-26 11:42:01 UTC (rev 4679)
+++ jcr/trunk/exo.jcr.component.core/pom.xml 2011-07-26 11:44:20 UTC (rev 4680)
@@ -78,6 +78,10 @@
</dependency>
<dependency>
<groupId>org.exoplatform.core</groupId>
+ <artifactId>exo.core.component.database</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exoplatform.core</groupId>
<artifactId>exo.core.component.security.core</artifactId>
</dependency>
<dependency>
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBBackup.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBBackup.java 2011-07-26 11:42:01 UTC (rev 4679)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBBackup.java 2011-07-26 11:44:20 UTC (rev 4680)
@@ -19,6 +19,7 @@
package org.exoplatform.services.jcr.impl.backup.rdbms;
import org.exoplatform.commons.utils.PrivilegedFileHelper;
+import org.exoplatform.services.database.utils.ExceptionManagementHelper;
import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.backup.BackupException;
@@ -112,18 +113,7 @@
}
catch (SQLException e)
{
- SQLException next = e.getNextException();
- String errorTrace = "";
- while (next != null)
- {
- errorTrace += next.getMessage() + "; ";
- next = next.getNextException();
- }
-
- Throwable cause = e.getCause();
- String msg = "SQL Exception: " + errorTrace + (cause != null ? " (Cause: " + cause.getMessage() + ")" : "");
-
- throw new BackupException(msg, e);
+ throw new BackupException("SQL Exception: " + ExceptionManagementHelper.getFullSQLExceptionMessage(e), e);
}
finally
{
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java 2011-07-26 11:42:01 UTC (rev 4679)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/DBRestore.java 2011-07-26 11:44:20 UTC (rev 4680)
@@ -20,6 +20,7 @@
import org.exoplatform.commons.utils.PrivilegedFileHelper;
import org.exoplatform.commons.utils.PrivilegedSystemHelper;
+import org.exoplatform.services.database.utils.ExceptionManagementHelper;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
@@ -98,7 +99,7 @@
/**
* Connection to database.
*/
- private final Connection jdbcConn;
+ protected final Connection jdbcConn;
/**
* Directory with tables dump.
@@ -108,7 +109,7 @@
/**
* Restore table rules.
*/
- private final Map<String, RestoreTableRule> tables;
+ protected final Map<String, RestoreTableRule> tables;
/**
* Database cleaner.
@@ -116,6 +117,16 @@
private final DBClean dbClean;
/**
+ * Database dialect.
+ */
+ protected final int dialect;
+
+ /**
+ * Contains constraint for JCR_SITEM or JCR_MITEM table.
+ */
+ private String constraint;
+
+ /**
* Constructor DBRestor.
*
* @throws NamingException
@@ -135,6 +146,7 @@
this.storageDir = storageDir;
this.tables = tables;
this.dbClean = DBCleanService.getDBCleaner(this.jdbcConn, wsConfig);
+ this.dialect = DialectDetecter.detect(jdbcConn.getMetaData()).hashCode();
}
/**
@@ -157,56 +169,18 @@
*/
public void restore() throws BackupException
{
- Statement st = null;
-
try
{
- int dialect = DialectDetecter.detect(jdbcConn.getMetaData()).hashCode();
-
for (Entry<String, RestoreTableRule> entry : tables.entrySet())
{
String tableName = entry.getKey();
RestoreTableRule restoreRule = entry.getValue();
- String constraint = null;
- if (tableName.equals("JCR_SITEM") || tableName.equals("JCR_MITEM"))
- {
- if (dialect != DBBackup.DB_DIALECT_SYBASE)
- {
- // resolve constraint name depends on database
- String constraintName;
- if (dialect == DBBackup.DB_DIALECT_DB2 || dialect == DBBackup.DB_DIALECT_DB2V8)
- {
- constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PAREN";
- }
- else
- {
- constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PARENT";
- }
- constraint =
- "CONSTRAINT " + constraintName + " FOREIGN KEY(PARENT_ID) REFERENCES " + tableName + "(ID)";
+ preRestoreTable(tableName, restoreRule);
- // drop constraint
- st = jdbcConn.createStatement();
-
- if (dialect == DBBackup.DB_DIALECT_MYSQL || dialect == DBBackup.DB_DIALECT_MYSQL_UTF8)
- {
- st.execute("ALTER TABLE " + tableName + " DROP FOREIGN KEY " + constraintName);
- }
- else
- {
- st.execute("ALTER TABLE " + tableName + " DROP CONSTRAINT " + constraintName);
- }
- }
- }
-
restoreTable(storageDir, jdbcConn, tableName, restoreRule);
- if (constraint != null)
- {
- // add constraint
- st.execute("ALTER TABLE " + tableName + " ADD " + constraint);
- }
+ postRestoreTable(tableName, restoreRule);
}
}
catch (IOException e)
@@ -215,21 +189,99 @@
}
catch (SQLException e)
{
- SQLException next = e.getNextException();
- String errorTrace = "";
- while (next != null)
+ throw new BackupException("SQL Exception: " + ExceptionManagementHelper.getFullSQLExceptionMessage(e), e);
+ }
+ }
+
+ /**
+ * Prepare of restore table. (Drop constraint, etc...)
+ *
+ * @param tableName
+ * name of table
+ * @param restoreRule
+ * rule of table
+ * @throws SQLException
+ * Will throw SQLException if fail.
+ */
+ public void preRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+ {
+ Statement st = null;
+
+ try
+ {
+ if (tableName.equals("JCR_SITEM") || tableName.equals("JCR_MITEM"))
{
- errorTrace += next.getMessage() + "; ";
- next = next.getNextException();
+ // resolve constraint name depends on database
+ String constraintName;
+ if (dialect == DBBackup.DB_DIALECT_DB2 || dialect == DBBackup.DB_DIALECT_DB2V8)
+ {
+ constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PAREN";
+ }
+ else
+ {
+ constraintName = "JCR_FK_" + (restoreRule.getDstMultiDb() ? "M" : "S") + "ITEM_PARENT";
+ }
+ constraint = "CONSTRAINT " + constraintName + " FOREIGN KEY(PARENT_ID) REFERENCES " + tableName + "(ID)";
+
+ // drop constraint
+ st = jdbcConn.createStatement();
+
+ if (dialect == DBBackup.DB_DIALECT_MYSQL || dialect == DBBackup.DB_DIALECT_MYSQL_UTF8)
+ {
+ st.execute("ALTER TABLE " + tableName + " DROP FOREIGN KEY " + constraintName);
+ }
+ else
+ {
+ st.execute("ALTER TABLE " + tableName + " DROP CONSTRAINT " + constraintName);
+ }
}
+ }
+ finally
+ {
+ if (st != null)
+ {
+ try
+ {
+ st.close();
+ }
+ catch (SQLException e)
+ {
+ LOG.warn("Can't close statemnt", e);
+ }
+ }
+ }
+ }
- Throwable cause = e.getCause();
- String msg = "SQL Exception: " + errorTrace + (cause != null ? " (Cause: " + cause.getMessage() + ")" : "");
+ /**
+ * After of restore table. (Add constraint, etc...)
+ *
+ * @param tableName
+ * name of table
+ * @param restoreRule
+ * rule of table
+ * @throws SQLException
+ * Will throw SQLException if fail.
+ */
+ public void postRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+ {
+ Statement st = null;
- throw new BackupException(msg, e);
+ try
+ {
+ if (tableName.equals("JCR_SITEM") || tableName.equals("JCR_MITEM"))
+ {
+ if (constraint != null)
+ {
+ // add constraint
+ st = jdbcConn.createStatement();
+ st.execute("ALTER TABLE " + tableName + " ADD " + constraint);
+ }
+ }
}
finally
{
+ constraint = null;
+
if (st != null)
{
try
@@ -312,8 +364,6 @@
PreparedStatement insertNode = null;
ResultSet tableMetaData = null;
- int dialect = DialectDetecter.detect(jdbcConn.getMetaData()).hashCode();
-
// switch table name to lower case
if (dialect == DBBackup.DB_DIALECT_PGSQL)
{
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/backup/rdbms/SybaseDBRestore.java 2011-07-26 11:44:20 UTC (rev 4680)
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2003-2011 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.backup.rdbms;
+
+import org.exoplatform.services.database.utils.ExceptionManagementHelper;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
+import org.exoplatform.services.jcr.impl.backup.BackupException;
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.naming.NamingException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: SybaseDBRestore.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class SybaseDBRestore
+ extends DBRestore
+{
+ private String restoreConstraint = null;
+
+ public SybaseDBRestore(File storageDir, Connection jdbcConn, Map<String, RestoreTableRule> tables,
+ WorkspaceEntry wsConfig, FileCleaner fileCleaner) throws NamingException, SQLException,
+ RepositoryConfigurationException
+ {
+ super(storageDir, jdbcConn, tables, wsConfig, fileCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clean() throws BackupException
+ {
+
+ try
+ {
+ // the Sybase is not allowed DDL query (CREATE TABLE, DROP TABLE, etc. ) within a multi-statement transaction
+ jdbcConn.setAutoCommit(true);
+
+ for (Entry<String, RestoreTableRule> entry : tables.entrySet())
+ {
+ String tableName = entry.getKey();
+ RestoreTableRule restoreRule = entry.getValue();
+
+ super.preRestoreTable(tableName, restoreRule);
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(ExceptionManagementHelper.getFullSQLExceptionMessage(e), e);
+ }
+ finally
+ {
+ try
+ {
+ jdbcConn.setAutoCommit(false);
+ }
+ catch (SQLException e)
+ {
+ LOG.warn("Can't set auto commit to \"false\"", e);
+ }
+ }
+
+ super.clean();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void commit() throws BackupException
+ {
+ super.commit();
+
+ restoreConstraint();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rollback() throws BackupException
+ {
+ BackupException rollbackException = null;
+
+ try
+ {
+ super.rollback();
+ }
+ catch (BackupException e)
+ {
+ rollbackException = e;
+ throw rollbackException;
+ }
+ finally
+ {
+ try
+ {
+ restoreConstraint();
+ }
+ catch (BackupException e)
+ {
+ if (rollbackException != null)
+ {
+ LOG.error("Can not restore constraint", e);
+ throw rollbackException;
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ * Restore constraint.
+ *
+ * @throws BackupException
+ * Will throw BackupException if fail.
+ */
+ private void restoreConstraint() throws BackupException
+ {
+ try
+ {
+ // restore constraint
+ jdbcConn.setAutoCommit(true);
+
+ for (Entry<String, RestoreTableRule> entry : tables.entrySet())
+ {
+ String tableName = entry.getKey();
+ RestoreTableRule restoreRule = entry.getValue();
+
+ super.postRestoreTable(tableName, restoreRule);
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new BackupException(e);
+ }
+ finally
+ {
+ try
+ {
+ jdbcConn.setAutoCommit(false);
+ }
+ catch (SQLException e)
+ {
+ LOG.warn("Can't set auto commit to \"false\"", e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void preRestoreTable(String tableName, RestoreTableRule restoreRule) throws SQLException
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void postRestoreTable(String tableName, RestoreTableRule restoreRule) 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-07-26 11:42:01 UTC (rev 4679)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-07-26 11:44:20 UTC (rev 4680)
@@ -36,6 +36,7 @@
import org.exoplatform.services.jcr.impl.backup.rdbms.DBRestore;
import org.exoplatform.services.jcr.impl.backup.rdbms.DirectoryRestore;
import org.exoplatform.services.jcr.impl.backup.rdbms.RestoreTableRule;
+import org.exoplatform.services.jcr.impl.backup.rdbms.SybaseDBRestore;
import org.exoplatform.services.jcr.impl.clean.rdbms.DBCleanService;
import org.exoplatform.services.jcr.impl.core.query.NodeDataIndexingIterator;
import org.exoplatform.services.jcr.impl.core.query.Reindexable;
@@ -1083,7 +1084,7 @@
if (multiDb)
{
- scripts.put("JCR_MITEM", "select * from JCR_MITEM where JCR_MITEM.name <> '" + Constants.ROOT_PARENT_NAME
+ scripts.put("JCR_MITEM", "select * from JCR_MITEM where JCR_MITEM.NAME <> '" + Constants.ROOT_PARENT_NAME
+ "'");
scripts.put("JCR_MVALUE", "select * from JCR_MVALUE");
scripts.put("JCR_MREF", "select * from JCR_MREF");
@@ -1272,7 +1273,14 @@
}
tables.put(dstTableName, restoreTableRule);
- restorers.add(new DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
+ if (dbDialect == DBConstants.DB_DIALECT_SYBASE)
+ {
+ restorers.add(new SybaseDBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
+ }
+ else
+ {
+ restorers.add(new DBRestore(storageDir, jdbcConn, tables, wsConfig, swapCleaner));
+ }
// prepare value storage restorer
File backupValueStorageDir = new File(storageDir, "values");
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java 2011-07-26 11:42:01 UTC (rev 4679)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/jdbc/DBInitializer.java 2011-07-26 11:44:20 UTC (rev 4680)
@@ -19,6 +19,7 @@
package org.exoplatform.services.jcr.impl.util.jdbc;
import org.exoplatform.commons.utils.SecurityHelper;
+import org.exoplatform.services.database.utils.ExceptionManagementHelper;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCUtils;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -409,18 +410,9 @@
}
else
{
- SQLException next = e.getNextException();
- String errorTrace = "";
- while (next != null)
- {
- errorTrace += next.getMessage() + "; ";
- next = next.getNextException();
- }
- Throwable cause = e.getCause();
String msg =
- "Could not create db schema of DataSource: '" + containerName + "'. Reason: " + e.getMessage() + "; "
- + errorTrace + (cause != null ? " (Cause: " + cause.getMessage() + ")" : "") + ". Last command: "
- + sql;
+ "Could not create db schema of DataSource: '" + containerName + "'. Reason: " + e.getMessage() + "; "
+ + ExceptionManagementHelper.getFullSQLExceptionMessage(e) + ". Last command: " + sql;
throw new DBInitializerException(msg, e);
}
12 years, 9 months
exo-jcr SVN: r4679 - in core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database: creator and 2 other directories.
by do-not-reply@jboss.org
Author: areshetnyak
Date: 2011-07-26 07:42:01 -0400 (Tue, 26 Jul 2011)
New Revision: 4679
Added:
core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/utils/
core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/utils/ExceptionManagementHelper.java
Modified:
core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/creator/DBCreator.java
core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/jdbc/DBSchemaCreator.java
Log:
EXOJCR-1287 : Add ExceptionManagementHelper.
Modified: core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/creator/DBCreator.java
===================================================================
--- core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/creator/DBCreator.java 2011-07-25 09:18:04 UTC (rev 4678)
+++ core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/creator/DBCreator.java 2011-07-26 11:42:01 UTC (rev 4679)
@@ -25,6 +25,7 @@
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.container.xml.PropertiesParam;
import org.exoplatform.container.xml.Property;
+import org.exoplatform.services.database.utils.ExceptionManagementHelper;
import java.io.IOException;
import java.io.InputStream;
@@ -242,14 +243,7 @@
}
catch (SQLException e)
{
- String errorTrace = "";
- while (e != null)
- {
- errorTrace += e.getMessage() + "; ";
- e = e.getNextException();
- }
-
- throw new DBCreatorException("Can't execute SQL script " + errorTrace);
+ throw new DBCreatorException("Can't execute SQL script : " + ExceptionManagementHelper.getFullSQLExceptionMessage(e));
}
finally
{
Modified: core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/jdbc/DBSchemaCreator.java
===================================================================
--- core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/jdbc/DBSchemaCreator.java 2011-07-25 09:18:04 UTC (rev 4678)
+++ core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/jdbc/DBSchemaCreator.java 2011-07-26 11:42:01 UTC (rev 4679)
@@ -19,6 +19,7 @@
package org.exoplatform.services.database.jdbc;
import org.exoplatform.container.component.ComponentPlugin;
+import org.exoplatform.services.database.utils.ExceptionManagementHelper;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.naming.InitialContextInitializer;
@@ -137,16 +138,8 @@
}
catch (SQLException e)
{
- SQLException next = e.getNextException();
- String errorTrace = "";
- while (next != null)
- {
- errorTrace += next.getMessage() + "; ";
- next = next.getNextException();
- }
- Throwable cause = e.getCause();
log.error("Could not create db schema of DataSource: '" + dsName + "'. Reason: " + e.getMessage() + "; "
- + errorTrace + (cause != null ? " (Cause: " + cause.getMessage() + ")" : "") + ". Last command: " + sql, e);
+ + ExceptionManagementHelper.getFullSQLExceptionMessage(e) + ". Last command: " + sql, e);
}
finally
{
Added: core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/utils/ExceptionManagementHelper.java
===================================================================
--- core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/utils/ExceptionManagementHelper.java (rev 0)
+++ core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/utils/ExceptionManagementHelper.java 2011-07-26 11:42:01 UTC (rev 4679)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003-2011 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.database.utils;
+
+import java.sql.SQLException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date: 2011
+ *
+ * @author <a href="mailto:alex.reshetnyak@exoplatform.com.ua">Alex Reshetnyak</a>
+ * @version $Id: ExceptionManagementHelper.java 111 2011-11-11 11:11:11Z rainf0x $
+ */
+public class ExceptionManagementHelper
+{
+ /**
+ * Prepare message from SQLException.
+ *
+ * @param e
+ * SQLException
+ * @return String
+ * The message form SQLException
+ */
+ public static String getFullSQLExceptionMessage(SQLException e)
+ {
+ SQLException next = e.getNextException();
+ String errorTrace = "";
+ while (next != null)
+ {
+ errorTrace += next.getMessage() + "; ";
+ next = next.getNextException();
+ }
+
+ Throwable cause = e.getCause();
+
+ return errorTrace + (cause != null ? " (Cause: " + cause.getMessage() + ")" : "");
+ }
+}
Property changes on: core/trunk/exo.core.component.database/src/main/java/org/exoplatform/services/database/utils/ExceptionManagementHelper.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
12 years, 9 months