feat: 接入两端用户名登录和独立学习空间 (#2)
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
driver "github.com/go-sql-driver/mysql"
|
||||
"go-admin/app/lexgo"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
func openDB() (*gorm.DB, error) {
|
||||
c := driver.NewConfig()
|
||||
c.Net = "tcp"
|
||||
host := os.Getenv("LEXGO_DB_HOST")
|
||||
if host == "" {
|
||||
host = "127.0.0.1"
|
||||
}
|
||||
port := os.Getenv("LEXGO_DB_PORT")
|
||||
if port == "" {
|
||||
port = "3308"
|
||||
}
|
||||
c.Addr = net.JoinHostPort(host, port)
|
||||
c.User = os.Getenv("LEXGO_DB_USER")
|
||||
c.Passwd = os.Getenv("LEXGO_DB_PASSWORD")
|
||||
c.DBName = os.Getenv("LEXGO_DB_NAME")
|
||||
if c.User == "" || c.Passwd == "" || c.DBName == "" {
|
||||
return nil, errors.New("set LEXGO_DB_USER, LEXGO_DB_PASSWORD and LEXGO_DB_NAME")
|
||||
}
|
||||
c.ParseTime = true
|
||||
c.Loc = time.UTC
|
||||
c.Timeout = 5 * time.Second
|
||||
c.ReadTimeout = 10 * time.Second
|
||||
c.WriteTimeout = 10 * time.Second
|
||||
c.Params = map[string]string{"charset": "utf8mb4"}
|
||||
db, err := gorm.Open(mysql.Open(c.FormatDSN()), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)})
|
||||
if err != nil {
|
||||
return nil, errors.New("database connection failed; check local configuration")
|
||||
}
|
||||
pool, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pool.SetMaxOpenConns(10)
|
||||
pool.SetMaxIdleConns(5)
|
||||
pool.SetConnMaxLifetime(5 * time.Minute)
|
||||
var version string
|
||||
if err = db.Raw("SELECT VERSION()").Scan(&version).Error; err != nil || !strings.HasPrefix(version, "8.") {
|
||||
pool.Close()
|
||||
return nil, errors.New("MySQL 8 is required")
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func run() error {
|
||||
if len(os.Args) != 2 {
|
||||
return errors.New("usage: lexgo migrate|bootstrap|serve")
|
||||
}
|
||||
command := os.Args[1]
|
||||
if command != "migrate" && command != "bootstrap" && command != "serve" {
|
||||
return errors.New("unknown command")
|
||||
}
|
||||
db, err := openDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pool, _ := db.DB()
|
||||
defer pool.Close()
|
||||
if command == "migrate" {
|
||||
if err = lexgo.Migrate(db); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("LexGo schema version 1 ready")
|
||||
return nil
|
||||
}
|
||||
if err = lexgo.CheckSchema(db); err != nil {
|
||||
return err
|
||||
}
|
||||
if command == "bootstrap" {
|
||||
if err = lexgo.BootstrapAdmin(db, os.Getenv("LEXGO_BOOTSTRAP_USERNAME"), os.Getenv("LEXGO_BOOTSTRAP_PASSWORD")); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Initial administrator created; credentials are only in your local configuration")
|
||||
return nil
|
||||
}
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
addr := os.Getenv("LEXGO_LISTEN")
|
||||
if addr == "" {
|
||||
addr = "127.0.0.1:8000"
|
||||
}
|
||||
srv := &http.Server{Addr: addr, Handler: lexgo.Router(db, time.Now), ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, MaxHeaderBytes: 1 << 20}
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
done := make(chan error, 1)
|
||||
go func() { done <- srv.ListenAndServe() }()
|
||||
fmt.Println("LexGo API listening on", addr)
|
||||
select {
|
||||
case err = <-done:
|
||||
if errors.Is(err, http.ErrServerClosed) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
case <-ctx.Done():
|
||||
shutdown, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
return srv.Shutdown(shutdown)
|
||||
}
|
||||
}
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user