use of io.micronaut.data.model.DataType in project micronaut-data by micronaut-projects.
the class SqlResultEntityTypeMapper method read.
@Nullable
@Override
public Object read(@NonNull RS resultSet, @NonNull Argument<?> argument) {
RuntimePersistentProperty<R> property = entity.getPropertyByName(argument.getName());
DataType dataType;
String columnName;
if (property == null) {
dataType = argument.getAnnotationMetadata().enumValue(TypeDef.class, "type", DataType.class).orElseGet(() -> DataType.forType(argument.getType()));
columnName = argument.getName();
} else {
dataType = property.getDataType();
columnName = property.getPersistedName();
}
return resultReader.readDynamic(resultSet, columnName, dataType);
}
use of io.micronaut.data.model.DataType in project micronaut-data by micronaut-projects.
the class DefaultMongoStoredQuery method getValue.
private <QE, QR, T> BsonValue getValue(int index, QueryParameterBinding queryParameterBinding, InvocationContext<?, ?> invocationContext, RuntimePersistentEntity<T> persistentEntity, CodecRegistry codecRegistry, E entity) {
Class<?> parameterConverter = queryParameterBinding.getParameterConverterClass();
Object value;
if (queryParameterBinding.getParameterIndex() != -1) {
requireInvocationContext(invocationContext);
value = resolveParameterValue(queryParameterBinding, invocationContext.getParameterValues());
} else if (queryParameterBinding.isAutoPopulated()) {
PersistentPropertyPath pp = getRequiredPropertyPath(queryParameterBinding, persistentEntity);
RuntimePersistentProperty<?> persistentProperty = (RuntimePersistentProperty) pp.getProperty();
Object previousValue = null;
QueryParameterBinding previousPopulatedValueParameter = queryParameterBinding.getPreviousPopulatedValueParameter();
if (previousPopulatedValueParameter != null) {
if (previousPopulatedValueParameter.getParameterIndex() == -1) {
throw new IllegalStateException("Previous value parameter cannot be bind!");
}
previousValue = resolveParameterValue(previousPopulatedValueParameter, invocationContext.getParameterValues());
}
value = runtimeEntityRegistry.autoPopulateRuntimeProperty(persistentProperty, previousValue);
value = convert(value, persistentProperty);
parameterConverter = null;
} else if (entity != null) {
PersistentPropertyPath pp = getRequiredPropertyPath(queryParameterBinding, persistentEntity);
value = pp.getPropertyValue(entity);
} else {
throw new IllegalStateException("Invalid query [" + "]. Unable to establish parameter value for parameter at position: " + (index + 1));
}
DataType dataType = queryParameterBinding.getDataType();
List<Object> values = expandValue(value, dataType);
if (values != null && values.isEmpty()) {
// Empty collections / array should always set at least one value
value = null;
values = null;
}
if (values == null) {
if (parameterConverter != null) {
int parameterIndex = queryParameterBinding.getParameterIndex();
Argument<?> argument;
if (parameterIndex > -1) {
requireInvocationContext(invocationContext);
argument = invocationContext.getArguments()[parameterIndex];
} else {
argument = null;
}
value = convert(parameterConverter, value, argument);
}
// Check if the parameter is not an id which might be represented as String but needs to mapped as ObjectId
if (value instanceof String && queryParameterBinding.getPropertyPath() != null) {
// TODO: improve id recognition
PersistentPropertyPath pp = getRequiredPropertyPath(queryParameterBinding, persistentEntity);
RuntimePersistentProperty<?> persistentProperty = (RuntimePersistentProperty) pp.getProperty();
if (persistentProperty instanceof RuntimeAssociation) {
RuntimeAssociation runtimeAssociation = (RuntimeAssociation) persistentProperty;
RuntimePersistentProperty identity = runtimeAssociation.getAssociatedEntity().getIdentity();
if (identity != null && identity.getType() == String.class && identity.isGenerated()) {
return new BsonObjectId(new ObjectId((String) value));
}
}
if (persistentProperty.getOwner().getIdentity() == persistentProperty && persistentProperty.getType() == String.class && persistentProperty.isGenerated()) {
return new BsonObjectId(new ObjectId((String) value));
}
}
return MongoUtils.toBsonValue(conversionService, value, codecRegistry);
} else {
Class<?> finalParameterConverter = parameterConverter;
return new BsonArray(values.stream().map(val -> {
if (finalParameterConverter != null) {
int parameterIndex = queryParameterBinding.getParameterIndex();
Argument<?> argument;
if (parameterIndex > -1) {
requireInvocationContext(invocationContext);
argument = invocationContext.getArguments()[parameterIndex];
} else {
argument = null;
}
val = convert(finalParameterConverter, val, argument);
}
return MongoUtils.toBsonValue(conversionService, val, codecRegistry);
}).collect(Collectors.toList()));
}
}
use of io.micronaut.data.model.DataType in project micronaut-data by micronaut-projects.
the class SourceParameterExpressionImpl method bind.
@Override
public QueryParameterBinding bind(BindingContext bindingContext) {
String bindName;
if (bindingContext.getName() == null) {
bindName = String.valueOf(bindingContext.getIndex());
} else {
bindName = bindingContext.getName();
}
PersistentPropertyPath incomingMethodParameterProperty = bindingContext.getIncomingMethodParameterProperty();
PersistentPropertyPath outgoingQueryParameterProperty = bindingContext.getOutgoingQueryParameterProperty();
PersistentPropertyPath propertyPath = outgoingQueryParameterProperty == null ? incomingMethodParameterProperty : outgoingQueryParameterProperty;
if (propertyPath == null) {
Objects.requireNonNull(parameterElement);
int index = Arrays.asList(parameters).indexOf(parameterElement);
DataType dataType = getDataType(null, parameterElement);
String converter = parameterElement.stringValue(TypeDef.class, "converter").orElse(null);
boolean isExpandable = isExpandable(bindingContext, dataType);
return new QueryParameterBinding() {
@Override
public String getKey() {
return bindName;
}
@Override
public int getParameterIndex() {
return index;
}
@Override
public DataType getDataType() {
return dataType;
}
@Override
public String getConverterClassName() {
return converter;
}
@Override
public boolean isExpandable() {
return isExpandable;
}
};
}
if (outgoingQueryParameterProperty == null) {
throw new IllegalStateException("Outgoing query parameter property is required!");
}
boolean autopopulated = propertyPath.getProperty().findAnnotation(AutoPopulated.class).map(ap -> ap.getRequiredValue(AutoPopulated.UPDATEABLE, Boolean.class)).orElse(false);
DataType dataType = getDataType(propertyPath, parameterElement);
String converterClassName = ((SourcePersistentProperty) propertyPath.getProperty()).getConverterClassName();
int index = parameterElement == null || isEntityParameter ? -1 : Arrays.asList(parameters).indexOf(parameterElement);
String[] path = asStringPath(outgoingQueryParameterProperty.getAssociations(), outgoingQueryParameterProperty.getProperty());
String[] parameterBindingPath = index != -1 ? getBindingPath(incomingMethodParameterProperty, outgoingQueryParameterProperty) : null;
boolean requiresPrevValue = index == -1 && autopopulated && !isUpdate;
boolean isExpandable = isExpandable(bindingContext, dataType);
return new QueryParameterBinding() {
@Override
public String getKey() {
return bindName;
}
@Override
public DataType getDataType() {
return dataType;
}
@Override
public String getConverterClassName() {
return converterClassName;
}
@Override
public int getParameterIndex() {
return index;
}
@Override
public String[] getParameterBindingPath() {
return parameterBindingPath;
}
@Override
public String[] getPropertyPath() {
return path;
}
@Override
public boolean isAutoPopulated() {
return autopopulated;
}
@Override
public boolean isRequiresPreviousPopulatedValue() {
return requiresPrevValue;
}
@Override
public boolean isExpandable() {
return isExpandable;
}
};
}
use of io.micronaut.data.model.DataType in project micronaut-data by micronaut-projects.
the class SqlQueryBuilder method addWriteExpression.
private boolean addWriteExpression(List<String> values, PersistentProperty property) {
DataType dt = property.getDataType();
String transformer = getDataTransformerWriteValue(null, property).orElse(null);
if (transformer != null) {
return values.add(transformer);
}
if (dt == DataType.JSON) {
switch(dialect) {
case POSTGRES:
return values.add("to_json(" + formatParameter(values.size() + 1).getName() + "::json)");
case H2:
return values.add(formatParameter(values.size() + 1).getName() + " FORMAT JSON");
case MYSQL:
return values.add("CONVERT(" + formatParameter(values.size() + 1).getName() + " USING UTF8MB4)");
default:
return values.add(formatParameter(values.size() + 1).getName());
}
}
return values.add(formatParameter(values.size() + 1).getName());
}
use of io.micronaut.data.model.DataType in project micronaut-data by micronaut-projects.
the class MappedEntityVisitor method computeMappingDefaults.
private void computeMappingDefaults(NamingStrategy namingStrategy, PersistentProperty property, Map<String, DataType> dataTypes, Map<String, String> dataConverters, VisitorContext context) {
AnnotationMetadata annotationMetadata = property.getAnnotationMetadata();
SourcePersistentProperty spp = (SourcePersistentProperty) property;
PropertyElement propertyElement = spp.getPropertyElement();
boolean isRelation = propertyElement.hasStereotype(Relation.class);
DataType dataType = annotationMetadata.getValue(TypeDef.class, "type", DataType.class).orElse(null);
String converter = annotationMetadata.stringValue(MappedProperty.class, "converter").orElseGet(() -> annotationMetadata.stringValue(TypeDef.class, "converter").orElse(null));
if (Objects.equals(converter, Object.class.getName())) {
converter = null;
}
if (converter == null) {
ClassElement type = propertyElement.getGenericType();
converter = TypeUtils.resolveDataConverter(type, dataConverters);
}
if (converter != null) {
if (isRelation) {
context.fail("Relation cannot have converter specified", propertyElement);
return;
}
ClassElement persistedClassFromConverter = getPersistedClassFromConverter(converter, context);
if (persistedClassFromConverter != null) {
propertyElement.annotate(MappedProperty.class, builder -> {
builder.member("converterPersistedType", new AnnotationClassValue<>(persistedClassFromConverter.getCanonicalName()));
});
}
if (dataType == null) {
dataType = getDataTypeFromConverter(propertyElement.getGenericType(), converter, dataTypes, context);
if (dataType == null) {
context.fail("Cannot recognize proper data type. Please use @TypeDef to specify one", propertyElement);
return;
}
}
} else {
if (dataType == null && spp.getType().isEnum()) {
if (spp.getOwner().getAnnotationMetadata().hasAnnotation("javax.persistence.Entity") || spp.getOwner().getAnnotationMetadata().hasAnnotation("jakarta.persistence.Entity")) {
// JPA enums have default ORDINAL mapping for enums
dataType = DataType.INTEGER;
}
}
if (dataType == null) {
ClassElement type = propertyElement.getGenericType();
dataType = TypeUtils.resolveDataType(type, dataTypes);
}
}
if (dataType == DataType.ENTITY && !isRelation) {
propertyElement = (PropertyElement) propertyElement.annotate(Relation.class, builder -> builder.value(Relation.Kind.MANY_TO_ONE));
} else if (isRelation) {
Relation.Kind kind = propertyElement.enumValue(Relation.class, Relation.Kind.class).orElse(Relation.Kind.MANY_TO_ONE);
if (kind == Relation.Kind.EMBEDDED || kind == Relation.Kind.MANY_TO_ONE) {
if (propertyElement.stringValue(Relation.class, "mappedBy").isPresent()) {
context.fail("Relation " + kind + " doesn't support 'mappedBy'.", propertyElement);
}
}
if (kind == Relation.Kind.EMBEDDED) {
// handled embedded
SourcePersistentEntity embeddedEntity = entityResolver.apply(propertyElement.getType());
List<SourcePersistentProperty> persistentProperties = embeddedEntity.getPersistentProperties();
List<AnnotationValue<Property>> embeddedProperties = new ArrayList<>(persistentProperties.size());
for (SourcePersistentProperty embeddedProperty : persistentProperties) {
if (!(embeddedProperty instanceof Association)) {
String mappedName = embeddedProperty.stringValue(MappedProperty.class).orElseGet(() -> namingStrategy.mappedName(property.getName() + embeddedProperty.getCapitilizedName()));
AnnotationValue<Property> av = AnnotationValue.builder(Property.class).value(mappedName).member("name", embeddedProperty.getName()).build();
embeddedProperties.add(av);
}
// else {
// // TODO: handle nested embedded
// }
}
propertyElement.annotate(MappedProperty.class, builder -> builder.member(MappedProperty.EMBEDDED_PROPERTIES, embeddedProperties.toArray(new AnnotationValue[0])));
}
}
Optional<String> mapping = annotationMetadata.stringValue(MappedProperty.class);
if (mappedEntity && !mapping.isPresent()) {
propertyElement.annotate(MappedProperty.class, builder -> builder.value(namingStrategy.mappedName(spp)));
}
if (dataType != DataType.OBJECT) {
DataType finalDataType = dataType;
propertyElement.annotate(MappedProperty.class, builder -> builder.member("type", finalDataType));
}
if (converter != null) {
String finalConverter = converter;
propertyElement.annotate(MappedProperty.class, builder -> builder.member("converter", new AnnotationClassValue<>(finalConverter)));
}
}
Aggregations