mirror of
https://github.com/dalbodeule/snap-admin.git
synced 2025-12-16 21:31:59 +09:00
0.1.0
This commit is contained in:
@@ -1,14 +0,0 @@
|
||||
package tech.ailef.dbadmin;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@ConditionalOnProperty(name = "dbadmin.enabled", matchIfMissing = true)
|
||||
@ComponentScan
|
||||
@EnableConfigurationProperties(DbAdminProperties.class)
|
||||
@AutoConfiguration
|
||||
public class DbAdminAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
//package tech.ailef.dbadmin.dto;
|
||||
//
|
||||
//import java.util.Set;
|
||||
//
|
||||
//public class ListModelRequest {
|
||||
// private String className;
|
||||
//
|
||||
// private String query;
|
||||
//
|
||||
// private Integer page;
|
||||
//
|
||||
// private Integer pageSize;
|
||||
//
|
||||
// private String sortKey;
|
||||
//
|
||||
// private String sortOrder;
|
||||
//
|
||||
// private Set<QueryFilter> queryFilters;
|
||||
//
|
||||
// private PaginationInfo paginationInfo;
|
||||
//
|
||||
// public ListModelRequest(String className, String query, Integer page, Integer pageSize, String sortKey,
|
||||
// String sortOrder, Set<QueryFilter> queryFilters, PaginationInfo paginationInfo) {
|
||||
// super();
|
||||
// this.className = className;
|
||||
// this.query = query;
|
||||
// this.page = page;
|
||||
// this.pageSize = pageSize;
|
||||
// this.sortKey = sortKey;
|
||||
// this.sortOrder = sortOrder;
|
||||
// this.queryFilters = queryFilters;
|
||||
// this.paginationInfo = paginationInfo;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// @RequestParam MultiValueMap<String, String> otherParams,
|
||||
//}
|
||||
@@ -1,30 +0,0 @@
|
||||
package tech.ailef.dbadmin.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import tech.ailef.dbadmin.dbmapping.DbObject;
|
||||
|
||||
public class PaginatedResult {
|
||||
private PaginationInfo pagination;
|
||||
|
||||
private List<DbObject> results;
|
||||
|
||||
public PaginatedResult(PaginationInfo pagination, List<DbObject> page) {
|
||||
this.pagination = pagination;
|
||||
this.results = page;
|
||||
}
|
||||
|
||||
public PaginationInfo getPagination() {
|
||||
return pagination;
|
||||
}
|
||||
|
||||
public List<DbObject> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
public int getActualResults() {
|
||||
return getResults().size();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin;
|
||||
package tech.ailef.dbadmin.external;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -10,9 +10,7 @@ import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -26,14 +24,13 @@ import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import tech.ailef.dbadmin.annotations.DisplayFormat;
|
||||
import tech.ailef.dbadmin.dbmapping.AdvancedJpaRepository;
|
||||
import tech.ailef.dbadmin.dbmapping.DbField;
|
||||
import tech.ailef.dbadmin.dbmapping.DbFieldType;
|
||||
import tech.ailef.dbadmin.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.misc.Utils;
|
||||
import tech.ailef.dbadmin.external.annotations.DisplayFormat;
|
||||
import tech.ailef.dbadmin.external.dbmapping.AdvancedJpaRepository;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbField;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbFieldType;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.external.misc.Utils;
|
||||
|
||||
/**
|
||||
* The main DbAdmin class responsible for the initialization phase. This class scans
|
||||
@@ -48,7 +45,7 @@ import tech.ailef.dbadmin.misc.Utils;
|
||||
public class DbAdmin {
|
||||
private static final Logger logger = Logger.getLogger(DbAdmin.class.getName());
|
||||
|
||||
@PersistenceContext
|
||||
// @PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
private List<DbObjectSchema> schemas = new ArrayList<>();
|
||||
@@ -91,6 +88,18 @@ public class DbAdmin {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a schema by its table name
|
||||
* @param tableName the table name on the database
|
||||
* @return
|
||||
* @throws DbAdminException if corresponding schema not found
|
||||
*/
|
||||
public DbObjectSchema findSchemaByTableName(String tableName) {
|
||||
return schemas.stream().filter(s -> s.getTableName().equals(tableName)).findFirst().orElseThrow(() -> {
|
||||
return new DbAdminException("Schema " + tableName + " not found.");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a schema by its class
|
||||
* @param klass
|
||||
76
src/main/java/tech/ailef/dbadmin/external/DbAdminAutoConfiguration.java
vendored
Normal file
76
src/main/java/tech/ailef/dbadmin/external/DbAdminAutoConfiguration.java
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
package tech.ailef.dbadmin.external;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import tech.ailef.dbadmin.internal.InternalDbAdminConfiguration;
|
||||
|
||||
@ConditionalOnProperty(name = "dbadmin.enabled", matchIfMissing = true)
|
||||
@ComponentScan
|
||||
@EnableConfigurationProperties(DbAdminProperties.class)
|
||||
@Configuration
|
||||
@EnableJpaRepositories(
|
||||
entityManagerFactoryRef = "internalEntityManagerFactory",
|
||||
transactionManagerRef = "internalTransactionManager",
|
||||
basePackages = { "tech.ailef.dbadmin.internal.repository" }
|
||||
)
|
||||
@EnableTransactionManagement
|
||||
@Import(InternalDbAdminConfiguration.class)
|
||||
public class DbAdminAutoConfiguration {
|
||||
@Autowired
|
||||
private DbAdminProperties props;
|
||||
|
||||
@Bean
|
||||
public DataSource internalDataSource() {
|
||||
DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
|
||||
dataSourceBuilder.driverClassName("org.h2.Driver");
|
||||
if (props.isTestMode()) {
|
||||
dataSourceBuilder.url("jdbc:h2:mem:test");
|
||||
} else {
|
||||
dataSourceBuilder.url("jdbc:h2:file:./dbadmin_internal");
|
||||
}
|
||||
|
||||
dataSourceBuilder.username("sa");
|
||||
dataSourceBuilder.password("password");
|
||||
return dataSourceBuilder.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory() {
|
||||
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
|
||||
factoryBean.setDataSource(internalDataSource());
|
||||
factoryBean.setPersistenceUnitName("internal");
|
||||
factoryBean.setPackagesToScan("tech.ailef.dbadmin.internal.model"); // , "tech.ailef.dbadmin.repository");
|
||||
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
|
||||
properties.setProperty("hibernate.hbm2ddl.auto", "update");
|
||||
factoryBean.setJpaProperties(properties);
|
||||
factoryBean.afterPropertiesSet();
|
||||
return factoryBean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager internalTransactionManager() {
|
||||
JpaTransactionManager transactionManager = new JpaTransactionManager();
|
||||
transactionManager.setEntityManagerFactory(internalEntityManagerFactory().getObject());
|
||||
return transactionManager;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin;
|
||||
package tech.ailef.dbadmin.external;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -26,6 +26,8 @@ public class DbAdminProperties {
|
||||
*/
|
||||
private String modelsPackage;
|
||||
|
||||
private boolean testMode = false;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
@@ -50,11 +52,20 @@ public class DbAdminProperties {
|
||||
this.modelsPackage = modelsPackage;
|
||||
}
|
||||
|
||||
public boolean isTestMode() {
|
||||
return testMode;
|
||||
}
|
||||
|
||||
public void setTestMode(boolean testMode) {
|
||||
this.testMode = testMode;
|
||||
}
|
||||
|
||||
public Map<String, String> toMap() {
|
||||
Map<String, String> conf = new HashMap<>();
|
||||
conf.put("enabled", enabled + "");
|
||||
conf.put("baseUrl", baseUrl);
|
||||
conf.put("modelsPackage", modelsPackage);
|
||||
conf.put("testMode", testMode + "");
|
||||
return conf;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.annotations;
|
||||
package tech.ailef.dbadmin.external.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.annotations;
|
||||
package tech.ailef.dbadmin.external.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.annotations;
|
||||
package tech.ailef.dbadmin.external.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.annotations;
|
||||
package tech.ailef.dbadmin.external.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.annotations;
|
||||
package tech.ailef.dbadmin.external.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.controller;
|
||||
package tech.ailef.dbadmin.external.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -19,6 +19,7 @@ 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;
|
||||
@@ -27,16 +28,21 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import tech.ailef.dbadmin.DbAdmin;
|
||||
import tech.ailef.dbadmin.DbAdminProperties;
|
||||
import tech.ailef.dbadmin.dbmapping.DbAdminRepository;
|
||||
import tech.ailef.dbadmin.dbmapping.DbObject;
|
||||
import tech.ailef.dbadmin.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.dto.PaginatedResult;
|
||||
import tech.ailef.dbadmin.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.exceptions.InvalidPageException;
|
||||
import tech.ailef.dbadmin.misc.Utils;
|
||||
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.DbObject;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.external.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.external.dto.LogsSearchRequest;
|
||||
import tech.ailef.dbadmin.external.dto.PaginatedResult;
|
||||
import tech.ailef.dbadmin.external.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.external.exceptions.InvalidPageException;
|
||||
import tech.ailef.dbadmin.external.misc.Utils;
|
||||
import tech.ailef.dbadmin.internal.model.UserAction;
|
||||
import tech.ailef.dbadmin.internal.model.UserSetting;
|
||||
import tech.ailef.dbadmin.internal.repository.UserSettingsRepository;
|
||||
import tech.ailef.dbadmin.internal.service.UserActionService;
|
||||
|
||||
/**
|
||||
* The main DbAdmin controller that register most of the routes of the web interface.
|
||||
@@ -52,7 +58,14 @@ public class DefaultDbAdminController {
|
||||
|
||||
@Autowired
|
||||
private DbAdmin dbAdmin;
|
||||
|
||||
@Autowired
|
||||
private UserActionService userActionService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserSettingsRepository userSettingsRepo;
|
||||
|
||||
/**
|
||||
* Home page with list of schemas
|
||||
* @param model
|
||||
@@ -61,6 +74,7 @@ public class DefaultDbAdminController {
|
||||
*/
|
||||
@GetMapping
|
||||
public String index(Model model, @RequestParam(required = false) String query) {
|
||||
|
||||
List<DbObjectSchema> schemas = dbAdmin.getSchemas();
|
||||
if (query != null && !query.isBlank()) {
|
||||
schemas = schemas.stream().filter(s -> {
|
||||
@@ -149,7 +163,7 @@ public class DefaultDbAdminController {
|
||||
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
||||
|
||||
try {
|
||||
PaginatedResult result = null;
|
||||
PaginatedResult<DbObject> result = null;
|
||||
if (query != null || !otherParams.isEmpty()) {
|
||||
result = repository.search(schema, query, page, pageSize, sortKey, sortOrder, queryFilters);
|
||||
} else {
|
||||
@@ -264,6 +278,8 @@ public class DefaultDbAdminController {
|
||||
attr.addFlashAttribute("error", e.getMessage());
|
||||
}
|
||||
|
||||
saveAction(new UserAction(schema.getTableName(), id, "DELETE"));
|
||||
|
||||
return "redirect:/" + properties.getBaseUrl() + "/model/" + className;
|
||||
}
|
||||
|
||||
@@ -291,6 +307,10 @@ public class DefaultDbAdminController {
|
||||
if (countDeleted > 0)
|
||||
attr.addFlashAttribute("message", "Deleted " + countDeleted + " of " + ids.length + " items");
|
||||
|
||||
for (String id : ids) {
|
||||
saveAction(new UserAction(schema.getTableName(), id, "DELETE"));
|
||||
}
|
||||
|
||||
return "redirect:/" + properties.getBaseUrl() + "/model/" + className;
|
||||
}
|
||||
|
||||
@@ -353,6 +373,7 @@ public class DefaultDbAdminController {
|
||||
repository.attachManyToMany(schema, newPrimaryKey, multiValuedParams);
|
||||
pkValue = newPrimaryKey.toString();
|
||||
attr.addFlashAttribute("message", "Item created successfully.");
|
||||
saveAction(new UserAction(schema.getTableName(), pkValue, "CREATE"));
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
attr.addFlashAttribute("errorTitle", "Unable to INSERT row");
|
||||
attr.addFlashAttribute("error", e.getMessage());
|
||||
@@ -376,6 +397,7 @@ public class DefaultDbAdminController {
|
||||
repository.update(schema, params, files);
|
||||
repository.attachManyToMany(schema, pkValue, multiValuedParams);
|
||||
attr.addFlashAttribute("message", "Item saved successfully.");
|
||||
saveAction(new UserAction(schema.getTableName(), pkValue, "EDIT"));
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
attr.addFlashAttribute("errorTitle", "Unable to UPDATE row (no changes applied)");
|
||||
attr.addFlashAttribute("error", e.getMessage());
|
||||
@@ -391,6 +413,7 @@ public class DefaultDbAdminController {
|
||||
Object newPrimaryKey = repository.create(schema, params, files, pkValue);
|
||||
repository.attachManyToMany(schema, newPrimaryKey, multiValuedParams);
|
||||
attr.addFlashAttribute("message", "Item created successfully");
|
||||
saveAction(new UserAction(schema.getTableName(), pkValue, "CREATE"));
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
attr.addFlashAttribute("errorTitle", "Unable to INSERT row (no changes applied)");
|
||||
attr.addFlashAttribute("error", e.getMessage());
|
||||
@@ -409,6 +432,23 @@ public class DefaultDbAdminController {
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/logs")
|
||||
public String logs(Model model, LogsSearchRequest searchRequest) {
|
||||
model.addAttribute("activePage", "logs");
|
||||
model.addAttribute(
|
||||
"page",
|
||||
userActionService.findActions(
|
||||
searchRequest.getTable(),
|
||||
searchRequest.getActionType(),
|
||||
searchRequest.getItemId(),
|
||||
searchRequest.toPageRequest()
|
||||
)
|
||||
);
|
||||
model.addAttribute("schemas", dbAdmin.getSchemas());
|
||||
model.addAttribute("searchRequest", searchRequest);
|
||||
return "logs";
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/settings")
|
||||
public String settings(Model model) {
|
||||
@@ -416,5 +456,16 @@ public class DefaultDbAdminController {
|
||||
return "settings";
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/settings")
|
||||
public String settings(@RequestParam Map<String, String> params, Model model) {
|
||||
for (String paramName : params.keySet()) {
|
||||
userSettingsRepo.save(new UserSetting(paramName, params.get(paramName)));
|
||||
}
|
||||
model.addAttribute("activePage", "settings");
|
||||
return "settings";
|
||||
}
|
||||
|
||||
private UserAction saveAction(UserAction action) {
|
||||
return userActionService.save(action);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.controller;
|
||||
package tech.ailef.dbadmin.external.controller;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -17,12 +17,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import tech.ailef.dbadmin.DbAdmin;
|
||||
import tech.ailef.dbadmin.dbmapping.DbAdminRepository;
|
||||
import tech.ailef.dbadmin.dbmapping.DbFieldValue;
|
||||
import tech.ailef.dbadmin.dbmapping.DbObject;
|
||||
import tech.ailef.dbadmin.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.external.DbAdmin;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbAdminRepository;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbFieldValue;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObject;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
|
||||
/**
|
||||
* Controller to serve file or images (`@DisplayImage`)
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.controller;
|
||||
package tech.ailef.dbadmin.external.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -7,7 +7,8 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import tech.ailef.dbadmin.DbAdminProperties;
|
||||
import tech.ailef.dbadmin.external.DbAdminProperties;
|
||||
import tech.ailef.dbadmin.internal.UserConfiguration;
|
||||
|
||||
/**
|
||||
* This class registers some ModelAttribute objects that are
|
||||
@@ -18,6 +19,9 @@ public class GlobalController {
|
||||
|
||||
@Autowired
|
||||
private DbAdminProperties props;
|
||||
|
||||
@Autowired
|
||||
private UserConfiguration userConf;
|
||||
|
||||
/**
|
||||
* A multi valued map containing the query parameters. It is used primarily
|
||||
@@ -36,7 +40,18 @@ public class GlobalController {
|
||||
* @return
|
||||
*/
|
||||
@ModelAttribute("baseUrl")
|
||||
public String getBaseUrl(HttpServletRequest request) {
|
||||
public String getBaseUrl() {
|
||||
return props.getBaseUrl();
|
||||
}
|
||||
}
|
||||
|
||||
@ModelAttribute("requestUrl")
|
||||
public String getRequestUrl(HttpServletRequest request) {
|
||||
return request.getRequestURI();
|
||||
}
|
||||
|
||||
@ModelAttribute("userConf")
|
||||
public UserConfiguration getUserConf() {
|
||||
return userConf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.controller.rest;
|
||||
package tech.ailef.dbadmin.external.controller.rest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -11,10 +11,10 @@ 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.DbAdmin;
|
||||
import tech.ailef.dbadmin.dbmapping.DbAdminRepository;
|
||||
import tech.ailef.dbadmin.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.dto.AutocompleteSearchResult;
|
||||
import tech.ailef.dbadmin.external.DbAdmin;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbAdminRepository;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.external.dto.AutocompleteSearchResult;
|
||||
|
||||
/**
|
||||
* API controller for autocomplete results
|
||||
@@ -1,8 +1,6 @@
|
||||
package tech.ailef.dbadmin.controller.rest;
|
||||
package tech.ailef.dbadmin.external.controller.rest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -14,12 +12,12 @@ 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.DbAdmin;
|
||||
import tech.ailef.dbadmin.DbAdminProperties;
|
||||
import tech.ailef.dbadmin.dbmapping.DbAdminRepository;
|
||||
import tech.ailef.dbadmin.dbmapping.DbObjectSchema;
|
||||
import tech.ailef.dbadmin.dto.PaginatedResult;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
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/"})
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dbmapping;
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
@@ -21,9 +21,9 @@ import jakarta.persistence.criteria.CriteriaUpdate;
|
||||
import jakarta.persistence.criteria.Path;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import tech.ailef.dbadmin.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.external.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.external.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class AdvancedJpaRepository extends SimpleJpaRepository {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dbmapping;
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -18,14 +18,14 @@ import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import tech.ailef.dbadmin.dto.PaginatedResult;
|
||||
import tech.ailef.dbadmin.dto.PaginationInfo;
|
||||
import tech.ailef.dbadmin.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.exceptions.InvalidPageException;
|
||||
import tech.ailef.dbadmin.external.dto.PaginatedResult;
|
||||
import tech.ailef.dbadmin.external.dto.PaginationInfo;
|
||||
import tech.ailef.dbadmin.external.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.external.exceptions.InvalidPageException;
|
||||
|
||||
/**
|
||||
* Implements the basic CRUD operations (and some more)
|
||||
@@ -117,7 +117,7 @@ public class DbAdminRepository {
|
||||
}
|
||||
|
||||
|
||||
return new PaginatedResult(
|
||||
return new PaginatedResult<DbObject>(
|
||||
new PaginationInfo(page, maxPage, pageSize, maxElement, null, new HashSet<>()),
|
||||
results
|
||||
);
|
||||
@@ -128,18 +128,18 @@ public class DbAdminRepository {
|
||||
* @param schema
|
||||
* @param params
|
||||
*/
|
||||
@Transactional
|
||||
@Transactional("transactionManager")
|
||||
public void update(DbObjectSchema schema, Map<String, String> params, Map<String, MultipartFile> files) {
|
||||
schema.getJpaRepository().update(schema, params, files);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Transactional
|
||||
@Transactional("transactionManager")
|
||||
private void save(DbObjectSchema schema, DbObject o) {
|
||||
schema.getJpaRepository().save(o.getUnderlyingInstance());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Transactional("transactionManager")
|
||||
public void attachManyToMany(DbObjectSchema schema, Object id, Map<String, List<String>> params) {
|
||||
Optional<DbObject> optional = findById(schema, id);
|
||||
|
||||
@@ -215,7 +215,7 @@ public class DbAdminRepository {
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
public PaginatedResult search(DbObjectSchema schema, String query, int page, int pageSize, String sortKey,
|
||||
public PaginatedResult<DbObject> search(DbObjectSchema schema, String query, int page, int pageSize, String sortKey,
|
||||
String sortOrder, Set<QueryFilter> queryFilters) {
|
||||
AdvancedJpaRepository jpaRepository = schema.getJpaRepository();
|
||||
|
||||
@@ -227,7 +227,7 @@ public class DbAdminRepository {
|
||||
throw new InvalidPageException();
|
||||
}
|
||||
|
||||
return new PaginatedResult(
|
||||
return new PaginatedResult<DbObject>(
|
||||
new PaginationInfo(page, maxPage, pageSize, maxElement, query, queryFilters),
|
||||
jpaRepository.search(query, page, pageSize, sortKey, sortOrder, queryFilters).stream()
|
||||
.map(o -> new DbObject(o, schema))
|
||||
@@ -256,7 +256,7 @@ public class DbAdminRepository {
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Transactional
|
||||
@Transactional("transactionManager")
|
||||
public void delete(DbObjectSchema schema, String id) {
|
||||
schema.getJpaRepository().deleteById(id);
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package tech.ailef.dbadmin.dbmapping;
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import tech.ailef.dbadmin.annotations.DisplayImage;
|
||||
import tech.ailef.dbadmin.external.annotations.DisplayImage;
|
||||
|
||||
public class DbField {
|
||||
protected String dbName;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dbmapping;
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
@@ -11,8 +11,8 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import tech.ailef.dbadmin.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.external.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
|
||||
public enum DbFieldType {
|
||||
INTEGER {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dbmapping;
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dbmapping;
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -11,9 +11,9 @@ import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import tech.ailef.dbadmin.annotations.DisplayName;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.misc.Utils;
|
||||
import tech.ailef.dbadmin.external.annotations.DisplayName;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.external.misc.Utils;
|
||||
|
||||
public class DbObject {
|
||||
private Object instance;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dbmapping;
|
||||
package tech.ailef.dbadmin.external.dbmapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
@@ -16,11 +16,11 @@ import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import tech.ailef.dbadmin.DbAdmin;
|
||||
import tech.ailef.dbadmin.annotations.ComputedColumn;
|
||||
import tech.ailef.dbadmin.annotations.Filterable;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.misc.Utils;
|
||||
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;
|
||||
|
||||
public class DbObjectSchema {
|
||||
/**
|
||||
@@ -1,6 +1,6 @@
|
||||
package tech.ailef.dbadmin.dto;
|
||||
package tech.ailef.dbadmin.external.dto;
|
||||
|
||||
import tech.ailef.dbadmin.dbmapping.DbObject;
|
||||
import tech.ailef.dbadmin.external.dbmapping.DbObject;
|
||||
|
||||
public class AutocompleteSearchResult {
|
||||
private Object id;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dto;
|
||||
package tech.ailef.dbadmin.external.dto;
|
||||
|
||||
public enum CompareOperator {
|
||||
GT {
|
||||
98
src/main/java/tech/ailef/dbadmin/external/dto/LogsSearchRequest.java
vendored
Normal file
98
src/main/java/tech/ailef/dbadmin/external/dto/LogsSearchRequest.java
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
package tech.ailef.dbadmin.external.dto;
|
||||
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
public class LogsSearchRequest {
|
||||
private String table;
|
||||
|
||||
private String actionType;
|
||||
|
||||
private String itemId;
|
||||
|
||||
private int page;
|
||||
|
||||
private int pageSize;
|
||||
|
||||
private String sortKey;
|
||||
|
||||
private String sortOrder;
|
||||
|
||||
public String getTable() {
|
||||
return table == null || table.isBlank() || table.equalsIgnoreCase("Any") ? null : table;
|
||||
}
|
||||
|
||||
public void setTable(String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public String getActionType() {
|
||||
return actionType == null || actionType.isBlank() || actionType.equalsIgnoreCase("Any") ? null : actionType;
|
||||
}
|
||||
|
||||
public void setActionType(String actionType) {
|
||||
this.actionType = actionType;
|
||||
}
|
||||
|
||||
public String getItemId() {
|
||||
return itemId == null || itemId.isBlank() ? null : itemId;
|
||||
}
|
||||
|
||||
public void setItemId(String itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setPageSize(int pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
public String getSortKey() {
|
||||
return sortKey;
|
||||
}
|
||||
|
||||
public void setSortKey(String sortKey) {
|
||||
this.sortKey = sortKey;
|
||||
}
|
||||
|
||||
public String getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public void setSortOrder(String sortOrder) {
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LogsSearchRequest [table=" + table + ", actionType=" + actionType + ", itemId=" + itemId + ", page="
|
||||
+ page + ", pageSize=" + pageSize + ", sortKey=" + sortKey + ", sortOrder=" + sortOrder + "]";
|
||||
}
|
||||
|
||||
public PageRequest toPageRequest() {
|
||||
int actualPage = page - 1 < 0 ? 0 : page - 1;
|
||||
int actualPageSize = pageSize <= 0 ? 50 : pageSize;
|
||||
if (sortKey == null)
|
||||
return PageRequest.of(actualPage, actualPageSize);
|
||||
|
||||
if (sortOrder == null) sortOrder = "ASC";
|
||||
|
||||
if (sortOrder.equals("DESC")) {
|
||||
return PageRequest.of(actualPage, actualPageSize, Sort.by(sortKey).descending());
|
||||
} else {
|
||||
return PageRequest.of(actualPage, actualPageSize, Sort.by(sortKey).ascending());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
32
src/main/java/tech/ailef/dbadmin/external/dto/PaginatedResult.java
vendored
Normal file
32
src/main/java/tech/ailef/dbadmin/external/dto/PaginatedResult.java
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
package tech.ailef.dbadmin.external.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PaginatedResult<T> {
|
||||
private PaginationInfo pagination;
|
||||
|
||||
private List<T> results;
|
||||
|
||||
public PaginatedResult(PaginationInfo pagination, List<T> page) {
|
||||
this.pagination = pagination;
|
||||
this.results = page;
|
||||
}
|
||||
|
||||
public PaginationInfo getPagination() {
|
||||
return pagination;
|
||||
}
|
||||
|
||||
public List<T> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return results.isEmpty();
|
||||
}
|
||||
|
||||
public int getNumberOfResults() {
|
||||
return getResults().size();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dto;
|
||||
package tech.ailef.dbadmin.external.dto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -8,7 +8,7 @@ import java.util.stream.IntStream;
|
||||
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import tech.ailef.dbadmin.misc.Utils;
|
||||
import tech.ailef.dbadmin.external.misc.Utils;
|
||||
|
||||
/**
|
||||
* Attached as output to requests that have a paginated response,
|
||||
@@ -35,6 +35,7 @@ public class PaginationInfo {
|
||||
*/
|
||||
private int pageSize;
|
||||
|
||||
// TODO: Check if used
|
||||
private long maxElement;
|
||||
|
||||
private Set<QueryFilter> queryFilters;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.dto;
|
||||
package tech.ailef.dbadmin.external.dto;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.exceptions;
|
||||
package tech.ailef.dbadmin.external.exceptions;
|
||||
|
||||
public class DbAdminException extends RuntimeException {
|
||||
private static final long serialVersionUID = 8120227031645804467L;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.exceptions;
|
||||
package tech.ailef.dbadmin.external.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown during the computation of pagination if the requested
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.ailef.dbadmin.misc;
|
||||
package tech.ailef.dbadmin.external.misc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -8,9 +8,9 @@ import java.util.Set;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import tech.ailef.dbadmin.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.external.dto.CompareOperator;
|
||||
import tech.ailef.dbadmin.external.dto.QueryFilter;
|
||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||
|
||||
public interface Utils {
|
||||
public static String camelToSnake(String v) {
|
||||
@@ -24,6 +24,8 @@ public interface Utils {
|
||||
|
||||
public static MultiValueMap<String, String> computeParams(Set<QueryFilter> filters) {
|
||||
MultiValueMap<String, String> r = new LinkedMultiValueMap<>();
|
||||
if (filters == null)
|
||||
return r;
|
||||
|
||||
r.put("filter_field", new ArrayList<>());
|
||||
r.put("filter_op", new ArrayList<>());
|
||||
@@ -0,0 +1,12 @@
|
||||
package tech.ailef.dbadmin.internal;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@ConditionalOnProperty(name = "dbadmin.enabled", matchIfMissing = true)
|
||||
@ComponentScan
|
||||
@Configuration
|
||||
public class InternalDbAdminConfiguration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package tech.ailef.dbadmin.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import tech.ailef.dbadmin.internal.model.UserSetting;
|
||||
import tech.ailef.dbadmin.internal.repository.UserSettingsRepository;
|
||||
|
||||
@Component
|
||||
public class UserConfiguration {
|
||||
@Autowired
|
||||
private UserSettingsRepository repo;
|
||||
|
||||
public String get(String settingName) {
|
||||
Optional<UserSetting> setting = repo.findById(settingName);
|
||||
if (setting.isPresent())
|
||||
return setting.get().getSettingValue();
|
||||
return defaultValues().get(settingName);
|
||||
}
|
||||
|
||||
private Map<String, String> defaultValues() {
|
||||
Map<String, String> values = new HashMap<>();
|
||||
values.put("brandName", "Spring Boot Database Admin");
|
||||
return values;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package tech.ailef.dbadmin.internal.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.format.datetime.standard.DateTimeFormatterFactory;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
|
||||
@Entity
|
||||
public class UserAction {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Lob
|
||||
@Column(nullable = false)
|
||||
private String sql;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String onTable;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String primaryKey;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String actionType;
|
||||
|
||||
public UserAction() {
|
||||
}
|
||||
|
||||
public UserAction(String onTable, String primaryKey, String actionType) {
|
||||
this.createdAt = LocalDateTime.now();
|
||||
this.sql = "SQL TODO";
|
||||
this.onTable = onTable;
|
||||
this.actionType = actionType;
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public void setSql(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public String getOnTable() {
|
||||
return onTable;
|
||||
}
|
||||
|
||||
public void setOnTable(String onTable) {
|
||||
this.onTable = onTable;
|
||||
}
|
||||
|
||||
public String getPrimaryKey() {
|
||||
return primaryKey;
|
||||
}
|
||||
|
||||
public void setPrimaryKey(String primaryKey) {
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
public String getActionType() {
|
||||
return actionType;
|
||||
}
|
||||
|
||||
public void setActionType(String actionType) {
|
||||
this.actionType = actionType;
|
||||
}
|
||||
|
||||
public String getFormattedDate() {
|
||||
return new DateTimeFormatterFactory("YYYY-MM-dd HH:mm:ss").createDateTimeFormatter().format(createdAt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package tech.ailef.dbadmin.internal.model;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class UserSetting {
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String settingValue;
|
||||
|
||||
public UserSetting() {
|
||||
}
|
||||
|
||||
public UserSetting(String id, String settingValue) {
|
||||
this.id = id;
|
||||
this.settingValue = settingValue;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSettingValue() {
|
||||
return settingValue;
|
||||
}
|
||||
|
||||
public void setSettingValue(String settingValue) {
|
||||
this.settingValue = settingValue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package tech.ailef.dbadmin.internal.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import tech.ailef.dbadmin.internal.model.UserAction;
|
||||
|
||||
public interface CustomActionRepository {
|
||||
public List<UserAction> findActions(String table, String actionType, String itemId, PageRequest pageRequest);
|
||||
|
||||
public long countActions(String table, String actionType, String itemId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package tech.ailef.dbadmin.internal.repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import tech.ailef.dbadmin.internal.model.UserAction;
|
||||
|
||||
@Component
|
||||
public class CustomActionRepositoryImpl implements CustomActionRepository {
|
||||
|
||||
@PersistenceContext(unitName = "internal")
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Override
|
||||
public List<UserAction> findActions(String table, String actionType, String itemId, PageRequest page) {
|
||||
|
||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<UserAction> query = cb.createQuery(UserAction.class);
|
||||
Root<UserAction> userAction = query.from(UserAction.class);
|
||||
|
||||
List<Predicate> predicates = new ArrayList<Predicate>();
|
||||
if (table != null)
|
||||
predicates.add(cb.equal(userAction.get("onTable"), table));
|
||||
if (actionType != null)
|
||||
predicates.add(cb.equal(userAction.get("actionType"), actionType));
|
||||
if (itemId != null)
|
||||
predicates.add(cb.equal(userAction.get("primaryKey"), itemId));
|
||||
|
||||
if (!predicates.isEmpty()) {
|
||||
query.select(userAction)
|
||||
.where(cb.and(
|
||||
predicates.toArray(new Predicate[predicates.size()])));
|
||||
}
|
||||
|
||||
return entityManager.createQuery(query)
|
||||
.setMaxResults(page.getPageSize())
|
||||
.setFirstResult((int)page.getOffset())
|
||||
.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countActions(String table, String actionType, String itemId) {
|
||||
|
||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> query = cb.createQuery(Long.class);
|
||||
Root<UserAction> userAction = query.from(UserAction.class);
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (table != null)
|
||||
predicates.add(cb.equal(userAction.get("onTable"), table));
|
||||
if (actionType != null)
|
||||
predicates.add(cb.equal(userAction.get("actionType"), actionType));
|
||||
if (itemId != null)
|
||||
predicates.add(cb.equal(userAction.get("primaryKey"), itemId));
|
||||
|
||||
if (!predicates.isEmpty()) {
|
||||
query.select(cb.count(userAction))
|
||||
.where(cb.and(
|
||||
predicates.toArray(new Predicate[predicates.size()])));
|
||||
} else {
|
||||
query.select(cb.count(userAction));
|
||||
}
|
||||
|
||||
return entityManager.createQuery(query).getSingleResult();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package tech.ailef.dbadmin.internal.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import tech.ailef.dbadmin.internal.model.UserAction;
|
||||
|
||||
@Repository
|
||||
public interface UserActionRepository extends JpaRepository<UserAction, Integer>, CustomActionRepository {
|
||||
public List<UserAction> findAllByOnTableAndActionTypeAndPrimaryKey(String table, String actionType, String primaryKey, PageRequest pageRequest);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package tech.ailef.dbadmin.internal.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import tech.ailef.dbadmin.internal.model.UserSetting;
|
||||
|
||||
@Repository
|
||||
public interface UserSettingsRepository extends JpaRepository<UserSetting, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package tech.ailef.dbadmin.internal.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import tech.ailef.dbadmin.external.dto.PaginatedResult;
|
||||
import tech.ailef.dbadmin.external.dto.PaginationInfo;
|
||||
import tech.ailef.dbadmin.internal.model.UserAction;
|
||||
import tech.ailef.dbadmin.internal.repository.CustomActionRepositoryImpl;
|
||||
import tech.ailef.dbadmin.internal.repository.UserActionRepository;
|
||||
|
||||
@Service
|
||||
public class UserActionService {
|
||||
@Autowired
|
||||
private UserActionRepository repo;
|
||||
|
||||
@Autowired
|
||||
private CustomActionRepositoryImpl customRepo;
|
||||
|
||||
@Transactional("internalTransactionManager")
|
||||
public UserAction save(UserAction a) {
|
||||
return repo.save(a);
|
||||
}
|
||||
|
||||
public PaginatedResult<UserAction> findActions(String table, String actionType, String userId, PageRequest page) {
|
||||
long count = customRepo.countActions(table, actionType, userId);
|
||||
List<UserAction> actions = customRepo.findActions(table, actionType, userId, page);
|
||||
int maxPage = (int)(Math.ceil ((double)count / page.getPageSize()));
|
||||
|
||||
return new PaginatedResult<>(
|
||||
new PaginationInfo(page.getPageNumber() + 1, maxPage, page.getPageSize(), count, null, null),
|
||||
actions
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user