Skip to content

Commit

Permalink
Merge pull request #11050 from pontusmelke/3.4-more-traversal
Browse files Browse the repository at this point in the history
Relationship properties in Kernel API
  • Loading branch information
pontusmelke committed Feb 25, 2018
2 parents 499efdd + 219b97f commit 0079c91
Show file tree
Hide file tree
Showing 71 changed files with 1,236 additions and 368 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@
import org.neo4j.internal.kernel.api.NodeCursor;
import org.neo4j.internal.kernel.api.PropertyCursor;
import org.neo4j.internal.kernel.api.Read;
import org.neo4j.internal.kernel.api.RelationshipScanCursor;
import org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.internal.kernel.api.helpers.RelationshipSelectionCursor;
import org.neo4j.internal.kernel.api.helpers.RelationshipSelections;
import org.neo4j.kernel.api.StatementConstants;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.storageengine.api.EntityType;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.Values;
Expand Down Expand Up @@ -119,6 +120,37 @@ public static RelationshipSelectionCursor nodeGetRelationships( Read read, Curso
}
}

/**
* Fetches a given property from a relationship
*
* @param read The current Read instance
* @param relationship The node cursor to use
* @param node The id of the node
* @param propertyCursor The property cursor to use
* @param prop The id of the property to find
* @return The value of the given property
* @throws EntityNotFoundException If the node cannot be find.
*/
public static Value relationshipGetProperty( Read read, RelationshipScanCursor relationship, long node, PropertyCursor propertyCursor,
int prop ) throws EntityNotFoundException
{
if ( prop == StatementConstants.NO_SUCH_PROPERTY_KEY )
{
return Values.NO_VALUE;
}
singleRelationship( read, relationship, node );
relationship.properties( propertyCursor );
while ( propertyCursor.next() )
{
if ( propertyCursor.propertyKey() == prop )
{
return propertyCursor.propertyValue();
}
}

return Values.NO_VALUE;
}

public static RelationshipSelectionCursor nodeGetRelationships( Read read, CursorFactory cursors, NodeCursor node,
long nodeId,
Direction direction )
Expand All @@ -134,5 +166,14 @@ private static void singleNode( Read read, NodeCursor nodeCursor, long node ) th
throw new EntityNotFoundException( EntityType.NODE, node );
}
}

private static void singleRelationship( Read read, RelationshipScanCursor relationships, long relationship ) throws EntityNotFoundException
{
read.singleRelationship( relationship, relationships );
if ( !relationships.next() )
{
throw new EntityNotFoundException( EntityType.NODE, relationship );
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
import org.neo4j.internal.kernel.api.CursorFactory;
import org.neo4j.internal.kernel.api.NodeCursor;
import org.neo4j.internal.kernel.api.Read;
import org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.internal.kernel.api.helpers.RelationshipSelectionCursor;
import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException;

public abstract class CompiledExpandUtils
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import org.neo4j.kernel.impl.api.store.RelationshipIterator
import org.neo4j.kernel.impl.core.EmbeddedProxySPI
import org.neo4j.values.AnyValue
import org.neo4j.values.storable.Value
import org.neo4j.values.virtual.{RelationshipValue, ListValue, NodeValue}
import org.neo4j.values.virtual.{ListValue, NodeValue, RelationshipValue}

import scala.collection.Iterator

Expand Down Expand Up @@ -81,9 +81,6 @@ class ExceptionTranslatingQueryContext(val inner: QueryContext) extends QueryCon
override def removeLabelsFromNode(node: Long, labelIds: Iterator[Int]): Int =
translateException(inner.removeLabelsFromNode(node, labelIds))

override def getPropertiesForRelationship(relId: Long): Iterator[Int] =
translateException(inner.getPropertiesForRelationship(relId))

override def getPropertyKeyName(propertyKeyId: Int): String =
translateException(inner.getPropertyKeyName(propertyKeyId))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ import org.neo4j.graphdb.RelationshipType._
import org.neo4j.graphdb._
import org.neo4j.graphdb.security.URLAccessValidationError
import org.neo4j.graphdb.traversal.{Evaluators, TraversalDescription, Uniqueness}
import org.neo4j.internal.kernel.api
import org.neo4j.internal.kernel.api.{IndexQuery, InternalIndexState}
import org.neo4j.kernel.GraphDatabaseQueryService
import org.neo4j.kernel.api.exceptions.schema.{AlreadyConstrainedException, AlreadyIndexedException}
import org.neo4j.kernel.api.schema.SchemaDescriptorFactory
import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptorFactory
import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory
import org.neo4j.kernel.api.{exceptions, _}
import org.neo4j.kernel.api.{SilentTokenNameLookup, StatementConstants}
import org.neo4j.kernel.impl.core.EmbeddedProxySPI
import org.neo4j.values.storable.Values

Expand Down Expand Up @@ -273,15 +274,15 @@ final class TransactionBoundQueryContext(tc: TransactionalContextWrapper)
try {
tc.statement.dataWriteOperations().nodeDelete(obj.getId)
} catch {
case _: exceptions.EntityNotFoundException => // node has been deleted by another transaction, oh well...
case _: api.exceptions.EntityNotFoundException => // node has been deleted by another transaction, oh well...
}
}

def detachDelete(obj: Node): Int = {
try {
tc.statement.dataWriteOperations().nodeDetachDelete(obj.getId)
} catch {
case _: exceptions.EntityNotFoundException => // the node has been deleted by another transaction, oh well...
case _: api.exceptions.EntityNotFoundException => // the node has been deleted by another transaction, oh well...
0
}
}
Expand All @@ -297,35 +298,35 @@ final class TransactionBoundQueryContext(tc: TransactionalContextWrapper)
override def next(): Int = try {
inner.next()
} catch {
case _: exceptions.EntityNotFoundException => null.asInstanceOf[Int]
case _: api.exceptions.EntityNotFoundException => null.asInstanceOf[Int]
}
}
} catch {
case _: exceptions.EntityNotFoundException => Iterator.empty
case _: api.exceptions.EntityNotFoundException => Iterator.empty
}

