protected static Object getAssociationRow(Tuple row, AssociationKey associationKey) { String[] columnsToPersist = associationKey.getMetadata() .getColumnsWithoutKeyColumns( row.getColumnNames() ); // return value itself if there is only a single column to store if ( columnsToPersist.length == 1 ) { return row.get( columnsToPersist[0] ); } Entity rowObject = new Entity(); String prefix = getColumnSharedPrefixOfAssociatedEntityLink( associationKey ); for ( String column : columnsToPersist ) { Object value = row.get( column ); if ( value != null ) { String columnName = column.startsWith( prefix ) ? column.substring( prefix.length() ) : column; rowObject.set( columnName, value ); } } return rowObject.getPropertiesAsHierarchy(); }
@Override public <X> GridValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) { return new GridValueExtractor<X>() { @Override public X extract(Tuple resultset, String name) { final X result = (X) resultset.get( name ); if ( result == null ) { return null; } else { byte[] bytes = Base64ByteArrayTypeDescriptor.INSTANCE.fromString( (String) result ); return javaTypeDescriptor.wrap( bytes, null ); } } }; }
@Override public void nullSafeSet(Tuple resultset, Object value, String[] names, SessionImplementor session) throws HibernateException { if ( names.length > 1 ) { throw new NotYetImplementedException( "Multi column property not implemented yet" ); } if ( value == null ) { log.tracef( "binding [null] to parameter [$s]", names[0] ); } else { Object endValue = isOrdinal() ? Integer.toString( ( (Enum<?>) value ).ordinal() ) : ( (Enum<?>) value ).name(); log.tracef( "binding [$s] to parameter(s) $s", endValue, names[0] ); resultset.put( names[0], endValue ); } }
@Override public Tuple getTuple(EntityKey key, OperationContext operationContext) { String entityIdString = entityId( key ); if ( !connection.exists( entityIdString ) ) { return null; } Map<String, String> objects; if ( operationContext.getTupleTypeContext().getSelectableColumns().isEmpty() ) { objects = connection.hgetall( entityIdString ); } else { List<String> hmget = connection.hmget( entityIdString, getFields( operationContext.getTupleTypeContext() ) ); objects = toEntity( operationContext.getTupleTypeContext(), hmget ); } return createTuple( objects ); }
public IgniteEmbeddedAssociationSnapshot(AssociationKey associationKey, Tuple tuple) { this.associationMetadata = associationKey.getMetadata(); this.tuple = tuple; BinaryObject obj = ( (IgniteTupleSnapshot) tuple.getSnapshot() ).getCacheValue(); Object objects[] = obj != null ? (Object[]) obj.field( StringHelper.realColumnName( associationMetadata.getCollectionRole() ) ) : null; rows = new HashMap<>(); if ( objects != null ) { String rowKeyColumnNames[] = new String[ associationMetadata.getRowKeyColumnNames().length ]; for ( int i = 0; i < rowKeyColumnNames.length; i++ ) { rowKeyColumnNames[i] = StringHelper.stringAfterPoint( associationMetadata.getRowKeyColumnNames()[i] ); } for ( int i = 0; i < objects.length; i++ ) { BinaryObject itemObject = (BinaryObject) objects[i]; Object rowKeyColumnValues[] = new Object[rowKeyColumnNames.length]; for ( int j = 0; j < rowKeyColumnNames.length; j++ ) { rowKeyColumnValues[j] = itemObject.field( rowKeyColumnNames[j] ); } RowKey rowKey = new RowKey( associationMetadata.getRowKeyColumnNames(), rowKeyColumnValues ); this.rows.put( rowKey, new IgniteTupleSnapshot( null, itemObject, associationMetadata.getAssociatedEntityKeyMetadata().getEntityKeyMetadata() ) ); } } }
public void update(Tuple tuple) { for (TupleOperation operation : tuple.getOperations()) { columnNames.add(operation.getColumn()); ObjectNode context = node; String[] components = operation.getColumn().split("\\."); for (int i = 0; i < components.length - 1; i++) { context = ensureNode(context, components[i]); } String fieldName = components[components.length - 1]; switch (operation.getType()) { case PUT: context.putPOJO(fieldName, operation.getValue()); break; default: context.putNull(fieldName); } } }
@Override public Tuple getTuple(EntityKey key, OperationContext operationContext) { Entity entity = entityStorageStrategy.getEntity( entityId( key ) ); if ( entity != null ) { return new Tuple( new RedisJsonTupleSnapshot( entity ), SnapshotType.UPDATE ); } else if ( isInTheInsertionQueue( key, operationContext ) ) { return createTuple( key, operationContext ); } else { return null; } }
@Override public org.hibernate.ogm.model.spi.Association createAssociation( AssociationKey key, AssociationContext associationContext) { RedisAssociation redisAssociation; if ( isStoredInEntityStructure( key.getMetadata(), associationContext.getAssociationTypeContext() ) ) { TuplePointer tuplePointer = getEmbeddingEntityTuplePointer( key, associationContext ); Entity owningEntity = getEntityFromTuple( tuplePointer.getTuple() ); if ( owningEntity == null ) { owningEntity = new Entity(); storeEntity( key.getEntityKey(), owningEntity, associationContext.getAssociationTypeContext().getHostingEntityOptionsContext() ); tuplePointer.setTuple( new Tuple( new RedisJsonTupleSnapshot( owningEntity ), SnapshotType.UPDATE ) ); } redisAssociation = RedisAssociation.fromEmbeddedAssociation( tuplePointer, key.getMetadata() ); } else { redisAssociation = RedisAssociation.fromAssociationDocument( new Association() ); } org.hibernate.ogm.model.spi.Association association = new org.hibernate.ogm.model.spi.Association( new RedisAssociationSnapshot( redisAssociation, key ) ); // in the case of an association stored in the entity structure, we might end up with rows present in the current snapshot of the entity // while we want an empty association here. So, in this case, we clear the snapshot to be sure the association created is empty. if ( !association.isEmpty() ) { association.clear(); } return association; }
@Override public Tuple next() { String key = iterator.next(); Entity document = storageStrategy.getEntity( key ); addKeyValuesFromKeyName( entityKeyMetadata, prefix, key, document ); return createTuple( document ); }
@Override public <X> GridValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) { return new BasicGridBinder<X>( javaTypeDescriptor, this ) { @Override protected void doBind(Tuple resultset, X value, String[] names, WrapperOptions options) { byte[] unwrap = javaTypeDescriptor.unwrap( value, byte[].class, options ); resultset.put( names[0], Base64ByteArrayTypeDescriptor.INSTANCE.toString( unwrap ) ); } }; }
@Override public Association createAssociation( AssociationKey key, AssociationContext associationContext) { RedisAssociation redisAssociation; if ( isStoredInEntityStructure( key.getMetadata(), associationContext.getAssociationTypeContext() ) ) { TuplePointer tuplePointer = getEmbeddingEntityTuplePointer( key, associationContext ); HashEntity owningEntity = getEntityFromTuple( tuplePointer.getTuple() ); if ( owningEntity == null ) { owningEntity = new HashEntity( new HashMap<String, String>() ); storeEntity( key.getEntityKey(), owningEntity, associationContext.getAssociationTypeContext().getHostingEntityOptionsContext() ); tuplePointer.setTuple( new Tuple( new RedisHashTupleSnapshot( owningEntity ), SnapshotType.UPDATE ) ); } redisAssociation = RedisAssociation.fromHashEmbeddedAssociation( tuplePointer, key.getMetadata() ); } else { redisAssociation = RedisAssociation.fromAssociationDocument( new org.hibernate.ogm.datastore.redis.dialect.value.Association() ); } return new org.hibernate.ogm.model.spi.Association( new RedisAssociationSnapshot( redisAssociation, key ) ); }
@Override public Tuple next() { String key = iterator.next(); Map<String, String> hgetall = connection.hgetall( key ); Map<String, String> properties = new HashMap<>(); properties.putAll( hgetall ); addKeyValuesFromKeyName( entityKeyMetadata, prefix, key, properties ); return createTuple( properties ); }
@Override public Tuple getTuple(EntityKey key, OperationContext operationContext) { IgniteCache<Object, BinaryObject> entityCache = provider.getEntityCache( key.getMetadata() ); if ( entityCache == null ) { throw log.cacheNotFound( key.getMetadata().getTable() ); } Object id = provider.createKeyObject( key ); BinaryObject po = entityCache.get( id ); if ( po != null ) { return new Tuple( new IgniteTupleSnapshot( id, po, key.getMetadata() ), SnapshotType.UPDATE ); } else { return null; } }
@Override public Tuple createTuple(EntityKey key, OperationContext operationContext) { IgniteCache<Object, BinaryObject> entityCache = provider.getEntityCache( key.getMetadata() ); if ( entityCache == null ) { throw log.cacheNotFound( key.getMetadata().getTable() ); } Object id = provider.createKeyObject( key ); return new Tuple( new IgniteTupleSnapshot( id, null, key.getMetadata() ), SnapshotType.INSERT ); }
@Override public void insertOrUpdateTuple(EntityKey key, TuplePointer tuplePointer, TupleContext tupleContext) throws TupleAlreadyExistsException { IgniteCache<Object, BinaryObject> entityCache = provider.getEntityCache( key.getMetadata() ); Tuple tuple = tuplePointer.getTuple(); Object keyObject = null; BinaryObjectBuilder builder = null; IgniteTupleSnapshot tupleSnapshot = (IgniteTupleSnapshot) tuple.getSnapshot(); keyObject = tupleSnapshot.getCacheKey(); if ( tuple.getSnapshotType() == SnapshotType.UPDATE ) { builder = provider.createBinaryObjectBuilder( tupleSnapshot.getCacheValue() ); } else { builder = provider.createBinaryObjectBuilder( provider.getEntityTypeName( key.getMetadata().getTable() ) ); } for ( String columnName : tuple.getColumnNames() ) { Object value = tuple.get( columnName ); if ( value != null ) { builder.setField( StringHelper.realColumnName( columnName ), value ); } else { builder.removeField( StringHelper.realColumnName( columnName ) ); } } BinaryObject valueObject = builder.build(); entityCache.put( keyObject, valueObject ); tuplePointer.setTuple( new Tuple( new IgniteTupleSnapshot( keyObject, valueObject, key.getMetadata() ), SnapshotType.UPDATE ) ); }
@Override public <X> GridValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) { return new BasicGridBinder<X>( javaTypeDescriptor, this ) { @Override protected void doBind(Tuple resultset, X value, String[] names, WrapperOptions options) { resultset.put( names[0], javaTypeDescriptor.unwrap( value, targetClass, options ) ); } }; }
@Override public Tuple getTuple(EntityKey key, TupleContext tupleContext) { ObjectNode object = fetchObject(key, tupleContext); if (object != null) { return new Tuple(new LightblueTupleSnapshot(object, key.getMetadata(), OperationType.UPDATE)); } if (isInQueue(key, tupleContext)) { return createTuple(key, tupleContext); } return null; }
@Override public Tuple createTuple(EntityKey key, OperationContext operationContext) { return new Tuple( new RedisJsonTupleSnapshot( new Entity() ), SnapshotType.INSERT ); }
@Override public ClosableIterator<Tuple> get(TransactionContext transactionContext) { return new RedisJsonTupleIterator( cursor, storageStrategy, prefix, entityKeyMetadata ); }
private Tuple createTuple(Entity document) { return new Tuple( new RedisJsonTupleSnapshot( document ), SnapshotType.UPDATE ); }
private Entity getEntityFromTuple(Tuple tuple) { if ( tuple == null ) { return null; } return ( (RedisJsonTupleSnapshot) tuple.getSnapshot() ).getEntity(); }
@Override public Tuple createTuple(EntityKey key, OperationContext operationContext) { return new Tuple( new RedisHashTupleSnapshot( new HashEntity( new HashMap<String, String>() ) ), SnapshotType.INSERT ); }
private static Tuple createTuple(Map<String, String> properties) { return new Tuple( new RedisHashTupleSnapshot( new HashEntity( properties ) ), SnapshotType.UPDATE ); }
private HashEntity getEntityFromTuple(Tuple tuple) { if ( tuple == null ) { return null; } return ( (RedisHashTupleSnapshot) tuple.getSnapshot() ).getEntity(); }
@Override public ClosableIterator<Tuple> get(TransactionContext transactionContext) { return new RedisHashTupleIterator( cursor, connection, prefix, entityKeyMetadata ); }
@Test public void testScan() throws Exception { AbstractRedisDialect dialect = RedisTestHelper.getDialect( getProvider() ); assumeTrue( dialect.isClusterMode() ); // pre-computed key file. URL resource = Resources.getResource( "redis-cluster-slothashes.txt" ); List<String> lines = Resources.readLines( resource, StandardCharsets.ISO_8859_1 ); OgmSession session = openSession(); session.getTransaction().begin(); // given int availableKeys = 0; for ( String line : lines ) { if ( line.startsWith( "#" ) || line.trim().isEmpty() ) { continue; } String key = line.substring( 0, line.indexOf( ' ' ) ).trim(); Band record = new Band( key, key ); session.persist( record ); availableKeys++; } session.getTransaction().commit(); final AtomicInteger counter = new AtomicInteger(); dialect.forEachTuple( new ModelConsumer() { @Override public void consume(TuplesSupplier supplier) { try ( ClosableIterator<Tuple> closableIterator = supplier.get( null ) ) { while ( closableIterator.hasNext() ) { counter.incrementAndGet(); } } } }, null, new DefaultEntityKeyMetadata( "Band", new String[] {"id"} ) ); assertEquals( availableKeys, counter.get() ); }
@Override public Tuple get(RowKey rowKey) { TupleSnapshot row = rows.get( rowKey ); return row != null ? new Tuple( row, SnapshotType.UPDATE ) : null; }
@Override public Tuple next() { T value = resultIterator.next(); rowNum++; return new Tuple( createTupleSnapshot( value ), SnapshotType.UPDATE ); }
@Override public Tuple createTuple(EntityKey key, TupleContext tupleContext) { return new Tuple(new LightblueTupleSnapshot(mapper.createObjectNode(), key.getMetadata(), OperationType.INSERT)); }
@Override public ClosableIterator<Tuple> executeBackendQuery(BackendQuery<String> query, QueryParameters queryParameters) { final String queryString = query.getQuery(); String entityName = queryParameters.getNamedParameters().get("entityName").getValue().toString(); String entityVersion = queryParameters.getNamedParameters().get("entityVersion").getValue().toString(); DataFindRequest request = new DataFindRequest(entityName, entityVersion); request.select(new FieldProjection("*", true, true)); // FIXME dummy projection for broken client request.where(new Query() { @Override public String toJson() { return queryString; } }); JsonNode jsonNode; try { jsonNode = provider.getLightblueClient().data(request).getJson().get("processed"); List<Tuple> tuples = new ArrayList<Tuple>(jsonNode.size()); for (int i = 0; i < jsonNode.size(); i++) { tuples.add(tupleFromNode((ObjectNode) jsonNode.get(i), entityName, entityVersion)); } final Iterator<Tuple> iter = tuples.iterator(); return new ClosableIterator<Tuple>() { @Override public Tuple next() { return iter.next(); } @Override public boolean hasNext() { return iter.hasNext(); } @Override public void close() { // NO-OP } @Override public void remove() { // TODO Auto-generated method stub } }; } catch (LightblueException e) { throw new RuntimeException("Error while communicating with lightblue.", e); } }
private Tuple tupleFromNode(ObjectNode objectNode, String entityName, String entityVersion) { return new Tuple(new LightblueTupleSnapshot(objectNode, entityName, entityVersion, OperationType.UPDATE)); }