feat: add TableList component with styles and functionality for displaying database tables

feat: implement NewConnectionDialog component for creating and editing database connections with form validation

chore: generate TypeScript definitions and JavaScript bindings for app functions

chore: add models for configuration, connection requests, and database entities
This commit is contained in:
loveuer
2026-04-06 21:45:28 +08:00
parent 9874561410
commit 347ecd0f1b
22 changed files with 2475 additions and 315 deletions

View File

@@ -2,6 +2,7 @@ package app
import (
"context"
"errors"
"time"
"go.uber.org/zap"
@@ -13,14 +14,25 @@ import (
"uzdb/internal/services"
)
// rootErrMsg unwraps the full error chain and returns the deepest error message.
func rootErrMsg(err error) string {
for {
unwrapped := errors.Unwrap(err)
if unwrapped == nil {
return err.Error()
}
err = unwrapped
}
}
// 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
ctx context.Context
config *config.Config
connectionSvc *services.ConnectionService
querySvc *services.QueryService
httpServer *handler.HTTPServer
shutdownFunc context.CancelFunc
}
// NewApp creates a new App instance
@@ -44,7 +56,7 @@ func (a *App) Initialize(
// 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")
}
@@ -124,6 +136,24 @@ func (a *App) DeleteConnection(id string) string {
return ""
}
// DisconnectConnection removes an active connection from the connection manager
// Returns error message or empty string on success
func (a *App) DisconnectConnection(id string) string {
if a.connectionSvc == nil {
return "Service not initialized"
}
err := a.connectionSvc.DisconnectConnection(a.ctx, id)
if err != nil {
config.GetLogger().Error("failed to disconnect connection",
zap.String("id", id),
zap.Error(err))
return err.Error()
}
return ""
}
// TestConnection tests a database connection
// Returns (success, error_message)
func (a *App) TestConnection(id string) (bool, string) {
@@ -137,14 +167,19 @@ func (a *App) TestConnection(id string) (bool, string) {
return false, err.Error()
}
return result.Success, result.Message
return result.Success, func() string {
if result.Success {
return ""
}
return 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"
return &models.QueryResult{Success: false, Error: "Service not initialized"}, ""
}
result, err := a.connectionSvc.ExecuteQuery(a.ctx, connectionID, sql)
@@ -153,7 +188,7 @@ func (a *App) ExecuteQuery(connectionID, sql string) (*models.QueryResult, strin
zap.String("connection_id", connectionID),
zap.String("sql", sql),
zap.Error(err))
return nil, err.Error()
return &models.QueryResult{Success: false, Error: rootErrMsg(err)}, ""
}
return result, ""
@@ -188,7 +223,7 @@ func (a *App) GetTableData(connectionID, tableName string, limit, offset int) (*
zap.String("connection_id", connectionID),
zap.String("table", tableName),
zap.Error(err))
return nil, err.Error()
return nil, rootErrMsg(err)
}
return result, ""
@@ -306,19 +341,19 @@ func (a *App) StartHTTPServer() string {
// 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()
}