205 lines
5.1 KiB
Go
205 lines
5.1 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
|
|
"github.com/rogeecn/database_render/internal/config"
|
|
"github.com/rogeecn/database_render/internal/database"
|
|
"github.com/rogeecn/database_render/internal/model"
|
|
"github.com/rogeecn/database_render/internal/repository"
|
|
)
|
|
|
|
// DataService handles business logic for data operations
|
|
type DataService struct {
|
|
repo *repository.DataRepository
|
|
config *config.Config
|
|
logger *slog.Logger
|
|
}
|
|
|
|
// NewDataService creates a new data service
|
|
func NewDataService(repo *repository.DataRepository, cfg *config.Config) *DataService {
|
|
return &DataService{
|
|
repo: repo,
|
|
config: cfg,
|
|
logger: slog.With("component", "service"),
|
|
}
|
|
}
|
|
|
|
// GetTables returns all configured tables
|
|
func (s *DataService) GetTables() ([]model.TableInfo, error) {
|
|
tables, err := s.repo.GetTables()
|
|
if err != nil {
|
|
s.logger.Error("failed to get tables", "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Debug("retrieved tables", "count", len(tables))
|
|
return tables, nil
|
|
}
|
|
|
|
// GetTableData returns paginated data for a table
|
|
func (s *DataService) GetTableData(tableName string, page, pageSize int, search string, sortField string, sortOrder string) (*model.DataResponse, error) {
|
|
// Validate table exists
|
|
tableConfig, err := s.repo.GetTableConfig(tableName)
|
|
if err != nil {
|
|
s.logger.Error("failed to get table config", "table", tableName, "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
// Use configured page size if not provided
|
|
if pageSize <= 0 {
|
|
pageSize = tableConfig.PageSize
|
|
}
|
|
|
|
// Validate page and page size
|
|
if page <= 0 {
|
|
page = 1
|
|
}
|
|
if pageSize <= 0 {
|
|
pageSize = 10
|
|
}
|
|
if pageSize > 100 {
|
|
pageSize = 100 // Limit maximum page size
|
|
}
|
|
|
|
// Get data from repository
|
|
data, total, err := s.repo.GetTableData(tableName, page, pageSize, search, sortField, sortOrder)
|
|
if err != nil {
|
|
s.logger.Error("failed to get table data",
|
|
"table", tableName,
|
|
"page", page,
|
|
"pageSize", pageSize,
|
|
"search", search,
|
|
"error", err)
|
|
return nil, err
|
|
}
|
|
|
|
// Calculate total pages
|
|
totalPages := int((total + int64(pageSize) - 1) / int64(pageSize))
|
|
|
|
response := &model.DataResponse{
|
|
Data: data,
|
|
Total: total,
|
|
Page: page,
|
|
PerPage: pageSize,
|
|
Pages: totalPages,
|
|
Table: tableName,
|
|
Columns: tableConfig.Columns,
|
|
Filters: tableConfig.Filters,
|
|
}
|
|
|
|
s.logger.Info("retrieved table data",
|
|
"table", tableName,
|
|
"page", page,
|
|
"pageSize", pageSize,
|
|
"total", total,
|
|
"pages", totalPages)
|
|
|
|
return response, nil
|
|
}
|
|
|
|
// GetTableDetail returns a single record detail
|
|
func (s *DataService) GetTableDetail(tableName string, id interface{}) (*model.DetailResponse, error) {
|
|
// Validate table exists
|
|
_, err := s.repo.GetTableConfig(tableName)
|
|
if err != nil {
|
|
s.logger.Error("failed to get table config", "table", tableName, "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
// Get data from repository
|
|
data, err := s.repo.GetTableDataByID(tableName, id)
|
|
if err != nil {
|
|
s.logger.Error("failed to get table detail",
|
|
"table", tableName,
|
|
"id", id,
|
|
"error", err)
|
|
return nil, err
|
|
}
|
|
|
|
response := &model.DetailResponse{
|
|
Data: data,
|
|
}
|
|
|
|
s.logger.Debug("retrieved table detail",
|
|
"table", tableName,
|
|
"id", id)
|
|
|
|
return response, nil
|
|
}
|
|
|
|
// GetTableColumns returns column information for a table
|
|
func (s *DataService) GetTableColumns(tableName string) ([]database.ColumnInfo, error) {
|
|
// Validate table exists
|
|
_, err := s.repo.GetTableConfig(tableName)
|
|
if err != nil {
|
|
s.logger.Error("failed to get table config", "table", tableName, "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
// Get column information from repository
|
|
columns, err := s.repo.GetTableColumns(tableName)
|
|
if err != nil {
|
|
s.logger.Error("failed to get table columns",
|
|
"table", tableName,
|
|
"error", err)
|
|
return nil, err
|
|
}
|
|
|
|
return columns, nil
|
|
}
|
|
|
|
// ValidateConfiguration validates the entire configuration
|
|
func (s *DataService) ValidateConfiguration() error {
|
|
// Validate tables configuration
|
|
if len(s.config.Tables) == 0 {
|
|
return fmt.Errorf("no tables configured")
|
|
}
|
|
|
|
// Validate table existence in database
|
|
if err := s.repo.ValidateTableConfig(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Validate individual table configurations
|
|
for tableName, tableConfig := range s.config.Tables {
|
|
if tableConfig.Alias == "" {
|
|
return fmt.Errorf("table %s has empty alias", tableName)
|
|
}
|
|
|
|
if tableConfig.PageSize <= 0 {
|
|
return fmt.Errorf("table %s has invalid page size", tableName)
|
|
}
|
|
|
|
// Validate field configurations
|
|
for fieldName, fieldConfig := range tableConfig.Fields {
|
|
if fieldConfig.Type == "" {
|
|
return fmt.Errorf("field %s in table %s has empty type", fieldName, tableName)
|
|
}
|
|
}
|
|
}
|
|
|
|
s.logger.Info("configuration validation completed successfully")
|
|
return nil
|
|
}
|
|
|
|
// GetTableConfig returns the configuration for a specific table
|
|
func (s *DataService) GetTableConfig(tableName string) (*model.TableConfig, error) {
|
|
return s.repo.GetTableConfig(tableName)
|
|
}
|
|
|
|
// GetDefaultTable returns the first configured table name
|
|
func (s *DataService) GetDefaultTable() (string, error) {
|
|
if len(s.config.Tables) == 0 {
|
|
return "", fmt.Errorf("no tables configured")
|
|
}
|
|
|
|
// Return the first table name
|
|
for tableName := range s.config.Tables {
|
|
return tableName, nil
|
|
}
|
|
|
|
return "", fmt.Errorf("no tables configured")
|
|
}
|