Merge pull request #80 from mc0814/master

Changed: load config publish event
This commit is contained in:
zhenorzz 2024-01-19 14:01:34 +08:00 committed by GitHub
commit 32410775ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 391 additions and 142 deletions

View File

@ -216,7 +216,7 @@ func install() {
if err := model.UseDB(db, cfg.DB.Database); err != nil {
panic(err)
}
if err := model.ImportSQL(db, database.GoploySQL); err != nil {
if err := model.ImportSQL(&model.Model{DB: db}, database.GoploySQL); err != nil {
panic(err)
}
println("Database installation is complete")

View File

@ -4,5 +4,27 @@
package config
import (
"time"
)
const NamespaceHeaderName = "G-N-ID"
const ApiKeyHeaderName = "X-API-KEY"
type APPConfig struct {
DeployLimit int32 `toml:"deployLimit"`
ShutdownTimeout time.Duration `toml:"shutdownTimeout"`
RepositoryPath string `toml:"repositoryPath"`
PasswordPeriod int `toml:"passwordPeriod"`
}
func (a *APPConfig) OnChange() error {
setAPPDefault()
return nil
}
func setAPPDefault() {
if Toml.APP.ShutdownTimeout == 0 {
Toml.APP.ShutdownTimeout = 10
}
}

5
config/cache.go Normal file
View File

@ -0,0 +1,5 @@
package config
type CacheConfig struct {
Type string `toml:"type"`
}

5
config/captcha.go Normal file
View File

@ -0,0 +1,5 @@
package config
type CaptchaConfig struct {
Enabled bool `toml:"enabled"`
}

6
config/cookie.go Normal file
View File

@ -0,0 +1,6 @@
package config
type CookieConfig struct {
Name string `toml:"name"`
Expire int `toml:"expire"` // second
}

9
config/cors.go Normal file
View File

@ -0,0 +1,9 @@
package config
type CORSConfig struct {
Enabled bool `toml:"enabled"`
Origins string `toml:"origins"`
Methods string `toml:"methods"`
Headers string `toml:"headers"`
Credentials bool `toml:"credentials"`
}

6
config/dingtalk.go Normal file
View File

@ -0,0 +1,6 @@
package config
type DingtalkConfig struct {
AppKey string `toml:"appKey"`
AppSecret string `toml:"appSecret"`
}

105
config/events.go Normal file
View File

@ -0,0 +1,105 @@
package config
import (
"errors"
"fmt"
log "github.com/sirupsen/logrus"
"sync"
)
const DBEventTopic = "db_config"
const LogEventTopic = "log_config"
const APPEventTopic = "app_config"
type Event struct {
Topic string
Val interface{}
}
type Observer interface {
OnChange() error
}
type EventBus struct {
mux sync.RWMutex
observers map[string]map[Observer]struct{}
}
type BaseObserver struct {
}
func (b *BaseObserver) OnChange(e *Event) error {
log.Printf("observer: %s, event key: %s, event val: %v", b, e.Topic, e.Val)
return nil
}
var eventBus = &EventBus{
observers: make(map[string]map[Observer]struct{}),
}
func GetEventBus() *EventBus {
return eventBus
}
func (s *EventBus) Subscribe(topic string, o Observer) {
s.mux.Lock()
defer s.mux.Unlock()
_, ok := s.observers[topic]
if !ok {
s.observers[topic] = make(map[Observer]struct{})
}
s.observers[topic][o] = struct{}{}
}
func (s *EventBus) Unsubscribe(topic string, o Observer) {
s.mux.Lock()
defer s.mux.Unlock()
delete(s.observers[topic], o)
}
func (s *EventBus) Publish(e *Event) error {
s.mux.RLock()
defer s.mux.RUnlock()
subscribers := s.observers[e.Topic]
errs := make(map[Observer]error)
for subscriber := range subscribers {
if err := subscriber.OnChange(); err != nil {
errs[subscriber] = err
}
}
return s.handleErr(errs)
}
func (s *EventBus) handleErr(errs map[Observer]error) error {
if len(errs) > 0 {
message := ""
for o, err := range errs {
message += fmt.Sprintf("observer: %v, err: %v;", o, err)
}
return errors.New(message)
}
return nil
}
func PublishEvents(newConfig Config, topics []string) error {
errMsg := ""
for _, topic := range topics {
err := eventBus.Publish(&Event{
Topic: topic,
Val: newConfig,
})
if err != nil {
errMsg += err.Error()
}
}
if errMsg != "" {
return errors.New(errMsg)
}
return nil
}

6
config/feishu.go Normal file
View File

@ -0,0 +1,6 @@
package config
type FeishuConfig struct {
AppKey string `toml:"appKey"`
AppSecret string `toml:"appSecret"`
}

5
config/jwt.go Normal file
View File

@ -0,0 +1,5 @@
package config
type JWTConfig struct {
Key string `toml:"key"`
}

12
config/ldap.go Normal file
View File

@ -0,0 +1,12 @@
package config
type LDAPConfig struct {
Enabled bool `toml:"enabled"`
URL string `toml:"url"`
BindDN string `toml:"bindDN"`
Password string `toml:"password"`
BaseDN string `toml:"baseDN"`
UID string `toml:"uid"`
Name string `toml:"name"`
UserFilter string `toml:"userFilter"`
}

55
config/log.go Normal file
View File

@ -0,0 +1,55 @@
package config
import (
"fmt"
log "github.com/sirupsen/logrus"
"io"
"os"
"path"
"path/filepath"
"runtime"
"strings"
)
type LogConfig struct {
Path string `toml:"path"`
}
func (l *LogConfig) OnChange() error {
setLogger()
return nil
}
func setLogger() {
var logFile io.Writer
logPathEnv := Toml.Log.Path
if strings.ToLower(logPathEnv) == "stdout" {
logFile = os.Stdout
} else {
logPath, err := filepath.Abs(logPathEnv)
if err != nil {
fmt.Println(err.Error())
}
if _, err := os.Stat(logPath); err != nil && os.IsNotExist(err) {
if err := os.Mkdir(logPath, os.ModePerm); nil != err {
panic(err.Error())
}
}
logFile, err = os.OpenFile(logPath+"/goploy.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
if nil != err {
panic(err.Error())
}
}
log.SetReportCaller(true)
log.SetFormatter(&log.TextFormatter{
CallerPrettyfier: func(f *runtime.Frame) (string, string) {
return fmt.Sprintf("%s()", path.Base(f.Function)), fmt.Sprintf("%s:%d", path.Base(f.File), f.Line)
},
})
log.SetOutput(logFile)
log.SetLevel(log.TraceLevel)
}

30
config/mysql.go Normal file
View File

@ -0,0 +1,30 @@
package config
type DBConfig struct {
Type string `toml:"type"`
User string `toml:"user"`
Password string `toml:"password"`
Host string `toml:"host"`
Port string `toml:"port"`
Database string `toml:"database"`
}
func (d *DBConfig) OnChange() error {
setDBDefault()
return nil
}
func setDBDefault() {
if Toml.DB.Type == "" {
Toml.DB.Type = "mysql"
}
if Toml.DB.Host == "" {
Toml.DB.Host = "127.0.0.1"
}
if Toml.DB.Port == "" {
Toml.DB.Port = "3306"
}
if Toml.DB.Database == "" {
Toml.DB.Database = "goploy"
}
}

View File

@ -6,15 +6,11 @@ package config
import (
"fmt"
"github.com/pelletier/go-toml/v2"
log "github.com/sirupsen/logrus"
"io"
"github.com/knadh/koanf/parsers/toml"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/providers/structs"
"github.com/knadh/koanf/v2"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"time"
)
type Config struct {
@ -33,155 +29,85 @@ type Config struct {
Cache CacheConfig `toml:"cache"`
}
type APPConfig struct {
DeployLimit int32 `toml:"deployLimit"`
ShutdownTimeout time.Duration `toml:"shutdownTimeout"`
RepositoryPath string `toml:"repositoryPath"`
PasswordPeriod int `toml:"passwordPeriod"`
}
type CORSConfig struct {
Enabled bool `toml:"enabled"`
Origins string `toml:"origins"`
Methods string `toml:"methods"`
Headers string `toml:"headers"`
Credentials bool `toml:"credentials"`
}
type CookieConfig struct {
Name string `toml:"name"`
Expire int `toml:"expire"` // second
}
type JWTConfig struct {
Key string `toml:"key"`
}
type DBConfig struct {
Type string `toml:"type"`
User string `toml:"user"`
Password string `toml:"password"`
Host string `toml:"host"`
Port string `toml:"port"`
Database string `toml:"database"`
}
type LogConfig struct {
Path string `toml:"path"`
}
type WebConfig struct {
Port string `toml:"port"`
}
type LDAPConfig struct {
Enabled bool `toml:"enabled"`
URL string `toml:"url"`
BindDN string `toml:"bindDN"`
Password string `toml:"password"`
BaseDN string `toml:"baseDN"`
UID string `toml:"uid"`
Name string `toml:"name"`
UserFilter string `toml:"userFilter"`
}
type DingtalkConfig struct {
AppKey string `toml:"appKey"`
AppSecret string `toml:"appSecret"`
}
type FeishuConfig struct {
AppKey string `toml:"appKey"`
AppSecret string `toml:"appSecret"`
}
type CaptchaConfig struct {
Enabled bool `toml:"enabled"`
}
type CacheConfig struct {
Type string `toml:"type"`
}
var Toml Config
var Koanf = koanf.New(".")
func InitToml() {
config, err := os.ReadFile(GetConfigFile())
if err != nil {
panic(err)
}
err = toml.Unmarshal(config, &Toml)
if err != nil {
// If first time load config error, need to panic
if err := setToml(); err != nil {
panic(err)
}
setAPPDefault()
setDBDefault()
setLogger()
}
func setAPPDefault() {
if Toml.APP.ShutdownTimeout == 0 {
Toml.APP.ShutdownTimeout = 10
}
}
GetEventBus().Subscribe(APPEventTopic, &Toml.APP)
GetEventBus().Subscribe(LogEventTopic, &Toml.Log)
GetEventBus().Subscribe(DBEventTopic, &Toml.DB)
func setDBDefault() {
if Toml.DB.Type == "" {
Toml.DB.Type = "mysql"
}
if Toml.DB.Host == "" {
Toml.DB.Host = "127.0.0.1"
}
if Toml.DB.Port == "" {
Toml.DB.Port = "3306"
}
if Toml.DB.Database == "" {
Toml.DB.Database = "goploy"
}
}
func setLogger() {
var logFile io.Writer
logPathEnv := Toml.Log.Path
if strings.ToLower(logPathEnv) == "stdout" {
logFile = os.Stdout
} else {
logPath, err := filepath.Abs(logPathEnv)
err := file.Provider(GetConfigFile()).Watch(func(event interface{}, err error) {
if err != nil {
fmt.Println(err.Error())
return
}
if _, err := os.Stat(logPath); err != nil && os.IsNotExist(err) {
if err := os.Mkdir(logPath, os.ModePerm); nil != err {
panic(err.Error())
}
}
logFile, err = os.OpenFile(logPath+"/goploy.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
if nil != err {
panic(err.Error())
}
}
log.SetReportCaller(true)
log.SetFormatter(&log.TextFormatter{
CallerPrettyfier: func(f *runtime.Frame) (string, string) {
return fmt.Sprintf("%s()", path.Base(f.Function)), fmt.Sprintf("%s:%d", path.Base(f.File), f.Line)
},
oldToml := Toml
if err = setToml(); err != nil {
fmt.Println(err.Error())
return
}
if err = PublishEvents(Toml, getEventTopics(oldToml, Toml)); err != nil {
// If new config publish events error, use the old config
fmt.Printf("publish config events error: %v \n", err)
errToml := Toml
Toml = oldToml
_ = PublishEvents(Toml, getEventTopics(errToml, Toml))
}
})
log.SetOutput(logFile)
if err != nil {
panic(err)
}
}
log.SetLevel(log.TraceLevel)
func getEventTopics(oldToml Config, newToml Config) (topics []string) {
if oldToml.DB != newToml.DB {
topics = append(topics, DBEventTopic)
}
if oldToml.Log != newToml.Log {
topics = append(topics, LogEventTopic)
}
if oldToml.APP != newToml.APP {
topics = append(topics, APPEventTopic)
}
return topics
}
func setToml() error {
if err := Koanf.Load(file.Provider(GetConfigFile()), toml.Parser()); err != nil {
return fmt.Errorf("load config file error: %s", err)
}
if err := Koanf.Unmarshal("", &Toml); err != nil {
return fmt.Errorf("unmarshal config error: %s", err)
}
return nil
}
func Write(cfg Config) error {
yamlData, err := toml.Marshal(&cfg)
if err != nil {
if err := Koanf.Load(structs.Provider(cfg, "toml"), nil); err != nil {
return err
}
err = os.WriteFile(GetConfigFile(), yamlData, 0644)
b, _ := Koanf.Marshal(toml.Parser())
err := os.WriteFile(GetConfigFile(), b, 0644)
if err != nil {
return err
}

5
config/web.go Normal file
View File

@ -0,0 +1,5 @@
package config
type WebConfig struct {
Port string `toml:"port"`
}

13
go.mod
View File

@ -33,16 +33,26 @@ require (
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/klauspost/compress v1.17.3 // indirect
github.com/knadh/koanf/maps v0.1.1 // indirect
github.com/knadh/koanf/parsers/toml v0.1.0 // indirect
github.com/knadh/koanf/providers/file v0.1.0 // indirect
github.com/knadh/koanf/providers/structs v0.1.0 // indirect
github.com/knadh/koanf/v2 v2.0.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.5.0 // indirect
@ -50,11 +60,12 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
github.com/opencontainers/runc v1.1.10 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
golang.org/x/image v0.10.0 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/time v0.4.0 // indirect
golang.org/x/tools v0.10.0 // indirect
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect

24
go.sum
View File

@ -25,6 +25,10 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.5.3 h1:u7utq56RUFiynqUzgVMFDymapcOtQ/MZkh3H4QYkxag=
github.com/go-asn1-ber/asn1-ber v1.5.3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
@ -62,6 +66,16 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA=
github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs=
github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
github.com/knadh/koanf/parsers/toml v0.1.0 h1:S2hLqS4TgWZYj4/7mI5m1CQQcWurxUz6ODgOub/6LCI=
github.com/knadh/koanf/parsers/toml v0.1.0/go.mod h1:yUprhq6eo3GbyVXFFMdbfZSo928ksS+uo0FFqNMnO18=
github.com/knadh/koanf/providers/file v0.1.0 h1:fs6U7nrV58d3CFAFh8VTde8TM262ObYf3ODrc//Lp+c=
github.com/knadh/koanf/providers/file v0.1.0/go.mod h1:rjJ/nHQl64iYCtAW2QQnF0eSmDEX/YZ/eNFj5yR6BvA=
github.com/knadh/koanf/providers/structs v0.1.0 h1:wJRteCNn1qvLtE5h8KQBvLJovidSdntfdyIbbCzEyE0=
github.com/knadh/koanf/providers/structs v0.1.0/go.mod h1:sw2YZ3txUcqA3Z27gPlmmBzWn1h8Nt9O6EP/91MkcWE=
github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g=
github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
@ -70,6 +84,12 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhR
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
@ -84,6 +104,8 @@ github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
github.com/opencontainers/runc v1.1.10 h1:EaL5WeO9lv9wmS6SASjszOeQdSctvpbu0DdBQBizE40=
github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.0-beta.4 h1:GCs8ebsDtEH3RiO78+BvhHqj65d/I6tjESitJZc07Rc=
github.com/pelletier/go-toml/v2 v2.0.0-beta.4/go.mod h1:ke6xncR3W76Ba8xnVxkrZG0js6Rd2BsQEAYrfgJ6eQA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -152,6 +174,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=

View File

@ -12,7 +12,6 @@ import (
"github.com/zhenorzz/goploy/config"
"github.com/zhenorzz/goploy/database"
"github.com/zhenorzz/goploy/internal/pkg"
"log"
"net/url"
"path"
"sort"
@ -46,10 +45,26 @@ const (
DENY
)
type Model struct {
*sql.DB
config.BaseObserver
}
func (d *Model) OnChange() error {
return connectDB()
}
// DB init when the program start
var DB *sql.DB
var DB = &Model{}
func Init() {
if err := connectDB(); err != nil {
panic(err)
}
config.GetEventBus().Subscribe(config.DBEventTopic, DB)
}
func connectDB() error {
dbConn := fmt.Sprintf(
"%s:%s@(%s:%s)/%s?charset=utf8mb4,utf8",
config.Toml.DB.User,
@ -62,16 +77,18 @@ func Init() {
{
// @see https://github.com/go-sql-driver/mysql/wiki/Examples#a-word-on-sqlopen
var err error
DB, err = sql.Open(config.Toml.DB.Type, dbConn)
DB.DB, err = sql.Open(config.Toml.DB.Type, dbConn)
if err != nil {
log.Fatal(err)
return err
}
// ping db to make sure the db has connected
if err := DB.Ping(); err != nil {
log.Fatal(err)
if err = DB.Ping(); err != nil {
return err
}
}
return nil
}
// PaginationFrom param return pagination struct
@ -106,7 +123,7 @@ func UseDB(db *sql.DB, name string) error {
return nil
}
func ImportSQL(db *sql.DB, sqlPath string) error {
func ImportSQL(db *Model, sqlPath string) error {
sqlContent, err := database.File.ReadFile(sqlPath)
if err != nil {
return err