diff --git a/src/main/java/tech/ailef/dbadmin/external/controller/DataExportController.java b/src/main/java/tech/ailef/dbadmin/external/controller/DataExportController.java index 3900d94..b357d48 100644 --- a/src/main/java/tech/ailef/dbadmin/external/controller/DataExportController.java +++ b/src/main/java/tech/ailef/dbadmin/external/controller/DataExportController.java @@ -6,6 +6,7 @@ import java.io.StringWriter; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -31,6 +32,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + import tech.ailef.dbadmin.external.DbAdmin; import tech.ailef.dbadmin.external.dbmapping.DbAdminRepository; import tech.ailef.dbadmin.external.dbmapping.DbField; @@ -52,6 +56,9 @@ public class DataExportController { @Autowired private DbAdminRepository repository; + + @Autowired + private ObjectMapper mapper; @GetMapping("/{className}") @ResponseBody @@ -90,6 +97,12 @@ public class DataExportController { .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"export_" + schema.getJavaClass().getSimpleName() + ".xlsx\"") .body(toXlsx(sheetName, results, fieldsToInclude, raw)); + case JSONL: + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, + "attachment; filename=\"export_" + schema.getJavaClass().getSimpleName() + ".jsonl\"") + .body(toJsonl(results, fieldsToInclude, raw).getBytes()); + default: throw new DbAdminException("Invalid DataExportFormat"); } @@ -139,6 +152,35 @@ public class DataExportController { return fos.toByteArray(); } + /** + * Converts a list of DbObjects to a string containing their JSONL representation. + * One item per line in JSON format. + * @param items the items to be serialized + * @param fields the fields to take from each item + * @param raw whether to use raw values or not + * @return a string containing the items serialized in JSONL format + */ + private String toJsonl(List items, List fields, boolean raw) { + if (items.isEmpty()) + return ""; + + StringBuilder sb = new StringBuilder(); + + for (DbObject item : items) { + Map map = item.toMap(fields, raw); + try { + String json = mapper.writeValueAsString(map); + sb.append(json); + } catch (JsonProcessingException e) { + throw new DbAdminException(e); + } + + sb.append("\n"); + } + + return sb.toString(); + } + private String toCsv(List items, List fields, boolean raw) { if (items.isEmpty()) return ""; @@ -219,4 +261,5 @@ public class DataExportController { return record; } + } diff --git a/src/main/java/tech/ailef/dbadmin/external/dbmapping/DbObject.java b/src/main/java/tech/ailef/dbadmin/external/dbmapping/DbObject.java index baf5bcb..07ca29d 100644 --- a/src/main/java/tech/ailef/dbadmin/external/dbmapping/DbObject.java +++ b/src/main/java/tech/ailef/dbadmin/external/dbmapping/DbObject.java @@ -22,7 +22,9 @@ package tech.ailef.dbadmin.external.dbmapping; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -255,6 +257,54 @@ public class DbObject { return null; } + + /** + * Converts this object to map where each key is a field name, + * including only the specified fields. + * If raw, values are not processed and are included as they are + * in the database table. + * + * @return + */ + public Map toMap(List fields, boolean raw) { + Map result = new HashMap<>(); + + for (String field : fields) { + DbField dbField = schema.getFieldByName(field); + + if (dbField == null) { + // The field is a computed column + Object computedValue = compute(field); + result.put(field, computedValue); + } else { + if (dbField.isForeignKey()) { + DbObject linkedItem = traverse(dbField); + + if (linkedItem == null) result.put(field, null); + else { + if (raw) { + result.put(field, linkedItem.getPrimaryKeyValue().toString()); + } else { + result.put(field, linkedItem.getPrimaryKeyValue() + " (" + linkedItem.getDisplayName() + ")"); + } + } + } else { + if (raw) { + DbFieldValue fieldValue = get(dbField); + if (fieldValue.getValue() == null) result.put(field, null); + else result.put(field, fieldValue.getValue().toString()); + } else { + + result.put(field, get(dbField).getFormattedValue()); + } + + } + } + } + + + return result; + } @Override public String toString() { diff --git a/src/main/java/tech/ailef/dbadmin/external/dto/DataExportFormat.java b/src/main/java/tech/ailef/dbadmin/external/dto/DataExportFormat.java index 29e4fb7..442e036 100644 --- a/src/main/java/tech/ailef/dbadmin/external/dto/DataExportFormat.java +++ b/src/main/java/tech/ailef/dbadmin/external/dto/DataExportFormat.java @@ -2,5 +2,6 @@ package tech.ailef.dbadmin.external.dto; public enum DataExportFormat { CSV, - XLSX; + XLSX, + JSONL; }