def getProperty(id: Long, propertyKeyId: Int): Any = try {
tc.statement.readOperations().nodeGetProperty(id, propertyKeyId).asObject()
} catch {
case _: exceptions.EntityNotFoundException => null.asInstanceOf[Int]
case _: api.exceptions.EntityNotFoundException => null.asInstanceOf[Int]
}

def hasProperty(id: Long, propertyKey: Int): Boolean = try {
tc.statement.readOperations().nodeHasProperty(id, propertyKey)
} catch {
case _: exceptions.EntityNotFoundException => false
case _: api.exceptions.EntityNotFoundException => false
}

def removeProperty(id: Long, propertyKeyId: Int): Unit = try {
tc.statement.dataWriteOperations().nodeRemoveProperty(id, propertyKeyId)
} catch {
case _: exceptions.EntityNotFoundException => //ignore
case _: api.exceptions.EntityNotFoundException => //ignore
}

def setProperty(id: Long, propertyKeyId: Int, value: Any): Unit = try {
tc.statement.dataWriteOperations().nodeSetProperty(id, propertyKeyId, Values.of(value))
} catch {
case _: exceptions.EntityNotFoundException => //ignore
case _: api.exceptions.EntityNotFoundException => //ignore
}

override def getById(id: Long): Node =
Expand All @@ -352,7 +353,7 @@ final class TransactionBoundQueryContext(tc: TransactionalContextWrapper)
try {
tc.statement.dataWriteOperations().relationshipDelete(obj.getId)
} catch {
case _: exceptions.EntityNotFoundException => // node has been deleted by another transaction, oh well...
case _: api.exceptions.EntityNotFoundException => // node has been deleted by another transaction, oh well...
}
}

Expand All @@ -367,43 +368,43 @@ final class TransactionBoundQueryContext(tc: TransactionalContextWrapper)
override def next(): Int = try {
inner.next()
} catch {
case _: exceptions.EntityNotFoundException => null.asInstanceOf[Int]
case _: api.exceptions.EntityNotFoundException => null.asInstanceOf[Int]
}
}
} catch {
case _: exceptions.EntityNotFoundException => Iterator.empty
case _: api.exceptions.EntityNotFoundException => Iterator.empty
}

override def getProperty(id: Long, propertyKeyId: Int): Any = try {
tc.statement.readOperations().relationshipGetProperty(id, propertyKeyId).asObject()
} catch {
case _: exceptions.EntityNotFoundException => null
case _: api.exceptions.EntityNotFoundException => null
}

override def hasProperty(id: Long, propertyKey: Int): Boolean = try {
tc.statement.readOperations().relationshipHasProperty(id, propertyKey)
} catch {
case _: exceptions.EntityNotFoundException => false
case _: api.exceptions.EntityNotFoundException => false
}

