protected static Map<String, Direction> filterMapToTypes( GraphDatabaseService db, Direction defaultDirection, Map<String, Object> filterMap, boolean caseInsensitiveFilters, boolean looseFilters) throws ShellException { Map<String, Direction> matches = new TreeMap<String, Direction>(); for (RelationshipType type : GlobalGraphOperations.at(db).getAllRelationshipTypes()) { Direction direction = null; if (filterMap == null || filterMap.isEmpty()) { direction = defaultDirection; } else { for (Map.Entry<String, Object> entry : filterMap.entrySet()) { if (matches( newPattern(entry.getKey(), caseInsensitiveFilters), type.name(), caseInsensitiveFilters, looseFilters)) { direction = getDirection( entry.getValue() != null ? entry.getValue().toString() : null, defaultDirection); break; } } } // It matches if (direction != null) { matches.put(type.name(), direction); } } return matches.isEmpty() ? null : matches; }
private int getOrCreateRelationshipTypeToken(RelationshipType type) { int typeId = relationshipTypeTokens.idOf(type.name()); if (typeId == -1) { typeId = createNewRelationshipType(type.name()); } return typeId; }
private void showRelCounts(ReadOperations read, DbStructureVisitor visitor) { // all wildcards noSide(read, visitor, WILDCARD_REL_TYPE, ANY_RELATIONSHIP_TYPE); // one label only for (Label label : glops.getAllLabels()) { int labelId = read.labelGetForName(label.name()); leftSide(read, visitor, label, labelId, WILDCARD_REL_TYPE, ANY_RELATIONSHIP_TYPE); rightSide(read, visitor, label, labelId, WILDCARD_REL_TYPE, ANY_RELATIONSHIP_TYPE); } // fixed rel type for (RelationshipType relType : glops.getAllRelationshipTypes()) { int relTypeId = read.relationshipTypeGetForName(relType.name()); noSide(read, visitor, relType, relTypeId); for (Label label : glops.getAllLabels()) { int labelId = read.labelGetForName(label.name()); // wildcard on right leftSide(read, visitor, label, labelId, relType, relTypeId); // wildcard on left rightSide(read, visitor, label, labelId, relType, relTypeId); } } }
/** * Returns an {@link Evaluator} which compares the type of the last relationship in a {@link Path} * to a given set of relationship types (one or more).If the type of the last relationship in a * path is of one of the given types then {@code evaluationIfMatch} will be returned, otherwise * {@code evaluationIfNoMatch} will be returned. * * @param evaluationIfMatch the {@link Evaluation} to return if the type of the last relationship * in the path matches any of the given types. * @param evaluationIfNoMatch the {@link Evaluation} to return if the type of the last * relationship in the path doesn't match any of the given types. * @param type the (first) type (of possibly many) to match the last relationship in paths with. * @param orAnyOfTheseTypes additional types to match the last relationship in paths with. * @return an {@link Evaluator} which compares the type of the last relationship in a {@link Path} * to a given set of relationship types. */ public static Evaluator lastRelationshipTypeIs( final Evaluation evaluationIfMatch, final Evaluation evaluationIfNoMatch, RelationshipType type, RelationshipType... orAnyOfTheseTypes) { final Set<String> expectedTypes = new HashSet<String>(); expectedTypes.add(type.name()); for (RelationshipType otherType : orAnyOfTheseTypes) { expectedTypes.add(otherType.name()); } return new Evaluator() { @Override public Evaluation evaluate(Path path) { Relationship lastRelationship = path.lastRelationship(); if (lastRelationship == null) { return evaluationIfNoMatch; } return expectedTypes.contains(lastRelationship.getType().name()) ? evaluationIfMatch : evaluationIfNoMatch; } }; }
ArrayMap<String, IntArray> getMoreRelationships(NodeImpl node) { int nodeId = (int) node.getId(); RelationshipChainPosition position = node.getRelChainPosition(); Iterable<RelationshipData> rels = persistenceManager.getMoreRelationships(nodeId, position); ArrayMap<String, IntArray> newRelationshipMap = new ArrayMap<String, IntArray>(); for (RelationshipData rel : rels) { int relId = rel.getId(); RelationshipImpl relImpl = relCache.get(relId); RelationshipType type = null; if (relImpl == null) { type = getRelationshipTypeById(rel.relationshipType()); assert type != null; relImpl = new RelationshipImpl(relId, rel.firstNode(), rel.secondNode(), type, false, this); relCache.put(relId, relImpl); } else { type = relImpl.getType(); } IntArray relationshipSet = newRelationshipMap.get(type.name()); if (relationshipSet == null) { relationshipSet = new IntArray(); newRelationshipMap.put(type.name(), relationshipSet); } relationshipSet.add(relId); } return newRelationshipMap; }
@Override public String getType() { final RelationshipType relType = getRelType(); if (relType != null) { return relType.name(); } return null; }
@Override public StandardExpander remove(RelationshipType type) { Exclusion excluded = exclusion.get(type.name()); if (excluded == Exclusion.ALL) { return this; } Map<String, Exclusion> newExclusion = new HashMap<String, Exclusion>(exclusion); newExclusion.put(type.name(), Exclusion.ALL); return new ExcludingExpander(defaultExclusion, newExclusion); }
List<RelTypeElementIterator> getAllRelationshipsOfType( NodeManager nodeManager, RelationshipType... types) { ensureRelationshipMapNotNull(nodeManager); List<RelTypeElementIterator> relTypeList = new LinkedList<RelTypeElementIterator>(); for (RelationshipType type : types) { IntArray src = relationshipMap.get(type.name()); IntArray remove = nodeManager.getCowRelationshipRemoveMap(this, type.name()); IntArray add = nodeManager.getCowRelationshipAddMap(this, type.name()); if (src != null || add != null) { relTypeList.add(RelTypeElement.create(type.name(), this, src, add, remove)); } } return relTypeList; }
@Test public void shouldProvideTheCorrectRelationshipData() { GraphDatabaseService db = dbRule.getGraphDatabaseService(); // create a rel type so the next type id is non zero try (Transaction tx = db.beginTx()) { db.createNode() .createRelationshipTo(db.createNode(), DynamicRelationshipType.withName("TYPE")); } RelationshipType livesIn = DynamicRelationshipType.withName("LIVES_IN"); long relId; try (Transaction tx = db.beginTx()) { Node person = db.createNode(DynamicLabel.label("Person")); Node city = db.createNode(DynamicLabel.label("City")); Relationship rel = person.createRelationshipTo(city, livesIn); rel.setProperty("since", 2009); relId = rel.getId(); tx.success(); } final Set<String> changedRelationships = new HashSet<>(); db.registerTransactionEventHandler( new TransactionEventHandler.Adapter<Void>() { @Override public Void beforeCommit(TransactionData data) throws Exception { for (PropertyEntry<Relationship> entry : data.assignedRelationshipProperties()) { changedRelationships.add(entry.entity().getType().name()); } return null; } }); try (Transaction tx = db.beginTx()) { Relationship rel = db.getRelationshipById(relId); rel.setProperty("since", 2010); tx.success(); } assertEquals(1, changedRelationships.size()); assertTrue( livesIn + " not in " + changedRelationships.toString(), changedRelationships.contains(livesIn.name())); }
// Private methods private Envelope getChildNodeEnvelope(Node child, RelationshipType relType) { if (relType.name().equals(RTreeRelationshipTypes.RTREE_REFERENCE.name())) { return getLeafNodeEnvelope(child); } else { return getIndexNodeEnvelope(child); } }
private void noSide( ReadOperations read, DbStructureVisitor visitor, RelationshipType relType, int relTypeId) { String userDescription = format("MATCH ()-[%s]->() RETURN count(*)", colon(relType.name())); long amount = read.countsForRelationship(ANY_LABEL, relTypeId, ANY_LABEL); visitor.visitRelCount(ANY_LABEL, relTypeId, ANY_LABEL, userDescription, amount); }
public static BinaryEdgeTypeImpl getOrCreateInstance( DatabaseService db, RelationshipType relType) { VertexTypeImpl vertexType = new VertexTypeImpl( db, getOrCreateByDescriptor( new TypeNodeDescriptor(db, relType.name(), getImplementationClass())) .getId()); return new BinaryEdgeTypeImpl(db, vertexType.getNode().getId()); }
private void updateCache() { if (uuid != null) { AccessPathCache.invalidateForId(uuid); } if (relType != null) { AccessPathCache.invalidateForRelType(relType.name()); } }
List<RelTypeElementIterator> getAllRelationshipsOfType( NodeManager nodeManager, RelationshipType... types) { ensureRelationshipMapNotNull(nodeManager); List<RelTypeElementIterator> relTypeList = new LinkedList<RelTypeElementIterator>(); boolean hasModifications = nodeManager.getLockReleaser().hasRelationshipModifications(this); for (RelationshipType type : types) { RelIdArray src = relationshipMap.get(type.name()); RelIdArray remove = null; RelIdArray add = null; if (hasModifications) { remove = nodeManager.getCowRelationshipRemoveMap(this, type.name()); add = nodeManager.getCowRelationshipAddMap(this, type.name()); } // if ( src != null || add != null ) // { relTypeList.add(RelTypeElement.create(type.name(), this, src, add, remove)); // } } return relTypeList; }
@Override public long createRelationship( long node1, long node2, RelationshipType type, Map<String, Object> properties) { NodeRecord firstNode = getNodeRecord(node1); NodeRecord secondNode = getNodeRecord(node2); int typeId = typeHolder.getTypeId(type.name()); if (typeId == -1) { typeId = createNewRelationshipType(type.name()); } long id = getRelationshipStore().nextId(); RelationshipRecord record = new RelationshipRecord(id, node1, node2, typeId); record.setInUse(true); record.setCreated(); connectRelationship(firstNode, secondNode, record); getNodeStore().updateRecord(firstNode); getNodeStore().updateRecord(secondNode); record.setNextProp(createPropertyChain(properties)); getRelationshipStore().updateRecord(record); return id; }
@Override public StandardExpander add(RelationshipType type, Direction direction) { Exclusion excluded = exclusion.get(type.name()); final Map<String, Exclusion> newExclusion; if (((excluded == null) ? defaultExclusion : excluded).includes(direction)) { return this; } else { excluded = Exclusion.include(direction); if (excluded == defaultExclusion) { if (exclusion.size() == 1) { return new AllExpander(defaultExclusion.direction); } else { newExclusion = new HashMap<String, Exclusion>(exclusion); newExclusion.remove(type.name()); } } else { newExclusion = new HashMap<String, Exclusion>(exclusion); newExclusion.put(type.name(), excluded); } } return new ExcludingExpander(defaultExclusion, newExclusion); }
/** * Returns an {@link Evaluator} which compares the type of the last relationship in a {@link Path} * to a given set of relationship types (one or more).If the type of the last relationship in a * path is of one of the given types then {@code evaluationIfMatch} will be returned, otherwise * {@code evaluationIfNoMatch} will be returned. * * @param evaluationIfMatch the {@link Evaluation} to return if the type of the last relationship * in the path matches any of the given types. * @param evaluationIfNoMatch the {@link Evaluation} to return if the type of the last * relationship in the path doesn't match any of the given types. * @param type the (first) type (of possibly many) to match the last relationship in paths with. * @param orAnyOfTheseTypes additional types to match the last relationship in paths with. * @return an {@link Evaluator} which compares the type of the last relationship in a {@link Path} * to a given set of relationship types. */ @SuppressWarnings("rawtypes") public static PathEvaluator lastRelationshipTypeIs( final Evaluation evaluationIfMatch, final Evaluation evaluationIfNoMatch, final RelationshipType type, RelationshipType... orAnyOfTheseTypes) { if (orAnyOfTheseTypes.length == 0) { return new PathEvaluator.Adapter() { @Override public Evaluation evaluate(Path path, BranchState state) { Relationship rel = path.lastRelationship(); return rel != null && rel.isType(type) ? evaluationIfMatch : evaluationIfNoMatch; } }; } final Set<String> expectedTypes = new HashSet<String>(); expectedTypes.add(type.name()); for (RelationshipType otherType : orAnyOfTheseTypes) { expectedTypes.add(otherType.name()); } return new PathEvaluator.Adapter() { @Override public Evaluation evaluate(Path path, BranchState state) { Relationship lastRelationship = path.lastRelationship(); if (lastRelationship == null) { return evaluationIfNoMatch; } return expectedTypes.contains(lastRelationship.getType().name()) ? evaluationIfMatch : evaluationIfNoMatch; } }; }
public Relationship createRelationship( Node startNodeProxy, NodeImpl startNode, Node endNode, RelationshipType type) { if (startNode == null || endNode == null || type == null) { throw new IllegalArgumentException( "Null parameter, startNode=" + startNode + ", endNode=" + endNode + ", type=" + type); } if (!relTypeHolder.isValidRelationshipType(type)) { relTypeHolder.addValidRelationshipType(type.name(), true); } long startNodeId = startNode.getId(); long endNodeId = endNode.getId(); NodeImpl secondNode = getLightNode(endNodeId); if (secondNode == null) { setRollbackOnly(); throw new NotFoundException("Second node[" + endNode.getId() + "] deleted"); } long id = idGenerator.nextId(Relationship.class); int typeId = getRelationshipTypeIdFor(type); RelationshipImpl rel = newRelationshipImpl(id, startNodeId, endNodeId, type, typeId, true); RelationshipProxy proxy = new RelationshipProxy(id, relationshipLookups); TransactionState transactionState = getTransactionState(); transactionState.acquireWriteLock(proxy); boolean success = false; TransactionState tx = transactionState; try { transactionState.acquireWriteLock(startNodeProxy); transactionState.acquireWriteLock(endNode); persistenceManager.relationshipCreate(id, typeId, startNodeId, endNodeId); if (startNodeId == endNodeId) { tx.getOrCreateCowRelationshipAddMap(startNode, typeId).add(id, DirectionWrapper.BOTH); } else { tx.getOrCreateCowRelationshipAddMap(startNode, typeId).add(id, DirectionWrapper.OUTGOING); tx.getOrCreateCowRelationshipAddMap(secondNode, typeId).add(id, DirectionWrapper.INCOMING); } // relCache.put( rel.getId(), rel ); relCache.put(rel); success = true; return proxy; } finally { if (!success) { setRollbackOnly(); } } }
public Relationship getSingleRelationship(Node node, RelationshipType type) { Transaction tx = graphDb().beginTx(); try { Iterator<Relationship> itr = node.getRelationships(type).iterator(); Relationship rel = null; if (itr.hasNext()) { rel = itr.next(); if (itr.hasNext()) { throw new RuntimeException( node + " has more than one " + "relationship of type '" + type.name() + "'"); } } tx.success(); return rel; } finally { tx.finish(); } }
public static ValueRepresentation relationshipType(RelationshipType type) { return new ValueRepresentation(RepresentationType.RELATIONSHIP_TYPE, type.name()); }
// ----- private methods ----- private JsonElement serializeNestedKeyValueType( GraphObject src, Type typeOfSrc, JsonSerializationContext context, boolean includeTypeInOutput, String localPropertyView, int depth) { // prevent endless recursion by pruning at depth 2 if (depth > outputNestingDepth) { return null; } JsonObject jsonObject = new JsonObject(); // id (only if idProperty is not set) if (idProperty == null) { jsonObject.add("id", new JsonPrimitive(src.getId())); } else { Object idPropertyValue = src.getProperty(idProperty); if (idPropertyValue != null) { String idString = idPropertyValue.toString(); jsonObject.add("id", new JsonPrimitive(idString)); } } /* * String type = src.getType(); * if (type != null) { * * jsonObject.add("type", new JsonPrimitive(type)); * * } */ // property keys JsonArray properties = new JsonArray(); for (String key : src.getPropertyKeys(localPropertyView)) { Object value = src.getProperty(key); if (value instanceof Iterable) { JsonArray property = new JsonArray(); for (Object o : (Iterable) value) { if (o instanceof GraphObject) { GraphObject obj = (GraphObject) o; JsonElement recursiveSerializedValue = this.serializeNestedKeyValueType( obj, typeOfSrc, context, includeTypeInOutput, localPropertyView, depth + 1); if (recursiveSerializedValue != null) { property.add(recursiveSerializedValue); } } else if (o instanceof Map) { properties.add( serializeMap( (Map) o, typeOfSrc, context, localPropertyView, includeTypeInOutput, true, depth)); } else { // serialize primitive, this is for PropertyNotion properties.add(serializePrimitive(key, o, includeTypeInOutput)); } // TODO: Unterstützung von Notions mit mehr als einem Property bei der Ausgabe! // => neuer Typ? } properties.add(property); } else if (value instanceof GraphObject) { GraphObject graphObject = (GraphObject) value; properties.add( this.serializeNestedKeyValueType( graphObject, typeOfSrc, context, includeTypeInOutput, localPropertyView, depth + 1)); } else if (value instanceof Map) { properties.add( serializeMap( (Map) value, typeOfSrc, context, localPropertyView, includeTypeInOutput, true, depth)); } else { properties.add(serializePrimitive(key, value, includeTypeInOutput)); } } jsonObject.add("properties", properties); if (src instanceof AbstractNode) { // outgoing relationships Map<RelationshipType, Long> outRelStatistics = ((AbstractNode) src).getRelationshipInfo(Direction.OUTGOING); if (outRelStatistics != null) { JsonArray outRels = new JsonArray(); for (Entry<RelationshipType, Long> entry : outRelStatistics.entrySet()) { RelationshipType relType = entry.getKey(); Long count = entry.getValue(); JsonObject outRelEntry = new JsonObject(); outRelEntry.add("type", new JsonPrimitive(relType.name())); outRelEntry.add("count", new JsonPrimitive(count)); outRels.add(outRelEntry); } jsonObject.add("out", outRels); } // incoming relationships Map<RelationshipType, Long> inRelStatistics = ((AbstractNode) src).getRelationshipInfo(Direction.INCOMING); if (inRelStatistics != null) { JsonArray inRels = new JsonArray(); for (Entry<RelationshipType, Long> entry : inRelStatistics.entrySet()) { RelationshipType relType = entry.getKey(); Long count = entry.getValue(); JsonObject inRelEntry = new JsonObject(); inRelEntry.add("type", new JsonPrimitive(relType.name())); inRelEntry.add("count", new JsonPrimitive(count)); inRels.add(inRelEntry); } jsonObject.add("in", inRels); } } else if (src instanceof AbstractRelationship) { // start node id (for relationships) String startNodeId = ((AbstractRelationship) src).getStartNodeId(); if (startNodeId != null) { jsonObject.add("startNodeId", new JsonPrimitive(startNodeId)); } // end node id (for relationships) String endNodeId = ((AbstractRelationship) src).getEndNodeId(); if (endNodeId != null) { jsonObject.add("endNodeId", new JsonPrimitive(endNodeId)); } } return jsonObject; }
// caller is responsible for acquiring lock // this method is only called when a undo create relationship or // a relationship delete is invoked. void removeRelationship(NodeManager nodeManager, RelationshipType type, long relId) { RelIdArray relationshipSet = nodeManager.getCowRelationshipRemoveMap(this, type.name(), true); relationshipSet.add(relId); }
public void describeTo(Description description) { description.appendText("Version matcher "); description.appendText("\"" + relationshipType.toString() + "\""); }
public Relationship createRelationship(Node startNode, Node endNode, RelationshipType type) { if (startNode == null || endNode == null || type == null) { throw new IllegalArgumentException( "Null parameter, startNode=" + startNode + ", endNode=" + endNode + ", type=" + type); } if (!relTypeHolder.isValidRelationshipType(type)) { relTypeHolder.addValidRelationshipType(type.name(), true); } int startNodeId = (int) startNode.getId(); NodeImpl firstNode = getLightNode(startNodeId); if (firstNode == null) { setRollbackOnly(); throw new NotFoundException("First node[" + startNode.getId() + "] deleted"); } int endNodeId = (int) endNode.getId(); NodeImpl secondNode = getLightNode(endNodeId); if (secondNode == null) { setRollbackOnly(); throw new NotFoundException("Second node[" + endNode.getId() + "] deleted"); } int id = idGenerator.nextId(Relationship.class); RelationshipImpl rel = new RelationshipImpl(id, startNodeId, endNodeId, type, true, this); boolean firstNodeTaken = false; boolean secondNodeTaken = false; acquireLock(rel, LockType.WRITE); boolean success = false; try { acquireLock(firstNode, LockType.WRITE); firstNodeTaken = true; acquireLock(secondNode, LockType.WRITE); secondNodeTaken = true; int typeId = getRelationshipTypeIdFor(type); persistenceManager.relationshipCreate(id, typeId, startNodeId, endNodeId); firstNode.addRelationship(type, id); secondNode.addRelationship(type, id); relCache.put((int) rel.getId(), rel); success = true; return new RelationshipProxy(id, this); } finally { boolean releaseFailed = false; if (firstNodeTaken) { try { releaseLock(firstNode, LockType.WRITE); } catch (Exception e) { releaseFailed = true; e.printStackTrace(); log.severe("Failed to release lock"); } } if (secondNodeTaken) { try { releaseLock(secondNode, LockType.WRITE); } catch (Exception e) { releaseFailed = true; e.printStackTrace(); log.severe("Failed to release lock"); } } releaseLock(rel, LockType.WRITE); if (!success) { setRollbackOnly(); } if (releaseFailed) { throw new LockException( "Unable to release locks [" + startNode + "," + endNode + "] in relationship create->" + rel); } } }
// caller is responsible for acquiring lock // this method is only called when a relationship is created or // a relationship delete is undone or when the full node is loaded void addRelationship(NodeManager nodeManager, RelationshipType type, int relId) { IntArray relationshipSet = nodeManager.getCowRelationshipAddMap(this, type.name(), true); relationshipSet.add(relId); }
@Override public StandardExpander remove(RelationshipType type) { Map<String, Exclusion> exclude = new HashMap<String, Exclusion>(); exclude.put(type.name(), Exclusion.ALL); return new ExcludingExpander(Exclusion.include(direction), exclude); }
private void showRelTypes(ReadOperations read, DbStructureVisitor visitor) { for (RelationshipType relType : glops.getAllRelationshipTypes()) { int relTypeId = read.relationshipTypeGetForName(relType.name()); visitor.visitRelationshipType(relTypeId, relType.name()); } }
public boolean isType(NodeManager nodeManager, RelationshipType otherType) { return otherType != null && otherType.name().equals(this.getType(nodeManager).name()); }
public boolean isType(RelationshipType otherType) { return otherType != null && otherType.name().equals(this.getType().name()); }