private Map<RowKey, Tuple> createAssociationMap( AssociationKey associationKey, AssociationContext associationContext, EntityKey entityKey) { String relationshipType = associationContext.getAssociationTypeContext().getRoleOnMainSide(); ResourceIterator<Relationship> relationships = entityQueries .get(entityKey.getMetadata()) .findAssociation(dataBase, entityKey.getColumnValues(), relationshipType); Map<RowKey, Tuple> tuples = new HashMap<RowKey, Tuple>(); try { while (relationships.hasNext()) { Relationship relationship = relationships.next(); AssociatedEntityKeyMetadata associatedEntityKeyMetadata = associationContext.getAssociationTypeContext().getAssociatedEntityKeyMetadata(); EmbeddedNeo4jTupleAssociationSnapshot snapshot = new EmbeddedNeo4jTupleAssociationSnapshot( relationship, associationKey, associatedEntityKeyMetadata); RowKey rowKey = convert(associationKey, snapshot); tuples.put(rowKey, new Tuple(snapshot, SnapshotType.UPDATE)); } return tuples; } finally { relationships.close(); } }
private void putOneToOneAssociation( Tuple tuple, Node node, TupleOperation operation, TupleContext tupleContext, Set<String> processedAssociationRoles) { String associationRole = tupleContext.getTupleTypeContext().getRole(operation.getColumn()); if (!processedAssociationRoles.contains(associationRole)) { processedAssociationRoles.add(associationRole); EntityKey targetKey = getEntityKey( tuple, tupleContext .getTupleTypeContext() .getAssociatedEntityKeyMetadata(operation.getColumn())); // delete the previous relationship if there is one; for a to-one association, the // relationship won't have any // properties, so the type is uniquely identifying it Iterator<Relationship> relationships = node.getRelationships(withName(associationRole)).iterator(); if (relationships.hasNext()) { relationships.next().delete(); } // create a new relationship Node targetNode = entityQueries .get(targetKey.getMetadata()) .findEntity(dataBase, targetKey.getColumnValues()); node.createRelationshipTo(targetNode, withName(associationRole)); } }
@Override @SuppressWarnings("unchecked") public Map<String, Object> extractEntityTuple(Session session, EntityKey key) { MongoDBDatastoreProvider provider = MongoDBTestHelper.getProvider(session.getSessionFactory()); DBObject finder = new BasicDBObject(MongoDBDialect.ID_FIELDNAME, key.getColumnValues()[0]); DBObject result = provider.getDatabase().getCollection(key.getTable()).findOne(finder); replaceIdentifierColumnName(result, key); return result.toMap(); }
private Relationship findOrCreateRelationshipWithEntityNode( AssociationKey associationKey, Tuple associationRow, AssociatedEntityKeyMetadata associatedEntityKeyMetadata) { EntityKey targetEntityKey = getEntityKey(associationRow, associatedEntityKeyMetadata); Node targetNode = entityQueries .get(targetEntityKey.getMetadata()) .findEntity(dataBase, targetEntityKey.getColumnValues()); return createRelationshipWithTargetNode(associationKey, associationRow, targetNode); }
private Relationship createRelationshipWithTargetNode( AssociationKey associationKey, Tuple associationRow, Node targetNode) { EntityKey entityKey = associationKey.getEntityKey(); Node ownerNode = entityQueries .get(entityKey.getMetadata()) .findEntity(dataBase, entityKey.getColumnValues()); Relationship relationship = ownerNode.createRelationshipTo( targetNode, withName(associationKey.getMetadata().getCollectionRole())); applyProperties(associationKey, associationRow, relationship); return relationship; }
private Node insertTuple(EntityKey key, Tuple tuple) { try { return entityQueries.get(key.getMetadata()).insertEntity(dataBase, key.getColumnValues()); } catch (QueryExecutionException qee) { if (CONSTRAINT_VIOLATION_CODE.equals(qee.getStatusCode())) { Throwable cause = findRecognizableCause(qee); if (cause instanceof UniquePropertyConstraintViolationKernelException) { throw new TupleAlreadyExistsException(key, qee); } } throw qee; } }
@Override public Tuple getTuple(EntityKey key, TupleContext context) { Node entityNode = entityQueries.get(key.getMetadata()).findEntity(dataBase, key.getColumnValues()); if (entityNode == null) { return null; } return new Tuple( new Neo4jTupleSnapshot( entityNode, context.getAllAssociatedEntityKeyMetadata(), context.getAllRoles(), key.getMetadata())); }
@Override public Tuple getTuple(EntityKey key, OperationContext context) { Node entityNode = entityQueries.get(key.getMetadata()).findEntity(dataBase, key.getColumnValues()); if (entityNode == null) { return null; } return new Tuple( EmbeddedNeo4jTupleSnapshot.fromNode( entityNode, context.getTupleTypeContext().getAllAssociatedEntityKeyMetadata(), context.getTupleTypeContext().getAllRoles(), key.getMetadata()), SnapshotType.UPDATE); }
private void removeTupleOperation( EntityKey entityKey, Node node, TupleOperation operation, TupleContext tupleContext, Set<String> processedAssociationRoles) { if (!tupleContext.getTupleTypeContext().isPartOfAssociation(operation.getColumn())) { if (isPartOfRegularEmbedded(entityKey.getColumnNames(), operation.getColumn())) { // Embedded node String[] split = split(operation.getColumn()); removePropertyForEmbedded(node, split, 0); } else if (node.hasProperty(operation.getColumn())) { node.removeProperty(operation.getColumn()); } } // if the column represents a to-one association, remove the relationship else { String associationRole = tupleContext.getTupleTypeContext().getRole(operation.getColumn()); if (!processedAssociationRoles.contains(associationRole)) { Iterator<Relationship> relationships = node.getRelationships(withName(associationRole)).iterator(); if (relationships.hasNext()) { relationships.next().delete(); } } } }
@Override public Association getAssociation( AssociationKey associationKey, AssociationContext associationContext) { EntityKey entityKey = associationKey.getEntityKey(); Node entityNode = entityQueries .get(entityKey.getMetadata()) .findEntity(dataBase, entityKey.getColumnValues()); GraphLogger.log("Found owner node: %1$s", entityNode); if (entityNode == null) { return null; } Map<RowKey, Tuple> tuples = createAssociationMap(associationKey, associationContext, entityKey); return new Association(new EmbeddedNeo4jAssociationSnapshot(tuples)); }
@Override public Tuple getTuple(EntityKey key, TupleContext tupleContext) { final Cache<EK> entityCache = getCacheManager().getEntityCache(key.getMetadata()); final Element element = entityCache.get(getKeyProvider().getEntityCacheKey(key)); if (element != null) { return createTuple(element); } else { return null; } }
@Override public void insertOrUpdateTuple(EntityKey key, Tuple tuple, TupleContext tupleContext) { Cache<EK> entityCache = getCacheManager().getEntityCache(key.getMetadata()); Map<String, Object> entityRecord = ((MapTupleSnapshot) tuple.getSnapshot()).getMap(); if (entityRecord.isEmpty()) { MapHelpers.applyTupleOpsOnMap(tuple, entityRecord); Element previous = entityCache.putIfAbsent( new Element(getKeyProvider().getEntityCacheKey(key), entityRecord)); if (previous != null) { throw new TupleAlreadyExistsException(key.getMetadata(), tuple); } } else { MapHelpers.applyTupleOpsOnMap(tuple, entityRecord); entityCache.put(new Element(getKeyProvider().getEntityCacheKey(key), entityRecord)); } }
@Override public Tuple createTuple(EntityKey key, OperationContext operationContext) { // TODO we don't verify that it does not yet exist assuming that this has been done before by // the calling code // should we improve? Cache<EK, Map<String, Object>> cache = getCacheManager().getEntityCache(key.getMetadata()); EK cacheKey = getKeyProvider().getEntityCacheKey(key); FineGrainedAtomicMap<String, Object> atomicMap = AtomicMapLookup.getFineGrainedAtomicMap(cache, cacheKey, true); return new Tuple(new InfinispanTupleSnapshot(atomicMap), SnapshotType.INSERT); }
private void putTupleOperation( EntityKey entityKey, Tuple tuple, Node node, TupleOperation operation, TupleContext tupleContext, Set<String> processedAssociationRoles) { if (tupleContext.getTupleTypeContext().isPartOfAssociation(operation.getColumn())) { // the column represents a to-one association, map it as relationship putOneToOneAssociation(tuple, node, operation, tupleContext, processedAssociationRoles); } else if (isPartOfRegularEmbedded( entityKey.getMetadata().getColumnNames(), operation.getColumn())) { entityQueries .get(entityKey.getMetadata()) .updateEmbeddedColumn( dataBase, entityKey.getColumnValues(), operation.getColumn(), operation.getValue()); } else { putProperty(entityKey, node, operation); } }
@Override public Tuple getTuple(EntityKey key, OperationContext operationContext) { EK cacheKey = getKeyProvider().getEntityCacheKey(key); Cache<EK, Map<String, Object>> cache = getCacheManager().getEntityCache(key.getMetadata()); return getTupleFromCacheKey(cacheKey, cache); }
@Override public Tuple createTuple(EntityKey key, TupleContext tupleContext) { return new Tuple(new Neo4jTupleSnapshot(key.getMetadata())); }
@Test public void shouldSerializeAndDeserializeEntityKey() throws Exception { String[] columnNames = {"foo", "bar", "baz"}; EntityKeyMetadata keyMetadata = new DefaultEntityKeyMetadata("Foobar", columnNames); Object[] values = {123, "Hello", 456L}; // given EntityKey key = new EntityKey(keyMetadata, values); // when byte[] bytes = externalizerHelper.marshall(key); EntityKey unmarshalledKey = externalizerHelper.unmarshall(bytes); // then assertThat(unmarshalledKey.getTable()).isEqualTo(key.getTable()); assertThat(unmarshalledKey.getColumnNames()).isEqualTo(key.getColumnNames()); assertThat(unmarshalledKey.getColumnValues()).isEqualTo(key.getColumnValues()); assertTrue(key.equals(unmarshalledKey)); assertTrue(unmarshalledKey.equals(key)); assertThat(unmarshalledKey.hashCode()).isEqualTo(key.hashCode()); }
@Override public void removeTuple(EntityKey key, TupleContext tupleContext) { entityQueries.get(key.getMetadata()).removeEntity(dataBase, key.getColumnValues()); }
/** * The MongoDB dialect replaces the name of the column identifier, so when the tuple is extracted * from the db we replace the column name of the identifier with the original one. We are assuming * the identifier is not embedded and is a single property. */ private void replaceIdentifierColumnName(DBObject result, EntityKey key) { Object idValue = result.get(MongoDBDialect.ID_FIELDNAME); result.removeField(MongoDBDialect.ID_FIELDNAME); result.put(key.getColumnNames()[0], idValue); }
@Override public Tuple createTuple(EntityKey key, OperationContext tupleContext) { return new Tuple( EmbeddedNeo4jTupleSnapshot.emptySnapshot(key.getMetadata()), SnapshotType.INSERT); }
@Override public void removeTuple(EntityKey key, TupleContext tupleContext) { Cache<EK, Map<String, Object>> cache = getCacheManager().getEntityCache(key.getMetadata()); EK cacheKey = getKeyProvider().getEntityCacheKey(key); AtomicMapLookup.removeAtomicMap(cache, cacheKey); }
@Override public void removeTuple(EntityKey key, TupleContext tupleContext) { getCacheManager() .getEntityCache(key.getMetadata()) .remove(getKeyProvider().getEntityCacheKey(key)); }