refactor: Flatten directory structure
Move project files from uzdb/ subdirectory to root directory for cleaner project structure.
Changes:
- Move frontend/ to root
- Move internal/ to root
- Move build/ to root
- Move all config files (go.mod, wails.json, etc.) to root
- Remove redundant uzdb/ subdirectory nesting
Project structure is now:
├── frontend/ # React application
├── internal/ # Go backend
├── build/ # Wails build assets
├── doc/ # Design documentation
├── main.go # Entry point
└── ...
🤖 Generated with Qoder
This commit is contained in:
324
internal/app/app.go
Normal file
324
internal/app/app.go
Normal file
@@ -0,0 +1,324 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"uzdb/internal/config"
|
||||
"uzdb/internal/database"
|
||||
"uzdb/internal/handler"
|
||||
"uzdb/internal/models"
|
||||
"uzdb/internal/services"
|
||||
)
|
||||
|
||||
// App is the main application structure for Wails bindings
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
config *config.Config
|
||||
connectionSvc *services.ConnectionService
|
||||
querySvc *services.QueryService
|
||||
httpServer *handler.HTTPServer
|
||||
shutdownFunc context.CancelFunc
|
||||
}
|
||||
|
||||
// NewApp creates a new App instance
|
||||
func NewApp() *App {
|
||||
return &App{}
|
||||
}
|
||||
|
||||
// Initialize initializes the application with all services
|
||||
func (a *App) Initialize(
|
||||
cfg *config.Config,
|
||||
connectionSvc *services.ConnectionService,
|
||||
querySvc *services.QueryService,
|
||||
httpServer *handler.HTTPServer,
|
||||
) {
|
||||
a.config = cfg
|
||||
a.connectionSvc = connectionSvc
|
||||
a.querySvc = querySvc
|
||||
a.httpServer = httpServer
|
||||
}
|
||||
|
||||
// OnStartup is called when the app starts (public method for Wails)
|
||||
func (a *App) OnStartup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
|
||||
config.GetLogger().Info("Wails application started")
|
||||
}
|
||||
|
||||
// GetConnections returns all user connections
|
||||
// Wails binding: frontend can call window.go.app.GetConnections()
|
||||
func (a *App) GetConnections() []models.UserConnection {
|
||||
if a.connectionSvc == nil {
|
||||
return []models.UserConnection{}
|
||||
}
|
||||
|
||||
connections, err := a.connectionSvc.GetAllConnections(a.ctx)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to get connections", zap.Error(err))
|
||||
return []models.UserConnection{}
|
||||
}
|
||||
|
||||
return connections
|
||||
}
|
||||
|
||||
// CreateConnection creates a new database connection
|
||||
// Returns error message or empty string on success
|
||||
func (a *App) CreateConnection(conn models.CreateConnectionRequest) string {
|
||||
if a.connectionSvc == nil {
|
||||
return "Service not initialized"
|
||||
}
|
||||
|
||||
_, err := a.connectionSvc.CreateConnection(a.ctx, &conn)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to create connection", zap.Error(err))
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// UpdateConnection updates an existing database connection
|
||||
// Returns error message or empty string on success
|
||||
func (a *App) UpdateConnection(conn models.UserConnection) string {
|
||||
if a.connectionSvc == nil {
|
||||
return "Service not initialized"
|
||||
}
|
||||
|
||||
req := &models.UpdateConnectionRequest{
|
||||
Name: conn.Name,
|
||||
Type: conn.Type,
|
||||
Host: conn.Host,
|
||||
Port: conn.Port,
|
||||
Username: conn.Username,
|
||||
Password: conn.Password,
|
||||
Database: conn.Database,
|
||||
SSLMode: conn.SSLMode,
|
||||
Timeout: conn.Timeout,
|
||||
}
|
||||
|
||||
_, err := a.connectionSvc.UpdateConnection(a.ctx, conn.ID, req)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to update connection", zap.Error(err))
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// DeleteConnection deletes a database connection
|
||||
// Returns error message or empty string on success
|
||||
func (a *App) DeleteConnection(id string) string {
|
||||
if a.connectionSvc == nil {
|
||||
return "Service not initialized"
|
||||
}
|
||||
|
||||
err := a.connectionSvc.DeleteConnection(a.ctx, id)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to delete connection", zap.Error(err))
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// TestConnection tests a database connection
|
||||
// Returns (success, error_message)
|
||||
func (a *App) TestConnection(id string) (bool, string) {
|
||||
if a.connectionSvc == nil {
|
||||
return false, "Service not initialized"
|
||||
}
|
||||
|
||||
result, err := a.connectionSvc.TestConnection(a.ctx, id)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to test connection", zap.Error(err))
|
||||
return false, err.Error()
|
||||
}
|
||||
|
||||
return result.Success, result.Message
|
||||
}
|
||||
|
||||
// ExecuteQuery executes a SQL query on a connection
|
||||
// Returns query result or error message
|
||||
func (a *App) ExecuteQuery(connectionID, sql string) (*models.QueryResult, string) {
|
||||
if a.connectionSvc == nil {
|
||||
return nil, "Service not initialized"
|
||||
}
|
||||
|
||||
result, err := a.connectionSvc.ExecuteQuery(a.ctx, connectionID, sql)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to execute query",
|
||||
zap.String("connection_id", connectionID),
|
||||
zap.String("sql", sql),
|
||||
zap.Error(err))
|
||||
return nil, err.Error()
|
||||
}
|
||||
|
||||
return result, ""
|
||||
}
|
||||
|
||||
// GetTables returns all tables for a connection
|
||||
func (a *App) GetTables(connectionID string) ([]models.Table, string) {
|
||||
if a.connectionSvc == nil {
|
||||
return []models.Table{}, "Service not initialized"
|
||||
}
|
||||
|
||||
tables, err := a.connectionSvc.GetTables(a.ctx, connectionID)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to get tables",
|
||||
zap.String("connection_id", connectionID),
|
||||
zap.Error(err))
|
||||
return []models.Table{}, err.Error()
|
||||
}
|
||||
|
||||
return tables, ""
|
||||
}
|
||||
|
||||
// GetTableData returns data from a table
|
||||
func (a *App) GetTableData(connectionID, tableName string, limit, offset int) (*models.QueryResult, string) {
|
||||
if a.connectionSvc == nil {
|
||||
return nil, "Service not initialized"
|
||||
}
|
||||
|
||||
result, err := a.connectionSvc.GetTableData(a.ctx, connectionID, tableName, limit, offset)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to get table data",
|
||||
zap.String("connection_id", connectionID),
|
||||
zap.String("table", tableName),
|
||||
zap.Error(err))
|
||||
return nil, err.Error()
|
||||
}
|
||||
|
||||
return result, ""
|
||||
}
|
||||
|
||||
// GetTableStructure returns the structure of a table
|
||||
func (a *App) GetTableStructure(connectionID, tableName string) (*models.TableStructure, string) {
|
||||
if a.connectionSvc == nil {
|
||||
return nil, "Service not initialized"
|
||||
}
|
||||
|
||||
structure, err := a.connectionSvc.GetTableStructure(a.ctx, connectionID, tableName)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to get table structure",
|
||||
zap.String("connection_id", connectionID),
|
||||
zap.String("table", tableName),
|
||||
zap.Error(err))
|
||||
return nil, err.Error()
|
||||
}
|
||||
|
||||
return structure, ""
|
||||
}
|
||||
|
||||
// GetQueryHistory returns query history with pagination
|
||||
func (a *App) GetQueryHistory(connectionID string, page, pageSize int) ([]models.QueryHistory, int64, string) {
|
||||
if a.querySvc == nil {
|
||||
return []models.QueryHistory{}, 0, "Service not initialized"
|
||||
}
|
||||
|
||||
history, total, err := a.querySvc.GetQueryHistory(a.ctx, connectionID, page, pageSize)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to get query history", zap.Error(err))
|
||||
return []models.QueryHistory{}, 0, err.Error()
|
||||
}
|
||||
|
||||
return history, total, ""
|
||||
}
|
||||
|
||||
// GetSavedQueries returns all saved queries
|
||||
func (a *App) GetSavedQueries(connectionID string) ([]models.SavedQuery, string) {
|
||||
if a.querySvc == nil {
|
||||
return []models.SavedQuery{}, "Service not initialized"
|
||||
}
|
||||
|
||||
queries, err := a.querySvc.GetSavedQueries(a.ctx, connectionID)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to get saved queries", zap.Error(err))
|
||||
return []models.SavedQuery{}, err.Error()
|
||||
}
|
||||
|
||||
return queries, ""
|
||||
}
|
||||
|
||||
// CreateSavedQuery creates a new saved query
|
||||
func (a *App) CreateSavedQuery(req models.CreateSavedQueryRequest) (*models.SavedQuery, string) {
|
||||
if a.querySvc == nil {
|
||||
return nil, "Service not initialized"
|
||||
}
|
||||
|
||||
query, err := a.querySvc.CreateSavedQuery(a.ctx, &req)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to create saved query", zap.Error(err))
|
||||
return nil, err.Error()
|
||||
}
|
||||
|
||||
return query, ""
|
||||
}
|
||||
|
||||
// UpdateSavedQuery updates a saved query
|
||||
func (a *App) UpdateSavedQuery(id uint, req models.UpdateSavedQueryRequest) (*models.SavedQuery, string) {
|
||||
if a.querySvc == nil {
|
||||
return nil, "Service not initialized"
|
||||
}
|
||||
|
||||
query, err := a.querySvc.UpdateSavedQuery(a.ctx, id, &req)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to update saved query", zap.Error(err))
|
||||
return nil, err.Error()
|
||||
}
|
||||
|
||||
return query, ""
|
||||
}
|
||||
|
||||
// DeleteSavedQuery deletes a saved query
|
||||
func (a *App) DeleteSavedQuery(id uint) string {
|
||||
if a.querySvc == nil {
|
||||
return "Service not initialized"
|
||||
}
|
||||
|
||||
err := a.querySvc.DeleteSavedQuery(a.ctx, id)
|
||||
if err != nil {
|
||||
config.GetLogger().Error("failed to delete saved query", zap.Error(err))
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// StartHTTPServer starts the HTTP API server in background
|
||||
func (a *App) StartHTTPServer() string {
|
||||
if a.httpServer == nil {
|
||||
return "HTTP server not initialized"
|
||||
}
|
||||
|
||||
go func() {
|
||||
port := a.config.API.Port
|
||||
if err := a.httpServer.Start(port); err != nil {
|
||||
config.GetLogger().Error("HTTP server error", zap.Error(err))
|
||||
}
|
||||
}()
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// Shutdown gracefully shuts down the application
|
||||
func (a *App) Shutdown() {
|
||||
config.GetLogger().Info("shutting down application")
|
||||
|
||||
if a.shutdownFunc != nil {
|
||||
a.shutdownFunc()
|
||||
}
|
||||
|
||||
if a.httpServer != nil {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
a.httpServer.Shutdown(ctx)
|
||||
}
|
||||
|
||||
// Close all database connections
|
||||
database.CloseSQLite()
|
||||
|
||||
config.Sync()
|
||||
}
|
||||
Reference in New Issue
Block a user