diff --git a/README.md b/README.md index 2ff08fc..7f423ce 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,21 @@ # IGo [![Go Report Card](https://goreportcard.com/badge/github.com/aichy126/igo)](https://goreportcard.com/report/github.com/aichy126/igo) [![Language](https://img.shields.io/badge/Language-Go-blue.svg)](https://golang.org/) ![GitHub](https://img.shields.io/github/license/aichy126/igo) golang web项目脚手架,对常用组件进行封装,通过配置文件初始化后即可方便使用,避免每次创建新项目都需要初始化各种组件的业务逻辑 + ## 包含组件 - - `viper` github.com/spf13/viper 配置 - - `xorm` xorm.io/xorm mysql orm - - `gin` github.com/gin-gonic/gin web框架 - - `pprof` net/http/pprof gin debug 模式默认打开pprof - - `zap` go.uber.org/zap 日志处理 - - `context` 简单封装 - - `redis` github.com/go-redis/redis/v8 - - `util` 常用函数 - - `httpclient` http 请求简单封装 + +- `viper` github.com/spf13/viper 配置 +- `xorm` xorm.io/xorm mysql orm +- `gin` github.com/gin-gonic/gin web框架 +- `pprof` net/http/pprof gin debug 模式默认打开pprof +- `zap` go.uber.org/zap 日志处理 +- `context` 简单封装 +- `redis` github.com/go-redis/redis/v8 +- `util` 常用函数 +- `httpclient` http 请求简单封装 ## 如何初始化 + ```golang func main() { igo.App = igo.NewApp("") //初始化各个组件 @@ -30,10 +33,13 @@ func Ping(c *gin.Context) { ``` ## 配置文件 + 配置文件可以使用本地配置文件和consul配置中心 #### 本地配置文件 + ```toml + [local] address = ":8001" # host and port debug = true # debug mode for Gin @@ -54,6 +60,9 @@ max_open = 20 is_debug = true data_source = "root:root@tcp(127.0.0.1:3306)/igo?interpolateParams=true&timeout=3s&readTimeout=3s&writeTimeout=3s" +[sqlite.test] +data_source = "test.db" + [redis.igorediskey] address = "127.0.0.1:6379" password = "xxx" @@ -61,7 +70,9 @@ db = 0 poolsize = 50 ``` + #### 本地配置文件指向配置中心 + ```toml [config] address = "127.0.0.1:8500" @@ -69,22 +80,29 @@ key ="/igo/config" ``` ### 如何找到配置文件 - 1. go run main.go -c config.toml 使用 -c 加本地配置文件路径 - 2. export CONFIG_PATH=./config.toml 使用环境变量指定本地配置文件 - 3. 不使用本地配置文件环境变量直接指向配置中心 - ```shell + +1. go run main.go -c config.toml 使用 -c 加本地配置文件路径 +2. export CONFIG_PATH=./config.toml 使用环境变量指定本地配置文件 +3. 不使用本地配置文件环境变量直接指向配置中心 + +```shell export CONFIG_ADDRESS=127.0.0.1:8500 export CONFIG_KEY=/igo/config ``` ## 如何使用各个组件 + 配置文件中的 redis 和mysql 可以设置多个使用的时候只需要选择对应的配置即可 + ```golang //配置文件 Conf是viper的封装 -igo.App.Conf.GetString("xxx.xxx") +igo.App.Conf.GetString("xxx.xxx") //直接通过viper读取 +util.ConfGetString("local.debug") //util方法读取配置文件 //日志 log是zap的封装 -log.Info("hello igo", log.Any("now_time", time.Now().Unix())) -log.Error("error", log.Any("now_time", time.Now().Unix())) +log.Info("hello igo", log.Any("now_time", time.Now().Unix())) //不带traceId +log.Error("error", log.Any("now_time", time.Now().Unix())) //不带traceId +ctx.LogInfo("main-info", log.Any("info", "test")) //包含traceId +ctx.LogError("main-error", log.Any("error", "test")) //包含traceId //xorm db是xorm的封装 db := igo.App.DB.NewDBTable("dbname", "news") session := db.Where("") diff --git a/db/config.go b/db/config.go index 00f86c7..801aafa 100644 --- a/db/config.go +++ b/db/config.go @@ -8,6 +8,7 @@ import ( "time" "github.com/aichy126/igo/log" + _ "github.com/mattn/go-sqlite3" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" "github.com/spf13/viper" @@ -24,12 +25,13 @@ type DBConfig struct { MaxIdleLife int `json:"max_idle_life" toml:"max_idle_life" yaml:"max_idle_life" mapstructure:"max_idle_life"` IsDebug bool `json:"is_debug" toml:"is_debug" yaml:"is_debug" mapstructure:"is_debug"` Datasource string `json:"data_source" toml:"data_source" yaml:"data_source" mapstructure:"data_source"` + DbType string `json:"-" toml:"-" yaml:"-" mapstructure:"-"` } func (db DBConfig) newDB() (engine *xorm.Engine, err error) { - orm, err := xorm.NewEngine("mysql", db.Datasource) + orm, err := xorm.NewEngine(db.DbType, db.Datasource) if err != nil { - err = errors.Wrap(err, "conn mysql error ") + err = errors.Wrap(err, "conn xorm db error ") return } @@ -75,13 +77,26 @@ func (db *DBResourceManager) initFromToml(conf *viper.Viper) error { defer db.mutex.Unlock() mysqlList := make(map[string]*DBConfig, 0) - list := conf.GetStringMap("mysql") - for k, v := range list { + mysqlConfigList := conf.GetStringMap("mysql") + sqliteConfigList := conf.GetStringMap("sqlite") + + for k, v := range mysqlConfigList { + data := new(DBConfig) + err := mapstructure.Decode(v, data) + if err != nil { + continue + } + data.DbType = "mysql" + mysqlList[k] = data + } + + for k, v := range sqliteConfigList { data := new(DBConfig) err := mapstructure.Decode(v, data) if err != nil { continue } + data.DbType = "sqlite3" mysqlList[k] = data } diff --git a/example/config.toml b/example/config.toml index b26c07e..cee94a8 100644 --- a/example/config.toml +++ b/example/config.toml @@ -10,3 +10,8 @@ level = "INFO" max_size = 1 #每个日志文件保存的最大尺寸 单位:M max_backups = 5 #文件最多保存多少天 max_age = 7 #日志文件最多保存多少个备份 + + +[sqlite.test] +data_source = "test.db" + diff --git a/example/dao/db.go b/example/dao/db.go new file mode 100644 index 0000000..c058654 --- /dev/null +++ b/example/dao/db.go @@ -0,0 +1,52 @@ +package dao + +import ( + "time" + + "github.com/aichy126/igo" + "github.com/aichy126/igo/context" + "github.com/aichy126/igo/db" +) + +type Test0 struct { + ID int64 `xorm:"not null pk autoincr BIGINT(20) id"` + CreatedAt time.Time `xorm:"created not null default CURRENT_TIMESTAMP TIMESTAMP created_at"` + UpdatedAt time.Time `xorm:"updated_at TIMESTAMP"` + UserID string `xorm:"not null default 0 BIGINT(20) INDEX user_id"` +} + +type Test1 struct { + ID string `xorm:"not null pk autoincr BIGINT(20) id"` + UserID string `xorm:"not null default 0 BIGINT(20) INDEX user_id"` +} + +type Test2 struct { + ID int64 `xorm:"not null pk autoincr BIGINT(20) id"` + CreatedAt time.Time `xorm:"created not null default CURRENT_TIMESTAMP TIMESTAMP created_at"` + UpdatedAt time.Time `xorm:"updated_at TIMESTAMP"` +} + +type TestDbDao struct { + db *db.Repo +} + +// NewTestDbDao +func NewTestDbDao() *TestDbDao { + return &TestDbDao{ + db: igo.App.DB.NewDBTable("test", "test0"), + } +} + +func (m *TestDbDao) Info(ctx context.IContext, ID int64) (*Test0, bool, error) { + Data := new(Test0) + has, err := m.db.Where("id =? ", ID).Get(Data) + if err != nil { + return Data, false, err + } + return Data, has, nil +} + +func (m *TestDbDao) Sync(ctx context.IContext) error { + m.db.Engine.Sync(new(Test0), new(Test1), new(Test2)) + return nil +} diff --git a/example/main.go b/example/main.go index 0c6de4f..dd361e9 100644 --- a/example/main.go +++ b/example/main.go @@ -3,6 +3,7 @@ package main import ( "github.com/aichy126/igo" "github.com/aichy126/igo/context" + "github.com/aichy126/igo/example/dao" "github.com/aichy126/igo/log" "github.com/aichy126/igo/util" "github.com/gin-gonic/gin" @@ -18,7 +19,8 @@ func main() { func Router(r *gin.Engine) { r.GET("ping", Ping) - r.GET("tools", Tools) + r.GET("db/search", DbSearch) + r.GET("db/sync", DbSyncSqlite) } func Ping(c *gin.Context) { @@ -35,11 +37,24 @@ func Ping(c *gin.Context) { }) } -func Tools(c *gin.Context) { - num := 123456 - util.Dump(num, util.String(num), util.Int64(util.String(num))) +func DbSearch(c *gin.Context) { + idStr := c.Query("id") + id := util.Int64(idStr) + db := dao.NewTestDbDao() + ctx := context.Ginform(c) + info, has, err := db.Info(ctx, id) + c.JSON(200, gin.H{ + "info": info, + "has": has, + "err": err, + }) +} +func DbSyncSqlite(c *gin.Context) { + db := dao.NewTestDbDao() + ctx := context.Ginform(c) + err := db.Sync(ctx) c.JSON(200, gin.H{ - "num": util.String(num), + "err": err, }) } diff --git a/go.mod b/go.mod index 11f4026..6af371c 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/google/uuid v1.3.0 github.com/gookit/goutil v0.6.11 github.com/hashicorp/consul/api v1.12.0 + github.com/mattn/go-sqlite3 v1.14.9 github.com/mitchellh/mapstructure v1.5.0 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/pkg/errors v0.9.1