use of com.google.cloud.spanner.Key in project spring-cloud-gcp by spring-cloud.
the class SpannerKeyIdConverter method toRequestId.
@Override
public String toRequestId(Serializable source, Class<?> entityType) {
Key id = (Key) source;
StringJoiner stringJoiner = new StringJoiner(getUrlIdSeparator());
id.getParts().forEach((p) -> stringJoiner.add(p.toString()));
return stringJoiner.toString();
}
use of com.google.cloud.spanner.Key in project spring-cloud-gcp by spring-cloud.
the class SpannerStatementQueryExecutor method buildQuery.
/**
* Builds a query that returns the rows associated with a key set with additional SQL-where.
* The {@link org.springframework.cloud.gcp.data.spanner.core.mapping.Where} of the {@code persistentEntity} parameter
* is ignored, you should pass the SQL-where as a {@code whereClause} parameter.
* The secondary {@code index} will be used instead of the table name when the corresponding parameter is not null.
* @param keySet the key set whose members to get.
* @param persistentEntity the persistent entity of the table.
* @param <T> the type of the persistent entity
* @param writeConverter a converter to convert key values as needed to bind to the query statement.
* @param mappingContext mapping context
* @param whereClause SQL where clause
* @param index the secondary index name
* @return the Spanner statement to perform the retrieval.
*/
public static <T> Statement buildQuery(KeySet keySet, SpannerPersistentEntity<T> persistentEntity, SpannerCustomConverter writeConverter, SpannerMappingContext mappingContext, String whereClause, String index) {
List<String> orParts = new ArrayList<>();
List<String> tags = new ArrayList<>();
List keyParts = new ArrayList();
int tagNum = 0;
List<SpannerPersistentProperty> keyProperties = persistentEntity.getFlattenedPrimaryKeyProperties();
for (Key key : keySet.getKeys()) {
StringJoiner andJoiner = new StringJoiner(" AND ");
Iterator parentKeyParts = key.getParts().iterator();
while (parentKeyParts.hasNext()) {
SpannerPersistentProperty keyProp = keyProperties.get(tagNum % keyProperties.size());
String tagName = "tag" + tagNum;
andJoiner.add(keyProp.getColumnName() + " = @" + tagName);
tags.add(tagName);
keyParts.add(parentKeyParts.next());
tagNum++;
}
orParts.add(andJoiner.toString());
}
String keyClause = orParts.stream().map(s -> "(" + s + ")").collect(Collectors.joining(" OR "));
String condition = combineWithAnd(keyClause, whereClause);
String sb = "SELECT " + getColumnsStringForSelect(persistentEntity, mappingContext, true) + " FROM " + (StringUtils.isEmpty(index) ? persistentEntity.tableName() : String.format("%s@{FORCE_INDEX=%s}", persistentEntity.tableName(), index)) + (condition.isEmpty() ? "" : " WHERE " + condition);
return buildStatementFromSqlWithArgs(sb, tags, null, writeConverter, keyParts.toArray(), null);
}
use of com.google.cloud.spanner.Key in project spring-cloud-gcp by spring-cloud.
the class SpannerPersistentEntityImpl method getPropertyAccessor.
@Override
public <B> PersistentPropertyAccessor<B> getPropertyAccessor(B object) {
PersistentPropertyAccessor<B> delegatedAccessor = super.getPropertyAccessor(object);
return new PersistentPropertyAccessor<B>() {
@Override
public void setProperty(PersistentProperty<?> property, @Nullable Object value) {
if (property.isIdProperty()) {
SpannerPersistentEntity<?> owner = (SpannerPersistentEntity<?>) property.getOwner();
SpannerPersistentProperty[] primaryKeyProperties = owner.getPrimaryKeyProperties();
Iterator<Object> partsIterator;
if (value instanceof Key) {
Key keyValue = (Key) value;
if (keyValue.size() != primaryKeyProperties.length) {
throwWrongNumOfPartsException();
}
partsIterator = keyValue.getParts().iterator();
} else {
if (primaryKeyProperties.length > 1) {
throwWrongNumOfPartsException();
}
partsIterator = Collections.singleton(value).iterator();
}
for (int i = 0; i < primaryKeyProperties.length; i++) {
SpannerPersistentProperty prop = primaryKeyProperties[i];
delegatedAccessor.setProperty(prop, SpannerPersistentEntityImpl.this.spannerEntityProcessor.getReadConverter().convert(partsIterator.next(), prop.getType()));
}
} else {
delegatedAccessor.setProperty(property, value);
}
}
private void throwWrongNumOfPartsException() {
throw new SpannerDataException("The number of key parts is not equal to the number of primary key properties");
}
@Nullable
@Override
public Object getProperty(PersistentProperty<?> property) {
if (property.isIdProperty()) {
return ((SpannerCompositeKeyProperty) property).getId(getBean());
} else {
return delegatedAccessor.getProperty(property);
}
}
@Override
public B getBean() {
return delegatedAccessor.getBean();
}
};
}
use of com.google.cloud.spanner.Key in project spring-cloud-gcp by spring-cloud.
the class SpannerMutationFactoryImpl method delete.
@Override
public <T> Mutation delete(Class<T> entityClass, Iterable<? extends T> entities) {
SpannerPersistentEntity<?> persistentEntity = this.spannerMappingContext.getPersistentEntity(entityClass);
KeySet.Builder builder = KeySet.newBuilder();
for (T entity : entities) {
PersistentPropertyAccessor accessor = persistentEntity.getPropertyAccessor(entity);
PersistentProperty idProperty = persistentEntity.getIdProperty();
Key value = (Key) accessor.getProperty(idProperty);
builder.addKey(value);
}
return delete(entityClass, builder.build());
}
use of com.google.cloud.spanner.Key in project spring-cloud-gcp by spring-cloud.
the class ConverterAwareMappingSpannerEntityWriter method convertToKey.
@Override
public Key convertToKey(Object key) {
Assert.notNull(key, "Key of an entity to be written cannot be null!");
Key k;
boolean isIterable = Iterable.class.isAssignableFrom(key.getClass());
boolean isArray = Object[].class.isAssignableFrom(key.getClass());
if ((isIterable || isArray) && !ByteArray.class.isAssignableFrom(key.getClass())) {
Key.Builder kb = Key.newBuilder();
for (Object keyPart : (isArray ? (Arrays.asList((Object[]) key)) : ((Iterable) key))) {
kb.appendObject(convertKeyPart(keyPart));
}
k = kb.build();
if (k.size() == 0) {
throw new SpannerDataException("A key must have at least one component, but 0 were given.");
}
} else {
k = Key.class.isAssignableFrom(key.getClass()) ? (Key) key : Key.of(convertKeyPart(key));
}
return k;
}
Aggregations