Files
uzdb/internal/app/app.go
loveuer 9874561410 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
2026-04-04 07:14:00 -07:00

325 lines
8.3 KiB
Go

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()
}