Browse Source

MySQL in wrapper, engin progress

Vova Tkach 6 years ago
parent
commit
767c483a80
5 changed files with 141 additions and 3 deletions
  1. 52 1
      engine/engine.go
  2. 20 1
      engine/wrapper/wrapper.go
  3. 3 0
      main.go
  4. 51 0
      utils/mysql_config.go
  5. 15 1
      utils/utils.go

+ 52 - 1
engine/engine.go

@@ -1,18 +1,22 @@
 package engine
 
 import (
+	"database/sql"
 	"fmt"
 	"net/http"
+	"os"
+	"strings"
 
+	"golang-fave/assets"
 	"golang-fave/engine/wrapper"
 	"golang-fave/logger"
+	"golang-fave/utils"
 
 	"github.com/vladimirok5959/golang-server-sessions/session"
 )
 
 type Engine struct {
 	Wrap *wrapper.Wrapper
-	// Database
 	// Actions
 	// Front-end or Back-end
 }
@@ -25,6 +29,52 @@ func Response(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *sessi
 }
 
 func (this *Engine) Process() bool {
+	this.Wrap.IsBackend = this.Wrap.R.URL.Path == "/cp" || strings.HasPrefix(this.Wrap.R.URL.Path, "/cp/")
+	this.Wrap.ConfMysqlExists = utils.IsMySqlConfigExists(this.Wrap.DConfig + string(os.PathSeparator) + "mysql.json")
+
+	// Some system actions here...
+	// MySQL install
+	// MySQL first user
+	// User login
+	// User logout
+
+	// Redirect to CP for creating MySQL config file
+	if !this.Wrap.IsBackend && !this.Wrap.ConfMysqlExists {
+		this.Wrap.W.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+		http.Redirect(this.Wrap.W, this.Wrap.R, this.Wrap.R.URL.Scheme+"://"+this.Wrap.R.Host+"/cp/", 302)
+		return true
+	}
+
+	// Display MySQL install page on backend
+	if this.Wrap.IsBackend && !this.Wrap.ConfMysqlExists {
+		utils.SystemRenderTemplate(this.Wrap.W, assets.TmplCpMySql, nil)
+		return true
+	}
+
+	// Read MySQL settings file
+	mc, err := utils.MySqlConfigRead(this.Wrap.DConfig + string(os.PathSeparator) + "mysql.json")
+	if err != nil {
+		utils.SystemErrorPageEngine(this.Wrap.W, err)
+		return true
+	}
+
+	// Connect to MySQL server
+	db, err := sql.Open("mysql", mc.User+":"+mc.Password+"@tcp("+mc.Host+":"+mc.Port+")/"+mc.Name)
+	if err != nil {
+		utils.SystemErrorPageEngine(this.Wrap.W, err)
+		return true
+	}
+	this.Wrap.DB = db
+	defer db.Close()
+	err = db.Ping()
+
+	// Check if MySQL server alive
+	if err != nil {
+		utils.SystemErrorPageEngine(this.Wrap.W, err)
+		return true
+	}
+
+	// Front-end or back-end here...
 	if this.Wrap.R.URL.Path == "/" {
 		this.Wrap.W.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
 		this.Wrap.W.Header().Set("Content-Type", "text/html")
@@ -40,5 +90,6 @@ func (this *Engine) Process() bool {
 
 		return true
 	}
+
 	return false
 }

+ 20 - 1
engine/wrapper/wrapper.go

@@ -1,10 +1,12 @@
 package wrapper
 
 import (
+	"database/sql"
 	"net/http"
 
 	"golang-fave/logger"
 
+	_ "github.com/go-sql-driver/mysql"
 	"github.com/vladimirok5959/golang-server-sessions/session"
 )
 
@@ -22,10 +24,27 @@ type Wrapper struct {
 	DLogs     string
 	DTemplate string
 	DTmp      string
+
+	IsBackend       bool
+	ConfMysqlExists bool
+
+	DB *sql.DB
 }
 
 func New(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Session, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string) *Wrapper {
-	return &Wrapper{l, w, r, s, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp}
+	return &Wrapper{
+		l:         l,
+		W:         w,
+		R:         r,
+		S:         s,
+		Host:      host,
+		Port:      port,
+		DConfig:   dirConfig,
+		DHtdocs:   dirHtdocs,
+		DLogs:     dirLogs,
+		DTemplate: dirTemplate,
+		DTmp:      dirTmp,
+	}
 }
 
 func (this *Wrapper) LogAccess(msg string) {

+ 3 - 0
main.go

@@ -67,6 +67,9 @@ func main() {
 	bootstrap.Start(lg.Handler, fmt.Sprintf("%s:%d", ParamHost, ParamPort), 30, consts.AssetsPath, func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("Server", "fave.pro/"+consts.ServerVersion)
 	}, func(w http.ResponseWriter, r *http.Request) {
+		// Schema
+		r.URL.Scheme = "http"
+
 		// Mounted assets
 		if res.Response(w, r, func(w http.ResponseWriter, r *http.Request, i *resource.Resource) {
 			w.Header().Set("Cache-Control", "public, max-age=31536000")

+ 51 - 0
utils/mysql_config.go

@@ -0,0 +1,51 @@
+package utils
+
+import (
+	"encoding/json"
+	"os"
+)
+
+type ConfigMySql struct {
+	Host     string
+	Port     string
+	Name     string
+	User     string
+	Password string
+}
+
+func IsMySqlConfigExists(file string) bool {
+	return IsFileExists(file) && !IsDir(file)
+}
+
+func MySqlConfigRead(file string) (*ConfigMySql, error) {
+	f, err := os.Open(file)
+	if err == nil {
+		defer f.Close()
+		dec := json.NewDecoder(f)
+		conf := ConfigMySql{}
+		err = dec.Decode(&conf)
+		if err == nil {
+			return &conf, err
+		}
+	}
+	return nil, err
+}
+
+func MySqlConfigWrite(file string, host string, port string, name string, user string, password string) error {
+	r, err := json.Marshal(&ConfigMySql{
+		Host:     host,
+		Port:     port,
+		Name:     name,
+		User:     user,
+		Password: password,
+	})
+	if err == nil {
+		f, err := os.Create(file)
+		if err == nil {
+			defer f.Close()
+			_, err = f.WriteString(string(r))
+			return err
+		}
+	}
+	return err
+}

+ 15 - 1
utils/utils.go

@@ -86,8 +86,22 @@ func GetTmplError(err error) consts.TmplError {
 	}
 }
 
+func SystemRenderTemplate(w http.ResponseWriter, c []byte, d interface{}) {
+	tmpl, err := template.New("template").Parse(string(c))
+	if err != nil {
+		SystemErrorPageEngine(w, err)
+		return
+	}
+	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+	w.Header().Set("Content-Type", "text/html")
+	tmpl.Execute(w, consts.TmplData{
+		System: GetTmplSystemData(),
+		Data:   d,
+	})
+}
+
 func SystemErrorPageEngine(w http.ResponseWriter, err error) {
-	if tmpl, errr := template.New("template").Parse(string(assets.TmplPageErrorEngine)); errr == nil {
+	if tmpl, e := template.New("template").Parse(string(assets.TmplPageErrorEngine)); e == nil {
 		w.WriteHeader(http.StatusInternalServerError)
 		w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
 		w.Header().Set("Content-Type", "text/html")