Permalink
Browse files

Nicer error message when trying to delete a node still containing rel…

…ationships
  • Loading branch information...
systay committed Apr 26, 2012
1 parent d3f228e commit 23a19ebe5281d4a5f4d406a2c74c33f670a025d4
@@ -47,3 +47,5 @@ class PatternException(message:String) extends CypherException(message, null)
class InternalException(message:String, inner:Exception=null) extends CypherException(message, inner)
class MissingIndexException(indexName:String) extends CypherException("Index `" + indexName + "` does not exist")
+
+class NodeStillHasRelationshipsException(val nodeId:Long, cause:Throwable) extends CypherException("Node with id " + nodeId + " still has relationships, and can not be deleted.")
@@ -19,18 +19,40 @@
*/
package org.neo4j.cypher.internal.pipes
-import org.neo4j.graphdb.GraphDatabaseService
-import org.neo4j.cypher.InternalException
+import org.neo4j.graphdb.{TransactionFailureException, GraphDatabaseService}
+import org.neo4j.kernel.impl.nioneo.store.InvalidRecordException
+import org.neo4j.cypher.{NodeStillHasRelationshipsException, InternalException}
class CommitPipe(source: Pipe, graph: GraphDatabaseService) extends PipeWithSource(source) {
+ lazy val still_has_relationships = "Node record Node\\[(\\d),.*] still has relationships".r
+
def createResults(state: QueryState) = {
val result = source.createResults(state)
state.transaction match {
case None => throw new InternalException("Expected to be in a transaction but wasn't")
case Some(tx) => {
tx.success()
- tx.finish()
+ try {
+ tx.finish()
+ } catch {
+ case e: TransactionFailureException => {
+ if (e.getCause != null) {
+ val inner = e.getCause
+ if (inner.getCause != null) {
+ val invalidRecord = inner.getCause
+ if (invalidRecord.isInstanceOf[InvalidRecordException]) {
+ invalidRecord.getMessage match {
+ case still_has_relationships(id) => throw new NodeStillHasRelationshipsException(id.toLong, e)
+ case _ => throw e
+ }
+ }
+ }
+ }
+
+ throw e
+ }
+ }
}
}
@@ -23,7 +23,7 @@ import org.junit.Test
import org.junit.Assert._
import collection.JavaConverters._
import org.scalatest.Assertions
-import org.neo4j.graphdb.{NotFoundException, Relationship, Node}
+import org.neo4j.graphdb.{TransactionFailureException, NotFoundException, Relationship, Node}
class MutatingIntegrationTests extends ExecutionEngineHelper with Assertions {
@@ -123,7 +123,7 @@ class MutatingIntegrationTests extends ExecutionEngineHelper with Assertions {
@Test
def multiple_deletes_should_not_break_anything() {
- (1 to 4).foreach( i => createNode() )
+ (1 to 4).foreach(i => createNode())
val result = parseAndExecute("start a = node(1),b=node(2,3,4) delete a")
assert(result.queryStatistics() === stats.copy(
@@ -236,7 +236,7 @@ class MutatingIntegrationTests extends ExecutionEngineHelper with Assertions {
@Test
def set_property_for_null_removes_the_property() {
- val n = createNode("name"->"Michael")
+ val n = createNode("name" -> "Michael")
parseAndExecute("start n = node(1) set n.name = null return n")
assertFalse("Property should have been removed", n.hasProperty("name"))
@@ -277,4 +277,24 @@ foreach(n in nodes(p) :
assertTrue(b.getProperty("marked").asInstanceOf[Boolean])
assertTrue(c.getProperty("marked").asInstanceOf[Boolean])
}
+
+ @Test
+ def match_and_delete() {
+ val a = createNode()
+ val b = createNode()
+
+ relate(a,b, "HATES")
+ relate(a,b, "LOVES")
+
+ intercept[NodeStillHasRelationshipsException](parseAndExecute("start n = node(1) match n-[r:HATES]->() delete n,r"))
+ }
+
+ @Test
+ def delete_and_return() {
+ val a = createNode()
+
+ val result = parseAndExecute("start n = node(1) delete n return n").toList
+ assert(result === List(Map("n" -> a)))
+ }
+
}

0 comments on commit 23a19eb

Please sign in to comment.