[DEV] add management of UUID (not tested)
This commit is contained in:
parent
e0b7ed1e1e
commit
56609e4f59
6
pom.xml
6
pom.xml
@ -114,6 +114,12 @@
|
||||
<artifactId>jackson-dataformat-csv</artifactId>
|
||||
<version>2.16.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>2.16.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
|
@ -15,6 +15,7 @@ import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.kar.archidata.annotation.AnnotationTools;
|
||||
import org.kar.archidata.annotation.CreationTimestamp;
|
||||
@ -191,7 +192,14 @@ public class DataAccess {
|
||||
}
|
||||
|
||||
protected static <T> void setValuedb(final Class<?> type, final T data, final CountInOut iii, final Field field, final PreparedStatement ps) throws Exception {
|
||||
if (type == Long.class) {
|
||||
if (type == UUID.class) {
|
||||
final Object tmp = field.get(data);
|
||||
if (tmp == null) {
|
||||
ps.setNull(iii.value, Types.BINARY);
|
||||
} else {
|
||||
ps.setObject(iii.value, tmp);
|
||||
}
|
||||
} else if (type == Long.class) {
|
||||
final Object tmp = field.get(data);
|
||||
if (tmp == null) {
|
||||
ps.setNull(iii.value, Types.BIGINT);
|
||||
@ -288,7 +296,15 @@ 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 == Long.class) {
|
||||
if (type == UUID.class) {
|
||||
final UUID tmp = rs.getObject(count.value, UUID.class);
|
||||
if (rs.wasNull()) {
|
||||
field.set(data, null);
|
||||
} else {
|
||||
field.set(data, tmp);
|
||||
countNotNull.inc();
|
||||
}
|
||||
} else if (type == Long.class) {
|
||||
final Long tmp = rs.getLong(count.value);
|
||||
if (rs.wasNull()) {
|
||||
field.set(data, null);
|
||||
@ -449,6 +465,16 @@ public class DataAccess {
|
||||
// TODO: this function will replace the previous one !!!
|
||||
protected static RetreiveFromDB createSetValueFromDbCallback(final int count, final Field field) throws Exception {
|
||||
final Class<?> type = field.getType();
|
||||
if (type == UUID.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final UUID tmp = rs.getObject(count, UUID.class);
|
||||
if (rs.wasNull()) {
|
||||
field.set(obj, null);
|
||||
} else {
|
||||
field.set(obj, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == Long.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Long tmp = rs.getLong(count);
|
||||
@ -672,6 +698,7 @@ public class DataAccess {
|
||||
final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
|
||||
final List<Field> asyncFieldUpdate = new ArrayList<>();
|
||||
Long uniqueSQLID = null;
|
||||
UUID uniqueSQLUUID = null;
|
||||
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||
// real add in the BDD:
|
||||
try {
|
||||
@ -788,7 +815,12 @@ public class DataAccess {
|
||||
// Retrieve uid inserted
|
||||
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
|
||||
if (generatedKeys.next()) {
|
||||
uniqueSQLID = generatedKeys.getLong(1);
|
||||
if (primaryKeyField.getType() == UUID.class) {
|
||||
uniqueSQLUUID = generatedKeys.getObject(1, UUID.class);
|
||||
} else {
|
||||
uniqueSQLID = generatedKeys.getLong(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new SQLException("Creating node failed, no ID obtained (1).");
|
||||
}
|
||||
@ -802,6 +834,8 @@ public class DataAccess {
|
||||
primaryKeyField.set(data, uniqueSQLID);
|
||||
} else if (primaryKeyField.getType() == long.class) {
|
||||
primaryKeyField.setLong(data, uniqueSQLID);
|
||||
} else if (primaryKeyField.getType() == UUID.class) {
|
||||
primaryKeyField.set(data, uniqueSQLUUID);
|
||||
} else {
|
||||
LOGGER.error("Can not manage the primary filed !!!");
|
||||
}
|
||||
@ -1160,6 +1194,10 @@ public class DataAccess {
|
||||
querySelect.append(query.toString());
|
||||
query = querySelect;
|
||||
condition.whereAppendQuery(query, tableName, options, deletedFieldName);
|
||||
final GroupBy groups = options.get(GroupBy.class);
|
||||
if (groups != null) {
|
||||
groups.generateQuerry(query, null);
|
||||
}
|
||||
final OrderBy orders = options.get(OrderBy.class);
|
||||
if (orders != null) {
|
||||
orders.generateQuerry(query, tableName);
|
||||
@ -1508,7 +1546,14 @@ public class DataAccess {
|
||||
}
|
||||
}
|
||||
|
||||
/* - useful code to manage external query: List<T> query<T>(class<T> clazz, ); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2"); */
|
||||
/** Execute a simple query with external property.
|
||||
* @param <TYPE> Type of the data generate.
|
||||
* @param clazz Class that might be analyze.
|
||||
* @param query Base of the query.
|
||||
* @param parameters "?" parameter of the query.
|
||||
* @param option Optional parameters
|
||||
* @return The list of element requested
|
||||
* @throws Exception */
|
||||
public static <TYPE> List<TYPE> query(final Class<TYPE> clazz, final String query, final List<Object> parameters, final QueryOption... option) throws Exception {
|
||||
final QueryOptions options = new QueryOptions(option);
|
||||
return query(clazz, query, parameters, options);
|
||||
@ -1529,6 +1574,19 @@ public class DataAccess {
|
||||
try {
|
||||
final CountInOut count = new CountInOut();
|
||||
condition.whereAppendQuery(query, null, options, null);
|
||||
|
||||
final GroupBy groups = options.get(GroupBy.class);
|
||||
if (groups != null) {
|
||||
groups.generateQuerry(query, null);
|
||||
}
|
||||
final OrderBy orders = options.get(OrderBy.class);
|
||||
if (orders != null) {
|
||||
orders.generateQuerry(query, null);
|
||||
}
|
||||
final Limit limit = options.get(Limit.class);
|
||||
if (limit != null) {
|
||||
limit.generateQuerry(query, null);
|
||||
}
|
||||
LOGGER.warn("generate the query: '{}'", query.toString());
|
||||
// prepare the request:
|
||||
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
|
||||
@ -1540,16 +1598,21 @@ public class DataAccess {
|
||||
iii.inc();
|
||||
}
|
||||
condition.injectQuerry(ps, iii);
|
||||
if (limit != null) {
|
||||
limit.injectQuerry(ps, iii);
|
||||
}
|
||||
// execute the request
|
||||
final ResultSet rs = ps.executeQuery();
|
||||
final ResultSetMetaData rsmd = rs.getMetaData();
|
||||
final List<RetreiveFromDB> actionToRetreive = new ArrayList<>();
|
||||
LOGGER.info("Field:");
|
||||
for (int jjj = 0; jjj < rsmd.getColumnCount(); jjj++) {
|
||||
final String name = rsmd.getColumnName(jjj + 1);
|
||||
final String label = rsmd.getColumnLabel(jjj + 1);
|
||||
LOGGER.info(" - {}:{}", jjj, label);
|
||||
// find field name ...
|
||||
final Field field = AnnotationTools.getFieldNamed(clazz, name);
|
||||
final Field field = AnnotationTools.getFieldNamed(clazz, label);
|
||||
if (field == null) {
|
||||
throw new DataAccessException("Querry with unknown field: '" + name + "'");
|
||||
throw new DataAccessException("Querry with unknown field: '" + label + "'");
|
||||
}
|
||||
// create the callback...
|
||||
final RetreiveFromDB element = createSetValueFromDbCallback(jjj + 1, field);
|
||||
@ -1558,7 +1621,6 @@ public class DataAccess {
|
||||
|
||||
while (rs.next()) {
|
||||
count.value = 1;
|
||||
final CountInOut countNotNull = new CountInOut(0);
|
||||
Object data = null;
|
||||
for (final Constructor<?> contructor : clazz.getConstructors()) {
|
||||
if (contructor.getParameterCount() == 0) {
|
||||
@ -1590,5 +1652,4 @@ public class DataAccess {
|
||||
}
|
||||
return outs;
|
||||
}
|
||||
|
||||
}
|
387
src/org/kar/archidata/dataAccess/DataExport.java
Normal file
387
src/org/kar/archidata/dataAccess/DataExport.java
Normal file
@ -0,0 +1,387 @@
|
||||
package org.kar.archidata.dataAccess;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.kar.archidata.dataAccess.exportTools.TableQuery;
|
||||
import org.kar.archidata.dataAccess.exportTools.TableQueryTypes;
|
||||
import org.kar.archidata.dataAccess.options.Condition;
|
||||
import org.kar.archidata.dataAccess.options.DBInterfaceOption;
|
||||
import org.kar.archidata.db.DBEntry;
|
||||
import org.kar.archidata.exception.DataAccessException;
|
||||
import org.kar.archidata.tools.DateTools;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
public class DataExport {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(DataExport.class);
|
||||
public static final String CSV_TYPE = "text/csv";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static RetreiveFromDB createSetValueFromDbCallbackTable(final int count, final Class<?> type, final int id) throws Exception {
|
||||
if (type == UUID.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final UUID tmp = rs.getObject(count, UUID.class);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == Long.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Long tmp = rs.getLong(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == long.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Long tmp = rs.getLong(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == Integer.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Integer tmp = rs.getInt(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == int.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Integer tmp = rs.getInt(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == Float.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Float tmp = rs.getFloat(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == float.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Float tmp = rs.getFloat(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == Double.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Double tmp = rs.getDouble(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == double.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Double tmp = rs.getDouble(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == Boolean.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Boolean tmp = rs.getBoolean(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == boolean.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Boolean tmp = rs.getBoolean(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == Timestamp.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final Timestamp tmp = rs.getTimestamp(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == Date.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
try {
|
||||
final Timestamp tmp = rs.getTimestamp(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, Date.from(tmp.toInstant()));
|
||||
}
|
||||
} catch (final SQLException ex) {
|
||||
final String tmp = rs.getString(count);
|
||||
LOGGER.error("Fail to parse the SQL time !!! {}", tmp);
|
||||
if (!rs.wasNull()) {
|
||||
final Date date = DateTools.parseDate(tmp);
|
||||
LOGGER.error("Fail to parse the SQL time !!! {}", date);
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, date);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == LocalDate.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final java.sql.Date tmp = rs.getDate(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp.toLocalDate());
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == LocalTime.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final java.sql.Time tmp = rs.getTime(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp.toLocalTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type == String.class) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final String tmp = rs.getString(count);
|
||||
if (!rs.wasNull()) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, tmp);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (type.isEnum()) {
|
||||
return (final ResultSet rs, final Object obj) -> {
|
||||
final String tmp = rs.getString(count);
|
||||
if (!rs.wasNull()) {
|
||||
boolean find = false;
|
||||
final Object[] arr = type.getEnumConstants();
|
||||
for (final Object elem : arr) {
|
||||
if (elem.toString().equals(tmp)) {
|
||||
final List<Object> data = (List<Object>) (obj);
|
||||
data.set(id, elem);
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
throw new DataAccessException("Enum value does not exist in the Model: '" + tmp + "'");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
throw new DataAccessException("Unknown Field Type");
|
||||
|
||||
}
|
||||
|
||||
private static int getQueryPropertyId(final List<TableQueryTypes> properties, final String name) throws DataAccessException {
|
||||
for (int iii = 0; iii < properties.size(); iii++) {
|
||||
if (properties.get(iii).name.equals(name)) {
|
||||
return iii;
|
||||
}
|
||||
}
|
||||
throw new DataAccessException("Querry with unknown field: '" + name + "'");
|
||||
}
|
||||
|
||||
public static TableQuery queryTable(final List<TableQueryTypes> headers, final String query, final List<Object> parameters, final QueryOption... option) throws Exception {
|
||||
final QueryOptions options = new QueryOptions(option);
|
||||
return queryTable(headers, query, parameters, options);
|
||||
}
|
||||
|
||||
public static TableQuery queryTable(final List<TableQueryTypes> headers, final String queryBase, final List<Object> parameters, final QueryOptions options) throws Exception {
|
||||
final List<LazyGetter> lazyCall = new ArrayList<>();
|
||||
// TODO ... final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
||||
final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
|
||||
|
||||
Condition condition = options.get(Condition.class);
|
||||
if (condition == null) {
|
||||
condition = new Condition();
|
||||
}
|
||||
final StringBuilder query = new StringBuilder(queryBase);
|
||||
final TableQuery out = new TableQuery(headers);
|
||||
// real add in the BDD:
|
||||
try {
|
||||
final CountInOut count = new CountInOut();
|
||||
condition.whereAppendQuery(query, null, options, null);
|
||||
|
||||
final GroupBy groups = options.get(GroupBy.class);
|
||||
if (groups != null) {
|
||||
groups.generateQuerry(query, null);
|
||||
}
|
||||
final OrderBy orders = options.get(OrderBy.class);
|
||||
if (orders != null) {
|
||||
orders.generateQuerry(query, null);
|
||||
}
|
||||
final Limit limit = options.get(Limit.class);
|
||||
if (limit != null) {
|
||||
limit.generateQuerry(query, null);
|
||||
}
|
||||
LOGGER.warn("generate the query: '{}'", query.toString());
|
||||
// prepare the request:
|
||||
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
|
||||
final CountInOut iii = new CountInOut(1);
|
||||
if (parameters != null) {
|
||||
for (final Object elem : parameters) {
|
||||
DataAccess.addElement(ps, elem, iii);
|
||||
}
|
||||
iii.inc();
|
||||
}
|
||||
condition.injectQuerry(ps, iii);
|
||||
if (limit != null) {
|
||||
limit.injectQuerry(ps, iii);
|
||||
}
|
||||
// execute the request
|
||||
final ResultSet rs = ps.executeQuery();
|
||||
final ResultSetMetaData rsmd = rs.getMetaData();
|
||||
final List<RetreiveFromDB> actionToRetreive = new ArrayList<>();
|
||||
LOGGER.info("Field:");
|
||||
for (int jjj = 0; jjj < rsmd.getColumnCount(); jjj++) {
|
||||
final String label = rsmd.getColumnLabel(jjj + 1);
|
||||
final String typeName = rsmd.getColumnTypeName(jjj + 1);
|
||||
final int typeId = rsmd.getColumnType(jjj + 1);
|
||||
final int id = getQueryPropertyId(headers, label);
|
||||
LOGGER.info(" - {}:{} type=[{}] {} REQUEST={}", jjj, label, typeId, typeName, headers.get(id).type.getCanonicalName());
|
||||
// create the callback...
|
||||
final RetreiveFromDB element = createSetValueFromDbCallbackTable(jjj + 1, headers.get(id).type, id);
|
||||
actionToRetreive.add(element);
|
||||
}
|
||||
while (rs.next()) {
|
||||
count.value = 1;
|
||||
final List<Object> data = Arrays.asList(new Object[headers.size()]);
|
||||
for (final RetreiveFromDB action : actionToRetreive) {
|
||||
action.doRequest(rs, data);
|
||||
}
|
||||
out.values.add(data);
|
||||
}
|
||||
LOGGER.info("Async calls: {}", lazyCall.size());
|
||||
for (final LazyGetter elem : lazyCall) {
|
||||
elem.doRequest();
|
||||
}
|
||||
} catch (final SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
throw ex;
|
||||
} catch (final Exception ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
entry.close();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public static String CSVReplaceSeparator(final String data, final String separator) {
|
||||
if (data == null) {
|
||||
return "";
|
||||
}
|
||||
final String separatorLine = "\n";
|
||||
final String separatorLineReplace = "\\n";
|
||||
return data.replaceAll(separator, "__SEP__").replaceAll(separatorLine, separatorLineReplace);
|
||||
}
|
||||
|
||||
public static String tableToCSV(final TableQuery data) {
|
||||
final String separator = ";";
|
||||
final StringBuilder out = new StringBuilder();
|
||||
// generate header:
|
||||
boolean first = true;
|
||||
for (final TableQueryTypes elem : data.headers) {
|
||||
if (!first) {
|
||||
out.append(separator);
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
out.append(CSVReplaceSeparator(elem.title, separator));
|
||||
}
|
||||
out.append("\n");
|
||||
// generate body:
|
||||
first = true;
|
||||
for (final List<Object> line : data.values) {
|
||||
for (final Object elem : line) {
|
||||
if (!first) {
|
||||
out.append(separator);
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
if (elem != null) {
|
||||
out.append(CSVReplaceSeparator(elem.toString(), separator));
|
||||
}
|
||||
}
|
||||
out.append("\n");
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static Response convertInResponse(final TableQuery dataOut, final String accept) throws DataAccessException, IOException {
|
||||
if (CSV_TYPE.equals(accept)) {
|
||||
// CSV serialization
|
||||
String out = null;
|
||||
try {
|
||||
out = DataExport.tableToCSV(dataOut);
|
||||
} catch (final Exception e) {
|
||||
LOGGER.error("Fail to generate CSV....");
|
||||
e.printStackTrace();
|
||||
throw new DataAccessException("Fail in CSV convertion data");
|
||||
}
|
||||
return Response.ok(out).header("Content-Type", CSV_TYPE).build();
|
||||
}
|
||||
if (MediaType.APPLICATION_JSON.equals(accept)) {
|
||||
LOGGER.info("Start mapping josn");
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
LOGGER.info("Start find modules josn");
|
||||
objectMapper.findAndRegisterModules();
|
||||
LOGGER.info("Start map object");
|
||||
String out;
|
||||
try {
|
||||
out = objectMapper.writeValueAsString(dataOut);
|
||||
} catch (final JsonProcessingException e) {
|
||||
LOGGER.error("Fail to generate JSON....");
|
||||
e.printStackTrace();
|
||||
throw new DataAccessException("Fail in JSON convertion data");
|
||||
}
|
||||
LOGGER.info("generate response");
|
||||
return Response.ok(out).header("Content-Type", MediaType.APPLICATION_JSON).build();
|
||||
}
|
||||
throw new IOException("This type is not managed: '" + accept + "'");
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,7 @@ import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.kar.archidata.annotation.AnnotationTools;
|
||||
import org.kar.archidata.annotation.CreationTimestamp;
|
||||
@ -27,6 +28,9 @@ public class DataFactory {
|
||||
|
||||
public static String convertTypeInSQL(final Class<?> type, final String fieldName) throws Exception {
|
||||
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
|
||||
if (type == UUID.class) {
|
||||
return "binary(16)";
|
||||
}
|
||||
if (type == Long.class || type == long.class) {
|
||||
return "bigint";
|
||||
}
|
||||
@ -75,6 +79,9 @@ public class DataFactory {
|
||||
return out.toString();
|
||||
}
|
||||
} else {
|
||||
if (type == UUID.class) {
|
||||
return "BINARY(16)";
|
||||
}
|
||||
if (type == Long.class || type == long.class) {
|
||||
return "INTEGER";
|
||||
}
|
||||
|
39
src/org/kar/archidata/dataAccess/GroupBy.java
Normal file
39
src/org/kar/archidata/dataAccess/GroupBy.java
Normal file
@ -0,0 +1,39 @@
|
||||
package org.kar.archidata.dataAccess;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.List;
|
||||
|
||||
public class GroupBy extends QueryOption {
|
||||
protected final List<String> childs;
|
||||
|
||||
public GroupBy(final List<String> childs) {
|
||||
this.childs = childs;
|
||||
}
|
||||
|
||||
public GroupBy(final String... childs) {
|
||||
this.childs = List.of(childs);
|
||||
}
|
||||
|
||||
public void generateQuerry(final StringBuilder query, final String tableName) {
|
||||
if (this.childs.size() == 0) {
|
||||
return;
|
||||
}
|
||||
query.append(" GROUP BY ");
|
||||
boolean first = true;
|
||||
for (final String elem : this.childs) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
query.append(", ");
|
||||
}
|
||||
// query.append("`");
|
||||
query.append(elem);
|
||||
// query.append("` ");
|
||||
}
|
||||
query.append("\n");
|
||||
}
|
||||
|
||||
public void injectQuerry(final PreparedStatement ps, final CountInOut iii) throws Exception {
|
||||
// nothing to add.
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ public class Limit extends QueryOption {
|
||||
}
|
||||
|
||||
public void generateQuerry(final StringBuilder query, final String tableName) {
|
||||
query.append(" LIMIT ? ");
|
||||
query.append(" LIMIT ? \n");
|
||||
}
|
||||
|
||||
public void injectQuerry(final PreparedStatement ps, final CountInOut iii) throws Exception {
|
||||
|
@ -15,9 +15,10 @@ public class OrderBy extends QueryOption {
|
||||
}
|
||||
|
||||
public void generateQuerry(final StringBuilder query, final String tableName) {
|
||||
if (this.childs.size() >= 1) {
|
||||
query.append(" ORDER BY ");
|
||||
if (this.childs.size() == 0) {
|
||||
return;
|
||||
}
|
||||
query.append(" ORDER BY ");
|
||||
boolean first = true;
|
||||
for (final OrderItem elem : this.childs) {
|
||||
if (first) {
|
||||
@ -25,14 +26,13 @@ public class OrderBy extends QueryOption {
|
||||
} else {
|
||||
query.append(", ");
|
||||
}
|
||||
query.append("`");
|
||||
// query.append("`");
|
||||
query.append(elem.value);
|
||||
query.append("` ");
|
||||
// query.append("`");
|
||||
query.append(" ");
|
||||
query.append(elem.order.toString());
|
||||
}
|
||||
if (this.childs.size() >= 1) {
|
||||
query.append(")");
|
||||
}
|
||||
query.append("\n");
|
||||
}
|
||||
|
||||
public void injectQuerry(final PreparedStatement ps, final CountInOut iii) throws Exception {
|
||||
|
14
src/org/kar/archidata/dataAccess/exportTools/TableQuery.java
Normal file
14
src/org/kar/archidata/dataAccess/exportTools/TableQuery.java
Normal file
@ -0,0 +1,14 @@
|
||||
package org.kar.archidata.dataAccess.exportTools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TableQuery {
|
||||
|
||||
public final List<TableQueryTypes> headers;
|
||||
public final List<List<Object>> values = new ArrayList<>();
|
||||
|
||||
public TableQuery(final List<TableQueryTypes> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package org.kar.archidata.dataAccess.exportTools;
|
||||
|
||||
public class TableQueryTypes {
|
||||
|
||||
public Class<?> type;
|
||||
public String name;
|
||||
public String title;
|
||||
|
||||
public TableQueryTypes(final Class<?> type, final String name, final String title) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public TableQueryTypes(final Class<?> type, final String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.title = name;
|
||||
}
|
||||
}
|
@ -43,13 +43,12 @@ public class Condition extends QueryOption {
|
||||
query.append(tableName);
|
||||
query.append(".");
|
||||
query.append(deletedFieldName);
|
||||
query.append(" = false ");
|
||||
query.append(" = false \n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
query.append(" WHERE (");
|
||||
this.condition.generateQuerry(query, tableName);
|
||||
|
||||
query.append(") ");
|
||||
if (exclude_deleted && deletedFieldName != null) {
|
||||
query.append("AND ");
|
||||
@ -58,5 +57,6 @@ public class Condition extends QueryOption {
|
||||
query.append(deletedFieldName);
|
||||
query.append(" = false ");
|
||||
}
|
||||
query.append("\n");
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import jakarta.persistence.Table;
|
||||
@DataIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Data extends GenericDataSoftDelete {
|
||||
|
||||
@Column(length = 128, nullable = false)
|
||||
@Schema(description = "Sha512 of the data")
|
||||
public String sha512;
|
||||
|
@ -1,38 +1,15 @@
|
||||
package org.kar.archidata.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.kar.archidata.annotation.CreationTimestamp;
|
||||
import org.kar.archidata.annotation.DataNotRead;
|
||||
import org.kar.archidata.annotation.UpdateTimestamp;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Temporal;
|
||||
import jakarta.persistence.TemporalType;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public class GenericData {
|
||||
public class GenericData extends GenericTiming {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(nullable = false, unique = true)
|
||||
@Schema(description = "Unique Id of the object", required = false, readOnly = true, example = "123456")
|
||||
public Long id = null;
|
||||
@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)
|
||||
public Date createdAt = null;
|
||||
@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)
|
||||
public Date updatedAt = null;
|
||||
}
|
||||
|
34
src/org/kar/archidata/model/GenericTiming.java
Normal file
34
src/org/kar/archidata/model/GenericTiming.java
Normal file
@ -0,0 +1,34 @@
|
||||
package org.kar.archidata.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
import org.kar.archidata.annotation.CreationTimestamp;
|
||||
import org.kar.archidata.annotation.DataNotRead;
|
||||
import org.kar.archidata.annotation.UpdateTimestamp;
|
||||
|
||||
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")
|
||||
public Date createdAt = null;
|
||||
@DataNotRead
|
||||
@UpdateTimestamp
|
||||
@Column(nullable = false)
|
||||
@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;
|
||||
}
|
16
src/org/kar/archidata/model/UUIDGenericData.java
Normal file
16
src/org/kar/archidata/model/UUIDGenericData.java
Normal file
@ -0,0 +1,16 @@
|
||||
package org.kar.archidata.model;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.ws.rs.DefaultValue;
|
||||
|
||||
public class UUIDGenericData extends GenericTiming {
|
||||
@Id
|
||||
@DefaultValue("UUID_TO_BIN(UUID())")
|
||||
@Column(nullable = false, unique = true)
|
||||
@Schema(description = "Unique UUID of the object", required = false, readOnly = true, example = "e6b33c1c-d24d-11ee-b616-02420a030102")
|
||||
public UUID id = null;
|
||||
}
|
19
src/org/kar/archidata/model/UUIDGenericDataSoftDelete.java
Normal file
19
src/org/kar/archidata/model/UUIDGenericDataSoftDelete.java
Normal file
@ -0,0 +1,19 @@
|
||||
package org.kar.archidata.model;
|
||||
|
||||
import org.kar.archidata.annotation.DataDefault;
|
||||
import org.kar.archidata.annotation.DataDeleted;
|
||||
import org.kar.archidata.annotation.DataNotRead;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public class UUIDGenericDataSoftDelete extends UUIDGenericData {
|
||||
@DataNotRead
|
||||
@Column(nullable = false)
|
||||
@DataDefault("'0'")
|
||||
@DataDeleted
|
||||
@NotNull
|
||||
@Schema(description = "Deleted state", hidden = true, required = false, readOnly = true)
|
||||
public Boolean deleted = null;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package org.kar.archidata.serializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
|
||||
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
|
||||
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.MultivaluedMap;
|
||||
import jakarta.ws.rs.ext.MessageBodyWriter;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
|
||||
/** Body writer use in jersey with : In your main: ```java rc.register(new CSVMessageBodyWritter()); ```
|
||||
*
|
||||
* and in the produce element: ```java
|
||||
* @GET
|
||||
* @Produces(CSVMessageBodyWritter.CSV_TYPE) public List<Data> getData() {} ``` */
|
||||
@Provider
|
||||
@Produces("text/csv")
|
||||
public class CSVMessageBodyWriter implements MessageBodyWriter<List<Object>> {
|
||||
public static final String CSV_TYPE = "text/csv";
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
|
||||
return List.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize(final List<Object> data, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(final List<Object> data, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType,
|
||||
final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException, WebApplicationException {
|
||||
if (data != null && data.size() > 0) {
|
||||
final CsvMapper mapper = new CsvMapper();
|
||||
final Object o = data.get(0);
|
||||
final CsvSchema schema = mapper.schemaFor(o.getClass()).withHeader();
|
||||
mapper.writer(schema).writeValue(entityStream, data);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user