Skip to content

Commit

Permalink
[add] setup validate db & hosting
Browse files Browse the repository at this point in the history
  • Loading branch information
trheyi committed Oct 28, 2022
1 parent 56b9def commit d041b2a
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 137 deletions.
6 changes: 5 additions & 1 deletion engine/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ func Load(cfg config.Config) (err error) {
}

// 第二步: 建立数据库 & 会话连接
share.DBConnect(cfg.DB) // 创建数据库连接
err = share.DBConnect(cfg.DB) // 创建数据库连接
if err != nil {
printErr(cfg.Mode, "DB", err)
}

// share.SessionConnect(cfg.Session) // 创建会话服务器链接

// 加载应用引擎
Expand Down
68 changes: 49 additions & 19 deletions setup/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package setup

import (
"fmt"
"net"
"os"
"path/filepath"
"time"

"github.com/yaoapp/gou/connector"
"github.com/yaoapp/xun/capsule"
"github.com/yaoapp/yao/config"
)

Expand All @@ -30,30 +32,59 @@ func Check() bool {
return false
}

// Validate db link
func Validate() (err error) {
// ValidateHosting host ports
func ValidateHosting(option map[string]string) error {
if option["YAO_PORT"] == "" {
return fmt.Errorf("监听端口必须填写")
}

root := appRoot()
path := filepath.Join(root, "db", "yao.db")
if option["YAO_STUDIO_PORT"] == option["YAO_PORT"] {
return fmt.Errorf("监听端口和 Studio 端口不能相同")
}

data := []byte(fmt.Sprintf(`{
"type": "sqlite3",
"options": {
"file": "%s"
if option["YAO_PORT"] != SetupPort {
conn, _ := net.DialTimeout("tcp", net.JoinHostPort("127.0.0.1", option["YAO_PORT"]), time.Second)
if conn != nil {
defer conn.Close()
return fmt.Errorf("监听端口 %s 已被占用", option["YAO_PORT"])
}
}`, path))
}

data = []byte(`{
"type": "mysql",
"options": {
"db": "test",
"hosts": [{ "host": "127.0.0.1", "user":"root", "pass":"123456" }]
if option["YAO_STUDIO_PORT"] != SetupPort {
conn, _ := net.DialTimeout("tcp", net.JoinHostPort("127.0.0.1", option["YAO_STUDIO_PORT"]), time.Second)
if conn != nil {
defer conn.Close()
return fmt.Errorf("Studio 端口 %s 已被占用", option["YAO_STUDIO_PORT"])
}
}`)
}

_, err = connector.Load(string(data), "test")
return err
return nil
}

// ValidateDB db connection
func ValidateDB(option map[string]string) error {

driver, dsn, err := getDSN(option)
if err != nil {
return fmt.Errorf("连接失败 %s", err.Error())
}

m, err := capsule.Add("validate", driver, dsn)
if err != nil {
return fmt.Errorf("连接失败 %s", err.Error())
}

conn, err := m.Primary()
if err != nil {
return fmt.Errorf("连接失败 %s", err.Error())
}

err = conn.Ping(2 * time.Second)
if err != nil {
return fmt.Errorf("连接失败 %s", err.Error())
}

return nil
}

