[DEV] correct timing
This commit is contained in:
parent
41fb181545
commit
6584022861
17
.classpath
17
.classpath
@ -25,21 +25,24 @@
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="ignore_optional_problems" value="true"/>
|
||||
<attribute name="m2e-apt" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="target/generated-sources/annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
@ -53,7 +53,40 @@ public class AnnotationTools {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public static String getSchemedescription(final Field element) throws Exception {
|
||||
public static boolean getSchemaReadOnly(final Field element) throws Exception {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||
if (annotation.length == 0) {
|
||||
return false;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception("Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Schema) annotation[0]).readOnly();
|
||||
}
|
||||
|
||||
public static String getSchemaExample(final Class<?> element) throws Exception {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception("Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Schema) annotation[0]).example();
|
||||
}
|
||||
|
||||
public static String getSchemaDescription(final Class<?> element) throws Exception {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception("Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Schema) annotation[0]).description();
|
||||
}
|
||||
|
||||
public static String getSchemaDescription(final Field element) throws Exception {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
@ -67,7 +100,7 @@ public class AnnotationTools {
|
||||
public static String getComment(final Field element) throws Exception {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DataComment.class);
|
||||
if (annotation.length == 0) {
|
||||
return getSchemedescription(element);
|
||||
return getSchemaDescription(element);
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception("Must not have more than 1 element @DataComment on " + element.getClass().getCanonicalName());
|
||||
|
@ -309,11 +309,11 @@ public class DataAccess {
|
||||
protected static <T> void setValueFromDb(final Class<?> type, final Object data, final CountInOut count, final Field field, final ResultSet rs, final CountInOut countNotNull) throws Exception {
|
||||
if (type == UUID.class) {
|
||||
final byte[] tmp = rs.getBytes(count.value);
|
||||
//final UUID tmp = rs.getObject(count.value, UUID.class);
|
||||
// final UUID tmp = rs.getObject(count.value, UUID.class);
|
||||
if (rs.wasNull()) {
|
||||
field.set(data, null);
|
||||
} else {
|
||||
//field.set(data, tmp);
|
||||
// field.set(data, tmp);
|
||||
final UUID uuid = UuidUtils.asUuid(tmp);
|
||||
field.set(data, uuid);
|
||||
countNotNull.inc();
|
||||
@ -491,11 +491,11 @@ public class DataAccess {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
|
||||
final byte[] tmp = rs.getBytes(count);
|
||||
//final UUID tmp = rs.getObject(count, UUID.class);
|
||||
// final UUID tmp = rs.getObject(count, UUID.class);
|
||||
if (rs.wasNull()) {
|
||||
field.set(obj, null);
|
||||
} else {
|
||||
//field.set(obj, tmp);
|
||||
// field.set(obj, tmp);
|
||||
final UUID uuid = UuidUtils.asUuid(tmp);
|
||||
field.set(obj, uuid);
|
||||
}
|
||||
@ -852,7 +852,7 @@ public class DataAccess {
|
||||
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
|
||||
if (generatedKeys.next()) {
|
||||
if (primaryKeyField.getType() == UUID.class) {
|
||||
//uniqueSQLUUID = generatedKeys.getObject(1, UUID.class);
|
||||
// uniqueSQLUUID = generatedKeys.getObject(1, UUID.class);
|
||||
final byte[] tmpid = generatedKeys.getBytes(1);
|
||||
uniqueSQLUUID = UuidUtils.asUuid(tmpid);
|
||||
} else {
|
||||
|
247
src/org/kar/archidata/dataAccess/DataFactoryZod.java
Normal file
247
src/org/kar/archidata/dataAccess/DataFactoryZod.java
Normal file
@ -0,0 +1,247 @@
|
||||
package org.kar.archidata.dataAccess;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.kar.archidata.annotation.AnnotationTools;
|
||||
import org.kar.archidata.exception.DataAccessException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DataFactoryZod {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(DataFactoryZod.class);
|
||||
|
||||
public static String convertTypeZod(final Class<?> type) throws Exception {
|
||||
if (type == UUID.class) {
|
||||
return "string()";
|
||||
}
|
||||
if (type == Long.class) {
|
||||
return "bigint()";
|
||||
}
|
||||
if (type == long.class) {
|
||||
return "bigint()";
|
||||
}
|
||||
if (type == Integer.class || type == int.class) {
|
||||
return "number().safe()";
|
||||
}
|
||||
if (type == Boolean.class || type == boolean.class) {
|
||||
return "boolean()";
|
||||
}
|
||||
if (type == double.class || type == float.class || type == Double.class || type == Float.class) {
|
||||
return "number()";
|
||||
}
|
||||
if (type == Instant.class) {
|
||||
return "string().utc()";
|
||||
}
|
||||
if (type == Date.class || type == Timestamp.class) {
|
||||
return "date()";
|
||||
}
|
||||
if (type == LocalDate.class) {
|
||||
return "date()";
|
||||
}
|
||||
if (type == LocalTime.class) {
|
||||
return "date()";
|
||||
}
|
||||
if (type == String.class) {
|
||||
return "string()";
|
||||
}
|
||||
if (type.isEnum()) {
|
||||
final Object[] arr = type.getEnumConstants();
|
||||
final StringBuilder out = new StringBuilder();
|
||||
boolean first = true;
|
||||
out.append("enum([");
|
||||
for (final Object elem : arr) {
|
||||
if (!first) {
|
||||
out.append(",");
|
||||
}
|
||||
first = false;
|
||||
out.append("\"");
|
||||
out.append(elem.toString());
|
||||
out.append("\"");
|
||||
}
|
||||
out.append("])");
|
||||
return out.toString();
|
||||
}
|
||||
throw new DataAccessException("Imcompatible type of element in object for: " + type.getCanonicalName());
|
||||
}
|
||||
|
||||
public static String optionalTypeZod(final Class<?> type) throws Exception {
|
||||
if (type.isEnum() || type == UUID.class || type == Long.class || type == Integer.class || type == Boolean.class | type == Double.class || type == Float.class || type == Instant.class
|
||||
|| type == Date.class || type == Timestamp.class || type == LocalDate.class || type == LocalTime.class || type == String.class) {
|
||||
return ".optional()";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void createTablesSpecificType(final Field elem, final int fieldId, final StringBuilder builder) throws Exception {
|
||||
final String name = elem.getName();
|
||||
final Class<?> classModel = elem.getType();
|
||||
final int limitSize = AnnotationTools.getLimitSize(elem);
|
||||
|
||||
final String comment = AnnotationTools.getComment(elem);
|
||||
|
||||
if (fieldId != 0) {
|
||||
builder.append(",");
|
||||
}
|
||||
if (comment != null) {
|
||||
builder.append("\n\t// ");
|
||||
builder.append(comment);
|
||||
}
|
||||
builder.append("\n\t");
|
||||
builder.append(name);
|
||||
builder.append(": zod.");
|
||||
builder.append(convertTypeZod(classModel));
|
||||
if (limitSize > 0 && classModel == String.class) {
|
||||
builder.append(".max(");
|
||||
builder.append(limitSize);
|
||||
builder.append(")");
|
||||
}
|
||||
if (AnnotationTools.getSchemaReadOnly(elem)) {
|
||||
builder.append(".readonly()");
|
||||
}
|
||||
builder.append(optionalTypeZod(classModel));
|
||||
}
|
||||
|
||||
private static boolean isFieldFromSuperClass(final Class<?> model, final String filedName) {
|
||||
final Class<?> superClass = model.getSuperclass();
|
||||
if (superClass == null) {
|
||||
return false;
|
||||
}
|
||||
for (final Field field : superClass.getFields()) {
|
||||
String name;
|
||||
try {
|
||||
name = AnnotationTools.getFieldName(field);
|
||||
if (filedName.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
LOGGER.trace("Catch error field name in parent create data table: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Request the generation of the TypeScript file for the "Zod" export model
|
||||
* @param classs List of class used in the model
|
||||
* @return A string representing the Server models
|
||||
* @throws Exception */
|
||||
public static String createTables(final List<Class<?>> classs) throws Exception {
|
||||
final Map<String, String> previousClassesGenerated = new LinkedHashMap<>();
|
||||
final List<String> order = new ArrayList<>();
|
||||
for (final Class<?> clazz : classs) {
|
||||
createTable(clazz, previousClassesGenerated, order);
|
||||
}
|
||||
final StringBuilder generatedData = new StringBuilder();
|
||||
generatedData.append("""
|
||||
/**
|
||||
* Interface of the server (auto-generated code)
|
||||
*/
|
||||
import { z as zod } from \"zod\";
|
||||
|
||||
""");
|
||||
for (final String elem : order) {
|
||||
final String data = previousClassesGenerated.get(elem);
|
||||
generatedData.append(data);
|
||||
generatedData.append("\n\n");
|
||||
}
|
||||
LOGGER.info("generated: {}", generatedData.toString());
|
||||
final FileWriter myWriter = new FileWriter("api.ts");
|
||||
myWriter.write(generatedData.toString());
|
||||
myWriter.close();
|
||||
return generatedData.toString();
|
||||
}
|
||||
|
||||
public static void createTable(final Class<?> clazz, final Map<String, String> previousClassesGenerated, final List<String> order) throws Exception {
|
||||
if (previousClassesGenerated.get(clazz.getCanonicalName()) != null) {
|
||||
return;
|
||||
}
|
||||
// add the current class to prevent multiple creation
|
||||
previousClassesGenerated.put(clazz.getCanonicalName(), "In Generation");
|
||||
// Local generation of class:
|
||||
final StringBuilder internalBuilder = new StringBuilder();
|
||||
final List<String> alreadyAdded = new ArrayList<>();
|
||||
LOGGER.trace("parse class: '{}'", clazz.getCanonicalName());
|
||||
int fieldId = 0;
|
||||
for (final Field elem : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
final String dataName = elem.getName();
|
||||
if (isFieldFromSuperClass(clazz, dataName)) {
|
||||
LOGGER.trace(" SKIP: '{}'", elem.getName());
|
||||
continue;
|
||||
}
|
||||
if (alreadyAdded.contains(dataName)) {
|
||||
LOGGER.trace(" SKIP2: '{}'", elem.getName());
|
||||
continue;
|
||||
}
|
||||
alreadyAdded.add(dataName);
|
||||
LOGGER.trace(" + '{}'", elem.getName());
|
||||
if (DataAccess.isAddOnField(elem)) {
|
||||
final DataAccessAddOn addOn = DataAccess.findAddOnforField(elem);
|
||||
LOGGER.error("Create type for: {} ==> {} (ADD-ON) ==> Not managed now ....", AnnotationTools.getFieldName(elem), elem.getType());
|
||||
/* LOGGER.trace("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType()); if (addOn != null) { addOn.createTables(tableName, elem, tmpOut,
|
||||
* preActionList, postActionList, createIfNotExist, createDrop, fieldId); } else { throw new DataAccessException( "Element matked as add-on but add-on does not loaded: table:" +
|
||||
* tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType()); } fieldId++; */
|
||||
} else {
|
||||
LOGGER.trace("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType());
|
||||
DataFactoryZod.createTablesSpecificType(elem, fieldId, internalBuilder);
|
||||
fieldId++;
|
||||
}
|
||||
|
||||
}
|
||||
final String description = AnnotationTools.getSchemaDescription(clazz);
|
||||
final String example = AnnotationTools.getSchemaExample(clazz);
|
||||
final StringBuilder generatedData = new StringBuilder();
|
||||
if (description != null || example != null) {
|
||||
generatedData.append("/**\n");
|
||||
if (description != null) {
|
||||
for (final String elem : description.split("\n")) {
|
||||
generatedData.append(" * ");
|
||||
generatedData.append(elem);
|
||||
generatedData.append("\n");
|
||||
}
|
||||
}
|
||||
if (example != null) {
|
||||
generatedData.append(" * Example:\n");
|
||||
generatedData.append(" * ```\n");
|
||||
for (final String elem : example.split("\n")) {
|
||||
generatedData.append(" * ");
|
||||
generatedData.append(elem);
|
||||
generatedData.append("\n");
|
||||
}
|
||||
generatedData.append(" * ```\n");
|
||||
}
|
||||
generatedData.append(" */\n");
|
||||
}
|
||||
generatedData.append("export const ");
|
||||
generatedData.append(clazz.getSimpleName());
|
||||
generatedData.append(" = ");
|
||||
final Class<?> parentClass = clazz.getSuperclass();
|
||||
if (parentClass != Object.class) {
|
||||
createTable(parentClass, previousClassesGenerated, order);
|
||||
generatedData.append(parentClass.getSimpleName());
|
||||
generatedData.append(".extend({");
|
||||
} else {
|
||||
generatedData.append("zod.object({");
|
||||
}
|
||||
generatedData.append(internalBuilder.toString());
|
||||
generatedData.append("\n});");
|
||||
// Remove the previous to reorder the map ==> parent must be inserted before us.
|
||||
previousClassesGenerated.put(clazz.getCanonicalName(), generatedData.toString());
|
||||
order.add(clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
}
|
@ -21,6 +21,7 @@ record Action(String action, AsyncCall async, List<String> filterDB) {
|
||||
public Action(final String action, final String filterDB) {
|
||||
this(action, null, List.of(filterDB));
|
||||
}
|
||||
|
||||
public Action(final AsyncCall async) {
|
||||
this(null, async, List.of());
|
||||
}
|
||||
@ -142,6 +143,7 @@ public class MigrationSqlStep implements MigrationInterface {
|
||||
public void addAction(final String action) {
|
||||
this.actions.add(new Action(action));
|
||||
}
|
||||
|
||||
public void addAction(final AsyncCall async) {
|
||||
this.actions.add(new Action(async));
|
||||
}
|
||||
@ -149,6 +151,7 @@ public class MigrationSqlStep implements MigrationInterface {
|
||||
public void addAction(final String action, final String filterdBType) {
|
||||
this.actions.add(new Action(action, filterdBType));
|
||||
}
|
||||
|
||||
public void addAction(final AsyncCall async, final String filterdBType) {
|
||||
this.actions.add(new Action(async, filterdBType));
|
||||
}
|
||||
|
@ -10,15 +10,12 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Temporal;
|
||||
import jakarta.persistence.TemporalType;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public class GenericTiming {
|
||||
@DataNotRead
|
||||
@CreationTimestamp
|
||||
@Column(nullable = false)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@NotNull
|
||||
@Schema(description = "Create time of the object", required = false, example = "2000-01-23T01:23:45.678+01:00", readOnly = true)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
|
||||
@ -26,10 +23,9 @@ public class GenericTiming {
|
||||
@DataNotRead
|
||||
@UpdateTimestamp
|
||||
@Column(nullable = false)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@NotNull
|
||||
@Schema(description = "When update the object", required = false, example = "2000-01-23T00:23:45.678Z", readOnly = true)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
|
||||
//public Instant updatedAt = null;
|
||||
// public Instant updatedAt = null;
|
||||
public Date updatedAt = null;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user