Files
goauto/server/cmd/import-cmautobuy-products/main.go
T

94 lines
2.9 KiB
Go

package main
import (
"context"
"database/sql"
"encoding/json"
"flag"
"fmt"
"os"
"strings"
"time"
"go-admin/app/goauto/cmautobuyimport"
)
func main() {
var sourceConfig, targetConfig string
var apply bool
flag.StringVar(&sourceConfig, "source-config", os.Getenv("GOAUTO_CMAUTOBUY_CONFIG"), "cmautobuy 未跟踪 config.yaml 路径")
flag.StringVar(&targetConfig, "target-config", os.Getenv("GOAUTO_CONFIG"), "GoAuto 未跟踪 config.yaml 路径")
flag.BoolVar(&apply, "apply", false, "确认写入目标库;缺省只执行 dry-run")
flag.Parse()
if sourceConfig == "" || targetConfig == "" {
fatal("必须通过 --source-config/--target-config 或对应环境变量提供两个未跟踪配置文件")
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
sourceDSN, err := cmautobuyimport.DSNFromConfig(sourceConfig, true)
if err != nil {
fatal(err.Error())
}
targetDSN, err := cmautobuyimport.DSNFromConfig(targetConfig, false)
if err != nil {
fatal(err.Error())
}
source, err := sql.Open("mysql", sourceDSN)
if err != nil {
fatal("打开来源数据库失败")
}
defer source.Close()
target, err := sql.Open("mysql", targetDSN)
if err != nil {
fatal("打开目标数据库失败")
}
defer target.Close()
if err := source.PingContext(ctx); err != nil {
fatal("连接来源数据库失败:" + safeConnectionError(err))
}
if err := target.PingContext(ctx); err != nil {
fatal("连接目标数据库失败:" + safeConnectionError(err))
}
dataset, err := cmautobuyimport.LoadSource(ctx, source)
if err != nil {
fatal(err.Error())
}
currency, err := cmautobuyimport.ResolveTargetCurrency(ctx, target)
if err != nil {
fatal(err.Error())
}
report, err := cmautobuyimport.Run(ctx, target, dataset, cmautobuyimport.Options{Apply: apply, Currency: currency})
if err != nil {
fatal(err.Error())
}
raw, err := json.MarshalIndent(report, "", " ")
if err != nil {
fatal("生成导入报告失败")
}
fmt.Println(string(raw))
if !apply {
fmt.Println("dry-run 完成:没有写入数据库。查看报告并再次确认后才能使用 --apply。")
}
}
func safeConnectionError(err error) string {
message := strings.ToLower(err.Error())
switch {
case strings.Contains(message, "access denied") || strings.Contains(message, "authentication"):
return "认证失败(凭据和 DSN 未输出)"
case strings.Contains(message, "certificate") || strings.Contains(message, "tls") || strings.Contains(message, "x509"):
return "TLS 证书校验失败(凭据和 DSN 未输出)"
case strings.Contains(message, "refused"):
return "服务器拒绝连接(凭据和 DSN 未输出)"
case strings.Contains(message, "timeout") || strings.Contains(message, "deadline"):
return "连接超时(凭据和 DSN 未输出)"
default:
return "网络或数据库连接异常(凭据和 DSN 未输出)"
}
}
func fatal(message string) {
fmt.Fprintln(os.Stderr, "导入失败:"+message)
os.Exit(1)
}