override def removeProperty(id: Long, propertyKeyId: Int): Unit = try {
tc.statement.dataWriteOperations().relationshipRemoveProperty(id, propertyKeyId)
} catch {
case _: exceptions.EntityNotFoundException => //ignore
case _: api.exceptions.EntityNotFoundException => //ignore
}

override def setProperty(id: Long, propertyKeyId: Int, value: Any): Unit = try {
tc.statement.dataWriteOperations().relationshipSetProperty(id, propertyKeyId, Values.of(value))
} catch {
case _: exceptions.EntityNotFoundException => //ignore
case _: api.exceptions.EntityNotFoundException => //ignore
}

override def getById(id: Long): Relationship =
try {
tc.statement.readOperations().relationshipCursorById(id)
proxySpi.newRelationshipProxy(id)
} catch {
case e: exceptions.EntityNotFoundException =>
case e: api.exceptions.EntityNotFoundException =>
throw new EntityNotFoundException(s"Relationship with id $id", e)
}

Expand Down Expand Up @@ -521,7 +522,7 @@ final class TransactionBoundQueryContext(tc: TransactionalContextWrapper)

def relationshipEndNode(rel: Relationship) = rel.getEndNode

private val tokenNameLookup = new SilentTokenNameLookup(tc.kernelTransaction.tokenRead())
private val tokenNameLookup = new SilentTokenNameLookup(tc.tokenRead)

override def commitAndRestartTx() { tc.commitAndRestartTx() }

Expand Down Expand Up @@ -617,7 +618,7 @@ final class TransactionBoundQueryContext(tc: TransactionalContextWrapper)
try {
tc.statement.dataWriteOperations().nodeDetachDelete(node.getId)
} catch {
case _: exceptions.EntityNotFoundException => // the node has been deleted by another transaction, oh well...
case _: api.exceptions.EntityNotFoundException => // the node has been deleted by another transaction, oh well...
0
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,17 @@ import org.neo4j.graphdb.RelationshipType._
import org.neo4j.graphdb._
import org.neo4j.graphdb.security.URLAccessValidationError
import org.neo4j.graphdb.traversal.{Evaluators, TraversalDescription, Uniqueness}
import org.neo4j.internal.kernel.api
import org.neo4j.internal.kernel.api.{IndexQuery, InternalIndexState}
import org.neo4j.kernel.GraphDatabaseQueryService
import org.neo4j.kernel.api._
import org.neo4j.kernel.api.dbms.DbmsOperations
import org.neo4j.kernel.api.exceptions.ProcedureException
import org.neo4j.kernel.api.exceptions.schema.{AlreadyConstrainedException, AlreadyIndexedException}
import org.neo4j.kernel.api.proc.{QualifiedName => KernelQualifiedName}
import org.neo4j.kernel.api.schema.SchemaDescriptorFactory
import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptorFactory
import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory
import org.neo4j.kernel.api.{exceptions, _}
import org.neo4j.kernel.impl.core.EmbeddedProxySPI
import org.neo4j.kernel.impl.locking.ResourceTypes
import org.neo4j.kernel.impl.util.ValueUtils
Expand Down Expand Up @@ -110,7 +111,7 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper)
override def getLabelsForNode(node: Long) = try {
JavaConversionSupport.asScala(txContext.statement.readOperations().nodeGetLabels(node))
} catch {
case e: exceptions.EntityNotFoundException =>
case e: api.exceptions.EntityNotFoundException =>
if (nodeOps.isDeletedInThisTx(node))
throw new EntityNotFoundException(s"Node with id $node has been deleted in this transaction", e)
else
Expand Down Expand Up @@ -297,20 +298,20 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper)
try {
txContext.statement.dataWriteOperations().nodeDelete(obj.getId)
} catch {
case _: exceptions.EntityNotFoundException => // node has been deleted by another transaction, oh well...
case _: api.exceptions.EntityNotFoundException => // node has been deleted by another transaction, oh well...
}
}

override def propertyKeyIds(id: Long): Iterator[Int] = try {
JavaConversionSupport.asScalaENFXSafe(txContext.statement.readOperations().nodeGetPropertyKeys(id))
} catch {
case _: exceptions.EntityNotFoundException => Iterator.empty
case _: api.exceptions.EntityNotFoundException => Iterator.empty
}

