mirror of
https://github.com/dalbodeule/snap-admin.git
synced 2025-12-16 05:12:00 +09:00
0.1.2
This commit is contained in:
@@ -7,8 +7,9 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
@@ -20,12 +21,13 @@ import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import tech.ailef.dbadmin.external.annotations.DisplayFormat;
|
||||
import tech.ailef.dbadmin.external.dbmapping.AdvancedJpaRepository;
|
||||
import tech.ailef.dbadmin.external.dbmapping.CustomJpaRepository;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbField;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbFieldType;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObjectSchema;
|
||||
@@ -43,9 +45,8 @@ import tech.ailef.dbadmin.external.misc.Utils;
|
||||
*/
|
||||
@Component
|
||||
public class DbAdmin {
|
||||
private static final Logger logger = Logger.getLogger(DbAdmin.class.getName());
|
||||
private static final Logger logger = LoggerFactory.getLogger(DbAdmin.class.getName());
|
||||
|
||||
// @PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
private List<DbObjectSchema> schemas = new ArrayList<>();
|
||||
@@ -125,25 +126,23 @@ public class DbAdmin {
|
||||
try {
|
||||
Class<?> klass = Class.forName(fullClassName);
|
||||
DbObjectSchema schema = new DbObjectSchema(klass, this);
|
||||
AdvancedJpaRepository simpleJpaRepository = new AdvancedJpaRepository(schema, entityManager);
|
||||
CustomJpaRepository simpleJpaRepository = new CustomJpaRepository(schema, entityManager);
|
||||
schema.setJpaRepository(simpleJpaRepository);
|
||||
|
||||
System.out.println("\n\n******************************************************");
|
||||
System.out.println("* Class: " + klass + " - Table: " + schema.getTableName());
|
||||
System.out.println("******************************************************");
|
||||
|
||||
logger.debug("Processing class: " + klass + " - Table: " + schema.getTableName());
|
||||
|
||||
Field[] fields = klass.getDeclaredFields();
|
||||
for (Field f : fields) {
|
||||
System.out.println(" - Mapping field " + f);
|
||||
DbField field = mapField(f, schema);
|
||||
if (field == null) {
|
||||
throw new DbAdminException("Impossible to map field: " + f);
|
||||
}
|
||||
field.setSchema(schema);
|
||||
|
||||
schema.addField(field);
|
||||
}
|
||||
|
||||
logger.debug("Processed " + klass + ", extracted " + schema.getSortedFields().size() + " fields");
|
||||
|
||||
return schema;
|
||||
} catch (ClassNotFoundException |
|
||||
IllegalArgumentException | SecurityException e) {
|
||||
@@ -201,6 +200,7 @@ public class DbAdmin {
|
||||
ManyToMany manyToMany = f.getAnnotation(ManyToMany.class);
|
||||
ManyToOne manyToOne = f.getAnnotation(ManyToOne.class);
|
||||
OneToOne oneToOne = f.getAnnotation(OneToOne.class);
|
||||
Lob lob = f.getAnnotation(Lob.class);
|
||||
|
||||
String fieldName = determineFieldName(f);
|
||||
|
||||
@@ -212,6 +212,10 @@ public class DbAdmin {
|
||||
DbFieldType fieldType = null;
|
||||
try {
|
||||
fieldType = DbFieldType.fromClass(f.getType());
|
||||
|
||||
if (fieldType != null && lob != null && fieldType == DbFieldType.STRING) {
|
||||
fieldType = DbFieldType.TEXT;
|
||||
}
|
||||
} catch (DbAdminException e) {
|
||||
// If failure, we try to map a relationship on this field
|
||||
}
|
||||
|
||||
@@ -16,4 +16,5 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Filterable {
|
||||
public FilterableType type() default FilterableType.DEFAULT;
|
||||
}
|
||||
5
src/main/java/tech/ailef/dbadmin/external/annotations/FilterableType.java
vendored
Normal file
5
src/main/java/tech/ailef/dbadmin/external/annotations/FilterableType.java
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
package tech.ailef.dbadmin.external.annotations;
|
||||
|
||||
public enum FilterableType {
|
||||
DEFAULT, CATEGORICAL;
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@@ -89,7 +88,7 @@ public class DefaultDbAdminController {
|
||||
model.addAttribute("schemas", schemas);
|
||||
model.addAttribute("query", query);
|
||||
model.addAttribute("counts", counts);
|
||||
model.addAttribute("activePage", "home");
|
||||
model.addAttribute("activePage", "entities");
|
||||
model.addAttribute("title", "Entities | Index");
|
||||
|
||||
return "home";
|
||||
@@ -124,17 +123,20 @@ public class DefaultDbAdminController {
|
||||
if (page == null) page = 1;
|
||||
if (pageSize == null) pageSize = 50;
|
||||
|
||||
Set<QueryFilter> queryFilters = Utils.computeFilters(otherParams);
|
||||
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
||||
|
||||
Set<QueryFilter> queryFilters = Utils.computeFilters(schema, otherParams);
|
||||
if (otherParams.containsKey("remove_field")) {
|
||||
List<String> fields = otherParams.get("remove_field");
|
||||
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
QueryFilter toRemove =
|
||||
new QueryFilter(
|
||||
fields.get(i),
|
||||
schema.getFieldByJavaName(fields.get(i)),
|
||||
CompareOperator.valueOf(otherParams.get("remove_op").get(i).toUpperCase()),
|
||||
otherParams.get("remove_value").get(i)
|
||||
);
|
||||
|
||||
queryFilters.removeIf(f -> f.equals(toRemove));
|
||||
}
|
||||
|
||||
@@ -160,8 +162,6 @@ public class DefaultDbAdminController {
|
||||
return "redirect:" + redirectUrl.trim();
|
||||
}
|
||||
|
||||
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
||||
|
||||
try {
|
||||
PaginatedResult<DbObject> result = null;
|
||||
if (query != null || !otherParams.isEmpty()) {
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
package tech.ailef.dbadmin.external.controller.rest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import tech.ailef.dbadmin.external.DbAdmin;
|
||||
import tech.ailef.dbadmin.external.DbAdminProperties;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbAdminRepository;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.external.dto.PaginatedResult;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = {"/${dbadmin.baseUrl}/api", "/${dbadmin.baseUrl}/api/"})
|
||||
public class DefaultDbAdminRestController {
|
||||
@Autowired
|
||||
public DbAdmin dbAdmin;
|
||||
|
||||
@Autowired
|
||||
private DbAdminProperties properties;
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
// @Autowired
|
||||
// @Qualifier("internalJdbc")
|
||||
// private JdbcTemplate internalJdbc;
|
||||
|
||||
// @GetMapping("/configuration")
|
||||
// public ResponseEntity<?> conf() {
|
||||
// return ResponseEntity.ok(properties.toMap());
|
||||
// }
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<?> index(@RequestParam(required = false) String query) {
|
||||
checkInit();
|
||||
|
||||
List<DbObjectSchema> schemas = dbAdmin.getSchemas();
|
||||
if (query != null && !query.isBlank()) {
|
||||
schemas = schemas.stream().filter(s -> {
|
||||
return s.getClassName().toLowerCase().contains(query.toLowerCase())
|
||||
|| s.getTableName().toLowerCase().contains(query.toLowerCase());
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(schemas);
|
||||
}
|
||||
|
||||
@GetMapping("/model/{className}")
|
||||
public ResponseEntity<?> list(@PathVariable String className,
|
||||
@RequestParam(required=false) Integer page, @RequestParam(required=false) Integer pageSize,
|
||||
@RequestParam(required=false) String sortKey, @RequestParam(required=false) String sortOrder) {
|
||||
checkInit();
|
||||
DbAdminRepository repository = new DbAdminRepository(jdbcTemplate);
|
||||
|
||||
if (page == null) page = 1;
|
||||
if (pageSize == null) pageSize = 50;
|
||||
|
||||
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
||||
PaginatedResult result = repository.findAll(schema, page, pageSize, sortKey, sortOrder);
|
||||
|
||||
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
@GetMapping("/model/{className}/schema")
|
||||
public ResponseEntity<?> schema(@PathVariable String className) {
|
||||
checkInit();
|
||||
|
||||
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
||||
|
||||
return ResponseEntity.ok(schema);
|
||||
}
|
||||
|
||||
// @GetMapping("/model/{className}/show/{id}")
|
||||
// public ResponseEntity<?> show(@PathVariable String className, @PathVariable String id,
|
||||
// @RequestParam(required = false) Boolean expand) {
|
||||
// checkInit();
|
||||
// DbAdminRepository repository = new DbAdminRepository(jdbcTemplate);
|
||||
// if (expand == null) expand = true;
|
||||
//
|
||||
// DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
||||
//
|
||||
// DbObject object = repository.findById(schema, id).orElseThrow(() -> {
|
||||
// return new ResponseStatusException(
|
||||
// HttpStatus.NOT_FOUND, "Object " + className + " with id " + id + " not found"
|
||||
// );
|
||||
// });
|
||||
//
|
||||
// return ResponseEntity.ok(new DbObjectDTO(object, expand));
|
||||
// }
|
||||
|
||||
private void checkInit() {
|
||||
if (dbAdmin == null)
|
||||
throw new DbAdminException("Not initialized correctly: DB_ADMIN object is null.");
|
||||
}
|
||||
}
|
||||
@@ -26,14 +26,14 @@ import tech.ailef.dbadmin.external.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class AdvancedJpaRepository extends SimpleJpaRepository {
|
||||
public class CustomJpaRepository extends SimpleJpaRepository {
|
||||
|
||||
private EntityManager entityManager;
|
||||
|
||||
private DbObjectSchema schema;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public AdvancedJpaRepository(DbObjectSchema schema, EntityManager em) {
|
||||
public CustomJpaRepository(DbObjectSchema schema, EntityManager em) {
|
||||
super(schema.getJavaClass(), em);
|
||||
this.entityManager = em;
|
||||
this.schema = schema;
|
||||
@@ -90,7 +90,7 @@ public class AdvancedJpaRepository extends SimpleJpaRepository {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Predicate> queryPredicates = new ArrayList<>();
|
||||
if (q != null) {
|
||||
if (q != null && !q.isBlank()) {
|
||||
for (DbField f : stringFields) {
|
||||
Path path = root.get(f.getJavaName());
|
||||
queryPredicates.add(cb.like(cb.lower(cb.toString(path)), "%" + q.toLowerCase() + "%"));
|
||||
@@ -104,48 +104,51 @@ public class AdvancedJpaRepository extends SimpleJpaRepository {
|
||||
if (queryFilters == null) queryFilters = new HashSet<>();
|
||||
for (QueryFilter filter : queryFilters) {
|
||||
CompareOperator op = filter.getOp();
|
||||
String field = filter.getField();
|
||||
DbField dbField = filter.getField();
|
||||
String fieldName = dbField.getJavaName();
|
||||
String v = filter.getValue();
|
||||
|
||||
DbField dbField = schema.getFieldByJavaName(field);
|
||||
Object value = dbField.getType().parseValue(v);
|
||||
|
||||
if (op == CompareOperator.STRING_EQ) {
|
||||
finalPredicates.add(cb.equal(cb.lower(cb.toString(root.get(field))), value.toString().toLowerCase()));
|
||||
if (value == null)
|
||||
finalPredicates.add(cb.isNull(root.get(fieldName)));
|
||||
else
|
||||
finalPredicates.add(cb.equal(cb.lower(cb.toString(root.get(fieldName))), value.toString().toLowerCase()));
|
||||
} else if (op == CompareOperator.CONTAINS) {
|
||||
finalPredicates.add(
|
||||
cb.like(cb.lower(cb.toString(root.get(field))), "%" + value.toString().toLowerCase() + "%")
|
||||
cb.like(cb.lower(cb.toString(root.get(fieldName))), "%" + value.toString().toLowerCase() + "%")
|
||||
);
|
||||
} else if (op == CompareOperator.EQ) {
|
||||
finalPredicates.add(
|
||||
cb.equal(root.get(field), value)
|
||||
cb.equal(root.get(fieldName), value)
|
||||
);
|
||||
} else if (op == CompareOperator.GT) {
|
||||
finalPredicates.add(
|
||||
cb.greaterThan(root.get(field), value.toString())
|
||||
cb.greaterThan(root.get(fieldName), value.toString())
|
||||
);
|
||||
} else if (op == CompareOperator.LT) {
|
||||
finalPredicates.add(
|
||||
cb.lessThan(root.get(field), value.toString())
|
||||
cb.lessThan(root.get(fieldName), value.toString())
|
||||
);
|
||||
} else if (op == CompareOperator.AFTER) {
|
||||
if (value instanceof LocalDate)
|
||||
finalPredicates.add(
|
||||
cb.greaterThan(root.get(field), (LocalDate)value)
|
||||
cb.greaterThan(root.get(fieldName), (LocalDate)value)
|
||||
);
|
||||
else if (value instanceof LocalDateTime)
|
||||
finalPredicates.add(
|
||||
cb.greaterThan(root.get(field), (LocalDateTime)value)
|
||||
cb.greaterThan(root.get(fieldName), (LocalDateTime)value)
|
||||
);
|
||||
|
||||
} else if (op == CompareOperator.BEFORE) {
|
||||
if (value instanceof LocalDate)
|
||||
finalPredicates.add(
|
||||
cb.lessThan(root.get(field), (LocalDate)value)
|
||||
cb.lessThan(root.get(fieldName), (LocalDate)value)
|
||||
);
|
||||
else if (value instanceof LocalDateTime)
|
||||
finalPredicates.add(
|
||||
cb.lessThan(root.get(field), (LocalDateTime)value)
|
||||
cb.lessThan(root.get(fieldName), (LocalDateTime)value)
|
||||
);
|
||||
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public class DbAdminRepository {
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public PaginatedResult findAll(DbObjectSchema schema, int page, int pageSize, String sortKey, String sortOrder) {
|
||||
public PaginatedResult<DbObject> findAll(DbObjectSchema schema, int page, int pageSize, String sortKey, String sortOrder) {
|
||||
SimpleJpaRepository repository = schema.getJpaRepository();
|
||||
|
||||
long maxElement = count(schema);
|
||||
@@ -193,7 +193,10 @@ public class DbAdminRepository {
|
||||
|
||||
files.keySet().forEach(f -> {
|
||||
try {
|
||||
allValues.put(f, files.get(f).getBytes());
|
||||
// The file parameter gets sent even if empty, so it's needed
|
||||
// to check if the file has actual content, to avoid storing an empty file
|
||||
if (files.get(f).getSize() > 0)
|
||||
allValues.put(f, files.get(f).getBytes());
|
||||
} catch (IOException e) {
|
||||
throw new DbAdminException(e);
|
||||
}
|
||||
@@ -217,7 +220,7 @@ public class DbAdminRepository {
|
||||
*/
|
||||
public PaginatedResult<DbObject> search(DbObjectSchema schema, String query, int page, int pageSize, String sortKey,
|
||||
String sortOrder, Set<QueryFilter> queryFilters) {
|
||||
AdvancedJpaRepository jpaRepository = schema.getJpaRepository();
|
||||
CustomJpaRepository jpaRepository = schema.getJpaRepository();
|
||||
|
||||
long maxElement = count(schema, query, queryFilters);
|
||||
int maxPage = (int)(Math.ceil ((double)maxElement / pageSize));
|
||||
@@ -242,7 +245,7 @@ public class DbAdminRepository {
|
||||
* @return
|
||||
*/
|
||||
public List<DbObject> search(DbObjectSchema schema, String query) {
|
||||
AdvancedJpaRepository jpaRepository = schema.getJpaRepository();
|
||||
CustomJpaRepository jpaRepository = schema.getJpaRepository();
|
||||
|
||||
return jpaRepository.search(query, 1, 50, null, null, null).stream()
|
||||
.map(o -> new DbObject(o, schema))
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import tech.ailef.dbadmin.external.annotations.DisplayImage;
|
||||
import tech.ailef.dbadmin.external.annotations.Filterable;
|
||||
import tech.ailef.dbadmin.external.annotations.FilterableType;
|
||||
|
||||
public class DbField {
|
||||
protected String dbName;
|
||||
@@ -124,6 +130,26 @@ public class DbField {
|
||||
return format;
|
||||
}
|
||||
|
||||
public boolean isText() {
|
||||
return type == DbFieldType.TEXT;
|
||||
}
|
||||
|
||||
public boolean isFilterable() {
|
||||
return getPrimitiveField().getAnnotation(Filterable.class) != null;
|
||||
}
|
||||
|
||||
public boolean isFilterableCategorical() {
|
||||
Filterable filterable = getPrimitiveField().getAnnotation(Filterable.class);
|
||||
return filterable != null && filterable.type() == FilterableType.CATEGORICAL;
|
||||
}
|
||||
|
||||
public Set<DbFieldValue> getAllValues() {
|
||||
List<?> findAll = schema.getJpaRepository().findAll();
|
||||
return findAll.stream()
|
||||
.map(o -> new DbObject(o, schema).get(this))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DbField [name=" + dbName + ", javaName=" + javaName + ", type=" + type + ", field=" + field
|
||||
@@ -131,6 +157,23 @@ public class DbField {
|
||||
+ ", schema=" + schema.getClassName() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(dbName, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
DbField other = (DbField) obj;
|
||||
return Objects.equals(dbName, other.dbName) && type == other.type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ public enum DbFieldType {
|
||||
|
||||
@Override
|
||||
public Object parseValue(Object value) {
|
||||
if (value == null) return null;
|
||||
return LocalDate.parse(value.toString());
|
||||
}
|
||||
|
||||
@@ -129,6 +130,7 @@ public enum DbFieldType {
|
||||
|
||||
@Override
|
||||
public Object parseValue(Object value) {
|
||||
if (value == null || value.toString().isBlank()) return null;
|
||||
return LocalDateTime.parse(value.toString());
|
||||
}
|
||||
|
||||
@@ -163,6 +165,28 @@ public enum DbFieldType {
|
||||
return List.of(CompareOperator.CONTAINS, CompareOperator.STRING_EQ);
|
||||
}
|
||||
},
|
||||
TEXT {
|
||||
@Override
|
||||
public String getHTMLName() {
|
||||
return "textarea";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseValue(Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getJavaClass() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompareOperator> getCompareOperators() {
|
||||
return List.of(CompareOperator.CONTAINS, CompareOperator.STRING_EQ);
|
||||
}
|
||||
|
||||
},
|
||||
BOOLEAN {
|
||||
@Override
|
||||
public String getHTMLName() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
public class DbFieldValue {
|
||||
@@ -39,6 +41,22 @@ public class DbFieldValue {
|
||||
public String toString() {
|
||||
return "DbFieldValue [value=" + value + ", field=" + field + "]";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(field, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
DbFieldValue other = (DbFieldValue) obj;
|
||||
return Objects.equals(field, other.field) && Objects.equals(value, other.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -18,7 +19,6 @@ import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import tech.ailef.dbadmin.external.DbAdmin;
|
||||
import tech.ailef.dbadmin.external.annotations.ComputedColumn;
|
||||
import tech.ailef.dbadmin.external.annotations.Filterable;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.external.misc.Utils;
|
||||
|
||||
@@ -39,7 +39,7 @@ public class DbObjectSchema {
|
||||
/**
|
||||
* A JPA repository to operate on the database
|
||||
*/
|
||||
private AdvancedJpaRepository jpaRepository;
|
||||
private CustomJpaRepository jpaRepository;
|
||||
|
||||
private DbAdmin dbAdmin;
|
||||
|
||||
@@ -113,11 +113,11 @@ public class DbObjectSchema {
|
||||
fields.add(f);
|
||||
}
|
||||
|
||||
public AdvancedJpaRepository getJpaRepository() {
|
||||
public CustomJpaRepository getJpaRepository() {
|
||||
return jpaRepository;
|
||||
}
|
||||
|
||||
public void setJpaRepository(AdvancedJpaRepository jpaRepository) {
|
||||
public void setJpaRepository(CustomJpaRepository jpaRepository) {
|
||||
this.jpaRepository = jpaRepository;
|
||||
}
|
||||
|
||||
@@ -182,13 +182,37 @@ public class DbObjectSchema {
|
||||
public List<DbField> getFilterableFields() {
|
||||
return getSortedFields().stream().filter(f -> {
|
||||
return !f.isBinary() && !f.isPrimaryKey()
|
||||
&& f.getPrimitiveField().getAnnotation(Filterable.class) != null;
|
||||
&& f.isFilterable();
|
||||
}).toList();
|
||||
}
|
||||
|
||||
public List<DbObject> findAll() {
|
||||
List<?> r = jpaRepository.findAll();
|
||||
return r.stream().map(o -> new DbObject(o, this)).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DbObjectSchema [fields=" + fields + ", className=" + entityClass.getName() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(tableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
DbObjectSchema other = (DbObjectSchema) obj;
|
||||
return Objects.equals(tableName, other.tableName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,20 +2,22 @@ package tech.ailef.dbadmin.external.dto;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbField;
|
||||
|
||||
public class QueryFilter {
|
||||
private String field;
|
||||
private DbField field;
|
||||
|
||||
private CompareOperator op;
|
||||
|
||||
private String value;
|
||||
|
||||
public QueryFilter(String field, CompareOperator op, String value) {
|
||||
public QueryFilter(DbField field, CompareOperator op, String value) {
|
||||
this.field = field;
|
||||
this.op = op;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
public DbField getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
@@ -27,20 +29,28 @@ public class QueryFilter {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (value != null && !value.toString().isBlank()) {
|
||||
String displayValue = value;
|
||||
if (value.length() > 10) {
|
||||
displayValue = value.substring(0, 4) + "..." + value.substring(value.length() - 4);
|
||||
}
|
||||
return "'" + field.getName() + "' " + op.getDisplayName() + " '" + displayValue + "'";
|
||||
} else {
|
||||
if (op != CompareOperator.STRING_EQ && op != CompareOperator.EQ) {
|
||||
return "'" + field.getName() + "' " + op.getDisplayName() + " NULL";
|
||||
} else {
|
||||
return "'" + field.getName() + "' IS NULL";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(field, op, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String displayValue = value;
|
||||
if (value.length() > 10) {
|
||||
displayValue = value.substring(0, 4) + "..." + value.substring(value.length() - 4);
|
||||
}
|
||||
return "'" + field + "' " + op.getDisplayName() + " '" + displayValue + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
@@ -50,8 +60,8 @@ public class QueryFilter {
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
QueryFilter other = (QueryFilter) obj;
|
||||
return Objects.equals(field, other.field) && Objects.equals(op, other.op) && Objects.equals(value, other.value);
|
||||
return Objects.equals(field, other.field) && op == other.op && Objects.equals(value, other.value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Set;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.external.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.external.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
@@ -32,7 +33,7 @@ public interface Utils {
|
||||
r.put("filter_value", new ArrayList<>());
|
||||
|
||||
for (QueryFilter filter : filters) {
|
||||
r.get("filter_field").add(filter.getField());
|
||||
r.get("filter_field").add(filter.getField().getJavaName());
|
||||
r.get("filter_op").add(filter.getOp().toString());
|
||||
r.get("filter_value").add(filter.getValue());
|
||||
}
|
||||
@@ -40,7 +41,7 @@ public interface Utils {
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Set<QueryFilter> computeFilters(MultiValueMap<String, String> params) {
|
||||
public static Set<QueryFilter> computeFilters(DbObjectSchema schema, MultiValueMap<String, String> params) {
|
||||
if (params == null)
|
||||
return new HashSet<>();
|
||||
|
||||
@@ -62,7 +63,7 @@ public interface Utils {
|
||||
String field = fields.get(i);
|
||||
String value = values.get(i);
|
||||
|
||||
QueryFilter queryFilter = new QueryFilter(field, CompareOperator.valueOf(op.toUpperCase()), value);
|
||||
QueryFilter queryFilter = new QueryFilter(schema.getFieldByJavaName(field), CompareOperator.valueOf(op.toUpperCase()), value);
|
||||
filters.add(queryFilter);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user