added interactive setup of config.json
This commit is contained in:
131
dbPrompt.go
131
dbPrompt.go
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"database/sql"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
@ -52,17 +53,9 @@ var db *sql.DB
|
||||
var historyDir = "./history"
|
||||
|
||||
func main() {
|
||||
// Load configuration
|
||||
file, err := os.Open("config.json")
|
||||
config, err := loadOrCreateConfig("config.json")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open config file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var config Config
|
||||
decoder := json.NewDecoder(file)
|
||||
if err := decoder.Decode(&config); err != nil {
|
||||
log.Fatalf("Failed to decode config: %v", err)
|
||||
log.Fatalf("Failed to load configuration: %v", err)
|
||||
}
|
||||
|
||||
// Connect to the database
|
||||
@ -99,6 +92,124 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func loadOrCreateConfig(path string) (Config, error) {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
fmt.Printf("Configuration file %q was not found.\n", path)
|
||||
fmt.Println("Please provide MySQL connection details to create it.")
|
||||
|
||||
cfg, promptErr := promptConfigFromConsole()
|
||||
if promptErr != nil {
|
||||
return Config{}, promptErr
|
||||
}
|
||||
|
||||
data, marshalErr := json.MarshalIndent(cfg, "", " ")
|
||||
if marshalErr != nil {
|
||||
return Config{}, fmt.Errorf("failed to serialize config: %w", marshalErr)
|
||||
}
|
||||
|
||||
if writeErr := os.WriteFile(path, append(data, '\n'), 0600); writeErr != nil {
|
||||
return Config{}, fmt.Errorf("failed to create %s: %w", path, writeErr)
|
||||
}
|
||||
|
||||
fmt.Printf("Created %s successfully.\n", path)
|
||||
return cfg, nil
|
||||
} else if err != nil {
|
||||
return Config{}, fmt.Errorf("failed to check config file: %w", err)
|
||||
}
|
||||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("failed to open config file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var cfg Config
|
||||
decoder := json.NewDecoder(file)
|
||||
if err := decoder.Decode(&cfg); err != nil {
|
||||
return Config{}, fmt.Errorf("failed to decode config: %w", err)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func promptConfigFromConsole() (Config, error) {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
hostname, err := promptRequired(reader, "hostname")
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
port, err := promptPort(reader, 3306)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
username, err := promptRequired(reader, "username")
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
password, err := promptRequired(reader, "password")
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
database, err := promptRequired(reader, "database")
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
return Config{
|
||||
Username: username,
|
||||
Password: password,
|
||||
Hostname: hostname,
|
||||
Port: port,
|
||||
Database: database,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func promptRequired(reader *bufio.Reader, field string) (string, error) {
|
||||
for {
|
||||
fmt.Printf("%s: ", field)
|
||||
value, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read %s: %w", field, err)
|
||||
}
|
||||
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" {
|
||||
fmt.Printf("%s is required.\n", field)
|
||||
continue
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
}
|
||||
|
||||
func promptPort(reader *bufio.Reader, defaultPort int) (int, error) {
|
||||
for {
|
||||
fmt.Printf("port [%d]: ", defaultPort)
|
||||
value, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to read port: %w", err)
|
||||
}
|
||||
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" {
|
||||
return defaultPort, nil
|
||||
}
|
||||
|
||||
port, atoiErr := strconv.Atoi(value)
|
||||
if atoiErr != nil || port <= 0 || port > 65535 {
|
||||
fmt.Println("Port must be a number between 1 and 65535.")
|
||||
continue
|
||||
}
|
||||
|
||||
return port, nil
|
||||
}
|
||||
}
|
||||
|
||||
func serveIndex(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, "index.html")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user