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:
85
internal/models/connection.go
Normal file
85
internal/models/connection.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ConnectionType represents the type of database connection
|
||||
type ConnectionType string
|
||||
|
||||
const (
|
||||
// ConnectionTypeMySQL represents MySQL database
|
||||
ConnectionTypeMySQL ConnectionType = "mysql"
|
||||
// ConnectionTypePostgreSQL represents PostgreSQL database
|
||||
ConnectionTypePostgreSQL ConnectionType = "postgres"
|
||||
// ConnectionTypeSQLite represents SQLite database
|
||||
ConnectionTypeSQLite ConnectionType = "sqlite"
|
||||
)
|
||||
|
||||
// UserConnection represents a user's database connection configuration
|
||||
// This model is stored in the local SQLite database
|
||||
type UserConnection struct {
|
||||
ID string `gorm:"type:varchar(36);primaryKey" json:"id"`
|
||||
Name string `gorm:"type:varchar(100);not null" json:"name"`
|
||||
Type ConnectionType `gorm:"type:varchar(20);not null" json:"type"`
|
||||
Host string `gorm:"type:varchar(255)" json:"host,omitempty"`
|
||||
Port int `gorm:"type:integer" json:"port,omitempty"`
|
||||
Username string `gorm:"type:varchar(100)" json:"username,omitempty"`
|
||||
Password string `gorm:"type:text" json:"password"` // Encrypted password
|
||||
Database string `gorm:"type:varchar(255)" json:"database"`
|
||||
SSLMode string `gorm:"type:varchar(50)" json:"ssl_mode,omitempty"`
|
||||
Timeout int `gorm:"type:integer;default:30" json:"timeout"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||
|
||||
// For SQLite connections, Database field contains the file path
|
||||
}
|
||||
|
||||
// TableName returns the table name for UserConnection
|
||||
func (UserConnection) TableName() string {
|
||||
return "user_connections"
|
||||
}
|
||||
|
||||
// CreateConnectionRequest represents a request to create a new connection
|
||||
type CreateConnectionRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Type ConnectionType `json:"type" binding:"required"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Database string `json:"database" binding:"required"`
|
||||
SSLMode string `json:"ssl_mode"`
|
||||
Timeout int `json:"timeout"`
|
||||
}
|
||||
|
||||
// UpdateConnectionRequest represents a request to update an existing connection
|
||||
type UpdateConnectionRequest struct {
|
||||
Name string `json:"name"`
|
||||
Type ConnectionType `json:"type"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Database string `json:"database"`
|
||||
SSLMode string `json:"ssl_mode"`
|
||||
Timeout int `json:"timeout"`
|
||||
}
|
||||
|
||||
// Validate validates the connection request
|
||||
func (r *CreateConnectionRequest) Validate() error {
|
||||
switch r.Type {
|
||||
case ConnectionTypeMySQL, ConnectionTypePostgreSQL:
|
||||
if r.Host == "" {
|
||||
return ErrValidationFailed
|
||||
}
|
||||
if r.Port <= 0 || r.Port > 65535 {
|
||||
return ErrValidationFailed
|
||||
}
|
||||
case ConnectionTypeSQLite:
|
||||
if r.Database == "" {
|
||||
return ErrValidationFailed
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
74
internal/models/errors.go
Normal file
74
internal/models/errors.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package models
|
||||
|
||||
import "errors"
|
||||
|
||||
// Application errors
|
||||
var (
|
||||
// ErrNotFound resource not found
|
||||
ErrNotFound = errors.New("resource not found")
|
||||
|
||||
// ErrAlreadyExists resource already exists
|
||||
ErrAlreadyExists = errors.New("resource already exists")
|
||||
|
||||
// ErrValidationFailed validation failed
|
||||
ErrValidationFailed = errors.New("validation failed")
|
||||
|
||||
// ErrUnauthorized unauthorized access
|
||||
ErrUnauthorized = errors.New("unauthorized access")
|
||||
|
||||
// ErrForbidden forbidden access
|
||||
ErrForbidden = errors.New("forbidden access")
|
||||
|
||||
// ErrInternalServer internal server error
|
||||
ErrInternalServer = errors.New("internal server error")
|
||||
|
||||
// ErrConnectionFailed connection failed
|
||||
ErrConnectionFailed = errors.New("connection failed")
|
||||
|
||||
// ErrQueryFailed query execution failed
|
||||
ErrQueryFailed = errors.New("query execution failed")
|
||||
|
||||
// ErrEncryptionFailed encryption/decryption failed
|
||||
ErrEncryptionFailed = errors.New("encryption/decryption failed")
|
||||
|
||||
// ErrInvalidConfig invalid configuration
|
||||
ErrInvalidConfig = errors.New("invalid configuration")
|
||||
|
||||
// ErrDatabaseLocked database is locked
|
||||
ErrDatabaseLocked = errors.New("database is locked")
|
||||
|
||||
// ErrTimeout operation timeout
|
||||
ErrTimeout = errors.New("operation timeout")
|
||||
)
|
||||
|
||||
// ErrorCode represents error codes for API responses
|
||||
type ErrorCode string
|
||||
|
||||
const (
|
||||
// CodeSuccess successful operation
|
||||
CodeSuccess ErrorCode = "SUCCESS"
|
||||
|
||||
// CodeNotFound resource not found
|
||||
CodeNotFound ErrorCode = "NOT_FOUND"
|
||||
|
||||
// CodeValidation validation error
|
||||
CodeValidation ErrorCode = "VALIDATION_ERROR"
|
||||
|
||||
// CodeUnauthorized unauthorized
|
||||
CodeUnauthorized ErrorCode = "UNAUTHORIZED"
|
||||
|
||||
// CodeForbidden forbidden
|
||||
CodeForbidden ErrorCode = "FORBIDDEN"
|
||||
|
||||
// CodeInternal internal error
|
||||
CodeInternal ErrorCode = "INTERNAL_ERROR"
|
||||
|
||||
// CodeConnection connection error
|
||||
CodeConnection ErrorCode = "CONNECTION_ERROR"
|
||||
|
||||
// CodeQuery query error
|
||||
CodeQuery ErrorCode = "QUERY_ERROR"
|
||||
|
||||
// CodeEncryption encryption error
|
||||
CodeEncryption ErrorCode = "ENCRYPTION_ERROR"
|
||||
)
|
||||
58
internal/models/query.go
Normal file
58
internal/models/query.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// QueryHistory represents a record of executed queries
|
||||
type QueryHistory struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
ConnectionID string `gorm:"type:varchar(36);not null;index" json:"connection_id"`
|
||||
SQL string `gorm:"type:text;not null" json:"sql"`
|
||||
Duration int64 `gorm:"type:bigint" json:"duration_ms"` // Duration in milliseconds
|
||||
ExecutedAt time.Time `gorm:"autoCreateTime;index" json:"executed_at"`
|
||||
RowsAffected int64 `gorm:"type:bigint" json:"rows_affected"`
|
||||
Error string `gorm:"type:text" json:"error,omitempty"`
|
||||
Success bool `gorm:"type:boolean;default:false" json:"success"`
|
||||
ResultPreview string `gorm:"type:text" json:"result_preview,omitempty"` // JSON preview of first few rows
|
||||
}
|
||||
|
||||
// TableName returns the table name for QueryHistory
|
||||
func (QueryHistory) TableName() string {
|
||||
return "query_history"
|
||||
}
|
||||
|
||||
// SavedQuery represents a saved SQL query
|
||||
type SavedQuery struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"type:varchar(255);not null" json:"name"`
|
||||
Description string `gorm:"type:text" json:"description"`
|
||||
SQL string `gorm:"type:text;not null" json:"sql"`
|
||||
ConnectionID string `gorm:"type:varchar(36);index" json:"connection_id"`
|
||||
Tags string `gorm:"type:text" json:"tags"` // Comma-separated tags
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName returns the table name for SavedQuery
|
||||
func (SavedQuery) TableName() string {
|
||||
return "saved_queries"
|
||||
}
|
||||
|
||||
// CreateSavedQueryRequest represents a request to save a query
|
||||
type CreateSavedQueryRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Description string `json:"description"`
|
||||
SQL string `json:"sql" binding:"required"`
|
||||
ConnectionID string `json:"connection_id"`
|
||||
Tags string `json:"tags"`
|
||||
}
|
||||
|
||||
// UpdateSavedQueryRequest represents a request to update a saved query
|
||||
type UpdateSavedQueryRequest struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
SQL string `json:"sql"`
|
||||
ConnectionID string `json:"connection_id"`
|
||||
Tags string `json:"tags"`
|
||||
}
|
||||
128
internal/models/response.go
Normal file
128
internal/models/response.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// APIResponse represents a standard API response
|
||||
type APIResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// QueryResult represents the result of a SQL query execution
|
||||
type QueryResult struct {
|
||||
Columns []string `json:"columns"`
|
||||
Rows [][]interface{} `json:"rows"`
|
||||
RowCount int64 `json:"row_count"`
|
||||
AffectedRows int64 `json:"affected_rows"`
|
||||
Duration int64 `json:"duration_ms"`
|
||||
Success bool `json:"success"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// Table represents a database table
|
||||
type Table struct {
|
||||
Name string `json:"name"`
|
||||
Schema string `json:"schema,omitempty"`
|
||||
Type string `json:"type"` // table, view, etc.
|
||||
RowCount int64 `json:"row_count,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// TableStructure represents the structure of a database table
|
||||
type TableStructure struct {
|
||||
TableName string `json:"table_name"`
|
||||
Schema string `json:"schema,omitempty"`
|
||||
Columns []TableColumn `json:"columns"`
|
||||
Indexes []TableIndex `json:"indexes,omitempty"`
|
||||
ForeignKeys []ForeignKey `json:"foreign_keys,omitempty"`
|
||||
}
|
||||
|
||||
// TableColumn represents a column in a database table
|
||||
type TableColumn struct {
|
||||
Name string `json:"name"`
|
||||
DataType string `json:"data_type"`
|
||||
Nullable bool `json:"nullable"`
|
||||
Default string `json:"default,omitempty"`
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
IsUnique bool `json:"is_unique"`
|
||||
AutoIncrement bool `json:"auto_increment"`
|
||||
Length int `json:"length,omitempty"`
|
||||
Scale int `json:"scale,omitempty"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
// TableIndex represents an index on a database table
|
||||
type TableIndex struct {
|
||||
Name string `json:"name"`
|
||||
Columns []string `json:"columns"`
|
||||
IsUnique bool `json:"is_unique"`
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// ForeignKey represents a foreign key constraint
|
||||
type ForeignKey struct {
|
||||
Name string `json:"name"`
|
||||
Columns []string `json:"columns"`
|
||||
ReferencedTable string `json:"referenced_table"`
|
||||
ReferencedColumns []string `json:"referenced_columns"`
|
||||
OnDelete string `json:"on_delete,omitempty"`
|
||||
OnUpdate string `json:"on_update,omitempty"`
|
||||
}
|
||||
|
||||
// ConnectionTestResult represents the result of a connection test
|
||||
type ConnectionTestResult struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
Duration int64 `json:"duration_ms"`
|
||||
Metadata *DBMetadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// DBMetadata represents database metadata
|
||||
type DBMetadata struct {
|
||||
Version string `json:"version"`
|
||||
Database string `json:"database"`
|
||||
User string `json:"user"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
ServerTime string `json:"server_time"`
|
||||
}
|
||||
|
||||
// ErrorResponse represents an error response
|
||||
type ErrorResponse struct {
|
||||
Error string `json:"error"`
|
||||
Message string `json:"message"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Details map[string]interface{} `json:"details,omitempty"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Path string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// PaginatedResponse represents a paginated response
|
||||
type PaginatedResponse struct {
|
||||
Data interface{} `json:"data"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
TotalPages int `json:"total_pages"`
|
||||
}
|
||||
|
||||
// NewAPIResponse creates a new API response
|
||||
func NewAPIResponse(data interface{}) *APIResponse {
|
||||
return &APIResponse{
|
||||
Success: true,
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// NewErrorResponse creates a new error response
|
||||
func NewErrorResponse(message string) *APIResponse {
|
||||
return &APIResponse{
|
||||
Success: false,
|
||||
Error: message,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user