init
This commit is contained in:
44
serve/cache/init.go
vendored
Normal file
44
serve/cache/init.go
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"Edu/config"
|
||||
"Edu/serve/cache/logic"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
Cache logic.ICache
|
||||
|
||||
engines = map[string]func() logic.ICache{
|
||||
"memory": memory, "redis": redis,
|
||||
}
|
||||
)
|
||||
|
||||
func memory() logic.ICache {
|
||||
return logic.NewMemory()
|
||||
}
|
||||
|
||||
func redis() logic.ICache {
|
||||
return logic.NewRedis(&logic.RedisOption{
|
||||
Addr: config.SettingInfo.Cache.Redis.Addr,
|
||||
Password: config.SettingInfo.Cache.Redis.Password,
|
||||
DB: config.SettingInfo.Cache.Redis.DB,
|
||||
MinIdleConns: config.SettingInfo.Cache.Redis.MaxIdle,
|
||||
IdleTimeout: config.SettingInfo.Cache.Redis.IdleTimeout,
|
||||
})
|
||||
}
|
||||
|
||||
func Init() {
|
||||
handle, has := engines[config.SettingInfo.Cache.Type]
|
||||
|
||||
if !has {
|
||||
panic(fmt.Sprintf("Unknown Cache Engine Mode:%s", config.SettingInfo.Cache.Type))
|
||||
}
|
||||
Cache = handle()
|
||||
|
||||
err := Cache.Run()
|
||||
|
||||
if err != nil {
|
||||
panic("Cache Run Error:" + err.Error())
|
||||
}
|
||||
}
|
28
serve/cache/logic/cache.go
vendored
Normal file
28
serve/cache/logic/cache.go
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
package logic
|
||||
|
||||
type ICache interface {
|
||||
Set(key string, value interface{}, expiration int) error
|
||||
Get(key string) (string, error)
|
||||
Del(key string) error
|
||||
ZAdd(key string, members ...*ScoreParams) error
|
||||
ZRangebyscore(key string, opt *ScoreRangeBy) ([]string, error)
|
||||
ZRem(key string, members ...interface{}) error
|
||||
HExists(key, field string) (bool, error)
|
||||
HSet(key, field string, value interface{}) error
|
||||
HGet(key, field string) (string, error)
|
||||
HDel(key string, fields ...string) error
|
||||
SAdd(key string, members ...interface{}) error
|
||||
SIsMember(key string, members interface{}) (bool, error)
|
||||
SRem(key string, members ...interface{}) error
|
||||
Run() error
|
||||
}
|
||||
|
||||
type ScoreParams struct {
|
||||
Score float64
|
||||
Member interface{}
|
||||
}
|
||||
|
||||
type ScoreRangeBy struct {
|
||||
Min, Max string
|
||||
Offset, Count int64
|
||||
}
|
177
serve/cache/logic/memory.go
vendored
Normal file
177
serve/cache/logic/memory.go
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"Edu/utils"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Memory struct {
|
||||
cache map[string]interface{}
|
||||
cacheList []interface{}
|
||||
cacheSorted map[string][]*ScoreParams
|
||||
locker *sync.RWMutex
|
||||
}
|
||||
|
||||
func (this *Memory) Set(key string, value interface{}, expiration int) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
this.cache[key] = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get
|
||||
func (this *Memory) Get(key string) (string, error) {
|
||||
this.locker.RLock()
|
||||
defer this.locker.RUnlock()
|
||||
data, has := this.cache[key]
|
||||
|
||||
if !has {
|
||||
return "", nil
|
||||
}
|
||||
return utils.AnyToJSON(data), nil
|
||||
}
|
||||
|
||||
// Del
|
||||
func (this *Memory) Del(key string) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
delete(this.cache, key)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Memory) ZAdd(key string, members ...*ScoreParams) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
if _, has := this.cacheSorted[key]; !has {
|
||||
this.cacheSorted[key] = members
|
||||
} else {
|
||||
this.cacheSorted[key] = append(this.cacheSorted[key], members...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Memory) ZRangebyscore(key string, opt *ScoreRangeBy) ([]string, error) {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
if _, has := this.cacheSorted[key]; !has {
|
||||
return []string{}, nil
|
||||
}
|
||||
out := make([]string, 0)
|
||||
|
||||
function := func(src string) (float64, bool) {
|
||||
contain := false
|
||||
|
||||
if strings.Contains(opt.Min, "(") {
|
||||
src = strings.Replace(src, "(", "", 1)
|
||||
contain = true
|
||||
}
|
||||
f, _ := utils.StringToFloat(src)
|
||||
return f, contain
|
||||
}
|
||||
min, minContain := function(opt.Min)
|
||||
max, maxContain := function(opt.Max)
|
||||
|
||||
for _, v := range this.cacheSorted[key] {
|
||||
if ((v.Score >= min && minContain) || v.Score > min) &&
|
||||
((v.Score <= max && maxContain) || v.Score < max) {
|
||||
out = append(out, utils.AnyToJSON(v.Member))
|
||||
|
||||
if opt.Count > 0 && int64(len(out)) > opt.Count {
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (this *Memory) ZRem(key string, members ...interface{}) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
if _, has := this.cacheSorted[key]; !has {
|
||||
return nil
|
||||
}
|
||||
for k, v := range this.cacheSorted[key] {
|
||||
for _, member := range members {
|
||||
if v.Member == member {
|
||||
this.cacheSorted[key] = append(this.cacheSorted[key][:k], this.cacheSorted[key][k+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HExists HASH Exist
|
||||
func (this *Memory) HExists(key, field string) (bool, error) {
|
||||
return this.cache[key] != nil, nil
|
||||
}
|
||||
|
||||
// HSet HASH Set
|
||||
func (this *Memory) HSet(key, field string, value interface{}) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
this.cache[key] = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// HGet Hash Get
|
||||
func (this *Memory) HGet(key, field string) (string, error) {
|
||||
this.locker.RLock()
|
||||
defer this.locker.RUnlock()
|
||||
data, has := this.cache[key]
|
||||
|
||||
if !has {
|
||||
return "", nil
|
||||
}
|
||||
return utils.AnyToJSON(data), nil
|
||||
}
|
||||
|
||||
// HDel HASH Del
|
||||
func (this *Memory) HDel(key string, fields ...string) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
delete(this.cache, key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SAdd
|
||||
func (this *Memory) SAdd(key string, members ...interface{}) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
this.cacheList = append(this.cacheList, members...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SIsMember
|
||||
func (this *Memory) SIsMember(key string, members interface{}) (bool, error) {
|
||||
this.locker.RLock()
|
||||
defer this.locker.RUnlock()
|
||||
return utils.InArray(members, this.cacheList), nil
|
||||
}
|
||||
|
||||
// SRem
|
||||
func (this *Memory) SRem(key string, members ...interface{}) error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
|
||||
for k, v := range this.cacheList {
|
||||
if utils.InArray(v, members) {
|
||||
this.cacheList = append(this.cacheList[:k], this.cacheList[k+1:]...)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Memory) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewMemory() *Memory {
|
||||
return &Memory{
|
||||
cache: make(map[string]interface{}, 0),
|
||||
cacheList: make([]interface{}, 0),
|
||||
cacheSorted: make(map[string][]*ScoreParams, 0),
|
||||
locker: new(sync.RWMutex),
|
||||
}
|
||||
}
|
114
serve/cache/logic/redis.go
vendored
Normal file
114
serve/cache/logic/redis.go
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/go-redis/redis"
|
||||
)
|
||||
|
||||
type Redis struct {
|
||||
*RedisOption
|
||||
}
|
||||
|
||||
type RedisOption struct {
|
||||
Addr string
|
||||
Password string
|
||||
DB int
|
||||
MinIdleConns int
|
||||
IdleTimeout int
|
||||
}
|
||||
|
||||
var RedisClient *redis.Client
|
||||
|
||||
// Set
|
||||
func (this *Redis) Set(key string, value interface{}, expiration int) error {
|
||||
return RedisClient.Set(key, value, time.Duration(expiration)*time.Second).Err()
|
||||
}
|
||||
|
||||
// Get
|
||||
func (this *Redis) Get(key string) (string, error) {
|
||||
return RedisClient.Get(key).Result()
|
||||
}
|
||||
|
||||
// Del
|
||||
func (this *Redis) Del(key string) error {
|
||||
return RedisClient.Del(key).Err()
|
||||
}
|
||||
|
||||
func (this *Redis) ZAdd(key string, members ...*ScoreParams) error {
|
||||
redisZ := make([]redis.Z, 0)
|
||||
|
||||
for _, v := range members {
|
||||
redisZ = append(redisZ, redis.Z{Score: v.Score, Member: v.Member})
|
||||
}
|
||||
return RedisClient.ZAdd(key, redisZ...).Err()
|
||||
}
|
||||
|
||||
func (this *Redis) ZRangebyscore(key string, opt *ScoreRangeBy) ([]string, error) {
|
||||
return RedisClient.ZRangeByScore(key, redis.ZRangeBy{Min: opt.Min, Max: opt.Max, Offset: opt.Offset, Count: opt.Count}).Result()
|
||||
}
|
||||
|
||||
func (this *Redis) ZRem(key string, members ...interface{}) error {
|
||||
return RedisClient.ZRem(key, members...).Err()
|
||||
}
|
||||
|
||||
// HExists HASH Exist
|
||||
func (this *Redis) HExists(key, field string) (bool, error) {
|
||||
return RedisClient.HExists(key, field).Result()
|
||||
}
|
||||
|
||||
// HSet HASH Set
|
||||
func (this *Redis) HSet(key, field string, value interface{}) error {
|
||||
return RedisClient.HSet(key, field, value).Err()
|
||||
}
|
||||
|
||||
// HGet Hash Get
|
||||
func (this *Redis) HGet(key, field string) (string, error) {
|
||||
return RedisClient.HGet(key, field).Result()
|
||||
}
|
||||
|
||||
// HDel HASH Del
|
||||
func (this *Redis) HDel(key string, fields ...string) error {
|
||||
return RedisClient.HDel(key, fields...).Err()
|
||||
}
|
||||
|
||||
// SAdd
|
||||
func (this *Redis) SAdd(key string, members ...interface{}) error {
|
||||
return RedisClient.SAdd(key, members...).Err()
|
||||
}
|
||||
|
||||
// SIsMember
|
||||
func (this *Redis) SIsMember(key string, members interface{}) (bool, error) {
|
||||
return RedisClient.SIsMember(key, members).Result()
|
||||
}
|
||||
|
||||
// SRem
|
||||
func (this *Redis) SRem(key string, members ...interface{}) error {
|
||||
return RedisClient.SRem(key, members...).Err()
|
||||
}
|
||||
|
||||
// Run 开启
|
||||
func (this *Redis) Run() error {
|
||||
option := &redis.Options{
|
||||
Network: "",
|
||||
Addr: this.Addr,
|
||||
Password: this.Password,
|
||||
DB: this.DB,
|
||||
MinIdleConns: this.MinIdleConns,
|
||||
IdleTimeout: time.Duration(this.IdleTimeout),
|
||||
}
|
||||
RedisClient = redis.NewClient(option)
|
||||
|
||||
ping, err := RedisClient.Ping().Result()
|
||||
|
||||
if err != nil {
|
||||
return errors.New(ping + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewRedis(option *RedisOption) *Redis {
|
||||
return &Redis{option}
|
||||
}
|
32
serve/cache/logic/redis_test.go
vendored
Normal file
32
serve/cache/logic/redis_test.go
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"github.com/go-redis/redis"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var redisClient *redis.Client
|
||||
|
||||
func InitRedis() {
|
||||
option := &redis.Options{
|
||||
Network: "",
|
||||
//Addr: this.Addr,
|
||||
//Password: this.Password,
|
||||
//DB: this.DB,
|
||||
//MinIdleConns: this.MinIdleConns,
|
||||
//IdleTimeout: time.Duration(this.IdleTimeout),
|
||||
}
|
||||
redisClient = redis.NewClient(option)
|
||||
|
||||
ping, err := redisClient.Ping().Result()
|
||||
|
||||
if err != nil {
|
||||
panic(ping + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRedis(t *testing.T) {
|
||||
InitRedis()
|
||||
|
||||
//redisClient.
|
||||
}
|
32
serve/es/es.go
Normal file
32
serve/es/es.go
Normal file
@ -0,0 +1,32 @@
|
||||
package es
|
||||
|
||||
import "github.com/elastic/go-elasticsearch/v7"
|
||||
|
||||
type Es struct{ *EsConfig }
|
||||
|
||||
type EsConfig struct {
|
||||
Address []string
|
||||
}
|
||||
|
||||
type EsServer func(*EsConfig) *Es
|
||||
|
||||
var esClient = new(elasticsearch.Client)
|
||||
|
||||
func (this *Es) Run() {
|
||||
obj := elasticsearch.Config{
|
||||
Addresses: this.Address,
|
||||
Username: "",
|
||||
Password: "",
|
||||
}
|
||||
var err error
|
||||
|
||||
if esClient, err = elasticsearch.NewClient(obj); err != nil {
|
||||
panic("Elasticsearch Error " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func NewEs() EsServer {
|
||||
return func(config *EsConfig) *Es {
|
||||
return &Es{config}
|
||||
}
|
||||
}
|
5
serve/es/serve.go
Normal file
5
serve/es/serve.go
Normal file
@ -0,0 +1,5 @@
|
||||
package es
|
||||
|
||||
func Set() {
|
||||
esClient.Search()
|
||||
}
|
89
serve/logger/hook.go
Normal file
89
serve/logger/hook.go
Normal file
@ -0,0 +1,89 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"Edu/utils"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
nested "github.com/antonfisher/nested-logrus-formatter"
|
||||
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
||||
"github.com/rifflock/lfshook"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Hook
|
||||
type Hook struct {
|
||||
Path string
|
||||
File string
|
||||
}
|
||||
|
||||
// Levels 只定义 error, warn, panic 等级的日志,其他日志等级不会触发 hook
|
||||
func (this *Hook) Levels() []log.Level {
|
||||
return []log.Level{
|
||||
log.WarnLevel,
|
||||
log.ErrorLevel,
|
||||
log.PanicLevel,
|
||||
}
|
||||
}
|
||||
|
||||
// Fire 将异常日志写入到指定日志文件中
|
||||
func (this *Hook) Fire(entry *log.Entry) error {
|
||||
if isExist, _ := utils.PathExists(this.Path); !isExist {
|
||||
utils.MkdirAll(this.Path)
|
||||
}
|
||||
f, err := os.OpenFile(this.Path+this.File, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write(utils.AnyToByte(entry.Data))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func formatter(isConsole bool) *nested.Formatter {
|
||||
fmtter := &nested.Formatter{
|
||||
HideKeys: true,
|
||||
TimestampFormat: "2006-01-02 15:04:05",
|
||||
CallerFirst: true,
|
||||
CustomCallerFormatter: func(frame *runtime.Frame) string {
|
||||
funcInfo := runtime.FuncForPC(frame.PC)
|
||||
if funcInfo == nil {
|
||||
return "error during runtime.FuncForPC"
|
||||
}
|
||||
fullPath, line := funcInfo.FileLine(frame.PC)
|
||||
return fmt.Sprintf(" [%v:%v]", filepath.Base(fullPath), line)
|
||||
},
|
||||
}
|
||||
if isConsole {
|
||||
fmtter.NoColors = false
|
||||
} else {
|
||||
fmtter.NoColors = true
|
||||
}
|
||||
return fmtter
|
||||
}
|
||||
|
||||
// NewHook
|
||||
func NewHook(logName string, rotationTime time.Duration, leastDay uint) log.Hook {
|
||||
writer, err := rotatelogs.New(
|
||||
// 日志文件
|
||||
logName+".%Y%m%d",
|
||||
rotatelogs.WithRotationCount(leastDay), // 只保留最近的N个日志文件
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
lfsHook := lfshook.NewHook(lfshook.WriterMap{
|
||||
log.DebugLevel: writer,
|
||||
log.InfoLevel: writer,
|
||||
log.WarnLevel: writer,
|
||||
log.ErrorLevel: writer,
|
||||
log.FatalLevel: writer,
|
||||
log.PanicLevel: writer,
|
||||
}, formatter(false))
|
||||
|
||||
return lfsHook
|
||||
}
|
63
serve/logger/init.go
Normal file
63
serve/logger/init.go
Normal file
@ -0,0 +1,63 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
*Option
|
||||
Logger *log.Logger
|
||||
}
|
||||
|
||||
type Option struct {
|
||||
File string `json:"file"`
|
||||
LeastDay uint `json:"least_day"`
|
||||
Level string `json:"level"`
|
||||
IsStdout bool `json:"is_stdout"`
|
||||
}
|
||||
|
||||
var logger *log.Logger
|
||||
|
||||
var loggerLevel = map[string]log.Level{
|
||||
"debug": log.DebugLevel,
|
||||
"info": log.InfoLevel,
|
||||
"warn": log.WarnLevel,
|
||||
"error": log.ErrorLevel,
|
||||
}
|
||||
|
||||
func (this *Logger) level() log.Level {
|
||||
if _, has := loggerLevel[this.Level]; !has {
|
||||
return log.ErrorLevel
|
||||
}
|
||||
return loggerLevel[this.Level]
|
||||
}
|
||||
|
||||
func (this *Logger) Load() {
|
||||
logger = this.Logger
|
||||
}
|
||||
|
||||
func (this *Logger) Init(option *Option) *Logger {
|
||||
this.Option = option
|
||||
|
||||
logger = log.New()
|
||||
logger.SetFormatter(&log.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05"})
|
||||
logger.SetReportCaller(true)
|
||||
logger.AddHook(NewHook(this.File, 0, this.LeastDay))
|
||||
|
||||
if this.IsStdout {
|
||||
logger.SetOutput(io.MultiWriter(os.Stdout))
|
||||
}
|
||||
logger.SetFormatter(formatter(true))
|
||||
logger.SetLevel(this.level())
|
||||
|
||||
this.Logger = logger
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
func NewLogger() *Logger {
|
||||
return &Logger{}
|
||||
}
|
37
serve/logger/serve.go
Normal file
37
serve/logger/serve.go
Normal file
@ -0,0 +1,37 @@
|
||||
package logger
|
||||
|
||||
import "github.com/sirupsen/logrus"
|
||||
|
||||
func Warn(args ...interface{}) {
|
||||
logger.Log(logrus.WarnLevel, args...)
|
||||
}
|
||||
|
||||
func Error(args ...interface{}) {
|
||||
logger.Log(logrus.ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func Fatal(args ...interface{}) {
|
||||
logger.Log(logrus.FatalLevel, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func Panic(args ...interface{}) {
|
||||
logger.Log(logrus.PanicLevel, args...)
|
||||
}
|
||||
|
||||
func WarnF(format string, args ...interface{}) {
|
||||
logger.Logf(logrus.WarnLevel, format, args...)
|
||||
}
|
||||
|
||||
func ErrorF(format string, args ...interface{}) {
|
||||
logger.Logf(logrus.ErrorLevel, format, args...)
|
||||
}
|
||||
|
||||
func FatalF(format string, args ...interface{}) {
|
||||
logger.Logf(logrus.FatalLevel, format, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func PanicF(format string, args ...interface{}) {
|
||||
logger.Logf(logrus.PanicLevel, format, args...)
|
||||
}
|
7
serve/orm/logic/engine.go
Normal file
7
serve/orm/logic/engine.go
Normal file
@ -0,0 +1,7 @@
|
||||
package logic
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type IEngine interface {
|
||||
DSN() gorm.Dialector
|
||||
}
|
20
serve/orm/logic/mysql.go
Normal file
20
serve/orm/logic/mysql.go
Normal file
@ -0,0 +1,20 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Mysql struct {
|
||||
User, Password, Host string
|
||||
Port int
|
||||
DBName, Parameters string
|
||||
}
|
||||
|
||||
func (this *Mysql) DSN() gorm.Dialector {
|
||||
return mysql.Open(fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?%s",
|
||||
this.User, this.Password, this.Host, this.Port, this.DBName, this.Parameters,
|
||||
))
|
||||
}
|
19
serve/orm/logic/sqlite.go
Normal file
19
serve/orm/logic/sqlite.go
Normal file
@ -0,0 +1,19 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"github.com/belief428/gorm-engine/tools"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Sqlite struct {
|
||||
Path string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (this *Sqlite) DSN() gorm.Dialector {
|
||||
if isExist, _ := tools.PathExists(this.Path); !isExist {
|
||||
_ = tools.MkdirAll(this.Path)
|
||||
}
|
||||
return sqlite.Open(this.Path + "/" + this.Name)
|
||||
}
|
79
serve/orm/orm.go
Normal file
79
serve/orm/orm.go
Normal file
@ -0,0 +1,79 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"Edu/config"
|
||||
"Edu/serve/orm/logic"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
orm *gorm.DB
|
||||
|
||||
engines = map[string]func() logic.IEngine{
|
||||
"mysql": mysql, "sqlite": sqlite,
|
||||
}
|
||||
)
|
||||
|
||||
func mysql() logic.IEngine {
|
||||
return &logic.Mysql{
|
||||
User: config.SettingInfo.Engine.Mysql.User, Password: config.SettingInfo.Engine.Mysql.Password,
|
||||
Host: config.SettingInfo.Engine.Mysql.Host, Port: config.SettingInfo.Engine.Mysql.Port,
|
||||
DBName: config.SettingInfo.Engine.Mysql.DBName, Parameters: config.SettingInfo.Engine.Mysql.Parameters,
|
||||
}
|
||||
}
|
||||
|
||||
func sqlite() logic.IEngine {
|
||||
return &logic.Sqlite{Path: config.SettingInfo.Engine.Sqlite.Path, Name: config.SettingInfo.Engine.Sqlite.Name}
|
||||
}
|
||||
|
||||
func Init() {
|
||||
handle, has := engines[config.SettingInfo.Engine.DBMode]
|
||||
|
||||
if !has {
|
||||
panic(fmt.Sprintf("Unknown Engine Mode:%d", config.SettingInfo.Engine.DBMode))
|
||||
}
|
||||
option := &gorm.Config{
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
TablePrefix: config.SettingInfo.Engine.TablePrefix,
|
||||
SingularTable: !config.SettingInfo.Engine.Complex,
|
||||
},
|
||||
}
|
||||
if config.SettingInfo.Engine.Debug {
|
||||
option.Logger = logger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags),
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second,
|
||||
LogLevel: logger.Info,
|
||||
Colorful: false,
|
||||
IgnoreRecordNotFoundError: true,
|
||||
},
|
||||
)
|
||||
}
|
||||
db, err := gorm.Open(handle().DSN(), option)
|
||||
|
||||
if err != nil {
|
||||
panic("Orm Open Error:" + err.Error())
|
||||
}
|
||||
_db, _ := db.DB()
|
||||
_db.SetMaxIdleConns(config.SettingInfo.Engine.MaxIdleConns)
|
||||
_db.SetMaxOpenConns(config.SettingInfo.Engine.MaxOpenConns)
|
||||
_db.SetConnMaxLifetime(time.Duration(config.SettingInfo.Engine.MaxLifetime) * time.Second)
|
||||
|
||||
orm = db
|
||||
}
|
||||
|
||||
func GetDB() *gorm.DB {
|
||||
if _, err := orm.DB(); err != nil {
|
||||
Init()
|
||||
}
|
||||
return orm
|
||||
}
|
62
serve/web/web.go
Normal file
62
serve/web/web.go
Normal file
@ -0,0 +1,62 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Web struct {
|
||||
*WebConfig
|
||||
httpServer *http.Server
|
||||
}
|
||||
|
||||
type WebConfig struct {
|
||||
Port, ReadTimeout, WriteTimeout, IdleTimeout int
|
||||
}
|
||||
|
||||
type WebServer func(config *WebConfig) *Web
|
||||
|
||||
func (this *Web) stop() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
err = fmt.Errorf("internal error: %v", err)
|
||||
}
|
||||
}()
|
||||
s := <-c
|
||||
defer close(c)
|
||||
signal.Stop(c)
|
||||
fmt.Printf("Http Server Stop:Closed - %d\n", s)
|
||||
os.Exit(0)
|
||||
}()
|
||||
}
|
||||
|
||||
func (this *Web) Run(handler http.Handler) {
|
||||
this.httpServer = &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", this.Port),
|
||||
Handler: handler,
|
||||
ReadTimeout: time.Duration(this.ReadTimeout) * time.Second,
|
||||
WriteTimeout: time.Duration(this.WriteTimeout) * time.Second,
|
||||
IdleTimeout: time.Duration(this.IdleTimeout) * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
this.stop()
|
||||
|
||||
fmt.Println("Http Server Start")
|
||||
fmt.Printf("Http Server Address - %v\n", fmt.Sprintf("http://127.0.0.1:%d", this.Port))
|
||||
|
||||
_ = this.httpServer.ListenAndServe()
|
||||
}
|
||||
|
||||
func NewWeb() WebServer {
|
||||
return func(config *WebConfig) *Web {
|
||||
return &Web{WebConfig: config}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user