Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public Pattern getValidIdentifierPattern() {
"TABLESAMPLE", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR",
"TIMEZONE_MINUTE", "TO", "TRAILING", "TRANSLATE", "TRANSLATION", "TREAT",
"TRIGGER", "TRIM", "TRUE", "UESCAPE", "UNDER", "UNION", "UNIQUE", "UNKNOWN",
"UNNEST", "UPDATE", "UPPER", "USER", "USING", "VALUE", "VALUES", "VAR_POP",
"UNNEST", "UPDATE", "UPPER", "USE", "USER", "USING", "VALUE", "VALUES", "VAR_POP",
"VAR_SAMP", "VARBINARY", "VARCHAR", "VARYING", "VERSIONING", "WHEN",
"WHENEVER", "WHERE", "WIDTH_BUCKET", "WINDOW", "WITH", "WITHIN", "WITHOUT",
"YEAR"
Expand Down
41 changes: 41 additions & 0 deletions storm-core/src/main/java/st/orm/core/template/ORMTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import jakarta.annotation.Nonnull;
import java.sql.Connection;
import java.util.List;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import javax.sql.DataSource;
import st.orm.Data;
Expand Down Expand Up @@ -104,6 +105,28 @@ default List<String> validateSchema() {
throw new PersistenceException("Schema validation is not supported by this template.");
}

/**
* Validates discovered types matching the filter against the database schema.
*
* <p>Discovers all entity and projection types via the classpath index, applies the given filter, and validates
* the matching types. This is useful when a single application connects to multiple datasources and only a
* subset of types is reachable from each connection.</p>
*
* <p>Logs each validation error and returns the list of error messages. On success, logs a
* confirmation message and returns an empty list.</p>
*
* <p>This method requires a DataSource-backed template. Templates created from a raw
* {@link Connection} or {@code EntityManager} do not support schema validation.</p>
*
* @param filter predicate to select which discovered types to validate.
* @return the list of validation error messages (empty on success).
* @throws PersistenceException if the template does not support schema validation.
* @since 1.11
*/
default List<String> validateSchema(@Nonnull Predicate<Class<? extends Data>> filter) {
throw new PersistenceException("Schema validation is not supported by this template.");
}

/**
* Validates the specified types against the database schema.
*
Expand Down Expand Up @@ -135,6 +158,24 @@ default void validateSchemaOrThrow() {
throw new PersistenceException("Schema validation is not supported by this template.");
}

/**
* Validates discovered types matching the filter and throws if any errors are found.
*
* <p>Discovers all entity and projection types via the classpath index, applies the given filter, and validates
* the matching types. This is useful when a single application connects to multiple datasources and only a
* subset of types is reachable from each connection.</p>
*
* <p>This method requires a DataSource-backed template. Templates created from a raw
* {@link Connection} or {@code EntityManager} do not support schema validation.</p>
*
* @param filter predicate to select which discovered types to validate.
* @throws PersistenceException if validation fails or the template does not support schema validation.
* @since 1.11
*/
default void validateSchemaOrThrow(@Nonnull Predicate<Class<? extends Data>> filter) {
throw new PersistenceException("Schema validation is not supported by this template.");
}

/**
* Validates the specified types and throws if any errors are found.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ public List<String> validateSchema() {
return createSchemaValidator().validateAndReport(isStrictSchemaValidation());
}

@Override
public List<String> validateSchema(@Nonnull Predicate<Class<? extends Data>> filter) {
return createSchemaValidator().validateAndReport(filter, isStrictSchemaValidation());
}

@Override
public List<String> validateSchema(@Nonnull Iterable<Class<? extends Data>> types) {
return createSchemaValidator().validateAndReport(types, isStrictSchemaValidation());
Expand All @@ -121,6 +126,11 @@ public void validateSchemaOrThrow() {
createSchemaValidator().validateReportAndThrow(isStrictSchemaValidation());
}

@Override
public void validateSchemaOrThrow(@Nonnull Predicate<Class<? extends Data>> filter) {
createSchemaValidator().validateReportAndThrow(filter, isStrictSchemaValidation());
}

@Override
public void validateSchemaOrThrow(@Nonnull Iterable<Class<? extends Data>> types) {
List<String> errors = createSchemaValidator().validateAndReport(types, isStrictSchemaValidation());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.slf4j.Logger;
Expand Down Expand Up @@ -202,6 +203,28 @@ public List<String> validateAndReport(boolean strict) {
return reportErrors(validate(types), strict, types.size());
}

/**
* Validates discovered types matching the filter, logs each finding, and returns the error messages.
*
* <p>Discovers all entity and projection types via the classpath index, applies the given filter, and validates
* the matching types.</p>
*
* <p>In strict mode, all findings (including warnings like type narrowing and nullability mismatches) are treated
* as errors. In non-strict mode, warnings are logged at WARN level but excluded from the returned error list.</p>
*
* @param filter predicate to select which discovered types to validate.
* @param strict whether to treat warnings as errors.
* @return the list of error messages (empty on success).
* @since 1.11
*/
public List<String> validateAndReport(@Nonnull Predicate<Class<? extends Data>> filter, boolean strict) {
LOGGER.info("Validating Data types for schema compatibility.");
List<Class<? extends Data>> types = TypeDiscovery.getDataTypes().stream()
.filter(filter)
.toList();
return reportErrors(validate(types), strict, types.size());
}

/**
* Validates the specified types, logs each finding, and returns the error messages.
*
Expand Down Expand Up @@ -241,6 +264,21 @@ public void validateReportAndThrow(boolean strict) {
}
}

/**
* Validates discovered types matching the filter, reports errors with logging, and throws if any errors remain.
*
* @param filter predicate to select which discovered types to validate.
* @param strict whether to treat warnings as errors.
* @throws st.orm.PersistenceException if one or more validation errors are detected after reporting.
* @since 1.11
*/
public void validateReportAndThrow(@Nonnull Predicate<Class<? extends Data>> filter, boolean strict) {
List<String> errors = validateAndReport(filter, strict);
if (!errors.isEmpty()) {
throw new st.orm.PersistenceException(formatErrors(errors));
}
}

private static List<String> reportErrors(
@Nonnull List<SchemaValidationError> validationErrors,
boolean strict,
Expand Down
37 changes: 37 additions & 0 deletions storm-java21/src/main/java/st/orm/template/ORMTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import jakarta.annotation.Nonnull;
import java.sql.Connection;
import java.util.List;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import javax.sql.DataSource;
import st.orm.Data;
Expand Down Expand Up @@ -105,6 +106,26 @@ public interface ORMTemplate extends QueryTemplate, RepositoryLookup {
*/
List<String> validateSchema();

/**
* Validates discovered types matching the filter against the database schema.
*
* <p>Discovers all entity and projection types via the classpath index, applies the given filter, and validates
* the matching types. This is useful when a single application connects to multiple datasources and only a
* subset of types is reachable from each connection.</p>
*
* <p>Logs each validation error and returns the list of error messages. On success, logs a
* confirmation message and returns an empty list.</p>
*
* <p>This method requires a DataSource-backed template. Templates created from a raw
* {@link Connection} or {@code EntityManager} do not support schema validation.</p>
*
* @param filter predicate to select which discovered types to validate.
* @return the list of validation error messages (empty on success).
* @throws st.orm.PersistenceException if the template does not support schema validation.
* @since 1.11
*/
List<String> validateSchema(@Nonnull Predicate<Class<? extends Data>> filter);

/**
* Validates the specified types against the database schema.
*
Expand Down Expand Up @@ -132,6 +153,22 @@ public interface ORMTemplate extends QueryTemplate, RepositoryLookup {
*/
void validateSchemaOrThrow();

/**
* Validates discovered types matching the filter and throws if any errors are found.
*
* <p>Discovers all entity and projection types via the classpath index, applies the given filter, and validates
* the matching types. This is useful when a single application connects to multiple datasources and only a
* subset of types is reachable from each connection.</p>
*
* <p>This method requires a DataSource-backed template. Templates created from a raw
* {@link Connection} or {@code EntityManager} do not support schema validation.</p>
*
* @param filter predicate to select which discovered types to validate.
* @throws st.orm.PersistenceException if validation fails or the template does not support schema validation.
* @since 1.11
*/
void validateSchemaOrThrow(@Nonnull Predicate<Class<? extends Data>> filter);

/**
* Validates the specified types and throws if any errors are found.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.lang.reflect.Type;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import st.orm.Data;
import st.orm.Entity;
import st.orm.EntityCallback;
Expand Down Expand Up @@ -64,6 +65,11 @@ public List<String> validateSchema() {
return core.validateSchema();
}

@Override
public List<String> validateSchema(@Nonnull Predicate<Class<? extends Data>> filter) {
return core.validateSchema(filter);
}

@Override
public List<String> validateSchema(@Nonnull Iterable<Class<? extends Data>> types) {
return core.validateSchema(types);
Expand All @@ -74,6 +80,11 @@ public void validateSchemaOrThrow() {
core.validateSchemaOrThrow();
}

@Override
public void validateSchemaOrThrow(@Nonnull Predicate<Class<? extends Data>> filter) {
core.validateSchemaOrThrow(filter);
}

@Override
public void validateSchemaOrThrow(@Nonnull Iterable<Class<? extends Data>> types) {
core.validateSchemaOrThrow(types);
Expand Down
36 changes: 36 additions & 0 deletions storm-kotlin/src/main/kotlin/st/orm/template/ORMTemplate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,26 @@ interface ORMTemplate :
*/
fun validateSchema(): List<String>

/**
* Validates discovered types matching the filter against the database schema.
*
* Discovers all entity and projection types via the classpath index, applies the given filter, and validates
* the matching types. This is useful when a single application connects to multiple datasources and only a
* subset of types is reachable from each connection.
*
* Logs each validation error and returns the list of error messages. On success, logs a
* confirmation message and returns an empty list.
*
* This method requires a DataSource-backed template. Templates created from a raw
* [java.sql.Connection] or `EntityManager` do not support schema validation.
*
* @param filter predicate to select which discovered types to validate.
* @return the list of validation error messages (empty on success).
* @throws st.orm.PersistenceException if the template does not support schema validation.
* @since 1.11
*/
fun validateSchema(filter: (KClass<out Data>) -> Boolean): List<String>

/**
* Validates the specified types against the database schema.
*
Expand Down Expand Up @@ -126,6 +146,22 @@ interface ORMTemplate :
*/
fun validateSchemaOrThrow()

/**
* Validates discovered types matching the filter and throws if any errors are found.
*
* Discovers all entity and projection types via the classpath index, applies the given filter, and validates
* the matching types. This is useful when a single application connects to multiple datasources and only a
* subset of types is reachable from each connection.
*
* This method requires a DataSource-backed template. Templates created from a raw
* [java.sql.Connection] or `EntityManager` do not support schema validation.
*
* @param filter predicate to select which discovered types to validate.
* @throws st.orm.PersistenceException if validation fails or the template does not support schema validation.
* @since 1.11
*/
fun validateSchemaOrThrow(filter: (KClass<out Data>) -> Boolean)

/**
* Validates the specified types and throws if any errors are found.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,14 @@ class ORMTemplateImpl(private val core: st.orm.core.template.ORMTemplate) :

override fun validateSchema(): List<String> = core.validateSchema()

override fun validateSchema(filter: (KClass<out Data>) -> Boolean): List<String> = core.validateSchema { filter(it.kotlin) }

override fun validateSchema(vararg types: KClass<out Data>): List<String> = core.validateSchema(types.map { it.java })

override fun validateSchemaOrThrow() = core.validateSchemaOrThrow()

override fun validateSchemaOrThrow(filter: (KClass<out Data>) -> Boolean) = core.validateSchemaOrThrow { filter(it.kotlin) }

override fun validateSchemaOrThrow(vararg types: KClass<out Data>) = core.validateSchemaOrThrow(types.map { it.java })

/**
Expand Down
Loading