This commit is contained in:
Francesco 2023-10-01 09:02:54 +02:00
parent c7258e9968
commit 5b027be0d1
10 changed files with 90 additions and 15 deletions

View File

@ -55,8 +55,8 @@ import tech.ailef.dbadmin.external.misc.Utils;
/**
* The main DbAdmin class responsible for the initialization phase. This class scans
* the user provided package containing the `@Entity` definitions and tries to map each
* entity to a DbObjectSchema instance.
* the user provided package containing the {@code Entity} definitions and tries to map each
* entity to a {@link DbObjectSchema} instance.
*
* This process involves determining the correct type for each class field and its
* configuration at the database level. An exception will be thrown if it's not possible

View File

@ -41,8 +41,10 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
import tech.ailef.dbadmin.internal.InternalDbAdminConfiguration;
/**
* The configuration class that adds and configures the "internal" data source.
*
* The configuration class for "internal" data source. This is not the
* source connected to the user's data/entities, but rather an internal
* H2 database which is used by Spring Boot Database Admin to store user
* settings and other information like operations history.
*/
@ConditionalOnProperty(name = "dbadmin.enabled", matchIfMissing = true)
@ComponentScan

View File

@ -49,9 +49,9 @@ public class AutocompleteController {
/**
* Returns a list of entities from a given table that match an input query.
* @param className
* @param query
* @return
* @param className full qualified class name; only search items for this entity
* @param query the query to search for
* @return a list of {@link AutocompleteSearchResult}
*/
@GetMapping("/{className}")
public ResponseEntity<?> autocomplete(@PathVariable String className, @RequestParam String query) {

View File

@ -46,25 +46,30 @@ public class LogsSearchRequest implements FilterRequest {
private String itemId;
/**
* The requested page
* The requested page number
*/
private int page;
/**
* The requested page size
* The requested number of elements per page
*/
private int pageSize;
/**
* The requested sort key
* The requested sort key, possibly null
*/
private String sortKey;
/**
* The requested sort order
* The requested sort order, possibly null
*/
private String sortOrder;
/**
* Returns the table specified in this search request. If the value is blank or 'Any',
* the method returns null in order ignore the field in subsequent queries.
* @return
*/
public String getTable() {
return table == null || table.isBlank() || table.equalsIgnoreCase("Any") ? null : table;
}
@ -73,6 +78,11 @@ public class LogsSearchRequest implements FilterRequest {
this.table = table;
}
/**
* Returns the actionType specified in this search request. If the value is blank or 'Any',
* the method returns null in order ignore the field in subsequent queries.
* @return
*/
public String getActionType() {
return actionType == null || actionType.isBlank() || actionType.equalsIgnoreCase("Any") ? null : actionType;
}
@ -81,6 +91,11 @@ public class LogsSearchRequest implements FilterRequest {
this.actionType = actionType;
}
/**
* Returns the itemId specified in this search request. If the value is blank or 'Any',
* the method returns null in order ignore the field in subsequent queries.
* @return
*/
public String getItemId() {
return itemId == null || itemId.isBlank() ? null : itemId;
}
@ -89,6 +104,10 @@ public class LogsSearchRequest implements FilterRequest {
this.itemId = itemId;
}
/**
* Returns the requested page number
* @return
*/
public int getPage() {
return page;
}
@ -97,6 +116,10 @@ public class LogsSearchRequest implements FilterRequest {
this.page = page;
}
/**
* Returns the requested number of elements per page
* @return
*/
public int getPageSize() {
return pageSize;
}
@ -105,6 +128,10 @@ public class LogsSearchRequest implements FilterRequest {
this.pageSize = pageSize;
}
/**
* Returns the requested sort key, possibly null
* @return
*/
public String getSortKey() {
return sortKey;
}
@ -113,6 +140,11 @@ public class LogsSearchRequest implements FilterRequest {
this.sortKey = sortKey;
}
/**
* Returns the requested sort order, possibly null
* @param sortOrder
*/
public String getSortOrder() {
return sortOrder;
}

View File

@ -23,6 +23,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* Configuration class for the "internal" data source. Place in the root "internal"
* package so as to allow component scanning and detection of models and repositories.
*/
@ConditionalOnProperty(name = "dbadmin.enabled", matchIfMissing = true)
@ComponentScan
@Configuration

View File

@ -31,8 +31,9 @@ import jakarta.persistence.Id;
import jakarta.persistence.Lob;
/**
* An action executed by any user from the web UI.
*
* An write operation executed by a user from the web UI. This class
* only holds metadata about the operation and not anything
* concrete yet (e.g. a diff or SQL query) about what change was performed.
*/
@Entity
public class UserAction {
@ -40,22 +41,39 @@ public class UserAction {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* The time at which the operation was perfomed
*/
@Column(nullable = false)
private LocalDateTime createdAt;
/**
* The SQL query generated by the operation.
* This field is here but it's NOT currently supported
*/
@Lob
@Column(nullable = false)
private String sql;
/**
* The full qualified name of the Entity class this operation
* occurred on.
*/
@Column(nullable = false)
private String javaClass;
/**
* The table name of the Entity class this operation occurred on.
*/
@Column(nullable = false)
private String onTable;
@Column(nullable = false)
private String primaryKey;
/**
* The action type (EDIT, CREATE or DELETE)
*/
@Column(nullable = false)
private String actionType;

View File

@ -23,7 +23,7 @@ import jakarta.persistence.Entity;
import jakarta.persistence.Id;
/**
* A single variable in the settings.
* A single variable in the user settings.
*/
@Entity
public class UserSetting {

View File

@ -0,0 +1,10 @@
/**
* This is the root package for the "internal" data source, i.e. not the data source
* that interacts with the user entities, but rather the one used internally by Spring
* Boot Database Admin in order to save information.
*
* Due to the way Spring Boot component scanning works, it is needed to create this package and the
* respective {@link tech.ailef.dbadmin.internal.InternalDbAdminConfiguration} in order to
* have the component scanning only pick the correct entities/repositories.
*/
package tech.ailef.dbadmin.internal;

View File

@ -92,7 +92,7 @@ public class CustomActionRepositoryImpl implements CustomActionRepository {
/**
* Returns the count that match the filtering parameters, used for pagination.
* @return
* @return the number of user actions matching the filtering parameters
*/
@Override
public long countActions(String table, String actionType, String itemId) {

View File

@ -33,6 +33,10 @@ import tech.ailef.dbadmin.internal.model.UserAction;
import tech.ailef.dbadmin.internal.repository.CustomActionRepositoryImpl;
import tech.ailef.dbadmin.internal.repository.UserActionRepository;
/**
* Service class to retrieve user actions through the {@link CustomActionRepositoryImpl}.
*
*/
@Service
public class UserActionService {
@Autowired
@ -46,6 +50,11 @@ public class UserActionService {
return repo.save(a);
}
/**
* Retruns a page of results of user actions that match the given input request.
* @param request a request containing filtering parameters for user actions
* @return a page of results matching the input request
*/
public PaginatedResult<UserAction> findActions(LogsSearchRequest request) {
String table = request.getTable();
String actionType = request.getActionType();