func appRoot() string {
Expand Down Expand Up @@ -97,7 +128,6 @@ func hasInstalled(cfg config.Config) bool {
}

if _, err := os.Stat(dbfile); err != nil && os.IsNotExist(err) {
fmt.Println(dbfile)
return false
}

Expand Down
144 changes: 139 additions & 5 deletions setup/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package setup
import (
"fmt"
"net/http"
"time"
"os"
"path/filepath"
"strings"

"github.com/gin-gonic/gin"
"github.com/yaoapp/kun/exception"
Expand Down Expand Up @@ -56,7 +58,7 @@ func recovered(c *gin.Context, recovered interface{}) {
// }
func runSetup(c *gin.Context) {

payload := getPayload(c)
payload := getSetting(c)

cfg, err := getConfig()
if err != nil {
Expand Down Expand Up @@ -99,17 +101,149 @@ func runSetup(c *gin.Context) {
}

func runCheck(c *gin.Context) {
time.Sleep(2 * time.Second)

payload := getCheck(c)
dbOption, err := getDBOption(map[string]map[string]string{"db": payload})
if err != nil {
c.JSON(500, gin.H{"code": 500, "message": err.Error()})
return
}

err = ValidateDB(dbOption)
if err != nil {
c.JSON(500, gin.H{"code": 500, "message": err.Error()})
return
}

c.JSON(200, gin.H{"code": 200})
}

func getPayload(c *gin.Context) map[string]map[string]string {
var payload map[string]map[string]string
func getCheck(c *gin.Context) map[string]string {
var payload map[string]string
err := c.ShouldBindJSON(&payload)
if err != nil {
c.JSON(500, gin.H{"code": 400, "message": err.Error()})
c.Abort()
return nil
}
return payload
}

func getSetting(c *gin.Context) map[string]map[string]string {
var payload map[string]map[string]string
err := c.ShouldBindJSON(&payload)
if err != nil {
c.JSON(500, gin.H{"code": 400, "message": err.Error()})
c.Abort()
return nil
}
return payload
}

func getENVOption(payload map[string]map[string]string) (map[string]string, error) {
env, has := payload["env"]
if !has {
return nil, fmt.Errorf("缺少服务配置信息")
}

if env["YAO_ENV"] == "开发模式(推荐)" {
env["YAO_ENV"] = "development"
} else {
env["YAO_ENV"] = "production"
}

if env["YAO_LANG"] == "中文" {
env["YAO_LANG"] = "zh-cn"
} else {
env["YAO_LANG"] = "en-us"
}
return env, nil
}

func getDBOption(payload map[string]map[string]string) (map[string]string, error) {

db, has := payload["db"]
if !has {
return nil, fmt.Errorf("缺少数据库配置信息")
}

dbOption := map[string]string{}
switch db["type"] {
case "", "sqlite", "sqlite3":
dbOption["type"] = "sqlite3"
dbOption["file"] = db["option.file"]
return dbOption, nil

case "mysql":
dbOption["type"] = "mysql"
dbOption["db"] = db["option.db"]
dbOption["host"] = db["option.host.host"]
dbOption["port"] = db["option.host.port"]
dbOption["user"] = db["option.host.user"]
dbOption["pass"] = db["option.host.pass"]
return dbOption, nil
}

return nil, fmt.Errorf("数据库驱动暂不支持")
}

func getDSN(dbOption map[string]string) (string, string, error) {

switch dbOption["type"] {
case "", "sqlite", "sqlite3":
root := appRoot()
var err error
db := filepath.Join("db", "yao.db")
if v, has := dbOption["file"]; has {
db = v
}

if !strings.HasPrefix(db, "/") {
db = filepath.Join(root, db)
db, err = filepath.Abs(db)
if err != nil && !os.IsNotExist(err) {
return "", "", err
}
}

dir := filepath.Dir(db)
err = os.MkdirAll(dir, os.ModePerm)
if err != nil && !os.IsExist(err) {
return "", "", err
}

return "sqlite3", db, nil

case "mysql":

db := "yao"
if v, has := dbOption["db"]; has {
db = v
}

host := "127.0.0.1"
if v, has := dbOption["host"]; has {
host = v
}

port := "3306"
if v, has := dbOption["port"]; has {
port = v
}

user := "root"
if v, has := dbOption["user"]; has {
user = v
}

pass := ""
if v, has := dbOption["pass"]; has {
pass = v
}

return "mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, pass, host, port, db), nil
}

return "", "", fmt.Errorf("driver does not support")

}
Loading

0 comments on commit d041b2a

Please sign in to comment.