/** * Copyright (c) 2002-2012 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Neo4j 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.consistency.checking; import org.neo4j.consistency.report.ConsistencyReport; import org.neo4j.consistency.store.DiffRecordAccess; import org.neo4j.consistency.store.RecordAccess; import org.neo4j.kernel.impl.nioneo.store.NodeRecord; import org.neo4j.kernel.impl.nioneo.store.Record; import org.neo4j.kernel.impl.nioneo.store.RelationshipRecord; enum RelationshipNodeField implements RecordField<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport>, ComparativeRecordChecker<RelationshipRecord, NodeRecord, ConsistencyReport.RelationshipConsistencyReport> { SOURCE { @Override public long valueFrom( RelationshipRecord relationship ) { return relationship.getFirstNode(); } @Override public long prev( RelationshipRecord relationship ) { return relationship.getFirstPrevRel(); } @Override public long next( RelationshipRecord relationship ) { return relationship.getFirstNextRel(); } @Override void illegalNode( ConsistencyReport.RelationshipConsistencyReport report ) { report.illegalSourceNode(); } @Override void nodeNotInUse( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ) { report.sourceNodeNotInUse( node ); } @Override void noBackReference( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ) { report.sourceNodeDoesNotReferenceBack( node ); } @Override void noChain( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ) { report.sourceNodeHasNoRelationships( node ); } @Override void notFirstInChain( ConsistencyReport.NodeConsistencyReport report, RelationshipRecord relationship ) { report.relationshipNotFirstInSourceChain( relationship ); } @Override void notUpdated( ConsistencyReport.RelationshipConsistencyReport report ) { report.sourceNodeNotUpdated(); } }, TARGET { @Override public long valueFrom( RelationshipRecord relationship ) { return relationship.getSecondNode(); } @Override public long prev( RelationshipRecord relationship ) { return relationship.getSecondPrevRel(); } @Override public long next( RelationshipRecord relationship ) { return relationship.getSecondNextRel(); } @Override void illegalNode( ConsistencyReport.RelationshipConsistencyReport report ) { report.illegalTargetNode(); } @Override void nodeNotInUse( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ) { report.targetNodeNotInUse( node ); } @Override void noBackReference( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ) { report.targetNodeDoesNotReferenceBack( node ); } @Override void noChain( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ) { report.targetNodeHasNoRelationships( node ); } @Override void notFirstInChain( ConsistencyReport.NodeConsistencyReport report, RelationshipRecord relationship ) { report.relationshipNotFirstInTargetChain( relationship ); } @Override void notUpdated( ConsistencyReport.RelationshipConsistencyReport report ) { report.targetNodeNotUpdated(); } }; @Override public abstract long valueFrom( RelationshipRecord relationship ); public static RelationshipNodeField select( RelationshipRecord relationship, NodeRecord node ) { return select( relationship, node.getId() ); } public static RelationshipNodeField select( RelationshipRecord relationship, long nodeId ) { if ( relationship.getFirstNode() == nodeId ) { return SOURCE; } else if ( relationship.getSecondNode() == nodeId ) { return TARGET; } else { return null; } } public abstract long prev( RelationshipRecord relationship ); public abstract long next( RelationshipRecord relationship ); @Override public void checkConsistency( RelationshipRecord relationship, ConsistencyReport.RelationshipConsistencyReport report, RecordAccess records ) { if ( valueFrom( relationship ) < 0 ) { illegalNode( report ); } else { report.forReference( records.node( valueFrom( relationship ) ), this ); } } @Override public void checkReference( RelationshipRecord relationship, NodeRecord node, ConsistencyReport.RelationshipConsistencyReport report, RecordAccess records ) { if ( !node.inUse() ) { nodeNotInUse( report, node ); } else { if ( Record.NO_PREV_RELATIONSHIP.is( prev( relationship ) ) ) { if ( node.getNextRel() != relationship.getId() ) { noBackReference( report, node ); } } else { if ( Record.NO_NEXT_RELATIONSHIP.is( node.getNextRel() ) ) { noChain( report, node ); } } } } @Override public void checkChange( RelationshipRecord oldRecord, RelationshipRecord newRecord, ConsistencyReport.RelationshipConsistencyReport report, DiffRecordAccess records ) { if ( Record.NO_PREV_RELATIONSHIP.is( prev( oldRecord ) ) ) { if ( !newRecord.inUse() || valueFrom( oldRecord ) != valueFrom( newRecord ) || prev( oldRecord ) != prev( newRecord ) ) { if ( records.changedNode( valueFrom( oldRecord ) ) == null ) { notUpdated(report); } } } } abstract void notUpdated( ConsistencyReport.RelationshipConsistencyReport report ); abstract void illegalNode( ConsistencyReport.RelationshipConsistencyReport report ); abstract void nodeNotInUse( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ); abstract void noBackReference( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ); abstract void noChain( ConsistencyReport.RelationshipConsistencyReport report, NodeRecord node ); abstract void notFirstInChain( ConsistencyReport.NodeConsistencyReport report, RelationshipRecord relationship ); }