override def getProperty(id: Long, propertyKeyId: Int): Any = try {
txContext.statement.readOperations().nodeGetProperty(id, propertyKeyId).asObject()
} catch {
case e: exceptions.EntityNotFoundException =>
case e: api.exceptions.EntityNotFoundException =>
if (isDeletedInThisTx(id))
throw new EntityNotFoundException(s"Node with id $id has been deleted in this transaction", e)
else
Expand All @@ -320,22 +321,22 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper)
override def hasProperty(id: Long, propertyKey: Int): Boolean = try {
txContext.statement.readOperations().nodeHasProperty(id, propertyKey)
} catch {
case _: exceptions.EntityNotFoundException => false
case _: api.exceptions.EntityNotFoundException => false
}

override def removeProperty(id: Long, propertyKeyId: Int): Unit = {
try {
txContext.statement.dataWriteOperations().nodeRemoveProperty(id, propertyKeyId)
} catch {
case _: exceptions.EntityNotFoundException => //ignore
case _: api.exceptions.EntityNotFoundException => //ignore
}
}

override def setProperty(id: Long, propertyKeyId: Int, value: Any): Unit = {
try {
txContext.statement.dataWriteOperations().nodeSetProperty(id, propertyKeyId, Values.of(value) )
} catch {
case _: exceptions.EntityNotFoundException => //ignore
case _: api.exceptions.EntityNotFoundException => //ignore
}
}

Expand Down Expand Up @@ -372,20 +373,20 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper)
try {
txContext.statement.dataWriteOperations().relationshipDelete(obj.getId)
} catch {
case _: exceptions.EntityNotFoundException => // node has been deleted by another transaction, oh well...
case _: api.exceptions.EntityNotFoundException => // node has been deleted by another transaction, oh well...
}
}

override def propertyKeyIds(id: Long): Iterator[Int] = try {
JavaConversionSupport.asScalaENFXSafe(txContext.statement.readOperations().relationshipGetPropertyKeys(id))
} catch {
case _: exceptions.EntityNotFoundException => Iterator.empty
case _: api.exceptions.EntityNotFoundException => Iterator.empty
}

override def getProperty(id: Long, propertyKeyId: Int): Any = try {
txContext.statement.readOperations().relationshipGetProperty(id, propertyKeyId).asObject()
} catch {
case e: exceptions.EntityNotFoundException =>
case e: api.exceptions.EntityNotFoundException =>
if (isDeletedInThisTx(id))
throw new EntityNotFoundException(s"Relationship with id $id has been deleted in this transaction", e)
else
Expand All @@ -395,22 +396,22 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper)
override def hasProperty(id: Long, propertyKey: Int): Boolean = try {
txContext.statement.readOperations().relationshipHasProperty(id, propertyKey)
} catch {
case _: exceptions.EntityNotFoundException => false
case _: api.exceptions.EntityNotFoundException => false
}

override def removeProperty(id: Long, propertyKeyId: Int): Unit = {
try {
txContext.statement.dataWriteOperations().relationshipRemoveProperty(id, propertyKeyId)
} catch {
case _: exceptions.EntityNotFoundException => //ignore
case _: api.exceptions.EntityNotFoundException => //ignore
}
}

override def setProperty(id: Long, propertyKeyId: Int, value: Any): Unit = {
try {
txContext.statement.dataWriteOperations().relationshipSetProperty(id, propertyKeyId, Values.of(value) )
} catch {
case _: exceptions.EntityNotFoundException => //ignore
case _: api.exceptions.EntityNotFoundException => //ignore
}
}

Expand All @@ -419,7 +420,7 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper)
txContext.statement.readOperations().relationshipCursorById(id)
entityAccessor.newRelationshipProxy(id)
} catch {
case e: exceptions.EntityNotFoundException =>
case e: api.exceptions.EntityNotFoundException =>
throw new EntityNotFoundException(s"Relationship with id $id", e)
}

Expand Down Expand Up @@ -706,7 +707,7 @@ final class TransactionBoundQueryContext(txContext: TransactionalContextWrapper)
try {
txContext.statement.dataWriteOperations().nodeDetachDelete(node.getId)
} catch {
case _: exceptions.EntityNotFoundException => 0 // node has been deleted by another transaction, oh well...
case _: api.exceptions.EntityNotFoundException => 0 // node has been deleted by another transaction, oh well...
}
}

Expand Down

0 comments on commit 0079c91

Please sign in to comment.