use of io.micronaut.data.model.DataType in project micronaut-data by micronaut-projects.
the class PreparedQueryDBOperation method setParameters.
@Override
public <K, Cnt, PS> void setParameters(OpContext<Cnt, PS> context, Cnt connection, PS stmt, RuntimePersistentEntity<K> persistentEntity, K entity, Map<QueryParameterBinding, Object> previousValues) {
int index = context.shiftIndex(0);
Object[] parameterArray = preparedQuery.getParameterArray();
Argument[] parameterArguments = preparedQuery.getArguments();
for (QueryParameterBinding queryParameterBinding : preparedQuery.getQueryBindings()) {
Class<?> parameterConverter = queryParameterBinding.getParameterConverterClass();
Object value;
if (queryParameterBinding.getParameterIndex() != -1) {
value = resolveParameterValue(queryParameterBinding, parameterArray);
} else if (queryParameterBinding.isAutoPopulated()) {
String[] propertyPath = queryParameterBinding.getRequiredPropertyPath();
PersistentPropertyPath pp = persistentEntity.getPropertyPath(propertyPath);
if (pp == null) {
throw new IllegalStateException("Cannot find auto populated property: " + String.join(".", propertyPath));
}
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, parameterArray);
}
value = context.getRuntimeEntityRegistry().autoPopulateRuntimeProperty(persistentProperty, previousValue);
value = context.convert(connection, value, persistentProperty);
parameterConverter = null;
} else {
throw new IllegalStateException("Invalid query [" + query + "]. Unable to establish parameter value for parameter at position: " + (index + 1));
}
DataType dataType = queryParameterBinding.getDataType();
List<Object> values = queryParameterBinding.isExpandable() ? expandValue(value, dataType) : Collections.singletonList(value);
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 = parameterIndex > -1 ? parameterArguments[parameterIndex] : null;
value = context.convert(parameterConverter, connection, value, argument);
}
context.setStatementParameter(stmt, index++, dataType, value, dialect);
} else {
for (Object v : values) {
if (parameterConverter != null) {
int parameterIndex = queryParameterBinding.getParameterIndex();
Argument<?> argument = parameterIndex > -1 ? parameterArguments[parameterIndex] : null;
v = context.convert(parameterConverter, connection, v, argument);
}
context.setStatementParameter(stmt, index++, dataType, v, dialect);
}
}
}
}
use of io.micronaut.data.model.DataType in project micronaut-data by micronaut-projects.
the class StoredSqlOperation method setParameters.
@Override
public <T, Cnt, PS> void setParameters(OpContext<Cnt, PS> context, Cnt connection, PS stmt, RuntimePersistentEntity<T> persistentEntity, T entity, Map<QueryParameterBinding, Object> previousValues) {
int index = context.shiftIndex(0);
for (QueryParameterBinding binding : queryParameterBindings) {
String[] stringPropertyPath = binding.getRequiredPropertyPath();
PersistentPropertyPath pp = persistentEntity.getPropertyPath(stringPropertyPath);
if (pp == null) {
throw new IllegalStateException("Unrecognized path: " + String.join(".", stringPropertyPath));
}
if (binding.isAutoPopulated() && binding.isRequiresPreviousPopulatedValue()) {
if (previousValues != null) {
Object previousValue = previousValues.get(binding);
if (previousValue != null) {
index = setStatementParameter(context, stmt, index, pp.getProperty().getDataType(), previousValue, dialect, binding.isExpandable());
continue;
}
}
continue;
}
Object value = pp.getPropertyValue(entity);
RuntimePersistentProperty<?> property = (RuntimePersistentProperty<?>) pp.getProperty();
DataType type = property.getDataType();
if (value == null && type == DataType.ENTITY) {
RuntimePersistentEntity<?> referencedEntity = context.getEntity(property.getType());
RuntimePersistentProperty<?> identity = referencedEntity.getIdentity();
if (identity == null) {
throw new IllegalStateException("Cannot set an entity value without identity: " + referencedEntity);
}
property = identity;
type = identity.getDataType();
}
value = context.convert(connection, value, property);
index = setStatementParameter(context, stmt, index, type, value, dialect, binding.isExpandable());
}
}
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 String name) {
RuntimePersistentProperty<R> property = entity.getPropertyByName(name);
if (property == null) {
throw new DataAccessException("DTO projection defines a property [" + name + "] that doesn't exist on root entity: " + entity.getName());
}
DataType dataType = property.getDataType();
String 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 SqlQueryBuilder method buildInsert.
@NonNull
@Override
public QueryResult buildInsert(AnnotationMetadata repositoryMetadata, PersistentEntity entity) {
boolean escape = shouldEscape(entity);
final String unescapedTableName = getUnescapedTableName(entity);
NamingStrategy namingStrategy = entity.getNamingStrategy();
Collection<? extends PersistentProperty> persistentProperties = entity.getPersistentProperties();
List<QueryParameterBinding> parameterBindings = new ArrayList<>();
List<String> columns = new ArrayList<>();
List<String> values = new ArrayList<>();
for (PersistentProperty prop : persistentProperties) {
if (!prop.isGenerated()) {
traversePersistentProperties(prop, (associations, property) -> {
addWriteExpression(values, prop);
String key = String.valueOf(values.size());
String[] path = asStringPath(associations, property);
parameterBindings.add(new QueryParameterBinding() {
@Override
public String getKey() {
return key;
}
@Override
public DataType getDataType() {
return property.getDataType();
}
@Override
public String[] getPropertyPath() {
return path;
}
});
String columnName = namingStrategy.mappedName(associations, property);
if (escape) {
columnName = quote(columnName);
}
columns.add(columnName);
});
}
}
PersistentProperty version = entity.getVersion();
if (version != null) {
addWriteExpression(values, version);
String key = String.valueOf(values.size());
parameterBindings.add(new QueryParameterBinding() {
@Override
public String getKey() {
return key;
}
@Override
public DataType getDataType() {
return version.getDataType();
}
@Override
public String[] getPropertyPath() {
return new String[] { version.getName() };
}
});
String columnName = namingStrategy.mappedName(Collections.emptyList(), version);
if (escape) {
columnName = quote(columnName);
}
columns.add(columnName);
}
PersistentProperty identity = entity.getIdentity();
if (identity != null) {
traversePersistentProperties(identity, (associations, property) -> {
boolean isSequence = false;
if (isNotForeign(associations)) {
Optional<AnnotationValue<GeneratedValue>> generated = property.findAnnotation(GeneratedValue.class);
if (generated.isPresent()) {
GeneratedValue.Type idGeneratorType = generated.flatMap(av -> av.enumValue(GeneratedValue.Type.class)).orElseGet(() -> selectAutoStrategy(property));
if (idGeneratorType == GeneratedValue.Type.SEQUENCE) {
isSequence = true;
} else if (dialect != Dialect.MYSQL || property.getDataType() != DataType.UUID) {
// Property skipped
return;
}
}
}
if (isSequence) {
values.add(getSequenceStatement(unescapedTableName, property));
} else {
addWriteExpression(values, property);
String key = String.valueOf(values.size());
String[] path = asStringPath(associations, property);
parameterBindings.add(new QueryParameterBinding() {
@Override
public String getKey() {
return key;
}
@Override
public DataType getDataType() {
return property.getDataType();
}
@Override
public String[] getPropertyPath() {
return path;
}
});
}
String columnName = namingStrategy.mappedName(associations, property);
if (escape) {
columnName = quote(columnName);
}
columns.add(columnName);
});
}
String builder = INSERT_INTO + getTableName(entity) + " (" + String.join(",", columns) + CLOSE_BRACKET + " " + "VALUES (" + String.join(String.valueOf(COMMA), values) + CLOSE_BRACKET;
return QueryResult.of(builder, Collections.emptyList(), parameterBindings, Collections.emptyMap());
}
use of io.micronaut.data.model.DataType in project micronaut-data by micronaut-projects.
the class SqlQueryBuilder method addTypeToColumn.
private String addTypeToColumn(PersistentProperty prop, String column, boolean required) {
if (prop instanceof Association) {
throw new IllegalStateException("Association is not supported here");
}
AnnotationMetadata annotationMetadata = prop.getAnnotationMetadata();
String definition = annotationMetadata.stringValue(MappedProperty.class, "definition").orElse(null);
DataType dataType = prop.getDataType();
if (definition != null) {
return column + " " + definition;
}
OptionalInt precision = annotationMetadata.intValue("javax.persistence.Column", "precision");
OptionalInt scale = annotationMetadata.intValue("javax.persistence.Column", "scale");
switch(dataType) {
case STRING:
int stringLength = annotationMetadata.findAnnotation("javax.validation.constraints.Size$List").flatMap(v -> {
Optional value = v.getValue(AnnotationValue.class);
return (Optional<AnnotationValue<Annotation>>) value;
}).map(v -> v.intValue("max")).orElseGet(() -> annotationMetadata.intValue("javax.persistence.Column", "length")).orElse(255);
column += " VARCHAR(" + stringLength + ")";
if (required) {
column += " NOT NULL";
}
break;
case UUID:
if (dialect == Dialect.ORACLE || dialect == Dialect.MYSQL) {
column += " VARCHAR(36)";
} else if (dialect == Dialect.SQL_SERVER) {
column += " UNIQUEIDENTIFIER";
} else {
column += " UUID";
}
if (required) {
column += " NOT NULL";
}
break;
case BOOLEAN:
if (dialect == Dialect.ORACLE) {
column += " NUMBER(3)";
} else if (dialect == Dialect.SQL_SERVER) {
column += " BIT NOT NULL";
} else {
column += " BOOLEAN";
if (required) {
column += " NOT NULL";
}
}
break;
case TIMESTAMP:
if (dialect == Dialect.ORACLE) {
column += " TIMESTAMP";
if (required) {
column += " NOT NULL";
}
} else if (dialect == Dialect.SQL_SERVER) {
// sql server timestamp is an internal type, use datetime instead
column += " DATETIME2";
if (required) {
column += " NOT NULL";
}
} else if (dialect == Dialect.MYSQL) {
// mysql doesn't allow timestamp without default
column += " TIMESTAMP(6) DEFAULT NOW(6)";
} else {
column += " TIMESTAMP";
if (required) {
column += " NOT NULL";
}
}
break;
case DATE:
column += " DATE";
if (required) {
column += " NOT NULL";
}
break;
case LONG:
if (dialect == Dialect.ORACLE) {
column += " NUMBER(19)";
} else {
column += " BIGINT";
}
if (required) {
column += " NOT NULL";
}
break;
case CHARACTER:
column += " CHAR(1)";
if (required) {
column += " NOT NULL";
}
break;
case INTEGER:
if (precision.isPresent()) {
String numericName = dialect == Dialect.ORACLE ? "NUMBER" : "NUMERIC";
column += " " + numericName + "(" + precision.getAsInt() + ")";
} else if (dialect == Dialect.ORACLE) {
column += " NUMBER(10)";
} else if (dialect == Dialect.POSTGRES) {
column += " INTEGER";
} else {
column += " INT";
}
if (required) {
column += " NOT NULL";
}
break;
case BIGDECIMAL:
if (precision.isPresent()) {
if (scale.isPresent()) {
String numericName = dialect == Dialect.ORACLE ? "NUMBER" : "NUMERIC";
column += " " + numericName + "(" + precision.getAsInt() + "," + scale.getAsInt() + ")";
} else {
column += " FLOAT(" + precision.getAsInt() + ")";
}
} else if (dialect == Dialect.ORACLE) {
column += " FLOAT(126)";
} else {
column += " DECIMAL";
}
if (required) {
column += " NOT NULL";
}
break;
case FLOAT:
if (precision.isPresent()) {
if (scale.isPresent()) {
String numericName = dialect == Dialect.ORACLE ? "NUMBER" : "NUMERIC";
column += " " + numericName + "(" + precision.getAsInt() + "," + scale.getAsInt() + ")";
} else {
column += " FLOAT(" + precision.getAsInt() + ")";
}
} else if (dialect == Dialect.ORACLE || dialect == Dialect.SQL_SERVER) {
column += " FLOAT(53)";
} else if (dialect == Dialect.POSTGRES) {
column += " REAL";
} else {
column += " FLOAT";
}
if (required) {
column += " NOT NULL";
}
break;
case BYTE_ARRAY:
if (dialect == Dialect.POSTGRES) {
column += " BYTEA";
} else if (dialect == Dialect.SQL_SERVER) {
column += " VARBINARY(MAX)";
} else if (dialect == Dialect.ORACLE) {
column += " BLOB";
} else {
column += " BLOB";
}
if (required) {
column += " NOT NULL";
}
break;
case DOUBLE:
if (precision.isPresent()) {
if (scale.isPresent()) {
String numericName = dialect == Dialect.ORACLE ? "NUMBER" : "NUMERIC";
column += " " + numericName + "(" + precision.getAsInt() + "," + scale.getAsInt() + ")";
} else {
column += " FLOAT(" + precision.getAsInt() + ")";
}
} else if (dialect == Dialect.ORACLE) {
column += " FLOAT(23)";
} else if (dialect == Dialect.MYSQL || dialect == Dialect.H2) {
column += " DOUBLE";
} else {
column += " DOUBLE PRECISION";
}
if (required) {
column += " NOT NULL";
}
break;
case SHORT:
case BYTE:
if (dialect == Dialect.ORACLE) {
column += " NUMBER(5)";
} else if (dialect == Dialect.POSTGRES) {
column += " SMALLINT";
} else {
column += " TINYINT";
}
if (required) {
column += " NOT NULL";
}
break;
case JSON:
switch(dialect) {
case POSTGRES:
column += " JSONB";
break;
case SQL_SERVER:
column += " NVARCHAR(MAX)";
break;
case ORACLE:
column += " CLOB";
break;
default:
column += " JSON";
break;
}
if (required) {
column += " NOT NULL";
}
break;
case STRING_ARRAY:
case CHARACTER_ARRAY:
if (dialect == Dialect.H2) {
column += " ARRAY";
} else {
column += " VARCHAR(255) ARRAY";
}
if (required) {
column += " NOT NULL";
}
break;
case SHORT_ARRAY:
if (dialect == Dialect.H2) {
column += " ARRAY";
} else if (dialect == Dialect.POSTGRES) {
column += " SMALLINT ARRAY";
} else {
column += " TINYINT ARRAY";
}
if (required) {
column += " NOT NULL";
}
break;
case INTEGER_ARRAY:
if (dialect == Dialect.H2) {
column += " ARRAY";
} else if (dialect == Dialect.POSTGRES) {
column += " INTEGER ARRAY";
} else {
column += " INT ARRAY";
}
if (required) {
column += " NOT NULL";
}
break;
case LONG_ARRAY:
if (dialect == Dialect.H2) {
column += " ARRAY";
} else {
column += " BIGINT ARRAY";
}
if (required) {
column += " NOT NULL";
}
break;
case FLOAT_ARRAY:
if (dialect == Dialect.H2) {
column += " ARRAY";
} else if (dialect == Dialect.POSTGRES) {
column += " REAL ARRAY";
} else {
column += " FLOAT ARRAY";
}
if (required) {
column += " NOT NULL";
}
break;
case DOUBLE_ARRAY:
if (dialect == Dialect.H2) {
column += " ARRAY";
} else if (dialect == Dialect.POSTGRES) {
column += " DOUBLE PRECISION ARRAY";
} else {
column += " DOUBLE ARRAY";
}
if (required) {
column += " NOT NULL";
}
break;
case BOOLEAN_ARRAY:
if (dialect == Dialect.H2) {
column += " ARRAY";
} else {
column += " BOOLEAN ARRAY";
}
if (required) {
column += " NOT NULL";
}
break;
default:
if (prop.isEnum()) {
column += " VARCHAR(255)";
if (required) {
column += " NOT NULL";
}
break;
} else if (prop.isAssignable(Clob.class)) {
if (dialect == Dialect.POSTGRES) {
column += " TEXT";
} else {
column += " CLOB";
}
if (required) {
column += " NOT NULL";
}
break;
} else if (prop.isAssignable(Blob.class)) {
if (dialect == Dialect.POSTGRES) {
column += " BYTEA";
} else {
column += " BLOB";
}
if (required) {
column += " NOT NULL";
}
break;
} else {
throw new MappingException("Unable to create table column for property [" + prop.getName() + "] of entity [" + prop.getOwner().getName() + "] with unknown data type: " + dataType);
}
}
return column;
}
Aggregations