Schema changes and ID-based node storage

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2727 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-04-28 12:54:29 +00:00
parent 2b251c922b
commit 7edcb18bc0
64 changed files with 2798 additions and 2820 deletions

View File

@@ -376,10 +376,10 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest
private int countNodesById(NodeRef nodeRef)
{
String query =
"select count(node.key.guid)" +
"select count(node.uuid)" +
" from " +
NodeImpl.class.getName() + " node" +
" where node.key.guid = ?";
" where node.uuid = ?";
Session session = getSession();
List results = session.createQuery(query)
.setString(0, nodeRef.getId())
@@ -710,7 +710,7 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest
"select node.childAssocs" +
" from " +
NodeImpl.class.getName() + " node" +
" where node.key.guid = ?";
" where node.uuid = ?";
Session session = getSession();
List results = session.createQuery(query)
.setString(0, nodeRef.getId())

View File

@@ -31,13 +31,11 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.NodeAssoc;
import org.alfresco.repo.domain.NodeKey;
import org.alfresco.repo.domain.NodeStatus;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.domain.Store;
import org.alfresco.repo.node.AbstractNodeServiceImpl;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
@@ -92,9 +90,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
*/
private Node getNodeNotNull(NodeRef nodeRef) throws InvalidNodeRefException
{
String protocol = nodeRef.getStoreRef().getProtocol();
String identifier = nodeRef.getStoreRef().getIdentifier();
Node unchecked = nodeDaoService.getNode(protocol, identifier, nodeRef.getId());
Node unchecked = nodeDaoService.getNode(nodeRef);
if (unchecked == null)
{
throw new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef);
@@ -112,10 +108,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
public boolean exists(NodeRef nodeRef)
{
StoreRef storeRef = nodeRef.getStoreRef();
Node node = nodeDaoService.getNode(storeRef.getProtocol(),
storeRef.getIdentifier(),
nodeRef.getId());
Node node = nodeDaoService.getNode(nodeRef);
boolean exists = (node != null);
// done
return exists;
@@ -123,10 +116,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
public Status getNodeStatus(NodeRef nodeRef)
{
NodeStatus nodeStatus = nodeDaoService.getNodeStatus(
nodeRef.getStoreRef().getProtocol(),
nodeRef.getStoreRef().getIdentifier(),
nodeRef.getId());
NodeStatus nodeStatus = nodeDaoService.getNodeStatus(nodeRef);
if (nodeStatus == null) // node never existed
{
return null;
@@ -416,8 +406,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
invokeOnUpdateNode(newParentRef);
// update the node status
NodeStatus nodeStatus = nodeToMove.getStatus();
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
nodeDaoService.recordChangeId(nodeToMoveRef);
// done
return newAssoc.getChildAssocRef();
@@ -526,8 +515,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
invokeOnAddAspect(nodeRef, aspectTypeQName);
// update the node status
NodeStatus nodeStatus = node.getStatus();
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
nodeDaoService.recordChangeId(nodeRef);
}
}
@@ -581,8 +569,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
invokeOnRemoveAspect(nodeRef, aspectTypeQName);
// update the node status
NodeStatus nodeStatus = node.getStatus();
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
nodeDaoService.recordChangeId(nodeRef);
}
}
@@ -758,7 +745,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
{
Node parentNode = getNodeNotNull(parentRef);
Node childNode = getNodeNotNull(childRef);
NodeKey childNodeKey = childNode.getKey();
Long childNodeId = childNode.getId();
// get all the child assocs
ChildAssociationRef primaryAssocRef = null;
@@ -766,7 +753,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
assocs = new HashSet<ChildAssoc>(assocs); // copy set as we will be modifying it
for (ChildAssoc assoc : assocs)
{
if (!assoc.getChild().getKey().equals(childNodeKey))
if (!assoc.getChild().getId().equals(childNodeId))
{
continue; // not a matching association
}
@@ -901,8 +888,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
invokeOnUpdateProperties(nodeRef, propertiesBefore, propertiesAfter);
// update the node status
NodeStatus nodeStatus = node.getStatus();
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
nodeDaoService.recordChangeId(nodeRef);
}
/**
@@ -937,8 +923,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
invokeOnUpdateProperties(nodeRef, propertiesBefore, propertiesAfter);
// update the node status
NodeStatus nodeStatus = node.getStatus();
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
nodeDaoService.recordChangeId(nodeRef);
}
/**

View File

@@ -190,19 +190,13 @@ public class DbNodeServiceImplTest extends BaseNodeServiceTest
public Object doWork()
{
// check n6
NodeStatus n6Status = nodeDaoService.getNodeStatus(
n6Ref.getStoreRef().getProtocol(),
n6Ref.getStoreRef().getIdentifier(),
n6Ref.getId());
NodeStatus n6Status = nodeDaoService.getNodeStatus(n6Ref);
if (!n6Status.isDeleted())
{
throw new RuntimeException("Deleted node does not have deleted status");
}
// n8 is a primary child - it should be deleted too
NodeStatus n8Status = nodeDaoService.getNodeStatus(
n8Ref.getStoreRef().getProtocol(),
n8Ref.getStoreRef().getIdentifier(),
n8Ref.getId());
NodeStatus n8Status = nodeDaoService.getNodeStatus(n8Ref);
if (!n8Status.isDeleted())
{
throw new RuntimeException("Cascade-deleted node does not have deleted status");

View File

@@ -25,6 +25,7 @@ import org.alfresco.repo.domain.NodeAssoc;
import org.alfresco.repo.domain.NodeStatus;
import org.alfresco.repo.domain.Store;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
@@ -63,24 +64,40 @@ public interface NodeDaoService
* @return Returns a store with the given values or null if one doesn't exist
*/
public Store getStore(String protocol, String identifier);
/**
* Gets the node's status. If the node <i>never</i> existed, then
* <code>null</code> is returned.
*
* @param nodeRef the node reference
* @return Returns the node status if the node exists or once existed, otherwise
* returns <code>null</code>.
*/
public NodeStatus getNodeStatus(NodeRef nodeRef);
/**
* Sets the current transaction ID on the node status. Note that the node
* may not exist, but the status will.
*
* @param nodeRef the node reference
*/
public void recordChangeId(NodeRef nodeRef);
/**
* @param store the store to which the node must belong
* @param id the node store-unique identifier
* @param uuid the node store-unique identifier
* @param nodeTypeQName the type of the node
* @return Returns a new node of the given type and attached to the store
* @throws InvalidTypeException if the node type is invalid or if the node type
* is not a valid real node
*/
public Node newNode(Store store, String id, QName nodeTypeQName) throws InvalidTypeException;
public Node newNode(Store store, String uuid, QName nodeTypeQName) throws InvalidTypeException;
/**
* @param protocol the store protocol
* @param identifier the store identifier for the given protocol
* @param id the store-specific node identifier
* @param nodeRef the node reference
* @return Returns the <b>node</b> entity
*/
public Node getNode(String protocol, String identifier, String id);
public Node getNode(NodeRef nodeRef);
/**
* Deletes the node instance, taking care of any cascades that are required over
@@ -165,18 +182,6 @@ public interface NodeDaoService
*/
public void deleteNodeAssoc(NodeAssoc assoc);
/**
* Gets the node's status. If the node <i>never</i> existed, then
* <code>null</code> is returned.
*
* @param protocol the store protocol
* @param identifier the store identifier for the given protocol
* @param id the store-specific node status identifier
* @return Returns the node status if the node exists or once existed, otherwise
* returns <code>null</code>.
*/
public NodeStatus getNodeStatus(String protocol, String identifier, String id);
/**
* Fetch all content data strings. These are all string values that begin
* with <b>contentUrl=</b>.

View File

@@ -37,6 +37,7 @@ import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.hibernate.ObjectDeletedException;
@@ -173,59 +174,91 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
return store;
}
public Node newNode(Store store, String id, QName nodeTypeQName) throws InvalidTypeException
{
NodeKey key = new NodeKey(store.getKey(), id);
// create (or reuse) the mandatory node status
NodeStatus nodeStatus = (NodeStatus) getHibernateTemplate().get(NodeStatusImpl.class, key);
if (nodeStatus == null)
{
nodeStatus = new NodeStatusImpl();
}
// set required status properties
nodeStatus.setKey(key);
nodeStatus.setDeleted(false);
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
// persist the nodestatus
getHibernateTemplate().save(nodeStatus);
// build a concrete node based on a bootstrap type
Node node = new NodeImpl();
// set other required properties
node.setKey(key);
node.setTypeQName(nodeTypeQName);
node.setStore(store);
node.setStatus(nodeStatus);
// persist the node
getHibernateTemplate().save(node);
// done
return node;
}
public Node getNode(String protocol, String identifier, String id)
/**
* Fetch the node status, if it exists
*/
public NodeStatus getNodeStatus(NodeRef nodeRef)
{
try
{
NodeKey nodeKey = new NodeKey(protocol, identifier, id);
Object obj = getHibernateTemplate().get(NodeImpl.class, nodeKey);
NodeKey nodeKey = new NodeKey(nodeRef);
Object obj = getHibernateTemplate().get(NodeStatusImpl.class, nodeKey);
// done
return (Node) obj;
}
catch (ObjectDeletedException e)
{
return null;
return (NodeStatus) obj;
}
catch (DataAccessException e)
{
if (e.contains(ObjectDeletedException.class))
{
// the object no loner exists
// the object no longer exists
return null;
}
throw e;
}
}
public void recordChangeId(NodeRef nodeRef)
{
NodeKey key = new NodeKey(nodeRef);
NodeStatus status = (NodeStatus) getHibernateTemplate().get(NodeStatusImpl.class, key);
if (status == null)
{
// the node never existed or the status was deleted
return;
}
else
{
status.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
}
}
public Node newNode(Store store, String uuid, QName nodeTypeQName) throws InvalidTypeException
{
NodeKey key = new NodeKey(store.getKey(), uuid);
// build a concrete node based on a bootstrap type
Node node = new NodeImpl();
// set other required properties
node.setStore(store);
node.setUuid(uuid);
node.setTypeQName(nodeTypeQName);
// persist the node
getHibernateTemplate().save(node);
// create (or reuse) the mandatory node status
NodeStatus status = (NodeStatus) getHibernateTemplate().get(NodeStatusImpl.class, key);
if (status == null)
{
status = new NodeStatusImpl();
status.setKey(key);
}
// set required status properties
status.setNode(node);
status.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
// persist the nodestatus
getHibernateTemplate().save(status);
// done
return node;
}
public Node getNode(NodeRef nodeRef)
{
// get it via the node status
NodeStatus status = getNodeStatus(nodeRef);
if (status == null)
{
// no status implies no node
return null;
}
else
{
// a status may have a node
Node node = status.getNode();
return node;
}
}
/**
* Manually ensures that all cascading of associations is taken care of
@@ -261,37 +294,23 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
deleteNodeAssoc(assoc);
}
// update the node status
NodeStatus nodeStatus = node.getStatus();
nodeStatus.setDeleted(true);
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
NodeRef nodeRef = node.getNodeRef();
NodeStatus nodeStatus = getNodeStatus(nodeRef);
if (nodeStatus == null)
{
logger.warn("Node to be deleted does not have a status: \n" +
" node: " + node.getId());
}
else
{
nodeStatus.setNode(null);
nodeStatus.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
}
// finally delete the node
getHibernateTemplate().delete(node);
// done
}
/**
* Fetch the node status, if it exists
*/
public NodeStatus getNodeStatus(String protocol, String identifier, String id)
{
try
{
NodeKey nodeKey = new NodeKey(protocol, identifier, id);
Object obj = getHibernateTemplate().get(NodeStatusImpl.class, nodeKey);
// done
return (NodeStatus) obj;
}
catch (DataAccessException e)
{
if (e.contains(ObjectDeletedException.class))
{
// the object no loner exists
return null;
}
throw e;
}
}
public ChildAssoc newChildAssoc(
Node parentNode,
Node childNode,
@@ -427,21 +446,15 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
final Node targetNode,
final QName assocTypeQName)
{
final NodeKey sourceKey = sourceNode.getKey();
final NodeKey targetKey = targetNode.getKey();
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC);
query.setString("sourceKeyProtocol", sourceKey.getProtocol())
.setString("sourceKeyIdentifier", sourceKey.getIdentifier())
.setString("sourceKeyGuid", sourceKey.getGuid())
query.setEntity("sourceNode", sourceNode)
.setEntity("targetNode", targetNode)
.setString("assocTypeQName", assocTypeQName.toString())
.setString("targetKeyProtocol", targetKey.getProtocol())
.setString("targetKeyIdentifier", targetKey.getIdentifier())
.setString("targetKeyGuid", targetKey.getGuid());
query.setMaxResults(1);
.setMaxResults(1);
return query.uniqueResult();
}
};
@@ -458,15 +471,12 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
@SuppressWarnings("unchecked")
public Collection<Node> getNodeAssocTargets(final Node sourceNode, final QName assocTypeQName)
{
final NodeKey sourceKey = sourceNode.getKey();
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC_TARGETS);
query.setString("sourceKeyProtocol", sourceKey.getProtocol())
.setString("sourceKeyIdentifier", sourceKey.getIdentifier())
.setString("sourceKeyGuid", sourceKey.getGuid())
query.setEntity("sourceNode", sourceNode)
.setString("assocTypeQName", assocTypeQName.toString());
return query.list();
}
@@ -479,15 +489,12 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
@SuppressWarnings("unchecked")
public Collection<Node> getNodeAssocSources(final Node targetNode, final QName assocTypeQName)
{
final NodeKey targetKey = targetNode.getKey();
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_NODE_ASSOC_SOURCES);
query.setString("targetKeyProtocol", targetKey.getProtocol())
.setString("targetKeyIdentifier", targetKey.getIdentifier())
.setString("targetKeyGuid", targetKey.getGuid())
query.setEntity("targetNode", targetNode)
.setString("assocTypeQName", assocTypeQName.toString());
return query.list();
}