Search in sources :

Example 11 with DataType

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);
}
Also used : DataType(io.micronaut.data.model.DataType) Nullable(io.micronaut.core.annotation.Nullable)

Example 12 with 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()));
    }
}
Also used : QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding) BsonObjectId(org.bson.BsonObjectId) ObjectId(org.bson.types.ObjectId) RuntimeAssociation(io.micronaut.data.model.runtime.RuntimeAssociation) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) BsonObjectId(org.bson.BsonObjectId) BsonArray(org.bson.BsonArray) DataType(io.micronaut.data.model.DataType) RuntimePersistentProperty(io.micronaut.data.model.runtime.RuntimePersistentProperty)

Example 13 with DataType

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;
        }
    };
}
Also used : DataType(io.micronaut.data.model.DataType) PersistentProperty(io.micronaut.data.model.PersistentProperty) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) Arrays(java.util.Arrays) Expandable(io.micronaut.data.annotation.Expandable) AutoPopulated(io.micronaut.data.annotation.AutoPopulated) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ClassElement(io.micronaut.inject.ast.ClassElement) ParameterExpressionImpl(io.micronaut.data.model.jpa.criteria.impl.ParameterExpressionImpl) CriteriaUtils.notSupportedOperation(io.micronaut.data.model.jpa.criteria.impl.CriteriaUtils.notSupportedOperation) Internal(io.micronaut.core.annotation.Internal) TypeDef(io.micronaut.data.annotation.TypeDef) ParameterElement(io.micronaut.inject.ast.ParameterElement) ArrayList(java.util.ArrayList) Objects(java.util.Objects) BindingParameter(io.micronaut.data.model.query.BindingParameter) List(java.util.List) Association(io.micronaut.data.model.Association) Map(java.util.Map) TypeUtils(io.micronaut.data.processor.visitors.finders.TypeUtils) LinkedList(java.util.LinkedList) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) TypeDef(io.micronaut.data.annotation.TypeDef) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) DataType(io.micronaut.data.model.DataType) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath)

Example 14 with DataType

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());
}
Also used : DataType(io.micronaut.data.model.DataType)

Example 15 with DataType

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)));
    }
}
Also used : DataType(io.micronaut.data.model.DataType) MappedEntity(io.micronaut.data.annotation.MappedEntity) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ClassElement(io.micronaut.inject.ast.ClassElement) HashMap(java.util.HashMap) TypeDef(io.micronaut.data.annotation.TypeDef) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Utils.getConfiguredDataTypes(io.micronaut.data.processor.visitors.Utils.getConfiguredDataTypes) Utils.getConfiguredDataConverters(io.micronaut.data.processor.visitors.Utils.getConfiguredDataConverters) TypeElementVisitor(io.micronaut.inject.visitor.TypeElementVisitor) MappedProperty(io.micronaut.data.annotation.MappedProperty) PropertyElement(io.micronaut.inject.ast.PropertyElement) InstantiationUtils(io.micronaut.core.reflect.InstantiationUtils) Map(java.util.Map) TypeUtils(io.micronaut.data.processor.visitors.finders.TypeUtils) AnnotationClassValue(io.micronaut.core.annotation.AnnotationClassValue) NamingStrategies(io.micronaut.data.model.naming.NamingStrategies) PersistentProperty(io.micronaut.data.model.PersistentProperty) Property(io.micronaut.context.annotation.Property) Index(io.micronaut.data.annotation.Index) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Collectors(java.util.stream.Collectors) Indexes(io.micronaut.data.annotation.Indexes) Objects(java.util.Objects) NonNull(io.micronaut.core.annotation.NonNull) VisitorContext(io.micronaut.inject.visitor.VisitorContext) List(java.util.List) Association(io.micronaut.data.model.Association) Stream(java.util.stream.Stream) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Optional(java.util.Optional) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) AttributeConverter(io.micronaut.data.model.runtime.convert.AttributeConverter) Relation(io.micronaut.data.annotation.Relation) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) ClassElement(io.micronaut.inject.ast.ClassElement) AnnotationClassValue(io.micronaut.core.annotation.AnnotationClassValue) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Relation(io.micronaut.data.annotation.Relation) Association(io.micronaut.data.model.Association) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) TypeDef(io.micronaut.data.annotation.TypeDef) MappedProperty(io.micronaut.data.annotation.MappedProperty) DataType(io.micronaut.data.model.DataType) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) ArrayList(java.util.ArrayList) List(java.util.List) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) MappedProperty(io.micronaut.data.annotation.MappedProperty) PersistentProperty(io.micronaut.data.model.PersistentProperty) Property(io.micronaut.context.annotation.Property) PropertyElement(io.micronaut.inject.ast.PropertyElement)

Aggregations

DataType (io.micronaut.data.model.DataType)15 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)7 Association (io.micronaut.data.model.Association)6 PersistentProperty (io.micronaut.data.model.PersistentProperty)6 Map (java.util.Map)6 ClassElement (io.micronaut.inject.ast.ClassElement)5 ArrayList (java.util.ArrayList)5 List (java.util.List)5 Objects (java.util.Objects)5 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)4 AnnotationValue (io.micronaut.core.annotation.AnnotationValue)4 NonNull (io.micronaut.core.annotation.NonNull)4 Index (io.micronaut.data.annotation.Index)4 Indexes (io.micronaut.data.annotation.Indexes)4 MappedEntity (io.micronaut.data.annotation.MappedEntity)4 MappedProperty (io.micronaut.data.annotation.MappedProperty)4 Relation (io.micronaut.data.annotation.Relation)4 NamingStrategy (io.micronaut.data.model.naming.NamingStrategy)4 QueryParameterBinding (io.micronaut.data.model.query.builder.QueryParameterBinding)4 HashMap (java.util.HashMap)4